blob: aa561007f0efdf4664c361eaa76b8f89bfc7f58f [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
cr.define('options', function() {
var Preferences = options.Preferences;
/**
* A controlled setting indicator that can be placed on a setting as an
* indicator that the value is controlled by some external entity such as
* policy or an extension.
* @constructor
* @extends {HTMLSpanElement}
*/
var ControlledSettingIndicator = cr.ui.define('span');
ControlledSettingIndicator.prototype = {
__proto__: HTMLSpanElement.prototype,
/**
* Decorates the base element to show the proper icon.
*/
decorate: function() {
var self = this;
// If there is a pref, track its controlledBy property in order to be able
// to bring up the correct bubble.
if (this.pref) {
Preferences.getInstance().addEventListener(this.pref,
function(event) {
var controlledBy = event.value.controlledBy;
self.controlledBy = controlledBy ? controlledBy : null;
OptionsPage.hideBubble();
});
this.resetHandler = this.clearAssociatedPref_;
}
this.tabIndex = 0;
this.setAttribute('role', 'button');
this.addEventListener('click', this);
this.addEventListener('keydown', this);
this.addEventListener('mousedown', this);
},
/**
* The given handler will be called when the user clicks on the 'reset to
* recommended value' link shown in the indicator bubble.
* @param {function()} handler The handler to be called.
*/
set resetHandler(handler) {
this.resetHandler_ = handler;
},
/**
* Whether the indicator is currently showing a bubble.
* @type {boolean}
*/
get showingBubble() {
return !!this.showingBubble_;
},
set showingBubble(showing) {
if (showing)
this.classList.add('showing-bubble');
else
this.classList.remove('showing-bubble');
this.showingBubble_ = showing;
},
/**
* Clears the preference associated with this indicator.
* @private
*/
clearAssociatedPref_: function() {
Preferences.clearPref(this.pref, this.dialogPref);
},
/**
* Handle mouse and keyboard events, allowing the user to open and close a
* bubble with further information.
* @param {Event} event Mouse or keyboard event.
*/
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();
},
/**
* Open or close a bubble with further information about the pref.
* @private
*/
toggleBubble_: function() {
if (this.showingBubble) {
OptionsPage.hideBubble();
} else {
var self = this;
// Work out the popup text.
defaultStrings = {
'policy': loadTimeData.getString('controlledSettingPolicy'),
'extension': loadTimeData.getString('controlledSettingExtension'),
'recommended': loadTimeData.getString('controlledSettingRecommended'),
};
// No controller, no popup.
if (!this.controlledBy || !(this.controlledBy in defaultStrings))
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;
if (this.controlledBy == 'recommended' && this.resetHandler_) {
var container = document.createElement('div');
var 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);
}
},
};
/**
* The name of the associated preference.
* @type {string}
*/
cr.defineProperty(ControlledSettingIndicator, 'pref', cr.PropertyKind.ATTR);
/**
* 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);
// Export.
return {
ControlledSettingIndicator: ControlledSettingIndicator
};
});