Merge "Merge branch 'stable-2.16'"

This commit is contained in:
David Pursehouse
2019-03-09 02:05:45 +00:00
committed by Gerrit Code Review
29 changed files with 814 additions and 785 deletions

View File

@@ -17,11 +17,13 @@ import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Target({TYPE, METHOD})
@Retention(RUNTIME)
@Inherited
public @interface LogThreshold {
String level() default "DEBUG";
}

View File

@@ -32,9 +32,6 @@ limitations under the License.
<template>
<style include="shared-styles"></style>
<style include="gr-form-styles">
:host {
display: inline-block;
}
input:not([type="checkbox"]),
gr-autocomplete,
iron-autogrow-textarea {
@@ -43,13 +40,6 @@ limitations under the License.
.value {
width: 32em;
}
section {
align-items: center;
display: flex;
}
#description {
align-items: initial;
}
gr-autocomplete {
--gr-autocomplete: {
padding: 0 .15em;
@@ -58,9 +48,13 @@ limitations under the License.
.hide {
display: none;
}
@media only screen and (max-width: 40em) {
.value {
width: 29em;
}
}
</style>
<div class="gr-form-styles">
<div id="form">
<section class$="[[_computeBranchClass(baseChange)]]">
<span class="title">Select branch for new change</span>
<span class="value">
@@ -120,7 +114,6 @@ limitations under the License.
</span>
</section>
</div>
</div>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
</template>
<script src="gr-create-change-dialog.js"></script>

View File

@@ -24,7 +24,6 @@ limitations under the License.
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
<link rel="import" href="../../core/gr-reporting/gr-reporting.html">
<link rel="import" href="../../diff/gr-comment-api/gr-comment-api.html">
<link rel="import" href="../../diff/gr-diff-preferences/gr-diff-preferences.html">
<link rel="import" href="../../edit/gr-edit-constants.html">
<link rel="import" href="../../plugins/gr-endpoint-decorator/gr-endpoint-decorator.html">
<link rel="import" href="../../plugins/gr-endpoint-param/gr-endpoint-param.html">
@@ -40,6 +39,7 @@ limitations under the License.
<link rel="import" href="../../shared/gr-overlay/gr-overlay.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
<link rel="import" href="../../shared/gr-tooltip-content/gr-tooltip-content.html">
<link rel="import" href="../../shared/revision-info/revision-info.html">
<link rel="import" href="../gr-change-actions/gr-change-actions.html">
<link rel="import" href="../gr-change-metadata/gr-change-metadata.html">
<link rel="import" href="../gr-commit-info/gr-commit-info.html">
@@ -545,6 +545,7 @@ limitations under the License.
all-patch-sets="[[_allPatchSets]]"
change="[[_change]]"
change-num="[[_changeNum]]"
revision-info="[[_revisionInfo]]"
change-comments="[[_changeComments]]"
commit-info="[[_commitInfo]]"
change-url="[[_computeChangeUrl(_change)]]"

View File

@@ -132,6 +132,7 @@
type: Object,
value: {},
},
_prefs: Object,
/** @type {?} */
_changeComments: Object,
_canStartReview: {
@@ -144,6 +145,10 @@
type: Object,
observer: '_changeChanged',
},
_revisionInfo: {
type: Object,
computed: '_getRevisionInfo(_change)',
},
/** @type {?} */
_commitInfo: Object,
_currentRevision: {
@@ -291,6 +296,7 @@
'fullscreen-overlay-closed': '_handleShowBackgroundContent',
'diff-comments-modified': '_handleReloadCommentThreads',
},
observers: [
'_labelsChanged(_change.labels.*)',
'_paramsAndChangeChanged(params, _change)',
@@ -375,7 +381,7 @@
_setDiffViewMode(opt_reset) {
if (!opt_reset && this.viewState.diffViewMode) { return; }
return this.$.restAPI.getPreferences().then( prefs => {
return this._getPreferences().then( prefs => {
if (!this.viewState.diffMode) {
this.set('viewState.diffMode', prefs.default_diff_view);
}
@@ -847,10 +853,11 @@
_changeChanged(change) {
if (!change || !this._patchRange || !this._allPatchSets) { return; }
this.set('_patchRange.basePatchNum',
this._patchRange.basePatchNum || 'PARENT');
this.set('_patchRange.patchNum',
this._patchRange.patchNum ||
const parent = this._getBasePatchNum(change, this._patchRange);
this.set('_patchRange.basePatchNum', parent);
this.set('_patchRange.patchNum', this._patchRange.patchNum ||
this.computeLatestPatchNum(this._allPatchSets));
// Reset the related changes toggle in the event it was previously
@@ -861,6 +868,35 @@
this.fire('title-change', {title});
},
/**
* Gets base patch number, if is a parent try and
* decide from preference weather to default to `auto merge`
* or `Parent 1`.
* @param {Object} change
* @param {Object} patchRange
* @return {number|string}
*/
_getBasePatchNum(change, patchRange) {
if (patchRange.basePatchNum &&
patchRange.basePatchNum !== 'PARENT') {
return patchRange.basePatchNum;
}
const revisionInfo = this._getRevisionInfo(change);
if (!revisionInfo) return 'PARENT';
const parentCounts = revisionInfo.getParentCountMap();
// check that there is at least 2 parents otherwise fall back to 1,
// which means there is only one parent.
const parentCount = parentCounts.hasOwnProperty(1) ?
parentCounts[1] : 1;
const preferFirst = this._prefs &&
this._prefs.default_base_for_merges === 'FIRST_PARENT';
return parentCount > 1 && preferFirst ? -1 : 'PARENT';
},
_computeShowPrimaryTabs(dynamicTabContentEndpoints) {
return dynamicTabContentEndpoints.length > 0;
},
@@ -1120,6 +1156,10 @@
});
},
_getPreferences() {
return this.$.restAPI.getPreferences();
},
_updateRebaseAction(revisionActions) {
if (revisionActions && revisionActions.rebase) {
revisionActions.rebase.rebaseOnCurrent =
@@ -1173,9 +1213,12 @@
const detailCompletes = this.$.restAPI.getChangeDetail(
this._changeNum, this._handleGetChangeDetailError.bind(this));
const editCompletes = this._getEdit();
const prefCompletes = this._getPreferences();
return Promise.all([detailCompletes, editCompletes, prefCompletes])
.then(([change, edit, prefs]) => {
this._prefs = prefs;
return Promise.all([detailCompletes, editCompletes])
.then(([change, edit]) => {
if (!change) {
return '';
}
@@ -1724,6 +1767,10 @@
e.detail.starred);
},
_getRevisionInfo(change) {
return new Gerrit.RevisionInfo(change);
},
_computeCurrentRevision(currentRevision, revisions) {
return revisions && revisions[currentRevision];
},

View File

@@ -297,7 +297,8 @@ limitations under the License.
});
test(', should open diff preferences', () => {
const stub = sandbox.stub(element.$.fileList.$.diffPreferences, 'open');
const stub = sandbox.stub(
element.$.fileList.$.diffPreferencesDialog, 'open');
element._loggedIn = false;
element.disableDiffPrefs = true;
MockInteractions.pressAndReleaseKeyOn(element, 188, null, ',');
@@ -1604,8 +1605,8 @@ limitations under the License.
});
test('_selectedRevision updates when patchNum is changed', () => {
const revision1 = {_number: 1, commit: {}};
const revision2 = {_number: 2, commit: {}};
const revision1 = {_number: 1, commit: {parents: []}};
const revision2 = {_number: 2, commit: {parents: []}};
sandbox.stub(element.$.restAPI, 'getChangeDetail').returns(
Promise.resolve({
revisions: {
@@ -1618,6 +1619,7 @@ limitations under the License.
change_id: 'loremipsumdolorsitamet',
}));
sandbox.stub(element, '_getEdit').returns(Promise.resolve());
sandbox.stub(element, '_getPreferences').returns(Promise.resolve({}));
element._patchRange = {patchNum: '2'};
return element._getChangeDetail().then(() => {
assert.strictEqual(element._selectedRevision, revision2);

View File

@@ -19,8 +19,8 @@ limitations under the License.
<link rel="import" href="../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html">
<link rel="import" href="../../../behaviors/rest-client-behavior/rest-client-behavior.html">
<link rel="import" href="../../shared/gr-download-commands/gr-download-commands.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-download-commands/gr-download-commands.html">
<dom-module id="gr-download-dialog">
<template>
@@ -87,7 +87,7 @@ limitations under the License.
selected-scheme="{{_selectedScheme}}"></gr-download-commands>
</section>
<section class="flexContainer">
<div class="patchFiles">
<div class="patchFiles" hidden="[[_computeHidePatchFile(change, patchNum)]]" hidden>
<label>Patch file</label>
<div>
<a

View File

@@ -138,6 +138,17 @@
return shortRev + '.diff.' + (opt_zip ? 'zip' : 'base64');
},
_computeHidePatchFile(change, patchNum) {
for (const rev of Object.values(change.revisions || {})) {
if (this.patchNumEquals(rev._number, patchNum)) {
const parentLength = rev.commit && rev.commit.parents ?
rev.commit.parents.length : 0;
return parentLength == 0;
}
}
return false;
},
_computeArchiveDownloadLink(change, patchNum, format) {
return this.changeBaseURL(change.project, change._number, patchNum) +
'/archive?format=' + format;

View File

@@ -45,6 +45,9 @@ limitations under the License.
revisions: {
'34685798fe548b6d17d1e8e5edc43a26d055cc72': {
_number: 1,
commit: {
parents: [],
},
fetch: {
repo: {
commands: {
@@ -105,6 +108,9 @@ limitations under the License.
revisions: {
'34685798fe548b6d17d1e8e5edc43a26d055cc72': {
_number: 1,
commit: {
parents: [],
},
fetch: {},
},
},
@@ -188,5 +194,25 @@ limitations under the License.
assert.equal(element._computeShowDownloadCommands([]), 'hidden');
assert.equal(element._computeShowDownloadCommands(['test']), '');
});
test('_computeHidePatchFile', () => {
const patchNum = '1';
const change1 = {
revisions: {
r1: {_number: 1, commit: {parents: []}},
},
};
assert.isTrue(element._computeHidePatchFile(change1, patchNum));
const change2 = {
revisions: {
r1: {_number: 1, commit: {parents: [
{commit: 'p1'},
]}},
},
};
assert.isFalse(element._computeHidePatchFile(change2, patchNum));
});
});
</script>

View File

@@ -28,7 +28,6 @@ limitations under the License.
<link rel="import" href="../../shared/gr-select/gr-select.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-icons/gr-icons.html">
<link rel="import" href="../../shared/revision-info/revision-info.html">
<link rel="import" href="../gr-file-list-constants.html">
<dom-module id="gr-file-list-header">
@@ -167,7 +166,7 @@ limitations under the License.
base-patch-num="[[basePatchNum]]"
available-patches="[[allPatchSets]]"
revisions="[[change.revisions]]"
revision-info="[[_revisionInfo]]"
revision-info="[[revisionInfo]]"
on-patch-range-change="_handlePatchChange">
</gr-patch-range-select>
<span class="separator"></span>

View File

@@ -89,10 +89,7 @@
type: Boolean,
computed: '_computeDescriptionReadOnly(loggedIn, change, account)',
},
_revisionInfo: {
type: Object,
computed: '_getRevisionInfo(change)',
},
revisionInfo: Object,
},
behaviors: [
@@ -234,10 +231,6 @@
return 'patchInfoOldPatchSet';
},
_getRevisionInfo(change) {
return new Gerrit.RevisionInfo(change);
},
_hideIncludedIn(change) {
return change && change.status === MERGED_STATUS ? '' : 'hide';
},

View File

@@ -23,8 +23,9 @@ limitations under the License.
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
<link rel="import" href="../../core/gr-reporting/gr-reporting.html">
<link rel="import" href="../../diff/gr-diff-host/gr-diff-host.html">
<link rel="import" href="../../diff/gr-diff-cursor/gr-diff-cursor.html">
<link rel="import" href="../../diff/gr-diff-host/gr-diff-host.html">
<link rel="import" href="../../diff/gr-diff-preferences-dialog/gr-diff-preferences-dialog.html">
<link rel="import" href="../../edit/gr-edit-file-controls/gr-edit-file-controls.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-cursor-manager/gr-cursor-manager.html">
@@ -464,10 +465,11 @@ limitations under the License.
</gr-button><!--
--></gr-tooltip-content>
</div>
<gr-diff-preferences
id="diffPreferences"
prefs="{{diffPrefs}}"
local-prefs="{{_localPrefs}}"></gr-diff-preferences>
<gr-diff-preferences-dialog
id="diffPreferencesDialog"
diff-prefs="{{diffPrefs}}"
on-reload-diff-preference="_handleReloadingDiffPreference">
</gr-diff-preferences-dialog>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
<gr-storage id="storage"></gr-storage>
<gr-diff-cursor id="diffCursor"></gr-diff-cursor>

View File

@@ -125,7 +125,6 @@
},
/** @type {?} */
_userPrefs: Object,
_localPrefs: Object,
_showInlineDiffs: Boolean,
numFilesShown: {
type: Number,
@@ -269,7 +268,6 @@
});
}));
this._localPrefs = this.$.storage.getPreferences();
promises.push(this._getDiffPreferences().then(prefs => {
this.diffPrefs = prefs;
}));
@@ -297,7 +295,7 @@
},
openDiffPrefs() {
this.$.diffPreferences.open();
this.$.diffPreferencesDialog.open();
},
_calculatePatchChange(files) {
@@ -1255,5 +1253,11 @@
return 'Mark as reviewed (shortcut: r)';
},
_handleReloadingDiffPreference() {
this._getDiffPreferences().then(prefs => {
this.diffPrefs = prefs;
});
},
});
})();

View File

@@ -0,0 +1,80 @@
<!--
@license
Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-diff-preferences/gr-preferences.html">
<link rel="import" href="../../shared/gr-overlay/gr-overlay.html">
<dom-module id="gr-diff-preferences-dialog">
<template>
<style include="shared-styles">
.diffHeader,
.diffActions {
padding: 1em 1.5em;
}
.diffHeader,
.diffActions {
background-color: var(--dialog-background-color);
}
.diffHeader {
border-bottom: 1px solid var(--border-color);
font-weight: var(--font-weight-bold);
}
.diffActions {
border-top: 1px solid var(--border-color);
display: flex;
justify-content: flex-end;
}
.diffPrefsOverlay gr-button {
margin-left: 1em;
}
div.edited:after {
color: var(--deemphasized-text-color);
content: ' *';
}
#diffPreferences {
display: flex;
padding: .35em 1.5em;
}
</style>
<gr-overlay id="diffPrefsOverlay" with-backdrop>
<div class$="diffHeader [[_computeHeaderClass(_diffPrefsChanged)]]">Diff Preferences</div>
<gr-diff-preferences
id="diffPreferences"
diff-prefs="{{diffPrefs}}"
has-unsaved-changes="{{_diffPrefsChanged}}"></gr-diff-preferences>
<div class="diffActions">
<gr-button
id="cancelButton"
link
on-tap="_handleCancelDiff">
Cancel
</gr-button>
<gr-button
id="saveButton"
link primary
on-tap="_handleSaveDiffPreferences"
disabled$="[[!_diffPrefsChanged]]">
Save
</gr-button>
</div>
</gr-overlay>
</template>
<script src="gr-diff-preferences-dialog.js"></script>
</dom-module>

