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