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.
5 cr
.define('options', function() {
6 var Preferences
= options
.Preferences
;
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.
13 * @extends {cr.ui.BubbleButton}
15 var ControlledSettingIndicator
= cr
.ui
.define('span');
17 ControlledSettingIndicator
.prototype = {
18 __proto__
: cr
.ui
.BubbleButton
.prototype,
21 * Decorates the base element to show the proper icon.
23 decorate: function() {
24 cr
.ui
.BubbleButton
.prototype.decorate
.call(this);
25 this.classList
.add('controlled-setting-indicator');
27 // If there is a pref, track its controlledBy and recommendedValue
28 // properties in order to be able to bring up the correct bubble.
30 Preferences
.getInstance().addEventListener(
31 this.pref
, this.handlePrefChange
.bind(this));
32 this.resetHandler
= this.clearAssociatedPref_
;
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.
42 set resetHandler(handler
) {
43 this.resetHandler_
= handler
;
47 * Clears the preference associated with this indicator.
50 clearAssociatedPref_: function() {
51 Preferences
.clearPref(this.pref
, !this.dialogPref
);
55 * Handle changes to the associated pref by hiding any currently visible
56 * bubble and updating the controlledBy property.
57 * @param {Event} event Pref change event.
59 handlePrefChange: function(event
) {
60 PageManager
.hideBubble();
61 if (event
.value
.controlledBy
) {
62 if (!this.value
|| String(event
.value
.value
) == this.value
) {
63 this.controlledBy
= event
.value
.controlledBy
;
64 if (event
.value
.extension
) {
65 this.extensionId
= event
.value
.extension
.id
;
66 this.extensionIcon
= event
.value
.extension
.icon
;
67 this.extensionName
= event
.value
.extension
.name
;
70 this.controlledBy
= null;
72 } else if (event
.value
.recommendedValue
!= undefined) {
74 !this.value
|| String(event
.value
.recommendedValue
) == this.value
?
75 'hasRecommendation' : null;
77 this.controlledBy
= null;
82 * Open or close a bubble with further information about the pref.
85 toggleBubble: function() {
86 if (this.showingBubble
) {
87 PageManager
.hideBubble();
91 // Construct the bubble text.
92 if (this.hasAttribute('plural')) {
93 var defaultStrings
= {
94 'policy': loadTimeData
.getString('controlledSettingsPolicy'),
95 'extension': loadTimeData
.getString('controlledSettingsExtension'),
96 'extensionWithName': loadTimeData
.getString(
97 'controlledSettingsExtensionWithName'),
100 defaultStrings
.shared
=
101 loadTimeData
.getString('controlledSettingsShared');
104 var defaultStrings
= {
105 'policy': loadTimeData
.getString('controlledSettingPolicy'),
106 'extension': loadTimeData
.getString('controlledSettingExtension'),
107 'extensionWithName': loadTimeData
.getString(
108 'controlledSettingExtensionWithName'),
110 loadTimeData
.getString('controlledSettingRecommended'),
112 loadTimeData
.getString('controlledSettingHasRecommendation'),
115 defaultStrings
.owner
=
116 loadTimeData
.getString('controlledSettingOwner');
117 defaultStrings
.shared
=
118 loadTimeData
.getString('controlledSettingShared');
122 // No controller, no bubble.
123 if (!this.controlledBy
|| !(this.controlledBy
in defaultStrings
))
126 var text
= defaultStrings
[this.controlledBy
];
127 if (this.controlledBy
== 'extension' && this.extensionName
)
128 text
= defaultStrings
.extensionWithName
;
130 // Apply text overrides.
131 if (this.hasAttribute('text' + this.controlledBy
))
132 text
= this.getAttribute('text' + this.controlledBy
);
134 // Create the DOM tree.
135 var content
= document
.createElement('div');
136 content
.classList
.add('controlled-setting-bubble-header');
137 content
.textContent
= text
;
139 if (this.controlledBy
== 'hasRecommendation' && this.resetHandler_
&&
141 var container
= document
.createElement('div');
142 var action
= document
.createElement('button');
143 action
.classList
.add('link-button');
144 action
.classList
.add('controlled-setting-bubble-action');
146 loadTimeData
.getString('controlledSettingFollowRecommendation');
147 action
.addEventListener('click', function(event
) {
148 self
.resetHandler_();
150 container
.appendChild(action
);
151 content
.appendChild(container
);
152 } else if (this.controlledBy
== 'extension' && this.extensionName
) {
153 var extensionContainer
=
154 $('extension-controlled-settings-bubble-template').
156 // No need for an id anymore, and thus remove to avoid id collision.
157 extensionContainer
.removeAttribute('id');
158 extensionContainer
.hidden
= false;
160 var extensionName
= extensionContainer
.querySelector(
161 '.controlled-setting-bubble-extension-name');
162 extensionName
.textContent
= this.extensionName
;
163 extensionName
.style
.backgroundImage
=
164 'url("' + this.extensionIcon
+ '")';
166 var manageLink
= extensionContainer
.querySelector(
167 '.controlled-setting-bubble-extension-manage-link');
168 var extensionId
= this.extensionId
;
169 manageLink
.onclick = function() {
170 uber
.invokeMethodOnWindow(
171 window
.top
, 'showPage', {pageId
: 'extensions',
172 path
: '?id=' + extensionId
});
175 var disableButton
= extensionContainer
.querySelector(
176 '.controlled-setting-bubble-extension-disable-button');
177 disableButton
.onclick = function() {
178 chrome
.send('disableExtension', [extensionId
]);
180 content
.appendChild(extensionContainer
);
183 PageManager
.showBubble(content
, this.image
, this, this.location
);
189 * The name of the associated preference.
191 cr
.defineProperty(ControlledSettingIndicator
, 'pref', cr
.PropertyKind
.ATTR
);
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.
200 cr
.defineProperty(ControlledSettingIndicator
, 'dialogPref',
201 cr
.PropertyKind
.BOOL_ATTR
);
204 * The value of the associated preference that the indicator represents. If
205 * this is not set, the indicator will be visible whenever any value is
206 * enforced or recommended. If it is set, the indicator will be visible only
207 * when the enforced or recommended value matches the value it represents.
208 * This allows multiple indicators to be created for a set of radio buttons,
209 * ensuring that only one of them is visible at a time.
211 cr
.defineProperty(ControlledSettingIndicator
, 'value',
212 cr
.PropertyKind
.ATTR
);
215 * The status of the associated preference:
216 * - 'policy': A specific value is enforced by policy.
217 * - 'extension': A specific value is enforced by an extension.
218 * - 'recommended': A value is recommended by policy. The user could
219 * override this recommendation but has not done so.
220 * - 'hasRecommendation': A value is recommended by policy. The user has
221 * overridden this recommendation.
222 * - 'owner': A value is controlled by the owner of the device
224 * - 'shared': A value belongs to the primary user but can be
225 * modified (Chrome OS only).
226 * - unset: The value is controlled by the user alone.
228 cr
.defineProperty(ControlledSettingIndicator
, 'controlledBy',
229 cr
.PropertyKind
.ATTR
);
233 ControlledSettingIndicator
: ControlledSettingIndicator