View File

@@ -0,0 +1,66 @@
/**
* @license
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
'use strict';
Polymer({
is: 'gr-diff-preferences-dialog',
properties: {
/** @type {?} */
diffPrefs: Object,
_diffPrefsChanged: Boolean,
},
getFocusStops() {
return {
start: this.$.contextSelect,
end: this.$.saveButton,
};
},
resetFocus() {
this.$.contextSelect.focus();
},
_computeHeaderClass(changed) {
return changed ? 'edited' : '';
},
_handleCancelDiff(e) {
e.stopPropagation();
this.$.diffPrefsOverlay.close();
},
open() {
this.$.diffPrefsOverlay.open().then(() => {
const focusStops = this.getFocusStops();
this.$.diffPrefsOverlay.setFocusStops(focusStops);
this.resetFocus();
});
},
_handleSaveDiffPreferences() {
this.$.diffPreferences.save().then(() => {
this.fire('reload-diff-preference', null, {bubbles: false});
this.$.diffPrefsOverlay.close();
});
},
});
})();

View File

@@ -1,173 +0,0 @@
<!--
@license
Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-overlay/gr-overlay.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
<link rel="import" href="../../shared/gr-storage/gr-storage.html">
<link rel="import" href="../../../styles/shared-styles.html">
<dom-module id="gr-diff-preferences">
<template>
<style include="shared-styles">
:host {
display: block;
}
:host([disabled]) {
opacity: .5;
pointer-events: none;
}
input,
select {
font: inherit;
}
input[type="number"] {
width: 4em;
}
.header,
.actions {
padding: 1em 1.5em;
}
.header,
.mainContainer,
.actions {
background-color: var(--dialog-background-color);
}
.header {
border-bottom: 1px solid var(--border-color);
font-weight: var(--font-weight-bold);
}
.mainContainer {
padding: 1em 0;
}
.pref {
align-items: center;
display: flex;
padding: .35em 1.5em;
width: 25em;
}
.pref:hover {
background-color: var(--hover-background-color);
}
.pref label {
cursor: pointer;
flex: 1;
}
.actions {
border-top: 1px solid var(--border-color);
display: flex;
justify-content: flex-end;
}
gr-button {
margin-left: 1em;
}
</style>
<gr-overlay id="prefsOverlay" with-backdrop>
<div class="header">
Diff View Preferences
</div>
<div class="mainContainer">
<div class="pref">
<label for="contextSelect">Context</label>
<select id="contextSelect" on-change="_handleContextSelectChange">
<option value="3">3 lines</option>
<option value="10">10 lines</option>
<option value="25">25 lines</option>
<option value="50">50 lines</option>
<option value="75">75 lines</option>
<option value="100">100 lines</option>
<option value="-1">Whole file</option>
</select>
</div>
<div class="pref">
<label for="lineWrappingInput">Fit to screen</label>
<input
is="iron-input"
type="checkbox"
id="lineWrappingInput"
on-tap="_handlelineWrappingTap">
</div>
<div class="pref" id="columnsPref">
<label for="columnsInput">Diff width</label>
<input is="iron-input" type="number" id="columnsInput"
prevent-invalid-input
allowed-pattern="[0-9]"
bind-value="{{_newPrefs.line_length}}">
</div>
<div class="pref">
<label for="tabSizeInput">Tab width</label>
<input is="iron-input" type="number" id="tabSizeInput"
prevent-invalid-input
allowed-pattern="[0-9]"
bind-value="{{_newPrefs.tab_size}}">
</div>
<div class="pref" hidden$="[[!_newPrefs.font_size]]">
<label for="fontSizeInput">Font size</label>
<input is="iron-input" type="number" id="fontSizeInput"
prevent-invalid-input
allowed-pattern="[0-9]"
bind-value="{{_newPrefs.font_size}}">
</div>
<div class="pref">
<label for="showTabsInput">Show tabs</label>
<input is="iron-input" type="checkbox" id="showTabsInput"
on-tap="_handleShowTabsTap">
</div>
<div class="pref">
<label for="showTrailingWhitespaceInput">
Show trailing whitespace</label>
<input is="iron-input" type="checkbox"
id="showTrailingWhitespaceInput"
on-tap="_handleShowTrailingWhitespaceTap">
</div>
<div class="pref">
<label for="syntaxHighlightInput">Syntax highlighting</label>
<input is="iron-input" type="checkbox" id="syntaxHighlightInput"
on-tap="_handleSyntaxHighlightTap">
</div>
<div class="pref">
<label for="automaticReviewInput">Automatically mark viewed files reviewed</label>
<input
is="iron-input"
id="automaticReviewInput"
type="checkbox"
on-tap="_handleAutomaticReviewTap">
</div>
<div class="pref">
<label for="ignoreWhitespace">Ignore Whitespace</label>
<select id="ignoreWhitespace" on-change="_handleIgnoreWhitespaceChange">
<option value="IGNORE_NONE">None</option>
<option value="IGNORE_TRAILING">Trailing</option>
<option value="IGNORE_LEADING_AND_TRAILING">Leading & trailing</option>
<option value="IGNORE_ALL">All</option>
</select>
</div>
</div>
<div class="actions">
<gr-button id="cancelButton" link on-tap="_handleCancel">
Cancel</gr-button>
<gr-button id="saveButton" link primary on-tap="_handleSave">
Save</gr-button>
</div>
</gr-overlay>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
<gr-storage id="storage"></gr-storage>
</template>
<script src="gr-diff-preferences.js"></script>
</dom-module>

