Merge "Asynchronous diff rendering"

This commit is contained in:
Andrew Bonventre 2016-07-01 15:19:36 +00:00 committed by Gerrit Code Review
commit ca775c0ae5
5 changed files with 99 additions and 49 deletions

View File

@ -21,7 +21,9 @@ limitations under the License.
<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 @@ limitations under the License.
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 @@ limitations under the License.
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 @@ limitations under the License.
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 @@ limitations under the License.
}
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>

View File

@ -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');
};

View File

@ -98,28 +98,39 @@ limitations under the License.
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() {

View File

@ -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,13 +98,23 @@
// Increment the index and recurse.
state.sectionIndex++;
this.async(nextStep, 1);
this._nextStepHandle = this.async(nextStep, 1);
};
nextStep.call(this);
}.bind(this));
},
/**
* 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.
*/

View File

@ -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();