| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| /** |
| * This variable structure is here to document the structure that the template |
| * expects to correctly populate the page. |
| */ |
| |
| /** |
| * Takes the |experimentsData| input argument which represents data about all |
| * the current experiments and populates the html jstemplate with that data. |
| * with that data. It expects an object structure like the above. |
| * @param {Object} experimentsData Information about all experiments. |
| * See returnFlagsExperiments() for the structure of this object. |
| */ |
| function renderTemplate(experimentsData) { |
| // This is the javascript code that processes the template: |
| jstProcess(new JsEvalContext(experimentsData), |
| $('flagsExperimentTemplate')); |
| |
| // Add handlers to dynamically created HTML elements. |
| var elements = document.getElementsByClassName('experiment-select'); |
| for (var i = 0; i < elements.length; ++i) { |
| elements[i].onchange = function() { |
| handleSelectChoiceExperiment(this, this.selectedIndex); |
| return false; |
| }; |
| } |
| |
| elements = document.getElementsByClassName('experiment-disable-link'); |
| for (var i = 0; i < elements.length; ++i) { |
| elements[i].onclick = function() { |
| handleEnableExperiment(this, false); |
| return false; |
| }; |
| } |
| |
| elements = document.getElementsByClassName('experiment-enable-link'); |
| for (var i = 0; i < elements.length; ++i) { |
| elements[i].onclick = function() { |
| handleEnableExperiment(this, true); |
| return false; |
| }; |
| } |
| |
| elements = document.getElementsByClassName('experiment-restart-button'); |
| for (var i = 0; i < elements.length; ++i) { |
| elements[i].onclick = restartBrowser; |
| } |
| |
| $('experiment-reset-all').onclick = resetAllFlags; |
| |
| highlightReferencedFlag(); |
| } |
| |
| /** |
| * Highlight an element associated with the page's location's hash. We need to |
| * fake fragment navigation with '.scrollIntoView()', since the fragment IDs |
| * don't actually exist until after the template code runs; normal navigation |
| * therefore doesn't work. |
| */ |
| function highlightReferencedFlag() { |
| if (window.location.hash) { |
| var el = document.querySelector(window.location.hash); |
| if (el && !el.classList.contains('referenced')) { |
| // Unhighlight whatever's highlighted. |
| if (document.querySelector('.referenced')) |
| document.querySelector('.referenced').classList.remove('referenced'); |
| // Highlight the referenced element. |
| el.classList.add('referenced'); |
| el.scrollIntoView(); |
| } |
| } |
| } |
| |
| /** |
| * Asks the C++ FlagsDOMHandler to get details about the available experiments |
| * and return detailed data about the configuration. The FlagsDOMHandler |
| * should reply to returnFlagsExperiments() (below). |
| */ |
| function requestFlagsExperimentsData() { |
| chrome.send('requestFlagsExperiments'); |
| } |
| |
| /** |
| * Asks the C++ FlagsDOMHandler to restart the browser (restoring tabs). |
| */ |
| function restartBrowser() { |
| chrome.send('restartBrowser'); |
| } |
| |
| /** |
| * Reset all flags to their default values and refresh the UI. |
| */ |
| function resetAllFlags() { |
| // Asks the C++ FlagsDOMHandler to reset all flags to default values. |
| chrome.send('resetAllFlags'); |
| requestFlagsExperimentsData(); |
| } |
| |
| /** |
| * Called by the WebUI to re-populate the page with data representing the |
| * current state of all experiments. |
| * @param {Object} experimentsData Information about all experiments. |
| * in the following format: |
| * { |
| * supportedExperiments: [ |
| * { |
| * internal_name: 'Experiment ID string', |
| * name: 'Experiment Name', |
| * description: 'description', |
| * // enabled is only set if the experiment is single valued. |
| * enabled: true, |
| * // choices is only set if the experiment has multiple values. |
| * choices: [ |
| * { |
| * internal_name: 'Experiment ID string', |
| * description: 'description', |
| * selected: true |
| * } |
| * ], |
| * supported_platforms: [ |
| * 'Mac', |
| * 'Linux' |
| * ], |
| * } |
| * ], |
| * unsupportedExperiments: [ |
| * // Mirrors the format of |supportedExperiments| above. |
| * ], |
| * needsRestart: false, |
| * showBetaChannelPromotion: false, |
| * showDevChannelPromotion: false |
| * } |
| */ |
| function returnFlagsExperiments(experimentsData) { |
| var bodyContainer = $('body-container'); |
| renderTemplate(experimentsData); |
| |
| if (experimentsData.showBetaChannelPromotion) |
| $('channel-promo-beta').hidden = false; |
| else if (experimentsData.showDevChannelPromotion) |
| $('channel-promo-dev').hidden = false; |
| |
| bodyContainer.style.visibility = 'visible'; |
| } |
| |
| /** |
| * Handles a 'enable' or 'disable' button getting clicked. |
| * @param {HTMLElement} node The node for the experiment being changed. |
| * @param {boolean} enable Whether to enable or disable the experiment. |
| */ |
| function handleEnableExperiment(node, enable) { |
| // Tell the C++ FlagsDOMHandler to enable/disable the experiment. |
| chrome.send('enableFlagsExperiment', [String(node.internal_name), |
| String(enable)]); |
| requestFlagsExperimentsData(); |
| } |
| |
| /** |
| * Invoked when the selection of a multi-value choice is changed to the |
| * specified index. |
| * @param {HTMLElement} node The node for the experiment being changed. |
| * @param {number} index The index of the option that was selected. |
| */ |
| function handleSelectChoiceExperiment(node, index) { |
| // Tell the C++ FlagsDOMHandler to enable the selected choice. |
| chrome.send('enableFlagsExperiment', |
| [String(node.internal_name) + '@' + index, 'true']); |
| requestFlagsExperimentsData(); |
| } |
| |
| // Get data and have it displayed upon loading. |
| document.addEventListener('DOMContentLoaded', requestFlagsExperimentsData); |
| |
| // Update the highlighted flag when the hash changes. |
| window.addEventListener('hashchange', highlightReferencedFlag); |