Merge branch 'stable-3.0' into stable-3.1

* stable-3.0:
  Bump Bazel version to 2.0.0
  Set version in package.json to 3.0.7-SNAPSHOT
  Set version in package.json to 2.16.16-SNAPSHOT
  Use gerritCheck API for posting checker result
  Update git submodules
  Downport "Replace deprecated `require-jsdoc`, `valid-jsdoc` with jsdoc plugin for eslint"
  Downport "Add a shared pre-commit to run eslintfix for frontend code changes"
  Downport "Remove `|| exit 0` as eslint already supported correct exit code"
  Downport "Update eslint version and eslint rules"
  Downport "Simplify installing / running polylint"
  Downport "Make `npm start` run run-server.sh"
  Downport "Simplify installing / running template tests"
  Downport "Simplify installing and running eslint"
  Downport "Simplify running frontend tests via package.json"

Change-Id: Ic08aecefc55b0434a32c6d6836fd4019e26ace72
This commit is contained in:
David Ostrovsky
2020-01-04 13:41:34 +01:00
155 changed files with 868 additions and 567 deletions

View File

@@ -1 +1 @@
1.2.0
2.0.0

26
Jenkinsfile vendored
View File

@@ -53,15 +53,11 @@ class Builds {
class GerritCheck {
String uuid
String changeNum
String sha1
Build build
GerritCheck(name, changeNum, sha1, build) {
GerritCheck(name, build) {
this.uuid = "gerritforge:" + name.replaceAll("(bazel/)", "") +
Globals.gerritRepositoryNameSha1Suffix
this.changeNum = changeNum
this.sha1 = sha1
this.build = build
}
@@ -93,21 +89,7 @@ def hasChangeNumber() {
}
def postCheck(check) {
def gerritPostUrl = Globals.gerritUrl +
"a/changes/${check.changeNum}/revisions/${check.sha1}/checks"
try {
def json = check.createCheckPayload()
httpRequest(httpMode: 'POST', authentication: Globals.gerritCredentialsId,
contentType: 'APPLICATION_JSON', requestBody: json,
validResponseCodes: '200', url: gerritPostUrl)
echo "----------------------------------------------------------------------------"
echo "Gerrit Check: ${check.uuid}=" + check.build.result + " to change " +
check.changeNum + "/" + check.sha1
echo "----------------------------------------------------------------------------"
} catch(Exception e) {
echo "ERROR> Failed to post check results to Gerrit: ${e}"
}
gerritCheck(checks: [ "${check.uuid}" : "${check.getCheckResultFromBuild()}" ])
}
def queryChangedFiles(url, changeNum, sha1) {
@@ -313,7 +295,7 @@ node ('master') {
gerritReview(
labels: ['Code-Style': resCodeStyle],
message: createCodeStyleMsgBody(Builds.codeStyle, resCodeStyle))
postCheck(new GerritCheck("codestyle", Change.number, Change.sha1, Builds.codeStyle))
postCheck(new GerritCheck("codestyle", Builds.codeStyle))
def verificationResults = Builds.verification.collect { k, v -> v }
def resVerify = verificationResults.inject(1) {
@@ -324,7 +306,7 @@ node ('master') {
message: createVerifyMsgBody(Builds.verification))
Builds.verification.each { type, build -> postCheck(
new GerritCheck(type, Change.number, Change.sha1, build)
new GerritCheck(type, build)
)}
setResult(resVerify, resCodeStyle)

View File

@@ -4,9 +4,10 @@
"description": "Gerrit Code Review",
"dependencies": {},
"devDependencies": {
"eslint": "^5.16.0",
"eslint": "^6.6.0",
"eslint-config-google": "^0.13.0",
"eslint-plugin-html": "^5.0.5",
"eslint-plugin-html": "^6.0.0",
"eslint-plugin-jsdoc": "^18.4.3",
"fried-twinkie": "^0.2.2",
"polylint": "^2.10.4",
"typescript": "^2.x.x",
@@ -15,7 +16,8 @@
"scripts": {
"start": "polygerrit-ui/run-server.sh",
"test": "WCT_HEADLESS_MODE=1 WCT_ARGS='--verbose -l chrome' ./polygerrit-ui/app/run_test.sh",
"eslint": "./node_modules/eslint/bin/eslint.js --ignore-pattern 'bower_components/' --ignore-pattern 'gr-linked-text' --ignore-pattern 'scripts/vendor' --ext .html,.js polygerrit-ui/app || exit 0",
"eslint": "./node_modules/eslint/bin/eslint.js --ext .html,.js polygerrit-ui/app",
"eslintfix": "npm run eslint -- --fix",
"test-template": "./polygerrit-ui/app/run_template_test.sh",
"polylint": "bazel test polygerrit-ui/app:polylint_test"
},

View File

@@ -48,7 +48,13 @@ simply execute:
./polygerrit-ui/run-server.sh
```
Then visit <http://localhost:8081>.
Then visit http://localhost:8081
## Local UI, Test Data
```sh
./polygerrit-ui/run-server.sh --plugins=plugins/my_plugin/static/my_plugin.js,plugins/my_plugin/static/my_plugin.html
```
This method is based on a
[simple hand-written Go webserver](https://gerrit.googlesource.com/gerrit/+/master/polygerrit-ui/server.go).

View File

@@ -33,8 +33,7 @@
"functions": "never"
}],
"eol-last": "off",
"indent": "off",
"indent-legacy": ["error", 2, {
"indent": ["error", 2, {
"MemberExpression": 2,
"FunctionDeclaration": {"body": 1, "parameters": 2},
"FunctionExpression": {"body": 1, "parameters": 2},
@@ -44,13 +43,14 @@
"SwitchCase": 1
}],
"keyword-spacing": ["error", { "after": true, "before": true }],
"lines-between-class-members": ["error", "always"],
"max-len": [
"error",
80,
2,
{"ignoreComments": true}
],
"new-cap": ["error", { "capIsNewExceptions": ["Polymer"] }],
"new-cap": ["error", { "capIsNewExceptions": ["Polymer", "LegacyElementMixin", "GestureEventListeners", "LegacyDataMixin"] }],
"no-console": "off",
"no-restricted-syntax": [
"error",
@@ -70,17 +70,58 @@
"no-redeclare": "off",
"operator-linebreak": "off",
"object-shorthand": ["error", "always"],
"padding-line-between-statements": [
"error",
{
"blankLine": "always",
"prev": "class",
"next": "*"
},
{
"blankLine": "always",
"prev": "*",
"next": "class"
}
],
"prefer-arrow-callback": "error",
"prefer-const": "error",
"prefer-spread": "error",
"quote-props": ["error", "consistent-as-needed"],
"require-jsdoc": "off",
"semi": [2, "always"],
"template-curly-spacing": "error",
"valid-jsdoc": "off"
"require-jsdoc": 0,
"valid-jsdoc": 0,
"jsdoc/check-alignment": 2,
"jsdoc/check-examples": 0,
"jsdoc/check-indentation": 0,
"jsdoc/check-param-names": 0,
"jsdoc/check-syntax": 0,
"jsdoc/check-tag-names": 0,
"jsdoc/check-types": 0,
"jsdoc/implements-on-classes": 2,
"jsdoc/match-description": 0,
"jsdoc/newline-after-description": 2,
"jsdoc/no-types": 0,
"jsdoc/no-undefined-types": 0,
"jsdoc/require-description": 0,
"jsdoc/require-description-complete-sentence": 0,
"jsdoc/require-example": 0,
"jsdoc/require-hyphen-before-param-description": 0,
"jsdoc/require-jsdoc": 0,
"jsdoc/require-param": 0,
"jsdoc/require-param-description": 0,
"jsdoc/require-param-name": 2,
"jsdoc/require-param-type": 2,
"jsdoc/require-returns": 0,
"jsdoc/require-returns-check": 0,
"jsdoc/require-returns-description": 0,
"jsdoc/require-returns-type": 2,
"jsdoc/valid-types": 2
},
"plugins": [
"html"
"html",
"jsdoc"
],
"settings": {
"html/report-bad-indent": "error"

View File

@@ -31,6 +31,7 @@ limitations under the License.
/**
* Get the docs base URL from either the server config or by probing.
*
* @param {Object} config The server config.
* @param {!Object} restApi A REST API instance
* @return {!Promise<string>} A promise that resolves with the docs base
@@ -56,7 +57,7 @@ limitations under the License.
cachedPromise = undefined;
},
},
Gerrit.BaseUrlBehavior,
Gerrit.BaseUrlBehavior,
];
})(window);
</script>

View File

@@ -25,6 +25,7 @@ limitations under the License.
/**
* Are any ancestors of the element (or the element itself) members of the
* given class.
*
* @param {!Element} element
* @param {string} className
* @param {Element=} opt_stopElement If provided, stop traversing the

View File

@@ -41,6 +41,7 @@ limitations under the License.
/**
* Returns the complement to the given column array
*
* @param {Array} columns
* @return {!Array}
*/
@@ -63,6 +64,7 @@ limitations under the License.
* The Project column was renamed to Repo, but some users may have
* preferences that use its old name. If that column is found, rename it
* before use.
*
* @param {!Array<string>} columns
* @return {!Array<string>} If the column was renamed, returns a new array
* with the corrected name. Otherwise, it returns the original param.

View File

@@ -56,8 +56,8 @@ limitations under the License.
return 0;
},
},
Gerrit.BaseUrlBehavior,
Gerrit.URLEncodingBehavior,
Gerrit.BaseUrlBehavior,
Gerrit.URLEncodingBehavior,
];
})(window);
</script>

View File

@@ -52,6 +52,7 @@ limitations under the License.
/**
* Whether the given patch is a numbered parent of a merge (i.e. a negative
* number).
*
* @param {string|number} n
* @return {Boolean}
*/
@@ -124,8 +125,8 @@ limitations under the License.
// 2 -> 3, 3 -> 5, etc.
// Map an edit to the patchNum of parent*2... I.e. edit on 2 -> 4.
const num = r => r._number === Gerrit.PatchSetBehavior.EDIT_NAME ?
2 * editParent :
2 * (r._number - 1) + 1;
2 * editParent :
2 * (r._number - 1) + 1;
return revisions.sort((a, b) => num(b) - num(a));
},
@@ -265,6 +266,7 @@ limitations under the License.
/**
* Convert parent indexes from patch range expressions to numbers.
* For example, in a patch range expression `"-3"` becomes `3`.
*
* @param {number|string} rangeBase
* @return {number}
*/

View File

@@ -25,6 +25,7 @@ limitations under the License.
/**
* Pretty-encodes a URL. Double-encodes the string, and then replaces
* benevolent characters for legibility.
*
* @param {string} url
* @param {boolean=} replaceSlashes
* @return {string}
@@ -45,6 +46,7 @@ limitations under the License.
* Single decode for URL components. Will decode plus signs ('+') to spaces.
* Note: because this function decodes once, it is not the inverse of
* encodeURL.
*
* @param {string} url
* @return {string}
*/

View File

@@ -240,8 +240,8 @@ limitations under the License.
test('directory view', () => {
const {
NEXT_FILE, NEXT_LINE, GO_TO_OPENED_CHANGES, SEARCH,
SAVE_COMMENT,
NEXT_FILE, NEXT_LINE, GO_TO_OPENED_CHANGES, SEARCH,
SAVE_COMMENT,
} = kb.Shortcut;
const {DIFFS, EVERYWHERE, NAVIGATION} = kb.ShortcutSection;
const {GO_KEY, ShortcutManager} = kb;

View File

@@ -175,7 +175,7 @@ limitations under the License.
return this.changeStatuses(change).join(', ');
},
},
Gerrit.BaseUrlBehavior,
Gerrit.BaseUrlBehavior,
];
})(window);
</script>

View File

@@ -28,6 +28,7 @@ limitations under the License.
/**
* Wraps a string to be used as a URL. An error is thrown if the string cannot
* be considered safe.
*
* @constructor
* @param {string} url the unwrapped, potentially unsafe URL.
*/
@@ -40,6 +41,7 @@ limitations under the License.
/**
* Get the string representation of the safe URL.
*
* @returns {string}
*/
Gerrit.SafeTypes.SafeUrl.prototype.asString = function() {

View File

@@ -25,6 +25,7 @@
/**
* Fired when a section that was previously added was removed.
*
* @event added-section-removed
*/

View File

@@ -208,7 +208,7 @@ limitations under the License.
};
assert.equal(element._computePermissionName(name, permission,
element.permissionValues, element.capabilities),
element.capabilities[permission.id].name);
element.capabilities[permission.id].name);
name = 'refs/for/*';
permission = {
@@ -218,7 +218,7 @@ limitations under the License.
assert.equal(element._computePermissionName(
name, permission, element.permissionValues, element.capabilities),
element.permissionValues[permission.id].name);
element.permissionValues[permission.id].name);
name = 'refs/for/*';
permission = {
@@ -230,7 +230,7 @@ limitations under the License.
assert.equal(element._computePermissionName(name, permission,
element.permissionValues, element.capabilities),
'Label Code-Review');
'Label Code-Review');
permission = {
id: 'labelAs-Code-Review',
@@ -241,7 +241,7 @@ limitations under the License.
assert.equal(element._computePermissionName(name, permission,
element.permissionValues, element.capabilities),
'Label Code-Review(On Behalf Of)');
'Label Code-Review(On Behalf Of)');
});
test('_computeSectionName', () => {

View File

@@ -88,6 +88,7 @@
/**
* Opens the create overlay if the route has a hash 'create'
*
* @param {!Object} params
*/
_maybeOpenCreateOverlay(params) {
@@ -120,11 +121,11 @@
return;
}
this._groups = Object.keys(groups)
.map(key => {
const group = groups[key];
group.name = key;
return group;
});
.map(key => {
const group = groups[key];
group.name = key;
return group;
});
this._loading = false;
});
},

View File

@@ -105,23 +105,23 @@
.then(res => {
this._filteredLinks = res.links;
this._breadcrumbParentName = res.expandedSection ?
res.expandedSection.name : '';
res.expandedSection.name : '';
if (!res.expandedSection) {
this._subsectionLinks = [];
return;
}
this._subsectionLinks = [res.expandedSection]
.concat(res.expandedSection.children).map(section => {
return {
text: !section.detailType ? 'Home' : section.name,
value: section.view + (section.detailType || ''),
view: section.view,
url: section.url,
detailType: section.detailType,
parent: this._groupId || this._repoName || '',
};
});
.concat(res.expandedSection.children).map(section => {
return {
text: !section.detailType ? 'Home' : section.name,
value: section.view + (section.detailType || ''),
view: section.view,
url: section.url,
detailType: section.detailType,
parent: this._groupId || this._repoName || '',
};
});
});
});
},

View File

@@ -107,21 +107,21 @@
}
return this.$.restAPI.getRepoBranches(
input, this.repoName, SUGGESTIONS_LIMIT).then(response => {
const branches = [];
let branch;
for (const key in response) {
if (!response.hasOwnProperty(key)) { continue; }
if (response[key].ref.startsWith('refs/heads/')) {
branch = response[key].ref.substring('refs/heads/'.length);
} else {
branch = response[key].ref;
}
branches.push({
name: branch,
});
}
return branches;
const branches = [];
let branch;
for (const key in response) {
if (!response.hasOwnProperty(key)) { continue; }
if (response[key].ref.startsWith('refs/heads/')) {
branch = response[key].ref.substring('refs/heads/'.length);
} else {
branch = response[key].ref;
}
branches.push({
name: branch,
});
}
return branches;
});
},
_formatBooleanString(config) {

View File

@@ -141,15 +141,15 @@
_handleSavingGroupMember() {
return this.$.restAPI.saveGroupMembers(this._groupName,
this._groupMemberSearchId).then(config => {
if (!config) {
return;
}
this.$.restAPI.getGroupMembers(this._groupName).then(members => {
this._groupMembers = members;
});
this._groupMemberSearchName = '';
this._groupMemberSearchId = '';
});
if (!config) {
return;
}
this.$.restAPI.getGroupMembers(this._groupName).then(members => {
this._groupMembers = members;
});
this._groupMemberSearchName = '';
this._groupMemberSearchId = '';
});
},
_handleDeleteConfirm() {
@@ -239,24 +239,24 @@
if (input.length === 0) { return Promise.resolve([]); }
return this.$.restAPI.getSuggestedAccounts(
input, SUGGESTIONS_LIMIT).then(accounts => {
const accountSuggestions = [];
let nameAndEmail;
if (!accounts) { return []; }
for (const key in accounts) {
if (!accounts.hasOwnProperty(key)) { continue; }
if (accounts[key].email !== undefined) {
nameAndEmail = accounts[key].name +
const accountSuggestions = [];
let nameAndEmail;
if (!accounts) { return []; }
for (const key in accounts) {
if (!accounts.hasOwnProperty(key)) { continue; }
if (accounts[key].email !== undefined) {
nameAndEmail = accounts[key].name +
' <' + accounts[key].email + '>';
} else {
nameAndEmail = accounts[key].name;
}
accountSuggestions.push({
name: nameAndEmail,
value: accounts[key]._account_id,
});
}
return accountSuggestions;
} else {
nameAndEmail = accounts[key].name;
}
accountSuggestions.push({
name: nameAndEmail,
value: accounts[key]._account_id,
});
}
return accountSuggestions;
});
},
_getGroupSuggestions(input) {

View File

@@ -169,10 +169,10 @@ limitations under the License.
.querySelectorAll('.nameColumn a')[0].href, includedGroups[0].url);
assert.equal(Polymer.dom(element.root)
.querySelectorAll('.nameColumn a')[1].href,
'https://test/site/group/url');
'https://test/site/group/url');
assert.equal(Polymer.dom(element.root)
.querySelectorAll('.nameColumn a')[2].href,
'https://test/site/group/url');
'https://test/site/group/url');
});
test('save members correctly', () => {

View File

@@ -172,15 +172,15 @@
}
return this.$.restAPI.saveGroupOwner(this.groupId,
owner).then(config => {
this._owner = false;
});
this._owner = false;
});
},
_handleSaveDescription() {
return this.$.restAPI.saveGroupDescription(this.groupId,
this._groupConfig.description).then(config => {
this._description = false;
});
this._description = false;
});
},
_handleSaveOptions() {
@@ -190,8 +190,8 @@
return this.$.restAPI.saveGroupOptions(this.groupId,
options).then(config => {
this._options = false;
});
this._options = false;
});
},
_handleConfigName() {

View File

@@ -32,6 +32,7 @@
/**
* Fired when a permission that was previously added was removed.
*
* @event added-permission-removed
*/
@@ -228,7 +229,7 @@
_computeGroupName(groups, groupId) {
return groups && groups[groupId] && groups[groupId].name ?
groups[groupId].name : groupId;
groups[groupId].name : groupId;
},
_getGroupSuggestions() {

View File

@@ -92,11 +92,11 @@
return;
}
this._plugins = Object.keys(plugins)
.map(key => {
const plugin = plugins[key];
plugin.name = key;
return plugin;
});
.map(key => {
const plugin = plugins[key];
plugin.name = key;
return plugin;
});
this._loading = false;
});
},

View File

@@ -167,7 +167,7 @@
// current value appears. If there is no parent repo, it is
// initialized as an empty string.
this._inheritFromFilter = res.inherits_from ?
this._inheritsFrom.name : '';
this._inheritsFrom.name : '';
this._local = res.local;
this._groups = res.groups;
this._weblinks = res.config_web_links || [];
@@ -346,6 +346,7 @@
/**
* As add / delete both can happen in the new section,
* so here to make sure it will remove the deleted ones.
*
* @see Issue 11339
*/
this._recursivelyRemoveDeleted(addRemoveObj.add[k]);
@@ -370,11 +371,11 @@
};
const originalInheritsFromId = this._originalInheritsFrom ?
this.singleDecodeURL(this._originalInheritsFrom.id) :
null;
this.singleDecodeURL(this._originalInheritsFrom.id) :
null;
const inheritsFromId = this._inheritsFrom ?
this.singleDecodeURL(this._inheritsFrom.id) :
null;
this.singleDecodeURL(this._inheritsFrom.id) :
null;
const inheritFromChanged =
// Inherit from changed

View File

@@ -676,7 +676,7 @@ limitations under the License.
Polymer.dom(element.$$('gr-access-section').root).querySelectorAll(
'gr-permission')[2];
newPermission._handleAddRuleItem(
{detail: {value: {id: 'Maintainers'}}});
{detail: {value: {id: 'Maintainers'}}});
assert.deepEqual(element._computeAddAndRemove(), expectedInput);
// Modify a section reference.
@@ -909,7 +909,7 @@ limitations under the License.
Polymer.dom(element.$$('gr-access-section').root).querySelectorAll(
'gr-permission')[1];
readPermission._handleAddRuleItem(
{detail: {value: {id: 'Maintainers'}}});
{detail: {value: {id: 'Maintainers'}}});
expectedInput = {
add: {

View File

@@ -101,17 +101,16 @@
_handleEditRepoConfig() {
return this.$.restAPI.createChange(this.repo, CONFIG_BRANCH,
EDIT_CONFIG_SUBJECT, undefined, false, true).then(change => {
const message = change ?
CREATE_CHANGE_SUCCEEDED_MESSAGE :
CREATE_CHANGE_FAILED_MESSAGE;
this.dispatchEvent(new CustomEvent(
'show-alert',
{detail: {message}, bubbles: true, composed: true}));
if (!change) { return; }
const message = change ?
CREATE_CHANGE_SUCCEEDED_MESSAGE :
CREATE_CHANGE_FAILED_MESSAGE;
this.dispatchEvent(new CustomEvent('show-alert',
{detail: {message}, bubbles: true, composed: true}));
if (!change) { return; }
Gerrit.Nav.navigateToRelativeUrl(Gerrit.Nav.getEditUrlForDiff(
change, CONFIG_PATH, INITIAL_PATCHSET));
});
Gerrit.Nav.navigateToRelativeUrl(Gerrit.Nav.getEditUrlForDiff(
change, CONFIG_PATH, INITIAL_PATCHSET));
});
},
});
})();

View File

@@ -49,7 +49,7 @@
// Group by ref and sort by id.
const dashboards = res.concat.apply([], res).sort((a, b) =>
a.id < b.id ? -1 : 1);
a.id < b.id ? -1 : 1);
const dashboardsByRef = {};
dashboards.forEach(d => {
if (!dashboardsByRef[d.ref]) {

View File

@@ -91,7 +91,7 @@
_determineIfOwner(repo) {
return this.$.restAPI.getRepoAccess(repo)
.then(access =>
this._isOwner = access && !!access[repo].is_owner);
this._isOwner = access && !!access[repo].is_owner);
},
_paramsChanged(params) {
@@ -125,17 +125,17 @@
if (detailType === DETAIL_TYPES.BRANCHES) {
return this.$.restAPI.getRepoBranches(
filter, repo, itemsPerPage, offset, errFn).then(items => {
if (!items) { return; }
this._items = items;
this._loading = false;
});
if (!items) { return; }
this._items = items;
this._loading = false;
});
} else if (detailType === DETAIL_TYPES.TAGS) {
return this.$.restAPI.getRepoTags(
filter, repo, itemsPerPage, offset, errFn).then(items => {
if (!items) { return; }
this._items = items;
this._loading = false;
});
if (!items) { return; }
this._items = items;
this._loading = false;
});
}
},
@@ -174,7 +174,7 @@
_computeCanEditClass(ref, detailType, isOwner) {
return isOwner && this._stripRefs(ref, detailType) === 'HEAD' ?
'canEdit' : '';
'canEdit' : '';
},
_handleEditRevision(e) {

View File

@@ -155,9 +155,9 @@ limitations under the License.
const cancelBtn = Polymer.dom(element.root).querySelector('.cancelBtn');
const editBtn = Polymer.dom(element.root).querySelector('.editBtn');
const revisionNoEditing = Polymer.dom(element.root)
.querySelector('.revisionNoEditing');
.querySelector('.revisionNoEditing');
const revisionWithEditing = Polymer.dom(element.root)
.querySelector('.revisionWithEditing');
.querySelector('.revisionWithEditing');
sandbox.stub(element, '_getLoggedIn').returns(Promise.resolve(true));
sandbox.stub(element.$.restAPI, 'getRepoAccess').returns(

View File

@@ -90,6 +90,7 @@
/**
* Opens the create overlay if the route has a hash 'create'
*
* @param {!Object} params
*/
_maybeOpenCreateOverlay(params) {

View File

@@ -54,7 +54,7 @@ limitations under the License.
{base: {config: {}}}), []);
assert.deepEqual(element._computePluginConfigOptions(
{base: {config: {testKey: 'testInfo'}}}),
[{_key: 'testKey', info: 'testInfo'}]);
[{_key: 'testKey', info: 'testInfo'}]);
});
test('_computeDisabled', () => {

View File

@@ -283,8 +283,8 @@
_handleSaveRepoConfig() {
return this.$.restAPI.saveRepoConfig(this.repo,
this._formatRepoConfigForSave(this._repoConfig)).then(() => {
this._configChanged = false;
});
this._configChanged = false;
});
},
_handleConfigChanged() {
@@ -327,7 +327,7 @@
command: commandObj[title]
.replace(/\$\{project\}/gi, encodeURI(repo))
.replace(/\$\{project-base-name\}/gi,
encodeURI(repo.substring(repo.lastIndexOf('/') + 1))),
encodeURI(repo.substring(repo.lastIndexOf('/') + 1))),
});
}
return commands;

View File

@@ -25,6 +25,7 @@
/**
* Fired when a rule that was previously added was removed.
*
* @event added-rule-removed
*/

View File

@@ -125,7 +125,7 @@ limitations under the License.
let permission = 'priority';
let label;
assert.deepEqual(element._getDefaultRuleValues(permission, label),
{action: 'BATCH'});
{action: 'BATCH'});
permission = 'label-Code-Review';
label = {values: [
{value: -2, text: 'This shall not be merged'},
@@ -139,7 +139,7 @@ limitations under the License.
permission = 'push';
label = undefined;
assert.deepEqual(element._getDefaultRuleValues(permission, label),
{action: 'ALLOW', force: false});
{action: 'ALLOW', force: false});
permission = 'submit';
assert.deepEqual(element._getDefaultRuleValues(permission, label),
{action: 'ALLOW'});

View File

@@ -59,31 +59,31 @@ limitations under the License.
{labels: {}}, 'Verified'), 'cell label u-gray-background');
assert.equal(element._computeLabelClass(
{labels: {Verified: {approved: true, value: 1}}}, 'Verified'),
'cell label u-green u-monospace');
'cell label u-green u-monospace');
assert.equal(element._computeLabelClass(
{labels: {Verified: {rejected: true, value: -1}}}, 'Verified'),
'cell label u-monospace u-red');
'cell label u-monospace u-red');
assert.equal(element._computeLabelClass(
{labels: {'Code-Review': {value: 1}}}, 'Code-Review'),
'cell label u-green u-monospace');
'cell label u-green u-monospace');
assert.equal(element._computeLabelClass(
{labels: {'Code-Review': {value: -1}}}, 'Code-Review'),
'cell label u-monospace u-red');
'cell label u-monospace u-red');
assert.equal(element._computeLabelClass(
{labels: {'Code-Review': {value: -1}}}, 'Verified'),
'cell label u-gray-background');
'cell label u-gray-background');
assert.equal(element._computeLabelTitle({labels: {}}, 'Verified'),
'Label not applicable');
assert.equal(element._computeLabelTitle(
{labels: {Verified: {approved: {name: 'Diffy'}}}}, 'Verified'),
'Verified\nby Diffy');
'Verified\nby Diffy');
assert.equal(element._computeLabelTitle(
{labels: {Verified: {approved: {name: 'Diffy'}}}}, 'Code-Review'),
'Label not applicable');
'Label not applicable');
assert.equal(element._computeLabelTitle(
{labels: {Verified: {rejected: {name: 'Diffy'}}}}, 'Verified'),
'Verified\nby Diffy');
'Verified\nby Diffy');
assert.equal(element._computeLabelTitle(
{labels: {'Code-Review': {disliked: {name: 'Diffy'}, value: -1}}},
'Code-Review'), 'Code-Review\nby Diffy');
@@ -93,19 +93,19 @@ limitations under the License.
assert.equal(element._computeLabelTitle(
{labels: {'Code-Review': {recommended: {name: 'Diffy'},
rejected: {name: 'Admin'}}}}, 'Code-Review'),
'Code-Review\nby Admin');
'Code-Review\nby Admin');
assert.equal(element._computeLabelTitle(
{labels: {'Code-Review': {approved: {name: 'Diffy'},
rejected: {name: 'Admin'}}}}, 'Code-Review'),
'Code-Review\nby Admin');
'Code-Review\nby Admin');
assert.equal(element._computeLabelTitle(
{labels: {'Code-Review': {recommended: {name: 'Diffy'},
disliked: {name: 'Admin'}, value: -1}}}, 'Code-Review'),
'Code-Review\nby Admin');
'Code-Review\nby Admin');
assert.equal(element._computeLabelTitle(
{labels: {'Code-Review': {approved: {name: 'Diffy'},
disliked: {name: 'Admin'}, value: -1}}}, 'Code-Review'),
'Code-Review\nby Diffy');
'Code-Review\nby Diffy');
assert.equal(element._computeLabelValue({labels: {}}), '');
assert.equal(element._computeLabelValue({labels: {}}, 'Verified'), '');

View File

@@ -71,6 +71,7 @@
*
* Need sub-property declaration since it is used in template before
* assignment.
*
* @type {{ selectedChangeIndex: (number|undefined) }}
*
*/

View File

@@ -169,7 +169,7 @@
this.showNumber = !!(preferences &&
preferences.legacycid_in_change_table);
this.visibleChangeTableColumns = preferences.change_table.length > 0 ?
this.getVisibleColumns(preferences.change_table) : this.columnNames;
this.getVisibleColumns(preferences.change_table) : this.columnNames;
} else {
// Not logged in.
this.showNumber = false;

View File

@@ -113,7 +113,7 @@ limitations under the License.
test('computed fields', () => {
assert.equal(element._computeLabelNames(
[{results: [{_number: 0, labels: {}}]}]).length, 0);
[{results: [{_number: 0, labels: {}}]}]).length, 0);
assert.equal(element._computeLabelNames([
{results: [
{_number: 0, labels: {Verified: {approved: {}}}},

View File

@@ -109,21 +109,21 @@
};
return this.$.restAPI.getDashboard(
project, dashboard, errFn).then(response => {
if (!response) {
return;
}
if (!response) {
return;
}
return {
title: response.title,
sections: response.sections.map(section => {
const suffix = response.foreach ? ' ' + response.foreach : '';
return {
title: response.title,
sections: response.sections.map(section => {
const suffix = response.foreach ? ' ' + response.foreach : '';
return {
name: section.name,
query: (section.query + suffix).replace(
PROJECT_PLACEHOLDER_PATTERN, project),
};
}),
name: section.name,
query: (section.query + suffix).replace(
PROJECT_PLACEHOLDER_PATTERN, project),
};
});
}),
};
});
},
_computeTitle(user) {
@@ -156,11 +156,11 @@
this._loading = true;
const {project, dashboard, title, user, sections} = this.params;
const dashboardPromise = project ?
this._getProjectDashboard(project, dashboard) :
Promise.resolve(Gerrit.Nav.getUserDashboard(
user,
sections,
title || this._computeTitle(user)));
this._getProjectDashboard(project, dashboard) :
Promise.resolve(Gerrit.Nav.getUserDashboard(
user,
sections,
title || this._computeTitle(user)));
const checkForNewUser = !project && user === 'self';
return dashboardPromise
@@ -194,8 +194,8 @@
const queries = res.sections
.map(section => section.suffixForDashboard ?
section.query + ' ' + section.suffixForDashboard :
section.query);
section.query + ' ' + section.suffixForDashboard :
section.query);
if (checkForNewUser) {
queries.push('owner:self limit:1');
@@ -215,7 +215,7 @@
results,
isOutgoing: res.sections[i].isOutgoing,
})).filter((section, i) => i < res.sections.length && (
!res.sections[i].hideIfEmpty ||
!res.sections[i].hideIfEmpty ||
section.results.length));
});
},

View File

@@ -89,7 +89,7 @@
_computeDashboardLinkClass(showDashboardLink, loggedIn) {
return showDashboardLink && loggedIn ?
'dashboardLink' : 'dashboardLink hide';
'dashboardLink' : 'dashboardLink hide';
},
});
})();

View File

@@ -201,7 +201,7 @@
/**
* Fired when an action is tapped.
*
* @event <action key>-tap
* @event custom-tap - naming pattern: <action key>-tap
*/
/**
@@ -625,9 +625,9 @@
}
},
/**
* @param {string=} actionName
*/
/**
* @param {string=} actionName
*/
_deleteAndNotify(actionName) {
if (this.actions && this.actions[actionName]) {
delete this.actions[actionName];
@@ -868,6 +868,7 @@
/**
* Capitalize the first letter and lowecase all others.
*
* @param {string} s
* @return {string}
*/
@@ -1362,6 +1363,7 @@
/**
* Merge sources of change actions into a single ordered array of action
* values.
*
* @param {!Array} changeActionsRecord
* @param {!Array} revisionActionsRecord
* @param {!Array} primariesRecord
@@ -1448,9 +1450,9 @@
_filterPrimaryActions(_topLevelActions) {
this._topLevelPrimaryActions = _topLevelActions.filter(action =>
action.__primary);
action.__primary);
this._topLevelSecondaryActions = _topLevelActions.filter(action =>
!action.__primary);
!action.__primary);
},
_computeMenuActions(actionRecord, hiddenActionsRecord) {

View File

@@ -378,7 +378,7 @@ limitations under the License.
element._handleRebaseConfirm({detail: {base: '1234'}});
rebaseAction.rebaseOnCurrent = true;
assert.deepEqual(fireActionStub.lastCall.args,
['/rebase', rebaseAction, true, {base: '1234'}]);
['/rebase', rebaseAction, true, {base: '1234'}]);
done();
});
});

View File

@@ -114,7 +114,7 @@ limitations under the License.
js_resource_paths: [],
html_resource_paths: [
new URL('test/plugin.html?' + Math.random(),
window.location.href).toString(),
window.location.href).toString(),
],
},
};
@@ -140,7 +140,7 @@ limitations under the License.
setup(() => {
Gerrit.install(p => plugin = p, '0.1',
new URL('test/plugin.html?' + Math.random(),
window.location.href).toString());
window.location.href).toString());
sandbox.stub(Gerrit, '_arePluginsLoaded').returns(true);
Gerrit._loadPlugins([]);
element = createElement();

View File

@@ -228,12 +228,13 @@
this._newHashtag = '';
this.$.restAPI.setChangeHashtag(
this.change._number, {add: [newHashtag]}).then(newHashtag => {
this.set(['change', 'hashtags'], newHashtag);
if (newHashtag !== lastHashtag) {
this.dispatchEvent(new CustomEvent(
'hashtag-changed', {bubbles: true, composed: true}));
}
});
this.set(['change', 'hashtags'], newHashtag);
if (newHashtag !== lastHashtag) {
this.dispatchEvent(
new CustomEvent('hashtag-changed', {
bubbles: true, composed: true}));
}
});
},
_computeTopicReadOnly(mutable, change) {
@@ -344,7 +345,7 @@
if (!this.change || !this.change.status) return '';
return Gerrit.Nav.getUrlForBranch(branch, project,
this.change.status == this.ChangeStatus.NEW ? 'open' :
this.change.status.toLowerCase());
this.change.status.toLowerCase());
},
_computeTopicURL(topic) {
@@ -395,6 +396,7 @@
/**
* Get the user with the specified role on the change. Returns null if the
* user with that role is the same as the owner.
*
* @param {!Object} change
* @param {string} role One of the values from _CHANGE_ROLE
* @return {Object|null} either an accound or null.

View File

@@ -426,7 +426,7 @@ limitations under the License.
{current_revision: '789', revisions: {456: {commit: {parents}}}}));
assert.equal(element._computeParents(
{current_revision: '456', revisions: {456: {commit: {parents}}}}),
parents);
parents);
});
test('_computeParentsLabel', () => {

View File

@@ -135,8 +135,8 @@
_computeShowHideIcon(showOptionalLabels) {
return showOptionalLabels ?
'gr-icons:expand-less' :
'gr-icons:expand-more';
'gr-icons:expand-less' :
'gr-icons:expand-more';
},
_computeSectionClass(show) {

View File

@@ -184,7 +184,7 @@
computed:
'_computeChangeIdCommitMessageError(_latestCommitMessage, _change)',
},
/** @type {?} */
/** @type {?} */
_patchRange: {
type: Object,
},
@@ -456,16 +456,16 @@
this.$.commitMessageEditor.disabled = true;
this.$.restAPI.putChangeCommitMessage(
this._changeNum, message).then(resp => {
this.$.commitMessageEditor.disabled = false;
if (!resp.ok) { return; }
this.$.commitMessageEditor.disabled = false;
if (!resp.ok) { return; }
this._latestCommitMessage = this._prepareCommitMsgForLinkify(
message);
this._editingCommitMessage = false;
this._reloadWindow();
}).catch(err => {
this.$.commitMessageEditor.disabled = false;
});
this._latestCommitMessage = this._prepareCommitMsgForLinkify(
message);
this._editingCommitMessage = false;
this._reloadWindow();
}).catch(err => {
this.$.commitMessageEditor.disabled = false;
});
},
_reloadWindow() {
@@ -819,7 +819,7 @@
_viewStateChanged(viewState) {
this._numFilesShown = viewState.numFilesShown ?
viewState.numFilesShown : DEFAULT_NUM_FILES_SHOWN;
viewState.numFilesShown : DEFAULT_NUM_FILES_SHOWN;
},
_numFilesShownChanged(numFilesShown) {
@@ -920,6 +920,7 @@
/**
* Gets base patch number, if it is a parent try and decide from
* preference whether to default to `auto merge`, `Parent 1` or `PARENT`.
*
* @param {Object} change
* @param {Object} patchRange
* @return {number|string}
@@ -937,7 +938,7 @@
// 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;
parentCounts[1] : 1;
const preferFirst = this._prefs &&
this._prefs.default_base_for_merges === 'FIRST_PARENT';
@@ -1327,10 +1328,10 @@
_getLatestCommitMessage() {
return this.$.restAPI.getChangeCommitInfo(this._changeNum,
this.computeLatestPatchNum(this._allPatchSets)).then(commitInfo => {
if (!commitInfo) return Promise.resolve();
this._latestCommitMessage =
if (!commitInfo) return Promise.resolve();
this._latestCommitMessage =
this._prepareCommitMsgForLinkify(commitInfo.message);
});
});
},
_getLatestRevisionSHA(change) {
@@ -1376,7 +1377,7 @@
this._changeComments = comments;
this._diffDrafts = Object.assign({}, this._changeComments.drafts);
this._commentThreads = this._changeComments.getAllThreadsForChange()
.map(c => Object.assign({}, c));
.map(c => Object.assign({}, c));
});
},
@@ -1394,6 +1395,7 @@
/**
* Reload the change.
*
* @param {boolean=} opt_isLocationChange Reloads the related changes
* when true and ends reporting events that started on location change.
* @return {Promise} A promise that resolves when the core data has loaded.
@@ -1800,7 +1802,7 @@
*/
_handleEditTap() {
const editInfo = Object.values(this._change.revisions).find(info =>
info._number === this.EDIT_NAME);
info._number === this.EDIT_NAME);
if (editInfo) {
Gerrit.Nav.navigateToChange(this._change, this.EDIT_NAME);

View File

@@ -176,7 +176,7 @@ limitations under the License.
assert.isFalse(element.$.replyOverlay.opened);
assert(openSpy.lastCall.calledWithExactly(
element.$.replyDialog.FocusTarget.ANY),
'_openReplyDialog should have been passed ANY');
'_openReplyDialog should have been passed ANY');
assert.equal(openSpy.callCount, 1);
done();
});
@@ -1046,7 +1046,7 @@ limitations under the License.
MockInteractions.tap(element.$.replyBtn);
assert(openStub.lastCall.calledWithExactly(
element.$.replyDialog.FocusTarget.ANY),
'_openReplyDialog should have been passed ANY');
'_openReplyDialog should have been passed ANY');
assert.equal(openStub.callCount, 1);
});
@@ -1058,7 +1058,7 @@ limitations under the License.
{message: {message: 'text'}});
assert(openStub.lastCall.calledWithExactly(
element.$.replyDialog.FocusTarget.BODY),
'_openReplyDialog should have been passed BODY');
'_openReplyDialog should have been passed BODY');
assert.equal(openStub.callCount, 1);
done();
});
@@ -1483,7 +1483,7 @@ limitations under the License.
test('_computeEditMode', () => {
const callCompute = (range, params) =>
element._computeEditMode({base: range}, {base: params});
element._computeEditMode({base: range}, {base: params});
assert.isFalse(callCompute({}, {}));
assert.isTrue(callCompute({}, {edit: true}));
assert.isFalse(callCompute({basePatchNum: 'PARENT', patchNum: 1}, {}));
@@ -1703,7 +1703,7 @@ limitations under the License.
element._patchRange = {patchNum: 1};
element.$.actions.dispatchEvent(new CustomEvent('stop-edit-tap',
{bubbles: false}));
{bubbles: false}));
});
suite('plugin endpoints', () => {

View File

@@ -45,7 +45,7 @@
_computeDiffLineURL(file, changeNum, patchNum, comment) {
const basePatchNum = comment.hasOwnProperty('parent') ?
-comment.parent : null;
-comment.parent : null;
return Gerrit.Nav.getUrlForDiffById(this.changeNum, this.projectName,
file, patchNum, basePatchNum, comment.line,
this._isOnParent(comment));

View File

@@ -98,21 +98,21 @@
}
return this.$.restAPI.getRepoBranches(
input, this.project, SUGGESTIONS_LIMIT).then(response => {
const branches = [];
let branch;
for (const key in response) {
if (!response.hasOwnProperty(key)) { continue; }
if (response[key].ref.startsWith('refs/heads/')) {
branch = response[key].ref.substring('refs/heads/'.length);
} else {
branch = response[key].ref;
}
branches.push({
name: branch,
});
}
return branches;
const branches = [];
let branch;
for (const key in response) {
if (!response.hasOwnProperty(key)) { continue; }
if (response[key].ref.startsWith('refs/heads/')) {
branch = response[key].ref.substring('refs/heads/'.length);
} else {
branch = response[key].ref;
}
branches.push({
name: branch,
});
}
return branches;
});
},
});
})();

View File

@@ -68,21 +68,21 @@
}
return this.$.restAPI.getRepoBranches(
input, this.project, SUGGESTIONS_LIMIT).then(response => {
const branches = [];
let branch;
for (const key in response) {
if (!response.hasOwnProperty(key)) { continue; }
if (response[key].ref.startsWith('refs/heads/')) {
branch = response[key].ref.substring('refs/heads/'.length);
} else {
branch = response[key].ref;
}
branches.push({
name: branch,
});
}
return branches;
const branches = [];
let branch;
for (const key in response) {
if (!response.hasOwnProperty(key)) { continue; }
if (response[key].ref.startsWith('refs/heads/')) {
branch = response[key].ref.substring('refs/heads/'.length);
} else {
branch = response[key].ref;
}
branches.push({
name: branch,
});
}
return branches;
});
},
});
})();

View File

@@ -82,7 +82,7 @@
_getChangeSuggestions(input) {
return this._getRecentChanges().then(changes =>
this._filterChanges(input, changes));
this._filterChanges(input, changes));
},
_filterChanges(input, changes) {

View File

@@ -157,7 +157,7 @@
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;
rev.commit.parents.length : 0;
return parentLength == 0;
}
}

View File

@@ -182,7 +182,7 @@ limitations under the License.
test('computed fields', () => {
assert.equal(element._computeArchiveDownloadLink(
{project: 'test/project', _number: 123}, 2, 'tgz'),
'/changes/test%2Fproject~123/revisions/2/archive?format=tgz');
'/changes/test%2Fproject~123/revisions/2/archive?format=tgz');
});
test('close event', done => {

View File

@@ -148,7 +148,7 @@
const rev = this.getRevisionByPatchNum(change.revisions, patchNum);
this._patchsetDescription = (rev && rev.description) ?
rev.description.substring(0, PATCH_DESC_MAX_LENGTH) : '';
rev.description.substring(0, PATCH_DESC_MAX_LENGTH) : '';
},
_handleDescriptionRemoved(e) {
@@ -176,6 +176,7 @@
/**
* Update the patchset description with the rest API.
*
* @param {string} desc
* @param {?(Event|Node)} e
* @return {!Promise}
@@ -257,7 +258,7 @@
_computeUploadHelpContainerClass(change, account) {
const changeIsMerged = change && change.status === MERGED_STATUS;
const ownerId = change && change.owner && change.owner._account_id ?
change.owner._account_id : null;
change.owner._account_id : null;
const userId = account && account._account_id;
const userIsOwner = ownerId && userId && ownerId === userId;
const hideContainer = !userIsOwner || changeIsMerged;

View File

@@ -520,6 +520,7 @@
/**
* The closure compiler doesn't realize this.specialFilePathCompare is
* valid.
*
* @suppress {checkTypes}
*/
_normalizeChangeFilesResponse(response) {
@@ -839,7 +840,7 @@
_computeShowHideIcon(path, expandedFilesRecord) {
return this._isFileExpanded(path, expandedFilesRecord) ?
'gr-icons:expand-less' : 'gr-icons:expand-more';
'gr-icons:expand-less' : 'gr-icons:expand-more';
},
_computeFiles(filesByPath, changeComments, patchRange, reviewed, loading) {
@@ -879,7 +880,7 @@
}
const previousNumFilesShown = this._shownFiles ?
this._shownFiles.length : 0;
this._shownFiles.length : 0;
const filesShown = files.slice(0, numFilesShown);
this.fire('files-shown-changed', {length: filesShown.length});
@@ -954,19 +955,20 @@
const rev = this.getRevisionByPatchNum(revisions, patchNum);
return (rev && rev.description) ?
rev.description.substring(0, PATCH_DESC_MAX_LENGTH) : '';
rev.description.substring(0, PATCH_DESC_MAX_LENGTH) : '';
},
/**
* Get a descriptive label for use in the status indicator's tooltip and
* ARIA label.
*
* @param {string} status
* @return {string}
*/
_computeFileStatusLabel(status) {
const statusCode = this._computeFileStatus(status);
return FileStatus.hasOwnProperty(statusCode) ?
FileStatus[statusCode] : 'Status Unknown';
FileStatus[statusCode] : 'Status Unknown';
},
_isFileExpanded(path, expandedFilesRecord) {
@@ -992,13 +994,14 @@
* entries in the expanded list, then render each diff corresponding in
* order by waiting for the previous diff to finish before starting the next
* one.
*
* @param {!Array} record The splice record in the expanded paths list.
*/
_expandedPathsChanged(record) {
// Clear content for any diffs that are not open so if they get re-opened
// the stale content does not flash before it is cleared and reloaded.
const collapsedDiffs = this.diffs.filter(diff =>
this._expandedFilePaths.indexOf(diff.path) === -1);
this._expandedFilePaths.indexOf(diff.path) === -1);
this._clearCollapsedDiffs(collapsedDiffs);
if (!record) { return; } // Happens after "Collapse all" clicked.
@@ -1008,9 +1011,9 @@
// Find the paths introduced by the new index splices:
const newPaths = record.indexSplices
.map(splice => splice.object.slice(
splice.index, splice.index + splice.addedCount))
.reduce((acc, paths) => acc.concat(paths), []);
.map(splice => splice.object.slice(
splice.index, splice.index + splice.addedCount))
.reduce((acc, paths) => acc.concat(paths), []);
// Required so that the newly created diff view is included in this.diffs.
Polymer.dom.flush();
@@ -1036,6 +1039,7 @@
* Given an array of paths and a NodeList of diff elements, render the diff
* for each path in order, awaiting the previous render to complete before
* continung.
*
* @param {!Array<string>} paths
* @param {!NodeList<!Object>} diffElements (GrDiffHostElement)
* @param {number} initialCount The total number of paths in the pass. This
@@ -1081,6 +1085,7 @@
/**
* In the given NodeList of diff elements, find the diff for the given path.
*
* @param {string} path
* @param {!NodeList<!Object>} diffElements (GrDiffElement)
* @return {!Object|undefined} (GrDiffElement)
@@ -1095,6 +1100,7 @@
/**
* Reset the comments of a modified thread
*
* @param {string} rootId
* @param {string} path
*/
@@ -1141,6 +1147,7 @@
* Update the loading class for the file list rows. The update is inside a
* debouncer so that the file list doesn't flash gray when the API requests
* are reasonably fast.
*
* @param {boolean} loading
*/
_loadingChanged(loading) {
@@ -1166,6 +1173,7 @@
/**
* Given a file path, return whether that path should have visible size bars
* and be included in the size bars calculation.
*
* @param {string} path
* @return {boolean}
*/
@@ -1175,7 +1183,9 @@
/**
* Compute size bar layout values from the file list.
*
* @return {Gerrit.LayoutStats|undefined}
*
*/
_computeSizeBarLayout(shownFilesRecord) {
if (!shownFilesRecord || !shownFilesRecord.base) { return undefined; }
@@ -1209,6 +1219,7 @@
/**
* Get the width of the addition bar for a file.
*
* @param {Object} file
* @param {Gerrit.LayoutStats} stats
* @return {number}
@@ -1226,6 +1237,7 @@
/**
* Get the x-offset of the addition bar for a file.
*
* @param {Object} file
* @param {Gerrit.LayoutStats} stats
* @return {number}
@@ -1237,6 +1249,7 @@
/**
* Get the width of the deletion bar for a file.
*
* @param {Object} file
* @param {Gerrit.LayoutStats} stats
* @return {number}
@@ -1254,7 +1267,9 @@
/**
* Get the x-offset of the deletion bar for a file.
*
* @param {Gerrit.LayoutStats} stats
*
* @return {number}
*/
_computeBarDeletionX(stats) {
@@ -1290,6 +1305,7 @@
/**
* Returns true if none of the inline diffs have been expanded.
*
* @return {boolean}
*/
_noDiffsExpanded() {
@@ -1300,6 +1316,7 @@
* Method to call via binding when each file list row is rendered. This
* allows approximate detection of when the dom-repeat has completed
* rendering.
*
* @param {number} index The index of the row being rendered.
* @return {string} an empty string.
*/

View File

@@ -440,10 +440,10 @@ limitations under the License.
'/COMMIT_MSG', 'comment'), '3 comments (1 unresolved)');
assert.equal(
element._computeCommentsStringMobile(element.changeComments, parentTo1
, '/COMMIT_MSG'), '2c');
, '/COMMIT_MSG'), '2c');
assert.equal(
element._computeCommentsStringMobile(element.changeComments, _1To2
, '/COMMIT_MSG'), '3c');
, '/COMMIT_MSG'), '3c');
assert.equal(
element._computeDraftsString(element.changeComments, parentTo1,
'unresolved.file'), '1 draft');
@@ -639,7 +639,7 @@ limitations under the License.
assert(navStub.lastCall.calledWith(element.change,
'file_added_in_rev2.txt', '2'),
'Should navigate to /c/42/2/file_added_in_rev2.txt');
'Should navigate to /c/42/2/file_added_in_rev2.txt');
MockInteractions.pressAndReleaseKeyOn(element, 75, null, 'k');
MockInteractions.pressAndReleaseKeyOn(element, 75, null, 'k');
@@ -1639,7 +1639,7 @@ limitations under the License.
element.set('_filesByPath', _filesByPath);
flushAsynchronousOperations();
// Navigates when a file is selected.
// Navigates when a file is selected.
element._openSelectedFile();
assert.isTrue(navStub.called);
});
@@ -1701,7 +1701,7 @@ limitations under the License.
const editControls =
Array.from(
Polymer.dom(element.root)
.querySelectorAll('.row:not(.header-row)'))
.querySelectorAll('.row:not(.header-row)'))
.map(row => row.querySelector('gr-edit-file-controls'));
assert.isTrue(editControls[0].classList.contains('invisible'));
});

View File

@@ -123,7 +123,7 @@
if (!labels[label.name]) { return null; }
const labelValue = this._getLabelValue(labels, permittedLabels, label);
const len = permittedLabels[label.name] != null ?
permittedLabels[label.name].length : 0;
permittedLabels[label.name].length : 0;
for (let i = 0; i < len; i++) {
const val = permittedLabels[label.name][i];
if (val === labelValue) {
@@ -154,7 +154,7 @@
_computeHiddenClass(permittedLabels, label) {
return !this._computeAnyPermittedLabelValues(permittedLabels, label) ?
'hidden' : '';
'hidden' : '';
},
_computePermittedLabelValues(permittedLabels, label) {

View File

@@ -123,7 +123,7 @@ limitations under the License.
const labelName = 'Code-Review';
assert.strictEqual(element._getVoteForAccount(
element.change.labels, labelName, element.account),
'+1');
'+1');
});
test('_computeColumns', () => {
@@ -187,10 +187,10 @@ limitations under the License.
{name: 'Verified', value: null}
]);
element.set(['change', 'labels', 'Verified', 'all'],
[{_account_id: 123, value: 1}]);
[{_account_id: 123, value: 1}]);
assert.deepEqual(element._labels, [
{name: 'Code-Review', value: null},
{name: 'Verified', value: '+1'},
{name: 'Code-Review', value: null},
{name: 'Verified', value: '+1'},
]);
});
});

View File

@@ -102,8 +102,8 @@
el.set('message.expanded', true);
let top = el.offsetTop;
for (let offsetParent = el.offsetParent;
offsetParent;
offsetParent = offsetParent.offsetParent) {
offsetParent;
offsetParent = offsetParent.offsetParent) {
top += offsetParent.offsetTop;
}
window.scrollTo(0, top);
@@ -219,6 +219,7 @@
* Computes message author's file comments for change's message.
* Method uses this.messages to find next message and relies on messages
* to be sorted by date field descending.
*
* @param {!Object} changeComments changeComment object, which includes
* a method to get all published comments (including robot comments),
* which returns a Hash of arrays of comments, filename as key.

View File

@@ -158,6 +158,7 @@
* Determines whether or not the given change has a parent change. If there
* is a relation chain, and the change id is not the last item of the
* relation chain, there is a parent.
*
* @param {number} currentChangeId
* @param {!Array} relatedChanges
* @return {boolean}
@@ -219,6 +220,7 @@
/**
* Do the given objects describe the same change? Compares the changes by
* their numbers.
*
* @see /Documentation/rest-api-changes.html#change-info
* @see /Documentation/rest-api-changes.html#related-change-and-commit-info
* @param {!Object} a Either ChangeInfo or RelatedChangeAndCommitInfo
@@ -236,6 +238,7 @@
* SubmittedTogetherInfo responses) or get the change number from a
* RelatedChangeAndCommitInfo (such as those included in a
* RelatedChangesInfo response).
*
* @see /Documentation/rest-api-changes.html#change-info
* @see /Documentation/rest-api-changes.html#related-change-and-commit-info
*
@@ -368,7 +371,7 @@
_computeSubmittedTogetherClass(submittedTogether) {
if (!submittedTogether || (
submittedTogether.changes.length === 0 &&
submittedTogether.changes.length === 0 &&
!submittedTogether.non_visible_changes)) {
return 'hidden';
}

View File

@@ -321,7 +321,7 @@ limitations under the License.
sandbox.stub(element, '_getCherryPicks')
.returns(Promise.resolve());
conflictsStub = sandbox.stub(element, '_getConflicts')
.returns(Promise.resolve());
.returns(Promise.resolve());
});
test('request conflicts if open and mergeable', () => {

View File

@@ -87,11 +87,11 @@
* @event comment-refresh
*/
/**
* Fires when the state of the send button (enabled/disabled) changes.
*
* @event send-disabled-changed
*/
/**
* Fires when the state of the send button (enabled/disabled) changes.
*
* @event send-disabled-changed
*/
properties: {
/**
@@ -249,7 +249,7 @@
this.fetchChangeUpdates(this.change, this.$.restAPI)
.then(result => {
this.knownLatestState = result.isLatest ?
LatestPatchState.LATEST : LatestPatchState.NOT_LATEST;
LatestPatchState.LATEST : LatestPatchState.NOT_LATEST;
});
this._focusOn(opt_focusTarget);
@@ -394,16 +394,16 @@
return this.$.restAPI.removeChangeReviewer(this.change._number,
account._account_id).then(response => {
if (!response.ok) { return response; }
if (!response.ok) { return response; }
const reviewers = this.change.reviewers[type] || [];
for (let i = 0; i < reviewers.length; i++) {
if (reviewers[i]._account_id == account._account_id) {
this.splice(`change.reviewers.${type}`, i, 1);
break;
}
}
});
const reviewers = this.change.reviewers[type] || [];
for (let i = 0; i < reviewers.length; i++) {
if (reviewers[i]._account_id == account._account_id) {
this.splice(`change.reviewers.${type}`, i, 1);
break;
}
}
});
},
_mapReviewer(reviewer) {
@@ -624,6 +624,7 @@
* Generates a function to filter out reviewer/CC entries. When isCCs is
* truthy, the function filters out entries that already exist in this._ccs.
* When falsy, the function filters entries that exist in this._reviewers.
*
* @param {boolean} isCCs
* @return {!Function}
*/

View File

@@ -414,8 +414,8 @@ limitations under the License.
}).then(() => {
assert.isFalse(isVisible(element.$.reviewerConfirmationOverlay));
const additions = cc ?
element.$.ccs.additions() :
element.$.reviewers.additions();
element.$.ccs.additions() :
element.$.reviewers.additions();
assert.deepEqual(
additions,
[
@@ -843,7 +843,7 @@ limitations under the License.
// Send and purge and verify moves, delete cc3.
element.send()
.then(keepReviewers =>
element._purgeReviewersPendingRemove(false, keepReviewers))
element._purgeReviewersPendingRemove(false, keepReviewers))
.then(() => {
assert.deepEqual(
mutations, [

View File

@@ -105,6 +105,7 @@
/**
* Returns hash of labels to max permitted score.
*
* @param {!Object} change
* @returns {!Object} labels to max permitted scores hash
*/
@@ -119,6 +120,7 @@
/**
* Returns max permitted score for reviewer.
*
* @param {!Object} reviewer
* @param {!Object} change
* @param {string} label

View File

@@ -196,7 +196,7 @@ limitations under the License.
element.maxReviewersDisplayed = 5;
for (let i = 0; i < 6; i++) {
reviewers.push(
{email: i+'reviewer@google.com', name: 'reviewer-' + i});
{email: i+'reviewer@google.com', name: 'reviewer-' + i});
}
element.ccsOnly = true;
@@ -219,7 +219,7 @@ limitations under the License.
element.maxReviewersDisplayed = 5;
for (let i = 0; i < 8; i++) {
reviewers.push(
{email: i+'reviewer@google.com', name: 'reviewer-' + i});
{email: i+'reviewer@google.com', name: 'reviewer-' + i});
}
element.ccsOnly = true;
@@ -242,7 +242,7 @@ limitations under the License.
const reviewers = [];
for (let i = 0; i < 7; i++) {
reviewers.push(
{email: i+'reviewer@google.com', name: 'reviewer-' + i});
{email: i+'reviewer@google.com', name: 'reviewer-' + i});
}
element.ccsOnly = true;
@@ -265,7 +265,7 @@ limitations under the License.
element.maxReviewersDisplayed = 5;
for (let i = 0; i < 100; i++) {
reviewers.push(
{email: i+'reviewer@google.com', name: 'reviewer-' + i});
{email: i+'reviewer@google.com', name: 'reviewer-' + i});
}
element.ccsOnly = true;
@@ -298,7 +298,7 @@ limitations under the License.
},
Bar: {
all: [{_account_id: 1, permitted_voting_range: {max: 1}},
{_account_id: 7, permitted_voting_range: {max: 1}}],
{_account_id: 7, permitted_voting_range: {max: 1}}],
},
FooBar: {
all: [{_account_id: 7, value: 0}],

View File

@@ -62,6 +62,7 @@
* - Unresolved threads without drafts (reverse chronological)
* - Resolved threads with drafts (reverse chronological)
* - Resolved threads without drafts (reverse chronological)
*
* @param {!Object} changeRecord
*/
_computeSortedThreads(changeRecord) {
@@ -132,8 +133,8 @@
const lastNonDraftComment =
(lastComment.__draft && thread.comments.length > 1) ?
thread.comments[thread.comments.length - 2] :
lastComment;
thread.comments[thread.comments.length - 2] :
lastComment;
return {
thread,

View File

@@ -78,7 +78,7 @@ limitations under the License.
'none');
assert.notEqual(getComputedStyle(element.$$('gr-account-dropdown'))
.display,
'none');
'none');
assert.notEqual(getComputedStyle(element.$$('.settingsButton')).display,
'none');
});

View File

@@ -224,6 +224,7 @@ limitations under the License.
/**
* Setup router implementation.
*
* @param {function(!string)} navigate the router-abstracted equivalent of
* `window.location.href = ...`. Takes a string.
* @param {function(!Object): string} generateUrl generates a URL given
@@ -260,6 +261,7 @@ limitations under the License.
/**
* Generate a URL for the given route parameters.
*
* @param {Object} params
* @return {string}
*/
@@ -336,6 +338,7 @@ limitations under the License.
/**
* Navigate to a search for changes with the given status.
*
* @param {string} status
*/
navigateToStatusSearch(status) {
@@ -347,6 +350,7 @@ limitations under the License.
/**
* Navigate to a search query
*
* @param {string} query
* @param {number=} opt_offset
*/
@@ -548,6 +552,7 @@ limitations under the License.
/**
* Navigate to an arbitrary relative URL.
*
* @param {string} relativeUrl
*/
navigateToRelativeUrl(relativeUrl) {
@@ -570,6 +575,7 @@ limitations under the License.
/**
* Navigate to a repo settings page.
*
* @param {string} repoName
*/
navigateToRepo(repoName) {
@@ -732,11 +738,11 @@ limitations under the License.
getUserDashboard(user = 'self', sections = DEFAULT_SECTIONS,
title = '') {
sections = sections
.filter(section => (user === 'self' || !section.selfOnly))
.map(section => Object.assign({}, section, {
name: section.name,
query: section.query.replace(USER_PLACEHOLDER_PATTERN, user),
}));
.filter(section => (user === 'self' || !section.selfOnly))
.map(section => Object.assign({}, section, {
name: section.name,
query: section.query.replace(USER_PLACEHOLDER_PATTERN, user),
}));
return {title, sections};
},
};

View File

@@ -194,6 +194,7 @@
/**
* The default reporter reports events immediately.
*
* @param {string} type
* @param {string} category
* @param {string} eventName
@@ -231,6 +232,7 @@
/**
* The caching reporter will queue reports until plugins have loaded, and
* log events immediately if they're reported after plugins have loaded.
*
* @param {string} type
* @param {string} category
* @param {string} eventName
@@ -406,6 +408,7 @@
/**
* Reports just line timeEnd, but additionally reports an average given a
* denominator and a separate reporiting name for the average.
*
* @param {string} name Timing name.
* @param {string} averageName Average timing name.
* @param {number} denominator Number by which to divide the total to
@@ -424,6 +427,7 @@
/**
* Send a timing report with an arbitrary time value.
*
* @param {string} name Timing name.
* @param {number} time The time to report as an integer of milliseconds.
*/
@@ -436,6 +440,7 @@
* Get a timer object to for reporing a user timing. The start time will be
* the time that the object has been created, and the end time will be the
* time that the "end" method is called on the object.
*
* @param {string} name Timing name.
* @returns {!Object} The timer object.
*/
@@ -482,6 +487,7 @@
/**
* Log timing information for an RPC.
*
* @param {string} anonymizedUrl The URL of the RPC with tokens obfuscated.
* @param {number} elapsed The time elapsed of the RPC.
*/

View File

@@ -68,11 +68,11 @@ limitations under the License.
assert.isTrue(
element.reporter.calledWithExactly(
'timing-report', 'UI Latency', 'App Started', 42
));
));
assert.isTrue(
element.reporter.calledWithExactly(
'lifecycle', 'Page Visibility', 'hidden'
));
));
});
test('WebComponentsReady', () => {

View File

@@ -106,6 +106,7 @@
/**
* Support vestigial params from GWT UI.
*
* @see Issue 7673.
* @type {!RegExp}
*/
@@ -162,6 +163,7 @@
* the hash of diff URLs. In this format, a number on its own indicates that
* line number in the revision of the diff. A number prefixed by either an 'a'
* or a 'b' indicates that line number of the base of the diff.
*
* @type {RegExp}
*/
const LINE_ADDRESS_PATTERN = /^([ab]?)(\d+)$/;
@@ -461,8 +463,8 @@
// If there is a repo name provided, make sure to substitute it into the
// ${repo} (or legacy ${project}) query tokens.
const query = opt_repoName ?
section.query.replace(REPO_TOKEN_PATTERN, opt_repoName) :
section.query;
section.query.replace(REPO_TOKEN_PATTERN, opt_repoName) :
section.query;
return encodeURIComponent(section.name) + '=' +
encodeURIComponent(query);
});
@@ -540,6 +542,7 @@
* Given an object of parameters, potentially including a `patchNum` or a
* `basePatchNum` or both, return a string representation of that range. If
* no range is indicated in the params, the empty string is returned.
*
* @param {!Object} params
* @return {string}
*/
@@ -606,6 +609,7 @@
/**
* Redirect the user to login using the given return-URL for redirection
* after authentication success.
*
* @param {string} returnUrl
*/
_redirectToLogin(returnUrl) {
@@ -618,6 +622,7 @@
* Hashes parsed by page.js exclude "inner" hashes, so a URL like "/a#b#c"
* is parsed to have a hash of "b" rather than "b#c". Instead, this method
* parses hashes correctly. Will return an empty string if there is no hash.
*
* @param {!string} canonicalPath
* @return {!string} Everything after the first '#' ("a#b#c" -> "b#c").
*/
@@ -638,6 +643,7 @@
* Check to see if the user is logged in and return a promise that only
* resolves if the user is logged in. If the user us not logged in, the
* promise is rejected and the page is redirected to the login flow.
*
* @param {!Object} data The parsed route data.
* @return {!Promise<!Object>} A promise yielding the original route data
* (if it resolves).

View File

@@ -209,6 +209,7 @@
/**
* Determine what array of possible suggestions should be provided
* to _getSearchSuggestions.
*
* @param {string} input - The full search term, in lowercase.
* @return {!Promise} This returns a promise that resolves to an array of
* suggestion objects.
@@ -250,6 +251,7 @@
/**
* Get the sorted, pruned list of suggestions for the current search query.
*
* @param {string} input - The complete search query.
* @return {!Promise} This returns a promise that resolves to an array of
* suggestions.

View File

@@ -61,8 +61,8 @@ limitations under the License.
getActiveElement = () => {
return document.activeElement.shadowRoot ?
document.activeElement.shadowRoot.activeElement :
document.activeElement;
document.activeElement.shadowRoot.activeElement :
document.activeElement;
};
test('enter in search input fires event', done => {

View File

@@ -70,6 +70,7 @@
/**
* Fetch from the API the predicted projects.
*
* @param {string} predicate - The first part of the search term, e.g.
* 'project'
* @param {string} expression - The second part of the search term, e.g.
@@ -90,6 +91,7 @@
/**
* Fetch from the API the predicted groups.
*
* @param {string} predicate - The first part of the search term, e.g.
* 'ownerin'
* @param {string} expression - The second part of the search term, e.g.
@@ -111,6 +113,7 @@
/**
* Fetch from the API the predicted accounts.
*
* @param {string} predicate - The first part of the search term, e.g.
* 'owner'
* @param {string} expression - The second part of the search term, e.g.
@@ -144,8 +147,8 @@
return accounts.map(account => ({
label: account.name || '',
text: account.email ?
`${predicate}:${account.email}` :
`${predicate}:"${this._accountOrAnon(account)}"`,
`${predicate}:${account.email}` :
`${predicate}:"${this._accountOrAnon(account)}"`,
}));
},
});

View File

@@ -248,9 +248,9 @@
const all = comments.concat(drafts).concat(robotComments);
const baseComments = all.filter(c =>
this._isInBaseOfPatchRange(c, patchRange));
this._isInBaseOfPatchRange(c, patchRange));
const revisionComments = all.filter(c =>
this._isInRevisionOfPatchRange(c, patchRange));
this._isInRevisionOfPatchRange(c, patchRange));
return {
meta: {
@@ -348,7 +348,7 @@
const threads = this.getCommentThreads(this._sortComments(comments));
const unresolvedThreads = threads
.filter(thread =>
.filter(thread =>
thread.comments.length &&
thread.comments[thread.comments.length - 1].unresolved);
@@ -406,12 +406,13 @@
};
/**
* Whether the given comment should be included in the base side of the
* given patch range.
* @param {!Object} comment
* @param {!Gerrit.PatchRange} range
* @return {boolean}
*/
* Whether the given comment should be included in the base side of the
* given patch range.
*
* @param {!Object} comment
* @param {!Gerrit.PatchRange} range
* @return {boolean}
*/
ChangeComments.prototype._isInBaseOfPatchRange = function(comment, range) {
// If the base of the patch range is a parent of a merge, and the comment
// appears on a specific parent then only show the comment if the parent
@@ -439,6 +440,7 @@
/**
* Whether the given comment should be included in the revision side of the
* given patch range.
*
* @param {!Object} comment
* @param {!Gerrit.PatchRange} range
* @return {boolean}
@@ -451,6 +453,7 @@
/**
* Whether the given comment should be included in the given patch range.
*
* @param {!Object} comment
* @param {!Gerrit.PatchRange} range
* @return {boolean|undefined}
@@ -491,7 +494,7 @@
return Promise.all(promises).then(([comments, robotComments, drafts]) => {
this._changeComments = new ChangeComments(comments,
robotComments, drafts, changeNum);
robotComments, drafts, changeNum);
return this._changeComments;
});
},

View File

@@ -109,7 +109,7 @@ limitations under the License.
let draftStub;
setup(() => {
commentStub = sandbox.stub(element.$.restAPI, 'getDiffComments')
.returns(Promise.resolve({}));
.returns(Promise.resolve({}));
robotCommentStub = sandbox.stub(element.$.restAPI,
'getDiffRobotComments').returns(Promise.resolve({}));
draftStub = sandbox.stub(element.$.restAPI, 'getDiffDrafts')

View File

@@ -105,7 +105,7 @@
let tr = content.parentElement.parentElement;
while (tr = tr.nextSibling) {
if (tr.classList.contains('both') || (
(side === 'left' && tr.classList.contains('remove')) ||
(side === 'left' && tr.classList.contains('remove')) ||
(side === 'right' && tr.classList.contains('add')))) {
return tr.querySelector('.contentText');
}

View File

@@ -114,6 +114,7 @@ limitations under the License.
* The promise last returned from `render()` while the asynchronous
* rendering is running - `null` otherwise. Provides a `cancel()`
* method that rejects it with `{isCancelled: true}`.
*
* @type {?Object}
*/
_cancelableRenderPromise: Object,
@@ -219,8 +220,8 @@ limitations under the License.
getLineNumberByChild(node) {
const lineEl = this.getLineElByChild(node);
return lineEl ?
parseInt(lineEl.getAttribute('data-value'), 10) :
null;
parseInt(lineEl.getAttribute('data-value'), 10) :
null;
},
getContentByLine(lineNumber, opt_side, opt_root) {
@@ -249,7 +250,7 @@ limitations under the License.
getSideByLineEl(lineEl) {
return lineEl.classList.contains(GrDiffBuilder.Side.RIGHT) ?
GrDiffBuilder.Side.RIGHT : GrDiffBuilder.Side.LEFT;
GrDiffBuilder.Side.RIGHT : GrDiffBuilder.Side.LEFT;
},
emitGroup(group, sectionEl) {
@@ -304,7 +305,7 @@ limitations under the License.
let builder = null;
if (this.isImageDiff) {
builder = new GrDiffBuilderImage(diff, prefs, this.diffElement,
this.baseImage, this.revisionImage);
this.baseImage, this.revisionImage);
} else if (diff.binary) {
// If the diff is binary, but not an image.
return new GrDiffBuilderBinary(diff, prefs, this.diffElement);
@@ -352,8 +353,8 @@ limitations under the License.
// If endIndex isn't present, continue to the end of the line.
const endIndex = highlight.endIndex === undefined ?
line.text.length :
highlight.endIndex;
line.text.length :
highlight.endIndex;
GrAnnotation.annotateElement(
contentEl,

View File

@@ -92,6 +92,7 @@
/**
* Abstract method
*
* @param {string} outputEl
* @param {number} fontSize
*/
@@ -101,6 +102,7 @@
/**
* Abstract method
*
* @param {Object} group
*/
GrDiffBuilder.prototype.buildSectionElement = function() {
@@ -183,7 +185,7 @@
continue;
}
const lineNumber = opt_side === 'left' ?
line.beforeNumber : line.afterNumber;
line.beforeNumber : line.afterNumber;
if (lineNumber < start || lineNumber > end) { continue; }
if (out_lines) { out_lines.push(line); }
@@ -462,6 +464,7 @@
/**
* Finds the next DIV.contentText element following the given element, and on
* the same side. Will only search within a group.
*
* @param {HTMLElement} content
* @param {string} side Either 'left' or 'right'
* @return {HTMLElement}
@@ -473,6 +476,7 @@
/**
* Determines whether the given group is either totally an addition or totally
* a removal.
*
* @param {!Object} group (GrDiffGroup)
* @return {boolean}
*/
@@ -485,6 +489,7 @@
/**
* Set the blame information for the diff. For any already-rendered line,
* re-render its blame cell content.
*
* @param {Object} blame
*/
GrDiffBuilder.prototype.setBlame = function(blame) {
@@ -512,6 +517,7 @@
/**
* Find the blame cell for a given line number.
*
* @param {number} lineNum
* @return {HTMLTableDataCellElement}
*/
@@ -524,6 +530,7 @@
* Given a base line number, return the commit containing that line in the
* current set of blame information. If no blame information has been
* provided, null is returned.
*
* @param {number} lineNum
* @return {Object} The commit information.
*/
@@ -543,6 +550,7 @@
/**
* Given the number of a base line, get the content for the blame cell of that
* line. If there is no blame information for that line, returns null.
*
* @param {number} lineNum
* @param {Object=} opt_commit Optionally provide the commit object, so that
* it does not need to be searched.
@@ -567,6 +575,7 @@
/**
* Create a blame cell for the given base line. Blame information will be
* included in the cell if available.
*
* @param {GrDiffLine} line
* @return {HTMLTableDataCellElement}
*/

View File

@@ -69,7 +69,7 @@
* to that position. This parameter should be set at most for one gr-diff
* element in the page.
*
* @type (?number)
* @type {?number}
*/
initialLineNumber: {
type: Number,
@@ -176,6 +176,7 @@
/**
* Get the line number element targeted by the cursor row and side.
*
* @return {?Element|undefined}
*/
getTargetLineElement() {
@@ -251,6 +252,7 @@
* {leftSide: false, number: 123} for line 123 of the revision, or
* {leftSide: true, number: 321} for line 321 of the base patch.
* Returns null if an address is not available.
*
* @return {?Object}
*/
getAddress() {
@@ -315,7 +317,7 @@
if (this._getViewMode() === DiffViewMode.SIDE_BY_SIDE &&
this._isTargetBlank()) {
this.side = this.side === DiffSides.LEFT ?
DiffSides.RIGHT : DiffSides.LEFT;
DiffSides.RIGHT : DiffSides.LEFT;
}
},
@@ -375,6 +377,7 @@
/**
* Setup and tear down on-render listeners for any diffs that are added or
* removed from the cursor.
*
* @private
*/
_diffsChanged(changeRecord) {
@@ -391,15 +394,15 @@
splice = changeRecord.indexSplices[spliceIdx];
for (i = splice.index;
i < splice.index + splice.addedCount;
i++) {
i < splice.index + splice.addedCount;
i++) {
this.listen(this.diffs[i], 'render-start', '_handleDiffRenderStart');
this.listen(this.diffs[i], 'render-content', 'handleDiffUpdate');
}
for (i = 0;
i < splice.removed && splice.removed.length;
i++) {
i < splice.removed && splice.removed.length;
i++) {
this.unlisten(splice.removed[i],
'render-start', '_handleDiffRenderStart');
this.unlisten(splice.removed[i],

View File

@@ -31,6 +31,7 @@
/**
* The DOM API textContent.length calculation is broken when the text
* contains Unicode. See https://mathiasbynens.be/notes/javascript-unicode .
*
* @param {!Text} node text node.
* @return {number} The length of the text.
*/

View File

@@ -168,7 +168,7 @@ limitations under the License.
assert.equal(layer4[0].textContent +
layer4[1].textContent +
layer4[2].textContent,
layers[3]);
layers[3]);
});
test('splitTextNode', () => {

View File

@@ -137,7 +137,7 @@
}
return this.commentRanges.findIndex(commentRange =>
commentRange.side === side && rangesEqual(commentRange.range, range));
commentRange.side === side && rangesEqual(commentRange.range, range));
},
/**
@@ -145,6 +145,7 @@
* Merges multiple ranges, accounts for triple click, accounts for
* syntax highligh, convert native DOM Range objects to Gerrit concepts
* (line, side, etc).
*
* @param {Selection} selection
* @return {({
* start: {
@@ -180,6 +181,7 @@
/**
* Normalize a specific DOM Range.
*
* @return {!Object} fixed normalized range
*/
_normalizeRange(domRange) {

View File

@@ -272,12 +272,12 @@ limitations under the License.
};
const getActionRange = () =>
Polymer.dom(element.root).querySelector(
'gr-selection-action-box').range;
Polymer.dom(element.root).querySelector(
'gr-selection-action-box').range;
const getActionSide = () =>
Polymer.dom(element.root).querySelector(
'gr-selection-action-box').side;
Polymer.dom(element.root).querySelector(
'gr-selection-action-box').side;
const getLineElByChild = node => {
const stubs = contentStubs.find(stub => stub.contentTd.contains(node));

View File

@@ -97,6 +97,7 @@
/**
* The DOM API textContent.length calculation is broken when the text
* contains Unicode. See https://mathiasbynens.be/notes/javascript-unicode .
*
* @param {text} node A text node.
* @return {number} The length of the text.
*/

View File

@@ -79,6 +79,7 @@
/**
* Fired when the user selects a line.
*
* @event line-selected
*/
@@ -147,6 +148,7 @@
/**
* Special line number which should not be collapsed into a shared region.
*
* @type {{
* number: number,
* leftSide: {boolean}
@@ -395,6 +397,7 @@
/**
* Load and display blame information for the base of the diff.
*
* @return {Promise} A promise that resolves when blame finishes rendering.
*/
loadBlame() {
@@ -417,6 +420,7 @@
/**
* The thread elements in this diff, in no particular order.
*
* @return {!Array<!HTMLElement>}
*/
getThreadEls() {
@@ -511,7 +515,7 @@
// digits. Diffs with no delta are considered 0%.
const totalDelta = rebaseDelta + nonRebaseDelta;
const percentRebaseDelta = !totalDelta ? 0 :
Math.round(100 * rebaseDelta / totalDelta);
Math.round(100 * rebaseDelta / totalDelta);
// Report the due_to_rebase percentage in the "diff" category when
// applicable.
@@ -588,7 +592,7 @@
// thread and append to it.
if (comment.in_reply_to) {
const thread = threads.find(thread =>
thread.comments.some(c => c.id === comment.in_reply_to));
thread.comments.some(c => c.id === comment.in_reply_to));
if (thread) {
thread.comments.push(comment);
continue;
@@ -729,7 +733,7 @@
}
function matchesRange(threadEl) {
const threadRange = /** @type {!Gerrit.Range} */(
JSON.parse(threadEl.getAttribute('range')));
JSON.parse(threadEl.getAttribute('range')));
return Gerrit.rangesEqual(threadRange, range);
}
@@ -780,7 +784,7 @@
matchers.push(matchesFileComment);
}
return threadEls.filter(threadEl =>
matchers.some(matcher => matcher(threadEl)));
matchers.some(matcher => matcher(threadEl)));
},
_getIgnoreWhitespace() {
@@ -832,7 +836,7 @@
*/
_computeParentIndex(patchRangeRecord) {
return this.isMergeParent(patchRangeRecord.base.basePatchNum) ?
this.getParentIndex(patchRangeRecord.base.basePatchNum) : null;
this.getParentIndex(patchRangeRecord.base.basePatchNum) : null;
},
_handleCommentSave(e) {
@@ -926,8 +930,8 @@
if (!diff) return false;
return diff.content.some(section => {
const lines = section.ab ?
section.ab :
(section.a || []).concat(section.b || []);
section.ab :
(section.a || []).concat(section.b || []);
return lines.some(line => line.length >= SYNTAX_MAX_LINE_LENGTH);
});
},

View File

@@ -509,7 +509,7 @@ limitations under the License.
'getB64FileContents',
(changeId, patchNum, path, opt_parentIndex) => {
return Promise.resolve(opt_parentIndex === 1 ? mockFile1 :
mockFile2);
mockFile2);
});
element.patchRange = {basePatchNum: 'PARENT', patchNum: 1};

View File

@@ -105,6 +105,7 @@
* The promise last returned from `process()` while the asynchronous
* processing is running - `null` otherwise. Provides a `cancel()`
* method that rejects it with `{isCancelled: true}`.
*
* @type {?Object}
*/
_processPromise: {
@@ -133,8 +134,10 @@
/**
* Asynchronously process the diff chunks into groups. As it processes, it
* will splice groups into the `groups` property of the component.
*
* @param {!Array<!Gerrit.DiffChunk>} chunks
* @param {boolean} isBinary
*
* @return {!Promise<!Array<!Object>>} A promise that resolves with an
* array of GrDiffGroups when the diff is completely processed.
*/
@@ -290,7 +293,7 @@
if (this.context !== WHOLE_FILE) {
const hiddenStart = state.chunkIndex === 0 ? 0 : this.context;
const hiddenEnd = lineCount - (
firstUncollapsibleChunkIndex === chunks.length ?
firstUncollapsibleChunkIndex === chunks.length ?
0 : this.context);
groups = GrDiffGroup.hideInContextControl(
groups, hiddenStart, hiddenEnd);
@@ -460,6 +463,7 @@
* In order to show key locations, such as comments, out of the bounds of
* the selected context, treat them as separate chunks within the model so
* that the content (and context surrounding it) renders correctly.
*
* @param {!Array<!Object>} chunks DiffContents as returned from server.
* @return {!Array<!Object>} Finer grained DiffContents.
*/
@@ -483,7 +487,7 @@
if (chunk.common && chunk.a.length != chunk.b.length) {
throw new Error(
'DiffContent with common=true must always have equal length');
'DiffContent with common=true must always have equal length');
}
const numLines = this._commonChunkLength(chunk);
const chunkEnds = this._findChunkEndsAtKeyLocations(
@@ -494,7 +498,7 @@
if (chunk.ab) {
result.push(...this._splitAtChunkEnds(chunk.ab, chunkEnds)
.map(({lines, keyLocation}) =>
Object.assign({}, chunk, {ab: lines, keyLocation})));
Object.assign({}, chunk, {ab: lines, keyLocation})));
} else if (chunk.common) {
const aChunks = this._splitAtChunkEnds(chunk.a, chunkEnds);
const bChunks = this._splitAtChunkEnds(chunk.b, chunkEnds);
@@ -603,6 +607,7 @@
* If a group is an addition or a removal, break it down into smaller groups
* of that type using the MAX_GROUP_SIZE. If the group is a shared chunk
* or a delta it is returned as the single element of the result array.
*
* @param {!Gerrit.DiffChunk} chunk A raw chunk from a diff response.
* @return {!Array<!Array<!Object>>}
*/
@@ -632,6 +637,7 @@
/**
* Given an array and a size, return an array of arrays where no inner array
* is larger than that size, preserving the original order.
*
* @param {!Array<T>} array
* @param {number} size
* @return {!Array<!Array<T>>}

View File

@@ -106,8 +106,8 @@
const side = this.diffBuilder.getSideByLineEl(lineEl);
targetClasses.push(side === 'left' ?
SelectionClass.LEFT :
SelectionClass.RIGHT);
SelectionClass.LEFT :
SelectionClass.RIGHT);
if (commentSelected) {
targetClasses.push(SelectionClass.COMMENT);
@@ -120,6 +120,7 @@
/**
* Set the provided list of classes on the element, to the exclusion of all
* other SelectionClass values.
*
* @param {!Array<!string>} targetClasses
*/
_setClasses(targetClasses) {

View File

@@ -272,8 +272,8 @@
const patchRange = patchRangeRecord.base;
return this.$.restAPI.getChangeFilePathsAsSpeciallySortedArray(
changeNum, patchRange).then(files => {
this._fileList = files;
});
this._fileList = files;
});
},
_getDiffPreferences() {
@@ -566,8 +566,8 @@
let idx = fileList.indexOf(path);
if (idx === -1) {
const file = direction > 0 ?
fileList[0] :
fileList[fileList.length - 1];
fileList[0] :
fileList[fileList.length - 1];
return {path: file};
}
@@ -706,8 +706,8 @@
// is specified.
this._getReviewedStatus(this.editMode, this._changeNum,
this._patchRange.patchNum, this._path).then(status => {
this.$.reviewed.checked = status;
});
this.$.reviewed.checked = status;
});
return;
}
@@ -1138,7 +1138,7 @@
// so we resolve the right "next" file.
const unreviewedFiles = this._fileList
.filter(file =>
(file === this._path || !this._reviewedFiles.has(file)));
(file === this._path || !this._reviewedFiles.has(file)));
this._navToFile(this._path, unreviewedFiles, 1);
},

View File

@@ -269,28 +269,28 @@ limitations under the License.
assert.isTrue(element._loading);
assert(diffNavStub.lastCall.calledWithExactly(element._change,
'wheatley.md', '10', '5'),
'Should navigate to /c/42/5..10/wheatley.md');
'Should navigate to /c/42/5..10/wheatley.md');
element._path = 'wheatley.md';
MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
assert.isTrue(element._loading);
assert(diffNavStub.lastCall.calledWithExactly(element._change,
'glados.txt', '10', '5'),
'Should navigate to /c/42/5..10/glados.txt');
'Should navigate to /c/42/5..10/glados.txt');
element._path = 'glados.txt';
MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
assert.isTrue(element._loading);
assert(diffNavStub.lastCall.calledWithExactly(element._change, 'chell.go',
'10', '5'),
'Should navigate to /c/42/5..10/chell.go');
'Should navigate to /c/42/5..10/chell.go');
element._path = 'chell.go';
MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
assert.isTrue(element._loading);
assert(changeNavStub.lastCall.calledWithExactly(element._change, '10',
'5'),
'Should navigate to /c/42/5..10');
'Should navigate to /c/42/5..10');
});
test('keyboard shortcuts with old patch number', () => {
@@ -332,13 +332,13 @@ limitations under the License.
MockInteractions.pressAndReleaseKeyOn(element, 221, null, ']');
assert(diffNavStub.lastCall.calledWithExactly(element._change,
'wheatley.md', '1', PARENT),
'Should navigate to /c/42/1/wheatley.md');
'Should navigate to /c/42/1/wheatley.md');
element._path = 'wheatley.md';
MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
assert(diffNavStub.lastCall.calledWithExactly(element._change,
'glados.txt', '1', PARENT),
'Should navigate to /c/42/1/glados.txt');
'Should navigate to /c/42/1/glados.txt');
element._path = 'glados.txt';
MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');

View File

@@ -96,6 +96,7 @@
/**
* Fired when the user selects a line.
*
* @event line-selected
*/
@@ -169,7 +170,7 @@
observer: '_viewModeObserver',
},
/** @type ?Gerrit.LineOfInterest */
/** @type {?Gerrit.LineOfInterest} */
lineOfInterest: Object,
loading: {
@@ -206,7 +207,7 @@
* bypassed. If the value is a number, then that number represents the
* context preference to use when rendering the bypassed diff.
*
* @type (number|null)
* @type {number|null}
*/
_safetyBypass: {
type: Number,
@@ -241,6 +242,7 @@
* Observes comment nodes added or removed after the initial render.
* Can be used to unregister when the entire diff is (re-)rendered or upon
* detachment.
*
* @type {?PolymerDomApi.ObserveHandle}
*/
_incrementalNodeObserver: Object,
@@ -248,6 +250,7 @@
/**
* Observes comment nodes added or removed at any point.
* Can be used to unregister upon detachment.
*
* @type {?PolymerDomApi.ObserveHandle}
*/
_nodeObserver: Object,
@@ -324,8 +327,8 @@
// up the diff, because they are in the shadow DOM of the gr-diff element.
// This takes the shadow DOM selection if one exists.
return this.root.getSelection ?
this.root.getSelection() :
document.getSelection();
this.root.getSelection() :
document.getSelection();
},
_observeNodes() {
@@ -524,8 +527,8 @@
return false;
}
const patchNum = el.classList.contains(DiffSide.LEFT) ?
this.patchRange.basePatchNum :
this.patchRange.patchNum;
this.patchRange.basePatchNum :
this.patchRange.patchNum;
const isEdit = this.patchNumEquals(patchNum, this.EDIT_NAME);
const isEditBase = this.patchNumEquals(patchNum, this.PARENT_NAME) &&
@@ -576,6 +579,7 @@
/**
* Gets or creates a comment thread group for a specific line and side on a
* diff.
*
* @param {!Object} contentEl
* @param {!Gerrit.DiffSide} commentSide
* @return {!Node}
@@ -875,6 +879,7 @@
/**
* Find the last chunk for the given side.
*
* @param {!Object} diff
* @param {boolean} leftSide true if checking the base of the diff,
* false if testing the revision.
@@ -892,8 +897,8 @@
chunkIndex--;
chunk = diff.content[chunkIndex];
} while (
// We haven't reached the beginning.
chunkIndex >= 0 &&
// We haven't reached the beginning.
chunkIndex >= 0 &&
// The chunk doesn't have both sides.
!chunk.ab &&
@@ -911,6 +916,7 @@
/**
* Check whether the specified side of the diff has a trailing newline.
*
* @param {!Object} diff
* @param {boolean} leftSide true if checking the base of the diff,
* false if testing the revision.
@@ -961,6 +967,7 @@
/**
* Get the approximate length of the diff as the sum of the maximum
* length of the chunks.
*
* @param {Object} diff object
* @return {number}
*/

View File

@@ -80,7 +80,7 @@
const parentCounts = revisionInfo.getParentCountMap();
const currentParentCount = parentCounts.hasOwnProperty(patchNum) ?
parentCounts[patchNum] : 1;
parentCounts[patchNum] : 1;
const maxParents = revisionInfo.getMaxParents();
const isMerge = currentParentCount > 1;
@@ -178,6 +178,7 @@
* The basePatchNum should always be <= patchNum -- because sortedRevisions
* is sorted in reverse order (higher patchset nums first), invalid base
* patch nums have an index greater than the index of patchNum.
*
* @param {number|string} basePatchNum The possible base patch num.
* @param {number|string} patchNum The current selected patch num.
* @param {!Array} sortedRevisions
@@ -246,7 +247,7 @@
_computePatchSetDescription(revisions, patchNum, opt_addFrontSpace) {
const rev = this.getRevisionByPatchNum(revisions, patchNum);
return (rev && rev.description) ?
(opt_addFrontSpace ? ' ' : '') +
(opt_addFrontSpace ? ' ' : '') +
rev.description.substring(0, PATCH_DESC_MAX_LENGTH) : '';
},

View File

@@ -185,7 +185,7 @@ limitations under the License.
assert.deepEqual(element._computeBaseDropdownContent(availablePatches,
patchNum, sortedRevisions, element.changeComments,
element.revisionInfo),
expectedResult);
expectedResult);
});
test('_computeBaseDropdownContent called when patchNum updates', () => {
@@ -344,7 +344,7 @@ limitations under the License.
assert.deepEqual(element._computePatchDropdownContent(availablePatches,
basePatchNum, sortedRevisions, element.changeComments),
expectedResult);
expectedResult);
});
test('filesWeblinks', () => {

View File

@@ -58,6 +58,7 @@
/**
* Layer method to add annotations to a line.
*
* @param {!HTMLElement} el The DIV.contentText element to apply the
* annotation to.
* @param {!HTMLElement} lineNumberEl
@@ -66,12 +67,12 @@
annotate(el, lineNumberEl, line) {
let ranges = [];
if (line.type === GrDiffLine.Type.REMOVE || (
line.type === GrDiffLine.Type.BOTH &&
line.type === GrDiffLine.Type.BOTH &&
el.getAttribute('data-side') !== 'right')) {
ranges = ranges.concat(this._getRangesForLine(line, 'left'));
}
if (line.type === GrDiffLine.Type.ADD || (
line.type === GrDiffLine.Type.BOTH &&
line.type === GrDiffLine.Type.BOTH &&
el.getAttribute('data-side') !== 'left')) {
ranges = ranges.concat(this._getRangesForLine(line, 'right'));
}
@@ -85,6 +86,7 @@
/**
* Register a listener for layer updates.
*
* @param {function(number, number, string)} fn The update handler function.
* Should accept as arguments the line numbers for the start and end of
* the update and the side as a string.
@@ -95,6 +97,7 @@
/**
* Notify Layer listeners of changes to annotations.
*
* @param {number} start The line where the update starts.
* @param {number} end The line where the update ends.
* @param {string} side The side of the update. ('left' or 'right')
@@ -108,6 +111,7 @@
/**
* Handle change in the ranges by updating the ranges maps and by
* emitting appropriate update notifications.
*
* @param {Object} record The change record.
*/
_handleCommentRangesChange(record) {
@@ -134,7 +138,7 @@
this._updateRangesMap(
side, range, hovering, (forLine, start, end, hovering) => {
const index = forLine.findIndex(lineRange =>
lineRange.start === start && lineRange.end === end);
lineRange.start === start && lineRange.end === end);
forLine[index].hovering = hovering;
});
}
@@ -147,7 +151,7 @@
this._updateRangesMap(
side, range, hovering, (forLine, start, end) => {
const index = forLine.findIndex(lineRange =>
lineRange.start === start && lineRange.end === end);
lineRange.start === start && lineRange.end === end);
forLine.splice(index, 1);
});
}

View File

@@ -163,6 +163,7 @@
* The promise last returned from `process()` while the asynchronous
* processing is running - `null` otherwise. Provides a `cancel()`
* method that rejects it with `{isCancelled: true}`.
*
* @type {?Object}
*/
_processPromise: {
@@ -183,6 +184,7 @@
/**
* Annotation layer method to add syntax annotations to the given element
* for the given line.
*
* @param {!HTMLElement} el
* @param {!HTMLElement} lineNumberEl
* @param {!Object} line (GrDiffLine)
@@ -193,11 +195,11 @@
// Determine the side.
let side;
if (line.type === GrDiffLine.Type.REMOVE || (
line.type === GrDiffLine.Type.BOTH &&
line.type === GrDiffLine.Type.BOTH &&
el.getAttribute('data-side') !== 'right')) {
side = 'left';
} else if (line.type === GrDiffLine.Type.ADD || (
el.getAttribute('data-side') !== 'left')) {
el.getAttribute('data-side') !== 'left')) {
side = 'right';
}
@@ -227,6 +229,7 @@
/**
* Start processing syntax for the loaded diff and notify layer listeners
* as syntax info comes online.
*
* @return {Promise}
*/
process() {
@@ -322,6 +325,7 @@
* Take a string of HTML with the (potentially nested) syntax markers
* Highlight.js emits and emit a list of text ranges and classes for the
* markers.
*
* @param {string} str The string of HTML.
* @return {!Array<!Object>} The list of ranges.
*/
@@ -357,6 +361,7 @@
/**
* For a given state, process the syntax for the next line (or pair of
* lines).
*
* @param {!Object} state The processing state for the layer.
*/
_processNextLine(state) {
@@ -471,6 +476,7 @@
/**
* Tells whether the state has exhausted its current section.
*
* @param {!Object} state
* @return {boolean}
*/
@@ -487,6 +493,7 @@
/**
* For a given state, notify layer listeners of any processed line ranges
* that have not yet been notified.
*
* @param {!Object} state
*/
_notify(state) {

View File

@@ -112,6 +112,7 @@
/**
* Given a path string, checks that it is a valid file path.
*
* @param {string} path
* @return {boolean}
*/
@@ -126,6 +127,7 @@
/**
* Given a dom event, gets the dialog that lies along this event path.
*
* @param {!Event} e
* @return {!Element|undefined}
*/
@@ -214,17 +216,17 @@
const dialog = this._getDialogFromEvent(e);
return this.$.restAPI.renameFileInChangeEdit(this.change._number,
this._path, this._newPath).then(res => {
if (!res.ok) { return; }
this._closeDialog(dialog, true);
Gerrit.Nav.navigateToChange(this.change);
});
if (!res.ok) { return; }
this._closeDialog(dialog, true);
Gerrit.Nav.navigateToChange(this.change);
});
},
_queryFiles(input) {
return this.$.restAPI.queryChangeFiles(this.change._number,
this.patchNum, input).then(res => res.map(file => {
return {name: file};
}));
return {name: file};
}));
},
_computeIsInvisible(id, hiddenActions) {

View File

@@ -141,11 +141,11 @@
}
return this.$.restAPI.renameFileInChangeEdit(this._changeNum,
this._path, path).then(res => {
if (!res.ok) { return; }
if (!res.ok) { return; }
this._successfulSave = true;
this._viewEditInChangeView();
});
this._successfulSave = true;
this._viewEditInChangeView();
});
},
_viewEditInChangeView() {
@@ -191,13 +191,13 @@
this.$.storage.eraseEditableContentItem(this.storageKey);
return this.$.restAPI.saveChangeEdit(this._changeNum, this._path,
this._newContent).then(res => {
this._saving = false;
this._showAlert(res.ok ? SAVED_MESSAGE : SAVE_FAILED_MSG);
if (!res.ok) { return; }
this._saving = false;
this._showAlert(res.ok ? SAVED_MESSAGE : SAVE_FAILED_MSG);
if (!res.ok) { return; }
this._content = this._newContent;
this._successfulSave = true;
});
this._content = this._newContent;
this._successfulSave = true;
});
},
_showAlert(message) {

Some files were not shown because too many files have changed in this diff Show More