Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: chrome/browser/resources/options/controlled_setting.js

Issue 11066015: Finish implementation of controlled setting indicator (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 cr.define('options', function() { 5 cr.define('options', function() {
6 var Preferences = options.Preferences; 6 var Preferences = options.Preferences;
7 7
8 /** 8 /**
9 * A controlled setting indicator that can be placed on a setting as an 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 10 * indicator that the value is controlled by some external entity such as
11 * policy or an extension. 11 * policy or an extension.
12 * @constructor 12 * @constructor
13 * @extends {HTMLSpanElement} 13 * @extends {HTMLSpanElement}
14 */ 14 */
15 var ControlledSettingIndicator = cr.ui.define('span'); 15 var ControlledSettingIndicator = cr.ui.define('span');
16 16
17 ControlledSettingIndicator.prototype = { 17 ControlledSettingIndicator.prototype = {
18 __proto__: HTMLSpanElement.prototype, 18 __proto__: HTMLSpanElement.prototype,
19 19
20 /** 20 /**
21 * Decorates the base element to show the proper icon. 21 * Decorates the base element to show the proper icon.
22 */ 22 */
23 decorate: function() { 23 decorate: function() {
24 var self = this; 24 var self = this;
25 25
26 // If there is a pref, track its controlledBy property in order to be able 26 // If there is a pref, track its controlledBy and recommendedValue
27 // to bring up the correct bubble. 27 // properties in order to be able to bring up the correct bubble.
28 if (this.pref) { 28 if (this.pref) {
29 Preferences.getInstance().addEventListener(this.pref, 29 Preferences.getInstance().addEventListener(
30 function(event) { 30 this.pref, this.handlePrefChange.bind(this));
31 var controlledBy = event.value.controlledBy;
32 self.controlledBy = controlledBy ? controlledBy : null;
33 OptionsPage.hideBubble();
34 });
35 this.resetHandler = this.clearAssociatedPref_; 31 this.resetHandler = this.clearAssociatedPref_;
36 } 32 }
37 33
38 this.tabIndex = 0; 34 this.tabIndex = 0;
39 this.setAttribute('role', 'button'); 35 this.setAttribute('role', 'button');
40 this.addEventListener('click', this); 36 this.addEventListener('click', this);
41 this.addEventListener('keydown', this); 37 this.addEventListener('keydown', this);
42 this.addEventListener('mousedown', this); 38 this.addEventListener('mousedown', this);
43 }, 39 },
44 40
45 /** 41 /**
46 * The given handler will be called when the user clicks on the 'reset to 42 * The given handler will be called when the user clicks on the 'reset to
47 * recommended value' link shown in the indicator bubble. 43 * recommended value' link shown in the indicator bubble.
48 * @param {function()} handler The handler to be called. 44 * @param {function()} handler The handler to be called.
49 */ 45 */
50 set resetHandler(handler) { 46 set resetHandler(handler) {
pneubeck (no reviews) 2012/10/04 18:56:11 Please make it clear in the comment with which 'th
bartfab (slow) 2012/10/04 19:17:15 Done.
51 this.resetHandler_ = handler; 47 this.resetHandler_ = handler;
52 }, 48 },
53 49
54 /** 50 /**
55 * Whether the indicator is currently showing a bubble. 51 * Whether the indicator is currently showing a bubble.
56 * @type {boolean} 52 * @type {boolean}
57 */ 53 */
58 get showingBubble() { 54 get showingBubble() {
59 return !!this.showingBubble_; 55 return !!this.showingBubble_;
60 }, 56 },
61 set showingBubble(showing) { 57 set showingBubble(showing) {
62 if (showing) 58 if (showing)
63 this.classList.add('showing-bubble'); 59 this.classList.add('showing-bubble');
64 else 60 else
65 this.classList.remove('showing-bubble'); 61 this.classList.remove('showing-bubble');
66 this.showingBubble_ = showing; 62 this.showingBubble_ = showing;
67 }, 63 },
68 64
69 /** 65 /**
70 * Clears the preference associated with this indicator. 66 * Clears the preference associated with this indicator.
71 * @private 67 * @private
72 */ 68 */
73 clearAssociatedPref_: function() { 69 clearAssociatedPref_: function() {
74 Preferences.clearPref(this.pref, this.dialogPref); 70 Preferences.clearPref(this.pref, !this.dialogPref);
71 },
72
73 /* Handle changes to the associated pref by hiding any currently visible
74 * bubble and updating the controlledBy property.
75 * @param {Event} event Pref change event.
76 */
77 handlePrefChange: function(event) {
78 OptionsPage.hideBubble();
79 if (this.type == 'radio') {
80 if (event.value.controlledBy) {
81 this.controlledBy = String(event.value.value) == this.value ?
82 event.value.controlledBy : null;
83 } else if (event.value.recommendedValue != undefined) {
84 this.controlledBy =
85 String(event.value.recommendedValue) == this.value ?
86 'hasRecommendation' : null;
87 } else {
88 this.controlledBy = null;
89 }
90 } else {
91 if (event.value.controlledBy)
92 this.controlledBy = event.value.controlledBy;
93 else if (event.value.recommendedValue != undefined)
94 this.controlledBy = 'hasRecommendation';
95 else
96 this.controlledBy = null;
97 }
75 }, 98 },
76 99
77 /** 100 /**
78 * Handle mouse and keyboard events, allowing the user to open and close a 101 * Handle mouse and keyboard events, allowing the user to open and close a
79 * bubble with further information. 102 * bubble with further information.
80 * @param {Event} event Mouse or keyboard event. 103 * @param {Event} event Mouse or keyboard event.
81 */ 104 */
82 handleEvent: function(event) { 105 handleEvent: function(event) {
83 switch (event.type) { 106 switch (event.type) {
84 // Toggle the bubble on left click. Let any other clicks propagate. 107 // Toggle the bubble on left click. Let any other clicks propagate.
(...skipping 28 matching lines...) Expand all
113 /** 136 /**
114 * Open or close a bubble with further information about the pref. 137 * Open or close a bubble with further information about the pref.
115 * @private 138 * @private
116 */ 139 */
117 toggleBubble_: function() { 140 toggleBubble_: function() {
118 if (this.showingBubble) { 141 if (this.showingBubble) {
119 OptionsPage.hideBubble(); 142 OptionsPage.hideBubble();
120 } else { 143 } else {
121 var self = this; 144 var self = this;
122 145
123 // Work out the popup text. 146 // Work out the bubble text.
James Hawkins 2012/10/04 16:16:51 Can we change the wording from "Work out" to, say,
bartfab (slow) 2012/10/04 18:55:39 Done.
124 defaultStrings = { 147 defaultStrings = {
125 'policy': loadTimeData.getString('controlledSettingPolicy'), 148 'policy': loadTimeData.getString('controlledSettingPolicy'),
126 'extension': loadTimeData.getString('controlledSettingExtension'), 149 'extension': loadTimeData.getString('controlledSettingExtension'),
127 'recommended': loadTimeData.getString('controlledSettingRecommended'), 150 'recommended': loadTimeData.getString('controlledSettingRecommended'),
151 'hasRecommendation':
152 loadTimeData.getString('controlledSettingHasRecommendation'),
128 }; 153 };
129 154
130 // No controller, no popup. 155 // No controller, no popup.
pneubeck (no reviews) 2012/10/04 18:56:11 Nit: bubble
bartfab (slow) 2012/10/04 19:17:15 Done.
131 if (!this.controlledBy || !(this.controlledBy in defaultStrings)) 156 if (!this.controlledBy || !(this.controlledBy in defaultStrings))
132 return; 157 return;
133 158
134 var text = defaultStrings[this.controlledBy]; 159 var text = defaultStrings[this.controlledBy];
135 160
136 // Apply text overrides. 161 // Apply text overrides.
137 if (this.hasAttribute('text' + this.controlledBy)) 162 if (this.hasAttribute('text' + this.controlledBy))
138 text = this.getAttribute('text' + this.controlledBy); 163 text = this.getAttribute('text' + this.controlledBy);
139 164
140 // Create the DOM tree. 165 // Create the DOM tree.
pneubeck (no reviews) 2012/10/04 18:56:11 In general, instead of generating a DOM tree, I wo
bartfab (slow) 2012/10/04 19:17:15 Yes, this would be cleaner. I discussed this kind
141 var content = document.createElement('div'); 166 var content = document.createElement('div');
142 content.className = 'controlled-setting-bubble-content'; 167 content.className = 'controlled-setting-bubble-content';
143 content.setAttribute('controlled-by', this.controlledBy); 168 content.setAttribute('controlled-by', this.controlledBy);
144 content.textContent = text; 169 content.textContent = text;
145 170
146 if (this.controlledBy == 'recommended' && this.resetHandler_) { 171 if (this.controlledBy == 'hasRecommendation' && this.resetHandler_ &&
172 !this.readOnly) {
147 var container = document.createElement('div'); 173 var container = document.createElement('div');
148 var action = document.createElement('button'); 174 var action = document.createElement('button');
149 action.classList.add('link-button'); 175 action.classList.add('link-button');
150 action.classList.add('controlled-setting-bubble-action'); 176 action.classList.add('controlled-setting-bubble-action');
151 action.textContent = 177 action.textContent =
152 loadTimeData.getString('controlledSettingApplyRecommendation'); 178 loadTimeData.getString('controlledSettingFollowRecommendation');
153 action.addEventListener('click', function(event) { 179 action.addEventListener('click', function(event) {
154 self.resetHandler_(); 180 self.resetHandler_();
155 }); 181 });
156 container.appendChild(action); 182 container.appendChild(action);
157 content.appendChild(container); 183 content.appendChild(container);
158 } 184 }
159 185
160 OptionsPage.showBubble(content, this); 186 OptionsPage.showBubble(content, this);
161 } 187 }
162 }, 188 },
(...skipping 10 matching lines...) Expand all
173 * associated preference take effect in the settings UI immediately but are 199 * associated preference take effect in the settings UI immediately but are
174 * only actually committed when the user confirms the dialog. If the user 200 * only actually committed when the user confirms the dialog. If the user
175 * cancels the dialog instead, the changes are rolled back in the settings UI 201 * cancels the dialog instead, the changes are rolled back in the settings UI
176 * and never committed. 202 * and never committed.
177 * @type {boolean} 203 * @type {boolean}
178 */ 204 */
179 cr.defineProperty(ControlledSettingIndicator, 'dialogPref', 205 cr.defineProperty(ControlledSettingIndicator, 'dialogPref',
180 cr.PropertyKind.BOOL_ATTR); 206 cr.PropertyKind.BOOL_ATTR);
181 207
182 /** 208 /**
183 * Whether the associated preference is controlled by a source other than the 209 * The kind of input element that this indicator refers to.
James Hawkins 2012/10/04 16:16:51 I think we need to make this more coupled to the e
bartfab (slow) 2012/10/04 18:55:39 I discussed this with Philipp at length. We think
pneubeck (no reviews) 2012/10/04 18:56:11 For comparison, I like the alternative in the oppo
184 * user's setting (can be 'policy', 'extension', 'recommended' or unset). 210 * @type {string}
211 */
212 cr.defineProperty(ControlledSettingIndicator, 'type',
213 cr.PropertyKind.ATTR);
214
215 /**
216 * If this indicator refers to a radio button, the value of the associated
217 * preference that the radio button represents.
218 * @type {string}
219 */
220 cr.defineProperty(ControlledSettingIndicator, 'value',
221 cr.PropertyKind.ATTR);
222
223 /**
224 * The status of the associated preference:
225 * - 'policy': A specific value is enfoced by policy.
226 * - 'extension': A specific value is enforced by an extension.
227 * - 'recommended': A value is recommended by policy. The user could
228 * override this recommendation but has not done so.
229 * - 'hasRecommendation': A value is recommended by policy. The user has
230 * overridden this recommendation.
231 * - unset: The value is controlled by the user alone.
185 * @type {string} 232 * @type {string}
186 */ 233 */
187 cr.defineProperty(ControlledSettingIndicator, 'controlledBy', 234 cr.defineProperty(ControlledSettingIndicator, 'controlledBy',
188 cr.PropertyKind.ATTR); 235 cr.PropertyKind.ATTR);
189 236
190 // Export. 237 // Export.
191 return { 238 return {
192 ControlledSettingIndicator: ControlledSettingIndicator 239 ControlledSettingIndicator: ControlledSettingIndicator
193 }; 240 };
194 }); 241 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698