• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 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
5cr.define('options', function() {
6  /** @const */ var OptionsPage = options.OptionsPage;
7
8  //////////////////////////////////////////////////////////////////////////////
9  // ContentSettings class:
10
11  /**
12   * Encapsulated handling of content settings page.
13   * @constructor
14   */
15  function ContentSettings() {
16    this.activeNavTab = null;
17    OptionsPage.call(this, 'content',
18                     loadTimeData.getString('contentSettingsPageTabTitle'),
19                     'content-settings-page');
20  }
21
22  cr.addSingletonGetter(ContentSettings);
23
24  ContentSettings.prototype = {
25    __proto__: OptionsPage.prototype,
26
27    initializePage: function() {
28      OptionsPage.prototype.initializePage.call(this);
29
30      var exceptionsButtons =
31          this.pageDiv.querySelectorAll('.exceptions-list-button');
32      for (var i = 0; i < exceptionsButtons.length; i++) {
33        exceptionsButtons[i].onclick = function(event) {
34          var page = ContentSettingsExceptionsArea.getInstance();
35
36          // Add on the proper hash for the content type, and store that in the
37          // history so back/forward and tab restore works.
38          var hash = event.currentTarget.getAttribute('contentType');
39          var url = page.name + '#' + hash;
40          uber.pushState({pageName: page.name}, url);
41
42          // Navigate after the local history has been replaced in order to have
43          // the correct hash loaded.
44          OptionsPage.showPageByName('contentExceptions', false);
45        };
46      }
47
48      var manageHandlersButton = $('manage-handlers-button');
49      if (manageHandlersButton) {
50        manageHandlersButton.onclick = function(event) {
51          OptionsPage.navigateToPage('handlers');
52        };
53      }
54
55      if (cr.isChromeOS)
56        UIAccountTweaks.applyGuestModeVisibility(document);
57
58      // Cookies filter page ---------------------------------------------------
59      $('show-cookies-button').onclick = function(event) {
60        chrome.send('coreOptionsUserMetricsAction', ['Options_ShowCookies']);
61        OptionsPage.navigateToPage('cookies');
62      };
63
64      $('content-settings-overlay-confirm').onclick =
65          OptionsPage.closeOverlay.bind(OptionsPage);
66
67      $('media-pepper-flash-default').hidden = true;
68      $('media-pepper-flash-exceptions').hidden = true;
69
70      $('media-select-mic').addEventListener('change',
71          ContentSettings.setDefaultMicrophone_);
72      $('media-select-camera').addEventListener('change',
73          ContentSettings.setDefaultCamera_);
74    },
75  };
76
77  ContentSettings.updateHandlersEnabledRadios = function(enabled) {
78    var selector = '#content-settings-page input[type=radio][value=' +
79        (enabled ? 'allow' : 'block') + '].handler-radio';
80    document.querySelector(selector).checked = true;
81  };
82
83  /**
84   * Sets the values for all the content settings radios.
85   * @param {Object} dict A mapping from radio groups to the checked value for
86   *     that group.
87   */
88  ContentSettings.setContentFilterSettingsValue = function(dict) {
89    for (var group in dict) {
90      var managedBy = dict[group].managedBy;
91      var controlledBy = managedBy == 'policy' || managedBy == 'extension' ?
92          managedBy : null;
93      document.querySelector('input[type=radio][name=' + group + '][value=' +
94                             dict[group].value + ']').checked = true;
95      var radios = document.querySelectorAll('input[type=radio][name=' +
96                                             group + ']');
97      for (var i = 0, len = radios.length; i < len; i++) {
98        radios[i].disabled = (managedBy != 'default');
99        radios[i].controlledBy = controlledBy;
100      }
101      var indicators = document.querySelectorAll(
102          'span.controlled-setting-indicator[content-setting=' + group + ']');
103      if (indicators.length == 0)
104        continue;
105      // Create a synthetic pref change event decorated as
106      // CoreOptionsHandler::CreateValueForPref() does.
107      var event = new Event(group);
108      event.value = {
109        value: dict[group].value,
110        controlledBy: controlledBy,
111      };
112      for (var i = 0; i < indicators.length; i++) {
113        indicators[i].handlePrefChange(event);
114      }
115    }
116  };
117
118  /**
119   * Updates the labels and indicators for the Media settings. Those require
120   * special handling because they are backed by multiple prefs and can change
121   * their scope based on the managed state of the backing prefs.
122   * @param {Object} mediaSettings A dictionary containing the following fields:
123   *     {String} askText The label for the ask radio button.
124   *     {String} blockText The label for the block radio button.
125   *     {Boolean} cameraDisabled Whether to disable the camera dropdown.
126   *     {Boolean} micDisabled Whether to disable the microphone dropdown.
127   *     {Boolean} showBubble Wether to show the managed icon and bubble for the
128   *         media label.
129   *     {String} bubbleText The text to use inside the bubble if it is shown.
130   */
131  ContentSettings.updateMediaUI = function(mediaSettings) {
132    $('media-stream-ask-label').innerHTML =
133        loadTimeData.getString(mediaSettings.askText);
134    $('media-stream-block-label').innerHTML =
135        loadTimeData.getString(mediaSettings.blockText);
136
137    if (mediaSettings.micDisabled)
138      $('media-select-mic').disabled = true;
139    if (mediaSettings.cameraDisabled)
140      $('media-select-camera').disabled = true;
141
142    OptionsPage.hideBubble();
143    // Create a synthetic pref change event decorated as
144    // CoreOptionsHandler::CreateValueForPref() does.
145    // TODO(arv): It was not clear what event type this should use?
146    var event = new Event('undefined');
147    event.value = {};
148
149    if (mediaSettings.showBubble) {
150      event.value = { controlledBy: 'policy' };
151      $('media-indicator').setAttribute(
152          'textpolicy', loadTimeData.getString(mediaSettings.bubbleText));
153      $('media-indicator').location = cr.ui.ArrowLocation.TOP_START;
154    }
155
156    $('media-indicator').handlePrefChange(event);
157  };
158
159  /**
160   * Initializes an exceptions list.
161   * @param {string} type The content type that we are setting exceptions for.
162   * @param {Array} exceptions An array of pairs, where the first element of
163   *     each pair is the filter string, and the second is the setting
164   *     (allow/block).
165   */
166  ContentSettings.setExceptions = function(type, exceptions) {
167    this.getExceptionsList(type, 'normal').setExceptions(exceptions);
168  };
169
170  ContentSettings.setHandlers = function(handlers) {
171    $('handlers-list').setHandlers(handlers);
172  };
173
174  ContentSettings.setIgnoredHandlers = function(ignoredHandlers) {
175    $('ignored-handlers-list').setHandlers(ignoredHandlers);
176  };
177
178  ContentSettings.setOTRExceptions = function(type, otrExceptions) {
179    var exceptionsList = this.getExceptionsList(type, 'otr');
180    exceptionsList.parentNode.hidden = false;
181    exceptionsList.setExceptions(otrExceptions);
182  };
183
184  /**
185   * @param {string} type The type of exceptions (e.g. "location") to get.
186   * @param {string} mode The mode of the desired exceptions list (e.g. otr).
187   * @return {?ExceptionsList} The corresponding exceptions list or null.
188   */
189  ContentSettings.getExceptionsList = function(type, mode) {
190    return document.querySelector(
191        'div[contentType=' + type + '] list[mode=' + mode + ']');
192  };
193
194  /**
195   * The browser's response to a request to check the validity of a given URL
196   * pattern.
197   * @param {string} type The content type.
198   * @param {string} mode The browser mode.
199   * @param {string} pattern The pattern.
200   * @param {bool} valid Whether said pattern is valid in the context of
201   *     a content exception setting.
202   */
203  ContentSettings.patternValidityCheckComplete =
204      function(type, mode, pattern, valid) {
205    this.getExceptionsList(type, mode).patternValidityCheckComplete(pattern,
206                                                                    valid);
207  };
208
209  /**
210   * Shows/hides the link to the Pepper Flash camera and microphone default
211   * settings.
212   * Please note that whether the link is actually showed or not is also
213   * affected by the style class pepper-flash-settings.
214   */
215  ContentSettings.showMediaPepperFlashDefaultLink = function(show) {
216    $('media-pepper-flash-default').hidden = !show;
217  };
218
219  /**
220   * Shows/hides the link to the Pepper Flash camera and microphone
221   * site-specific settings.
222   * Please note that whether the link is actually showed or not is also
223   * affected by the style class pepper-flash-settings.
224   */
225  ContentSettings.showMediaPepperFlashExceptionsLink = function(show) {
226    $('media-pepper-flash-exceptions').hidden = !show;
227  };
228
229  /**
230   * Shows/hides the whole Web MIDI settings.
231   * @param {bool} show Wether to show the whole Web MIDI settings.
232   */
233  ContentSettings.showExperimentalWebMIDISettings = function(show) {
234    $('experimental-web-midi-settings').hidden = !show;
235  };
236
237  /**
238   * Updates the microphone/camera devices menu with the given entries.
239   * @param {string} type The device type.
240   * @param {Array} devices List of available devices.
241   * @param {string} defaultdevice The unique id of the current default device.
242   */
243  ContentSettings.updateDevicesMenu = function(type, devices, defaultdevice) {
244    var deviceSelect = '';
245    if (type == 'mic') {
246      deviceSelect = $('media-select-mic');
247    } else if (type == 'camera') {
248      deviceSelect = $('media-select-camera');
249    } else {
250      console.error('Unknown device type for <device select> UI element: ' +
251                    type);
252      return;
253    }
254
255    deviceSelect.textContent = '';
256
257    var deviceCount = devices.length;
258    var defaultIndex = -1;
259    for (var i = 0; i < deviceCount; i++) {
260      var device = devices[i];
261      var option = new Option(device.name, device.id);
262      if (option.value == defaultdevice)
263        defaultIndex = i;
264      deviceSelect.appendChild(option);
265    }
266    if (defaultIndex >= 0)
267      deviceSelect.selectedIndex = defaultIndex;
268  };
269
270  /**
271   * Enables/disables the protected content exceptions button.
272   * @param {bool} enable Whether to enable the button.
273   */
274  ContentSettings.enableProtectedContentExceptions = function(enable) {
275    var exceptionsButton = $('protected-content-exceptions');
276    if (exceptionsButton)
277      exceptionsButton.disabled = !enable;
278  };
279
280  /**
281   * Set the default microphone device based on the popup selection.
282   * @private
283   */
284  ContentSettings.setDefaultMicrophone_ = function() {
285    var deviceSelect = $('media-select-mic');
286    chrome.send('setDefaultCaptureDevice', ['mic', deviceSelect.value]);
287  };
288
289  /**
290   * Set the default camera device based on the popup selection.
291   * @private
292   */
293  ContentSettings.setDefaultCamera_ = function() {
294    var deviceSelect = $('media-select-camera');
295    chrome.send('setDefaultCaptureDevice', ['camera', deviceSelect.value]);
296  };
297
298  // Export
299  return {
300    ContentSettings: ContentSettings
301  };
302
303});
304