Merge "Add dropdown for selecting diff view mode to file list"

This commit is contained in:
Viktar Donich
2016-10-10 20:56:44 +00:00
committed by Gerrit Code Review
6 changed files with 134 additions and 14 deletions

View File

@@ -302,7 +302,8 @@ limitations under the License.
drafts="[[_diffDrafts]]"
revisions="[[_change.revisions]]"
projectConfig="[[_projectConfig]]"
selected-index="{{viewState.selectedFileIndex}}"></gr-file-list>
selected-index="{{viewState.selectedFileIndex}}"
diff-view-mode="{{viewState.diffMode}}"></gr-file-list>
</section>
<gr-messages-list id="messageList"
change-num="[[_changeNum]]"

View File

@@ -147,9 +147,18 @@ limitations under the License.
/
<gr-button link on-tap="_collapseAllDiffs">Hide diffs</gr-button>
/
<select
id="modeSelect"
is="gr-select"
bind-value="{{diffViewMode}}"
on-change="_handleDropdownChange">
<option value="SIDE_BY_SIDE">Side By Side</option>
<option value="UNIFIED_DIFF">Unified</option>
</select>
/
<label>
Diff against
<select on-change="_handlePatchChange">
<select id="patchChange" on-change="_handlePatchChange">
<option value="PARENT">Base</option>
<template is="dom-repeat" items="[[_computePatchSets(revisions, patchRange.*)]]" as="patchNum">
<option
@@ -210,7 +219,7 @@ limitations under the License.
path="[[file.__path]]"
prefs="[[_diffPrefs]]"
project-config="[[projectConfig]]"
view-mode="[[_userPrefs.diff_view]]"></gr-diff>
view-mode="[[_diffMode]]"></gr-diff>
</template>
<gr-button
class="fileListButton"

View File

@@ -16,6 +16,11 @@
var COMMIT_MESSAGE_PATH = '/COMMIT_MSG';
var DiffViewMode = {
SIDE_BY_SIDE: 'SIDE_BY_SIDE',
UNIFIED: 'UNIFIED_DIFF',
};
Polymer({
is: 'gr-file-list',
@@ -36,7 +41,10 @@
value: function() { return document.body; },
},
change: Object,
diffViewMode: {
type: String,
notify: true,
},
_files: {
type: Array,
observer: '_filesChanged',
@@ -67,6 +75,10 @@
type: Array,
computed: '_computeFilesShown(_numFilesShown, _files.*)',
},
_diffMode: {
type: String,
computed: '_getDiffViewMode(diffViewMode, _userPrefs)',
},
},
behaviors: [
@@ -100,8 +112,17 @@
this._diffPrefs = prefs;
}.bind(this)));
// Initialize with user's diff mode preference. Default to
// SIDE_BY_SIDE in the meantime.
var setDiffViewMode = this.diffViewMode === null;
if (setDiffViewMode) {
this.set('diffViewMode', DiffViewMode.SIDE_BY_SIDE);
}
promises.push(this._getPreferences().then(function(prefs) {
this._userPrefs = prefs;
if (setDiffViewMode) {
this.set('diffViewMode', prefs.diff_view);
}
}.bind(this)));
},
@@ -474,5 +495,32 @@
_showAllFiles: function() {
this._numFilesShown = this._files.length;
},
/**
* _getDiffViewMode: Get the diff view (side-by-side or unified) based on
* the current state.
*
* The expected behavior is to use the mode specified in the user's
* preferences unless they have manually chosen the alternative view. If the
* user navigates up to the change view, it should clear this choice and
* revert to the preference the next time a diff is viewed.
*
* Use side-by-side if the user is not logged in.
*
* @return {String}
*/
_getDiffViewMode: function() {
if (this.diffViewMode) {
return this.diffViewMode;
} else if (this._userPrefs && this._userPrefs.diff_view) {
return this.diffViewMode = this._userPrefs.diff_view;
}
return DiffViewMode.SIDE_BY_SIDE;
},
_handleDropdownChange: function(e) {
e.target.blur();
},
});
})();

View File

