diff --git a/Documentation/js-api.txt b/Documentation/js-api.txt index f3b84d2705..a28d062b41 100644 --- a/Documentation/js-api.txt +++ b/Documentation/js-api.txt @@ -167,7 +167,8 @@ Supported events: * `showchange`: Invoked when a change is made visible. A link:rest-api-changes.html#change-info[ChangeInfo] and link:rest-api-changes.html#revision-info[RevisionInfo] - are passed as arguments. + are passed as arguments. PolyGerrit provides a third parameter which + is an object with a `mergeable` boolean. * `submitchange`: Invoked when the submit button is clicked on a change. A link:rest-api-changes.html#change-info[ChangeInfo] diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js index 5718e8e1c4..5fdef79343 100644 --- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js +++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js @@ -554,10 +554,7 @@ patchRange.patchNum = this.computeLatestPatchNum(this._allPatchSets); } this._reloadPatchNumDependentResources().then(() => { - this.$.jsAPI.handleEvent(this.$.jsAPI.EventType.SHOW_CHANGE, { - change: this._change, - patchNum: patchRange.patchNum, - }); + this._sendShowChangeEvent(); }); return; } @@ -570,15 +567,20 @@ }); }, + _sendShowChangeEvent() { + this.$.jsAPI.handleEvent(this.$.jsAPI.EventType.SHOW_CHANGE, { + change: this._change, + patchNum: this._patchRange.patchNum, + info: {mergeable: this._mergeable}, + }); + }, + _performPostLoadTasks() { this.$.relatedChanges.reload(); this._maybeShowReplyDialog(); this._maybeShowRevertDialog(); - this.$.jsAPI.handleEvent(this.$.jsAPI.EventType.SHOW_CHANGE, { - change: this._change, - patchNum: this._patchRange.patchNum, - }); + this._sendShowChangeEvent(); this.async(() => { if (this.viewState.scrollTop) { diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html index d02db0cc78..347100e0e4 100644 --- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html +++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html @@ -1459,6 +1459,22 @@ limitations under the License. }); }); + test('_sendShowChangeEvent', () => { + element._change = {labels: {}}; + element._patchRange = {patchNum: 4}; + element._mergeable = true; + const showStub = sandbox.stub(element.$.jsAPI, 'handleEvent'); + element._sendShowChangeEvent(); + assert.isTrue(showStub.calledOnce); + assert.equal( + showStub.lastCall.args[0], element.$.jsAPI.EventType.SHOW_CHANGE); + assert.deepEqual(showStub.lastCall.args[1], { + change: {labels: {}}, + patchNum: 4, + info: {mergeable: true}, + }); + }); + suite('_handleEditTap', () => { let fireEdit; diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.js index 38262eccf4..d974b62469 100644 --- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.js +++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.js @@ -120,18 +120,34 @@ }, _handleShowChange(detail) { - for (const cb of this._getEventCallbacks(EventType.SHOW_CHANGE)) { - const change = detail.change; - const patchNum = detail.patchNum; - let revision; - for (const rev of Object.values(change.revisions || {})) { - if (this.patchNumEquals(rev._number, patchNum)) { - revision = rev; - break; - } + // Note (issue 8221) Shallow clone the change object and add a mergeable + // getter with deprecation warning. This makes the change detail appear as + // though SKIP_MERGEABLE was not set, so that plugins that expect it can + // still access. + // + // This clone and getter can be removed after plugins migrate to use + // info.mergeable. + const change = Object.assign({ + get mergeable() { + console.warn('Accessing change.mergeable from SHOW_CHANGE is ' + + 'deprecated! Use info.mergeable instead.'); + return detail.info.mergeable; + }, + }, detail.change); + const patchNum = detail.patchNum; + const info = detail.info; + + let revision; + for (const rev of Object.values(change.revisions || {})) { + if (this.patchNumEquals(rev._number, patchNum)) { + revision = rev; + break; } + } + + for (const cb of this._getEventCallbacks(EventType.SHOW_CHANGE)) { try { - cb(change, revision); + cb(change, revision, info); } catch (err) { console.error(err); } diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html index 62c4a91eb9..5ad389533e 100644 --- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html +++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html @@ -179,15 +179,17 @@ limitations under the License. _number: 42, revisions: {def: {_number: 2}, abc: {_number: 1}}, }; + const expectedChange = Object.assign({mergeable: false}, testChange); plugin.on(element.EventType.SHOW_CHANGE, throwErrFn); - plugin.on(element.EventType.SHOW_CHANGE, (change, revision) => { - assert.deepEqual(change, testChange); + plugin.on(element.EventType.SHOW_CHANGE, (change, revision, info) => { + assert.deepEqual(change, expectedChange); assert.deepEqual(revision, testChange.revisions.abc); + assert.deepEqual(info, {mergeable: false}); assert.isTrue(errorStub.calledOnce); done(); }); element.handleEvent(element.EventType.SHOW_CHANGE, - {change: testChange, patchNum: 1}); + {change: testChange, patchNum: 1, info: {mergeable: false}}); }); test('handleEvent awaits plugins load', done => {