Convert files to typescript

The change converts the following files to typescript:

* elements/diff/gr-diff-processor/gr-diff-processor.ts

Change-Id: I4aa8427d25547d2211e0dfb40cf13a53c47f4b6b
This commit is contained in:
Ben Rohlfs
2020-08-14 22:08:37 +02:00
parent 60cfc4b201
commit 32b8382c64
4 changed files with 304 additions and 272 deletions

View File

@@ -14,24 +14,44 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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 {GrDiffLine, GrDiffLineType, FILE} from '../gr-diff/gr-diff-line.js';
import {GrDiffGroup, GrDiffGroupType, hideInContextControl} from '../gr-diff/gr-diff-group.js';
import {util} from '../../../scripts/util.js';
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 {
GrDiffLine,
GrDiffLineType,
FILE,
Highlights,
} from '../gr-diff/gr-diff-line';
import {
GrDiffGroup,
GrDiffGroupType,
hideInContextControl,
} from '../gr-diff/gr-diff-group';
import {CancelablePromise, util} from '../../../scripts/util';
import {customElement, property} from '@polymer/decorators';
import {DiffContent} from '../../../types/common';
import {DiffSide} from '../gr-diff/gr-diff-utils';
const WHOLE_FILE = -1;
const DiffSide = {
LEFT: 'left',
RIGHT: 'right',
};
interface State {
lineNums: {
left: number;
right: number;
};
chunkIndex: number;
}
const DiffHighlights = {
ADDED: 'edit_b',
REMOVED: 'edit_a',
};
interface ChunkEnd {
offset: number;
keyLocation: boolean;
}
interface KeyLocations {
left: {[key: string]: boolean};
right: {[key: string]: boolean};
}
/**
* The maximum size for an addition or removal chunk before it is broken down
@@ -67,63 +87,31 @@ const MAX_GROUP_SIZE = 120;
* "expand context" widget. This may require splitting a chunk/group so
* that the part that is within the context or has comments is shown, while
* the rest is not.
*
* @extends PolymerElement
*/
class GrDiffProcessor extends GestureEventListeners(
LegacyElementMixin(
PolymerElement)) {
static get is() { return 'gr-diff-processor'; }
@customElement('gr-diff-processor')
export class GrDiffProcessor extends GestureEventListeners(
LegacyElementMixin(PolymerElement)
) {
@property({type: Number})
context = 3;
static get properties() {
return {
@property({type: Array, notify: true})
groups: GrDiffGroup[] = [];
/**
* The amount of context around collapsed groups.
*/
context: Number,
@property({type: Object})
keyLocations: KeyLocations = {left: {}, right: {}};
/**
* The array of groups output by the processor.
*/
groups: {
type: Array,
notify: true,
},
@property({type: Number})
_asyncThreshold = 64;
/**
* Locations that should not be collapsed, including the locations of
* comments.
*/
keyLocations: {
type: Object,
value() { return {left: {}, right: {}}; },
},
@property({type: Number})
_nextStepHandle: number | null = null;
/**
* The maximum number of lines to process synchronously.
*/
_asyncThreshold: {
type: Number,
value: 64,
},
@property({type: Object})
_processPromise: CancelablePromise<void> | null = null;
/** @type {?number} */
_nextStepHandle: Number,
/**
* The promise last returned from `process()` while the asynchronous
* processing is running - `null` otherwise. Provides a `cancel()`
* method that rejects it with `{isCancelled: true}`.
*
* @type {?Object}
*/
_processPromise: {
type: Object,
value: null,
},
_isScrolling: Boolean,
};
}
@property({type: Boolean})
_isScrolling?: boolean;
/** @override */
attached() {
@@ -140,22 +128,23 @@ class GrDiffProcessor extends GestureEventListeners(
_handleWindowScroll() {
this._isScrolling = true;
this.debounce('resetIsScrolling', () => {
this._isScrolling = false;
}, 50);
this.debounce(
'resetIsScrolling',
() => {
this._isScrolling = false;
},
50
);
}
/**
* Asynchronously process the diff chunks into groups. As it processes, it
* will splice groups into the `groups` property of the component.
*
* @param {!Array<!Gerrit.DiffChunk>} chunks
* @param {boolean} isBinary
*
* @return {!Promise<!Array<!Object>>} A promise that resolves with an
* array of GrDiffGroups when the diff is completely processed.
* @return A promise that resolves with an
* array of GrDiffGroups when the diff is completely processed.
*/
process(chunks, isBinary) {
process(chunks: DiffContent[], isBinary: boolean) {
// Cancel any still running process() calls, because they append to the
// same groups field.
this.cancel();
@@ -165,61 +154,65 @@ class GrDiffProcessor extends GestureEventListeners(
// If it's a binary diff, we won't be rendering hunks of text differences
// so finish processing.
if (isBinary) { return Promise.resolve(); }
if (isBinary) {
return Promise.resolve();
}
this._processPromise = util.makeCancelable(
new Promise(resolve => {
const state = {
lineNums: {left: 0, right: 0},
chunkIndex: 0,
};
new Promise(resolve => {
const state = {
lineNums: {left: 0, right: 0},
chunkIndex: 0,
};
chunks = this._splitLargeChunks(chunks);
chunks = this._splitCommonChunksWithKeyLocations(chunks);
chunks = this._splitLargeChunks(chunks);
chunks = this._splitCommonChunksWithKeyLocations(chunks);
let currentBatch = 0;
const nextStep = () => {
if (this._isScrolling) {
this._nextStepHandle = this.async(nextStep, 100);
return;
}
// If we are done, resolve the promise.
if (state.chunkIndex >= chunks.length) {
resolve();
this._nextStepHandle = null;
return;
}
let currentBatch = 0;
const nextStep = () => {
if (this._isScrolling) {
this._nextStepHandle = this.async(nextStep, 100);
return;
}
// If we are done, resolve the promise.
if (state.chunkIndex >= chunks.length) {
resolve();
this._nextStepHandle = null;
return;
}
// Process the next chunk and incorporate the result.
const stateUpdate = this._processNext(state, chunks);
for (const group of stateUpdate.groups) {
this.push('groups', group);
currentBatch += group.lines.length;
}
state.lineNums.left += stateUpdate.lineDelta.left;
state.lineNums.right += stateUpdate.lineDelta.right;
// Process the next chunk and incorporate the result.
const stateUpdate = this._processNext(state, chunks);
for (const group of stateUpdate.groups) {
this.push('groups', group);
currentBatch += group.lines.length;
}
state.lineNums.left += stateUpdate.lineDelta.left;
state.lineNums.right += stateUpdate.lineDelta.right;
// Increment the index and recurse.
state.chunkIndex = stateUpdate.newChunkIndex;
if (currentBatch >= this._asyncThreshold) {
currentBatch = 0;
this._nextStepHandle = this.async(nextStep, 1);
} else {
nextStep.call(this);
}
};
// Increment the index and recurse.
state.chunkIndex = stateUpdate.newChunkIndex;
if (currentBatch >= this._asyncThreshold) {
currentBatch = 0;
this._nextStepHandle = this.async(nextStep, 1);
} else {
nextStep.call(this);
}
};
nextStep.call(this);
}));
return this._processPromise
.finally(() => { this._processPromise = null; });
nextStep.call(this);
})
);
return this._processPromise.finally(() => {
this._processPromise = null;
});
}
/**
* Cancel any jobs that are running.
*/
cancel() {
if (this._nextStepHandle != null) {
if (this._nextStepHandle !== null) {
this.cancelAsync(this._nextStepHandle);
this._nextStepHandle = null;
}
@@ -230,14 +223,12 @@ class GrDiffProcessor extends GestureEventListeners(
/**
* Process the next uncollapsible chunk, or the next collapsible chunks.
*
* @param {!Object} state
* @param {!Array<!Object>} chunks
* @return {{lineDelta: {left: number, right: number}, groups: !Array<!Object>, newChunkIndex: number}}
*/
_processNext(state, chunks) {
const firstUncollapsibleChunkIndex =
this._firstUncollapsibleChunkIndex(chunks, state.chunkIndex);
_processNext(state: State, chunks: DiffContent[]) {
const firstUncollapsibleChunkIndex = this._firstUncollapsibleChunkIndex(
chunks,
state.chunkIndex
);
if (firstUncollapsibleChunkIndex === state.chunkIndex) {
const chunk = chunks[state.chunkIndex];
return {
@@ -245,34 +236,44 @@ class GrDiffProcessor extends GestureEventListeners(
left: this._linesLeft(chunk).length,
right: this._linesRight(chunk).length,
},
groups: [this._chunkToGroup(
chunk, state.lineNums.left + 1, state.lineNums.right + 1)],
groups: [
this._chunkToGroup(
chunk,
state.lineNums.left + 1,
state.lineNums.right + 1
),
],
newChunkIndex: state.chunkIndex + 1,
};
}
return this._processCollapsibleChunks(
state, chunks, firstUncollapsibleChunkIndex);
state,
chunks,
firstUncollapsibleChunkIndex
);
}
_linesLeft(chunk) {
_linesLeft(chunk: DiffContent) {
return chunk.ab || chunk.a || [];
}
_linesRight(chunk) {
_linesRight(chunk: DiffContent) {
return chunk.ab || chunk.b || [];
}
_firstUncollapsibleChunkIndex(chunks, offset) {
_firstUncollapsibleChunkIndex(chunks: DiffContent[], offset: number) {
let chunkIndex = offset;
while (chunkIndex < chunks.length &&
this._isCollapsibleChunk(chunks[chunkIndex])) {
while (
chunkIndex < chunks.length &&
this._isCollapsibleChunk(chunks[chunkIndex])
) {
chunkIndex++;
}
return chunkIndex;
}
_isCollapsibleChunk(chunk) {
_isCollapsibleChunk(chunk: DiffContent) {
return (chunk.ab || chunk.common) && !chunk.keyLocation;
}
@@ -280,36 +281,38 @@ class GrDiffProcessor extends GestureEventListeners(
* Process a stretch of collapsible chunks.
*
* Outputs up to three groups:
* 1) Visible context before the hidden common code, unless it's the
* very beginning of the file.
* 2) Context hidden behind a context bar, unless empty.
* 3) Visible context after the hidden common code, unless it's the very
* end of the file.
*
* @param {!Object} state
* @param {!Array<Object>} chunks
* @param {number} firstUncollapsibleChunkIndex
* @return {{lineDelta: {left: number, right: number}, groups: !Array<!Object>, newChunkIndex: number}}
* 1) Visible context before the hidden common code, unless it's the
* very beginning of the file.
* 2) Context hidden behind a context bar, unless empty.
* 3) Visible context after the hidden common code, unless it's the very
* end of the file.
*/
_processCollapsibleChunks(
state, chunks, firstUncollapsibleChunkIndex) {
state: State,
chunks: DiffContent[],
firstUncollapsibleChunkIndex: number
) {
const collapsibleChunks = chunks.slice(
state.chunkIndex, firstUncollapsibleChunkIndex);
state.chunkIndex,
firstUncollapsibleChunkIndex
);
const lineCount = collapsibleChunks.reduce(
(sum, chunk) => sum + this._commonChunkLength(chunk), 0);
(sum, chunk) => sum + this._commonChunkLength(chunk),
0
);
let groups = this._chunksToGroups(
collapsibleChunks,
state.lineNums.left + 1,
state.lineNums.right + 1);
collapsibleChunks,
state.lineNums.left + 1,
state.lineNums.right + 1
);
if (this.context !== WHOLE_FILE) {
const hiddenStart = state.chunkIndex === 0 ? 0 : this.context;
const hiddenEnd = lineCount - (
firstUncollapsibleChunkIndex === chunks.length ?
0 : this.context);
groups = hideInContextControl(
groups, hiddenStart, hiddenEnd);
const hiddenEnd =
lineCount -
(firstUncollapsibleChunkIndex === chunks.length ? 0 : this.context);
groups = hideInContextControl(groups, hiddenStart, hiddenEnd);
}
return {
@@ -322,21 +325,21 @@ class GrDiffProcessor extends GestureEventListeners(
};
}
_commonChunkLength(chunk) {
console.assert(chunk.ab || chunk.common);
_commonChunkLength(chunk: DiffContent) {
console.assert(!!chunk.ab || !!chunk.common);
console.assert(
!chunk.a || (chunk.b && chunk.a.length === chunk.b.length),
`common chunk needs same number of a and b lines: `, chunk);
!chunk.a || (!!chunk.b && chunk.a.length === chunk.b.length),
'common chunk needs same number of a and b lines: ',
chunk
);
return this._linesLeft(chunk).length;
}
/**
* @param {!Array<!Object>} chunks
* @param {number} offsetLeft
* @param {number} offsetRight
* @return {!Array<!Object>} (GrDiffGroup)
*/
_chunksToGroups(chunks, offsetLeft, offsetRight) {
_chunksToGroups(
chunks: DiffContent[],
offsetLeft: number,
offsetRight: number
): GrDiffGroup[] {
return chunks.map(chunk => {
const group = this._chunkToGroup(chunk, offsetLeft, offsetRight);
const chunkLength = this._commonChunkLength(chunk);
@@ -346,76 +349,83 @@ class GrDiffProcessor extends GestureEventListeners(
});
}
/**
* @param {!Object} chunk
* @param {number} offsetLeft
* @param {number} offsetRight
* @return {!Object} (GrDiffGroup)
*/
_chunkToGroup(chunk, offsetLeft, offsetRight) {
_chunkToGroup(
chunk: DiffContent,
offsetLeft: number,
offsetRight: number
): GrDiffGroup {
const type = chunk.ab ? GrDiffGroupType.BOTH : GrDiffGroupType.DELTA;
const lines = this._linesFromChunk(chunk, offsetLeft, offsetRight);
const group = new GrDiffGroup(type, lines);
group.keyLocation = chunk.keyLocation;
group.dueToRebase = chunk.due_to_rebase;
group.ignoredWhitespaceOnly = chunk.common;
group.keyLocation = !!chunk.keyLocation;
group.dueToRebase = !!chunk.due_to_rebase;
group.ignoredWhitespaceOnly = !!chunk.common;
return group;
}
_linesFromChunk(chunk, offsetLeft, offsetRight) {
_linesFromChunk(chunk: DiffContent, offsetLeft: number, offsetRight: number) {
if (chunk.ab) {
return chunk.ab.map((row, i) => this._lineFromRow(
GrDiffLineType.BOTH, offsetLeft, offsetRight, row, i));
return chunk.ab.map((row, i) =>
this._lineFromRow(GrDiffLineType.BOTH, offsetLeft, offsetRight, row, i)
);
}
let lines = [];
let lines: GrDiffLine[] = [];
if (chunk.a) {
// Avoiding a.push(...b) because that causes callstack overflows for
// large b, which can occur when large files are added removed.
lines = lines.concat(this._linesFromRows(
GrDiffLineType.REMOVE, chunk.a, offsetLeft,
chunk[DiffHighlights.REMOVED]));
lines = lines.concat(
this._linesFromRows(
GrDiffLineType.REMOVE,
chunk.a,
offsetLeft,
chunk.edit_a
)
);
}
if (chunk.b) {
// Avoiding a.push(...b) because that causes callstack overflows for
// large b, which can occur when large files are added removed.
lines = lines.concat(this._linesFromRows(
GrDiffLineType.ADD, chunk.b, offsetRight,
chunk[DiffHighlights.ADDED]));
lines = lines.concat(
this._linesFromRows(
GrDiffLineType.ADD,
chunk.b,
offsetRight,
chunk.edit_b
)
);
}
return lines;
}
/**
* @param {string} lineType (GrDiffLineType)
* @param {!Array<string>} rows
* @param {number} offset
* @param {?Array<!Gerrit.IntralineInfo>=} opt_intralineInfos
* @return {!Array<!Object>} (GrDiffLine)
*/
_linesFromRows(lineType, rows, offset, opt_intralineInfos) {
const grDiffHighlights = opt_intralineInfos ?
this._convertIntralineInfos(rows, opt_intralineInfos) : undefined;
return rows.map((row, i) => this._lineFromRow(
lineType, offset, offset, row, i, grDiffHighlights));
_linesFromRows(
lineType: GrDiffLineType,
rows: string[],
offset: number,
intralineInfos?: number[][]
): GrDiffLine[] {
const grDiffHighlights = intralineInfos
? this._convertIntralineInfos(rows, intralineInfos)
: undefined;
return rows.map((row, i) =>
this._lineFromRow(lineType, offset, offset, row, i, grDiffHighlights)
);
}
/**
* @param {string} type (GrDiffLineType)
* @param {number} offsetLeft
* @param {number} offsetRight
* @param {string} row
* @param {number} i
* @param {!Array<!Object>=} opt_highlights
* @return {!Object} (GrDiffLine)
*/
_lineFromRow(type, offsetLeft, offsetRight, row, i, opt_highlights) {
_lineFromRow(
type: GrDiffLineType,
offsetLeft: number,
offsetRight: number,
row: string,
i: number,
highlights: Highlights[] = []
): GrDiffLine {
const line = new GrDiffLine(type);
line.text = row;
if (type !== GrDiffLineType.ADD) line.beforeNumber = offsetLeft + i;
if (type !== GrDiffLineType.REMOVE) line.afterNumber = offsetRight + i;
if (opt_highlights) {
if (highlights) {
line.hasIntralineInfo = true;
line.highlights = opt_highlights.filter(hl => hl.contentIndex === i);
line.highlights = highlights.filter(hl => hl.contentIndex === i);
} else {
line.hasIntralineInfo = false;
}
@@ -441,10 +451,10 @@ class GrDiffProcessor extends GestureEventListeners(
* into 2 chunks, one max sized one and the rest (for reasons that are
* unclear to me).
*
* @param {!Array<!Gerrit.DiffChunk>} chunks Chunks as returned from the server
* @return {!Array<!Gerrit.DiffChunk>} Finer grained chunks.
* @param chunks Chunks as returned from the server
* @return Finer grained chunks.
*/
_splitLargeChunks(chunks) {
_splitLargeChunks(chunks: DiffContent[]): DiffContent[] {
const newChunks = [];
for (const chunk of chunks) {
@@ -476,10 +486,10 @@ class GrDiffProcessor extends GestureEventListeners(
* the selected context, treat them as separate chunks within the model so
* that the content (and context surrounding it) renders correctly.
*
* @param {!Array<!Object>} chunks DiffContents as returned from server.
* @return {!Array<!Object>} Finer grained DiffContents.
* @param chunks DiffContents as returned from server.
* @return Finer grained DiffContents.
*/
_splitCommonChunksWithKeyLocations(chunks) {
_splitCommonChunksWithKeyLocations(chunks: DiffContent[]): DiffContent[] {
const result = [];
let leftLineNum = 1;
let rightLineNum = 1;
@@ -497,32 +507,45 @@ class GrDiffProcessor extends GestureEventListeners(
continue;
}
if (chunk.common && chunk.a.length != chunk.b.length) {
if (chunk.common && chunk.a!.length !== chunk.b!.length) {
throw new Error(
'DiffContent with common=true must always have equal length');
'DiffContent with common=true must always have equal length'
);
}
const numLines = this._commonChunkLength(chunk);
const chunkEnds = this._findChunkEndsAtKeyLocations(
numLines, leftLineNum, rightLineNum);
numLines,
leftLineNum,
rightLineNum
);
leftLineNum += numLines;
rightLineNum += numLines;
if (chunk.ab) {
result.push(...this._splitAtChunkEnds(chunk.ab, chunkEnds)
.map(({lines, keyLocation}) => {
result.push(
...this._splitAtChunkEnds(chunk.ab, chunkEnds).map(
({lines, keyLocation}) => {
return {
...chunk,
ab: lines,
keyLocation,
};
}));
}
)
);
} else if (chunk.common) {
const aChunks = this._splitAtChunkEnds(chunk.a, chunkEnds);
const bChunks = this._splitAtChunkEnds(chunk.b, chunkEnds);
result.push(...aChunks.map(({lines, keyLocation}, i) => {
return {
...chunk, a: lines, b: bChunks[i].lines, keyLocation};
}));
const aChunks = this._splitAtChunkEnds(chunk.a!, chunkEnds);
const bChunks = this._splitAtChunkEnds(chunk.b!, chunkEnds);
result.push(
...aChunks.map(({lines, keyLocation}, i) => {
return {
...chunk,
a: lines,
b: bChunks[i].lines,
keyLocation,
};
})
);
}
}
@@ -530,16 +553,22 @@ class GrDiffProcessor extends GestureEventListeners(
}
/**
* @return {!Array<{offset: number, keyLocation: boolean}>} Offsets of the
* new chunk ends, including whether it's a key location.
* @return Offsets of the new chunk ends, including whether it's a key
* location.
*/
_findChunkEndsAtKeyLocations(numLines, leftOffset, rightOffset) {
_findChunkEndsAtKeyLocations(
numLines: number,
leftOffset: number,
rightOffset: number
): ChunkEnd[] {
const result = [];
let lastChunkEnd = 0;
for (let i=0; i<numLines; i++) {
for (let i = 0; i < numLines; i++) {
// If this line should not be collapsed.
if (this.keyLocations[DiffSide.LEFT][leftOffset + i] ||
this.keyLocations[DiffSide.RIGHT][rightOffset + i]) {
if (
this.keyLocations[DiffSide.LEFT][leftOffset + i] ||
this.keyLocations[DiffSide.RIGHT][rightOffset + i]
) {
// If any lines have been accumulated into the chunk leading up to
// this non-collapse line, then add them as a chunk and start a new
// one.
@@ -560,12 +589,14 @@ class GrDiffProcessor extends GestureEventListeners(
return result;
}
_splitAtChunkEnds(lines, chunkEnds) {
_splitAtChunkEnds(lines: string[], chunkEnds: ChunkEnd[]) {
const result = [];
let lastChunkEndOffset = 0;
for (const {offset, keyLocation} of chunkEnds) {
result.push(
{lines: lines.slice(lastChunkEndOffset, offset), keyLocation});
result.push({
lines: lines.slice(lastChunkEndOffset, offset),
keyLocation,
});
lastChunkEndOffset = offset;
}
return result;
@@ -574,12 +605,11 @@ class GrDiffProcessor extends GestureEventListeners(
/**
* Converts `IntralineInfo`s return by the API to `GrLineHighlights` used
* for rendering.
*
* @param {!Array<string>} rows
* @param {!Array<!Gerrit.IntralineInfo>} intralineInfos
* @return {!Array<!Object>} (Highlights[] from GrDiffLine)
*/
_convertIntralineInfos(rows, intralineInfos) {
_convertIntralineInfos(
rows: string[],
intralineInfos: number[][]
): Highlights[] {
let rowIndex = 0;
let idx = 0;
const normalized = [];
@@ -595,7 +625,7 @@ class GrDiffProcessor extends GestureEventListeners(
idx++;
j++;
}
let lineHighlight = {
let lineHighlight: Highlights = {
contentIndex: rowIndex,
startIndex: idx,
};
@@ -625,12 +655,9 @@ class GrDiffProcessor extends GestureEventListeners(
* If a group is an addition or a removal, break it down into smaller groups
* of that type using the MAX_GROUP_SIZE. If the group is a shared chunk
* or a delta it is returned as the single element of the result array.
*
* @param {!Gerrit.DiffChunk} chunk A raw chunk from a diff response.
* @return {!Array<!Array<!Object>>}
*/
_breakdownChunk(chunk) {
let key = null;
_breakdownChunk(chunk: DiffContent): DiffContent[] {
let key: 'a' | 'b' | 'ab' | null = null;
if (chunk.a && !chunk.b) {
key = 'a';
} else if (chunk.b && !chunk.a) {
@@ -639,31 +666,31 @@ class GrDiffProcessor extends GestureEventListeners(
key = 'ab';
}
if (!key) { return [chunk]; }
if (!key) {
return [chunk];
}
return this._breakdown(chunk[key], MAX_GROUP_SIZE)
.map(subChunkLines => {
const subChunk = {};
subChunk[key] = subChunkLines;
if (chunk.due_to_rebase) {
subChunk.due_to_rebase = true;
}
return subChunk;
});
return this._breakdown(chunk[key]!, MAX_GROUP_SIZE).map(subChunkLines => {
const subChunk: DiffContent = {};
subChunk[key!] = subChunkLines;
if (chunk.due_to_rebase) {
subChunk.due_to_rebase = true;
}
return subChunk;
});
}
/**
* Given an array and a size, return an array of arrays where no inner array
* is larger than that size, preserving the original order.
*
* @param {!Array<T>} array
* @param {number} size
* @return {!Array<!Array<T>>}
* @template T
*/
_breakdown(array, size) {
if (!array.length) { return []; }
if (array.length < size) { return [array]; }
_breakdown<T>(array: T[], size: number): T[][] {
if (!array.length) {
return [];
}
if (array.length < size) {
return [array];
}
const head = array.slice(0, array.length - size);
const tail = array.slice(array.length - size);
@@ -672,4 +699,8 @@ class GrDiffProcessor extends GestureEventListeners(
}
}
customElements.define(GrDiffProcessor.is, GrDiffProcessor);
declare global {
interface HTMLElementTagNameMap {
'gr-diff-processor': GrDiffProcessor;
}
}

View File

@@ -35,7 +35,7 @@ export class GrDiffLine {
hasIntralineInfo = false;
readonly highlights: Highlights[] = [];
highlights: Highlights[] = [];
text = '';

View File

@@ -15,7 +15,7 @@
* limitations under the License.
*/
interface CancelablePromise<T> extends Promise<T> {
export interface CancelablePromise<T> extends Promise<T> {
cancel(): void;
}

View File

@@ -1043,16 +1043,17 @@ export interface LabelTypeInfo {
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#diff-content
*/
export interface DiffContent {
a?: string;
b?: string;
ab?: string;
a?: string[];
b?: string[];
ab?: string[];
// The inner array is always of length two. The first entry is the 'skip'
// length. The second entry is the 'edit' length.
edit_a: number[][];
edit_b: number[][];
due_to_rebase: boolean;
edit_a?: number[][];
edit_b?: number[][];
due_to_rebase?: boolean;
skip?: string;
common?: string;
keyLocation?: boolean;
}
/**