- add sources.
[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         this.controlledBy =
62             !this.value || String(event.value.value) == this.value ?
63             event.value.controlledBy : null;
64       } else if (event.value.recommendedValue != undefined) {
65         this.controlledBy =
66             !this.value || String(event.value.recommendedValue) == this.value ?
67             'hasRecommendation' : null;
68       } else {
69         this.controlledBy = null;
70       }
71     },
72
73     /**
74      * Open or close a bubble with further information about the pref.
75      * @private
76      */
77     toggleBubble_: function() {
78       if (this.showingBubble) {
79         OptionsPage.hideBubble();
80       } else {
81         var self = this;
82
83         // Construct the bubble text.
84         if (this.hasAttribute('plural')) {
85           var defaultStrings = {
86             'policy': loadTimeData.getString('controlledSettingsPolicy'),
87             'extension': loadTimeData.getString('controlledSettingsExtension'),
88           };
89         } else {
90           var defaultStrings = {
91             'policy': loadTimeData.getString('controlledSettingPolicy'),
92             'extension': loadTimeData.getString('controlledSettingExtension'),
93             'recommended':
94                 loadTimeData.getString('controlledSettingRecommended'),
95             'hasRecommendation':
96                 loadTimeData.getString('controlledSettingHasRecommendation'),
97           };
98           if (cr.isChromeOS) {
99             defaultStrings.owner =
100                 loadTimeData.getString('controlledSettingOwner');
101           }
102         }
103
104         // No controller, no bubble.
105         if (!this.controlledBy || !(this.controlledBy in defaultStrings))
106           return;
107
108         var text = defaultStrings[this.controlledBy];
109
110         // Apply text overrides.
111         if (this.hasAttribute('text' + this.controlledBy))
112           text = this.getAttribute('text' + this.controlledBy);
113
114         // Create the DOM tree.
115         var content = document.createElement('div');
116         content.className = 'controlled-setting-bubble-content';
117         content.setAttribute('controlled-by', this.controlledBy);
118         content.textContent = text;
119
120         if (this.controlledBy == 'hasRecommendation' && this.resetHandler_ &&
121             !this.readOnly) {
122           var container = document.createElement('div');
123           var action = document.createElement('button');
124           action.classList.add('link-button');
125           action.classList.add('controlled-setting-bubble-action');
126           action.textContent =
127               loadTimeData.getString('controlledSettingFollowRecommendation');
128           action.addEventListener('click', function(event) {
129             self.resetHandler_();
130           });
131           container.appendChild(action);
132           content.appendChild(container);
133         }
134
135         OptionsPage.showBubble(content, this.image, this, this.location);
136       }
137     },
138   };
139
140   /**
141    * The name of the associated preference.
142    * @type {string}
143    */
144   cr.defineProperty(ControlledSettingIndicator, 'pref', cr.PropertyKind.ATTR);
145
146   /**
147    * Whether this indicator is part of a dialog. If so, changes made to the
148    * associated preference take effect in the settings UI immediately but are
149    * only actually committed when the user confirms the dialog. If the user
150    * cancels the dialog instead, the changes are rolled back in the settings UI
151    * and never committed.
152    * @type {boolean}
153    */
154   cr.defineProperty(ControlledSettingIndicator, 'dialogPref',
155                     cr.PropertyKind.BOOL_ATTR);
156
157   /**
158    * The value of the associated preference that the indicator represents. If
159    * this is not set, the indicator will be visible whenever any value is
160    * enforced or recommended. If it is set, the indicator will be visible only
161    * when the enforced or recommended value matches the value it represents.
162    * This allows multiple indicators to be created for a set of radio buttons,
163    * ensuring that only one of them is visible at a time.
164    */
165   cr.defineProperty(ControlledSettingIndicator, 'value',
166                     cr.PropertyKind.ATTR);
167
168   /**
169    * The status of the associated preference:
170    * - 'policy':            A specific value is enfoced by policy.
171    * - 'extension':         A specific value is enforced by an extension.
172    * - 'recommended':       A value is recommended by policy. The user could
173    *                        override this recommendation but has not done so.
174    * - 'hasRecommendation': A value is recommended by policy. The user has
175    *                        overridden this recommendation.
176    * - unset:               The value is controlled by the user alone.
177    * @type {string}
178    */
179   cr.defineProperty(ControlledSettingIndicator, 'controlledBy',
180                     cr.PropertyKind.ATTR);
181
182   // Export.
183   return {
184     ControlledSettingIndicator: ControlledSettingIndicator
185   };
186 });