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