OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 }); |
OLD | NEW |