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 /** @const */ 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.ControlledIndicator}
15 var ControlledSettingIndicator = cr.ui.define('span');
17 ControlledSettingIndicator.prototype = {
18 __proto__: cr.ui.ControlledIndicator.prototype,
21 * Decorates the base element to show the proper icon.
23 decorate: function() {
24 cr.ui.ControlledIndicator.prototype.decorate.call(this);
26 // If there is a pref, track its controlledBy and recommendedValue
27 // properties in order to be able to bring up the correct bubble.
29 Preferences.getInstance().addEventListener(
30 this.pref, this.handlePrefChange.bind(this));
31 this.resetHandler = this.clearAssociatedPref_;
36 * The given handler will be called when the user clicks on the 'reset to
37 * recommended value' link shown in the indicator bubble. The |this| object
38 * will be the indicator itself.
39 * @param {function()} handler The handler to be called.
41 set resetHandler(handler) {
42 this.resetHandler_ = handler;
46 * Clears the preference associated with this indicator.
49 clearAssociatedPref_: function() {
50 Preferences.clearPref(this.pref, !this.dialogPref);
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 * @suppress {checkTypes}
58 * TODO(vitalyp): remove the suppression. |controlledBy| property is defined
59 * by cr.defineProperty(). Currently null can't be assigned to such
60 * properties due to implementation of ChromePass.java. See this discussion
61 * to change nulls to empty string below:
62 * https://chromiumcodereview.appspot.com/11066015/
64 handlePrefChange: function(event) {
65 PageManager.hideBubble();
66 if (event.value.controlledBy) {
67 if (!this.value || String(event.value.value) == this.value) {
68 this.controlledBy = event.value.controlledBy;
69 if (event.value.extension) {
70 this.extensionId = event.value.extension.id;
71 this.extensionIcon = event.value.extension.icon;
72 this.extensionName = event.value.extension.name;
75 this.controlledBy = null;
77 } else if (event.value.recommendedValue != undefined) {
79 !this.value || String(event.value.recommendedValue) == this.value ?
80 'hasRecommendation' : null;
82 this.controlledBy = null;
87 * Uses the page's PageManager to display an informational bubble.
90 showBubble: function(content) {
91 PageManager.showBubble(content, this.image, this, this.location);
95 * Uses the page's PageManager to hide the currently visible bubble, if
99 hideBubble: function() {
100 PageManager.hideBubble();
104 * Queries the |loadTimeData| singleton for the default bubble text strings.
107 getDefaultStrings: function() {
108 // Construct the bubble text.
109 if (this.hasAttribute('plural')) {
110 var defaultStrings = {
111 'policy': loadTimeData.getString('controlledSettingsPolicy'),
112 'extension': loadTimeData.getString('controlledSettingsExtension'),
114 loadTimeData.getString('controlledSettingsExtensionWithName'),
117 defaultStrings.shared =
118 loadTimeData.getString('controlledSettingsShared');
121 var defaultStrings = {
122 'policy': loadTimeData.getString('controlledSettingPolicy'),
123 'extension': loadTimeData.getString('controlledSettingExtension'),
125 loadTimeData.getString('controlledSettingExtensionWithName'),
126 'recommended': loadTimeData.getString('controlledSettingRecommended'),
128 loadTimeData.getString('controlledSettingHasRecommendation'),
131 defaultStrings.owner =
132 loadTimeData.getString('controlledSettingOwner');
133 defaultStrings.shared =
134 loadTimeData.getString('controlledSettingShared');
137 return defaultStrings;
141 * Returns the DOM tree for a showing the message |text|.
142 * @param {string} text to be shown in the bubble.
145 createDomTree: function(text) {
146 var content = document.createElement('div');
147 content.classList.add('controlled-setting-bubble-header');
148 content.textContent = text;
150 if (this.controlledBy == 'hasRecommendation' && this.resetHandler_ &&
152 var container = document.createElement('div');
153 var action = new ActionLink;
154 action.classList.add('controlled-setting-bubble-action');
156 loadTimeData.getString('controlledSettingFollowRecommendation');
157 action.addEventListener('click', this.resetHandler_.bind(this));
158 container.appendChild(action);
159 content.appendChild(container);
160 } else if (this.controlledBy == 'extension' && this.extensionName) {
161 var extensionContainer =
162 $('extension-controlled-settings-bubble-template').cloneNode(true);
163 // No need for an id anymore, and thus remove to avoid id collision.
164 extensionContainer.removeAttribute('id');
165 extensionContainer.hidden = false;
167 var extensionName = extensionContainer.querySelector(
168 '.controlled-setting-bubble-extension-name');
169 extensionName.textContent = this.extensionName;
170 extensionName.style.backgroundImage =
171 'url("' + this.extensionIcon + '")';
173 var manageLink = extensionContainer.querySelector(
174 '.controlled-setting-bubble-extension-manage-link');
175 var extensionId = this.extensionId;
176 manageLink.onclick = function() {
177 uber.invokeMethodOnWindow(
178 window.top, 'showPage',
179 {pageId: 'extensions', path: '?id=' + extensionId});
182 var disableButton = extensionContainer.querySelector(
183 '.controlled-setting-bubble-extension-disable-button');
184 disableButton.onclick =
185 function() { chrome.send('disableExtension', [extensionId]); };
186 content.appendChild(extensionContainer);
193 * The name of the associated preference.
195 cr.defineProperty(ControlledSettingIndicator, 'pref', cr.PropertyKind.ATTR);
198 * Whether this indicator is part of a dialog. If so, changes made to the
199 * associated preference take effect in the settings UI immediately but are
200 * only actually committed when the user confirms the dialog. If the user
201 * cancels the dialog instead, the changes are rolled back in the settings UI
202 * and never committed.
204 cr.defineProperty(ControlledSettingIndicator, 'dialogPref',
205 cr.PropertyKind.BOOL_ATTR);
208 * The value of the associated preference that the indicator represents. If
209 * this is not set, the indicator will be visible whenever any value is
210 * enforced or recommended. If it is set, the indicator will be visible only
211 * when the enforced or recommended value matches the value it represents.
212 * This allows multiple indicators to be created for a set of radio buttons,
213 * ensuring that only one of them is visible at a time.
215 cr.defineProperty(ControlledSettingIndicator, 'value',
216 cr.PropertyKind.ATTR);
220 ControlledSettingIndicator: ControlledSettingIndicator