1926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Copyright (C) 2013 Google Inc. All rights reserved.
2926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)//
3926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without
4926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// modification, are permitted provided that the following conditions are
5926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// met:
6926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)//
7926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)//         * Redistributions of source code must retain the above copyright
8926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// notice, this list of conditions and the following disclaimer.
9926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)//         * Redistributions in binary form must reproduce the above
10926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer
11926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// in the documentation and/or other materials provided with the
12926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// distribution.
13926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)//         * Neither the name of Google Inc. nor the names of its
14926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// contributors may be used to endorse or promote products derived from
15926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// this software without specific prior written permission.
16926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)//
17926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
29926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
30926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)var history = history || {};
31926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
32926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)(function() {
33926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
34926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)history.DEFAULT_CROSS_DASHBOARD_STATE_VALUES = {
35926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    group: null,
36926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    showAllRuns: false,
37926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    testType: 'layout-tests',
38926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    useTestData: false,
395267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)}
40926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
41926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)history.validateParameter = function(state, key, value, validateFn)
42926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
435267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    if (validateFn()) {
44926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        state[key] = value;
455267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return true;
465267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    } else {
47926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        console.log(key + ' value is not valid: ' + value);
485267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return false;
495267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    }
50926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
51926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
52926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)history.isTreeMap = function()
53926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
54926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return string.endsWith(window.location.pathname, 'treemap.html');
55926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
56926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
57926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// TODO(jparent): Make private once callers move here.
58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)history.queryHashAsMap = function()
59926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
60926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    var hash = window.location.hash;
61926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    var paramsList = hash ? hash.substring(1).split('&') : [];
62926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    var paramsMap = {};
63926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    var invalidKeys = [];
64926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    for (var i = 0; i < paramsList.length; i++) {
65926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        var thisParam = paramsList[i].split('=');
66926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (thisParam.length != 2) {
67926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            console.log('Invalid query parameter: ' + paramsList[i]);
68926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            continue;
69926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
70926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
71926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        paramsMap[thisParam[0]] = decodeURIComponent(thisParam[1]);
72926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
73926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
74926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // FIXME: remove support for mapping from the master parameter to the group
75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // one once the waterfall starts to pass in the builder name instead.
76926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (paramsMap.master) {
775267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        var errors = new ui.Errors();
785267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        if (paramsMap.master == 'TryServer')
795267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            errors.addError('ERROR: You got here from the trybot waterfall. The try bots do not record data in the flakiness dashboard. Showing results for the regular waterfall.');
805267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        else if (!builders.masters[paramsMap.master])
815267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            errors.addError('ERROR: Unknown master name: ' + paramsMap.master);
825267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
835267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        if (errors.hasErrors()) {
845267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            errors.show();
855267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            window.location.hash = window.location.hash.replace('master=' + paramsMap.master, '');
865267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        } else {
87521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            var groupIndex = paramsMap.master == 'ChromiumWebkit' ? 1 : 0;
88521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            paramsMap.group = builders.masters[paramsMap.master].groups[groupIndex];
895267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            window.location.hash = window.location.hash.replace('master=' + paramsMap.master, 'group=' + encodeURIComponent(paramsMap.group));
905267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            delete paramsMap.master;
915267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        }
92926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
93926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
945267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    // FIXME: Find a better way to do this. For layout-tests, we want the default group to be
955267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    // the ToT blink group. For other test types, we want it to be the Deps group.
965267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    if (!paramsMap.group && (!paramsMap.testType || paramsMap.testType == 'layout-tests'))
975267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        paramsMap.group = builders.groupNamesForTestType('layout-tests')[1];
985267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return paramsMap;
100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
101926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)history._diffStates = function(oldState, newState)
103926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
104926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // If there is no old state, everything in the current state is new.
105926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!oldState)
106926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return newState;
107926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
108926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    var changedParams = {};
109926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    for (curKey in newState) {
110926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        var oldVal = oldState[curKey];
111926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        var newVal = newState[curKey];
112926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // Add new keys or changed values.
113926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (!oldVal || oldVal != newVal)
114926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            changedParams[curKey] = newVal;
115926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
116926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return changedParams;
117926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
118926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
119926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)history._fillMissingValues = function(to, from)
120926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
121926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    for (var state in from) {
122926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (!(state in to))
123926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            to[state] = from[state];
124926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
125926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
126926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
12753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)history.History = function(configuration)
128926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
12953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    this.crossDashboardState = {};
13053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    this.dashboardSpecificState = {};
13153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
13253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (configuration) {
13353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        this._defaultDashboardSpecificStateValues = configuration.defaultStateValues;
13453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        this._handleValidHashParameter = configuration.handleValidHashParameter;
13553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        this._handleQueryParameterChange = configuration.handleQueryParameterChange || function(historyInstance, params) { return true; };
13653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        this._dashboardSpecificInvalidatingParameters = configuration.invalidatingHashParameters;
13753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        this._generatePage = configuration.generatePage;
13853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
139926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
140926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1415267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)history.reloadRequiringParameters = ['showAllRuns', 'group', 'testType'];
142926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
14353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)var CROSS_DB_INVALIDATING_PARAMETERS = {
14453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    'testType': 'group'
14553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)};
14653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
147926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)history.History.prototype = {
14853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    initialize: function()
14953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
15053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        window.onhashchange = this._handleLocationChange.bind(this);
15153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        this._handleLocationChange();
15253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    },
153926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    isLayoutTestResults: function()
154926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
155926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return this.crossDashboardState.testType == 'layout-tests';
156926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    },
157926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    isGPUTestResults: function()
158926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
159926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return this.crossDashboardState.testType == 'gpu_tests';
160926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    },
161926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    parseCrossDashboardParameters: function()
162926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
163926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        this.crossDashboardState = {};
164926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        var parameters = history.queryHashAsMap();
165926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        for (parameterName in history.DEFAULT_CROSS_DASHBOARD_STATE_VALUES)
166926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            this.parseParameter(parameters, parameterName);
167926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
168926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        history._fillMissingValues(this.crossDashboardState, history.DEFAULT_CROSS_DASHBOARD_STATE_VALUES);
169926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    },
17053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    _parseDashboardSpecificParameters: function()
17153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
17253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        this.dashboardSpecificState = {};
17353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        var parameters = history.queryHashAsMap();
17453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        for (parameterName in this._defaultDashboardSpecificStateValues)
17553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            this.parseParameter(parameters, parameterName);
17653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    },
177926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // TODO(jparent): Make private once callers move here.
178926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    parseParameters: function()
179926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
180926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        var oldCrossDashboardState = this.crossDashboardState;
181926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        var oldDashboardSpecificState = this.dashboardSpecificState;
182926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
183926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        this.parseCrossDashboardParameters();
1845267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
185926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // Some parameters require loading different JSON files when the value changes. Do a reload.
186926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (Object.keys(oldCrossDashboardState).length) {
187926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            for (var key in this.crossDashboardState) {
1885267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)                if (oldCrossDashboardState[key] != this.crossDashboardState[key] && history.reloadRequiringParameters.indexOf(key) != -1) {
189926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    window.location.reload();
190926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    return false;
191926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                }
192926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            }
193926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
194926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
19553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        this._parseDashboardSpecificParameters();
196926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        var dashboardSpecificDiffState = history._diffStates(oldDashboardSpecificState, this.dashboardSpecificState);
197926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
19853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        history._fillMissingValues(this.dashboardSpecificState, this._defaultDashboardSpecificStateValues);
199926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
200926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // FIXME: dashboard_base shouldn't know anything about specific dashboard specific keys.
201926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (dashboardSpecificDiffState.builder)
202926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            delete this.dashboardSpecificState.tests;
203926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (this.dashboardSpecificState.tests)
204926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            delete this.dashboardSpecificState.builder;
205926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
206926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        var shouldGeneratePage = true;
207926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (Object.keys(dashboardSpecificDiffState).length)
20853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            shouldGeneratePage = this._handleQueryParameterChange(this, dashboardSpecificDiffState);
209926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return shouldGeneratePage;
210926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    },
211926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // TODO(jparent): Make private once callers move here.
212926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    parseParameter: function(parameters, key)
213926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
214926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (!(key in parameters))
215926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            return;
216926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        var value = parameters[key];
217926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (!this._handleValidHashParameterWrapper(key, value))
218926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            console.log("Invalid query parameter: " + key + '=' + value);
219926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    },
220926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // Takes a key and a value and sets the this.dashboardSpecificState[key] = value iff key is
221926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // a valid hash parameter and the value is a valid value for that key. Handles
222926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // cross-dashboard parameters then falls back to calling
223926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // handleValidHashParameter for dashboard-specific parameters.
224926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    //
225926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // @return {boolean} Whether the key what inserted into the this.dashboardSpecificState.
226926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    _handleValidHashParameterWrapper: function(key, value)
227926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
228926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        switch(key) {
229926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        case 'testType':
230926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            history.validateParameter(this.crossDashboardState, key, value,
2315267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)                function() { return builders.testTypes.indexOf(value) != -1; });
232926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            return true;
233926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
234926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        case 'group':
235926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            history.validateParameter(this.crossDashboardState, key, value,
236926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                function() {
2375267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)                    return builders.getAllGroupNames().indexOf(value) != -1;
238926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                });
239926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            return true;
240926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
241926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        case 'useTestData':
242926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        case 'showAllRuns':
243926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            this.crossDashboardState[key] = value == 'true';
244926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            return true;
245926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
246926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        default:
24753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            return this._handleValidHashParameter(this, key, value);
248926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
249926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    },
250926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    queryParameterValue: function(parameter)
251926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
252926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return this.dashboardSpecificState[parameter] || this.crossDashboardState[parameter];
2535267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    },
254926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // Sets the page state. Takes varargs of key, value pairs.
255926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    setQueryParameter: function(var_args)
256926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
257926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        var queryParamsAsState = {};
258926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        for (var i = 0; i < arguments.length; i += 2) {
259926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            var key = arguments[i];
260926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            queryParamsAsState[key] = arguments[i + 1];
261926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
262926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
263926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        this.invalidateQueryParameters(queryParamsAsState);
264926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
265926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        var newState = this._combinedDashboardState();
266926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        for (var key in queryParamsAsState) {
267926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            newState[key] = queryParamsAsState[key];
268926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
269926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
270926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // Note: We use window.location.hash rather that window.location.replace
271926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // because of bugs in Chrome where extra entries were getting created
272926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // when back button was pressed and full page navigation was occuring.
273926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // FIXME: file those bugs.
274926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        window.location.hash = this._permaLinkURLHash(newState);
275926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    },
276926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    toggleQueryParameter: function(param)
277926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
278926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        this.setQueryParameter(param, !this.queryParameterValue(param));
279926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    },
280926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    invalidateQueryParameters: function(queryParamsAsState)
281926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
282926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        for (var key in queryParamsAsState) {
283926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            if (key in CROSS_DB_INVALIDATING_PARAMETERS)
284926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                delete this.crossDashboardState[CROSS_DB_INVALIDATING_PARAMETERS[key]];
28553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            if (this._dashboardSpecificInvalidatingParameters && key in this._dashboardSpecificInvalidatingParameters)
28653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                delete this.dashboardSpecificState[this._dashboardSpecificInvalidatingParameters[key]];
287926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
288926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    },
289926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    _joinParameters: function(stateObject)
290926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
291926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        var state = [];
292926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        for (var key in stateObject) {
293926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            var value = stateObject[key];
29453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            if (value != this._defaultValue(key))
295926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                state.push(key + '=' + encodeURIComponent(value));
296926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
297926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return state.join('&');
2985267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    },
299926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    _permaLinkURLHash: function(opt_state)
300926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
301926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        var state = opt_state || this._combinedDashboardState();
302926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return '#' + this._joinParameters(state);
303926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    },
304926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    _combinedDashboardState: function()
305926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
306926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        var combinedState = Object.create(this.dashboardSpecificState);
307926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        for (var key in this.crossDashboardState)
308926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            combinedState[key] = this.crossDashboardState[key];
3095267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return combinedState;
31053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    },
31153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    _defaultValue: function(key)
31253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
31353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (key in this._defaultDashboardSpecificStateValues)
31453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            return this._defaultDashboardSpecificStateValues[key];
31553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return history.DEFAULT_CROSS_DASHBOARD_STATE_VALUES[key];
31653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    },
31753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    _handleLocationChange: function()
31853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
31953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (this.parseParameters())
32053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            this._generatePage(this);
321926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
32253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
323926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
324926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
3255267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)})();
326