Convert files to typescript
The change converts the following files to typescript:
* elements/diff/gr-diff-builder/gr-diff-builder-element.ts
Change-Id: Ic28adbe27eb2707427911cc1f956ed312689b160
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-element.ts b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-element.ts
index ef75da0..09e0df8 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-element.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-element.ts
@@ -14,23 +14,45 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import '../gr-coverage-layer/gr-coverage-layer.js';
-import '../gr-diff-processor/gr-diff-processor.js';
-import '../../shared/gr-hovercard/gr-hovercard.js';
-import '../gr-ranged-comment-layer/gr-ranged-comment-layer.js';
-import './gr-diff-builder-side-by-side.js';
-import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
-import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
-import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
-import {PolymerElement} from '@polymer/polymer/polymer-element.js';
-import {htmlTemplate} from './gr-diff-builder-element_html.js';
-import {GrAnnotation} from '../gr-diff-highlight/gr-annotation.js';
-import {GrDiffBuilder} from './gr-diff-builder.js';
-import {GrDiffBuilderSideBySide} from './gr-diff-builder-side-by-side.js';
-import {GrDiffBuilderImage} from './gr-diff-builder-image.js';
-import {GrDiffBuilderUnified} from './gr-diff-builder-unified.js';
-import {GrDiffBuilderBinary} from './gr-diff-builder-binary.js';
-import {util} from '../../../scripts/util.js';
+import '../gr-coverage-layer/gr-coverage-layer';
+import '../gr-diff-processor/gr-diff-processor';
+import '../../shared/gr-hovercard/gr-hovercard';
+import '../gr-ranged-comment-layer/gr-ranged-comment-layer';
+import './gr-diff-builder-side-by-side';
+import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners';
+import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin';
+import {PolymerElement} from '@polymer/polymer/polymer-element';
+import {htmlTemplate} from './gr-diff-builder-element_html';
+import {GrAnnotation} from '../gr-diff-highlight/gr-annotation';
+import {GrDiffBuilder} from './gr-diff-builder';
+import {GrDiffBuilderSideBySide} from './gr-diff-builder-side-by-side';
+import {GrDiffBuilderImage} from './gr-diff-builder-image';
+import {GrDiffBuilderUnified} from './gr-diff-builder-unified';
+import {GrDiffBuilderBinary} from './gr-diff-builder-binary';
+import {CancelablePromise, util} from '../../../scripts/util';
+import {customElement, property, observe} from '@polymer/decorators';
+import {
+ BlameInfo,
+ DiffInfo,
+ DiffPreferencesInfo,
+ ImageInfo,
+} from '../../../types/common';
+import {CoverageRange} from '../../../types/types';
+import {
+ GrDiffProcessor,
+ KeyLocations,
+} from '../gr-diff-processor/gr-diff-processor';
+import {
+ CommentRangeLayer,
+ DiffLayer,
+ GrRangedCommentLayer,
+} from '../gr-ranged-comment-layer/gr-ranged-comment-layer';
+import {GrCoverageLayer} from '../gr-coverage-layer/gr-coverage-layer';
+import {Side} from '../../../constants/constants';
+import {GrDiffLine, LineNumber} from '../gr-diff/gr-diff-line';
+import {GrDiffGroup} from '../gr-diff/gr-diff-group';
+import {PolymerSpliceChange} from '@polymer/polymer/interfaces';
+import {getLineNumber} from '../gr-diff/gr-diff-utils';
const DiffViewMode = {
SIDE_BY_SIDE: 'SIDE_BY_SIDE',
@@ -43,14 +65,23 @@
const COMMIT_MSG_PATH = '/COMMIT_MSG';
const COMMIT_MSG_LINE_LENGTH = 72;
-/**
- * @extends PolymerElement
- */
-class GrDiffBuilderElement extends GestureEventListeners(
- LegacyElementMixin(PolymerElement)) {
- static get template() { return htmlTemplate; }
+export interface GrDiffBuilderElement {
+ $: {
+ processor: GrDiffProcessor;
+ rangeLayer: GrRangedCommentLayer;
+ coverageLayerLeft: GrCoverageLayer;
+ coverageLayerRight: GrCoverageLayer;
+ };
+}
- static get is() { return 'gr-diff-builder'; }
+@customElement('gr-diff-builder')
+export class GrDiffBuilderElement extends GestureEventListeners(
+ LegacyElementMixin(PolymerElement)
+) {
+ static get template() {
+ return htmlTemplate;
+ }
+
/**
* Fired when the diff begins rendering.
*
@@ -63,55 +94,85 @@
* @event render-content
*/
- static get properties() {
- return {
- diff: Object,
- changeNum: String,
- patchNum: String,
- viewMode: String,
- isImageDiff: Boolean,
- baseImage: Object,
- revisionImage: Object,
- parentIndex: Number,
- path: String,
- projectName: String,
+ @property({type: Object})
+ diff?: DiffInfo;
- _builder: Object,
- _groups: Array,
- _layers: Array,
- _showTabs: Boolean,
- /** @type {!Array<!Gerrit.HoveredRange>} */
- commentRanges: {
- type: Array,
- value: () => [],
- },
- /** @type {!Array<!Gerrit.CoverageRange>} */
- coverageRanges: {
- type: Array,
- value: () => [],
- },
- _leftCoverageRanges: {
- type: Array,
- computed: '_computeLeftCoverageRanges(coverageRanges)',
- },
- _rightCoverageRanges: {
- type: Array,
- computed: '_computeRightCoverageRanges(coverageRanges)',
- },
- /**
- * The promise last returned from `render()` while the asynchronous
- * rendering is running - `null` otherwise. Provides a `cancel()`
- * method that rejects it with `{isCancelled: true}`.
- *
- * @type {?Object}
- */
- _cancelableRenderPromise: Object,
- layers: {
- type: Array,
- value: [],
- },
- };
- }
+ @property({type: String})
+ changeNum?: string;
+
+ @property({type: String})
+ patchNum?: string;
+
+ @property({type: String})
+ viewMode?: string;
+
+ @property({type: Boolean})
+ isImageDiff?: boolean;
+
+ @property({type: Object})
+ baseImage: ImageInfo | null = null;
+
+ @property({type: Object})
+ revisionImage: ImageInfo | null = null;
+
+ @property({type: Number})
+ parentIndex?: number;
+
+ @property({type: String})
+ path?: string;
+
+ @property({type: String})
+ projectName?: string;
+
+ @property({type: Object})
+ _builder?: GrDiffBuilder;
+
+ @property({type: Array})
+ _groups: GrDiffGroup[] = [];
+
+ /**
+ * Layers passed in from the outside.
+ */
+ @property({type: Array})
+ layers: DiffLayer[] = [];
+
+ /**
+ * All layers, both from the outside and the default ones.
+ */
+ @property({type: Array})
+ _layers: DiffLayer[] = [];
+
+ @property({type: Boolean})
+ _showTabs?: boolean;
+
+ @property({type: Boolean})
+ _showTrailingWhitespace?: boolean;
+
+ @property({type: Array})
+ commentRanges: CommentRangeLayer[] = [];
+
+ @property({type: Array})
+ coverageRanges: CoverageRange[] = [];
+
+ @property({
+ type: Array,
+ computed: '_computeLeftCoverageRanges(coverageRanges)',
+ })
+ _leftCoverageRanges?: CoverageRange[];
+
+ @property({
+ type: Array,
+ computed: '_computeRightCoverageRanges(coverageRanges)',
+ })
+ _rightCoverageRanges?: CoverageRange[];
+
+ /**
+ * The promise last returned from `render()` while the asynchronous
+ * rendering is running - `null` otherwise. Provides a `cancel()`
+ * method that rejects it with `{isCancelled: true}`.
+ */
+ @property({type: Object})
+ _cancelableRenderPromise: CancelablePromise<unknown> | null = null;
/** @override */
detached() {
@@ -122,24 +183,18 @@
}
get diffElement() {
- return this.queryEffectiveChildren('#diffTable');
+ return this.queryEffectiveChildren('#diffTable') as HTMLElement;
}
- static get observers() {
- return [
- '_groupsChanged(_groups.splices)',
- ];
- }
-
- _computeLeftCoverageRanges(coverageRanges) {
+ _computeLeftCoverageRanges(coverageRanges: CoverageRange[]) {
return coverageRanges.filter(range => range && range.side === 'left');
}
- _computeRightCoverageRanges(coverageRanges) {
+ _computeRightCoverageRanges(coverageRanges: CoverageRange[]) {
return coverageRanges.filter(range => range && range.side === 'right');
}
- render(keyLocations, prefs) {
+ render(keyLocations: KeyLocations, prefs: DiffPreferencesInfo) {
// Setting up annotation layers must happen after plugins are
// installed, and |render| satisfies the requirement, however,
// |attached| doesn't because in the diff view page, the element is
@@ -155,6 +210,9 @@
if (this._builder) {
this._builder.clear();
}
+ if (!this.diff) {
+ throw Error('Cannot render a diff without DiffInfo.');
+ }
this._builder = this._getDiffBuilder(this.diff, prefs);
this.$.processor.context = prefs.context;
@@ -165,23 +223,32 @@
const isBinary = !!(this.isImageDiff || this.diff.binary);
- this.dispatchEvent(new CustomEvent(
- 'render-start', {bubbles: true, composed: true}));
+ this.dispatchEvent(
+ new CustomEvent('render-start', {bubbles: true, composed: true})
+ );
this._cancelableRenderPromise = util.makeCancelable(
- this.$.processor.process(this.diff.content, isBinary)
- .then(() => {
- if (this.isImageDiff) {
- this._builder.renderDiff();
- }
- this.dispatchEvent(new CustomEvent('render-content',
- {bubbles: true, composed: true}));
- }));
- return this._cancelableRenderPromise
- .finally(() => { this._cancelableRenderPromise = null; })
- // Mocca testing does not like uncaught rejections, so we catch
- // the cancels which are expected and should not throw errors in
- // tests.
- .catch(e => { if (!e.isCanceled) return Promise.reject(e); });
+ this.$.processor.process(this.diff.content, isBinary).then(() => {
+ if (this.isImageDiff) {
+ (this._builder as GrDiffBuilderImage).renderDiff();
+ }
+ this.dispatchEvent(
+ new CustomEvent('render-content', {bubbles: true, composed: true})
+ );
+ })
+ );
+ return (
+ this._cancelableRenderPromise
+ .finally(() => {
+ this._cancelableRenderPromise = null;
+ })
+ // Mocca testing does not like uncaught rejections, so we catch
+ // the cancels which are expected and should not throw errors in
+ // tests.
+ .catch(e => {
+ if (!e.isCanceled) return Promise.reject(e);
+ return;
+ })
+ );
}
_setupAnnotationLayers() {
@@ -200,87 +267,91 @@
this._layers = layers;
}
- getLineElByChild(node) {
+ getLineElByChild(node?: Node): HTMLElement | null {
while (node) {
if (node instanceof Element) {
if (node.classList.contains('lineNum')) {
- return node;
+ return node as HTMLElement;
}
if (node.classList.contains('section')) {
return null;
}
}
- node = node.previousSibling || node.parentElement;
+ node = node.previousSibling ?? node.parentElement ?? undefined;
}
return null;
}
- getLineNumberByChild(node) {
+ getLineNumberByChild(node: Node) {
const lineEl = this.getLineElByChild(node);
- return lineEl ?
- parseInt(lineEl.getAttribute('data-value'), 10) :
- null;
+ return getLineNumber(lineEl);
}
- getContentTdByLine(lineNumber, opt_side, opt_root) {
- return this._builder.getContentTdByLine(lineNumber, opt_side, opt_root);
+ getContentTdByLine(lineNumber: LineNumber, side?: Side, root?: Element) {
+ if (!this._builder) return null;
+ return this._builder.getContentTdByLine(lineNumber, side, root);
}
- _getDiffRowByChild(child) {
+ _getDiffRowByChild(child: Element) {
while (!child.classList.contains('diff-row') && child.parentElement) {
child = child.parentElement;
}
return child;
}
- getContentTdByLineEl(lineEl) {
- if (!lineEl) return;
- const line = lineEl.getAttribute('data-value');
+ getContentTdByLineEl(lineEl?: Element): Element | null {
+ if (!lineEl) return null;
+ const line = getLineNumber(lineEl);
+ if (!line) return null;
const side = this.getSideByLineEl(lineEl);
// Performance optimization because we already have an element in the
// correct row
- const row = dom(this._getDiffRowByChild(lineEl));
+ const row = this._getDiffRowByChild(lineEl);
return this.getContentTdByLine(line, side, row);
}
- getLineElByNumber(lineNumber, opt_side) {
- const sideSelector = opt_side ? ('.' + opt_side) : '';
+ getLineElByNumber(lineNumber: string, side?: Side) {
+ const sideSelector = side ? '.' + side : '';
return this.diffElement.querySelector(
- '.lineNum[data-value="' + lineNumber + '"]' + sideSelector);
+ '.lineNum[data-value="' + lineNumber + '"]' + sideSelector
+ );
}
- getContentsByLineRange(startLine, endLine, opt_side) {
- const result = [];
- this._builder.findLinesByRange(startLine, endLine, opt_side, null,
- result);
- return result;
+ getSideByLineEl(lineEl: Element) {
+ return lineEl.classList.contains(GrDiffBuilder.Side.RIGHT)
+ ? Side.RIGHT
+ : Side.LEFT;
}
- getSideByLineEl(lineEl) {
- return lineEl.classList.contains(GrDiffBuilder.Side.RIGHT) ?
- GrDiffBuilder.Side.RIGHT : GrDiffBuilder.Side.LEFT;
- }
-
- emitGroup(group, sectionEl) {
+ emitGroup(group: GrDiffGroup, sectionEl: HTMLElement) {
+ if (!this._builder) return;
this._builder.emitGroup(group, sectionEl);
}
- showContext(newGroups, sectionEl) {
+ showContext(newGroups: GrDiffGroup[], sectionEl: HTMLElement) {
+ if (!this._builder) return;
const groups = this._builder.groups;
- const contextIndex = groups.findIndex(group =>
- group.element === sectionEl
- );
+ const contextIndex = groups.findIndex(group => group.element === sectionEl);
groups.splice(contextIndex, 1, ...newGroups);
for (const newGroup of newGroups) {
this._builder.emitGroup(newGroup, sectionEl);
}
- sectionEl.parentNode.removeChild(sectionEl);
+ if (sectionEl.parentNode) {
+ sectionEl.parentNode.removeChild(sectionEl);
+ }
- this.async(() => this.dispatchEvent(new CustomEvent('render-content', {
- composed: true, bubbles: true,
- })), 1);
+ this.async(
+ () =>
+ this.dispatchEvent(
+ new CustomEvent('render-content', {
+ composed: true,
+ bubbles: true,
+ })
+ ),
+ 1
+ );
}
cancel() {
@@ -291,25 +362,29 @@
}
}
- _handlePreferenceError(pref) {
- const message = `The value of the '${pref}' user preference is ` +
- `invalid. Fix in diff preferences`;
- this.dispatchEvent(new CustomEvent('show-alert', {
- detail: {
- message,
- }, bubbles: true, composed: true}));
+ _handlePreferenceError(pref: string): never {
+ const message =
+ `The value of the '${pref}' user preference is ` +
+ 'invalid. Fix in diff preferences';
+ this.dispatchEvent(
+ new CustomEvent('show-alert', {
+ detail: {
+ message,
+ },
+ bubbles: true,
+ composed: true,
+ })
+ );
throw Error(`Invalid preference value: ${pref}`);
}
- _getDiffBuilder(diff, prefs) {
+ _getDiffBuilder(diff: DiffInfo, prefs: DiffPreferencesInfo): GrDiffBuilder {
if (isNaN(prefs.tab_size) || prefs.tab_size <= 0) {
this._handlePreferenceError('tab size');
- return;
}
if (isNaN(prefs.line_length) || prefs.line_length <= 0) {
this._handlePreferenceError('diff width');
- return;
}
const localPrefs = {...prefs};
@@ -322,49 +397,51 @@
let builder = null;
if (this.isImageDiff) {
builder = new GrDiffBuilderImage(
- diff,
- localPrefs,
- this.diffElement,
- this.baseImage,
- this.revisionImage);
+ diff,
+ localPrefs,
+ this.diffElement,
+ this.baseImage,
+ this.revisionImage
+ );
} else if (diff.binary) {
// If the diff is binary, but not an image.
- return new GrDiffBuilderBinary(
- diff,
- localPrefs,
- this.diffElement);
+ return new GrDiffBuilderBinary(diff, localPrefs, this.diffElement);
} else if (this.viewMode === DiffViewMode.SIDE_BY_SIDE) {
builder = new GrDiffBuilderSideBySide(
- diff,
- localPrefs,
- this.diffElement,
- this._layers
+ diff,
+ localPrefs,
+ this.diffElement,
+ this._layers
);
} else if (this.viewMode === DiffViewMode.UNIFIED) {
builder = new GrDiffBuilderUnified(
- diff,
- localPrefs,
- this.diffElement,
- this._layers);
+ diff,
+ localPrefs,
+ this.diffElement,
+ this._layers
+ );
}
if (!builder) {
- throw Error('Unsupported diff view mode: ' + this.viewMode);
+ throw Error(`Unsupported diff view mode: ${this.viewMode}`);
}
return builder;
}
_clearDiffContent() {
- this.diffElement.innerHTML = null;
+ this.diffElement.innerHTML = '';
}
- _groupsChanged(changeRecord) {
- if (!changeRecord) { return; }
+ @observe('_groups.splices')
+ _groupsChanged(changeRecord: PolymerSpliceChange<GrDiffGroup[]>) {
+ if (!changeRecord || !this._builder) {
+ return;
+ }
for (const splice of changeRecord.indexSplices) {
let group;
for (let i = 0; i < splice.addedCount; i++) {
group = splice.object[splice.index + i];
this._builder.groups.push(group);
- this._builder.emitGroup(group);
+ this._builder.emitGroup(group, null);
}
}
}
@@ -374,24 +451,28 @@
// Take a DIV.contentText element and a line object with intraline
// differences to highlight and apply them to the element as
// annotations.
- annotate(contentEl, lineNumberEl, line) {
+ annotate(contentEl: HTMLElement, _: HTMLElement, line: GrDiffLine) {
const HL_CLASS = 'style-scope gr-diff intraline';
for (const highlight of line.highlights) {
// The start and end indices could be the same if a highlight is
// meant to start at the end of a line and continue onto the
// next one. Ignore it.
- if (highlight.startIndex === highlight.endIndex) { continue; }
+ if (highlight.startIndex === highlight.endIndex) {
+ continue;
+ }
// If endIndex isn't present, continue to the end of the line.
- const endIndex = highlight.endIndex === undefined ?
- line.text.length :
- highlight.endIndex;
+ const endIndex =
+ highlight.endIndex === undefined
+ ? line.text.length
+ : highlight.endIndex;
GrAnnotation.annotateElement(
- contentEl,
- highlight.startIndex,
- endIndex - highlight.startIndex,
- HL_CLASS);
+ contentEl,
+ highlight.startIndex,
+ endIndex - highlight.startIndex,
+ HL_CLASS
+ );
}
},
};
@@ -400,19 +481,27 @@
_createTabIndicatorLayer() {
const show = () => this._showTabs;
return {
- annotate(contentEl, lineNumberEl, line) {
+ annotate(contentEl: HTMLElement, _: HTMLElement, line: GrDiffLine) {
// If visible tabs are disabled, do nothing.
- if (!show()) { return; }
+ if (!show()) {
+ return;
+ }
// Find and annotate the locations of tabs.
const split = line.text.split('\t');
- if (!split) { return; }
+ if (!split) {
+ return;
+ }
for (let i = 0, pos = 0; i < split.length - 1; i++) {
// Skip forward by the length of the content
pos += split[i].length;
- GrAnnotation.annotateElement(contentEl, pos, 1,
- 'style-scope gr-diff tab-indicator');
+ GrAnnotation.annotateElement(
+ contentEl,
+ pos,
+ 1,
+ 'style-scope gr-diff tab-indicator'
+ );
// Skip forward by one tab character.
pos++;
@@ -422,32 +511,45 @@
}
_createTrailingWhitespaceLayer() {
- const show = function() {
+ const show = () => {
return this._showTrailingWhitespace;
- }.bind(this);
+ };
return {
- annotate(contentEl, lineNumberEl, line) {
- if (!show()) { return; }
+ annotate(contentEl: HTMLElement, _: HTMLElement, line: GrDiffLine) {
+ if (!show()) {
+ return;
+ }
const match = line.text.match(TRAILING_WHITESPACE_PATTERN);
if (match) {
// Normalize string positions in case there is unicode before or
// within the match.
const index = GrAnnotation.getStringLength(
- line.text.substr(0, match.index));
+ line.text.substr(0, match.index)
+ );
const length = GrAnnotation.getStringLength(match[0]);
- GrAnnotation.annotateElement(contentEl, index, length,
- 'style-scope gr-diff trailing-whitespace');
+ GrAnnotation.annotateElement(
+ contentEl,
+ index,
+ length,
+ 'style-scope gr-diff trailing-whitespace'
+ );
}
},
};
}
- setBlame(blame) {
- if (!this._builder || !blame) { return; }
+ setBlame(blame: BlameInfo[]) {
+ if (!this._builder || !blame) {
+ return;
+ }
this._builder.setBlame(blame);
}
}
-customElements.define(GrDiffBuilderElement.is, GrDiffBuilderElement);
+declare global {
+ interface HTMLElementTagNameMap {
+ 'gr-diff-builder': GrDiffBuilderElement;
+ }
+}
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-element_test.js b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-element_test.js
index 9eafda2..7cbbdb9 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-element_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-element_test.js
@@ -296,18 +296,15 @@
}
});
- test('_handlePreferenceError called with invalid preference', () => {
- sinon.stub(element, '_handlePreferenceError');
+ test('_handlePreferenceError throws with invalid preference', () => {
const prefs = {tab_size: 0};
- element._getDiffBuilder(element.diff, prefs);
- assert.isTrue(element._handlePreferenceError.lastCall
- .calledWithExactly('tab size'));
+ assert.throws(() => element._getDiffBuilder(element.diff, prefs));
});
test('_handlePreferenceError triggers alert and javascript error', () => {
const errorStub = sinon.stub();
element.addEventListener('show-alert', errorStub);
- assert.throws(element._handlePreferenceError.bind(element, 'tab size'));
+ assert.throws(() => element._handlePreferenceError('tab size'));
assert.equal(errorStub.lastCall.args[0].detail.message,
`The value of the 'tab size' user preference is invalid. ` +
`Fix in diff preferences`);
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-image.ts b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-image.ts
index 43086ae..f3de371 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-image.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-image.ts
@@ -17,6 +17,7 @@
import {GrDiffBuilderSideBySide} from './gr-diff-builder-side-by-side';
import {DiffInfo, DiffPreferencesInfo, ImageInfo} from '../../../types/common';
+import {GrEndpointParam} from '../../plugins/gr-endpoint-param/gr-endpoint-param';
// MIME types for images we allow showing. Do not include SVG, it can contain
// arbitrary JavaScript.
@@ -27,8 +28,8 @@
diff: DiffInfo,
prefs: DiffPreferencesInfo,
outputEl: HTMLElement,
- private readonly _baseImage: ImageInfo,
- private readonly _revisionImage: ImageInfo
+ private readonly _baseImage: ImageInfo | null,
+ private readonly _revisionImage: ImageInfo | null
) {
super(diff, prefs, outputEl, []);
}
@@ -66,10 +67,11 @@
return tbody;
}
- private _createEndpointParam(name: string, value: ImageInfo) {
- // TODO(TS): Replace any by GrEndpointParam type when it is available.
- const endpointParam: any = this._createElement('gr-endpoint-param');
- endpointParam.setAttribute('name', name);
+ private _createEndpointParam(name: string, value: ImageInfo | null) {
+ const endpointParam = this._createElement(
+ 'gr-endpoint-param'
+ ) as GrEndpointParam;
+ endpointParam.name = name;
endpointParam.value = value;
return endpointParam;
}
@@ -89,7 +91,7 @@
}
private _createImageCell(
- image: ImageInfo,
+ image: ImageInfo | null,
className: string,
section: HTMLElement
) {
@@ -122,7 +124,7 @@
this._setLabelText(label, image);
}
- private _setLabelText(label: HTMLElement, image: ImageInfo) {
+ private _setLabelText(label: HTMLElement, image: ImageInfo | null) {
label.textContent = _getImageLabel(image);
}
@@ -147,7 +149,7 @@
if (addNamesInLabel) {
nameSpan = this._createElement('span', 'name');
- nameSpan.textContent = this._baseImage._name;
+ nameSpan.textContent = this._baseImage?._name ?? '';
label.appendChild(nameSpan);
label.appendChild(this._createElement('br'));
}
@@ -165,7 +167,7 @@
if (addNamesInLabel) {
nameSpan = this._createElement('span', 'name');
- nameSpan.textContent = this._revisionImage._name;
+ nameSpan.textContent = this._revisionImage?._name ?? '';
label.appendChild(nameSpan);
label.appendChild(this._createElement('br'));
}
@@ -180,9 +182,9 @@
}
}
-function _getImageLabel(image: ImageInfo) {
+function _getImageLabel(image: ImageInfo | null) {
if (image) {
- const type = image.type || image._expectedType;
+ const type = image.type ?? image._expectedType;
if (image._width && image._height) {
return `${image._width}×${image._height} ${type}`;
} else {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.ts b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.ts
index d98f134..9ebf4b9 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.ts
@@ -72,7 +72,7 @@
protected readonly _outputEl: HTMLElement;
- private readonly groups: GrDiffGroup[];
+ readonly groups: GrDiffGroup[];
private _blameInfo: BlameInfo[] | null;
@@ -155,7 +155,7 @@
abstract buildSectionElement(group: GrDiffGroup): HTMLElement;
- emitGroup(group: GrDiffGroup, beforeSection: HTMLElement) {
+ emitGroup(group: GrDiffGroup, beforeSection: HTMLElement | null) {
const element = this.buildSectionElement(group);
this._outputEl.insertBefore(element, beforeSection);
group.element = element;
@@ -198,7 +198,7 @@
getContentTdByLine(
lineNumber: LineNumber,
side?: Side,
- root: HTMLElement = this._outputEl
+ root: Element = this._outputEl
): Element | null {
const sideSelector: string = side ? `.${side}` : '';
return root.querySelector(
@@ -221,17 +221,16 @@
* @param start The first line number
* @param end The last line number
* @param side The side of the range. Either 'left' or 'right'.
- * @param out_lines The output list of line objects. Use
- * null if not desired.
- * @param out_elements The output list of line elements.
- * Use null if not desired.
+ * @param out_lines The output list of line objects. Use null if not desired.
+ * @param out_elements The output list of line elements. Use null if not
+ * desired.
*/
findLinesByRange(
start: LineNumber,
end: LineNumber,
side: Side,
- out_lines: GrDiffLine[],
- out_elements: HTMLElement[]
+ out_lines: GrDiffLine[] | null,
+ out_elements: HTMLElement[] | null
) {
const groups = this.getGroupsByLineRange(start, end, side);
for (const group of groups) {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight.ts b/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight.ts
index 03dd931..9788c8e 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight.ts
@@ -28,6 +28,8 @@
import {Side} from '../../../constants/constants';
import {CommentRange} from '../../../types/common';
import {GrSelectionActionBox} from '../gr-selection-action-box/gr-selection-action-box';
+import {GrDiffBuilderElement} from '../gr-diff-builder/gr-diff-builder-element';
+import {FILE} from '../gr-diff/gr-diff-line';
interface SidedRange {
side: Side;
@@ -51,14 +53,6 @@
rootId: string;
}
-// TODO(TS): Replace by GrDiffBuilderElement once that is converted.
-interface DiffBuilderElement extends HTMLElement {
- getLineElByChild(node: Node): HTMLElement;
- getSideByLineEl(lineEl: HTMLElement): Side;
- getLineNumberByChild(lineEl: HTMLElement): number;
- getContentTdByLineEl(lineEl: HTMLElement): HTMLElement;
-}
-
@customElement('gr-diff-highlight')
export class GrDiffHighlight extends GestureEventListeners(
LegacyElementMixin(PolymerElement)
@@ -74,7 +68,7 @@
loggedIn?: boolean;
@property({type: Object})
- _cachedDiffBuilder?: DiffBuilderElement;
+ _cachedDiffBuilder?: GrDiffBuilderElement;
@property({type: Object, notify: true})
selectedRange?: SidedRange;
@@ -97,7 +91,7 @@
if (!this._cachedDiffBuilder) {
this._cachedDiffBuilder = this.querySelector(
'gr-diff-builder'
- ) as DiffBuilderElement;
+ ) as GrDiffBuilderElement;
}
return this._cachedDiffBuilder;
}
@@ -336,22 +330,15 @@
offset: number
): NormalizedPosition | null {
let column;
- if (!node || !this.contains(node)) {
- return null;
- }
+ if (!node || !this.contains(node)) return null;
const lineEl = this.diffBuilder.getLineElByChild(node);
- if (!lineEl) {
- return null;
- }
+ if (!lineEl) return null;
const side = this.diffBuilder.getSideByLineEl(lineEl);
- if (!side) {
- return null;
- }
+ if (!side) return null;
const line = this.diffBuilder.getLineNumberByChild(lineEl);
- if (!line) {
- return null;
- }
+ if (!line || line === FILE) return null;
const contentTd = this.diffBuilder.getContentTdByLineEl(lineEl);
+ if (!contentTd) return null;
const contentText = contentTd.querySelector('.contentText');
if (!contentTd.contains(node)) {
node = contentText;
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.ts b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.ts
index 74164a8..0ac39f0 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.ts
@@ -48,7 +48,7 @@
keyLocation: boolean;
}
-interface KeyLocations {
+export interface KeyLocations {
left: {[key: string]: boolean};
right: {[key: string]: boolean};
}
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection.ts b/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection.ts
index e040856..fab2b59 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection.ts
@@ -29,15 +29,7 @@
import {customElement, property, observe} from '@polymer/decorators';
import {DiffInfo} from '../../../types/common';
import {Side} from '../../../constants/constants';
-
-// TODO(TS): Replace by GrDiffBuilderElement once that is converted.
-interface DiffBuilderElement extends HTMLElement {
- diffElement: HTMLTableElement;
- getLineElByChild(node: Node): HTMLElement;
- getSideByLineEl(lineEl: HTMLElement): Side;
- getLineNumberByChild(lineEl: HTMLElement): number;
- getContentTdByLineEl(lineEl: HTMLElement): HTMLElement;
-}
+import {GrDiffBuilderElement} from '../gr-diff-builder/gr-diff-builder-element';
/**
* Possible CSS classes indicating the state of selection. Dynamically added/
@@ -71,7 +63,7 @@
diff?: DiffInfo;
@property({type: Object})
- _cachedDiffBuilder?: DiffBuilderElement;
+ _cachedDiffBuilder?: GrDiffBuilderElement;
@property({type: Object})
_linesCache: LinesCache = {left: null, right: null};
@@ -93,7 +85,7 @@
if (!this._cachedDiffBuilder) {
this._cachedDiffBuilder = this.querySelector(
'gr-diff-builder'
- ) as DiffBuilderElement;
+ ) as GrDiffBuilderElement;
}
return this._cachedDiffBuilder;
}
@@ -132,7 +124,7 @@
if (blameSelected) {
targetClasses.push(SelectionClass.BLAME);
- } else {
+ } else if (lineEl) {
const commentSelected = this._elementDescendedFromClass(
target,
'gr-comment'
@@ -237,6 +229,7 @@
}
const range = normalize(sel.getRangeAt(0));
const startLineEl = this.diffBuilder.getLineElByChild(range.startContainer);
+ if (!startLineEl) return;
const endLineEl = this.diffBuilder.getLineElByChild(range.endContainer);
// Happens when triple click in side-by-side mode with other side empty.
const endsAtOtherEmptySide =
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-line.ts b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-line.ts
index f983428..2d80213 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-line.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-line.ts
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+export const FILE = 'FILE';
export type LineNumber = number | 'FILE';
export enum GrDiffLineType {
@@ -24,8 +25,6 @@
REMOVE = 'remove',
}
-export const FILE = 'FILE';
-
export class GrDiffLine {
constructor(
readonly type: GrDiffLineType,
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-utils.ts b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-utils.ts
index dbdab05..0aa42c3 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-utils.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-utils.ts
@@ -16,6 +16,7 @@
*/
import {CommentRange} from '../../../types/common';
+import {FILE, LineNumber} from './gr-diff-line';
export enum DiffSide {
LEFT = 'left',
@@ -41,3 +42,12 @@
a.end_character === b.end_character
);
}
+
+export function getLineNumber(lineEl?: Element | null): LineNumber | null {
+ if (!lineEl) return null;
+ const lineNumberStr = lineEl.getAttribute('data-value');
+ if (!lineNumberStr) return null;
+ if (lineNumberStr === FILE) return FILE;
+ const lineNumber = Number(lineNumberStr);
+ return Number.isInteger(lineNumber) ? lineNumber : null;
+}
diff --git a/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer.ts b/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer.ts
index 36a229f..f001a89 100644
--- a/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer.ts
+++ b/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer.ts
@@ -80,7 +80,7 @@
const HOVER_HIGHLIGHT = 'style-scope gr-diff rangeHighlight';
@customElement('gr-ranged-comment-layer')
-class GrRangedCommentLayer
+export class GrRangedCommentLayer
extends GestureEventListeners(LegacyElementMixin(PolymerElement))
implements DiffLayer {
static get template() {
diff --git a/polygerrit-ui/app/elements/plugins/gr-endpoint-param/gr-endpoint-param.ts b/polygerrit-ui/app/elements/plugins/gr-endpoint-param/gr-endpoint-param.ts
index d731ef0..41964d5 100644
--- a/polygerrit-ui/app/elements/plugins/gr-endpoint-param/gr-endpoint-param.ts
+++ b/polygerrit-ui/app/elements/plugins/gr-endpoint-param/gr-endpoint-param.ts
@@ -35,14 +35,11 @@
@property({
type: Object,
notify: true,
- observer: GrEndpointParam.prototype._valueChanged,
+ observer: '_valueChanged',
})
- value: Record<string, unknown> | undefined = undefined;
+ value?: unknown;
- private _valueChanged(
- newValue: Record<string, unknown>,
- _oldValue: Record<string, unknown>
- ) {
+ _valueChanged(value: unknown) {
/* In polymer 2 the following change was made:
"Property change notifications (property-changed events) aren't fired when
the value changes as a result of a binding from the host"
@@ -51,9 +48,6 @@
In some cases this fire the event twice, but our code is
ready for it.
*/
- const detail = {
- value: newValue,
- };
- this.dispatchEvent(new CustomEvent('value-changed', {detail}));
+ this.dispatchEvent(new CustomEvent('value-changed', {detail: {value}}));
}
}
diff --git a/polygerrit-ui/app/types/common.ts b/polygerrit-ui/app/types/common.ts
index 272da74..646cb43 100644
--- a/polygerrit-ui/app/types/common.ts
+++ b/polygerrit-ui/app/types/common.ts
@@ -1196,10 +1196,10 @@
export interface ImageInfo {
body: string;
type: string;
- _name: string;
- _expectedType: string;
- _width: number;
- _height: number;
+ _name?: string;
+ _expectedType?: string;
+ _width?: number;
+ _height?: number;
}
/**
diff --git a/polygerrit-ui/app/types/types.ts b/polygerrit-ui/app/types/types.ts
index 69a550b..54411f8 100644
--- a/polygerrit-ui/app/types/types.ts
+++ b/polygerrit-ui/app/types/types.ts
@@ -14,6 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+import {Side} from '../constants/constants';
+
+export interface CoverageRange {
+ type: CoverageType;
+ side: Side;
+ code_range: {end_line: number; start_line: number};
+}
export enum CoverageType {
/**