View File

@@ -1,144 +0,0 @@
/**
* @license
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
'use strict';
Polymer({
is: 'gr-diff-preferences',
properties: {
prefs: {
type: Object,
notify: true,
},
localPrefs: {
type: Object,
notify: true,
},
disabled: {
type: Boolean,
value: false,
reflectToAttribute: true,
},
/** @type {?} */
_newPrefs: Object,
_newLocalPrefs: Object,
},
observers: [
'_prefsChanged(prefs.*)',
'_localPrefsChanged(localPrefs.*)',
],
getFocusStops() {
return {
start: this.$.contextSelect,
end: this.$.saveButton,
};
},
resetFocus() {
this.$.contextSelect.focus();
},
_prefsChanged(changeRecord) {
const prefs = changeRecord.base;
// NOTE: Object.assign is NOT automatically a deep copy. If prefs adds
// an object as a value, it must be marked enumerable.
this._newPrefs = Object.assign({}, prefs);
this.$.contextSelect.value = prefs.context;
this.$.showTabsInput.checked = prefs.show_tabs;
this.$.showTrailingWhitespaceInput.checked = prefs.show_whitespace_errors;
this.$.lineWrappingInput.checked = prefs.line_wrapping;
this.$.syntaxHighlightInput.checked = prefs.syntax_highlighting;
this.$.automaticReviewInput.checked = !prefs.manual_review;
this.$.ignoreWhitespace.value = prefs.ignore_whitespace;
},
_localPrefsChanged(changeRecord) {
const localPrefs = changeRecord.base || {};
this._newLocalPrefs = Object.assign({}, localPrefs);
},
_handleContextSelectChange(e) {
const selectEl = Polymer.dom(e).rootTarget;
this.set('_newPrefs.context', parseInt(selectEl.value, 10));
},
_handleIgnoreWhitespaceChange(e) {
const selectEl = Polymer.dom(e).rootTarget;
this.set('_newPrefs.ignore_whitespace', selectEl.value);
},
_handleShowTabsTap(e) {
this.set('_newPrefs.show_tabs', Polymer.dom(e).rootTarget.checked);
},
_handleShowTrailingWhitespaceTap(e) {
this.set('_newPrefs.show_whitespace_errors',
Polymer.dom(e).rootTarget.checked);
},
_handleSyntaxHighlightTap(e) {
this.set('_newPrefs.syntax_highlighting',
Polymer.dom(e).rootTarget.checked);
},
_handlelineWrappingTap(e) {
this.set('_newPrefs.line_wrapping', Polymer.dom(e).rootTarget.checked);
},
_handleAutomaticReviewTap(e) {
this.set('_newPrefs.manual_review', !Polymer.dom(e).rootTarget.checked);
},
_handleSave(e) {
e.stopPropagation();
this.prefs = this._newPrefs;
this.localPrefs = this._newLocalPrefs;
const el = Polymer.dom(e).rootTarget;
el.disabled = true;
this.$.storage.savePreferences(this._localPrefs);
this._saveDiffPreferences().then(response => {
el.disabled = false;
if (!response.ok) { return response; }
this.$.prefsOverlay.close();
}).catch(err => {
el.disabled = false;
});
},
_handleCancel(e) {
e.stopPropagation();
this.$.prefsOverlay.close();
},
open() {
this.$.prefsOverlay.open().then(() => {
const focusStops = this.getFocusStops();
this.$.prefsOverlay.setFocusStops(focusStops);
this.resetFocus();
});
},
_saveDiffPreferences() {
return this.$.restAPI.saveDiffPreferences(this.prefs);
},
});
})();

