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. 8 var $ = function(id) { return document.getElementById(id); }; 9 10 var currentTreatment = 0; 11 var 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 */ 18 function 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 */ 44 function 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 68 function setPreferenceValue(key, value) { 69 chrome.send('salsaSetPreferenceValue', [key, parseFloat(value)]); 70 } 71 72 function backupPreferenceValue(key) { 73 chrome.send('salsaBackupPreferenceValue', [key]); 74 } 75 76 function 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 94 function 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 111 function 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 */ 146 document.onkeydown = handleKeyPress; 147 document.addEventListener('DOMContentLoaded', initialize); 148