• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2014 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.ContentSettings', function() {
6  /** @const */ var Page = cr.ui.pageManager.Page;
7  /** @const */ var PageManager = cr.ui.pageManager.PageManager;
8  /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
9
10  // Lookup table to generate the i18n strings.
11  /** @const */ var permissionsLookup = {
12    'geolocation': 'location',
13    'notifications': 'notifications',
14    'media-stream': 'mediaStream',
15    'cookies': 'cookies',
16    'multiple-automatic-downloads': 'multipleAutomaticDownloads',
17    'images': 'images',
18    'plugins': 'plugins',
19    'popups': 'popups',
20    'javascript': 'javascript',
21    'battery': 'battery',
22    'storage': 'storage'
23  };
24
25  /////////////////////////////////////////////////////////////////////////////
26  // WebsiteSettingsManager class:
27
28  /**
29   * Encapsulated handling of the website settings page.
30   * @constructor
31   * @extends {cr.ui.pageManager.Page}
32   */
33  function WebsiteSettingsManager() {
34    Page.call(this, 'websiteSettings',
35              loadTimeData.getString('websitesOptionsPageTabTitle'),
36              'website-settings-page');
37  }
38
39  cr.addSingletonGetter(WebsiteSettingsManager);
40
41  WebsiteSettingsManager.prototype = {
42    __proto__: Page.prototype,
43
44    /**
45     * The saved allowed origins list.
46     * @type {options.OriginList}
47     * @private
48     */
49    allowedList_: null,
50
51    /**
52     * The saved blocked origins list.
53     * @type {options.OriginList}
54     * @private
55     */
56    blockedList_: null,
57
58    /** @override */
59    initializePage: function() {
60      Page.prototype.initializePage.call(this);
61
62      $('website-settings-overlay-confirm').onclick =
63          PageManager.closeOverlay.bind(PageManager);
64
65      $('global-setting').onchange = function(event) {
66        chrome.send('setDefaultContentSetting', [this.value]);
67      };
68
69      $('global-setting-toggle').onchange = function(event) {
70        var value = event.target.checked;
71        chrome.send('setGlobalEnabled', [value]);
72      };
73
74      var searchBox = $('website-settings-search-box');
75      searchBox.addEventListener('search',
76                                 this.handleSearchQueryChange_.bind(this));
77
78      searchBox.onkeydown = function(e) {
79        if (e.keyIdentifier == 'Enter')
80          e.preventDefault();
81      };
82
83      this.createOriginsList_();
84      this.updatePage_('geolocation');
85    },
86
87    /**
88     * Called after the page has been shown. Show the content settings or
89     * resource auditing for the location's hash.
90     */
91    didShowPage: function() {
92      var hash = this.hash;
93      if (hash)
94        hash = hash.slice(1);
95      else
96        hash = 'geolocation';
97      this.updatePage_(hash);
98    },
99
100    /**
101     * Creates, decorates and initializes the origin list.
102     * @private
103     */
104    createOriginsList_: function() {
105      var allowedList = $('allowed-origin-list');
106      options.OriginList.decorate(allowedList);
107      this.allowedList_ = assertInstanceof(allowedList, options.OriginList);
108      this.allowedList_.autoExpands = true;
109
110      var blockedList = $('blocked-origin-list');
111      options.OriginList.decorate(blockedList);
112      this.blockedList_ = assertInstanceof(blockedList, options.OriginList);
113      this.blockedList_.autoExpands = true;
114    },
115
116    /**
117     * Populate an origin list with all of the origins with a given permission
118     * or that are using a given resource.
119     * @param {options.OriginList} originList A list to populate.
120     * @param {!Object} originDict A dictionary of origins to their usage, which
121           will be used to sort the origins.
122     * @private
123     */
124    populateOriginsHelper_: function(originList, originDict) {
125      var origins = Object.keys(originDict).map(function(origin) {
126        // |usage| means the time of last usage in seconds since epoch
127        // (Jan 1, 1970) for permissions and means the amount of local storage
128        // in bytes used for local storage.
129        return {
130          origin: origin,
131          usage: originDict[origin].usage,
132          usageString: originDict[origin].usageString,
133          readableName: originDict[origin].readableName,
134        };
135      });
136      origins.sort(function(first, second) {
137        return second.usage - first.usage;
138      });
139      originList.dataModel = new ArrayDataModel(origins);
140    },
141
142
143    /**
144     * Populate the origin lists with all of the origins with a given permission
145     * or that are using a given resource, potentially split by if allowed or
146     * denied. If no blocked dictionary is provided, only the allowed list is
147     * shown.
148     * @param {!Object} allowedDict A dictionary of origins to their usage,
149           which will be used to sort the origins in the main/allowed list.
150     * @param {!Object} blockedDict An optional dictionary of origins to their
151           usage, which will be used to sort the origins in the blocked list.
152     * @param {bool} isGloballyEnabled If the content setting is turned on.
153     * @private
154     */
155    populateOrigins: function(allowedDict, blockedDict, isGloballyEnabled) {
156      this.populateOriginsHelper_(this.allowedList_, allowedDict);
157      if (blockedDict) {
158        this.populateOriginsHelper_(this.blockedList_, blockedDict);
159        this.blockedList_.hidden = false;
160        $('blocked-origin-list-title').hidden = false;
161        this.allowedList_.classList.remove('nonsplit-origin-list');
162      } else {
163        this.blockedList_.hidden = true;
164        $('blocked-origin-list-title').hidden = true;
165        $('allowed-origin-list-title').hidden = true;
166        this.allowedList_.classList.add('nonsplit-origin-list');
167      }
168      $('global-setting-toggle').checked = isGloballyEnabled;
169    },
170
171    /**
172     * Update the table with the origins filtered by the value in the search
173     * box.
174     * @private
175     */
176    searchOrigins: function() {
177      var filter = $('website-settings-search-box').value;
178      chrome.send('updateOriginsSearchResults', [filter]);
179    },
180
181    /**
182     * Handle and delay search query changes.
183     * @param {!Event} e The event object.
184     * @private
185     */
186    handleSearchQueryChange_: function(e) {
187      if (this.queryDelayTimerId_)
188        window.clearTimeout(this.queryDelayTimerId_);
189
190      this.queryDelayTimerId_ = window.setTimeout(this.searchOrigins.bind(this),
191                                                  160);
192    },
193
194    /**
195     * Sets the default content setting dropdown on the page to the current
196     * default.
197     * @param {!Object} dict A dictionary with the management and value of the
198     *     default setting for the last selected content setting..
199     */
200    updateDefault: function(dict) {
201      // TODO(dhnishi): Remove duplicate default handling in the Content
202      //     Settings page and here.
203      var managedBy = dict.managedBy;
204      var controlledBy = managedBy == 'policy' || managedBy == 'extension' ?
205                managedBy : null;
206      $('global-setting').disabled = (managedBy != 'default');
207
208      var options = $('global-setting').options;
209      for (var i = 0; i < options.length; i++) {
210        if (options[i].value == dict.value) {
211          options.selectedIndex = i;
212        }
213      }
214    },
215
216    /**
217     * Updates the page with the given content setting or resource name's
218     * information.
219     * @param {string} typeName The name of the content setting or resource.
220     */
221    updatePage_: function(typeName) {
222      if (typeName == 'storage')
223        chrome.send('updateLocalStorage');
224      else if (typeName == 'battery')
225        chrome.send('updateBatteryUsage');
226      else
227        chrome.send('updateOrigins', [typeName]);
228
229      var options = $('global-setting').options;
230      options.length = 0;
231      var permissionString = permissionsLookup[typeName];
232      var permissions = ['Allow', 'Ask', 'Block'];
233      for (var i = 0; i < permissions.length; i++) {
234        var valueId = permissionString + permissions[i];
235        if (loadTimeData.valueExists(valueId)) {
236          options.add(new Option(loadTimeData.getString(valueId),
237              permissions[i].toLowerCase()));
238        }
239      }
240      if (options.length == 0) {
241        $('website-settings-global-controls').hidden = true;
242      } else {
243        $('website-settings-global-controls').hidden = false;
244        chrome.send('updateDefaultSetting');
245      }
246
247      $('website-settings-title').textContent =
248          loadTimeData.getString(permissionString + 'TabLabel');
249    }
250  };
251
252  WebsiteSettingsManager.populateOrigins = function(allowedDict, blockedDict,
253      isGloballyEnabled) {
254    WebsiteSettingsManager.getInstance().populateOrigins(allowedDict,
255        blockedDict, isGloballyEnabled);
256  };
257
258  WebsiteSettingsManager.updateDefault = function(dict) {
259    WebsiteSettingsManager.getInstance().updateDefault(dict);
260  };
261
262  WebsiteSettingsManager.showWebsiteSettings = function(hash) {
263    PageManager.showPageByName('websiteSettings', true, {hash: '#' + hash});
264  };
265
266  // Export
267  return {
268    WebsiteSettingsManager: WebsiteSettingsManager
269  };
270});
271