| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 cr.define('options.contentSettings', function() { | 5 // TODO(sergiu): Write a base class such that both this and the content |
| 6 // settings exceptions inherit from it (http://crbug.com/227520). |
| 7 cr.define('options.managedUserSettings', function() { |
| 6 /** @const */ var ControlledSettingIndicator = | 8 /** @const */ var ControlledSettingIndicator = |
| 7 options.ControlledSettingIndicator; | 9 options.ControlledSettingIndicator; |
| 8 /** @const */ var InlineEditableItemList = options.InlineEditableItemList; | 10 /** @const */ var InlineEditableItemList = options.InlineEditableItemList; |
| 9 /** @const */ var InlineEditableItem = options.InlineEditableItem; | 11 /** @const */ var InlineEditableItem = options.InlineEditableItem; |
| 10 /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; | 12 /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; |
| 11 | 13 |
| 12 /** | 14 /** |
| 13 * Creates a new exceptions list item. | 15 * Creates a new exceptions list item. |
| 14 * | 16 * |
| 15 * @param {string} contentType The type of the list. | |
| 16 * @param {string} mode The browser mode, 'otr' or 'normal'. | |
| 17 * @param {boolean} enableAskOption Whether to show an 'ask every time' | |
| 18 * option in the select. | |
| 19 * @param {Object} exception A dictionary that contains the data of the | 17 * @param {Object} exception A dictionary that contains the data of the |
| 20 * exception. | 18 * exception. |
| 21 * @constructor | 19 * @constructor |
| 22 * @extends {options.InlineEditableItem} | 20 * @extends {options.InlineEditableItem} |
| 23 */ | 21 */ |
| 24 function ExceptionsListItem(contentType, mode, enableAskOption, exception) { | 22 function ExceptionsListItem(exception) { |
| 25 var el = cr.doc.createElement('div'); | 23 var el = cr.doc.createElement('div'); |
| 26 el.mode = mode; | 24 el.contentType = 'manual-exceptions'; |
| 27 el.contentType = contentType; | |
| 28 el.enableAskOption = enableAskOption; | |
| 29 el.dataItem = exception; | 25 el.dataItem = exception; |
| 30 el.__proto__ = ExceptionsListItem.prototype; | 26 el.__proto__ = ExceptionsListItem.prototype; |
| 31 el.decorate(); | 27 el.decorate(); |
| 32 | 28 |
| 33 return el; | 29 return el; |
| 34 } | 30 } |
| 35 | 31 |
| 36 ExceptionsListItem.prototype = { | 32 ExceptionsListItem.prototype = { |
| 37 __proto__: InlineEditableItem.prototype, | 33 __proto__: InlineEditableItem.prototype, |
| 38 | 34 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 63 this.contentElement.appendChild(settingLabel); | 59 this.contentElement.appendChild(settingLabel); |
| 64 this.settingLabel = settingLabel; | 60 this.settingLabel = settingLabel; |
| 65 } | 61 } |
| 66 | 62 |
| 67 // Setting select element for edit mode. | 63 // Setting select element for edit mode. |
| 68 var select = cr.doc.createElement('select'); | 64 var select = cr.doc.createElement('select'); |
| 69 var optionAllow = cr.doc.createElement('option'); | 65 var optionAllow = cr.doc.createElement('option'); |
| 70 optionAllow.textContent = loadTimeData.getString('allowException'); | 66 optionAllow.textContent = loadTimeData.getString('allowException'); |
| 71 optionAllow.value = 'allow'; | 67 optionAllow.value = 'allow'; |
| 72 select.appendChild(optionAllow); | 68 select.appendChild(optionAllow); |
| 73 | 69 var optionBlock = cr.doc.createElement('option'); |
| 74 if (this.enableAskOption) { | 70 optionBlock.textContent = loadTimeData.getString('blockException'); |
| 75 var optionAsk = cr.doc.createElement('option'); | 71 optionBlock.value = 'block'; |
| 76 optionAsk.textContent = loadTimeData.getString('askException'); | 72 select.appendChild(optionBlock); |
| 77 optionAsk.value = 'ask'; | |
| 78 select.appendChild(optionAsk); | |
| 79 } | |
| 80 | |
| 81 if (this.contentType == 'cookies') { | |
| 82 var optionSession = cr.doc.createElement('option'); | |
| 83 optionSession.textContent = loadTimeData.getString('sessionException'); | |
| 84 optionSession.value = 'session'; | |
| 85 select.appendChild(optionSession); | |
| 86 } | |
| 87 | |
| 88 if (this.contentType != 'fullscreen') { | |
| 89 var optionBlock = cr.doc.createElement('option'); | |
| 90 optionBlock.textContent = loadTimeData.getString('blockException'); | |
| 91 optionBlock.value = 'block'; | |
| 92 select.appendChild(optionBlock); | |
| 93 } | |
| 94 | |
| 95 if (this.isEmbeddingRule()) { | |
| 96 this.patternLabel.classList.add('sublabel'); | |
| 97 this.editable = false; | |
| 98 } | |
| 99 | |
| 100 if (this.setting == 'default') { | |
| 101 // Items that don't have their own settings (parents of 'embedded on' | |
| 102 // items) aren't deletable. | |
| 103 this.deletable = false; | |
| 104 this.editable = false; | |
| 105 } | |
| 106 | 73 |
| 107 this.contentElement.appendChild(select); | 74 this.contentElement.appendChild(select); |
| 108 select.className = 'exception-setting'; | 75 select.className = 'exception-setting'; |
| 109 if (this.pattern) | 76 if (this.pattern) |
| 110 select.setAttribute('displaymode', 'edit'); | 77 select.setAttribute('displaymode', 'edit'); |
| 111 | 78 |
| 112 if (this.contentType == 'media-stream') { | |
| 113 this.settingLabel.classList.add('media-audio-setting'); | |
| 114 | |
| 115 var videoSettingLabel = cr.doc.createElement('span'); | |
| 116 videoSettingLabel.textContent = this.videoSettingForDisplay(); | |
| 117 videoSettingLabel.className = 'exception-setting'; | |
| 118 videoSettingLabel.classList.add('media-video-setting'); | |
| 119 videoSettingLabel.setAttribute('displaymode', 'static'); | |
| 120 this.contentElement.appendChild(videoSettingLabel); | |
| 121 } | |
| 122 | |
| 123 // Used to track whether the URL pattern in the input is valid. | 79 // Used to track whether the URL pattern in the input is valid. |
| 124 // This will be true if the browser process has informed us that the | 80 // This will be true if the browser process has informed us that the |
| 125 // current text in the input is valid. Changing the text resets this to | 81 // current text in the input is valid. Changing the text resets this to |
| 126 // false, and getting a response from the browser sets it back to true. | 82 // false, and getting a response from the browser sets it back to true. |
| 127 // It starts off as false for empty string (new exceptions) or true for | 83 // It starts off as false for empty string (new exceptions) or true for |
| 128 // already-existing exceptions (which we assume are valid). | 84 // already-existing exceptions (which we assume are valid). |
| 129 this.inputValidityKnown = this.pattern; | 85 this.inputValidityKnown = this.pattern; |
| 130 // This one tracks the actual validity of the pattern in the input. This | 86 // This one tracks the actual validity of the pattern in the input. This |
| 131 // starts off as true so as not to annoy the user when he adds a new and | 87 // starts off as true so as not to annoy the user when he adds a new and |
| 132 // empty input. | 88 // empty input. |
| 133 this.inputIsValid = true; | 89 this.inputIsValid = true; |
| 134 | 90 |
| 135 this.input = input; | 91 this.input = input; |
| 136 this.select = select; | 92 this.select = select; |
| 137 | 93 |
| 138 this.updateEditables(); | 94 this.updateEditables(); |
| 139 | 95 |
| 140 // Editing notifications, geolocation and media-stream is disabled for | |
| 141 // now. | |
| 142 if (this.contentType == 'notifications' || | |
| 143 this.contentType == 'location' || | |
| 144 this.contentType == 'media-stream') { | |
| 145 this.editable = false; | |
| 146 } | |
| 147 | |
| 148 // If the source of the content setting exception is not a user | |
| 149 // preference, that source controls the exception and the user cannot edit | |
| 150 // or delete it. | |
| 151 var controlledBy = | |
| 152 this.dataItem.source && this.dataItem.source != 'preference' ? | |
| 153 this.dataItem.source : null; | |
| 154 | |
| 155 if (controlledBy) { | |
| 156 this.setAttribute('controlled-by', controlledBy); | |
| 157 this.deletable = false; | |
| 158 this.editable = false; | |
| 159 } | |
| 160 | |
| 161 if (controlledBy == 'policy' || controlledBy == 'extension') { | |
| 162 this.querySelector('.row-delete-button').hidden = true; | |
| 163 var indicator = ControlledSettingIndicator(); | |
| 164 indicator.setAttribute('content-exception', this.contentType); | |
| 165 // Create a synthetic pref change event decorated as | |
| 166 // CoreOptionsHandler::CreateValueForPref() does. | |
| 167 var event = new cr.Event(this.contentType); | |
| 168 event.value = { controlledBy: controlledBy }; | |
| 169 indicator.handlePrefChange(event); | |
| 170 this.appendChild(indicator); | |
| 171 } | |
| 172 | |
| 173 // If the exception comes from a hosted app, display the name and the | |
| 174 // icon of the app. | |
| 175 if (controlledBy == 'HostedApp') { | |
| 176 this.title = | |
| 177 loadTimeData.getString('set_by') + ' ' + this.dataItem.appName; | |
| 178 var button = this.querySelector('.row-delete-button'); | |
| 179 // Use the host app's favicon (16px, match bigger size). | |
| 180 // See c/b/ui/webui/extensions/extension_icon_source.h | |
| 181 // for a description of the chrome://extension-icon URL. | |
| 182 button.style.backgroundImage = | |
| 183 'url(\'chrome://extension-icon/' + this.dataItem.appId + '/16/1\')'; | |
| 184 } | |
| 185 | |
| 186 var listItem = this; | 96 var listItem = this; |
| 187 // Handle events on the editable nodes. | 97 // Handle events on the editable nodes. |
| 188 input.oninput = function(event) { | 98 input.oninput = function(event) { |
| 189 listItem.inputValidityKnown = false; | 99 listItem.inputValidityKnown = false; |
| 190 chrome.send('checkExceptionPatternValidity', | 100 chrome.send('checkManualExceptionValidity', |
| 191 [listItem.contentType, listItem.mode, input.value]); | 101 [input.value]); |
| 192 }; | 102 }; |
| 193 | 103 |
| 194 // Listen for edit events. | 104 // Listen for edit events. |
| 195 this.addEventListener('canceledit', this.onEditCancelled_); | 105 this.addEventListener('canceledit', this.onEditCancelled_); |
| 196 this.addEventListener('commitedit', this.onEditCommitted_); | 106 this.addEventListener('commitedit', this.onEditCommitted_); |
| 197 }, | 107 }, |
| 198 | 108 |
| 199 isEmbeddingRule: function() { | |
| 200 return this.dataItem.embeddingOrigin && | |
| 201 this.dataItem.embeddingOrigin !== this.dataItem.origin; | |
| 202 }, | |
| 203 | |
| 204 /** | 109 /** |
| 205 * The pattern (e.g., a URL) for the exception. | 110 * The pattern (e.g., a URL) for the exception. |
| 206 * | 111 * |
| 207 * @type {string} | 112 * @type {string} |
| 208 */ | 113 */ |
| 209 get pattern() { | 114 get pattern() { |
| 210 if (!this.isEmbeddingRule()) { | 115 return this.dataItem.pattern; |
| 211 return this.dataItem.origin; | |
| 212 } else { | |
| 213 return loadTimeData.getStringF('embeddedOnHost', | |
| 214 this.dataItem.embeddingOrigin); | |
| 215 } | |
| 216 | |
| 217 return this.dataItem.displayPattern; | |
| 218 }, | 116 }, |
| 219 set pattern(pattern) { | 117 set pattern(pattern) { |
| 220 if (!this.editable) | 118 if (!this.editable) |
| 221 console.error('Tried to change uneditable pattern'); | 119 console.error('Tried to change uneditable pattern'); |
| 222 | 120 |
| 223 this.dataItem.displayPattern = pattern; | 121 this.dataItem.pattern = pattern; |
| 224 }, | 122 }, |
| 225 | 123 |
| 226 /** | 124 /** |
| 227 * The setting (allow/block) for the exception. | 125 * The setting (allow/block) for the exception. |
| 228 * | 126 * |
| 229 * @type {string} | 127 * @type {string} |
| 230 */ | 128 */ |
| 231 get setting() { | 129 get setting() { |
| 232 return this.dataItem.setting; | 130 return this.dataItem.setting; |
| 233 }, | 131 }, |
| 234 set setting(setting) { | 132 set setting(setting) { |
| 235 this.dataItem.setting = setting; | 133 this.dataItem.setting = setting; |
| 236 }, | 134 }, |
| 237 | 135 |
| 238 /** | 136 /** |
| 239 * Gets a human-readable setting string. | 137 * Gets a human-readable setting string. |
| 240 * | 138 * |
| 241 * @return {string} The display string. | 139 * @return {string} The display string. |
| 242 */ | 140 */ |
| 243 settingForDisplay: function() { | 141 settingForDisplay: function() { |
| 244 return this.getDisplayStringForSetting(this.setting); | 142 return this.getDisplayStringForSetting(this.setting); |
| 245 }, | 143 }, |
| 246 | 144 |
| 247 /** | 145 /** |
| 248 * media video specific function. | |
| 249 * Gets a human-readable video setting string. | |
| 250 * | |
| 251 * @return {string} The display string. | |
| 252 */ | |
| 253 videoSettingForDisplay: function() { | |
| 254 return this.getDisplayStringForSetting(this.dataItem.video); | |
| 255 }, | |
| 256 | |
| 257 /** | |
| 258 * Gets a human-readable display string for setting. | 146 * Gets a human-readable display string for setting. |
| 259 * | 147 * |
| 260 * @param {string} setting The setting to be displayed. | 148 * @param {string} setting The setting to be displayed. |
| 261 * @return {string} The display string. | 149 * @return {string} The display string. |
| 262 */ | 150 */ |
| 263 getDisplayStringForSetting: function(setting) { | 151 getDisplayStringForSetting: function(setting) { |
| 264 if (setting == 'allow') | 152 if (setting == 'allow') |
| 265 return loadTimeData.getString('allowException'); | 153 return loadTimeData.getString('allowException'); |
| 266 else if (setting == 'block') | 154 else if (setting == 'block') |
| 267 return loadTimeData.getString('blockException'); | 155 return loadTimeData.getString('blockException'); |
| 268 else if (setting == 'ask') | |
| 269 return loadTimeData.getString('askException'); | |
| 270 else if (setting == 'session') | |
| 271 return loadTimeData.getString('sessionException'); | |
| 272 else if (setting == 'default') | |
| 273 return ''; | |
| 274 | 156 |
| 275 console.error('Unknown setting: [' + setting + ']'); | 157 console.error('Unknown setting: [' + setting + ']'); |
| 276 return ''; | 158 return ''; |
| 277 }, | 159 }, |
| 278 | 160 |
| 279 /** | 161 /** |
| 280 * Update this list item to reflect whether the input is a valid pattern. | 162 * Update this list item to reflect whether the input is a valid pattern. |
| 281 * | 163 * |
| 282 * @param {boolean} valid Whether said pattern is valid in the context of a | 164 * @param {boolean} valid Whether said pattern is valid in the context of a |
| 283 * content exception setting. | 165 * content exception setting. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 this.setPatternValid(true); | 229 this.setPatternValid(true); |
| 348 }, | 230 }, |
| 349 | 231 |
| 350 /** | 232 /** |
| 351 * Editing is complete; update the model. | 233 * Editing is complete; update the model. |
| 352 * | 234 * |
| 353 * @param {string} newPattern The pattern that the user entered. | 235 * @param {string} newPattern The pattern that the user entered. |
| 354 * @param {string} newSetting The setting the user chose. | 236 * @param {string} newSetting The setting the user chose. |
| 355 */ | 237 */ |
| 356 finishEdit: function(newPattern, newSetting) { | 238 finishEdit: function(newPattern, newSetting) { |
| 239 this.setting = newSetting; |
| 357 this.patternLabel.textContent = newPattern; | 240 this.patternLabel.textContent = newPattern; |
| 358 this.settingLabel.textContent = this.settingForDisplay(); | 241 this.settingLabel.textContent = this.settingForDisplay(); |
| 359 var oldPattern = this.pattern; | 242 var oldPattern = this.pattern; |
| 360 this.pattern = newPattern; | 243 this.pattern = newPattern; |
| 361 this.setting = newSetting; | 244 var needsUpdate = false; |
| 362 | 245 |
| 363 // TODO(estade): this will need to be updated if geolocation/notifications | |
| 364 // become editable. | |
| 365 if (oldPattern != newPattern) { | 246 if (oldPattern != newPattern) { |
| 366 chrome.send('removeException', | 247 needsUpdate = true; |
| 367 [this.contentType, this.mode, oldPattern]); | 248 chrome.send('removeManualException', [oldPattern]); |
| 368 } | 249 } |
| 369 | 250 |
| 370 chrome.send('setException', | 251 // If only the setting is changed for this pattern and not the pattern |
| 371 [this.contentType, this.mode, newPattern, newSetting]); | 252 // itself then the interface is already updated so we don't need to |
| 253 // trigger it then processing is completed. |
| 254 chrome.send('setManualException', [newPattern, newSetting, needsUpdate]); |
| 372 } | 255 } |
| 373 }; | 256 }; |
| 374 | 257 |
| 375 /** | 258 /** |
| 376 * Creates a new list item for the Add New Item row, which doesn't represent | 259 * Creates a new list item for the Add New Item row, which doesn't represent |
| 377 * an actual entry in the exceptions list but allows the user to add new | 260 * an actual entry in the exceptions list but allows the user to add new |
| 378 * exceptions. | 261 * exceptions. |
| 379 * | 262 * |
| 380 * @param {string} contentType The type of the list. | |
| 381 * @param {string} mode The browser mode, 'otr' or 'normal'. | |
| 382 * @param {boolean} enableAskOption Whether to show an 'ask every time' option | |
| 383 * in the select. | |
| 384 * @constructor | 263 * @constructor |
| 385 * @extends {cr.ui.ExceptionsListItem} | 264 * @extends {cr.ui.ExceptionsListItem} |
| 386 */ | 265 */ |
| 387 function ExceptionsAddRowListItem(contentType, mode, enableAskOption) { | 266 function ExceptionsAddRowListItem() { |
| 388 var el = cr.doc.createElement('div'); | 267 var el = cr.doc.createElement('div'); |
| 389 el.mode = mode; | |
| 390 el.contentType = contentType; | |
| 391 el.enableAskOption = enableAskOption; | |
| 392 el.dataItem = []; | 268 el.dataItem = []; |
| 393 el.__proto__ = ExceptionsAddRowListItem.prototype; | 269 el.__proto__ = ExceptionsAddRowListItem.prototype; |
| 394 el.decorate(); | 270 el.decorate(); |
| 395 | 271 |
| 396 return el; | 272 return el; |
| 397 } | 273 } |
| 398 | 274 |
| 399 ExceptionsAddRowListItem.prototype = { | 275 ExceptionsAddRowListItem.prototype = { |
| 400 __proto__: ExceptionsListItem.prototype, | 276 __proto__: ExceptionsListItem.prototype, |
| 401 | 277 |
| 402 decorate: function() { | 278 decorate: function() { |
| 403 ExceptionsListItem.prototype.decorate.call(this); | 279 ExceptionsListItem.prototype.decorate.call(this); |
| 404 | 280 |
| 405 this.input.placeholder = | 281 this.input.placeholder = |
| 406 loadTimeData.getString('addNewExceptionInstructions'); | 282 loadTimeData.getString('addNewExceptionInstructions'); |
| 407 | 283 |
| 408 // Do we always want a default of allow? | 284 // Set 'Allow' as default for new entries. |
| 409 this.setting = 'allow'; | 285 this.setting = 'allow'; |
| 410 }, | 286 }, |
| 411 | 287 |
| 412 /** | 288 /** |
| 413 * Clear the <input> and let the placeholder text show again. | 289 * Clear the <input> and let the placeholder text show again. |
| 414 */ | 290 */ |
| 415 resetInput: function() { | 291 resetInput: function() { |
| 416 this.input.value = ''; | 292 this.input.value = ''; |
| 417 }, | 293 }, |
| 418 | 294 |
| 419 /** @override */ | 295 /** @override */ |
| 420 get hasBeenEdited() { | 296 get hasBeenEdited() { |
| 421 return this.input.value != ''; | 297 return this.input.value != ''; |
| 422 }, | 298 }, |
| 423 | 299 |
| 424 /** | 300 /** |
| 425 * Editing is complete; update the model. As long as the pattern isn't | 301 * Editing is complete; update the model. As long as the pattern isn't |
| 426 * empty, we'll just add it. | 302 * empty, we'll just add it. |
| 427 * | 303 * |
| 428 * @param {string} newPattern The pattern that the user entered. | 304 * @param {string} newPattern The pattern that the user entered. |
| 429 * @param {string} newSetting The setting the user chose. | 305 * @param {string} newSetting The setting the user chose. |
| 430 */ | 306 */ |
| 431 finishEdit: function(newPattern, newSetting) { | 307 finishEdit: function(newPattern, newSetting) { |
| 432 this.resetInput(); | 308 this.resetInput(); |
| 433 chrome.send('setException', | 309 // We're adding a new entry, update the model once that is done. |
| 434 [this.contentType, this.mode, newPattern, newSetting]); | 310 chrome.send('setManualException', [newPattern, newSetting, true]); |
| 435 }, | 311 }, |
| 436 }; | 312 }; |
| 437 | 313 |
| 438 /** | 314 /** |
| 315 * Compares two elements in the list. Removes the schema if present and then |
| 316 * compares the two strings. |
| 317 * @param {string} a First element to compare. |
| 318 * @param {string} b Second element to compare. |
| 319 * @return {int} Result of comparison between a and b. |
| 320 */ |
| 321 function comparePatterns(a, b) { |
| 322 // Remove the schema (part before ://) if any. |
| 323 var stripString = function(str) { |
| 324 var indexStr = str.indexOf('://'); |
| 325 if (indexStr != -1) |
| 326 return str.slice(indexStr + 3); |
| 327 return str; |
| 328 }; |
| 329 if (a) |
| 330 a = stripString(a['pattern']); |
| 331 if (b) |
| 332 b = stripString(b['pattern']); |
| 333 return this.dataModel.defaultValuesCompareFunction(a, b); |
| 334 } |
| 335 |
| 336 /** |
| 439 * Creates a new exceptions list. | 337 * Creates a new exceptions list. |
| 440 * | 338 * |
| 441 * @constructor | 339 * @constructor |
| 442 * @extends {cr.ui.List} | 340 * @extends {cr.ui.List} |
| 443 */ | 341 */ |
| 444 var ExceptionsList = cr.ui.define('list'); | 342 var ExceptionsList = cr.ui.define('list'); |
| 445 | 343 |
| 446 ExceptionsList.prototype = { | 344 ExceptionsList.prototype = { |
| 447 __proto__: InlineEditableItemList.prototype, | 345 __proto__: InlineEditableItemList.prototype, |
| 448 | 346 |
| 449 /** | 347 /** |
| 450 * Called when an element is decorated as a list. | 348 * Called when an element is decorated as a list. |
| 451 */ | 349 */ |
| 452 decorate: function() { | 350 decorate: function() { |
| 453 InlineEditableItemList.prototype.decorate.call(this); | 351 InlineEditableItemList.prototype.decorate.call(this); |
| 454 | 352 |
| 455 this.classList.add('settings-list'); | 353 this.classList.add('settings-list'); |
| 456 | 354 |
| 457 for (var parentNode = this.parentNode; parentNode; | |
| 458 parentNode = parentNode.parentNode) { | |
| 459 if (parentNode.hasAttribute('contentType')) { | |
| 460 this.contentType = parentNode.getAttribute('contentType'); | |
| 461 break; | |
| 462 } | |
| 463 } | |
| 464 | |
| 465 this.mode = this.getAttribute('mode'); | |
| 466 | |
| 467 // Whether the exceptions in this list allow an 'Ask every time' option. | |
| 468 this.enableAskOption = this.contentType == 'plugins'; | |
| 469 | |
| 470 this.autoExpands = true; | 355 this.autoExpands = true; |
| 471 this.reset(); | 356 this.reset(); |
| 472 }, | 357 }, |
| 473 | 358 |
| 474 /** | 359 /** |
| 475 * Creates an item to go in the list. | 360 * Creates an item to go in the list. |
| 476 * | 361 * |
| 477 * @param {Object} entry The element from the data model for this row. | 362 * @param {Object} entry The element from the data model for this row. |
| 478 */ | 363 */ |
| 479 createItem: function(entry) { | 364 createItem: function(entry) { |
| 480 if (entry) { | 365 if (entry) { |
| 481 return new ExceptionsListItem(this.contentType, | 366 return new ExceptionsListItem(entry); |
| 482 this.mode, | |
| 483 this.enableAskOption, | |
| 484 entry); | |
| 485 } else { | 367 } else { |
| 486 var addRowItem = new ExceptionsAddRowListItem(this.contentType, | 368 var addRowItem = new ExceptionsAddRowListItem(); |
| 487 this.mode, | |
| 488 this.enableAskOption); | |
| 489 addRowItem.deletable = false; | 369 addRowItem.deletable = false; |
| 490 return addRowItem; | 370 return addRowItem; |
| 491 } | 371 } |
| 492 }, | 372 }, |
| 493 | 373 |
| 494 /** | 374 /** |
| 495 * Sets the exceptions in the js model. | 375 * Sets the exceptions in the js model. |
| 496 * | 376 * |
| 497 * @param {Object} entries A list of dictionaries of values, each dictionary | 377 * @param {Object} entries A list of dictionaries of values, each dictionary |
| 498 * represents an exception. | 378 * represents an exception. |
| 499 */ | 379 */ |
| 500 setExceptions: function(entries) { | 380 setManualExceptions: function(entries) { |
| 501 var deleteCount = this.dataModel.length; | 381 // We don't want to remove the Add New Exception row. |
| 502 | 382 var deleteCount = this.dataModel.length - 1; |
| 503 if (this.isEditable()) { | |
| 504 // We don't want to remove the Add New Exception row. | |
| 505 deleteCount = deleteCount - 1; | |
| 506 } | |
| 507 | 383 |
| 508 var args = [0, deleteCount]; | 384 var args = [0, deleteCount]; |
| 509 args.push.apply(args, entries); | 385 args.push.apply(args, entries); |
| 510 this.dataModel.splice.apply(this.dataModel, args); | 386 this.dataModel.splice.apply(this.dataModel, args); |
| 511 }, | 387 }, |
| 512 | 388 |
| 513 /** | 389 /** |
| 514 * The browser has finished checking a pattern for validity. Update the list | 390 * The browser has finished checking a pattern for validity. Update the list |
| 515 * item to reflect this. | 391 * item to reflect this. |
| 516 * | 392 * |
| 517 * @param {string} pattern The pattern. | 393 * @param {string} pattern The pattern. |
| 518 * @param {bool} valid Whether said pattern is valid in the context of a | 394 * @param {bool} valid Whether said pattern is valid in the context of a |
| 519 * content exception setting. | 395 * content exception setting. |
| 520 */ | 396 */ |
| 521 patternValidityCheckComplete: function(pattern, valid) { | 397 patternValidityCheckComplete: function(pattern, valid) { |
| 522 var listItems = this.items; | 398 var listItems = this.items; |
| 523 for (var i = 0; i < listItems.length; i++) { | 399 for (var i = 0; i < listItems.length; i++) { |
| 524 var listItem = listItems[i]; | 400 var listItem = listItems[i]; |
| 525 // Don't do anything for messages for the item if it is not the intended | 401 // Don't do anything for messages for the item if it is not the intended |
| 526 // recipient, or if the response is stale (i.e. the input value has | 402 // recipient, or if the response is stale (i.e. the input value has |
| 527 // changed since we sent the request to analyze it). | 403 // changed since we sent the request to analyze it). |
| 528 if (pattern == listItem.input.value) | 404 if (pattern == listItem.input.value) |
| 529 listItem.setPatternValid(valid); | 405 listItem.setPatternValid(valid); |
| 530 } | 406 } |
| 531 }, | 407 }, |
| 532 | 408 |
| 533 /** | 409 /** |
| 534 * Returns whether the rows are editable in this list. | |
| 535 */ | |
| 536 isEditable: function() { | |
| 537 // Exceptions of the following lists are not editable for now. | |
| 538 return !(this.contentType == 'notifications' || | |
| 539 this.contentType == 'location' || | |
| 540 this.contentType == 'fullscreen' || | |
| 541 this.contentType == 'media-stream'); | |
| 542 }, | |
| 543 | |
| 544 /** | |
| 545 * Removes all exceptions from the js model. | 410 * Removes all exceptions from the js model. |
| 546 */ | 411 */ |
| 547 reset: function() { | 412 reset: function() { |
| 548 if (this.isEditable()) { | 413 // The null creates the Add New Exception row. |
| 549 // The null creates the Add New Exception row. | 414 this.dataModel = new ArrayDataModel([null]); |
| 550 this.dataModel = new ArrayDataModel([null]); | 415 |
| 551 } else { | 416 // Set the initial sort order. |
| 552 this.dataModel = new ArrayDataModel([]); | 417 this.dataModel.setCompareFunction('pattern', comparePatterns.bind(this)); |
| 553 } | 418 this.dataModel.sort('pattern', 'asc'); |
| 554 }, | 419 }, |
| 555 | 420 |
| 556 /** @override */ | 421 /** @override */ |
| 557 deleteItemAtIndex: function(index) { | 422 deleteItemAtIndex: function(index) { |
| 558 var listItem = this.getListItemByIndex(index); | 423 var listItem = this.getListItemByIndex(index); |
| 559 if (!listItem.deletable) | 424 if (!listItem.deletable) |
| 560 return; | 425 return; |
| 561 | 426 |
| 562 var dataItem = listItem.dataItem; | 427 var dataItem = listItem.dataItem; |
| 563 var args = [listItem.contentType]; | 428 var args = []; |
| 564 if (listItem.contentType == 'notifications') | 429 args.push(dataItem.pattern); |
| 565 args.push(dataItem.origin, dataItem.setting); | |
| 566 else | |
| 567 args.push(listItem.mode, dataItem.origin, dataItem.embeddingOrigin); | |
| 568 | 430 |
| 569 chrome.send('removeException', args); | 431 chrome.send('removeManualException', args); |
| 570 }, | 432 }, |
| 571 }; | 433 }; |
| 572 | 434 |
| 573 var OptionsPage = options.OptionsPage; | 435 var OptionsPage = options.OptionsPage; |
| 574 | 436 |
| 575 /** | 437 /** |
| 576 * Encapsulated handling of content settings list subpage. | 438 * Encapsulated handling of content settings list subpage. |
| 577 * | |
| 578 * @constructor | 439 * @constructor |
| 440 * @class |
| 579 */ | 441 */ |
| 580 function ContentSettingsExceptionsArea() { | 442 function ManagedUserSettingsExceptionsArea() { |
| 581 OptionsPage.call(this, 'contentExceptions', | 443 OptionsPage.call(this, 'manualExceptions', |
| 582 loadTimeData.getString('contentSettingsPageTabTitle'), | 444 loadTimeData.getString('managedUserSettingsPageTabTitle'), |
| 583 'content-settings-exceptions-area'); | 445 'managed-user-exceptions-area'); |
| 584 } | 446 } |
| 585 | 447 |
| 586 cr.addSingletonGetter(ContentSettingsExceptionsArea); | 448 cr.addSingletonGetter(ManagedUserSettingsExceptionsArea); |
| 587 | 449 |
| 588 ContentSettingsExceptionsArea.prototype = { | 450 ManagedUserSettingsExceptionsArea.prototype = { |
| 589 __proto__: OptionsPage.prototype, | 451 __proto__: OptionsPage.prototype, |
| 590 | 452 |
| 591 initializePage: function() { | 453 initializePage: function() { |
| 592 OptionsPage.prototype.initializePage.call(this); | 454 OptionsPage.prototype.initializePage.call(this); |
| 593 | 455 |
| 594 var exceptionsLists = this.pageDiv.querySelectorAll('list'); | 456 var exceptionsLists = this.pageDiv.querySelectorAll('list'); |
| 595 for (var i = 0; i < exceptionsLists.length; i++) { | 457 for (var i = 0; i < exceptionsLists.length; i++) { |
| 596 options.contentSettings.ExceptionsList.decorate(exceptionsLists[i]); | 458 options.managedUserSettings.ExceptionsList.decorate(exceptionsLists[i]); |
| 597 } | 459 } |
| 598 | 460 |
| 599 ContentSettingsExceptionsArea.hideOTRLists(false); | 461 $('managed-user-settings-exceptions-overlay-confirm').onclick = |
| 600 | |
| 601 // If the user types in the URL without a hash, show just cookies. | |
| 602 this.showList('cookies'); | |
| 603 | |
| 604 $('content-settings-exceptions-overlay-confirm').onclick = | |
| 605 OptionsPage.closeOverlay.bind(OptionsPage); | 462 OptionsPage.closeOverlay.bind(OptionsPage); |
| 606 }, | 463 }, |
| 607 | |
| 608 /** | |
| 609 * Shows one list and hides all others. | |
| 610 * | |
| 611 * @param {string} type The content type. | |
| 612 */ | |
| 613 showList: function(type) { | |
| 614 var header = this.pageDiv.querySelector('h1'); | |
| 615 header.textContent = loadTimeData.getString(type + '_header'); | |
| 616 | |
| 617 var divs = this.pageDiv.querySelectorAll('div[contentType]'); | |
| 618 for (var i = 0; i < divs.length; i++) { | |
| 619 if (divs[i].getAttribute('contentType') == type) | |
| 620 divs[i].hidden = false; | |
| 621 else | |
| 622 divs[i].hidden = true; | |
| 623 } | |
| 624 | |
| 625 var mediaHeader = this.pageDiv.querySelector('.media-header'); | |
| 626 mediaHeader.hidden = type != 'media-stream'; | |
| 627 }, | |
| 628 | |
| 629 /** | |
| 630 * Called after the page has been shown. Show the content type for the | |
| 631 * location's hash. | |
| 632 */ | |
| 633 didShowPage: function() { | |
| 634 var hash = location.hash; | |
| 635 if (hash) | |
| 636 this.showList(hash.slice(1)); | |
| 637 }, | |
| 638 }; | |
| 639 | |
| 640 /** | |
| 641 * Called when the last incognito window is closed. | |
| 642 */ | |
| 643 ContentSettingsExceptionsArea.OTRProfileDestroyed = function() { | |
| 644 this.hideOTRLists(true); | |
| 645 }; | |
| 646 | |
| 647 /** | |
| 648 * Hides the incognito exceptions lists and optionally clears them as well. | |
| 649 * @param {boolean} clear Whether to clear the lists. | |
| 650 */ | |
| 651 ContentSettingsExceptionsArea.hideOTRLists = function(clear) { | |
| 652 var otrLists = document.querySelectorAll('list[mode=otr]'); | |
| 653 | |
| 654 for (var i = 0; i < otrLists.length; i++) { | |
| 655 otrLists[i].parentNode.hidden = true; | |
| 656 if (clear) | |
| 657 otrLists[i].reset(); | |
| 658 } | |
| 659 }; | 464 }; |
| 660 | 465 |
| 661 return { | 466 return { |
| 662 ExceptionsListItem: ExceptionsListItem, | 467 ExceptionsListItem: ExceptionsListItem, |
| 663 ExceptionsAddRowListItem: ExceptionsAddRowListItem, | 468 ExceptionsAddRowListItem: ExceptionsAddRowListItem, |
| 664 ExceptionsList: ExceptionsList, | 469 ExceptionsList: ExceptionsList, |
| 665 ContentSettingsExceptionsArea: ContentSettingsExceptionsArea, | 470 ManagedUserSettingsExceptionsArea: ManagedUserSettingsExceptionsArea, |
| 666 }; | 471 }; |
| 667 }); | 472 }); |
| OLD | NEW |