blob: 9046d23a70e5f728fffba48fc5aff130c290f82e [file] [log] [blame]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/* eslint-disable no-var */
/**
* This file contains JS functions that implement various navigation
* features of Monorail.
*/
/**
* Navigate the browser to the given URL.
* @param {string} url The URL of the page to browse.
* @param {boolean} newWindow Open a new tab or window.
*/
function TKR_go(url, newWindow) {
if (newWindow) {
window.open(url, '_blank');
} else {
document.location = url;
}
}
/**
* Tell the browser to scroll to the given anchor on the current page.
* @param {string} anchor Name of the <a name="xxx"> anchor on the page.
*/
function TKR_goToAnchor(anchor) {
document.location.hash = anchor;
}
/**
* Get the user-editable colspec form field. This text field is normally
* display:none, but it is shown when the user chooses "Edit columns...".
* We need a function to get this element because there are multiple form
* fields on the page with name="colspec", and an IE misfeature sets their
* id attributes as well, which makes document.getElementById() fail.
* @return {Element} user editable colspec form field.
*/
function TKR_getColspecElement() {
const elem = document.getElementById('colspec_field');
return elem && elem.firstChild;
}
/**
* Get the artifact search form field. This is a visible text field where
* the user enters a query for issues. This function
* is needed because there is also the project search field on the each page,
* and it has name="q". An IE misfeature confuses name="..." with id="...".
* @return {Element} artifact query form field, or undefined.
*/
function TKR_getArtifactSearchField() {
const element = _getSearchBarComponent();
if (!element) return $('searchq');
return element.shadowRoot.querySelector('#searchq');
}
/**
* Get the can selector. This function
* @return {Element} can input element.
*/
function TKR_getArtifactCanField() {
const element = _getSearchBarComponent();
if (!element) return $('can');
return element.shadowRoot.querySelector('#can');
}
function _getSearchBarComponent() {
const element = document.querySelector('mr-header');
if (!element) return;
return element.shadowRoot.querySelector('mr-search-bar');
}
/**
* Build a query string for all the common contextual values that we use.
*/
function TKR_formatContextQueryArgs() {
let args = '';
let colspec = _ctxDefaultColspec;
const colSpecElem = TKR_getColspecElement();
if (colSpecElem) {
colspec = colSpecElem.value;
}
if (_ctxHotlistID != '') args += '&hotlist_id=' + _ctxHotlistID;
if (_ctxCan != 2) args += '&can=' + _ctxCan;
args += '&q=' + encodeURIComponent(_ctxQuery);
if (_ctxSortspec != '') args += '&sort=' + _ctxSortspec;
if (_ctxGroupBy != '') args += '&groupby=' + _ctxGroupBy;
if (colspec != _ctxDefaultColspec) args += '&colspec=' + colspec;
if (_ctxStart != 0) args += '&start=' + _ctxStart;
if (_ctxNum != _ctxResultsPerPage) args += '&num=' + _ctxNum;
if (!colSpecElem) args += '&mode=grid';
return args;
}
// Fields that should use ":" when filtering.
const _PRETOKENIZED_FIELDS = [
'owner', 'reporter', 'cc', 'commentby', 'component'];
/**
* The user wants to narrow their search results by adding a search term
* for the given prefix and value. Reload the issue list page with that
* additional search term.
* @param {string} prefix Field or label prefix, e.g., "Priority".
* @param {string} suffix Field or label value, e.g., "High".
*/
function TKR_filterTo(prefix, suffix) {
let newQuery = TKR_getArtifactSearchField().value;
if (newQuery != '') newQuery += ' ';
let op = '=';
for (let i = 0; i < _PRETOKENIZED_FIELDS.length; i++) {
if (prefix == _PRETOKENIZED_FIELDS[i]) {
op = ':';
break;
}
}
newQuery += prefix + op + suffix;
let url = 'list?can=' + TKR_getArtifactCanField().value + '&q=' + newQuery;
if ($('sort') && $('sort').value) url += '&sort=' + $('sort').value;
url += '&colspec=' + TKR_getColspecElement().value;
TKR_go(url);
}
/**
* The user wants to sort their search results by adding a sort spec
* for the given column. Reload the issue list page with that
* additional sort spec.
* @param {string} colname Field or label prefix, e.g., "Priority".
* @param {boolean} descending True if the values should be reversed.
*/
function TKR_addSort(colname, descending) {
let existingSortSpec = '';
if ($('sort')) {
existingSortSpec = $('sort').value;
}
const oldSpecs = existingSortSpec.split(/ +/);
let sortDirective = colname;
if (descending) sortDirective = '-' + colname;
const specs = [sortDirective];
for (let i = 0; i < oldSpecs.length; i++) {
if (oldSpecs[i] != '' && oldSpecs[i] != colname &&
oldSpecs[i] != '-' + colname) {
specs.push(oldSpecs[i]);
}
}
const isHotlist = window.location.href.includes('/hotlists/');
let url = isHotlist ? ($('hotlist_name').value + '?') : ('list?');
url += ('can='+ TKR_getArtifactCanField().value + '&q=' +
TKR_getArtifactSearchField().value);
url += '&sort=' + specs.join('+');
url += '&colspec=' + TKR_getColspecElement().value;
TKR_go(url);
}
/** Convenience function for sorting in ascending order. */
function TKR_sortUp(colname) {
TKR_addSort(colname, false);
}
/** Convenience function for sorting in descending order. */
function TKR_sortDown(colname) {
TKR_addSort(colname, true);
}