@@ -32,20 +32,36 @@ limitations under the License.
</template>
</test-fixture>
<test-fixture id="blank">
<template>
<div></div>
</template>
</test-fixture>
<script>
suite('gr-file-list tests', function() {
var element;
var sandbox;
setup(function() {
sandbox = sinon.sandbox.create();
stub('gr-rest-api-interface', {
getLoggedIn: function() { return Promise.resolve(true); },
getPreferences: function() { return Promise.resolve({}); },
fetchJSON: function() { return Promise.resolve({}); },
});
stub('gr-date-formatter', {
_loadTimeFormat: function() { return Promise.resolve(''); }
});
element = fixture('basic');
});
teardown(function() {
sandbox.restore();
});
test('get file list', function(done) {
var getChangeFilesStub = sinon.stub(element.$.restAPI, 'getChangeFiles',
var getChangeFilesStub = sandbox.stub(element.$.restAPI, 'getChangeFiles',
function() {
return Promise.resolve({
'/COMMIT_MSG': {lines_inserted: 9},
@@ -97,12 +113,15 @@ limitations under the License.
});
test('toggle left diff via shortcut', function() {
var toggleLeftDiffStub = sinon.stub();
sinon.stub(element, 'diffs', {get: function() {
var toggleLeftDiffStub = sandbox.stub();
// Property getter cannot be stubbed w/ sandbox due to a bug in Sinon.
// https://github.com/sinonjs/sinon/issues/781
var diffsStub = sinon.stub(element, 'diffs', {get: function() {
return [{toggleLeftDiff: toggleLeftDiffStub}];
}});
MockInteractions.pressAndReleaseKeyOn(element, 65, 'shift'); // 'A'
assert.isTrue(toggleLeftDiffStub.calledOnce);
diffsStub.restore();
});
test('keyboard shortcuts', function() {
@@ -117,7 +136,7 @@ limitations under the License.
assert.equal(element.selectedIndex, 1);
MockInteractions.pressAndReleaseKeyOn(element, 74); // 'J'
var showStub = sinon.stub(page, 'show');
var showStub = sandbox.stub(page, 'show');
assert.equal(element.selectedIndex, 2);
MockInteractions.pressAndReleaseKeyOn(element, 13); // 'ENTER'
assert(showStub.lastCall.calledWith('/c/42/2/myfile.txt'),
@@ -241,7 +260,7 @@ limitations under the License.
assert.isFalse(fileAdded.checked);
assert.isTrue(myFile.checked);
var saveStub = sinon.stub(element, '_saveReviewedState',
var saveStub = sandbox.stub(element, '_saveReviewedState',
function() { return Promise.resolve(); });
MockInteractions.tap(commitMsg);
@@ -272,7 +291,7 @@ limitations under the License.
});
test('diff against dropdown', function(done) {
var showStub = sinon.stub(page, 'show');
var showStub = sandbox.stub(page, 'show');
element.changeNum = '42';
element.patchRange = {
basePatchNum: 'PARENT',
@@ -284,7 +303,7 @@ limitations under the License.
rev3: {_number: 3},
};
flush(function() {
var selectEl = element.$$('select');
var selectEl = element.$.patchChange;
assert.equal(selectEl.value, 'PARENT');
assert.isTrue(element.$$('option[value="3"]').hasAttribute('disabled'));
selectEl.addEventListener('change', function() {
@@ -313,7 +332,7 @@ limitations under the License.
var fileRows =
Polymer.dom(element.root).querySelectorAll('.row:not(.header)');
// Prevent diff from making API call.
var diffStub = sinon.stub(element.diffs[0], 'reload');
var diffStub = sandbox.stub(element.diffs[0], 'reload');
var showHideCheck = fileRows[0].querySelector(
'input.show-hide[type="checkbox"]');
assert.isTrue(showHideCheck.checked);
@@ -339,5 +358,50 @@ limitations under the License.
element.$$('a').getAttribute('href'),
'/c/42/2/foo+bar/my%252Bfile.txt%2525');
});
test('diff mode correctly toggles the diffs', function() {
element._files = [
{__path: 'myfile.txt', __expanded: false},
];
element.changeNum = '42';
element.patchRange = {
basePatchNum: 'PARENT',
patchNum: '2',
};
element.selectedIndex = 0;
flushAsynchronousOperations();
var select = element.$.modeSelect;
var diffDisplay = element.diffs[0];
element._userPrefs = {diff_view: 'SIDE_BY_SIDE'};
assert.equal(element._getDiffViewMode(), 'SIDE_BY_SIDE');
assert.equal(element.diffViewMode, 'SIDE_BY_SIDE');
assert.equal(diffDisplay.viewMode, 'SIDE_BY_SIDE');
element.set('diffViewMode', 'UNIFIED_DIFF');
assert.equal(element._getDiffViewMode(), 'UNIFIED_DIFF');
assert.equal(diffDisplay.viewMode, 'UNIFIED_DIFF');
});
test('diff mode selector initializes from preferences', function() {
var resolvePrefs;
var prefsPromise = new Promise(function(resolve) {
resolvePrefs = resolve;
});
sandbox.stub(element, '_getPreferences').returns(prefsPromise);
// Attach a new gr-file-list so we can intercept the preferences fetch.
var view = document.createElement('gr-file-list');
var select = view.$.modeSelect;
fixture('blank').appendChild(view);
flushAsynchronousOperations();
// At this point the diff mode doesn't yet have the user's preference.
assert.equal(select.value, 'SIDE_BY_SIDE');
// Receive the overriding preference.
resolvePrefs({diff_view: 'UNIFIED'});
flushAsynchronousOperations();
assert.equal(select.value, 'SIDE_BY_SIDE');
document.getElementById('blank').restore();
});
});
</script>

View File

@@ -104,7 +104,6 @@
this._setReviewed(true);
}
}.bind(this));
if (this.changeViewState.diffMode === null) {
// Initialize with user's diff mode preference. Default to
// SIDE_BY_SIDE in the meantime.

View File

@@ -457,7 +457,6 @@ limitations under the License.
// We will simulate a user change of the selected mode.
var newMode = 'UNIFIED_DIFF';
// Set the actual value of the select, and simulate the change event.
select.value = newMode;
element.fire('change', {}, {node: select});