1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Redefine '$' here rather than including 'cr.js', since this is
6// the only function needed.  This allows this file to be loaded
7// in a browser directly for layout and some testing purposes.
8var $ = function(id) { return document.getElementById(id); };
9
10var currentTreatment = 0;
11var treatments = [];
12
13/**
14 * Take a string of hex like '74657374' and return the ascii version 'test'.
15 * @param {string} str The string of hex characters to convert to ascii
16 * @return {string} The ASCII values of those hex encoded characters
17 */
18function hexToChars(str) {
19  var decoded = '';
20  if (str.length % 2 == 0) {
21    for (var pos = str.length; pos > 0; pos = pos - 2) {
22      var c = String.fromCharCode(parseInt(str.substring(pos - 2, pos), 16));
23      decoded = c + decoded;
24    }
25  }
26  return decoded;
27}
28
29/**
30 * Extract the experiment information out of the encoded URL string.
31 * The format is as follows:
32 * chrome://salsa/#HEX_ENCODED_EXPERIMENT
33 * Experiments are encoded as:
34 *    treatment1+treatment2+...+treatmentn
35 * Each treatment is of the form:
36 *    preference1,preference2,...,preferencen
37 * Each preference is of the form:
38 *    name:value
39 * This function returns an object storing all the parsed data.
40 * @param {string} url The URL to parse the experiment from
41 * @return {list} a list of objects, each representing a single treatment
42 *     and consisting of a set of preference name -> value pairs
43 */
44function parseURL(url) {
45  var match = url.match('#([0-9ABCDEFabcdef]*)');
46  var experimentString = match ? match[1] : '';
47  experimentString = hexToChars(experimentString);
48
49  var treatmentsFound = [];
50  if (experimentString == '')
51    return treatmentsFound;
52
53  var treatmentStrings = experimentString.split('+');
54  for (var i = 0; i < treatmentStrings.length; i++) {
55    var prefStrings = treatmentStrings[i].split(',');
56    treatment = [];
57    for (var j = 0; j < prefStrings.length; j++) {
58      var key = prefStrings[j].split(':')[0];
59      var value = prefStrings[j].split(':')[1];
60      treatment.push({'key': key, 'value': value});
61    }
62    treatmentsFound.push(treatment);
63  }
64
65  return treatmentsFound;
66}
67
68function setPreferenceValue(key, value) {
69  chrome.send('salsaSetPreferenceValue', [key, parseFloat(value)]);
70}
71
72function backupPreferenceValue(key) {
73  chrome.send('salsaBackupPreferenceValue', [key]);
74}
75
76function handleKeyPress(e) {
77  e = e || window.event;
78  var selectedTreatment = currentTreatment;
79
80  if (e.keyCode == '37' || e.keyCode == '38') {
81    selectedTreatment = currentTreatment - 1;
82    if (selectedTreatment < 0)
83      selectedTreatment = 0;
84  } else if (e.keyCode == '39' || e.keyCode == '40') {
85    selectedTreatment = currentTreatment + 1;
86    if (selectedTreatment >= treatments.length)
87      selectedTreatment = treatments.length - 1;
88  }
89
90  if (selectedTreatment != currentTreatment)
91    applyTreatment(selectedTreatment);
92}
93
94function applyTreatment(treatment_number) {
95  if (treatment_number < 0)
96    treatment_number = 0;
97  if (treatment_number >= treatments.length)
98    treatment_number = treatments.length;
99
100  $('treatment' + currentTreatment).className = 'treatment';
101  currentTreatment = treatment_number;
102  $('treatment' + currentTreatment).className = 'selected treatment';
103
104  for (var i = 0; i < treatments[treatment_number].length; i++) {
105    var key = treatments[treatment_number][i].key;
106    var value = treatments[treatment_number][i].value;
107    setPreferenceValue(key, value);
108  }
109}
110
111function initialize() {
112  // Parse the experiment string in the URL.
113  treatments = parseURL(document.URL);
114
115  // Update the available treatments list.
116  for (var i = 0; i < treatments.length; i++) {
117    var newTreatment = $('treatment-template').cloneNode(true);
118    newTreatment.id = 'treatment' + i.toString();
119    newTreatment.removeAttribute('hidden');
120    newTreatment.onclick = function() {
121      applyTreatment(parseInt(this.textContent));
122    };
123    newTreatment.textContent = i.toString();
124    $('treatment-list').appendChild(newTreatment);
125  }
126
127  if (treatments.length > 0) {
128    // Store a copy of the settings right now so you can reset them afterwards.
129    for (var i = 0; i < treatments[0].length; i++)
130      backupPreferenceValue(treatments[0][i].key);
131
132    // Select Treatment 0 to start
133    applyTreatment(0);
134  } else {
135    // Make the error message visible and hide everything else
136    $('invalid_treatment_info').removeAttribute('hidden');
137    var div = $('valid_treatment_info');
138    div.parentNode.removeChild(div);
139  }
140}
141
142/**
143 * A key handler so the user can use the arrow keys to select their treatments.
144 * This should fire any time they press a key
145 */
146document.onkeydown = handleKeyPress;
147document.addEventListener('DOMContentLoaded', initialize);
148