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