blob: fc5b960ab334c6c82e3bbaa261c310fc6bcb3824 [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() {
/** @const */ 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 {cr.ui.ControlledIndicator}
*/
var ControlledSettingIndicator = cr.ui.define('span');
ControlledSettingIndicator.prototype = {
__proto__: cr.ui.ControlledIndicator.prototype,
/**
* Decorates the base element to show the proper icon.
*/
decorate: function() {
cr.ui.ControlledIndicator.prototype.decorate.call(this);
// If there is a pref, track its controlledBy and recommendedValue
// properties in order to be able to bring up the correct bubble.
if (this.pref) {
Preferences.getInstance().addEventListener(
this.pref, this.handlePrefChange.bind(this));
this.resetHandler = this.clearAssociatedPref_;
}
},
/**
* The given handler will be called when the user clicks on the 'reset to
* recommended value' link shown in the indicator bubble. The |this| object
* will be the indicator itself.
* @param {function()} handler The handler to be called.
*/
set resetHandler(handler) {
this.resetHandler_ = handler;
},
/**
* Clears the preference associated with this indicator.
* @private
*/
clearAssociatedPref_: function() {
Preferences.clearPref(this.pref, !this.dialogPref);
},
/**
* Handle changes to the associated pref by hiding any currently visible
* bubble and updating the controlledBy property.
* @param {Event} event Pref change event.
* @suppress {checkTypes}
* TODO(vitalyp): remove the suppression. |controlledBy| property is defined
* by cr.defineProperty(). Currently null can't be assigned to such
* properties due to implementation of ChromePass.java. See this discussion
* to change nulls to empty string below:
* https://chromiumcodereview.appspot.com/11066015/
*/
handlePrefChange: function(event) {
PageManager.hideBubble();
if (event.value.controlledBy) {
if (!this.value || String(event.value.value) == this.value) {
this.controlledBy = event.value.controlledBy;
if (event.value.extension) {
this.extensionId = event.value.extension.id;
this.extensionIcon = event.value.extension.icon;
this.extensionName = event.value.extension.name;
}
} else {
this.controlledBy = null;
}
} else if (event.value.recommendedValue != undefined) {
this.controlledBy =
!this.value || String(event.value.recommendedValue) == this.value ?
'hasRecommendation' : null;
} else {
this.controlledBy = null;
}
},
/**
* Uses the page's PageManager to display an informational bubble.
* @override
*/
showBubble: function(content) {
PageManager.showBubble(content, this.image, this, this.location);
},
/**
* Uses the page's PageManager to hide the currently visible bubble, if
* any.
* @override
*/
hideBubble: function() {
PageManager.hideBubble();
},
/**
* Queries the |loadTimeData| singleton for the default bubble text strings.
* @override
*/
getDefaultStrings: function() {
// Construct the bubble text.
if (this.hasAttribute('plural')) {
var defaultStrings = {
'policy': loadTimeData.getString('controlledSettingsPolicy'),
'extension': loadTimeData.getString('controlledSettingsExtension'),
'extensionWithName':
loadTimeData.getString('controlledSettingsExtensionWithName'),
};
if (cr.isChromeOS) {
defaultStrings.shared =
loadTimeData.getString('controlledSettingsShared');
}
} else {
var defaultStrings = {
'policy': loadTimeData.getString('controlledSettingPolicy'),
'extension': loadTimeData.getString('controlledSettingExtension'),
'extensionWithName':
loadTimeData.getString('controlledSettingExtensionWithName'),
'recommended': loadTimeData.getString('controlledSettingRecommended'),
'hasRecommendation':
loadTimeData.getString('controlledSettingHasRecommendation'),
};
if (cr.isChromeOS) {
defaultStrings.owner =
loadTimeData.getString('controlledSettingOwner');
defaultStrings.shared =
loadTimeData.getString('controlledSettingShared');
}
}
return defaultStrings;
},
/**
* Returns the DOM tree for a showing the message |text|.
* @param {string} text to be shown in the bubble.
* @override
*/
createDomTree: function(text) {
var content = document.createElement('div');
content.classList.add('controlled-setting-bubble-header');
content.textContent = text;
if (this.controlledBy == 'hasRecommendation' && this.resetHandler_ &&
!this.readOnly) {
var container = document.createElement('div');
var action = new ActionLink;
action.classList.add('controlled-setting-bubble-action');
action.textContent =
loadTimeData.getString('controlledSettingFollowRecommendation');
action.addEventListener('click', this.resetHandler_.bind(this));
container.appendChild(action);
content.appendChild(container);
} else if (this.controlledBy == 'extension' && this.extensionName) {
var extensionContainer =
$('extension-controlled-settings-bubble-template').cloneNode(true);
// No need for an id anymore, and thus remove to avoid id collision.
extensionContainer.removeAttribute('id');
extensionContainer.hidden = false;
var extensionName = extensionContainer.querySelector(
'.controlled-setting-bubble-extension-name');
extensionName.textContent = this.extensionName;
extensionName.style.backgroundImage =
'url("' + this.extensionIcon + '")';
var manageLink = extensionContainer.querySelector(
'.controlled-setting-bubble-extension-manage-link');
var extensionId = this.extensionId;
manageLink.onclick = function() {
uber.invokeMethodOnWindow(
window.top, 'showPage',
{pageId: 'extensions', path: '?id=' + extensionId});
};
var disableButton = extensionContainer.querySelector(
'.controlled-setting-bubble-extension-disable-button');
disableButton.onclick =
function() { chrome.send('disableExtension', [extensionId]); };
content.appendChild(extensionContainer);
}
return content;
},
};
/**
* The name of the associated preference.
*/
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.
*/
cr.defineProperty(ControlledSettingIndicator, 'dialogPref',
cr.PropertyKind.BOOL_ATTR);
/**
* The value of the associated preference that the indicator represents. If
* this is not set, the indicator will be visible whenever any value is
* enforced or recommended. If it is set, the indicator will be visible only
* when the enforced or recommended value matches the value it represents.
* This allows multiple indicators to be created for a set of radio buttons,
* ensuring that only one of them is visible at a time.
*/
cr.defineProperty(ControlledSettingIndicator, 'value',
cr.PropertyKind.ATTR);
// Export.
return {
ControlledSettingIndicator: ControlledSettingIndicator
};
});