blob: 9046d23a70e5f728fffba48fc5aff130c290f82e [file] [log] [blame]
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +01001// Copyright 2016 The Chromium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Copybara854996b2021-09-07 19:36:02 +00004/* eslint-disable no-var */
5
6/**
7 * This file contains JS functions that implement various navigation
8 * features of Monorail.
9 */
10
11
12/**
13 * Navigate the browser to the given URL.
14 * @param {string} url The URL of the page to browse.
15 * @param {boolean} newWindow Open a new tab or window.
16 */
17function TKR_go(url, newWindow) {
18 if (newWindow) {
19 window.open(url, '_blank');
20 } else {
21 document.location = url;
22 }
23}
24
25
26/**
27 * Tell the browser to scroll to the given anchor on the current page.
28 * @param {string} anchor Name of the <a name="xxx"> anchor on the page.
29 */
30function TKR_goToAnchor(anchor) {
31 document.location.hash = anchor;
32}
33
34
35/**
36 * Get the user-editable colspec form field. This text field is normally
37 * display:none, but it is shown when the user chooses "Edit columns...".
38 * We need a function to get this element because there are multiple form
39 * fields on the page with name="colspec", and an IE misfeature sets their
40 * id attributes as well, which makes document.getElementById() fail.
41 * @return {Element} user editable colspec form field.
42 */
43function TKR_getColspecElement() {
44 const elem = document.getElementById('colspec_field');
45 return elem && elem.firstChild;
46}
47
48
49/**
50 * Get the artifact search form field. This is a visible text field where
51 * the user enters a query for issues. This function
52 * is needed because there is also the project search field on the each page,
53 * and it has name="q". An IE misfeature confuses name="..." with id="...".
54 * @return {Element} artifact query form field, or undefined.
55 */
56function TKR_getArtifactSearchField() {
57 const element = _getSearchBarComponent();
58 if (!element) return $('searchq');
59
60 return element.shadowRoot.querySelector('#searchq');
61}
62
63
64/**
65 * Get the can selector. This function
66 * @return {Element} can input element.
67 */
68function TKR_getArtifactCanField() {
69 const element = _getSearchBarComponent();
70 if (!element) return $('can');
71
72 return element.shadowRoot.querySelector('#can');
73}
74
75
76function _getSearchBarComponent() {
77 const element = document.querySelector('mr-header');
78 if (!element) return;
79
80 return element.shadowRoot.querySelector('mr-search-bar');
81}
82
83
84/**
85 * Build a query string for all the common contextual values that we use.
86 */
87function TKR_formatContextQueryArgs() {
88 let args = '';
89 let colspec = _ctxDefaultColspec;
90 const colSpecElem = TKR_getColspecElement();
91 if (colSpecElem) {
92 colspec = colSpecElem.value;
93 }
94
95 if (_ctxHotlistID != '') args += '&hotlist_id=' + _ctxHotlistID;
96 if (_ctxCan != 2) args += '&can=' + _ctxCan;
97 args += '&q=' + encodeURIComponent(_ctxQuery);
98 if (_ctxSortspec != '') args += '&sort=' + _ctxSortspec;
99 if (_ctxGroupBy != '') args += '&groupby=' + _ctxGroupBy;
100 if (colspec != _ctxDefaultColspec) args += '&colspec=' + colspec;
101 if (_ctxStart != 0) args += '&start=' + _ctxStart;
102 if (_ctxNum != _ctxResultsPerPage) args += '&num=' + _ctxNum;
103 if (!colSpecElem) args += '&mode=grid';
104 return args;
105}
106
107// Fields that should use ":" when filtering.
108const _PRETOKENIZED_FIELDS = [
109 'owner', 'reporter', 'cc', 'commentby', 'component'];
110
111/**
112 * The user wants to narrow their search results by adding a search term
113 * for the given prefix and value. Reload the issue list page with that
114 * additional search term.
115 * @param {string} prefix Field or label prefix, e.g., "Priority".
116 * @param {string} suffix Field or label value, e.g., "High".
117 */
118function TKR_filterTo(prefix, suffix) {
119 let newQuery = TKR_getArtifactSearchField().value;
120 if (newQuery != '') newQuery += ' ';
121
122 let op = '=';
123 for (let i = 0; i < _PRETOKENIZED_FIELDS.length; i++) {
124 if (prefix == _PRETOKENIZED_FIELDS[i]) {
125 op = ':';
126 break;
127 }
128 }
129
130 newQuery += prefix + op + suffix;
131 let url = 'list?can=' + TKR_getArtifactCanField().value + '&q=' + newQuery;
132 if ($('sort') && $('sort').value) url += '&sort=' + $('sort').value;
133 url += '&colspec=' + TKR_getColspecElement().value;
134 TKR_go(url);
135}
136
137
138/**
139 * The user wants to sort their search results by adding a sort spec
140 * for the given column. Reload the issue list page with that
141 * additional sort spec.
142 * @param {string} colname Field or label prefix, e.g., "Priority".
143 * @param {boolean} descending True if the values should be reversed.
144 */
145function TKR_addSort(colname, descending) {
146 let existingSortSpec = '';
147 if ($('sort')) {
148 existingSortSpec = $('sort').value;
149 }
150 const oldSpecs = existingSortSpec.split(/ +/);
151 let sortDirective = colname;
152 if (descending) sortDirective = '-' + colname;
153 const specs = [sortDirective];
154 for (let i = 0; i < oldSpecs.length; i++) {
155 if (oldSpecs[i] != '' && oldSpecs[i] != colname &&
156 oldSpecs[i] != '-' + colname) {
157 specs.push(oldSpecs[i]);
158 }
159 }
160
161 const isHotlist = window.location.href.includes('/hotlists/');
162 let url = isHotlist ? ($('hotlist_name').value + '?') : ('list?');
163 url += ('can='+ TKR_getArtifactCanField().value + '&q=' +
164 TKR_getArtifactSearchField().value);
165 url += '&sort=' + specs.join('+');
166 url += '&colspec=' + TKR_getColspecElement().value;
167 TKR_go(url);
168}
169
170/** Convenience function for sorting in ascending order. */
171function TKR_sortUp(colname) {
172 TKR_addSort(colname, false);
173}
174
175/** Convenience function for sorting in descending order. */
176function TKR_sortDown(colname) {
177 TKR_addSort(colname, true);
178}