Upstream version 7.35.139.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / resources / options / controlled_setting.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.define('options', function() {
6   var Preferences = options.Preferences;
7
8   /**
9    * A controlled setting indicator that can be placed on a setting as an
10    * indicator that the value is controlled by some external entity such as
11    * policy or an extension.
12    * @constructor
13    * @extends {HTMLSpanElement}
14    */
15   var ControlledSettingIndicator = cr.ui.define('span');
16
17   ControlledSettingIndicator.prototype = {
18     __proto__: cr.ui.BubbleButton.prototype,
19
20     /**
21      * Decorates the base element to show the proper icon.
22      */
23     decorate: function() {
24       cr.ui.BubbleButton.prototype.decorate.call(this);
25       this.classList.add('controlled-setting-indicator');
26
27       // If there is a pref, track its controlledBy and recommendedValue
28       // properties in order to be able to bring up the correct bubble.
29       if (this.pref) {
30         Preferences.getInstance().addEventListener(
31             this.pref, this.handlePrefChange.bind(this));
32         this.resetHandler = this.clearAssociatedPref_;
33       }
34     },
35
36     /**
37      * The given handler will be called when the user clicks on the 'reset to
38      * recommended value' link shown in the indicator bubble. The |this| object
39      * will be the indicator itself.
40      * @param {function()} handler The handler to be called.
41      */
42     set resetHandler(handler) {
43       this.resetHandler_ = handler;
44     },
45
46     /**
47      * Clears the preference associated with this indicator.
48      * @private
49      */
50     clearAssociatedPref_: function() {
51       Preferences.clearPref(this.pref, !this.dialogPref);
52     },
53
54     /* Handle changes to the associated pref by hiding any currently visible
55      * bubble and updating the controlledBy property.
56      * @param {Event} event Pref change event.
57      */
58     handlePrefChange: function(event) {
59       OptionsPage.hideBubble();
60       if (event.value.controlledBy) {
61         if (!this.value || String(event.value.value) == this.value) {
62           this.controlledBy = event.value.controlledBy;
63           if (event.value.extension) {
64             this.extensionId = event.value.extension.id;
65             this.extensionIcon = event.value.extension.icon;
66             this.extensionName = event.value.extension.name;
67           }
68         } else {
69           this.controlledBy = null;
70         }
71       } else if (event.value.recommendedValue != undefined) {
72         this.controlledBy =
73             !this.value || String(event.value.recommendedValue) == this.value ?
74             'hasRecommendation' : null;
75       } else {
76         this.controlledBy = null;
77       }
78     },
79
80     /**
81      * Open or close a bubble with further information about the pref.
82      * @private
83      */
84     toggleBubble_: function() {
85       if (this.showingBubble) {
86         OptionsPage.hideBubble();
87       } else {
88         var self = this;
89
90         // Construct the bubble text.
91         if (this.hasAttribute('plural')) {
92           var defaultStrings = {
93             'policy': loadTimeData.getString('controlledSettingsPolicy'),
94             'extension': loadTimeData.getString('controlledSettingsExtension'),
95             'extensionWithName': loadTimeData.getString(
96                 'controlledSettingsExtensionWithName'),
97           };
98           if (cr.isChromeOS) {
99             defaultStrings.shared =
100                 loadTimeData.getString('controlledSettingsShared');
101           }
102         } else {
103           var defaultStrings = {
104             'policy': loadTimeData.getString('controlledSettingPolicy'),
105             'extension': loadTimeData.getString('controlledSettingExtension'),
106             'extensionWithName': loadTimeData.getString(
107                 'controlledSettingExtensionWithName'),
108             'recommended':
109                 loadTimeData.getString('controlledSettingRecommended'),
110             'hasRecommendation':
111                 loadTimeData.getString('controlledSettingHasRecommendation'),
112           };
113           if (cr.isChromeOS) {
114             defaultStrings.owner =
115                 loadTimeData.getString('controlledSettingOwner');
116             defaultStrings.shared =
117                 loadTimeData.getString('controlledSettingShared');
118           }
119         }
120
121         // No controller, no bubble.
122         if (!this.controlledBy || !(this.controlledBy in defaultStrings))
123           return;
124
125         var text = defaultStrings[this.controlledBy];
126         if (this.controlledBy == 'extension' && this.extensionName)
127           text = defaultStrings.extensionWithName;
128
129         // Apply text overrides.
130         if (this.hasAttribute('text' + this.controlledBy))
131           text = this.getAttribute('text' + this.controlledBy);
132
133         // Create the DOM tree.
134         var content = document.createElement('div');
135         content.classList.add('controlled-setting-bubble-header');
136         content.textContent = text;
137
138         if (this.controlledBy == 'hasRecommendation' && this.resetHandler_ &&
139             !this.readOnly) {
140           var container = document.createElement('div');
141           var action = document.createElement('button');
142           action.classList.add('link-button');
143           action.classList.add('controlled-setting-bubble-action');
144           action.textContent =
145               loadTimeData.getString('controlledSettingFollowRecommendation');
146           action.addEventListener('click', function(event) {
147             self.resetHandler_();
148           });
149           container.appendChild(action);
150           content.appendChild(container);
151         } else if (this.controlledBy == 'extension' && this.extensionName) {
152           var extensionContainer =
153               $('extension-controlled-settings-bubble-template').
154                   cloneNode(true);
155           // No need for an id anymore, and thus remove to avoid id collision.
156           extensionContainer.removeAttribute('id');
157           extensionContainer.hidden = false;
158
159           var extensionName = extensionContainer.querySelector(
160               '.controlled-setting-bubble-extension-name');
161           extensionName.textContent = this.extensionName;
162           extensionName.style.backgroundImage =
163               'url("' + this.extensionIcon + '")';
164
165           var manageLink = extensionContainer.querySelector(
166               '.controlled-setting-bubble-extension-manage-link');
167           var extensionId = this.extensionId;
168           manageLink.onclick = function() {
169             uber.invokeMethodOnWindow(
170                 window.top, 'showPage', {pageId: 'extensions',
171                                          path: '?id=' + extensionId});
172           };
173
174           var disableButton = extensionContainer.querySelector(
175               '.controlled-setting-bubble-extension-disable-button');
176           disableButton.onclick = function() {
177             chrome.send('disableExtension', [extensionId]);
178           };
179           content.appendChild(extensionContainer);
180         }
181
182         OptionsPage.showBubble(content, this.image, this, this.location);
183       }
184     },
185   };
186
187   /**
188    * The name of the associated preference.
189    * @type {string}
190    */
191   cr.defineProperty(ControlledSettingIndicator, 'pref', cr.PropertyKind.ATTR);
192
193   /**
194    * Whether this indicator is part of a dialog. If so, changes made to the
195    * associated preference take effect in the settings UI immediately but are
196    * only actually committed when the user confirms the dialog. If the user
197    * cancels the dialog instead, the changes are rolled back in the settings UI
198    * and never committed.
199    * @type {boolean}
200    */
201   cr.defineProperty(ControlledSettingIndicator, 'dialogPref',
202                     cr.PropertyKind.BOOL_ATTR);
203
204   /**
205    * The value of the associated preference that the indicator represents. If
206    * this is not set, the indicator will be visible whenever any value is
207    * enforced or recommended. If it is set, the indicator will be visible only
208    * when the enforced or recommended value matches the value it represents.
209    * This allows multiple indicators to be created for a set of radio buttons,
210    * ensuring that only one of them is visible at a time.
211    */
212   cr.defineProperty(ControlledSettingIndicator, 'value',
213                     cr.PropertyKind.ATTR);
214
215   /**
216    * The status of the associated preference:
217    * - 'policy':            A specific value is enfoced by policy.
218    * - 'extension':         A specific value is enforced by an extension.
219    * - 'recommended':       A value is recommended by policy. The user could
220    *                        override this recommendation but has not done so.
221    * - 'hasRecommendation': A value is recommended by policy. The user has
222    *                        overridden this recommendation.
223    * - 'owner':             A value is controlled by the owner of the device
224    *                        (Chrome OS only).
225    * - 'shared':            A value belongs to the primary user but can be
226    *                        modified (Chrome OS only).
227    * - unset:               The value is controlled by the user alone.
228    * @type {string}
229    */
230   cr.defineProperty(ControlledSettingIndicator, 'controlledBy',
231                     cr.PropertyKind.ATTR);
232
233   // Export.
234   return {
235     ControlledSettingIndicator: ControlledSettingIndicator
236   };
237 });