Merge "Add reset button to my menu in settings"
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.js b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.js
index 1982b9a..853e316 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.js
@@ -297,7 +297,8 @@
*/
_recursivelyRemoveDeleted(obj) {
for (const k in obj) {
- if (!obj.hasOwnProperty(k)) { return; }
+ if (!obj.hasOwnProperty(k)) { continue; }
+
if (typeof obj[k] == 'object') {
if (obj[k].deleted) {
delete obj[k];
@@ -310,7 +311,7 @@
_recursivelyUpdateAddRemoveObj(obj, addRemoveObj, path = []) {
for (const k in obj) {
- if (!obj.hasOwnProperty(k)) { return; }
+ if (!obj.hasOwnProperty(k)) { continue; }
if (typeof obj[k] == 'object') {
const updatedId = obj[k].updatedId;
const ref = updatedId ? updatedId : k;
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.html b/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.html
index 8035df59..a9c3c6f 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.html
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.html
@@ -79,6 +79,7 @@
<gr-change-list
account="[[account]]"
changes="{{_changes}}"
+ preferences="[[preferences]]"
selected-index="{{viewState.selectedChangeIndex}}"
show-star="[[_loggedIn]]"></gr-change-list>
<nav class$="[[_computeNavClass(_loading)]]">
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.js b/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.js
index e4af24d..1728bc1 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.js
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.js
@@ -76,6 +76,8 @@
value() { return {}; },
},
+ preferences: Object,
+
_changesPerPage: Number,
/**
@@ -120,7 +122,7 @@
},
attached() {
- this.fire('title-change', {title: this._query});
+ this._loadPreferences();
},
_paramsChanged(value) {
@@ -158,6 +160,18 @@
});
},
+ _loadPreferences() {
+ return this.$.restAPI.getLoggedIn().then(loggedIn => {
+ if (loggedIn) {
+ this._getPreferences().then(preferences => {
+ this.preferences = preferences;
+ });
+ } else {
+ this.preferences = {};
+ }
+ });
+ },
+
_replaceCurrentLocation(url) {
window.location.replace(url);
},
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.html b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.html
index 1e0622e..d917423 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.html
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.html
@@ -24,7 +24,6 @@
<link rel="import" href="../../../styles/gr-change-list-styles.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
<link rel="import" href="../../shared/gr-cursor-manager/gr-cursor-manager.html">
-<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
<link rel="import" href="../gr-change-list-item/gr-change-list-item.html">
<link rel="import" href="../../../styles/shared-styles.html">
@@ -92,7 +91,6 @@
</template>
</template>
</table>
- <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
<gr-cursor-manager
id="cursor"
index="{{selectedIndex}}"
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.js b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.js
index 89c6577..dc41f59 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.js
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.js
@@ -94,6 +94,7 @@
},
changeTableColumns: Array,
visibleChangeTableColumns: Array,
+ preferences: Object,
},
behaviors: [
@@ -120,6 +121,7 @@
observers: [
'_sectionsChanged(sections.*)',
+ '_computePreferences(account, preferences)',
],
/**
@@ -136,38 +138,23 @@
}
},
- attached() {
- this._loadPreferences();
- },
-
_lowerCase(column) {
return column.toLowerCase();
},
- _loadPreferences() {
- return this._getLoggedIn().then(loggedIn => {
- this.changeTableColumns = this.columnNames;
+ _computePreferences(account, preferences) {
+ this.changeTableColumns = this.columnNames;
- if (!loggedIn) {
- this.showNumber = false;
- this.visibleChangeTableColumns = this.columnNames;
- return;
- }
- return this._getPreferences().then(preferences => {
- this.showNumber = !!(preferences &&
- preferences.legacycid_in_change_table);
- this.visibleChangeTableColumns = preferences.change_table.length > 0 ?
- preferences.change_table : this.columnNames;
- });
- });
- },
-
- _getLoggedIn() {
- return this.$.restAPI.getLoggedIn();
- },
-
- _getPreferences() {
- return this.$.restAPI.getPreferences();
+ if (account) {
+ this.showNumber = !!(preferences &&
+ preferences.legacycid_in_change_table);
+ this.visibleChangeTableColumns = preferences.change_table.length > 0 ?
+ preferences.change_table : this.columnNames;
+ } else {
+ // Not logged in.
+ this.showNumber = false;
+ this.visibleChangeTableColumns = this.columnNames;
+ }
},
_computeColspan(changeTableColumns, labelNames) {
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html
index e72830c..3dd8c9d 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html
@@ -52,22 +52,11 @@
teardown(() => { sandbox.restore(); });
- function stubRestAPI(preferences) {
- const loggedInPromise = Promise.resolve(preferences !== null);
- const preferencesPromise = Promise.resolve(preferences);
- stub('gr-rest-api-interface', {
- getLoggedIn: sinon.stub().returns(loggedInPromise),
- getPreferences: sinon.stub().returns(preferencesPromise),
- });
- return Promise.all([loggedInPromise, preferencesPromise]);
- }
-
suite('test show change number not logged in', () => {
setup(() => {
- return stubRestAPI(null).then(() => {
- element = fixture('basic');
- return element._loadPreferences();
- });
+ element = fixture('basic');
+ element.account = null;
+ element.preferences = null;
});
test('show number disabled', () => {
@@ -77,13 +66,14 @@
suite('test show change number preference enabled', () => {
setup(() => {
- return stubRestAPI({legacycid_in_change_table: true,
+ element = fixture('basic');
+ element.preferences = {
+ legacycid_in_change_table: true,
time_format: 'HHMM_12',
change_table: [],
- }).then(() => {
- element = fixture('basic');
- return element._loadPreferences();
- });
+ };
+ element.account = {_account_id: 1001};
+ flushAsynchronousOperations();
});
test('show number enabled', () => {
@@ -93,12 +83,14 @@
suite('test show change number preference disabled', () => {
setup(() => {
+ element = fixture('basic');
// legacycid_in_change_table is not set when false.
- return stubRestAPI({time_format: 'HHMM_12', change_table: []}).then(
- () => {
- element = fixture('basic');
- return element._loadPreferences();
- });
+ element.preferences = {
+ time_format: 'HHMM_12',
+ change_table: [],
+ };
+ element.account = {_account_id: 1001};
+ flushAsynchronousOperations();
});
test('show number disabled', () => {
@@ -275,16 +267,16 @@
suite('empty column preference', () => {
let element;
- setup(() =>
- stubRestAPI({
+ setup(() => {
+ element = fixture('basic');
+ element.account = {_account_id: 1001};
+ element.preferences = {
legacycid_in_change_table: true,
time_format: 'HHMM_12',
change_table: [],
- }).then(() => {
- element = fixture('basic');
- return element._loadPreferences();
- })
- );
+ };
+ flushAsynchronousOperations();
+ });
test('show number enabled', () => {
assert.isTrue(element.showNumber);
@@ -302,7 +294,9 @@
let element;
setup(() => {
- return stubRestAPI({
+ element = fixture('basic');
+ element.account = {_account_id: 1001};
+ element.preferences = {
legacycid_in_change_table: true,
time_format: 'HHMM_12',
change_table: [
@@ -315,10 +309,8 @@
'Updated',
'Size',
],
- }).then(() => {
- element = fixture('basic');
- return element._loadPreferences();
- });
+ };
+ flushAsynchronousOperations();
});
test('all columns visible', () => {
@@ -333,7 +325,9 @@
let element;
setup(() => {
- return stubRestAPI({
+ element = fixture('basic');
+ element.account = {_account_id: 1001};
+ element.preferences = {
legacycid_in_change_table: true,
time_format: 'HHMM_12',
change_table: [
@@ -345,10 +339,8 @@
'Updated',
'Size',
],
- }).then(() => {
- element = fixture('basic');
- return element._loadPreferences();
- });
+ };
+ flushAsynchronousOperations();
});
test('all columns except project visible', () => {
@@ -369,16 +361,16 @@
/* This would only exist if somebody manually updated the config
file. */
setup(() => {
- return stubRestAPI({
+ element = fixture('basic');
+ element.account = {_account_id: 1001};
+ element.preferences = {
legacycid_in_change_table: true,
time_format: 'HHMM_12',
change_table: [
'Bad',
],
- }).then(() => {
- element = fixture('basic');
- return element._loadPreferences();
- });
+ };
+ flushAsynchronousOperations();
});
test('bad column does not exist', () => {
diff --git a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.html b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.html
index 33cd39e..d97e7f4 100644
--- a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.html
+++ b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.html
@@ -57,6 +57,7 @@
show-star
show-reviewed-state
account="[[account]]"
+ preferences="[[preferences]]"
selected-index="{{viewState.selectedChangeIndex}}"
sections="[[_results]]"></gr-change-list>
</div>
diff --git a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js
index 6be2331..b6e06d8 100644
--- a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js
+++ b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js
@@ -77,6 +77,7 @@
type: Object,
value: null,
},
+ preferences: Object,
/** @type {{ selectedChangeIndex: number }} */
viewState: Object,
@@ -116,6 +117,22 @@
);
},
+ attached() {
+ this._loadPreferences();
+ },
+
+ _loadPreferences() {
+ return this.$.restAPI.getLoggedIn().then(loggedIn => {
+ if (loggedIn) {
+ this.$.restAPI.getPreferences().then(preferences => {
+ this.preferences = preferences;
+ });
+ } else {
+ this.preferences = {};
+ }
+ });
+ },
+
_getProjectDashboard(project, dashboard) {
const errFn = response => {
this.fire('page-error', {response});
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
index ff4562b..1827ef6 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
@@ -250,12 +250,8 @@
max-width: 15rem;
--paper-tab-ink: var(--color-link);
}
- #threadList,
- #messageList {
- display: none;
- }
- #threadList.visible,
- #messageList.visible {
+ gr-thread-list,
+ gr-messages-list {
display: block;
}
#includedInOverlay {
@@ -562,24 +558,26 @@
<span>Comment Threads</span></gr-tooltip-content>
</paper-tab>
</paper-tabs>
- <gr-messages-list id="messageList"
- class$="hideOnMobileOverlay [[_computeShowMessages(_showMessagesView)]]"
- change-num="[[_changeNum]]"
- labels="[[_change.labels]]"
- messages="[[_change.messages]]"
- reviewer-updates="[[_change.reviewer_updates]]"
- change-comments="[[_changeComments]]"
- project-name="[[_change.project]]"
- show-reply-buttons="[[_loggedIn]]"
- on-reply="_handleMessageReply"></gr-messages-list>
- <gr-thread-list
- id="threadList"
- threads="[[_commentThreads]]"
- change="[[_change]]"
- change-num="[[_changeNum]]"
- class$="[[_computeShowThreads(_showMessagesView)]]"
- logged-in="[[_loggedIn]]"
- on-thread-list-modified="_handleReloadDiffComments"></gr-thread-list>
+ <template is="dom-if" if="[[_showMessagesView]]">
+ <gr-messages-list
+ class="hideOnMobileOverlay"
+ change-num="[[_changeNum]]"
+ labels="[[_change.labels]]"
+ messages="[[_change.messages]]"
+ reviewer-updates="[[_change.reviewer_updates]]"
+ change-comments="[[_changeComments]]"
+ project-name="[[_change.project]]"
+ show-reply-buttons="[[_loggedIn]]"
+ on-reply="_handleMessageReply"></gr-messages-list>
+ </template>
+ <template is="dom-if" if="[[!_showMessagesView]]">
+ <gr-thread-list
+ threads="[[_commentThreads]]"
+ change="[[_change]]"
+ change-num="[[_changeNum]]"
+ logged-in="[[_loggedIn]]"
+ on-thread-list-modified="_handleReloadDiffComments"></gr-thread-list>
+ </template>
</div>
<gr-overlay id="downloadOverlay" with-backdrop>
<gr-download-dialog
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 ebce594..e999911 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
@@ -308,6 +308,14 @@
}
},
+ get messagesList() {
+ return this.$$('gr-messages-list');
+ },
+
+ get threadList() {
+ return this.$$('gr-thread-list');
+ },
+
/**
* @param {boolean=} opt_reset
*/
@@ -341,14 +349,6 @@
this._showMessagesView = this.$.commentTabs.selected === 0;
},
- _computeShowMessages(showSection) {
- return showSection ? 'visible' : '';
- },
-
- _computeShowThreads(showSection) {
- return !showSection ? 'visible' : '';
- },
-
_handleEditCommitMessage(e) {
this._editingCommitMessage = true;
this.$.commitMessageEditor.focusTextarea();
@@ -706,7 +706,7 @@
_maybeScrollToMessage(hash) {
const msgPrefix = '#message-';
if (hash.startsWith(msgPrefix)) {
- this.$.messageList.scrollToMessage(hash.substr(msgPrefix.length));
+ this.messagesList.scrollToMessage(hash.substr(msgPrefix.length));
}
},
@@ -937,7 +937,7 @@
this.modifierPressed(e)) { return; }
e.preventDefault();
- this.$.messageList.handleExpandCollapse(true);
+ this.messagesList.handleExpandCollapse(true);
},
_handleZKey(e) {
@@ -945,7 +945,7 @@
this.modifierPressed(e)) { return; }
e.preventDefault();
- this.$.messageList.handleExpandCollapse(false);
+ this.messagesList.handleExpandCollapse(false);
},
_handleCommaKey(e) {
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 4d33fab..f377277 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
@@ -205,18 +205,24 @@
assert.isTrue(handleCollapse.called);
});
- test('X should expand all messages', () => {
- const handleExpand =
- sandbox.stub(element.$.messageList, 'handleExpandCollapse');
- MockInteractions.pressAndReleaseKeyOn(element, 88, null, 'x');
- assert(handleExpand.calledWith(true));
+ test('X should expand all messages', done => {
+ flush(() => {
+ const handleExpand = sandbox.stub(element.messagesList,
+ 'handleExpandCollapse');
+ MockInteractions.pressAndReleaseKeyOn(element, 88, null, 'x');
+ assert(handleExpand.calledWith(true));
+ done();
+ });
});
- test('Z should collapse all messages', () => {
- const handleExpand =
- sandbox.stub(element.$.messageList, 'handleExpandCollapse');
- MockInteractions.pressAndReleaseKeyOn(element, 90, null, 'z');
- assert(handleExpand.calledWith(false));
+ test('Z should collapse all messages', done => {
+ flush(() => {
+ const handleExpand = sandbox.stub(element.messagesList,
+ 'handleExpandCollapse');
+ MockInteractions.pressAndReleaseKeyOn(element, 90, null, 'z');
+ assert(handleExpand.calledWith(false));
+ done();
+ });
});
test('shift + R should fetch and navigate to the latest patch set',
@@ -295,10 +301,7 @@
};
setup(() => {
reloadStub = sandbox.stub(element.$.commentAPI, 'reloadDrafts')
- .returns(Promise.resolve({
- drafts,
- }
- ));
+ .returns(Promise.resolve({drafts}));
});
test('drafts are reloaded when reload-drafts fired', done => {
@@ -327,14 +330,13 @@
test('thread list modified', () => {
sandbox.spy(element, '_handleReloadDiffComments');
- return element._reloadComments().then(() => {
- element.$.threadList.fire('thread-list-modified');
- assert.isTrue(element._handleReloadDiffComments.called);
- });
- });
+ element._showMessagesView = false;
+ flushAsynchronousOperations();
- test('thread list modified', () => {
return element._reloadComments().then(() => {
+ element.threadList.fire('thread-list-modified');
+ assert.isTrue(element._handleReloadDiffComments.called);
+
let draftStub = sinon.stub(element._changeComments, 'computeDraftCount')
.returns(1);
assert.equal(element._computeTotalCommentCounts(5,
@@ -395,27 +397,18 @@
// Wait for tab to get selected
flush(() => {
assert.equal(element.$.commentTabs.selected, 0);
- assert.notEqual(getComputedStyle(element.$.messageList).display,
- 'none');
- assert.equal(getComputedStyle(element.$.threadList).display, 'none');
-
+ assert.isTrue(element._showMessagesView);
// Switch to comment thread tab
MockInteractions.tap(element.$$('paper-tab.commentThreads'));
assert.equal(element.$.commentTabs.selected, 1);
- assert.equal(getComputedStyle(element.$.messageList).display,
- 'none');
- assert.notEqual(getComputedStyle(element.$.threadList).display,
- 'none');
+ assert.isFalse(element._showMessagesView);
// When the change is partially reloaded (ex: Shift+R), the content
// is swapped out before the tab, so messages list will display even
// though the tab for comment threads is still temporarily selected.
element._paramsChanged(element.params);
assert.equal(element.$.commentTabs.selected, 1);
- assert.notEqual(getComputedStyle(element.$.messageList).display,
- 'none');
- assert.equal(getComputedStyle(element.$.threadList).display,
- 'none');
+ assert.isTrue(element._showMessagesView);
done();
});
});
@@ -1021,13 +1014,17 @@
});
test('_openReplyDialog called with `BODY` when coming from message reply' +
- 'event', () => {
- const openStub = sandbox.stub(element, '_openReplyDialog');
- element.$.messageList.fire('reply', {message: {message: 'text'}});
- assert(openStub.lastCall.calledWithExactly(
- element.$.replyDialog.FocusTarget.BODY),
- '_openReplyDialog should have been passed BODY');
- assert.equal(openStub.callCount, 1);
+ 'event', done => {
+ flush(() => {
+ const openStub = sandbox.stub(element, '_openReplyDialog');
+ element.messagesList.fire('reply',
+ {message: {message: 'text'}});
+ assert(openStub.lastCall.calledWithExactly(
+ element.$.replyDialog.FocusTarget.BODY),
+ '_openReplyDialog should have been passed BODY');
+ assert.equal(openStub.callCount, 1);
+ done();
+ });
});
test('reply dialog focus can be controlled', () => {
@@ -1437,18 +1434,20 @@
assert.equal(element._computeHeaderClass(true), 'header editMode');
});
- test('_maybeScrollToMessage', () => {
- const scrollStub = sandbox.stub(element.$.messageList, 'scrollToMessage');
+ test('_maybeScrollToMessage', done => {
+ flush(() => {
+ const scrollStub = sandbox.stub(element.messagesList,
+ 'scrollToMessage');
- element._maybeScrollToMessage('');
- assert.isFalse(scrollStub.called);
-
- element._maybeScrollToMessage('message');
- assert.isFalse(scrollStub.called);
-
- element._maybeScrollToMessage('#message-TEST');
- assert.isTrue(scrollStub.called);
- assert.equal(scrollStub.lastCall.args[0], 'TEST');
+ element._maybeScrollToMessage('');
+ assert.isFalse(scrollStub.called);
+ element._maybeScrollToMessage('message');
+ assert.isFalse(scrollStub.called);
+ element._maybeScrollToMessage('#message-TEST');
+ assert.isTrue(scrollStub.called);
+ assert.equal(scrollStub.lastCall.args[0], 'TEST');
+ done();
+ });
});
test('topic update reloads related changes', () => {
@@ -1602,8 +1601,7 @@
setup(() => {
fireEdit = () => {
- element.$.actions
- .dispatchEvent(new CustomEvent('edit-tap', {bubbles: false}));
+ element.$.actions.dispatchEvent(new CustomEvent('edit-tap'));
};
sandbox.stub(element.$.metadata, '_computeShowLabelStatus');
sandbox.stub(element.$.metadata, '_computeLabelNames');
diff --git a/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list.html b/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list.html
index 4b36607..c3e65ab 100644
--- a/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list.html
+++ b/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list.html
@@ -80,7 +80,12 @@
<template is="dom-if" if="[[!threads.length]]">
There are no inline comment threads on any diff for this change.
</template>
- <template is="dom-repeat" items="[[_sortedThreads]]" as="thread">
+ <template
+ is="dom-repeat"
+ items="[[_sortedThreads]]"
+ as="thread"
+ initial-count="5"
+ target-framerate="60">
<gr-diff-comment-thread
show-file-path
change-num="[[changeNum]]"
diff --git a/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting.html b/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting.html
index 3181a0b..2970a26 100644
--- a/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting.html
+++ b/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting.html
@@ -15,7 +15,6 @@
limitations under the License.
-->
-<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html">
diff --git a/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting.js b/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting.js
index 49edbd5..8ab5adf3 100644
--- a/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting.js
+++ b/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting.js
@@ -40,9 +40,6 @@
const INTERACTION_TYPE = 'interaction';
- const CHANGE_VIEW_REGEX = /^\/c\/\d+\/?\d*$/;
- const DIFF_VIEW_REGEX = /^\/c\/\d+\/\d+\/.+$/;
-
const pending = [];
const onError = function(oldOnError, msg, url, line, column, error) {
@@ -89,10 +86,6 @@
},
},
- behaviors: [
- Gerrit.BaseUrlBehavior,
- ],
-
get performanceTiming() {
return window.performance.timing;
},
@@ -164,19 +157,7 @@
}
},
- locationChanged() {
- let page = '';
- const pathname = this._getPathname();
- if (pathname.startsWith('/q/')) {
- page = this.getBaseUrl() + '/q/';
- } else if (pathname.match(CHANGE_VIEW_REGEX)) { // change view
- page = this.getBaseUrl() + '/c/';
- } else if (pathname.match(DIFF_VIEW_REGEX)) { // diff view
- page = this.getBaseUrl() + '/c//COMMIT_MSG';
- } else {
- // Ignore other page changes.
- return;
- }
+ locationChanged(page) {
this.reporter(
NAVIGATION.TYPE, NAVIGATION.CATEGORY, NAVIGATION.PAGE, page);
},
@@ -185,10 +166,6 @@
this.timeEnd('PluginsLoaded');
},
- _getPathname() {
- return '/' + window.location.pathname.substring(this.getBaseUrl().length);
- },
-
/**
* Reset named timer.
*/
diff --git a/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting_test.html b/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting_test.html
index c3208ab..62ef2d6 100644
--- a/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting_test.html
+++ b/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting_test.html
@@ -135,43 +135,10 @@
});
});
- suite('location changed', () => {
- let pathnameStub;
- setup(() => {
- pathnameStub = sinon.stub(element, '_getPathname');
- });
-
- teardown(() => {
- pathnameStub.restore();
- });
-
- test('search', () => {
- pathnameStub.returns('/q/foo');
- element.locationChanged();
- assert.isTrue(element.reporter.calledWithExactly(
- 'nav-report', 'Location Changed', 'Page', '/q/'));
- });
-
- test('change view', () => {
- pathnameStub.returns('/c/42/');
- element.locationChanged();
- assert.isTrue(element.reporter.calledWithExactly(
- 'nav-report', 'Location Changed', 'Page', '/c/'));
- });
-
- test('change view', () => {
- pathnameStub.returns('/c/41/2');
- element.locationChanged();
- assert.isTrue(element.reporter.calledWithExactly(
- 'nav-report', 'Location Changed', 'Page', '/c/'));
- });
-
- test('diff view', () => {
- pathnameStub.returns('/c/41/2/file.txt');
- element.locationChanged();
- assert.isTrue(element.reporter.calledWithExactly(
- 'nav-report', 'Location Changed', 'Page', '/c//COMMIT_MSG'));
- });
+ test('search', () => {
+ element.locationChanged('_handleSomeRoute');
+ assert.isTrue(element.reporter.calledWithExactly(
+ 'nav-report', 'Location Changed', 'Page', '_handleSomeRoute'));
});
suite('exception logging', () => {
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router.html b/polygerrit-ui/app/elements/core/gr-router/gr-router.html
index 0d05bf1..7186b52 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router.html
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router.html
@@ -26,6 +26,7 @@
<dom-module id="gr-router">
<template>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
+ <gr-reporting id="reporting"></gr-reporting>
</template>
<script src="../../../bower_components/page/page.js"></script>
<script src="gr-router.js"></script>
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router.js b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
index 4ee00fb..f6079a5 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router.js
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
@@ -178,21 +178,18 @@
console.log('No gr-app found (running tests)');
}
- let _reporting;
- function getReporting() {
- if (!_reporting) {
- _reporting = document.createElement('gr-reporting');
- }
- return _reporting;
- }
+ // Setup listeners outside of the router component initialization.
+ (function() {
+ const reporting = document.createElement('gr-reporting');
- document.onload = function() {
- getReporting().pageLoaded();
- };
+ document.onload = function() {
+ reporting.pageLoaded();
+ };
- window.addEventListener('WebComponentsReady', () => {
- getReporting().timeEnd('WebComponentsReady');
- });
+ window.addEventListener('WebComponentsReady', () => {
+ reporting.timeEnd('WebComponentsReady');
+ });
+ })();
Polymer({
is: 'gr-router',
@@ -643,6 +640,7 @@
return;
}
page(pattern, this._loadUserMiddleware.bind(this), data => {
+ this.$.reporting.locationChanged(handlerName);
const promise = opt_authRedirect ?
this._redirectIfNotLoggedIn(data) : Promise.resolve();
promise.then(() => { this[handlerName](data); });
@@ -655,8 +653,6 @@
page.base(base);
}
- const reporting = getReporting();
-
Gerrit.Nav.setup(
url => { page.show(url); },
this._generateUrl.bind(this),
@@ -682,7 +678,6 @@
hash: window.location.hash,
pathname: window.location.pathname,
});
- reporting.locationChanged();
}, 1);
next();
});
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.html b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.html
index b6409792..f1bce4c 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.html
@@ -273,14 +273,16 @@
[[comment.robot_id]]
</div>
</template>
- <gr-textarea
- id="editTextarea"
- class="editMessage"
- autocomplete="on"
- monospace
- disabled="{{disabled}}"
- rows="4"
- text="{{_messageText}}"></gr-textarea>
+ <template is="dom-if" if="[[editing]]">
+ <gr-textarea
+ id="editTextarea"
+ class="editMessage"
+ autocomplete="on"
+ monospace
+ disabled="{{disabled}}"
+ rows="4"
+ text="{{_messageText}}"></gr-textarea>
+ </template>
<!--The message class is needed to ensure selectability from
gr-diff-selection.-->
<gr-formatted-text class="message"
@@ -339,27 +341,29 @@
</div>
</div>
</div>
- <gr-overlay id="confirmDeleteOverlay" with-backdrop>
- <gr-confirm-delete-comment-dialog id="confirmDeleteComment"
- on-confirm="_handleConfirmDeleteComment"
- on-cancel="_handleCancelDeleteComment">
- </gr-confirm-delete-comment-dialog>
- </gr-overlay>
- <gr-overlay id="confirmDiscardOverlay" with-backdrop>
- <gr-confirm-dialog
- id="confirmDiscardDialog"
- confirm-label="Discard"
- confirm-on-enter
- on-confirm="_handleConfirmDiscard"
- on-cancel="_closeConfirmDiscardOverlay">
- <div class="header" slot="header">
- Discard comment
- </div>
- <div class="main" slot="main">
- Are you sure you want to discard this draft comment?
- </div>
- </gr-confirm-dialog>
- </gr-overlay>
+ <template is="dom-if" if="[[_enableOverlay]]">
+ <gr-overlay id="confirmDeleteOverlay" with-backdrop>
+ <gr-confirm-delete-comment-dialog id="confirmDeleteComment"
+ on-confirm="_handleConfirmDeleteComment"
+ on-cancel="_handleCancelDeleteComment">
+ </gr-confirm-delete-comment-dialog>
+ </gr-overlay>
+ <gr-overlay id="confirmDiscardOverlay" with-backdrop>
+ <gr-confirm-dialog
+ id="confirmDiscardDialog"
+ confirm-label="Discard"
+ confirm-on-enter
+ on-confirm="_handleConfirmDiscard"
+ on-cancel="_closeConfirmDiscardOverlay">
+ <div class="header" slot="header">
+ Discard comment
+ </div>
+ <div class="main" slot="main">
+ Are you sure you want to discard this draft comment?
+ </div>
+ </gr-confirm-dialog>
+ </gr-overlay>
+ </template>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
<gr-storage id="storage"></gr-storage>
</template>
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.js b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.js
index 9e5ae87..8612011 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.js
@@ -124,6 +124,22 @@
},
_savingMessage: String,
+
+ _enableOverlay: {
+ type: Boolean,
+ value: false,
+ },
+
+ /**
+ * Property for storing references to overlay elements. When the overlays
+ * are moved to Gerrit.getRootElement() to be shown they are no-longer
+ * children, so they can't be queried along the tree, so they are stored
+ * here.
+ */
+ _overlays: {
+ type: Object,
+ value: () => ({}),
+ },
},
observers: [
@@ -155,7 +171,31 @@
detached() {
this.cancelDebouncer('fire-update');
- this.$.editTextarea.closeDropdown();
+ if (this.textarea) {
+ this.textarea.closeDropdown();
+ }
+ },
+
+ get textarea() {
+ return this.$$('#editTextarea');
+ },
+
+ get confirmDeleteOverlay() {
+ if (!this._overlays.confirmDelete) {
+ this._enableOverlay = true;
+ Polymer.dom.flush();
+ this._overlays.confirmDelete = this.$$('#confirmDeleteOverlay');
+ }
+ return this._overlays.confirmDelete;
+ },
+
+ get confirmDiscardOverlay() {
+ if (!this._overlays.confirmDiscard) {
+ this._enableOverlay = true;
+ Polymer.dom.flush();
+ this._overlays.confirmDiscard = this.$$('#confirmDiscardOverlay');
+ }
+ return this._overlays.confirmDiscard;
},
_computeShowHideText(collapsed) {
@@ -272,9 +312,6 @@
_editingChanged(editing, previousValue) {
this.$.container.classList.toggle('editing', editing);
- if (editing) {
- this.$.editTextarea.putCursorAtEnd();
- }
if (this.comment && this.comment.id) {
this.$$('.cancel').hidden = !editing;
}
@@ -285,6 +322,12 @@
// To prevent event firing on comment creation.
this._fireUpdate();
}
+ if (editing) {
+ this.async(() => {
+ Polymer.dom.flush();
+ this.textarea.putCursorAtEnd();
+ }, 1);
+ }
},
_computeLinkToComment(comment) {
@@ -437,7 +480,7 @@
this._discardDraft();
return;
}
- this._openOverlay(this.$.confirmDiscardOverlay);
+ this._openOverlay(this.confirmDiscardOverlay);
},
_handleConfirmDiscard(e) {
@@ -475,7 +518,7 @@
},
_closeConfirmDiscardOverlay() {
- this._closeOverlay(this.$.confirmDiscardOverlay);
+ this._closeOverlay(this.confirmDiscardOverlay);
},
_getSavingMessage(numPending) {
@@ -593,11 +636,11 @@
},
_handleCommentDelete() {
- this._openOverlay(this.$.confirmDeleteOverlay);
+ this._openOverlay(this.confirmDeleteOverlay);
},
_handleCancelDeleteComment() {
- this._closeOverlay(this.$.confirmDeleteOverlay);
+ this._closeOverlay(this.confirmDeleteOverlay);
},
_openOverlay(overlay) {
@@ -613,9 +656,11 @@
},
_handleConfirmDeleteComment() {
+ const dialog =
+ this.confirmDeleteOverlay.querySelector('#confirmDeleteComment');
this.$.restAPI.deleteComment(
- this.changeNum, this.patchNum, this.comment.id,
- this.$.confirmDeleteComment.message).then(newComment => {
+ this.changeNum, this.patchNum, this.comment.id, dialog.message)
+ .then(newComment => {
this._handleCancelDeleteComment();
this.comment = newComment;
});
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment_test.html b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment_test.html
index d124764..5b43430 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment_test.html
@@ -80,8 +80,7 @@
'gr-formatted-text is not visible');
assert.isFalse(isVisible(element.$$('.actions')),
'actions are not visible');
- assert.isFalse(isVisible(element.$$('gr-textarea')),
- 'textarea is not visible');
+ assert.isNotOk(element.textarea, 'textarea is not visible');
// The header middle content is only visible when comments are collapsed.
// It shows the message in a condensed way, and limits to a single line.
@@ -95,8 +94,7 @@
'gr-formatted-text is visible');
assert.isTrue(isVisible(element.$$('.actions')),
'actions are visible');
- assert.isFalse(isVisible(element.$$('gr-textarea')),
- 'textarea is not visible');
+ assert.isNotOk(element.textarea, 'textarea is not visible');
assert.isFalse(isVisible(element.$$('.collapsedContent')),
'header middle content is not visible');
});
@@ -167,8 +165,7 @@
'gr-formatted-text is not visible');
assert.isFalse(isVisible(element.$$('.actions')),
'actions are not visible');
- assert.isFalse(isVisible(element.$$('gr-textarea')),
- 'textarea is not visible');
+ assert.isNotOk(element.textarea, 'textarea is not visible');
assert.isTrue(isVisible(element.$$('.collapsedContent')),
'header middle content is visible');
@@ -178,8 +175,7 @@
'gr-formatted-text is visible');
assert.isTrue(isVisible(element.$$('.actions')),
'actions are visible');
- assert.isFalse(isVisible(element.$$('gr-textarea')),
- 'textarea is not visible');
+ assert.isNotOk(element.textarea, 'textarea is not visible');
assert.isFalse(isVisible(element.$$('.collapsedContent')),
'header middle content is is not visible');
});
@@ -201,50 +197,50 @@
test('esc closes comment when text is empty', () => {
MockInteractions.pressAndReleaseKeyOn(
- element.$.editTextarea, 27); // esc
+ element.textarea, 27); // esc
assert.isTrue(element._handleCancel.called);
});
test('ctrl+enter does not save', () => {
MockInteractions.pressAndReleaseKeyOn(
- element.$.editTextarea, 13, 'ctrl'); // ctrl + enter
+ element.textarea, 13, 'ctrl'); // ctrl + enter
assert.isFalse(element._handleSave.called);
});
test('meta+enter does not save', () => {
MockInteractions.pressAndReleaseKeyOn(
- element.$.editTextarea, 13, 'meta'); // meta + enter
+ element.textarea, 13, 'meta'); // meta + enter
assert.isFalse(element._handleSave.called);
});
test('ctrl+s does not save', () => {
MockInteractions.pressAndReleaseKeyOn(
- element.$.editTextarea, 83, 'ctrl'); // ctrl + s
+ element.textarea, 83, 'ctrl'); // ctrl + s
assert.isFalse(element._handleSave.called);
});
});
test('esc does not close comment that has content', () => {
MockInteractions.pressAndReleaseKeyOn(
- element.$.editTextarea, 27); // esc
+ element.textarea, 27); // esc
assert.isFalse(element._handleCancel.called);
});
test('ctrl+enter saves', () => {
MockInteractions.pressAndReleaseKeyOn(
- element.$.editTextarea, 13, 'ctrl'); // ctrl + enter
+ element.textarea, 13, 'ctrl'); // ctrl + enter
assert.isTrue(element._handleSave.called);
});
test('meta+enter saves', () => {
MockInteractions.pressAndReleaseKeyOn(
- element.$.editTextarea, 13, 'meta'); // meta + enter
+ element.textarea, 13, 'meta'); // meta + enter
assert.isTrue(element._handleSave.called);
});
test('ctrl+s saves', () => {
MockInteractions.pressAndReleaseKeyOn(
- element.$.editTextarea, 83, 'ctrl'); // ctrl + s
+ element.textarea, 83, 'ctrl'); // ctrl + s
assert.isTrue(element._handleSave.called);
});
});
@@ -264,7 +260,7 @@
test('delete comment', done => {
sandbox.stub(
element.$.restAPI, 'deleteComment').returns(Promise.resolve({}));
- sandbox.spy(element.$.confirmDeleteOverlay, 'open');
+ sandbox.spy(element.confirmDeleteOverlay, 'open');
element.changeNum = 42;
element.patchNum = 0xDEADBEEF;
element._isAdmin = true;
@@ -272,8 +268,10 @@
.classList.contains('showDeleteButtons'));
MockInteractions.tap(element.$$('.action.delete'));
flush(() => {
- element.$.confirmDeleteOverlay.open.lastCall.returnValue.then(() => {
- element.$.confirmDeleteComment.message = 'removal reason';
+ element.confirmDeleteOverlay.open.lastCall.returnValue.then(() => {
+ const dialog =
+ this.confirmDeleteOverlay.querySelector('#confirmDeleteComment');
+ dialog.message = 'removal reason';
element._handleConfirmDeleteComment();
assert.isTrue(element.$.restAPI.deleteComment.calledWith(
42, 0xDEADBEEF, 'baf0414d_60047215', 'removal reason'));
@@ -351,6 +349,7 @@
assert.isTrue(element.$$('.robotActions').hasAttribute('hidden'));
element.editing = true;
+ flushAsynchronousOperations();
assert.isFalse(isVisible(element.$$('.edit')), 'edit is not visible');
assert.isFalse(isVisible(element.$$('.discard')), 'discard not visible');
assert.isTrue(isVisible(element.$$('.save')), 'save is visible');
@@ -361,6 +360,7 @@
element.draft = false;
element.editing = false;
+ flushAsynchronousOperations();
assert.isFalse(isVisible(element.$$('.edit')), 'edit is not visible');
assert.isFalse(isVisible(element.$$('.discard')),
'discard is not visible');
@@ -372,6 +372,7 @@
element.comment.id = 'foo';
element.draft = true;
element.editing = true;
+ flushAsynchronousOperations();
assert.isTrue(isVisible(element.$$('.cancel')), 'cancel is visible');
assert.isFalse(element.$$('.humanActions').hasAttribute('hidden'));
assert.isTrue(element.$$('.robotActions').hasAttribute('hidden'));
@@ -411,8 +412,7 @@
'gr-formatted-text is not visible');
assert.isFalse(isVisible(element.$$('.actions')),
'actions are not visible');
- assert.isFalse(isVisible(element.$$('gr-textarea')),
- 'textarea is not visible');
+ assert.isNotOk(element.textarea, 'textarea is not visible');
assert.isTrue(isVisible(element.$$('.collapsedContent')),
'header middle content is visible');
@@ -422,21 +422,20 @@
'gr-formatted-text is visible');
assert.isTrue(isVisible(element.$$('.actions')),
'actions are visible');
- assert.isFalse(isVisible(element.$$('gr-textarea')),
- 'textarea is not visible');
+ assert.isNotOk(element.textarea, 'textarea is not visible');
assert.isFalse(isVisible(element.$$('.collapsedContent')),
'header middle content is is not visible');
// When the edit button is pressed, should still see the actions
// and also textarea
MockInteractions.tap(element.$$('.edit'));
+ flushAsynchronousOperations();
assert.isFalse(element.collapsed);
assert.isFalse(isVisible(element.$$('gr-formatted-text')),
'gr-formatted-text is not visible');
assert.isTrue(isVisible(element.$$('.actions')),
'actions are visible');
- assert.isTrue(isVisible(element.$$('gr-textarea')),
- 'textarea is visible');
+ assert.isTrue(isVisible(element.textarea), 'textarea is visible');
assert.isFalse(isVisible(element.$$('.collapsedContent')),
'header middle content is not visible');
@@ -460,8 +459,7 @@
'gr-formatted-text is not visible');
assert.isTrue(isVisible(element.$$('.actions')),
'actions are visible');
- assert.isTrue(isVisible(element.$$('gr-textarea')),
- 'textarea is visible');
+ assert.isTrue(isVisible(element.textarea), 'textarea is visible');
assert.isFalse(isVisible(element.$$('.collapsedContent')),
'header middle content is not visible');
});
@@ -496,7 +494,8 @@
MockInteractions.tap(element.$$('.cancel'));
element.flushDebouncer('fire-update');
element._messageText = '';
- MockInteractions.pressAndReleaseKeyOn(element.$.editTextarea, 27); // esc
+ flushAsynchronousOperations();
+ MockInteractions.pressAndReleaseKeyOn(element.textarea, 27); // esc
});
test('draft discard removes message from storage', done => {
@@ -562,7 +561,7 @@
test('confirms discard of comments with message text', () => {
element._messageText = 'test';
element._handleDiscard(mockEvent);
- assert.isTrue(overlayStub.calledWith(element.$.confirmDiscardOverlay));
+ assert.isTrue(overlayStub.calledWith(element.confirmDiscardOverlay));
assert.isFalse(discardStub.called);
});
@@ -581,8 +580,10 @@
done();
});
element._messageText = 'is that the horse from horsing around??';
+ element.editing = true;
+ flushAsynchronousOperations();
MockInteractions.pressAndReleaseKeyOn(
- element.$.editTextarea.$.textarea.textarea,
+ element.textarea.$.textarea.textarea,
83, 'ctrl'); // 'ctrl + s'
});
diff --git a/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view.js b/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view.js
index f34328e..c771332 100644
--- a/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view.js
+++ b/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view.js
@@ -132,9 +132,9 @@
// then hides the text box and submit button.
_computeHideAgreementClass(name, config) {
for (const key in config) {
- if (!config.hasOwnProperty(key)) { return; }
+ if (!config.hasOwnProperty(key)) { continue; }
for (const prop in config[key]) {
- if (!config[key].hasOwnProperty(prop)) { return; }
+ if (!config[key].hasOwnProperty(prop)) { continue; }
if (name === config[key].name &&
!config[key].auto_verify_group) {
return 'hideAgreementsTextBox';
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.html b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.html
index ca9c2baa..7f6cded 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.html
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.html
@@ -93,7 +93,7 @@
link="[[link]]"
class="dropdown-trigger" id="trigger"
down-arrow="[[downArrow]]"
- on-tap="_showDropdownTapHandler">
+ on-tap="_dropdownTriggerTapHandler">
<content></content>
</gr-button>
<iron-dropdown id="dropdown"
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.js b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.js
index 3e05c2b..f8edc83 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.js
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.js
@@ -153,21 +153,21 @@
* @param {!Event} e
*/
_handleDropdownTap(e) {
- // async is needed so that that the click event is fired before the
- // dropdown closes (This was a bug for touch devices).
- this.async(() => {
- this.$.dropdown.close();
- }, 1);
+ this._close();
},
/**
* Hanlde a click on the button to open the dropdown.
* @param {!Event} e
*/
- _showDropdownTapHandler(e) {
+ _dropdownTriggerTapHandler(e) {
e.preventDefault();
e.stopPropagation();
- this._open();
+ if (this.$.dropdown.opened) {
+ this._close();
+ } else {
+ this._open();
+ }
},
/**
@@ -180,6 +180,14 @@
this.$.cursor.target.focus();
},
+ _close() {
+ // async is needed so that that the click event is fired before the
+ // dropdown closes (This was a bug for touch devices).
+ this.async(() => {
+ this.$.dropdown.close();
+ }, 1);
+ },
+
/**
* Get the class for a top-content item based on the given boolean.
* @param {boolean} bold Whether the item is bold.
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html
index adb89d8..d4d21b0 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html
@@ -49,11 +49,14 @@
sandbox.restore();
});
- test('tap on trigger opens menu', () => {
+ test('tap on trigger opens menu, then closes', () => {
sandbox.stub(element, '_open', () => { element.$.dropdown.open(); });
+ sandbox.stub(element, '_close', () => { element.$.dropdown.close(); });
assert.isFalse(element.$.dropdown.opened);
MockInteractions.tap(element.$.trigger);
assert.isTrue(element.$.dropdown.opened);
+ MockInteractions.tap(element.$.trigger);
+ assert.isFalse(element.$.dropdown.opened);
});
test('_computeURLHelper', () => {
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
index 2c061f6..bb9b627 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
@@ -189,6 +189,7 @@
const params = [];
for (const p in opt_params) {
+ if (!opt_params.hasOwnProperty(p)) { continue; }
if (opt_params[p] == null) {
params.push(encodeURIComponent(p));
continue;
diff --git a/tools/js/bower2bazel.py b/tools/js/bower2bazel.py
index ccdf2df..171ab55 100755
--- a/tools/js/bower2bazel.py
+++ b/tools/js/bower2bazel.py
@@ -118,10 +118,15 @@
json.dump(bower_json, f, indent=2)
return ret
+def decode(input):
+ try:
+ return input.decode("utf-8")
+ except TypeError:
+ return input
def bower_command(args):
base = subprocess.check_output(["bazel", "info", "output_base"]).strip()
- exp = os.path.join(base, "external", "bower", "*npm_binary.tgz")
+ exp = os.path.join(decode(base), "external", "bower", "*npm_binary.tgz")
fs = sorted(glob.glob(exp))
assert len(fs) == 1, "bower tarball not found or have multiple versions %s" % fs
return ["python", os.getcwd() + "/tools/js/run_npm_binary.py", sorted(fs)[0]] + args
@@ -137,8 +142,8 @@
"bazel", "query", "kind(bower_component_bundle, //polygerrit-ui/...)"])
seed_str = subprocess.check_output([
"bazel", "query", "attr(seed, 1, kind(bower_component, deps(//polygerrit-ui/...)))"])
- targets = [s for s in target_str.split('\n') if s]
- seeds = [s for s in seed_str.split('\n') if s]
+ targets = [s for s in decode(target_str).split('\n') if s]
+ seeds = [s for s in decode(seed_str).split('\n') if s]
prefix = "//lib/js:"
non_seeds = [s for s in seeds if not s.startswith(prefix)]
assert not non_seeds, non_seeds
@@ -223,7 +228,7 @@
out = subprocess.check_output(["find", "bower_components/", "-name", ".bower.json"])
data = []
- for f in sorted(out.split('\n')):
+ for f in sorted(decode(out).split('\n')):
if not f:
continue
pkg = json.load(open(f))