// 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; 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); // 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'), function(event) { if (event.value) { var controlledBy = event.value['controlledBy']; self.controlledBy = controlledBy ? controlledBy : null; } }); } self.addEventListener('click', self.show_); }, /** * Closes the bubble. */ close: function() { this.querySelector('details').removeAttribute('open'); this.ownerDocument.removeEventListener('click', this.closeHandler_, true); }, /** * Constructs the bubble DOM tree and shows it. * @private */ 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); } // 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; var pref = self.getAttribute('pref'); if (self.controlledBy == 'recommended' && pref) { 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(e) { Preferences.clearPref(pref); }); container.appendChild(action); bubbleText.appendChild(container); } 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. */ cr.defineProperty(ControlledSettingIndicator, 'controlledBy', cr.PropertyKind.ATTR, ControlledSettingIndicator.prototype.close); // Export. return { ControlledSettingIndicator: ControlledSettingIndicator }; });