|  | <!-- | 
|  | @license | 
|  | 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. | 
|  | //    - `project`, optional, String: the project name. | 
|  | //    - `patchNum`, optional, 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. | 
|  | //    - `edit`, optional, Boolean: whether or not to load the file list with | 
|  | //        edit controls. | 
|  | //    - `messageHash`, optional, String: the hash of the change message to | 
|  | //        scroll to. | 
|  | // | 
|  | // - 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. | 
|  | //    - `offset`, optional, Number: the offset for the query. | 
|  | // | 
|  | //  - 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. | 
|  | // | 
|  | //  - Gerrit.Nav.View.REPO: | 
|  | //    - `repoName`, required, String: the name of the repo | 
|  | //    - `detail`, optional, String: the name of the repo detail view. | 
|  | //      Takes any value from Gerrit.Nav.RepoDetailView. | 
|  | // | 
|  | //  - Gerrit.Nav.View.DASHBOARD | 
|  | //    - `repo`, optional, String. | 
|  | //    - `sections`, optional, Array of objects with `title` and `query` | 
|  | //      strings. | 
|  | //    - `user`, optional, String. | 
|  | // | 
|  | //  - Gerrit.Nav.View.ROOT: | 
|  | //    - no possible parameters. | 
|  |  | 
|  | 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'; | 
|  |  | 
|  | const USER_PLACEHOLDER_PATTERN = /\$\{user\}/g; | 
|  |  | 
|  | // NOTE: These queries are tested in Java. Any changes made to definitions | 
|  | // here require corresponding changes to: | 
|  | // javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java | 
|  | const DEFAULT_SECTIONS = [ | 
|  | { | 
|  | // Changes with unpublished draft comments. This section is omitted when | 
|  | // viewing other users, so we don't need to filter anything out. | 
|  | name: 'Has draft comments', | 
|  | query: 'has:draft', | 
|  | selfOnly: true, | 
|  | hideIfEmpty: true, | 
|  | suffixForDashboard: 'limit:10', | 
|  | }, | 
|  | { | 
|  | // Changes that are assigned to the viewed user. | 
|  | name: 'Assigned reviews', | 
|  | query: 'assignee:${user} (-is:wip OR owner:self OR assignee:self) ' + | 
|  | 'is:open -is:ignored', | 
|  | hideIfEmpty: true, | 
|  | }, | 
|  | { | 
|  | // WIP open changes owned by viewing user. This section is omitted when | 
|  | // viewing other users, so we don't need to filter anything out. | 
|  | name: 'Work in progress', | 
|  | query: 'is:open owner:${user} is:wip', | 
|  | selfOnly: true, | 
|  | hideIfEmpty: true, | 
|  | }, | 
|  | { | 
|  | // Non-WIP open changes owned by viewed user. Filter out changes ignored | 
|  | // by the viewing user. | 
|  | name: 'Outgoing reviews', | 
|  | query: 'is:open owner:${user} -is:wip -is:ignored', | 
|  | isOutgoing: true, | 
|  | }, | 
|  | { | 
|  | // Non-WIP open changes not owned by the viewed user, that the viewed user | 
|  | // is associated with (as either a reviewer or the assignee). Changes | 
|  | // ignored by the viewing user are filtered out. | 
|  | name: 'Incoming reviews', | 
|  | query: 'is:open -owner:${user} -is:wip -is:ignored ' + | 
|  | '(reviewer:${user} OR assignee:${user})', | 
|  | }, | 
|  | { | 
|  | // Open changes the viewed user is CCed on. Changes ignored by the viewing | 
|  | // user are filtered out. | 
|  | name: 'CCed on', | 
|  | query: 'is:open -is:ignored cc:${user}', | 
|  | }, | 
|  | { | 
|  | name: 'Recently closed', | 
|  | // Closed changes where viewed user is owner, reviewer, or assignee. | 
|  | // Changes ignored by the viewing user are filtered out, and so are WIP | 
|  | // changes not owned by the viewing user (the one instance of | 
|  | // 'owner:self' is intentional and implements this logic). | 
|  | query: 'is:closed -is:ignored (-is:wip OR owner:self) ' + | 
|  | '(owner:${user} OR reviewer:${user} OR assignee:${user} ' + | 
|  | 'OR cc:${user})', | 
|  | suffixForDashboard: '-age:4w limit:10', | 
|  | }, | 
|  | ]; | 
|  |  | 
|  | window.Gerrit.Nav = { | 
|  |  | 
|  | View: { | 
|  | ADMIN: 'admin', | 
|  | AGREEMENTS: 'agreements', | 
|  | CHANGE: 'change', | 
|  | DASHBOARD: 'dashboard', | 
|  | DIFF: 'diff', | 
|  | DOCUMENTATION_SEARCH: 'documentation-search', | 
|  | EDIT: 'edit', | 
|  | GROUP: 'group', | 
|  | PLUGIN_SCREEN: 'plugin-screen', | 
|  | REPO: 'repo', | 
|  | ROOT: 'root', | 
|  | SEARCH: 'search', | 
|  | SETTINGS: 'settings', | 
|  | }, | 
|  |  | 
|  | GroupDetailView: { | 
|  | MEMBERS: 'members', | 
|  | LOG: 'log', | 
|  | }, | 
|  |  | 
|  | RepoDetailView: { | 
|  | ACCESS: 'access', | 
|  | BRANCHES: 'branches', | 
|  | COMMANDS: 'commands', | 
|  | DASHBOARDS: 'dashboards', | 
|  | TAGS: 'tags', | 
|  | }, | 
|  |  | 
|  | WeblinkType: { | 
|  | CHANGE: 'change', | 
|  | FILE: 'file', | 
|  | PATCHSET: 'patchset', | 
|  | }, | 
|  |  | 
|  | /** @type {Function} */ | 
|  | _navigate: uninitialized, | 
|  |  | 
|  | /** @type {Function} */ | 
|  | _generateUrl: uninitialized, | 
|  |  | 
|  | /** @type {Function} */ | 
|  | _generateWeblinks: uninitialized, | 
|  |  | 
|  | /** @type {Function} */ | 
|  | mapCommentlinks: 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(!string)} navigate the router-abstracted equivalent of | 
|  | *     `window.location.href = ...`. Takes a string. | 
|  | * @param {function(!Object): string} generateUrl generates a URL given | 
|  | *     navigation parameters, detailed in the file header. | 
|  | * @param {function(!Object): string} generateWeblinks weblinks generator | 
|  | *     function takes single payload parameter with type property that | 
|  | *  determines which | 
|  | *     part of the UI is the consumer of the weblinks. type property can | 
|  | *     be one of file, change, or patchset. | 
|  | *     - For file type, payload will also contain string properties: repo, | 
|  | *         commit, file. | 
|  | *     - For patchset type, payload will also contain string properties: | 
|  | *         repo, commit. | 
|  | *     - For change type, payload will also contain string properties: | 
|  | *         repo, commit. If server provides weblinks, those will be passed | 
|  | *         as options.weblinks property on the main payload object. | 
|  | * @param {function(!Object): Object} mapCommentlinks provides an escape | 
|  | *     hatch to modify the commentlinks object, e.g. if it contains any | 
|  | *     relative URLs. | 
|  | */ | 
|  | setup(navigate, generateUrl, generateWeblinks, mapCommentlinks) { | 
|  | this._navigate = navigate; | 
|  | this._generateUrl = generateUrl; | 
|  | this._generateWeblinks = generateWeblinks; | 
|  | this.mapCommentlinks = mapCommentlinks; | 
|  | }, | 
|  |  | 
|  | destroy() { | 
|  | this._navigate = uninitialized; | 
|  | this._generateUrl = uninitialized; | 
|  | this._generateWeblinks = uninitialized; | 
|  | this.mapCommentlinks = uninitialized; | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * Generate a URL for the given route parameters. | 
|  | * | 
|  | * @param {Object} params | 
|  | * @return {string} | 
|  | */ | 
|  | _getUrlFor(params) { | 
|  | return this._generateUrl(params); | 
|  | }, | 
|  |  | 
|  | getUrlForSearchQuery(query, opt_offset) { | 
|  | return this._getUrlFor({ | 
|  | view: Gerrit.Nav.View.SEARCH, | 
|  | query, | 
|  | offset: opt_offset, | 
|  | }); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * @param {!string} project The name of the project. | 
|  | * @param {boolean=} opt_openOnly When true, only search open changes in | 
|  | *     the project. | 
|  | * @param {string=} opt_host The host in which to search. | 
|  | * @return {string} | 
|  | */ | 
|  | getUrlForProjectChanges(project, opt_openOnly, opt_host) { | 
|  | return this._getUrlFor({ | 
|  | view: Gerrit.Nav.View.SEARCH, | 
|  | project, | 
|  | statuses: opt_openOnly ? ['open'] : [], | 
|  | host: opt_host, | 
|  | }); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * @param {string} branch The name of the branch. | 
|  | * @param {string} project The name of the project. | 
|  | * @param {string=} opt_status The status to search. | 
|  | * @param {string=} opt_host The host in which to search. | 
|  | * @return {string} | 
|  | */ | 
|  | getUrlForBranch(branch, project, opt_status, opt_host) { | 
|  | return this._getUrlFor({ | 
|  | view: Gerrit.Nav.View.SEARCH, | 
|  | branch, | 
|  | project, | 
|  | statuses: opt_status ? [opt_status] : undefined, | 
|  | host: opt_host, | 
|  | }); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * @param {string} topic The name of the topic. | 
|  | * @param {string=} opt_host The host in which to search. | 
|  | * @return {string} | 
|  | */ | 
|  | getUrlForTopic(topic, opt_host) { | 
|  | return this._getUrlFor({ | 
|  | view: Gerrit.Nav.View.SEARCH, | 
|  | topic, | 
|  | statuses: ['open', 'merged'], | 
|  | host: opt_host, | 
|  | }); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * @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], | 
|  | })); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * Navigate to a search query | 
|  | * | 
|  | * @param {string} query | 
|  | * @param {number=} opt_offset | 
|  | */ | 
|  | navigateToSearchQuery(query, opt_offset) { | 
|  | return this._navigate(this.getUrlForSearchQuery(query, opt_offset)); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * Navigate to the user's dashboard | 
|  | */ | 
|  | navigateToUserDashboard() { | 
|  | return this._navigate(this.getUrlForUserDashboard('self')); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * @param {!Object} change The change object. | 
|  | * @param {number=} opt_patchNum | 
|  | * @param {number|string=} opt_basePatchNum The string 'PARENT' can be | 
|  | *     used for none. | 
|  | * @param {boolean=} opt_isEdit | 
|  | * @param {string=} opt_messageHash | 
|  | * @return {string} | 
|  | */ | 
|  | getUrlForChange(change, opt_patchNum, opt_basePatchNum, opt_isEdit, | 
|  | opt_messageHash) { | 
|  | 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, | 
|  | edit: opt_isEdit, | 
|  | host: change.internalHost || undefined, | 
|  | messageHash: opt_messageHash, | 
|  | }); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * @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. | 
|  | * @param {boolean=} opt_isEdit | 
|  | */ | 
|  | navigateToChange(change, opt_patchNum, opt_basePatchNum, opt_isEdit) { | 
|  | this._navigate(this.getUrlForChange(change, opt_patchNum, | 
|  | opt_basePatchNum, opt_isEdit)); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * @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. | 
|  | * @param {number|string=} opt_lineNum | 
|  | * @return {string} | 
|  | */ | 
|  | getUrlForDiff(change, path, opt_patchNum, opt_basePatchNum, opt_lineNum) { | 
|  | return this.getUrlForDiffById(change._number, change.project, path, | 
|  | opt_patchNum, opt_basePatchNum, opt_lineNum); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * @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. | 
|  | * @param {number=} opt_patchNum | 
|  | * @return {string} | 
|  | */ | 
|  | getEditUrlForDiff(change, path, opt_patchNum) { | 
|  | return this.getEditUrlForDiffById(change._number, change.project, path, | 
|  | opt_patchNum); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * @param {number} changeNum | 
|  | * @param {string} project The name of the project. | 
|  | * @param {string} path The file path. | 
|  | * @param {number|string=} opt_patchNum The patchNum the file content | 
|  | *    should be based on, or ${EDIT_PATCHNUM} if left undefined. | 
|  | * @return {string} | 
|  | */ | 
|  | getEditUrlForDiffById(changeNum, project, path, opt_patchNum) { | 
|  | return this._getUrlFor({ | 
|  | view: Gerrit.Nav.View.EDIT, | 
|  | changeNum, | 
|  | project, | 
|  | path, | 
|  | patchNum: opt_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.SEARCH, | 
|  | owner, | 
|  | }); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * @param {string} user The name of the user. | 
|  | * @return {string} | 
|  | */ | 
|  | getUrlForUserDashboard(user) { | 
|  | return this._getUrlFor({ | 
|  | view: Gerrit.Nav.View.DASHBOARD, | 
|  | user, | 
|  | }); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * @return {string} | 
|  | */ | 
|  | getUrlForRoot() { | 
|  | return this._getUrlFor({ | 
|  | view: Gerrit.Nav.View.ROOT, | 
|  | }); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * @param {string} repo The name of the repo. | 
|  | * @param {string} dashboard The ID of the dashboard, in the form of | 
|  | *     '<ref>:<path>'. | 
|  | * @return {string} | 
|  | */ | 
|  | getUrlForRepoDashboard(repo, dashboard) { | 
|  | return this._getUrlFor({ | 
|  | view: Gerrit.Nav.View.DASHBOARD, | 
|  | repo, | 
|  | dashboard, | 
|  | }); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * 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} repoName | 
|  | * @return {string} | 
|  | */ | 
|  | getUrlForRepo(repoName) { | 
|  | return this._getUrlFor({ | 
|  | view: Gerrit.Nav.View.REPO, | 
|  | repoName, | 
|  | }); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * Navigate to a repo settings page. | 
|  | * | 
|  | * @param {string} repoName | 
|  | */ | 
|  | navigateToRepo(repoName) { | 
|  | this._navigate(this.getUrlForRepo(repoName)); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * @param {string} repoName | 
|  | * @return {string} | 
|  | */ | 
|  | getUrlForRepoTags(repoName) { | 
|  | return this._getUrlFor({ | 
|  | view: Gerrit.Nav.View.REPO, | 
|  | repoName, | 
|  | detail: Gerrit.Nav.RepoDetailView.TAGS, | 
|  | }); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * @param {string} repoName | 
|  | * @return {string} | 
|  | */ | 
|  | getUrlForRepoBranches(repoName) { | 
|  | return this._getUrlFor({ | 
|  | view: Gerrit.Nav.View.REPO, | 
|  | repoName, | 
|  | detail: Gerrit.Nav.RepoDetailView.BRANCHES, | 
|  | }); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * @param {string} repoName | 
|  | * @return {string} | 
|  | */ | 
|  | getUrlForRepoAccess(repoName) { | 
|  | return this._getUrlFor({ | 
|  | view: Gerrit.Nav.View.REPO, | 
|  | repoName, | 
|  | detail: Gerrit.Nav.RepoDetailView.ACCESS, | 
|  | }); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * @param {string} repoName | 
|  | * @return {string} | 
|  | */ | 
|  | getUrlForRepoCommands(repoName) { | 
|  | return this._getUrlFor({ | 
|  | view: Gerrit.Nav.View.REPO, | 
|  | repoName, | 
|  | detail: Gerrit.Nav.RepoDetailView.COMMANDS, | 
|  | }); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * @param {string} repoName | 
|  | * @return {string} | 
|  | */ | 
|  | getUrlForRepoDashboards(repoName) { | 
|  | return this._getUrlFor({ | 
|  | view: Gerrit.Nav.View.REPO, | 
|  | repoName, | 
|  | detail: Gerrit.Nav.RepoDetailView.DASHBOARDS, | 
|  | }); | 
|  | }, | 
|  |  | 
|  | /** | 
|  | * @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)); | 
|  | }, | 
|  |  | 
|  | 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), | 
|  | })); | 
|  | return {title, sections}; | 
|  | }, | 
|  | }; | 
|  | })(window); | 
|  | </script> |