View File

@@ -1,110 +0,0 @@
<!DOCTYPE html>
<!--
@license
Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-diff-preferences</title>
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-diff-preferences.html">
<script>void(0);</script>
<test-fixture id="basic">
<template>
<gr-diff-preferences></gr-diff-preferences>
</template>
</test-fixture>
<script>
suite('gr-diff-preferences tests', () => {
let element;
let sandbox;
setup(() => {
sandbox = sinon.sandbox.create();
element = fixture('basic');
});
teardown(() => {
sandbox.restore();
});
test('model changes', () => {
element.prefs = {
context: 10,
font_size: 12,
line_length: 100,
show_tabs: true,
tab_size: 8,
show_whitespace_errors: true,
syntax_highlighting: true,
};
assert.deepEqual(element.prefs, element._newPrefs);
element.$.contextSelect.value = '50';
element.fire('change', {}, {node: element.$.contextSelect});
element.$.columnsInput.bindValue = 80;
element.$.fontSizeInput.bindValue = 10;
element.$.tabSizeInput.bindValue = 4;
MockInteractions.tap(element.$.showTabsInput);
MockInteractions.tap(element.$.showTrailingWhitespaceInput);
MockInteractions.tap(element.$.syntaxHighlightInput);
MockInteractions.tap(element.$.lineWrappingInput);
assert.equal(element._newPrefs.context, 50);
assert.equal(element._newPrefs.font_size, 10);
assert.equal(element._newPrefs.line_length, 80);
assert.equal(element._newPrefs.tab_size, 4);
assert.isFalse(element._newPrefs.show_tabs);
assert.isFalse(element._newPrefs.show_whitespace_errors);
assert.isTrue(element._newPrefs.line_wrapping);
assert.isFalse(element._newPrefs.syntax_highlighting);
});
test('clicking save button calls _handleSave function', () => {
const savePrefs = sinon.stub(element, '_handleSave');
MockInteractions.tap(element.$.saveButton);
flushAsynchronousOperations();
assert(savePrefs.calledOnce);
savePrefs.restore();
});
test('save button', () => {
element.prefs = {
font_size: '11',
};
element._newPrefs = {
font_size: '12',
};
const saveStub = sandbox.stub(element.$.restAPI, 'saveDiffPreferences',
() => { return Promise.resolve(); });
MockInteractions.tap(element.$$('gr-button[primary]'));
assert.deepEqual(element.prefs, element._newPrefs);
assert.deepEqual(saveStub.lastCall.args[0], element._newPrefs);
});
test('cancel button', () => {
const closeStub = sandbox.stub(element.$.prefsOverlay, 'close');
MockInteractions.tap(element.$$('gr-button:not([primary])'));
assert.isTrue(closeStub.called);
});
});
</script>

View File

@@ -34,9 +34,9 @@ limitations under the License.
<link rel="import" href="../../shared/revision-info/revision-info.html">
<link rel="import" href="../gr-comment-api/gr-comment-api.html">
<link rel="import" href="../gr-diff-cursor/gr-diff-cursor.html">
<link rel="import" href="../gr-diff-mode-selector/gr-diff-mode-selector.html">
<link rel="import" href="../gr-diff-preferences/gr-diff-preferences.html">
<link rel="import" href="../gr-diff-host/gr-diff-host.html">
<link rel="import" href="../gr-diff-mode-selector/gr-diff-mode-selector.html">
<link rel="import" href="../gr-diff-preferences-dialog/gr-diff-preferences-dialog.html">
<link rel="import" href="../gr-patch-range-select/gr-patch-range-select.html">
<dom-module id="gr-diff-view">
@@ -338,10 +338,11 @@ limitations under the License.
on-comment-anchor-tap="_onLineSelected"
on-line-selected="_onLineSelected">
</gr-diff-host>
<gr-diff-preferences
id="diffPreferences"
prefs="{{_prefs}}"
local-prefs="{{_localPrefs}}"></gr-diff-preferences>
<gr-diff-preferences-dialog
id="diffPreferencesDialog"
diff-prefs="{{_prefs}}"
on-reload-diff-preference="_handleReloadingDiffPreference">
</gr-diff-preferences-dialog>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
<gr-storage id="storage"></gr-storage>
<gr-diff-cursor id="cursor"></gr-diff-cursor>

