| Index: chrome/browser/resources/options/managed_user_exceptions_area.js
|
| diff --git a/chrome/browser/resources/options/content_settings_exceptions_area.js b/chrome/browser/resources/options/managed_user_exceptions_area.js
|
| similarity index 52%
|
| copy from chrome/browser/resources/options/content_settings_exceptions_area.js
|
| copy to chrome/browser/resources/options/managed_user_exceptions_area.js
|
| index 7d2e452df4d9b574dc045de16cb7db8f49668f92..300e46462c60f9aa0b5693e098554d59b9720b15 100644
|
| --- a/chrome/browser/resources/options/content_settings_exceptions_area.js
|
| +++ b/chrome/browser/resources/options/managed_user_exceptions_area.js
|
| @@ -1,8 +1,10 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Copyright 2013 The Chromium Authors. All rights reserved.
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -cr.define('options.contentSettings', function() {
|
| +// TODO(sergiu): Write a base class such that both this and the content
|
| +// settings exceptions inherit from it (http://crbug.com/227520).
|
| +cr.define('options.managedUserSettings', function() {
|
| /** @const */ var ControlledSettingIndicator =
|
| options.ControlledSettingIndicator;
|
| /** @const */ var InlineEditableItemList = options.InlineEditableItemList;
|
| @@ -12,20 +14,14 @@ cr.define('options.contentSettings', function() {
|
| /**
|
| * Creates a new exceptions list item.
|
| *
|
| - * @param {string} contentType The type of the list.
|
| - * @param {string} mode The browser mode, 'otr' or 'normal'.
|
| - * @param {boolean} enableAskOption Whether to show an 'ask every time'
|
| - * option in the select.
|
| * @param {Object} exception A dictionary that contains the data of the
|
| * exception.
|
| * @constructor
|
| * @extends {options.InlineEditableItem}
|
| */
|
| - function ExceptionsListItem(contentType, mode, enableAskOption, exception) {
|
| + function ExceptionsListItem(exception) {
|
| var el = cr.doc.createElement('div');
|
| - el.mode = mode;
|
| - el.contentType = contentType;
|
| - el.enableAskOption = enableAskOption;
|
| + el.contentType = 'manual-exceptions';
|
| el.dataItem = exception;
|
| el.__proto__ = ExceptionsListItem.prototype;
|
| el.decorate();
|
| @@ -70,56 +66,16 @@ cr.define('options.contentSettings', function() {
|
| optionAllow.textContent = loadTimeData.getString('allowException');
|
| optionAllow.value = 'allow';
|
| select.appendChild(optionAllow);
|
| -
|
| - if (this.enableAskOption) {
|
| - var optionAsk = cr.doc.createElement('option');
|
| - optionAsk.textContent = loadTimeData.getString('askException');
|
| - optionAsk.value = 'ask';
|
| - select.appendChild(optionAsk);
|
| - }
|
| -
|
| - if (this.contentType == 'cookies') {
|
| - var optionSession = cr.doc.createElement('option');
|
| - optionSession.textContent = loadTimeData.getString('sessionException');
|
| - optionSession.value = 'session';
|
| - select.appendChild(optionSession);
|
| - }
|
| -
|
| - if (this.contentType != 'fullscreen') {
|
| - var optionBlock = cr.doc.createElement('option');
|
| - optionBlock.textContent = loadTimeData.getString('blockException');
|
| - optionBlock.value = 'block';
|
| - select.appendChild(optionBlock);
|
| - }
|
| -
|
| - if (this.isEmbeddingRule()) {
|
| - this.patternLabel.classList.add('sublabel');
|
| - this.editable = false;
|
| - }
|
| -
|
| - if (this.setting == 'default') {
|
| - // Items that don't have their own settings (parents of 'embedded on'
|
| - // items) aren't deletable.
|
| - this.deletable = false;
|
| - this.editable = false;
|
| - }
|
| + var optionBlock = cr.doc.createElement('option');
|
| + optionBlock.textContent = loadTimeData.getString('blockException');
|
| + optionBlock.value = 'block';
|
| + select.appendChild(optionBlock);
|
|
|
| this.contentElement.appendChild(select);
|
| select.className = 'exception-setting';
|
| if (this.pattern)
|
| select.setAttribute('displaymode', 'edit');
|
|
|
| - if (this.contentType == 'media-stream') {
|
| - this.settingLabel.classList.add('media-audio-setting');
|
| -
|
| - var videoSettingLabel = cr.doc.createElement('span');
|
| - videoSettingLabel.textContent = this.videoSettingForDisplay();
|
| - videoSettingLabel.className = 'exception-setting';
|
| - videoSettingLabel.classList.add('media-video-setting');
|
| - videoSettingLabel.setAttribute('displaymode', 'static');
|
| - this.contentElement.appendChild(videoSettingLabel);
|
| - }
|
| -
|
| // Used to track whether the URL pattern in the input is valid.
|
| // This will be true if the browser process has informed us that the
|
| // current text in the input is valid. Changing the text resets this to
|
| @@ -137,58 +93,12 @@ cr.define('options.contentSettings', function() {
|
|
|
| this.updateEditables();
|
|
|
| - // Editing notifications, geolocation and media-stream is disabled for
|
| - // now.
|
| - if (this.contentType == 'notifications' ||
|
| - this.contentType == 'location' ||
|
| - this.contentType == 'media-stream') {
|
| - this.editable = false;
|
| - }
|
| -
|
| - // If the source of the content setting exception is not a user
|
| - // preference, that source controls the exception and the user cannot edit
|
| - // or delete it.
|
| - var controlledBy =
|
| - this.dataItem.source && this.dataItem.source != 'preference' ?
|
| - this.dataItem.source : null;
|
| -
|
| - if (controlledBy) {
|
| - this.setAttribute('controlled-by', controlledBy);
|
| - this.deletable = false;
|
| - this.editable = false;
|
| - }
|
| -
|
| - if (controlledBy == 'policy' || controlledBy == 'extension') {
|
| - this.querySelector('.row-delete-button').hidden = true;
|
| - var indicator = ControlledSettingIndicator();
|
| - indicator.setAttribute('content-exception', this.contentType);
|
| - // Create a synthetic pref change event decorated as
|
| - // CoreOptionsHandler::CreateValueForPref() does.
|
| - var event = new cr.Event(this.contentType);
|
| - event.value = { controlledBy: controlledBy };
|
| - indicator.handlePrefChange(event);
|
| - this.appendChild(indicator);
|
| - }
|
| -
|
| - // If the exception comes from a hosted app, display the name and the
|
| - // icon of the app.
|
| - if (controlledBy == 'HostedApp') {
|
| - this.title =
|
| - loadTimeData.getString('set_by') + ' ' + this.dataItem.appName;
|
| - var button = this.querySelector('.row-delete-button');
|
| - // Use the host app's favicon (16px, match bigger size).
|
| - // See c/b/ui/webui/extensions/extension_icon_source.h
|
| - // for a description of the chrome://extension-icon URL.
|
| - button.style.backgroundImage =
|
| - 'url(\'chrome://extension-icon/' + this.dataItem.appId + '/16/1\')';
|
| - }
|
| -
|
| var listItem = this;
|
| // Handle events on the editable nodes.
|
| input.oninput = function(event) {
|
| listItem.inputValidityKnown = false;
|
| - chrome.send('checkExceptionPatternValidity',
|
| - [listItem.contentType, listItem.mode, input.value]);
|
| + chrome.send('checkManualExceptionValidity',
|
| + [input.value]);
|
| };
|
|
|
| // Listen for edit events.
|
| @@ -196,31 +106,19 @@ cr.define('options.contentSettings', function() {
|
| this.addEventListener('commitedit', this.onEditCommitted_);
|
| },
|
|
|
| - isEmbeddingRule: function() {
|
| - return this.dataItem.embeddingOrigin &&
|
| - this.dataItem.embeddingOrigin !== this.dataItem.origin;
|
| - },
|
| -
|
| /**
|
| * The pattern (e.g., a URL) for the exception.
|
| *
|
| * @type {string}
|
| */
|
| get pattern() {
|
| - if (!this.isEmbeddingRule()) {
|
| - return this.dataItem.origin;
|
| - } else {
|
| - return loadTimeData.getStringF('embeddedOnHost',
|
| - this.dataItem.embeddingOrigin);
|
| - }
|
| -
|
| - return this.dataItem.displayPattern;
|
| + return this.dataItem.pattern;
|
| },
|
| set pattern(pattern) {
|
| if (!this.editable)
|
| console.error('Tried to change uneditable pattern');
|
|
|
| - this.dataItem.displayPattern = pattern;
|
| + this.dataItem.pattern = pattern;
|
| },
|
|
|
| /**
|
| @@ -245,16 +143,6 @@ cr.define('options.contentSettings', function() {
|
| },
|
|
|
| /**
|
| - * media video specific function.
|
| - * Gets a human-readable video setting string.
|
| - *
|
| - * @return {string} The display string.
|
| - */
|
| - videoSettingForDisplay: function() {
|
| - return this.getDisplayStringForSetting(this.dataItem.video);
|
| - },
|
| -
|
| - /**
|
| * Gets a human-readable display string for setting.
|
| *
|
| * @param {string} setting The setting to be displayed.
|
| @@ -265,12 +153,6 @@ cr.define('options.contentSettings', function() {
|
| return loadTimeData.getString('allowException');
|
| else if (setting == 'block')
|
| return loadTimeData.getString('blockException');
|
| - else if (setting == 'ask')
|
| - return loadTimeData.getString('askException');
|
| - else if (setting == 'session')
|
| - return loadTimeData.getString('sessionException');
|
| - else if (setting == 'default')
|
| - return '';
|
|
|
| console.error('Unknown setting: [' + setting + ']');
|
| return '';
|
| @@ -354,21 +236,22 @@ cr.define('options.contentSettings', function() {
|
| * @param {string} newSetting The setting the user chose.
|
| */
|
| finishEdit: function(newPattern, newSetting) {
|
| + this.setting = newSetting;
|
| this.patternLabel.textContent = newPattern;
|
| this.settingLabel.textContent = this.settingForDisplay();
|
| var oldPattern = this.pattern;
|
| this.pattern = newPattern;
|
| - this.setting = newSetting;
|
| + var needsUpdate = false;
|
|
|
| - // TODO(estade): this will need to be updated if geolocation/notifications
|
| - // become editable.
|
| if (oldPattern != newPattern) {
|
| - chrome.send('removeException',
|
| - [this.contentType, this.mode, oldPattern]);
|
| + needsUpdate = true;
|
| + chrome.send('removeManualException', [oldPattern]);
|
| }
|
|
|
| - chrome.send('setException',
|
| - [this.contentType, this.mode, newPattern, newSetting]);
|
| + // If only the setting is changed for this pattern and not the pattern
|
| + // itself then the interface is already updated so we don't need to
|
| + // trigger it then processing is completed.
|
| + chrome.send('setManualException', [newPattern, newSetting, needsUpdate]);
|
| }
|
| };
|
|
|
| @@ -377,18 +260,11 @@ cr.define('options.contentSettings', function() {
|
| * an actual entry in the exceptions list but allows the user to add new
|
| * exceptions.
|
| *
|
| - * @param {string} contentType The type of the list.
|
| - * @param {string} mode The browser mode, 'otr' or 'normal'.
|
| - * @param {boolean} enableAskOption Whether to show an 'ask every time' option
|
| - * in the select.
|
| * @constructor
|
| * @extends {cr.ui.ExceptionsListItem}
|
| */
|
| - function ExceptionsAddRowListItem(contentType, mode, enableAskOption) {
|
| + function ExceptionsAddRowListItem() {
|
| var el = cr.doc.createElement('div');
|
| - el.mode = mode;
|
| - el.contentType = contentType;
|
| - el.enableAskOption = enableAskOption;
|
| el.dataItem = [];
|
| el.__proto__ = ExceptionsAddRowListItem.prototype;
|
| el.decorate();
|
| @@ -405,7 +281,7 @@ cr.define('options.contentSettings', function() {
|
| this.input.placeholder =
|
| loadTimeData.getString('addNewExceptionInstructions');
|
|
|
| - // Do we always want a default of allow?
|
| + // Set 'Allow' as default for new entries.
|
| this.setting = 'allow';
|
| },
|
|
|
| @@ -430,12 +306,34 @@ cr.define('options.contentSettings', function() {
|
| */
|
| finishEdit: function(newPattern, newSetting) {
|
| this.resetInput();
|
| - chrome.send('setException',
|
| - [this.contentType, this.mode, newPattern, newSetting]);
|
| + // We're adding a new entry, update the model once that is done.
|
| + chrome.send('setManualException', [newPattern, newSetting, true]);
|
| },
|
| };
|
|
|
| /**
|
| + * Compares two elements in the list. Removes the schema if present and then
|
| + * compares the two strings.
|
| + * @param {string} a First element to compare.
|
| + * @param {string} b Second element to compare.
|
| + * @return {int} Result of comparison between a and b.
|
| + */
|
| + function comparePatterns(a, b) {
|
| + // Remove the schema (part before ://) if any.
|
| + var stripString = function(str) {
|
| + var indexStr = str.indexOf('://');
|
| + if (indexStr != -1)
|
| + return str.slice(indexStr + 3);
|
| + return str;
|
| + };
|
| + if (a)
|
| + a = stripString(a['pattern']);
|
| + if (b)
|
| + b = stripString(b['pattern']);
|
| + return this.dataModel.defaultValuesCompareFunction(a, b);
|
| + }
|
| +
|
| + /**
|
| * Creates a new exceptions list.
|
| *
|
| * @constructor
|
| @@ -454,19 +352,6 @@ cr.define('options.contentSettings', function() {
|
|
|
| this.classList.add('settings-list');
|
|
|
| - for (var parentNode = this.parentNode; parentNode;
|
| - parentNode = parentNode.parentNode) {
|
| - if (parentNode.hasAttribute('contentType')) {
|
| - this.contentType = parentNode.getAttribute('contentType');
|
| - break;
|
| - }
|
| - }
|
| -
|
| - this.mode = this.getAttribute('mode');
|
| -
|
| - // Whether the exceptions in this list allow an 'Ask every time' option.
|
| - this.enableAskOption = this.contentType == 'plugins';
|
| -
|
| this.autoExpands = true;
|
| this.reset();
|
| },
|
| @@ -478,14 +363,9 @@ cr.define('options.contentSettings', function() {
|
| */
|
| createItem: function(entry) {
|
| if (entry) {
|
| - return new ExceptionsListItem(this.contentType,
|
| - this.mode,
|
| - this.enableAskOption,
|
| - entry);
|
| + return new ExceptionsListItem(entry);
|
| } else {
|
| - var addRowItem = new ExceptionsAddRowListItem(this.contentType,
|
| - this.mode,
|
| - this.enableAskOption);
|
| + var addRowItem = new ExceptionsAddRowListItem();
|
| addRowItem.deletable = false;
|
| return addRowItem;
|
| }
|
| @@ -497,13 +377,9 @@ cr.define('options.contentSettings', function() {
|
| * @param {Object} entries A list of dictionaries of values, each dictionary
|
| * represents an exception.
|
| */
|
| - setExceptions: function(entries) {
|
| - var deleteCount = this.dataModel.length;
|
| -
|
| - if (this.isEditable()) {
|
| - // We don't want to remove the Add New Exception row.
|
| - deleteCount = deleteCount - 1;
|
| - }
|
| + setManualExceptions: function(entries) {
|
| + // We don't want to remove the Add New Exception row.
|
| + var deleteCount = this.dataModel.length - 1;
|
|
|
| var args = [0, deleteCount];
|
| args.push.apply(args, entries);
|
| @@ -531,26 +407,15 @@ cr.define('options.contentSettings', function() {
|
| },
|
|
|
| /**
|
| - * Returns whether the rows are editable in this list.
|
| - */
|
| - isEditable: function() {
|
| - // Exceptions of the following lists are not editable for now.
|
| - return !(this.contentType == 'notifications' ||
|
| - this.contentType == 'location' ||
|
| - this.contentType == 'fullscreen' ||
|
| - this.contentType == 'media-stream');
|
| - },
|
| -
|
| - /**
|
| * Removes all exceptions from the js model.
|
| */
|
| reset: function() {
|
| - if (this.isEditable()) {
|
| - // The null creates the Add New Exception row.
|
| - this.dataModel = new ArrayDataModel([null]);
|
| - } else {
|
| - this.dataModel = new ArrayDataModel([]);
|
| - }
|
| + // The null creates the Add New Exception row.
|
| + this.dataModel = new ArrayDataModel([null]);
|
| +
|
| + // Set the initial sort order.
|
| + this.dataModel.setCompareFunction('pattern', comparePatterns.bind(this));
|
| + this.dataModel.sort('pattern', 'asc');
|
| },
|
|
|
| /** @override */
|
| @@ -560,13 +425,10 @@ cr.define('options.contentSettings', function() {
|
| return;
|
|
|
| var dataItem = listItem.dataItem;
|
| - var args = [listItem.contentType];
|
| - if (listItem.contentType == 'notifications')
|
| - args.push(dataItem.origin, dataItem.setting);
|
| - else
|
| - args.push(listItem.mode, dataItem.origin, dataItem.embeddingOrigin);
|
| + var args = [];
|
| + args.push(dataItem.pattern);
|
|
|
| - chrome.send('removeException', args);
|
| + chrome.send('removeManualException', args);
|
| },
|
| };
|
|
|
| @@ -574,18 +436,18 @@ cr.define('options.contentSettings', function() {
|
|
|
| /**
|
| * Encapsulated handling of content settings list subpage.
|
| - *
|
| * @constructor
|
| + * @class
|
| */
|
| - function ContentSettingsExceptionsArea() {
|
| - OptionsPage.call(this, 'contentExceptions',
|
| - loadTimeData.getString('contentSettingsPageTabTitle'),
|
| - 'content-settings-exceptions-area');
|
| + function ManagedUserSettingsExceptionsArea() {
|
| + OptionsPage.call(this, 'manualExceptions',
|
| + loadTimeData.getString('managedUserSettingsPageTabTitle'),
|
| + 'managed-user-exceptions-area');
|
| }
|
|
|
| - cr.addSingletonGetter(ContentSettingsExceptionsArea);
|
| + cr.addSingletonGetter(ManagedUserSettingsExceptionsArea);
|
|
|
| - ContentSettingsExceptionsArea.prototype = {
|
| + ManagedUserSettingsExceptionsArea.prototype = {
|
| __proto__: OptionsPage.prototype,
|
|
|
| initializePage: function() {
|
| @@ -593,75 +455,18 @@ cr.define('options.contentSettings', function() {
|
|
|
| var exceptionsLists = this.pageDiv.querySelectorAll('list');
|
| for (var i = 0; i < exceptionsLists.length; i++) {
|
| - options.contentSettings.ExceptionsList.decorate(exceptionsLists[i]);
|
| + options.managedUserSettings.ExceptionsList.decorate(exceptionsLists[i]);
|
| }
|
|
|
| - ContentSettingsExceptionsArea.hideOTRLists(false);
|
| -
|
| - // If the user types in the URL without a hash, show just cookies.
|
| - this.showList('cookies');
|
| -
|
| - $('content-settings-exceptions-overlay-confirm').onclick =
|
| + $('managed-user-settings-exceptions-overlay-confirm').onclick =
|
| OptionsPage.closeOverlay.bind(OptionsPage);
|
| },
|
| -
|
| - /**
|
| - * Shows one list and hides all others.
|
| - *
|
| - * @param {string} type The content type.
|
| - */
|
| - showList: function(type) {
|
| - var header = this.pageDiv.querySelector('h1');
|
| - header.textContent = loadTimeData.getString(type + '_header');
|
| -
|
| - var divs = this.pageDiv.querySelectorAll('div[contentType]');
|
| - for (var i = 0; i < divs.length; i++) {
|
| - if (divs[i].getAttribute('contentType') == type)
|
| - divs[i].hidden = false;
|
| - else
|
| - divs[i].hidden = true;
|
| - }
|
| -
|
| - var mediaHeader = this.pageDiv.querySelector('.media-header');
|
| - mediaHeader.hidden = type != 'media-stream';
|
| - },
|
| -
|
| - /**
|
| - * Called after the page has been shown. Show the content type for the
|
| - * location's hash.
|
| - */
|
| - didShowPage: function() {
|
| - var hash = location.hash;
|
| - if (hash)
|
| - this.showList(hash.slice(1));
|
| - },
|
| - };
|
| -
|
| - /**
|
| - * Called when the last incognito window is closed.
|
| - */
|
| - ContentSettingsExceptionsArea.OTRProfileDestroyed = function() {
|
| - this.hideOTRLists(true);
|
| - };
|
| -
|
| - /**
|
| - * Hides the incognito exceptions lists and optionally clears them as well.
|
| - * @param {boolean} clear Whether to clear the lists.
|
| - */
|
| - ContentSettingsExceptionsArea.hideOTRLists = function(clear) {
|
| - var otrLists = document.querySelectorAll('list[mode=otr]');
|
| -
|
| - for (var i = 0; i < otrLists.length; i++) {
|
| - otrLists[i].parentNode.hidden = true;
|
| - if (clear)
|
| - otrLists[i].reset();
|
| - }
|
| };
|
|
|
| return {
|
| ExceptionsListItem: ExceptionsListItem,
|
| ExceptionsAddRowListItem: ExceptionsAddRowListItem,
|
| ExceptionsList: ExceptionsList,
|
| - ContentSettingsExceptionsArea: ContentSettingsExceptionsArea,
|
| + ManagedUserSettingsExceptionsArea: ManagedUserSettingsExceptionsArea,
|
| };
|
| });
|
|
|