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

Unified Diff: chrome/browser/resources/options/controlled_setting.js

Issue 10907148: Implement popup bubbles for the controlled setting indicator (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comment addressed. Created 8 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/options/controlled_setting.js
diff --git a/chrome/browser/resources/options/controlled_setting.js b/chrome/browser/resources/options/controlled_setting.js
index 06bed391123266f0511a6779b7cb938e7fe87894..11f3b49ca19a589b757cf9beddb2713c691eabde 100644
--- a/chrome/browser/resources/options/controlled_setting.js
+++ b/chrome/browser/resources/options/controlled_setting.js
@@ -22,44 +22,24 @@ cr.define('options', function() {
*/
decorate: function() {
var self = this;
- var doc = self.ownerDocument;
-
- // Create the details and summary elements.
- var detailsContainer = doc.createElement('details');
- detailsContainer.appendChild(doc.createElement('summary'));
-
- // This should really create a div element, but that breaks :hover. See
- // https://bugs.webkit.org/show_bug.cgi?id=72957
- var bubbleContainer = doc.createElement('p');
- bubbleContainer.className = 'controlled-setting-bubble';
- detailsContainer.appendChild(bubbleContainer);
-
- self.appendChild(detailsContainer);
- self.addEventListener('click', self.show_);
// If there is a pref, track its controlledBy property in order to be able
// to bring up the correct bubble.
- if (this.hasAttribute('pref')) {
- Preferences.getInstance().addEventListener(
- this.getAttribute('pref'),
+ if (this.pref) {
+ Preferences.getInstance().addEventListener(this.pref,
function(event) {
- if (event.value) {
- var controlledBy = event.value.controlledBy;
- self.controlledBy = controlledBy ? controlledBy : null;
- }
+ var controlledBy = event.value.controlledBy;
+ self.controlledBy = controlledBy ? controlledBy : null;
+ OptionsPage.hideBubble();
});
-
- self.resetHandler(self.clearAssociatedPref_);
+ this.resetHandler = this.clearAssociatedPref_;
}
- },
-
- /**
- * Closes the bubble.
- */
- close: function() {
- this.querySelector('details').removeAttribute('open');
- this.ownerDocument.removeEventListener('click', this.closeHandler_, true);
+ this.tabIndex = 0;
+ this.setAttribute('role', 'button');
+ this.addEventListener('click', this);
+ this.addEventListener('keydown', this);
+ this.addEventListener('mousedown', this);
},
/**
@@ -76,86 +56,129 @@ cr.define('options', function() {
* @private
*/
clearAssociatedPref_: function() {
- Preferences.clearPref(this.getAttribute('pref'), this.dialogPref);
+ Preferences.clearPref(this.pref, this.dialogPref);
},
/**
- * Constructs the bubble DOM tree and shows it.
- * @private
+ * Handle mouse and keyboard events, allowing the user to open and close a
+ * bubble with further information.
+ * @param {Event} event Mouse or keyboard event.
*/
- show_: function() {
- var self = this;
- var doc = self.ownerDocument;
-
- // Clear out the old bubble contents.
- var bubbleContainer = this.querySelector('.controlled-setting-bubble');
- if (bubbleContainer) {
- while (bubbleContainer.hasChildNodes())
- bubbleContainer.removeChild(bubbleContainer.lastChild);
+ handleEvent: function(event) {
+ switch (event.type) {
+ // Toggle the bubble on left click. Let any other clicks propagate.
+ case 'click':
+ if (event.button != 0)
+ return;
+ break;
+ // Toggle the bubble when <Return> or <Space> is pressed. Let any other
+ // key presses propagate.
+ case 'keydown':
+ switch (event.keyCode) {
+ case 13: // Return.
+ case 32: // Space.
+ break;
+ default:
+ return;
+ }
+ break;
+ // Blur focus when a mouse button is pressed, matching the behavior of
+ // other Web UI elements.
+ case 'mousedown':
+ if (document.activeElement)
+ document.activeElement.blur();
+ event.preventDefault();
+ return;
}
+ this.toggleBubble_();
+ event.preventDefault();
+ event.stopPropagation();
+ },
- // Work out the bubble text.
- defaultStrings = {
- policy: loadTimeData.getString('controlledSettingPolicy'),
- extension: loadTimeData.getString('controlledSettingExtension'),
- recommended: loadTimeData.getString('controlledSettingRecommended'),
- };
-
- // No controller, no bubble.
- if (!self.controlledBy || !self.controlledBy in defaultStrings)
- return;
-
- var text = defaultStrings[self.controlledBy];
-
- // Apply text overrides.
- if (self.hasAttribute('text' + self.controlledBy))
- text = self.getAttribute('text' + self.controlledBy);
-
- // Create the DOM tree.
- var bubbleText = doc.createElement('p');
- bubbleText.className = 'controlled-setting-bubble-text';
- bubbleText.textContent = text;
-
- if (self.controlledBy == 'recommended' && self.resetHandler_) {
- var container = doc.createElement('div');
- var action = doc.createElement('button');
- action.classList.add('link-button');
- action.classList.add('controlled-setting-bubble-action');
- action.textContent =
- loadTimeData.getString('controlledSettingApplyRecommendation');
- action.addEventListener(
- 'click',
- function(event) { self.resetHandler_(); });
- container.appendChild(action);
- bubbleText.appendChild(container);
+ /**
+ * Open or close a bubble with further information about the pref.
+ * @private
+ */
+ toggleBubble_: function() {
+ if (this.isShowingBubble) {
+ OptionsPage.hideBubble();
+ } else {
+ var self = this;
+
+ // Work out the popup text.
+ defaultStrings = {
+ policy: loadTimeData.getString('controlledSettingPolicy'),
Evan Stade 2012/09/21 12:12:11 better to write the key in quotes.
bartfab (slow) 2012/09/24 17:15:55 Done.
+ extension: loadTimeData.getString('controlledSettingExtension'),
+ recommended: loadTimeData.getString('controlledSettingRecommended'),
+ };
+
+ // No controller, no popup.
+ if (!this.controlledBy || !this.controlledBy in defaultStrings)
Evan Stade 2012/09/21 12:12:11 ! is evaluated before in. This is asking if false
bartfab (slow) 2012/09/24 17:15:55 Done.
+ return;
+
+ var text = defaultStrings[this.controlledBy];
+
+ // Apply text overrides.
+ if (this.hasAttribute('text' + this.controlledBy))
+ text = this.getAttribute('text' + this.controlledBy);
+
+ // Create the DOM tree.
+ var content = document.createElement('div');
+ content.className = 'controlled-setting-bubble-content';
+ content.setAttribute('controlled-by', this.controlledBy);
+ content.textContent = text;
+
+ var action = null;
Evan Stade 2012/09/21 12:12:11 why is this declared out here
bartfab (slow) 2012/09/24 17:15:55 A leftover. Removed now.
+ if (this.controlledBy == 'recommended' && this.resetHandler_) {
+ var container = document.createElement('div');
+ action = document.createElement('button');
+ action.classList.add('link-button');
+ action.classList.add('controlled-setting-bubble-action');
+ action.textContent =
+ loadTimeData.getString('controlledSettingApplyRecommendation');
+ action.addEventListener('click', function(event) {
+ self.resetHandler_();
+ });
+ container.appendChild(action);
+ content.appendChild(container);
+ }
+
+ OptionsPage.showBubble(content, this);
}
-
- bubbleContainer.appendChild(bubbleText);
-
- // One-time bubble-closing event handler.
- self.closeHandler_ = this.close.bind(this);
- doc.addEventListener('click', self.closeHandler_, true);
- }
+ },
};
/**
- * The controlling entity of the setting. Can take the values "policy",
- * "extension", "recommended" or be unset.
+ * The name of the associated preference.
+ * @type {string}
*/
- cr.defineProperty(ControlledSettingIndicator, 'controlledBy',
- cr.PropertyKind.ATTR,
- ControlledSettingIndicator.prototype.close);
+ cr.defineProperty(ControlledSettingIndicator, 'pref', cr.PropertyKind.ATTR);
/**
- * A special preference type specific to dialogs. Changes take effect in the
- * settings UI immediately but are only actually committed when the user
- * confirms the dialog. If the user cancels the dialog instead, the changes
- * are rolled back in the settings UI and never committed.
+ * Whether this indicator is part of a dialog. If so, changes made to the
+ * associated preference take effect in the settings UI immediately but are
+ * only actually committed when the user confirms the dialog. If the user
+ * cancels the dialog instead, the changes are rolled back in the settings UI
+ * and never committed.
* @type {boolean}
*/
cr.defineProperty(ControlledSettingIndicator, 'dialogPref',
cr.PropertyKind.BOOL_ATTR);
+ /**
+ * Whether the associated preference is controlled by a source other than the
+ * user's setting (can be 'policy', 'extension', 'recommended' or unset).
+ * @type {string}
+ */
+ cr.defineProperty(ControlledSettingIndicator, 'controlledBy',
+ cr.PropertyKind.ATTR);
+
+ /**
+ * Whether the indicator is currently showing a bubble.
+ */
+ cr.defineProperty(ControlledSettingIndicator, 'isShowingBubble',
Evan Stade 2012/09/21 12:12:11 nit: I think the 'is' is superfluous. I also thin
bartfab (slow) 2012/09/24 17:15:55 Done.
+ cr.PropertyKind.BOOL_ATTR);
+
// Export.
return {
ControlledSettingIndicator: ControlledSettingIndicator

Powered by Google App Engine
This is Rietveld 408576698