
Adds `.screen()` plugin API method for adding plugin-provided screens. Such screens only have common headers and footers, while rest of the page is filled with the registered web component. Any navigation to URL containing `#/x/` hash results in client-only redirect to `/x/` and showing appropriate plugin-provided screen. Adds a `plugin.screenUrl()` method for generating consistent URLs for such screens. Adds an example plugin with number of ways the provided API can be used. Adds partial support for GWT UI `.screen()` method. Notable difference - does not support RegExp for the screen matching. Change-Id: I0be3dee8eba6f8535a1fb2be05f473f3649bad8f
459 lines
14 KiB
HTML
459 lines
14 KiB
HTML
<!--
|
|
Copyright (C) 2017 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.
|
|
-->
|
|
<script>
|
|
(function(window) {
|
|
'use strict';
|
|
|
|
// Navigation parameters object format:
|
|
//
|
|
// Each object has a `view` property with a value from Gerrit.Nav.View. The
|
|
// remaining properties depend on the value used for view.
|
|
//
|
|
// - Gerrit.Nav.View.CHANGE:
|
|
// - `changeNum`, required, String: the numeric ID of the change.
|
|
//
|
|
// - Gerrit.Nav.View.SEARCH:
|
|
// - `query`, optional, String: the literal search query. If provided,
|
|
// the string will be used as the query, and all other params will be
|
|
// ignored.
|
|
// - `owner`, optional, String: the owner name.
|
|
// - `project`, optional, String: the project name.
|
|
// - `branch`, optional, String: the branch name.
|
|
// - `topic`, optional, String: the topic name.
|
|
// - `hashtag`, optional, String: the hashtag name.
|
|
// - `statuses`, optional, Array<String>: the list of change statuses to
|
|
// search for. If more than one is provided, the search will OR them
|
|
// together.
|
|
//
|
|
// - Gerrit.Nav.View.DIFF:
|
|
// - `changeNum`, required, String: the numeric ID of the change.
|
|
// - `path`, required, String: the filepath of the diff.
|
|
// - `patchNum`, required, Number, the patch for the right-hand-side of
|
|
// the diff.
|
|
// - `basePatchNum`, optional, Number, the patch for the left-hand-side
|
|
// of the diff. If `basePatchNum` is provided, then `patchNum` must
|
|
// also be provided.
|
|
// - `lineNum`, optional, Number, the line number to be selected on load.
|
|
// - `leftSide`, optional, Boolean, if a `lineNum` is provided, a value
|
|
// of true selects the line from base of the patch range. False by
|
|
// default.
|
|
//
|
|
// - Gerrit.Nav.View.GROUP:
|
|
// - `groupId`, required, String, the ID of the group.
|
|
// - `detail`, optional, String, the name of the group detail view.
|
|
// Takes any value from Gerrit.Nav.GroupDetailView.
|
|
|
|
window.Gerrit = window.Gerrit || {};
|
|
|
|
// Prevent redefinition.
|
|
if (window.Gerrit.hasOwnProperty('Nav')) { return; }
|
|
|
|
const uninitialized = () => {
|
|
console.warn('Use of uninitialized routing');
|
|
};
|
|
|
|
const EDIT_PATCHNUM = 'edit';
|
|
const PARENT_PATCHNUM = 'PARENT';
|
|
|
|
window.Gerrit.Nav = {
|
|
|
|
View: {
|
|
ADMIN: 'admin',
|
|
AGREEMENTS: 'agreements',
|
|
CHANGE: 'change',
|
|
DASHBOARD: 'dashboard',
|
|
DIFF: 'diff',
|
|
EDIT: 'edit',
|
|
GROUP: 'group',
|
|
PLUGIN_SCREEN: 'plugin-screen',
|
|
SEARCH: 'search',
|
|
SETTINGS: 'settings',
|
|
},
|
|
|
|
GroupDetailView: {
|
|
MEMBERS: 'members',
|
|
LOG: 'log',
|
|
},
|
|
|
|
WeblinkType: {
|
|
CHANGE: 'change',
|
|
FILE: 'file',
|
|
PATCHSET: 'patchset',
|
|
},
|
|
|
|
/** @type {Function} */
|
|
_navigate: uninitialized,
|
|
|
|
/** @type {Function} */
|
|
_generateUrl: uninitialized,
|
|
|
|
/** @type {Function} */
|
|
_generateWeblinks: uninitialized,
|
|
|
|
/**
|
|
* @param {number=} patchNum
|
|
* @param {number|string=} basePatchNum
|
|
*/
|
|
_checkPatchRange(patchNum, basePatchNum) {
|
|
if (basePatchNum && !patchNum) {
|
|
throw new Error('Cannot use base patch number without patch number.');
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Setup router implementation.
|
|
* @param {Function} navigate
|
|
* @param {Function} generateUrl
|
|
* @param {Function} generateWeblinks
|
|
*/
|
|
setup(navigate, generateUrl, generateWeblinks) {
|
|
this._navigate = navigate;
|
|
this._generateUrl = generateUrl;
|
|
this._generateWeblinks = generateWeblinks;
|
|
},
|
|
|
|
destroy() {
|
|
this._navigate = uninitialized;
|
|
this._generateUrl = uninitialized;
|
|
this._generateWeblinks = uninitialized;
|
|
},
|
|
|
|
/**
|
|
* Generate a URL for the given route parameters.
|
|
* @param {Object} params
|
|
* @return {string}
|
|
*/
|
|
_getUrlFor(params) {
|
|
return this._generateUrl(params);
|
|
},
|
|
|
|
getUrlForSearchQuery(query) {
|
|
return this._getUrlFor({
|
|
view: Gerrit.Nav.View.SEARCH,
|
|
query,
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @param {!string} project The name of the project.
|
|
* @param {boolean=} opt_openOnly When true, only search open changes in
|
|
* the project.
|
|
* @return {string}
|
|
*/
|
|
getUrlForProjectChanges(project, opt_openOnly) {
|
|
return this._getUrlFor({
|
|
view: Gerrit.Nav.View.SEARCH,
|
|
project,
|
|
statuses: opt_openOnly ? ['open'] : [],
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @param {string} branch The name of the branch.
|
|
* @param {string} project The name of the project.
|
|
* @param {string=} opt_status The status to search.
|
|
* @return {string}
|
|
*/
|
|
getUrlForBranch(branch, project, opt_status) {
|
|
return this._getUrlFor({
|
|
view: Gerrit.Nav.View.SEARCH,
|
|
branch,
|
|
project,
|
|
statuses: opt_status ? [opt_status] : undefined,
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @param {string} topic The name of the topic.
|
|
* @return {string}
|
|
*/
|
|
getUrlForTopic(topic) {
|
|
return this._getUrlFor({
|
|
view: Gerrit.Nav.View.SEARCH,
|
|
topic,
|
|
statuses: ['open', 'merged'],
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @param {string} hashtag The name of the hashtag.
|
|
* @return {string}
|
|
*/
|
|
getUrlForHashtag(hashtag) {
|
|
return this._getUrlFor({
|
|
view: Gerrit.Nav.View.SEARCH,
|
|
hashtag,
|
|
statuses: ['open', 'merged'],
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Navigate to a search for changes with the given status.
|
|
* @param {string} status
|
|
*/
|
|
navigateToStatusSearch(status) {
|
|
this._navigate(this._getUrlFor({
|
|
view: Gerrit.Nav.View.SEARCH,
|
|
statuses: [status],
|
|
}));
|
|
},
|
|
|
|
/**
|
|
* @param {!Object} change The change object.
|
|
* @param {number=} opt_patchNum
|
|
* @param {number|string=} opt_basePatchNum The string 'PARENT' can be
|
|
* used for none.
|
|
* @return {string}
|
|
*/
|
|
getUrlForChange(change, opt_patchNum, opt_basePatchNum) {
|
|
if (opt_basePatchNum === PARENT_PATCHNUM) {
|
|
opt_basePatchNum = undefined;
|
|
}
|
|
|
|
this._checkPatchRange(opt_patchNum, opt_basePatchNum);
|
|
return this._getUrlFor({
|
|
view: Gerrit.Nav.View.CHANGE,
|
|
changeNum: change._number,
|
|
project: change.project,
|
|
patchNum: opt_patchNum,
|
|
basePatchNum: opt_basePatchNum,
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @param {number} changeNum
|
|
* @param {string} project The name of the project.
|
|
* @param {number=} opt_patchNum
|
|
* @return {string}
|
|
*/
|
|
getUrlForChangeById(changeNum, project, opt_patchNum) {
|
|
return this._getUrlFor({
|
|
view: Gerrit.Nav.View.CHANGE,
|
|
changeNum,
|
|
project,
|
|
patchNum: opt_patchNum,
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @param {!Object} change The change object.
|
|
* @param {number=} opt_patchNum
|
|
* @param {number|string=} opt_basePatchNum The string 'PARENT' can be
|
|
* used for none.
|
|
*/
|
|
navigateToChange(change, opt_patchNum, opt_basePatchNum) {
|
|
this._navigate(this.getUrlForChange(change, opt_patchNum,
|
|
opt_basePatchNum));
|
|
},
|
|
|
|
/**
|
|
* @param {{ _number: number, project: string }} change The change object.
|
|
* @param {string} path The file path.
|
|
* @param {number=} opt_patchNum
|
|
* @param {number|string=} opt_basePatchNum The string 'PARENT' can be
|
|
* used for none.
|
|
* @return {string}
|
|
*/
|
|
getUrlForDiff(change, path, opt_patchNum, opt_basePatchNum) {
|
|
return this.getUrlForDiffById(change._number, change.project, path,
|
|
opt_patchNum, opt_basePatchNum);
|
|
},
|
|
|
|
/**
|
|
* @param {number} changeNum
|
|
* @param {string} project The name of the project.
|
|
* @param {string} path The file path.
|
|
* @param {number=} opt_patchNum
|
|
* @param {number|string=} opt_basePatchNum The string 'PARENT' can be
|
|
* used for none.
|
|
* @param {number=} opt_lineNum
|
|
* @param {boolean=} opt_leftSide
|
|
* @return {string}
|
|
*/
|
|
getUrlForDiffById(changeNum, project, path, opt_patchNum,
|
|
opt_basePatchNum, opt_lineNum, opt_leftSide) {
|
|
if (opt_basePatchNum === PARENT_PATCHNUM) {
|
|
opt_basePatchNum = undefined;
|
|
}
|
|
|
|
this._checkPatchRange(opt_patchNum, opt_basePatchNum);
|
|
return this._getUrlFor({
|
|
view: Gerrit.Nav.View.DIFF,
|
|
changeNum,
|
|
project,
|
|
path,
|
|
patchNum: opt_patchNum,
|
|
basePatchNum: opt_basePatchNum,
|
|
lineNum: opt_lineNum,
|
|
leftSide: opt_leftSide,
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @param {{ _number: number, project: string }} change The change object.
|
|
* @param {string} path The file path.
|
|
* @return {string}
|
|
*/
|
|
getEditUrlForDiff(change, path) {
|
|
return this.getEditUrlForDiffById(change._number, change.project, path);
|
|
},
|
|
|
|
/**
|
|
* @param {number} changeNum
|
|
* @param {string} project The name of the project.
|
|
* @param {string} path The file path.
|
|
* @return {string}
|
|
*/
|
|
getEditUrlForDiffById(changeNum, project, path) {
|
|
return this._getUrlFor({
|
|
view: Gerrit.Nav.View.EDIT,
|
|
changeNum,
|
|
project,
|
|
path,
|
|
patchNum: EDIT_PATCHNUM,
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @param {!Object} change The change object.
|
|
* @param {string} path The file path.
|
|
* @param {number=} opt_patchNum
|
|
* @param {number|string=} opt_basePatchNum The string 'PARENT' can be
|
|
* used for none.
|
|
*/
|
|
navigateToDiff(change, path, opt_patchNum, opt_basePatchNum) {
|
|
this._navigate(this.getUrlForDiff(change, path, opt_patchNum,
|
|
opt_basePatchNum));
|
|
},
|
|
|
|
/**
|
|
* @param {string} owner The name of the owner.
|
|
* @return {string}
|
|
*/
|
|
getUrlForOwner(owner) {
|
|
return this._getUrlFor({
|
|
view: Gerrit.Nav.View.DASHBOARD,
|
|
user: owner,
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Navigate to an arbitrary relative URL.
|
|
* @param {string} relativeUrl
|
|
*/
|
|
navigateToRelativeUrl(relativeUrl) {
|
|
if (!relativeUrl.startsWith('/')) {
|
|
throw new Error('navigateToRelativeUrl with non-relative URL');
|
|
}
|
|
this._navigate(relativeUrl);
|
|
},
|
|
|
|
/**
|
|
* @param {string} groupId
|
|
* @return {string}
|
|
*/
|
|
getUrlForGroup(groupId) {
|
|
return this._getUrlFor({
|
|
view: Gerrit.Nav.View.GROUP,
|
|
groupId,
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @param {string} groupId
|
|
* @return {string}
|
|
*/
|
|
getUrlForGroupLog(groupId) {
|
|
return this._getUrlFor({
|
|
view: Gerrit.Nav.View.GROUP,
|
|
groupId,
|
|
detail: Gerrit.Nav.GroupDetailView.LOG,
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @param {string} groupId
|
|
* @return {string}
|
|
*/
|
|
getUrlForGroupMembers(groupId) {
|
|
return this._getUrlFor({
|
|
view: Gerrit.Nav.View.GROUP,
|
|
groupId,
|
|
detail: Gerrit.Nav.GroupDetailView.MEMBERS,
|
|
});
|
|
},
|
|
|
|
getUrlForSettings() {
|
|
return this._getUrlFor({view: Gerrit.Nav.View.SETTINGS});
|
|
},
|
|
|
|
/**
|
|
* @param {string} repo
|
|
* @param {string} commit
|
|
* @param {string} file
|
|
* @param {Object=} opt_options
|
|
* @return {
|
|
* Array<{label: string, url: string}>|
|
|
* {label: string, url: string}
|
|
* }
|
|
*/
|
|
getFileWebLinks(repo, commit, file, opt_options) {
|
|
const params = {type: Gerrit.Nav.WeblinkType.FILE, repo, commit, file};
|
|
if (opt_options) {
|
|
params.options = opt_options;
|
|
}
|
|
return [].concat(this._generateWeblinks(params));
|
|
},
|
|
|
|
/**
|
|
* @param {string} repo
|
|
* @param {string} commit
|
|
* @param {Object=} opt_options
|
|
* @return {{label: string, url: string}}
|
|
*/
|
|
getPatchSetWeblink(repo, commit, opt_options) {
|
|
const params = {type: Gerrit.Nav.WeblinkType.PATCHSET, repo, commit};
|
|
if (opt_options) {
|
|
params.options = opt_options;
|
|
}
|
|
const result = this._generateWeblinks(params);
|
|
if (Array.isArray(result)) {
|
|
return result.pop();
|
|
} else {
|
|
return result;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @param {string} repo
|
|
* @param {string} commit
|
|
* @param {Object=} opt_options
|
|
* @return {
|
|
* Array<{label: string, url: string}>|
|
|
* {label: string, url: string}
|
|
* }
|
|
*/
|
|
getChangeWeblinks(repo, commit, opt_options) {
|
|
const params = {type: Gerrit.Nav.WeblinkType.CHANGE, repo, commit};
|
|
if (opt_options) {
|
|
params.options = opt_options;
|
|
}
|
|
return [].concat(this._generateWeblinks(params));
|
|
},
|
|
};
|
|
})(window);
|
|
</script>
|