Merge "Add download attribute to diff view download link"
diff --git a/Documentation/pgm-LocalUsernamesToLowerCase.txt b/Documentation/pgm-LocalUsernamesToLowerCase.txt
index e0fe1b3..03aaabf 100644
--- a/Documentation/pgm-LocalUsernamesToLowerCase.txt
+++ b/Documentation/pgm-LocalUsernamesToLowerCase.txt
@@ -7,7 +7,7 @@
== SYNOPSIS
[verse]
--
-_java_ -jar gerrit.war _LocalUsernamesToLowerCase
+_java_ -jar gerrit.war _LocalUsernamesToLowerCase_
-d <SITE_PATH>
--
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/api/ConsoleUI.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/api/ConsoleUI.java
index 2068540..444f64f 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/api/ConsoleUI.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/api/ConsoleUI.java
@@ -199,7 +199,7 @@
T def, A options, String fmt, Object... args) {
final String prompt = String.format(fmt, args);
for (; ; ) {
- String r = console.readLine("%-30s [%s/?]: ", prompt, def.toString());
+ String r = console.readLine("%-30s [%s/?]: ", prompt, def.toString().toLowerCase());
if (r == null) {
throw abort();
}
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
index 83c4d80..09e5d34 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
@@ -468,10 +468,6 @@
return;
}
- // If the patch changed, and was not set to undefined/undefined, we need
- // not reload all resources -- only the commit info and the file list.
- // If the patch range was set to undefined/undefined, the user is looking
- // to refresh the whole view.
const patchChanged = this._patchRange &&
(value.patchNum !== undefined && value.basePatchNum !== undefined) &&
(this._patchRange.patchNum !== value.patchNum ||
@@ -481,24 +477,28 @@
this._initialLoadComplete = false;
}
- const patchNum = value.patchNum ||
- this.computeLatestPatchNum(this._allPatchSets);
-
- const basePatchNum = value.basePatchNum || 'PARENT';
-
- this._patchRange = {patchNum, basePatchNum};
+ const patchRange = {
+ patchNum: value.patchNum,
+ basePatchNum: value.basePatchNum || 'PARENT',
+ };
+ this.$.fileList.collapseAllDiffs();
if (this._initialLoadComplete && patchChanged) {
+ if (patchRange.patchNum == null) {
+ patchRange.patchNum = this.computeLatestPatchNum(this._allPatchSets);
+ }
+ this._patchRange = patchRange;
this._reloadPatchNumDependentResources().then(() => {
this.$.jsAPI.handleEvent(this.$.jsAPI.EventType.SHOW_CHANGE, {
change: this._change,
- patchNum,
+ patchNum: patchRange.patchNum,
});
});
return;
}
this._changeNum = value.changeNum;
+ this._patchRange = patchRange;
this.$.relatedChanges.clear();
this._reload().then(() => {
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
index 57b3e76..59f4f10 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
@@ -672,6 +672,7 @@
'_reloadPatchNumDependentResources',
() => { return Promise.resolve(); });
const relatedClearSpy = sandbox.spy(element.$.relatedChanges, 'clear');
+ const collapseStub = sandbox.stub(element.$.fileList, 'collapseAllDiffs');
const value = {
view: Gerrit.Nav.View.CHANGE,
@@ -689,26 +690,22 @@
assert.isFalse(reloadStub.calledTwice);
assert.isTrue(reloadPatchDependentStub.calledOnce);
assert.isTrue(relatedClearSpy.calledOnce);
+ assert.isTrue(collapseStub.calledTwice);
});
test('reload entire page when patchRange doesnt change', () => {
- const mockPatchRange = {patchNum: '1337', basePatchNum: 'PARENT'};
const reloadStub = sandbox.stub(element, '_reload',
() => { return Promise.resolve(); });
- element._patchRange = {};
- sandbox.stub(element, 'computeLatestPatchNum').returns('1337');
+ const collapseStub = sandbox.stub(element.$.fileList, 'collapseAllDiffs');
const value = {
view: Gerrit.Nav.View.CHANGE,
};
element._paramsChanged(value);
assert.isTrue(reloadStub.calledOnce);
- assert.deepEqual(element._patchRange, mockPatchRange);
-
element._initialLoadComplete = true;
- element._patchRange = {};
element._paramsChanged(value);
assert.isTrue(reloadStub.calledTwice);
- assert.deepEqual(element._patchRange, mockPatchRange);
+ assert.isTrue(collapseStub.calledTwice);
});
test('include base patch when not parent', () => {
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html
index b218f02..50bf0e4 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html
@@ -208,7 +208,7 @@
if="[[_fileListActionsVisible(_shownFiles.*, _maxFilesForBulkActions)]]">
<gr-button link on-tap="_expandAllDiffs">Show diffs</gr-button>
<span class="separator">/</span>
- <gr-button link on-tap="_collapseAllDiffs">Hide diffs</gr-button>
+ <gr-button link on-tap="collapseAllDiffs">Hide diffs</gr-button>
</template>
<template is="dom-if"
if="[[!_fileListActionsVisible(_shownFiles.*, _maxFilesForBulkActions)]]">
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
index 7164a16..088adc2 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
@@ -162,7 +162,7 @@
this._loading = true;
- this._collapseAllDiffs();
+ this.collapseAllDiffs();
const promises = [];
promises.push(this._getFiles().then(files => {
@@ -304,7 +304,7 @@
this.splice(...['_expandedFilePaths', 0, 0].concat(newPaths));
},
- _collapseAllDiffs() {
+ collapseAllDiffs() {
this._showInlineDiffs = false;
this._expandedFilePaths = [];
this.$.diffCursor.handleDiffUpdate();
@@ -640,7 +640,7 @@
_toggleInlineDiffs() {
if (this._showInlineDiffs) {
- this._collapseAllDiffs();
+ this.collapseAllDiffs();
} else {
this._expandAllDiffs();
}
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
index ff62845..28bb781 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
@@ -859,6 +859,24 @@
assert.notInclude(element._expandedFilePaths, path);
});
+ test('collapseAllDiffs', () => {
+ sandbox.stub(element, '_renderInOrder')
+ .returns(Promise.resolve());
+ const cursorUpdateStub = sandbox.stub(element.$.diffCursor,
+ 'handleDiffUpdate');
+
+ const path = 'path/to/my/file.txt';
+ element.files = [{__path: path}];
+ element._expandedFilePaths = [path];
+ element._showInlineDiffs = true;
+
+ element.collapseAllDiffs();
+ flushAsynchronousOperations();
+ assert.equal(element._expandedFilePaths.length, 0);
+ assert.isFalse(element._showInlineDiffs);
+ assert.isTrue(cursorUpdateStub.calledOnce);
+ });
+
test('_expandedPathsChanged', done => {
sandbox.stub(element, '_reviewFile');
const path = 'path/to/my/file.txt';
diff --git a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js
index c7a3815..fe4f7cf 100644
--- a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js
+++ b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js
@@ -219,6 +219,12 @@
// makes assumptions that work for the GWT UI, but not PolyGerrit,
// so we'll just disable it altogether for now.
delete linkObj.target;
+
+ // Becasue the "my menu" links may be arbitrary URLs, we don't know
+ // whether they correspond to any client routes. Mark all such links as
+ // external.
+ linkObj.external = true;
+
return linkObj;
},
diff --git a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.html b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.html
index e4cc7bd..3f45bbf 100644
--- a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.html
+++ b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.html
@@ -58,9 +58,9 @@
{url: 'https://awesometown.com/#hashyhash'},
{url: 'url', target: '_blank'},
].map(element._fixMyMenuItem), [
- {url: '/q/owner:self+is:draft'},
- {url: 'https://awesometown.com/#hashyhash'},
- {url: 'url'},
+ {url: '/q/owner:self+is:draft', external: true},
+ {url: 'https://awesometown.com/#hashyhash', external: true},
+ {url: 'url', external: true},
]);
});
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-etag-decorator.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-etag-decorator.js
index 2d48d36..21aa6cb 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-etag-decorator.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-etag-decorator.js
@@ -55,7 +55,16 @@
};
GrEtagDecorator.prototype.getCachedPayload = function(url) {
- return this._payloadCache.get(url);
+ let payload = this._payloadCache.get(url);
+
+ if (typeof payload === 'object') {
+ // Note: For the sake of cache transparency, deep clone the response
+ // object so that cache hits are not equal object references. Some code
+ // expects every network response to deserialize to a fresh object.
+ payload = JSON.parse(JSON.stringify(payload));
+ }
+
+ return payload;
};
GrEtagDecorator.prototype._truncateCache = function() {
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-etag-decorator_test.html b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-etag-decorator_test.html
index 8be2352..40e639e 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-etag-decorator_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-etag-decorator_test.html
@@ -84,7 +84,7 @@
});
test('getCachedPayload', () => {
- const payload = {};
+ const payload = 'payload';
etag.collect('/foo', fakeRequest('bar'), payload);
assert.strictEqual(etag.getCachedPayload('/foo'), payload);
etag.collect('/foo', fakeRequest('bar', 304), 'garbage');
@@ -92,5 +92,25 @@
etag.collect('/foo', fakeRequest('bar', 200), 'new payload');
assert.strictEqual(etag.getCachedPayload('/foo'), 'new payload');
});
+
+ test('getCachedPayload does not preserve object equality', () => {
+ const payload = {foo: 'bar'};
+ etag.collect('/foo', fakeRequest('bar'), payload);
+ assert.deepEqual(etag.getCachedPayload('/foo'), payload);
+ assert.notStrictEqual(etag.getCachedPayload('/foo'), payload);
+ etag.collect('/foo', fakeRequest('bar', 304), {foo: 'baz'});
+ assert.deepEqual(etag.getCachedPayload('/foo'), payload);
+ assert.notStrictEqual(etag.getCachedPayload('/foo'), payload);
+ etag.collect('/foo', fakeRequest('bar', 200), {foo: 'bar baz'});
+ assert.deepEqual(etag.getCachedPayload('/foo'), {foo: 'bar baz'});
+ assert.notStrictEqual(etag.getCachedPayload('/foo'), {foo: 'bar baz'});
+ });
+
+ test('getCachedPayload clones the response deeply', () => {
+ const payload = {foo: {bar: 'baz'}};
+ etag.collect('/foo', fakeRequest('bar'), payload);
+ assert.deepEqual(etag.getCachedPayload('/foo'), payload);
+ assert.notStrictEqual(etag.getCachedPayload('/foo').foo, payload.foo);
+ });
});
</script>