diff --git a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.html b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.html index 63af2b00e0..53ce6e6975 100644 --- a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.html +++ b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.html @@ -20,6 +20,7 @@ limitations under the License. + @@ -45,8 +46,10 @@ limitations under the License. error-message="[[_errorMessage]]" base-image="[[_baseImage]]" revision-image=[[_revisionImage]] + coverage-ranges="[[_coverageRanges]]" blame="[[_blame]]" diff="[[diff]]"> + diff --git a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.js b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.js index a177fb121e..9760d50580 100644 --- a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.js +++ b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.js @@ -193,6 +193,16 @@ value: null, }, + /** + * TODO(brohlfs): Replace Object type by Gerrit.CoverageRange. + * + * @type {!Array} + */ + _coverageRanges: { + type: Array, + value: () => [], + }, + _loadedWhitespaceLevel: String, _parentIndex: { @@ -247,6 +257,21 @@ this._errorMessage = null; const whitespaceLevel = this._getIgnoreWhitespace(); + this._coverageRanges = []; + const {changeNum, path, patchRange: {basePatchNum, patchNum}} = this; + this.$.jsAPI.getCoverageRanges(changeNum, path, basePatchNum, patchNum). + then(coverageRanges => { + if (changeNum !== this.changeNum || + path !== this.path || + basePatchNum !== this.patchRange.basePatchNum || + patchNum !== this.patchRange.patchNum) { + return; + } + this._coverageRanges = coverageRanges; + }).catch(err => { + console.warn('Loading coverage ranges failed: ', err); + }); + const diffRequest = this._getDiff() .then(diff => { this._loadedWhitespaceLevel = whitespaceLevel; diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-annotation-actions-js-api.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-annotation-actions-js-api.js index 09ff92a7f6..3f91a826c5 100644 --- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-annotation-actions-js-api.js +++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-annotation-actions-js-api.js @@ -26,6 +26,8 @@ // notifying their listeners in the notify function. this._annotationLayers = []; + this._coverageProvider = null; + // Default impl is a no-op. this._addLayerFunc = annotationActionsContext => {}; } @@ -57,6 +59,37 @@ return this; }; + /** + * The specified function will be called when a gr-diff component is built, + * and feeds the returned coverage data into the diff. Optional. + * + * Be sure to call this only once and only from one plugin. Multiple coverage + * providers are not supported. A second call will just overwrite the + * provider of the first call. + * + * TODO(brohlfs): Replace Array type by Array. + * + * @param {function(changeNum, path, basePatchNum, patchNum): + * !Promise>} coverageProvider + * @return {GrAnnotationActionsInterface} + */ + GrAnnotationActionsInterface.prototype.setCoverageProvider = function( + coverageProvider) { + if (this._coverageProvider) { + console.warn('Overwriting an existing coverage provider.'); + } + this._coverageProvider = coverageProvider; + return this; + }; + + /** + * Used by Gerrit to look up the coverage provider. Not intended to be called + * by plugins. + */ + GrAnnotationActionsInterface.prototype.getCoverageProvider = function() { + return this._coverageProvider; + }; + /** * Returns a checkbox HTMLElement that can be used to toggle annotations * on/off. The checkbox will be initially disabled. Plugins should enable it 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 16fb7b773d..ad318d7a74 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 @@ -228,6 +228,36 @@ return layers; }, + /** + * Retrieves coverage data possibly provided by a plugin. + * + * Will wait for plugins to be loaded. If multiple plugins offer a coverage + * provider, the first one is used. If no plugin offers a coverage provider, + * will resolve to []. + * + * TODO(brohlfs): Replace Array type by Array. + * + * @param {string|number} changeNum + * @param {string} path + * @param {string|number} basePatchNum + * @param {string|number} patchNum + * @return {!Promise>} + */ + getCoverageRanges(changeNum, path, basePatchNum, patchNum) { + return Gerrit.awaitPluginsLoaded().then(() => { + for (const annotationApi of + this._getEventCallbacks(EventType.ANNOTATE_DIFF)) { + const provider = annotationApi.getCoverageProvider(); + // Only one coverage provider makes sense. If there are more, then we + // simply ignore them. + if (provider) { + return provider(changeNum, path, basePatchNum, patchNum); + } + } + return []; + }); + }, + getAdminMenuLinks() { const links = []; for (const adminApi of