View File

@@ -266,7 +266,9 @@
},
_getDiffPreferences() {
return this.$.restAPI.getDiffPreferences();
return this.$.restAPI.getDiffPreferences().then(prefs => {
this._prefs = prefs;
});
},
_getPreferences() {
@@ -466,7 +468,7 @@
if (this._diffPrefsDisabled) { return; }
e.preventDefault();
this.$.diffPreferences.open();
this.$.diffPreferencesDialog.open();
},
_handleToggleDiffMode(e) {
@@ -617,10 +619,7 @@
const promises = [];
this._localPrefs = this.$.storage.getPreferences();
promises.push(this._getDiffPreferences().then(prefs => {
this._prefs = prefs;
}));
promises.push(this._getDiffPreferences());
promises.push(this._getPreferences().then(prefs => {
this._userPrefs = prefs;
@@ -846,22 +845,7 @@
_handlePrefsTap(e) {
e.preventDefault();
this.$.diffPreferences.open();
},
_handlePrefsSave(e) {
e.stopPropagation();
const el = Polymer.dom(e).rootTarget;
el.disabled = true;
this.$.storage.savePreferences(this._localPrefs);
this._saveDiffPreferences().then(response => {
el.disabled = false;
if (!response.ok) { return response; }
this.$.prefsOverlay.close();
}).catch(err => {
el.disabled = false;
});
this.$.diffPreferencesDialog.open();
},
/**
@@ -1049,5 +1033,9 @@
(file === this._path || !this._reviewedFiles.has(file)));
this._navToFile(this._path, unreviewedFiles, 1);
},
_handleReloadingDiffPreference() {
this._getDiffPreferences();
},
});
})();

View File

@@ -173,7 +173,7 @@ limitations under the License.
assert.isTrue(element._loading);
const showPrefsStub =
sandbox.stub(element.$.diffPreferences.$.prefsOverlay, 'open',
sandbox.stub(element.$.diffPreferencesDialog, 'open',
() => Promise.resolve());
MockInteractions.pressAndReleaseKeyOn(element, 188, null, ',');
@@ -386,7 +386,7 @@ limitations under the License.
test('prefsButton opens gr-diff-preferences', () => {
const handlePrefsTapSpy = sandbox.spy(element, '_handlePrefsTap');
const overlayOpenStub = sandbox.stub(element.$.diffPreferences,
const overlayOpenStub = sandbox.stub(element.$.diffPreferencesDialog,
'open');
const prefsButton =
Polymer.dom(element.root).querySelector('.prefsButton');

View File

@@ -27,6 +27,7 @@ limitations under the License.
<link rel="import" href="../../settings/gr-change-table-editor/gr-change-table-editor.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-date-formatter/gr-date-formatter.html">
<link rel="import" href="../../shared/gr-diff-preferences/gr-diff-preferences.html">
<link rel="import" href="../../shared/gr-page-nav/gr-page-nav.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
<link rel="import" href="../../shared/gr-select/gr-select.html">
@@ -194,6 +195,18 @@ limitations under the License.
</gr-select>
</span>
</section>
<section hidden$="[[!_localPrefs.default_base_for_merges]]">
<span class="title">Default Base For Merges</span>
<span class="value">
<gr-select
bind-value="{{_localPrefs.default_base_for_merges}}">
<select>
<option value="AUTO_MERGE">Auto Merge</option>
<option value="FIRST_PARENT">First Parent</option>
</select>
</gr-select>
</span>
</section>
<section>
<span class="title">Diff view</span>
<span class="value">
@@ -259,110 +272,9 @@ limitations under the License.
Diff Preferences
</h2>
<fieldset id="diffPreferences">
<section>
<span class="title">Context</span>
<span class="value">
<gr-select bind-value="{{_diffPrefs.context}}">
<select>
<option value="3">3 lines</option>
<option value="10">10 lines</option>
<option value="25">25 lines</option>
<option value="50">50 lines</option>
<option value="75">75 lines</option>
<option value="100">100 lines</option>
<option value="-1">Whole file</option>
</select>
</gr-select>
</span>
</section>
<section>
<span class="title">Fit to screen</span>
<span class="value">
<input
id="diffLineWrapping"
type="checkbox"
checked$="[[_diffPrefs.line_wrapping]]"
on-change="_handleDiffLineWrappingChanged">
</span>
</section>
<section id="columnsPref" hidden$="[[_diffPrefs.line_wrapping]]">
<span class="title">Diff width</span>
<span class="value">
<input
is="iron-input"
type="number"
prevent-invalid-input
allowed-pattern="[0-9]"
bind-value="{{_diffPrefs.line_length}}">
</span>
</section>
<section>
<span class="title">Tab width</span>
<span class="value">
<input
is="iron-input"
type="number"
prevent-invalid-input
allowed-pattern="[0-9]"
bind-value="{{_diffPrefs.tab_size}}">
</span>
</section>
<section hidden$="[[!_diffPrefs.font_size]]">
<span class="title">Font size</span>
<span class="value">
<input
is="iron-input"
type="number"
prevent-invalid-input
allowed-pattern="[0-9]"
bind-value="{{_diffPrefs.font_size}}">
</span>
</section>
<section>
<span class="title">Show tabs</span>
<span class="value">
<input
id="diffShowTabs"
type="checkbox"
checked$="[[_diffPrefs.show_tabs]]"
on-change="_handleDiffShowTabsChanged">
</span>
</section>
<section>
<span class="title">Show trailing whitespace</span>
<span class="value">
<input
id="showTrailingWhitespace"
type="checkbox"
checked$="[[_diffPrefs.show_whitespace_errors]]"
on-change="_handleShowTrailingWhitespaceChanged">
</span>
</section>
<section>
<span class="title">Syntax highlighting</span>
<span class="value">
<input
id="diffSyntaxHighlighting"
type="checkbox"
checked$="[[_diffPrefs.syntax_highlighting]]"
on-change="_handleDiffSyntaxHighlightingChanged">
</span>
</section>
<section>
<div class="pref">
<span class="title">Ignore Whitespace</span>
<span class="value">
<gr-select bind-value="{{_diffPrefs.ignore_whitespace}}">
<select>
<option value="IGNORE_NONE">None</option>
<option value="IGNORE_TRAILING">Trailing</option>
<option value="IGNORE_LEADING_AND_TRAILING">Leading & trailing</option>
<option value="IGNORE_ALL">All</option>
</select>
</gr-select>
</span>
</div>
</section>
<gr-diff-preferences
id="diffPrefs"
has-unsaved-changes="{{_diffPrefsChanged}}"></gr-diff-preferences>
<gr-button
id="saveDiffPrefs"
on-tap="_handleSaveDiffPreferences"

View File

@@ -25,6 +25,7 @@
'diff_view',
'publish_comments_on_push',
'work_in_progress_by_default',
'default_base_for_merges',
'signed_off_by',
'email_format',
'size_bar_in_change_table',
@@ -64,8 +65,6 @@
},
_accountNameMutable: Boolean,
_accountInfoChanged: Boolean,
/** @type {?} */
_diffPrefs: Object,
_changeTableColumnsNotDisplayed: Array,
/** @type {?} */
_localPrefs: {
@@ -92,10 +91,8 @@
type: Boolean,
value: false,
},
_diffPrefsChanged: {
type: Boolean,
value: false,
},
/** @type {?} */
_diffPrefsChanged: Boolean,
/** @type {?} */
_editPrefsChanged: Boolean,
_menuChanged: {
@@ -149,7 +146,6 @@
observers: [
'_handlePrefsChanged(_localPrefs.*)',
'_handleDiffPrefsChanged(_diffPrefs.*)',
'_handleMenuChanged(_localMenu.splices)',
'_handleChangeTableChanged(_localChangeTableColumns, _showNumber)',
],
@@ -166,6 +162,7 @@
this.$.httpPass.loadData(),
this.$.identities.loadData(),
this.$.editPrefs.loadData(),
this.$.diffPrefs.loadData(),
];
promises.push(this.$.restAPI.getPreferences().then(prefs => {
@@ -176,10 +173,6 @@
this._cloneChangeTableColumns();
}));
promises.push(this.$.restAPI.getDiffPreferences().then(prefs => {
this._diffPrefs = prefs;
}));
promises.push(this.$.restAPI.getConfig().then(config => {
this._serverConfig = config;
const configPromises = [];
@@ -277,11 +270,6 @@
this._prefsChanged = true;
},
_handleDiffPrefsChanged() {
if (this._isLoading()) { return; }
this._diffPrefsChanged = true;
},
_handleShowSizeBarsInFileListChanged() {
this.set('_localPrefs.size_bar_in_change_table',
this.$.showSizeBarsInFileList.checked);
@@ -318,24 +306,6 @@
});
},
_handleDiffLineWrappingChanged() {
this.set('_diffPrefs.line_wrapping', this.$.diffLineWrapping.checked);
},
_handleDiffShowTabsChanged() {
this.set('_diffPrefs.show_tabs', this.$.diffShowTabs.checked);
},
_handleShowTrailingWhitespaceChanged() {
this.set('_diffPrefs.show_whitespace_errors',
this.$.showTrailingWhitespace.checked);
},
_handleDiffSyntaxHighlightingChanged() {
this.set('_diffPrefs.syntax_highlighting',
this.$.diffSyntaxHighlighting.checked);
},
_handleSaveChangeTable() {
this.set('prefs.change_table', this._localChangeTableColumns);
this.set('prefs.legacycid_in_change_table', this._showNumber);
@@ -346,10 +316,7 @@
},
_handleSaveDiffPreferences() {
return this.$.restAPI.saveDiffPreferences(this._diffPrefs)
.then(() => {
this._diffPrefsChanged = false;
});
this.$.diffPrefs.save();
},
_handleSaveEditPreferences() {

View File

@@ -43,7 +43,6 @@ limitations under the License.
let element;
let account;
let preferences;
let diffPreferences;
let config;
let sandbox;
@@ -88,6 +87,7 @@ limitations under the License.
diff_view: 'UNIFIED_DIFF',
email_strategy: 'ENABLED',
email_format: 'HTML_PLAINTEXT',
default_base_for_merges: 'FIRST_PARENT',
size_bar_in_change_table: true,
my: [
@@ -96,31 +96,12 @@ limitations under the License.
],
change_table: [],
};
diffPreferences = {
context: 10,
tab_size: 8,
font_size: 12,
line_length: 100,
cursor_blink_rate: 0,
line_wrapping: false,
intraline_difference: true,
show_line_endings: true,
show_tabs: true,
show_whitespace_errors: true,
syntax_highlighting: true,
auto_hide_diff_table_header: true,
theme: 'DEFAULT',
ignore_whitespace: 'IGNORE_NONE',
};
config = {auth: {editable_account_fields: []}};
stub('gr-rest-api-interface', {
getLoggedIn() { return Promise.resolve(true); },
getAccount() { return Promise.resolve(account); },
getPreferences() { return Promise.resolve(preferences); },
getDiffPreferences() {
return Promise.resolve(diffPreferences);
},
getWatchedProjects() {
return Promise.resolve([]);
},
@@ -168,6 +149,8 @@ limitations under the License.
.firstElementChild.bindValue, preferences.email_strategy);
assert.equal(valueOf('Email format', 'preferences')
.firstElementChild.bindValue, preferences.email_format);
assert.equal(valueOf('Default Base For Merges', 'preferences')
.firstElementChild.bindValue, preferences.default_base_for_merges);
assert.equal(valueOf('Diff view', 'preferences')
.firstElementChild.bindValue, preferences.diff_view);
assert.equal(valueOf('Show size bars in file list', 'preferences')
@@ -261,56 +244,6 @@ limitations under the License.
});
});
test('diff preferences', done => {
// Rendered with the expected preferences selected.
assert.equal(valueOf('Context', 'diffPreferences')
.firstElementChild.bindValue, diffPreferences.context);
assert.equal(valueOf('Diff width', 'diffPreferences')
.firstElementChild.bindValue, diffPreferences.line_length);
assert.equal(valueOf('Tab width', 'diffPreferences')
.firstElementChild.bindValue, diffPreferences.tab_size);
assert.equal(valueOf('Font size', 'diffPreferences')
.firstElementChild.bindValue, diffPreferences.font_size);
assert.equal(valueOf('Show tabs', 'diffPreferences')
.firstElementChild.checked, diffPreferences.show_tabs);
assert.equal(valueOf('Show trailing whitespace', 'diffPreferences')
.firstElementChild.checked, diffPreferences.show_whitespace_errors);
assert.equal(valueOf('Fit to screen', 'diffPreferences')
.firstElementChild.checked, diffPreferences.line_wrapping);
assert.isFalse(element._diffPrefsChanged);
const showTabsCheckbox = valueOf('Show tabs', 'diffPreferences')
.firstElementChild;
showTabsCheckbox.checked = false;
element._handleDiffShowTabsChanged();
assert.isTrue(element._diffPrefsChanged);
stub('gr-rest-api-interface', {
saveDiffPreferences(prefs) {
assert.equal(prefs.show_tabs, false);
return Promise.resolve();
},
});
// Save the change.
element._handleSaveDiffPreferences().then(() => {
assert.isFalse(element._diffPrefsChanged);
done();
});
});
test('columns input is hidden with fit to scsreen is selected', () => {
assert.isFalse(element.$.columnsPref.hidden);
MockInteractions.tap(element.$.diffLineWrapping);
assert.isTrue(element.$.columnsPref.hidden);
MockInteractions.tap(element.$.diffLineWrapping);
assert.isFalse(element.$.columnsPref.hidden);
});
test('menu', done => {
assert.isFalse(element._menuChanged);
assert.isFalse(element._prefsChanged);

View File

@@ -41,25 +41,30 @@
attached() {
Promise.all([
this.$.restAPI.getConfig(),
this._getConfig(),
Gerrit.awaitPluginsLoaded(),
]).then(([cfg]) => {
this._hasAvatars = !!(cfg && cfg.plugin && cfg.plugin.has_avatars);
if (this._hasAvatars && this.account) {
// src needs to be set if avatar becomes visible
this._updateAvatarURL();
} else {
this.hidden = true;
}
});
},
_getConfig() {
return this.$.restAPI.getConfig();
},
_accountChanged(account) {
this._updateAvatarURL();
},
_updateAvatarURL() {
if (this.hidden || !this._hasAvatars) { return; }
if (!this._hasAvatars || !this.account) {
this.hidden = true;
return;
}
this.hidden = false;
const url = this._buildAvatarURL(this.account);
if (url) {
this.style.backgroundImage = 'url("' + url + '")';

View File

@@ -35,14 +35,17 @@ limitations under the License.
<script>
suite('gr-avatar tests', () => {
let element;
let sandbox;
setup(() => {
stub('gr-rest-api-interface', {
getConfig() { return Promise.resolve({plugin: {has_avatars: true}}); },
});
sandbox = sinon.sandbox.create();
element = fixture('basic');
});
teardown(() => {
sandbox.restore();
});
test('methods', () => {
assert.equal(element._buildAvatarURL(
{
@@ -94,22 +97,32 @@ limitations under the License.
],
}),
'/accounts/123/avatar?s=16');
assert.equal(element._buildAvatarURL(undefined), '');
});
test('dom for existing account', () => {
assert.isFalse(element.hasAttribute('hidden'));
sandbox.stub(element, '_getConfig', () => {
return Promise.resolve({plugin: {has_avatars: true}});
});
element.imageSize = 64;
element.account = {
_account_id: 123,
};
assert.strictEqual(element.style.backgroundImage, '');
// Emulate plugins loaded.
Gerrit._setPluginsPending([]);
return Promise.all([
Promise.all([
element.$.restAPI.getConfig(),
Gerrit.awaitPluginsLoaded(),
]).then(() => {
assert.isFalse(element.hasAttribute('hidden'));
assert.isTrue(
element.style.backgroundImage.includes('/accounts/123/avatar?s=64'));
});
@@ -117,10 +130,57 @@ limitations under the License.
test('dom for non available account', () => {
assert.isFalse(element.hasAttribute('hidden'));
element.account = null;
assert.isFalse(element.hasAttribute('hidden'));
sandbox.stub(element, '_getConfig', () => {
return Promise.resolve({plugin: {has_avatars: true}});
});
// Emulate plugins loaded.
Gerrit._setPluginsPending([]);
return Promise.all([
element.$.restAPI.getConfig(),
Gerrit.awaitPluginsLoaded(),
]).then(() => {
assert.isTrue(element.hasAttribute('hidden'));
assert.strictEqual(element.style.backgroundImage, '');
});
});
test('avatar config not set and account not set', () => {
assert.isFalse(element.hasAttribute('hidden'));
sandbox.stub(element, '_getConfig', () => {
return Promise.resolve({});
});
// Emulate plugins loaded.
Gerrit._setPluginsPending([]);
return Promise.all([
element.$.restAPI.getConfig(),
Gerrit.awaitPluginsLoaded(),
]).then(() => {
assert.isTrue(element.hasAttribute('hidden'));
});
});
test('avatar config not set and account set', () => {
assert.isFalse(element.hasAttribute('hidden'));
sandbox.stub(element, '_getConfig', () => {
return Promise.resolve({});
});
element.imageSize = 64;
element.account = {
_account_id: 123,
};
// Emulate plugins loaded.
Gerrit._setPluginsPending([]);
return Promise.all([
element.$.restAPI.getConfig(),
Gerrit.awaitPluginsLoaded(),

View File

@@ -0,0 +1,163 @@
<!--
@license
Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../gr-button/gr-button.html">
<link rel="import" href="../gr-rest-api-interface/gr-rest-api-interface.html">
<link rel="import" href="../gr-select/gr-select.html">
<dom-module id="gr-diff-preferences">
<template>
<style include="shared-styles"></style>
<style include="gr-form-styles"></style>
<div id="diffPreferences" class="gr-form-styles">
<section>
<span class="title">Context</span>
<span class="value">
<gr-select
id="contextSelect"
bind-value="{{diffPrefs.context}}">
<select
on-keypress="_handleDiffPrefsChanged"
on-change="_handleDiffPrefsChanged">
<option value="3">3 lines</option>
<option value="10">10 lines</option>
<option value="25">25 lines</option>
<option value="50">50 lines</option>
<option value="75">75 lines</option>
<option value="100">100 lines</option>
<option value="-1">Whole file</option>
</select>
</gr-select>
</span>
</section>
<section>
<span class="title">Fit to screen</span>
<span class="value">
<input
id="lineWrappingInput"
type="checkbox"
checked$="[[diffPrefs.line_wrapping]]"
on-change="_handleLineWrappingTap">
</span>
</section>
<section>
<span class="title">Diff width</span>
<span class="value">
<input
is="iron-input"
type="number"
id="columnsInput"
prevent-invalid-input
allowed-pattern="[0-9]"
bind-value="{{diffPrefs.line_length}}"
on-keypress="_handleDiffPrefsChanged"
on-change="_handleDiffPrefsChanged">
</span>
</section>
<section>
<span class="title">Tab width</span>
<span class="value">
<input
is="iron-input"
type="number"
id="tabSizeInput"
prevent-invalid-input
allowed-pattern="[0-9]"
bind-value="{{diffPrefs.tab_size}}"
on-keypress="_handleDiffPrefsChanged"
on-change="_handleDiffPrefsChanged">
</span>
</section>
<section hidden$="[[!diffPrefs.font_size]]">
<span class="title">Font size</span>
<span class="value">
<input
is="iron-input"
type="number"
id="fontSizeInput"
prevent-invalid-input
allowed-pattern="[0-9]"
bind-value="{{diffPrefs.font_size}}"
on-keypress="_handleDiffPrefsChanged"
on-change="_handleDiffPrefsChanged">
</span>
</section>
<section>
<span class="title">Show tabs</span>
<span class="value">
<input
id="showTabsInput"
type="checkbox"
checked$="[[diffPrefs.show_tabs]]"
on-change="_handleShowTabsTap">
</span>
</section>
<section>
<span class="title">Show trailing whitespace</span>
<span class="value">
<input
id="showTrailingWhitespaceInput"
type="checkbox"
checked$="[[diffPrefs.show_whitespace_errors]]"
on-change="_handleShowTrailingWhitespaceTap">
</span>
</section>
<section>
<span class="title">Syntax highlighting</span>
<span class="value">
<input
id="syntaxHighlightInput"
type="checkbox"
checked$="[[diffPrefs.syntax_highlighting]]"
on-change="_handleSyntaxHighlightTap">
</span>
</section>
<section>
<span class="title">Automatically mark viewed files reviewed</span>
<span class="value">
<input
id="automaticReviewInput"
type="checkbox"
checked$="[[diffPrefs.manual_review]]"
on-change="_handleAutomaticReviewTap">
</span>
</section>
<section>
<div class="pref">
<span class="title">Ignore Whitespace</span>
<span class="value">
<gr-select bind-value="{{diffPrefs.ignore_whitespace}}">
<select
on-keypress="_handleDiffPrefsChanged"
on-change="_handleDiffPrefsChanged">
<option value="IGNORE_NONE">None</option>
<option value="IGNORE_TRAILING">Trailing</option>
<option value="IGNORE_LEADING_AND_TRAILING">Leading & trailing</option>
<option value="IGNORE_ALL">All</option>
</select>
</gr-select>
</span>
</div>
</section>
</div>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
</template>
<script src="gr-diff-preferences.js"></script>
</dom-module>

View File

@@ -0,0 +1,78 @@
/**
* @license
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
'use strict';
Polymer({
is: 'gr-diff-preferences',
properties: {
hasUnsavedChanges: {
type: Boolean,
notify: true,
value: false,
},
/** @type {?} */
diffPrefs: Object,
},
loadData() {
return this.$.restAPI.getDiffPreferences().then(prefs => {
this.diffPrefs = prefs;
});
},
_handleDiffPrefsChanged() {
this.hasUnsavedChanges = true;
},
_handleLineWrappingTap() {
this.set('diffPrefs.line_wrapping', this.$.lineWrappingInput.checked);
this._handleDiffPrefsChanged();
},
_handleShowTabsTap() {
this.set('diffPrefs.show_tabs', this.$.showTabsInput.checked);
this._handleDiffPrefsChanged();
},
_handleShowTrailingWhitespaceTap() {
this.set('diffPrefs.show_whitespace_errors',
this.$.showTrailingWhitespaceInput.checked);
this._handleDiffPrefsChanged();
},
_handleSyntaxHighlightTap() {
this.set('diffPrefs.syntax_highlighting',
this.$.syntaxHighlightInput.checked);
this._handleDiffPrefsChanged();
},
_handleAutomaticReviewTap() {
this.set('diffPrefs.manual_review',
this.$.automaticReviewInput.checked);
this._handleDiffPrefsChanged();
},
save() {
return this.$.restAPI.saveDiffPreferences(this.diffPrefs).then(res => {
this.hasUnsavedChanges = false;
});
},
});
})();

View File

@@ -0,0 +1,123 @@
<!DOCTYPE html>
<!--
@license
Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-diff-preferences</title>
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-diff-preferences.html">
<script>void(0);</script>
<test-fixture id="basic">
<template>
<gr-diff-preferences></gr-diff-preferences>
</template>
</test-fixture>
<script>
suite('gr-diff-preferences tests', () => {
let element;
let sandbox;
let diffPreferences;
function valueOf(title, fieldsetid) {
const sections = element.$[fieldsetid].querySelectorAll('section');
let titleEl;
for (let i = 0; i < sections.length; i++) {
titleEl = sections[i].querySelector('.title');
if (titleEl.textContent.trim() === title) {
return sections[i].querySelector('.value');
}
}
}
setup(() => {
diffPreferences = {
context: 10,
line_wrapping: false,
line_length: 100,
tab_size: 8,
font_size: 12,
show_tabs: true,
show_whitespace_errors: true,
syntax_highlighting: true,
manual_review: false,
ignore_whitespace: 'IGNORE_NONE',
};
stub('gr-rest-api-interface', {
getDiffPreferences() {
return Promise.resolve(diffPreferences);
},
});
element = fixture('basic');
sandbox = sinon.sandbox.create();
return element.loadData();
});
teardown(() => { sandbox.restore(); });
test('renders', () => {
// Rendered with the expected preferences selected.
assert.equal(valueOf('Context', 'diffPreferences')
.firstElementChild.bindValue, diffPreferences.context);
assert.equal(valueOf('Fit to screen', 'diffPreferences')
.firstElementChild.checked, diffPreferences.line_wrapping);
assert.equal(valueOf('Diff width', 'diffPreferences')
.firstElementChild.bindValue, diffPreferences.line_length);
assert.equal(valueOf('Tab width', 'diffPreferences')
.firstElementChild.bindValue, diffPreferences.tab_size);
assert.equal(valueOf('Font size', 'diffPreferences')
.firstElementChild.bindValue, diffPreferences.font_size);
assert.equal(valueOf('Show tabs', 'diffPreferences')
.firstElementChild.checked, diffPreferences.show_tabs);
assert.equal(valueOf('Show trailing whitespace', 'diffPreferences')
.firstElementChild.checked, diffPreferences.show_whitespace_errors);
assert.equal(valueOf('Syntax highlighting', 'diffPreferences')
.firstElementChild.checked, diffPreferences.syntax_highlighting);
assert.equal(
valueOf('Automatically mark viewed files reviewed', 'diffPreferences')
.firstElementChild.checked, diffPreferences.manual_review);
assert.equal(valueOf('Ignore Whitespace', 'diffPreferences')
.firstElementChild.bindValue, diffPreferences.ignore_whitespace);
assert.isFalse(element.hasUnsavedChanges);
});
test('save changes', () => {
sandbox.stub(element.$.restAPI, 'saveDiffPreferences')
.returns(Promise.resolve());
const showTrailingWhitespaceCheckbox =
valueOf('Show trailing whitespace', 'diffPreferences')
.firstElementChild;
showTrailingWhitespaceCheckbox.checked = false;
element._handleShowTrailingWhitespaceTap();
assert.isTrue(element.hasUnsavedChanges);
// Save the change.
return element.save().then(() => {
assert.isFalse(element.hasUnsavedChanges);
});
});
});
</script>

View File

@@ -108,7 +108,6 @@ limitations under the License.
'diff/gr-diff-highlight/gr-annotation_test.html',
'diff/gr-diff-highlight/gr-diff-highlight_test.html',
'diff/gr-diff-mode-selector/gr-diff-mode-selector_test.html',
'diff/gr-diff-preferences/gr-diff-preferences_test.html',
'diff/gr-diff-processor/gr-diff-processor_test.html',
'diff/gr-diff-selection/gr-diff-selection_test.html',
'diff/gr-diff-view/gr-diff-view_test.html',
@@ -162,6 +161,7 @@ limitations under the License.
'shared/gr-cursor-manager/gr-cursor-manager_test.html',
'shared/gr-date-formatter/gr-date-formatter_test.html',
'shared/gr-dialog/gr-dialog_test.html',
'shared/gr-diff-preferences/gr-diff-preferences_test.html',
'shared/gr-download-commands/gr-download-commands_test.html',
'shared/gr-dropdown-list/gr-dropdown-list_test.html',
'shared/gr-editable-content/gr-editable-content_test.html',