1// Copyright 2012 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
10/**
11 * WebUI for configuring instant.* preference values used by
12 * Chrome's instant search system.
13 */
14var instantConfig = (function() {
15  'use strict';
16
17  /** List of fields used to dynamically build form. **/
18  var FIELDS = [
19    {
20      key: 'instant_ui.zero_suggest_url_prefix',
21      label: 'Prefix URL for the experimental Instant ZeroSuggest provider',
22      type: 'string',
23      size: 40,
24      units: '',
25      default: ''
26    },
27  ];
28
29  /**
30   * Returns a DOM element of the given type and class name.
31   */
32  function createElementWithClass(elementType, className) {
33    var element = document.createElement(elementType);
34    element.className = className;
35    return element;
36  }
37
38  /**
39   * Dynamically builds web-form based on FIELDS list.
40   * @return {string} The form's HTML.
41   */
42  function buildForm() {
43    var buf = [];
44
45    for (var i = 0; i < FIELDS.length; i++) {
46      var field = FIELDS[i];
47
48      var row = createElementWithClass('div', 'row');
49      row.id = '';
50
51      var label = createElementWithClass('label', 'row-label');
52      label.setAttribute('for', field.key);
53      label.textContent = field.label;
54      row.appendChild(label);
55
56      var input = createElementWithClass('input', 'row-input');
57      input.type = field.type;
58      input.id = field.key;
59      input.title = "Default Value: " + field.default;
60      if (field.size) input.size = field.size;
61      input.min = field.min || 0;
62      if (field.max) input.max = field.max;
63      if (field.step) input.step = field.step;
64      row.appendChild(input);
65
66      var units = createElementWithClass('div', 'row-units');
67      if (field.units) units.innerHTML = field.units;
68      row.appendChild(units);
69
70      $('instant-form').appendChild(row);
71    }
72  }
73
74  /**
75   * Initialize the form by adding 'onChange' listeners to all fields.
76   */
77  function initForm() {
78    for (var i = 0; i < FIELDS.length; i++) {
79      var field = FIELDS[i];
80      $(field.key).onchange = (function(key) {
81        setPreferenceValue(key);
82      }).bind(null, field.key);
83    }
84  }
85
86  /**
87   * Request a preference setting's value.
88   * This method is asynchronous; the result is provided by a call to
89   * getPreferenceValueResult.
90   * @param {string} prefName The name of the preference value being requested.
91   */
92  function getPreferenceValue(prefName) {
93    chrome.send('getPreferenceValue', [prefName]);
94  }
95
96  /**
97   * Handle callback from call to getPreferenceValue.
98   * @param {string} prefName The name of the requested preference value.
99   * @param {value} value The current value associated with prefName.
100   */
101  function getPreferenceValueResult(prefName, value) {
102    if ($(prefName).type == 'checkbox')
103      $(prefName).checked = value;
104    else
105      $(prefName).value = value;
106  }
107
108  /**
109   * Set a preference setting's value stored in the element with prefName.
110   * @param {string} prefName The name of the preference value being set.
111   */
112  function setPreferenceValue(prefName) {
113    var value;
114    if ($(prefName).type == 'checkbox')
115      value = $(prefName).checked;
116    else if ($(prefName).type == 'number')
117      value = parseFloat($(prefName).value);
118    else
119      value = $(prefName).value;
120    chrome.send('setPreferenceValue', [prefName, value]);
121  }
122
123  /**
124   * Saves data back into Chrome preferences.
125   */
126  function onSave() {
127    for (var i = 0; i < FIELDS.length; i++) {
128      var field = FIELDS[i];
129      setPreferenceValue(field.key);
130    }
131    return false;
132  }
133
134  /**
135   * Request debug info.
136   * The method is asynchronous, results being provided via getDebugInfoResult.
137   */
138  function getDebugInfo() {
139    chrome.send('getDebugInfo');
140  }
141
142  /**
143   * Handles callback from getDebugInfo.
144   * @param {Object} info The debug info.
145   */
146  function getDebugInfoResult(info) {
147    for (var i = 0; i < info.entries.length; ++i) {
148      var entry = info.entries[i];
149      var row = createElementWithClass('p', 'debug');
150      row.appendChild(createElementWithClass('span', 'timestamp')).textContent =
151          entry.time;
152      row.appendChild(document.createElement('span')).textContent = entry.text;
153      $('instant-debug-info').appendChild(row);
154    }
155  }
156
157  /**
158   * Resets list of debug events.
159   */
160  function clearDebugInfo() {
161    $('instant-debug-info').innerHTML = '';
162    chrome.send('clearDebugInfo');
163  }
164
165  function loadForm() {
166    for (var i = 0; i < FIELDS.length; i++)
167      getPreferenceValue(FIELDS[i].key);
168  }
169
170  /**
171   * Build and initialize the configuration form.
172   */
173  function initialize() {
174    buildForm();
175    loadForm();
176    initForm();
177    getDebugInfo();
178
179    $('save-button').onclick = onSave.bind(this);
180    $('clear-button').onclick = clearDebugInfo.bind(this);
181  }
182
183  return {
184    initialize: initialize,
185    getDebugInfoResult: getDebugInfoResult,
186    getPreferenceValueResult: getPreferenceValueResult
187  };
188})();
189
190document.addEventListener('DOMContentLoaded', instantConfig.initialize);
191