Merge "Asynchronous diff rendering"
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 557e7b8..832665b 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
@@ -21,7 +21,9 @@
<div class="contentWrapper">
<content></content>
</div>
- <gr-diff-processor id="processor"></gr-diff-processor>
+ <gr-diff-processor
+ id="processor"
+ groups="{{_groups}}"></gr-diff-processor>
</template>
<script src="../gr-diff/gr-diff-line.js"></script>
<script src="../gr-diff/gr-diff-group.js"></script>
@@ -53,19 +55,34 @@
baseImage: Object,
revisionImage: Object,
_builder: Object,
+ _groups: Array,
},
get diffElement() {
return this.queryEffectiveChildren('#diffTable');
},
+ observers: [
+ '_groupsChanged(_groups.splices)',
+ ],
+
render: function(diff, comments, prefs) {
+ // Stop the processor (if it's running).
+ this.$.processor.cancel();
+
this._builder = this._getDiffBuilder(diff, comments, prefs);
this.$.processor.context = prefs.context;
this.$.processor.keyLocations = this._getCommentLocations(comments);
- this.$.processor.process(diff.content)
- .then(this._renderDiff.bind(this));
+
+ this._clearDiffContent();
+
+ this.$.processor.process(diff.content).then(function() {
+ if (this.isImageDiff) {
+ this._builder.renderDiffImages();
+ }
+ this.fire('render');
+ }.bind(this));
},
getLineElByChild: function(node) {
@@ -183,10 +200,6 @@
this._builder.emitGroup(group, sectionEl);
},
- emitDiff: function() {
- this._builder.emitDiff();
- },
-
showContext: function(newGroups, sectionEl) {
var groups = this._builder.groups;
// TODO(viktard): Polyfill findIndex for IE10.
@@ -219,19 +232,6 @@
throw Error('Unsupported diff view mode: ' + this.viewMode);
},
- _renderDiff: function(groups) {
- this._builder.groups = groups;
-
- this._clearDiffContent();
- this.emitDiff();
- if (this.isImageDiff) {
- this._builder.renderDiffImages();
- }
- this.async(function() {
- this.fire('render');
- }, 1);
- },
-
_clearDiffContent: function() {
this.diffElement.innerHTML = null;
},
@@ -252,6 +252,18 @@
}
return result;
},
+
+ _groupsChanged: function(changeRecord) {
+ if (!changeRecord) { return; }
+ changeRecord.indexSplices.forEach(function(splice) {
+ var group;
+ for (var i = 0; i < splice.addedCount; i++) {
+ group = splice.object[splice.index + i];
+ this._builder.groups.push(group);
+ this._builder.emitGroup(group);
+ }
+ }, this);
+ },
});
})();
</script>
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.js b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.js
index b1256db..f68825c 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.js
@@ -59,12 +59,6 @@
var PARTIAL_CONTEXT_AMOUNT = 10;
- GrDiffBuilder.prototype.emitDiff = function() {
- for (var i = 0; i < this.groups.length; i++) {
- this.emitGroup(this.groups[i]);
- }
- };
-
GrDiffBuilder.prototype.buildSectionElement = function(group) {
throw Error('Subclasses must implement buildGroupElement');
};
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor_test.html b/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor_test.html
index 60654a8..4c5ee62 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor_test.html
@@ -98,28 +98,39 @@
assert.equal(cursorElement.diffRow, firstDeltaRow);
});
- test('diff cursor functionality (unified)', function() {
- diffElement.viewMode = 'UNIFIED_DIFF';
- cursorElement.reInitCursor();
+ suite('unified diff', function() {
- // The cursor has been initialized to the first delta.
- assert.isOk(cursorElement.diffRow);
+ setup(function(done) {
+ // We must allow the diff to re-render after setting the viewMode.
+ var renderHandler = function() {
+ diffElement.removeEventListener('render', renderHandler);
+ cursorElement.reInitCursor();
+ done();
+ };
+ diffElement.addEventListener('render', renderHandler);
+ diffElement.viewMode = 'UNIFIED_DIFF';
+ });
- var firstDeltaRow = diffElement.$$('.section.delta .diff-row');
- assert.equal(cursorElement.diffRow, firstDeltaRow);
+ test('diff cursor functionality (unified)', function() {
+ // The cursor has been initialized to the first delta.
+ assert.isOk(cursorElement.diffRow);
- firstDeltaRow = diffElement.$$('.section.delta .diff-row');
- assert.equal(cursorElement.diffRow, firstDeltaRow);
+ var firstDeltaRow = diffElement.$$('.section.delta .diff-row');
+ assert.equal(cursorElement.diffRow, firstDeltaRow);
- cursorElement.moveDown();
+ firstDeltaRow = diffElement.$$('.section.delta .diff-row');
+ assert.equal(cursorElement.diffRow, firstDeltaRow);
- assert.notEqual(cursorElement.diffRow, firstDeltaRow);
- assert.equal(cursorElement.diffRow, firstDeltaRow.nextSibling);
+ cursorElement.moveDown();
- cursorElement.moveUp();
+ assert.notEqual(cursorElement.diffRow, firstDeltaRow);
+ assert.equal(cursorElement.diffRow, firstDeltaRow.nextSibling);
- assert.notEqual(cursorElement.diffRow, firstDeltaRow.nextSibling);
- assert.equal(cursorElement.diffRow, firstDeltaRow);
+ cursorElement.moveUp();
+
+ assert.notEqual(cursorElement.diffRow, firstDeltaRow.nextSibling);
+ assert.equal(cursorElement.diffRow, firstDeltaRow);
+ });
});
test('cursor side functionality', function() {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.js b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.js
index 0a54665..f0fc649 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.js
@@ -58,6 +58,8 @@
type: Object,
value: function() { return {left: {}, right: {}}; },
},
+
+ _nextStepHandle: Number,
},
/**
@@ -82,6 +84,7 @@
// If we are done, resolve the promise.
if (state.sectionIndex >= content.length) {
resolve(this.groups);
+ this._nextStepHandle = undefined;
return;
}
@@ -95,7 +98,7 @@
// Increment the index and recurse.
state.sectionIndex++;
- this.async(nextStep, 1);
+ this._nextStepHandle = this.async(nextStep, 1);
};
nextStep.call(this);
@@ -103,6 +106,16 @@
},
/**
+ * Cancel any jobs that are running.
+ */
+ cancel: function() {
+ if (this._nextStepHandle !== undefined) {
+ this.cancelAsync(this._nextStepHandle);
+ this._nextStepHandle = undefined;
+ }
+ },
+
+ /**
* Process the next section of the diff.
*/
_processNext: function(state, content) {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.js b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.js
index 32de7d5..d4cced0 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.js
@@ -36,7 +36,10 @@
changeNum: String,
patchRange: Object,
path: String,
- prefs: Object,
+ prefs: {
+ type: Object,
+ observer: '_prefsObserver',
+ },
projectConfig: {
type: Object,
observer: '_projectConfigChanged',
@@ -57,6 +60,7 @@
viewMode: {
type: String,
value: DiffViewMode.SIDE_BY_SIDE,
+ observer: '_viewModeObserver',
},
_diff: Object,
_comments: Object,
@@ -64,10 +68,6 @@
_revisionImage: Object,
},
- observers: [
- '_prefsChanged(prefs.*, viewMode)',
- ],
-
listeners: {
'thread-discard': '_handleThreadDiscard',
'comment-discard': '_handleCommentDiscard',
@@ -303,8 +303,28 @@
});
},
- _prefsChanged: function(prefsChangeRecord) {
- var prefs = prefsChangeRecord.base;
+ _prefsObserver: function(newPrefs, oldPrefs) {
+ // Scan the preference objects one level deep to see if they differ.
+ var differ = !oldPrefs;
+ if (newPrefs && oldPrefs) {
+ for (var key in newPrefs) {
+ if (newPrefs[key] !== oldPrefs[key]) {
+ differ = true;
+ }
+ }
+ }
+
+ if (differ) {
+ this._prefsChanged(newPrefs);
+ }
+ },
+
+ _viewModeObserver: function() {
+ this._prefsChanged(this.prefs);
+ },
+
+ _prefsChanged: function(prefs) {
+ if (!prefs) { return; }
this.customStyle['--content-width'] = prefs.line_length + 'ch';
this.updateStyles();