Add support for inline diffs

Bug: Issue 4003
Change-Id: Iadb610616c29c4b308155d9f3bee3b5224096025
This commit is contained in:
Andrew Bonventre
2016-05-15 14:24:30 -04:00
parent 73d85d7545
commit e210805e53
6 changed files with 91 additions and 11 deletions

View File

@@ -277,6 +277,7 @@ limitations under the License.
comments="[[_comments]]" comments="[[_comments]]"
drafts="[[_diffDrafts]]" drafts="[[_diffDrafts]]"
revisions="[[_change.revisions]]" revisions="[[_change.revisions]]"
projectConfig="[[projectConfig]]"
selected-index="{{viewState.selectedFileIndex}}"></gr-file-list> selected-index="{{viewState.selectedFileIndex}}"></gr-file-list>
<gr-messages-list id="messageList" <gr-messages-list id="messageList"
change-num="[[_changeNum]]" change-num="[[_changeNum]]"

View File

@@ -16,6 +16,8 @@ limitations under the License.
<link rel="import" href="../../../bower_components/polymer/polymer.html"> <link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/keyboard-shortcut-behavior.html"> <link rel="import" href="../../../behaviors/keyboard-shortcut-behavior.html">
<link rel="import" href="../../diff/gr-diff/gr-diff.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html"> <link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
<dom-module id="gr-file-list"> <dom-module id="gr-file-list">
@@ -34,7 +36,7 @@ limitations under the License.
justify-content: space-between; justify-content: space-between;
margin-bottom: .5em; margin-bottom: .5em;
} }
.diffAgainst { .rightControls {
font-weight: normal; font-weight: normal;
} }
.positionIndicator, .positionIndicator,
@@ -106,6 +108,11 @@ limitations under the License.
color: #C62828; color: #C62828;
font-weight: bold; font-weight: bold;
} }
gr-diff {
box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
display: block;
margin: .25em 0 1em;
}
@media screen and (max-width: 50em) { @media screen and (max-width: 50em) {
.row[selected] { .row[selected] {
background-color: transparent; background-color: transparent;
@@ -125,7 +132,11 @@ limitations under the License.
</style> </style>
<header> <header>
<div>Files</div> <div>Files</div>
<div class="diffAgainst"> <div class="rightControls">
<gr-button link on-tap="_expandAllDiffs">Show diffs</gr-button>
/
<gr-button link on-tap="_collapseAllDiffs">Hide diffs</gr-button>
/
<label> <label>
Diff against Diff against
<select on-change="_handlePatchChange"> <select on-change="_handlePatchChange">
@@ -168,6 +179,13 @@ limitations under the License.
<span class="removed">-[[file.lines_deleted]]</span> <span class="removed">-[[file.lines_deleted]]</span>
</div> </div>
</div> </div>
<gr-diff id="diff" hidden
change-num="[[changeNum]]"
patch-range="[[patchRange]]"
path="[[file.__path]]"
prefs="[[_diffPrefs]]"
project-config="[[projectConfig]]"
view-mode="[[_userPrefs.diff_view]]"></gr-diff>
</template> </template>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface> <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
</template> </template>

View File

@@ -26,6 +26,7 @@
comments: Object, comments: Object,
drafts: Object, drafts: Object,
revisions: Object, revisions: Object,
projectConfig: Object,
selectedIndex: { selectedIndex: {
type: Number, type: Number,
notify: true, notify: true,
@@ -44,6 +45,9 @@
type: Array, type: Array,
value: function() { return []; }, value: function() { return []; },
}, },
_diffPrefs: Object,
_userPrefs: Object,
_showInlineDiffs: Boolean,
}, },
behaviors: [ behaviors: [
@@ -71,7 +75,21 @@
}); });
})); }));
return Promise.all(promises); promises.push(this._getDiffPreferences().then(function(prefs) {
this._diffPrefs = prefs;
}.bind(this)));
promises.push(this._getPreferences().then(function(prefs) {
this._userPrefs = prefs;
}.bind(this)));
},
_getDiffPreferences: function() {
return this.$.restAPI.getDiffPreferences();
},
_getPreferences: function() {
return this.$.restAPI.getPreferences();
}, },
_computePatchSets: function(revisions) { _computePatchSets: function(revisions) {
@@ -96,6 +114,28 @@
encodeURIComponent(this._patchRangeStr(this.patchRange))); encodeURIComponent(this._patchRangeStr(this.patchRange)));
}, },
_forEachDiff: function(fn) {
var diffs = Polymer.dom(this.root).querySelectorAll('gr-diff');
for (var i = 0; i < diffs.length; i++) {
fn(diffs[i]);
}
},
_expandAllDiffs: function() {
this._showInlineDiffs = true;
this._forEachDiff(function(diff) {
diff.hidden = false;
diff.reload();
});
},
_collapseAllDiffs: function() {
this._showInlineDiffs = false;
this._forEachDiff(function(diff) {
diff.hidden = true;
});
},
_computeCommentsString: function(comments, patchNum, path) { _computeCommentsString: function(comments, patchNum, path) {
return this._computeCountString(comments, patchNum, path, 'comment'); return this._computeCountString(comments, patchNum, path, 'comment');
}, },
@@ -159,6 +199,11 @@
if (this.shouldSupressKeyboardShortcut(e)) { return; } if (this.shouldSupressKeyboardShortcut(e)) { return; }
switch (e.keyCode) { switch (e.keyCode) {
case 73: // 'i'
if (!e.shiftKey) { return; }
e.preventDefault();
this._toggleInlineDiffs();
break;
case 74: // 'j' case 74: // 'j'
e.preventDefault(); e.preventDefault();
this.selectedIndex = this.selectedIndex =
@@ -184,6 +229,14 @@
} }
}, },
_toggleInlineDiffs: function() {
if (this._showInlineDiffs) {
this._collapseAllDiffs();
} else {
this._expandAllDiffs();
}
},
_openSelectedFile: function(opt_index) { _openSelectedFile: function(opt_index) {
if (opt_index != null) { if (opt_index != null) {
this.selectedIndex = opt_index; this.selectedIndex = opt_index;

View File

@@ -35,17 +35,12 @@ limitations under the License.
<script> <script>
suite('gr-file-list tests', function() { suite('gr-file-list tests', function() {
var element; var element;
var getLoggedInStub;
setup(function() { setup(function() {
element = fixture('basic'); stub('gr-rest-api-interface', {
getLoggedInStub = sinon.stub(element, '_getLoggedIn', function() { getLoggedIn: function() { return Promise.resolve(true); },
return Promise.resolve(true);
}); });
}); element = fixture('basic');
teardown(function() {
getLoggedInStub.restore();
}); });
test('get file list', function(done) { test('get file list', function(done) {
@@ -83,6 +78,11 @@ limitations under the License.
}); });
test('keyboard shortcuts', function() { test('keyboard shortcuts', function() {
var toggleInlineDiffsStub = sinon.stub(element, '_toggleInlineDiffs');
MockInteractions.pressAndReleaseKeyOn(element, 73, 'shift'); // 'I'
assert.isTrue(toggleInlineDiffsStub.calledOnce);
toggleInlineDiffsStub.restore();
element._files = [ element._files = [
{__path: '/COMMIT_MSG'}, {__path: '/COMMIT_MSG'},
{__path: 'file_added_in_rev2.txt'}, {__path: 'file_added_in_rev2.txt'},

View File

@@ -98,6 +98,13 @@ limitations under the License.
<td><span class="key">u</span></td> <td><span class="key">u</span></td>
<td>Up to change list</td> <td>Up to change list</td>
</tr> </tr>
<tr>
<td>
<span class="key modifier">Shift</span>
<span class="key">i</span>
</td>
<td>Show/hide inline diffs</td>
</tr>
</tbody> </tbody>
<!-- Diff View --> <!-- Diff View -->
<tbody hidden$="[[!_computeInView(view, 'gr-diff-view')]]" hidden> <tbody hidden$="[[!_computeInView(view, 'gr-diff-view')]]" hidden>

View File

@@ -220,6 +220,7 @@
return Promise.resolve({ return Promise.resolve({
changes_per_page: 25, changes_per_page: 25,
diff_view: 'SIDE_BY_SIDE',
}); });
}.bind(this)); }.bind(this));
}, },