summaryrefslogtreecommitdiffstats
path: root/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.html
diff options
context:
space:
mode:
Diffstat (limited to 'polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.html')
-rw-r--r--polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.html136
1 files changed, 115 insertions, 21 deletions
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.html b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.html
index dd18b65cbd..cc66e3bdff 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.html
@@ -1,4 +1,5 @@
<!--
+@license
Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,7 +25,7 @@ limitations under the License.
<dom-module id="gr-diff-builder">
<template>
<div class="contentWrapper">
- <content></content>
+ <slot></slot>
</div>
<gr-ranged-comment-layer
id="rangeLayer"
@@ -36,6 +37,7 @@ limitations under the License.
id="processor"
groups="{{_groups}}"></gr-diff-processor>
<gr-reporting id="reporting"></gr-reporting>
+ <gr-js-api-interface id="jsAPI"></gr-js-api-interface>
</template>
<script src="../gr-diff/gr-diff-line.js"></script>
<script src="../gr-diff/gr-diff-group.js"></script>
@@ -44,10 +46,21 @@ limitations under the License.
<script src="gr-diff-builder-side-by-side.js"></script>
<script src="gr-diff-builder-unified.js"></script>
<script src="gr-diff-builder-image.js"></script>
+ <script src="gr-diff-builder-binary.js"></script>
<script>
(function() {
'use strict';
+ const Defs = {};
+
+ /**
+ * @typedef {{
+ * number: number,
+ * leftSide: {boolean}
+ * }}
+ */
+ Defs.LineOfInterest;
+
const DiffViewMode = {
SIDE_BY_SIDE: 'SIDE_BY_SIDE',
UNIFIED: 'UNIFIED_DIFF',
@@ -63,6 +76,9 @@ limitations under the License.
// syntax highlighting for the entire file.
const SYNTAX_MAX_LINE_LENGTH = 500;
+ // Disable syntax highlighting if the overall diff is too large.
+ const SYNTAX_MAX_DIFF_LENGTH = 20000;
+
const TRAILING_WHITESPACE_PATTERN = /\s+$/;
Polymer({
@@ -89,12 +105,26 @@ limitations under the License.
properties: {
diff: Object,
+ diffPath: String,
+ changeNum: String,
+ patchNum: String,
viewMode: String,
comments: Object,
isImageDiff: Boolean,
baseImage: Object,
revisionImage: Object,
projectName: String,
+ parentIndex: Number,
+ /**
+ * @type {Defs.LineOfInterest|null}
+ */
+ lineOfInterest: Object,
+
+ /**
+ * @type {function(number, booleam, !string)}
+ */
+ createCommentFn: Function,
+
_builder: Object,
_groups: Array,
_layers: Array,
@@ -111,7 +141,7 @@ limitations under the License.
attached() {
// Setup annotation layers.
- this._layers = [
+ const layers = [
this._createTrailingWhitespaceLayer(),
this.$.syntaxLayer,
this._createIntralineLayer(),
@@ -119,6 +149,14 @@ limitations under the License.
this.$.rangeLayer,
];
+ // Get layers from plugins (if any).
+ for (const pluginLayer of this.$.jsAPI.getDiffLayers(
+ this.diffPath, this.changeNum, this.patchNum)) {
+ layers.push(pluginLayer);
+ }
+
+ this._layers = layers;
+
this.async(() => {
this._preRenderThread();
});
@@ -135,25 +173,27 @@ limitations under the License.
this._builder = this._getDiffBuilder(this.diff, comments, prefs);
this.$.processor.context = prefs.context;
- this.$.processor.keyLocations = this._getCommentLocations(comments);
+ this.$.processor.keyLocations = this._getKeyLocations(comments,
+ this.lineOfInterest);
this._clearDiffContent();
this._builder.addColumns(this.diffElement, prefs.font_size);
const reporting = this.$.reporting;
+ const isBinary = !!(this.isImageDiff || this.diff.binary);
reporting.time(TimingLabel.TOTAL);
reporting.time(TimingLabel.CONTENT);
this.dispatchEvent(new CustomEvent('render-start', {bubbles: true}));
- return this.$.processor.process(this.diff.content, this.isImageDiff)
+ return this.$.processor.process(this.diff.content, isBinary)
.then(() => {
if (this.isImageDiff) {
- this._builder.renderDiffImages();
+ this._builder.renderDiff();
}
this.dispatchEvent(new CustomEvent('render-content',
{bubbles: true}));
- if (this._anyLineTooLong()) {
+ if (this._diffTooLargeForSyntax()) {
this.$.syntaxLayer.enabled = false;
}
@@ -219,12 +259,6 @@ limitations under the License.
GrDiffBuilder.Side.RIGHT : GrDiffBuilder.Side.LEFT;
},
- createCommentThreadGroup(changeNum, patchNum, path,
- isOnParent, commentSide) {
- return this._builder.createCommentThreadGroup(changeNum, patchNum,
- path, isOnParent, commentSide);
- },
-
emitGroup(group, sectionEl) {
this._builder.emitGroup(group, sectionEl);
},
@@ -250,26 +284,58 @@ limitations under the License.
this.$.syntaxLayer.cancel();
},
+ _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}));
+ throw Error(`Invalid preference value: ${pref}`);
+ },
+
_getDiffBuilder(diff, comments, prefs) {
+ 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;
+ }
+
+ let builder = null;
+ const createFn = this.createCommentFn;
if (this.isImageDiff) {
- return new GrDiffBuilderImage(diff, comments, prefs,
- this.projectName, this.diffElement, this.baseImage,
- this.revisionImage);
+ builder = new GrDiffBuilderImage(diff, comments, createFn, prefs,
+ this.diffElement, this.baseImage, this.revisionImage);
+ } else if (diff.binary) {
+ // If the diff is binary, but not an image.
+ return new GrDiffBuilderBinary(diff, comments, prefs,
+ this.diffElement);
} else if (this.viewMode === DiffViewMode.SIDE_BY_SIDE) {
- return new GrDiffBuilderSideBySide(diff, comments, prefs,
- this.projectName, this.diffElement, this._layers);
+ builder = new GrDiffBuilderSideBySide(diff, comments, createFn,
+ prefs, this.diffElement, this._layers);
} else if (this.viewMode === DiffViewMode.UNIFIED) {
- return new GrDiffBuilderUnified(diff, comments, prefs,
- this.projectName, this.diffElement, this._layers);
+ builder = new GrDiffBuilderUnified(diff, comments, createFn, prefs,
+ 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;
},
- _getCommentLocations(comments) {
+ /**
+ * @param {!Object} comments
+ * @param {Defs.LineOfInterest|null} lineOfInterest
+ */
+ _getKeyLocations(comments, lineOfInterest) {
const result = {
left: {},
right: {},
@@ -283,6 +349,12 @@ limitations under the License.
result[side][c.line || GrDiffLine.FILE] = true;
}
}
+
+ if (lineOfInterest) {
+ const side = lineOfInterest.leftSide ? 'left' : 'right';
+ result[side][lineOfInterest.number] = true;
+ }
+
return result;
},
@@ -404,10 +476,32 @@ limitations under the License.
}, false);
},
+ _diffTooLargeForSyntax() {
+ return this._anyLineTooLong() ||
+ this.getDiffLength() > SYNTAX_MAX_DIFF_LENGTH;
+ },
+
setBlame(blame) {
if (!this._builder || !blame) { return; }
this._builder.setBlame(blame);
},
+
+ /**
+ * Get the approximate length of the diff as the sum of the maximum
+ * length of the chunks.
+ * @return {number}
+ */
+ getDiffLength() {
+ return this.diff.content.reduce((sum, sec) => {
+ if (sec.hasOwnProperty('ab')) {
+ return sum + sec.ab.length;
+ } else {
+ return sum + Math.max(
+ sec.hasOwnProperty('a') ? sec.a.length : 0,
+ sec.hasOwnProperty('b') ? sec.b.length : 0);
+ }
+ }, 0);
+ },
});
})();
</script>