summaryrefslogtreecommitdiffstats
path: root/chrome/browser/resources
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/resources')
-rw-r--r--chrome/browser/resources/options/advanced_options.html2
-rw-r--r--chrome/browser/resources/options/controlled_setting.js138
-rw-r--r--chrome/browser/resources/options/options.js2
-rw-r--r--chrome/browser/resources/options/options_bundle.js1
-rw-r--r--chrome/browser/resources/options/options_page.css123
5 files changed, 266 insertions, 0 deletions
diff --git a/chrome/browser/resources/options/advanced_options.html b/chrome/browser/resources/options/advanced_options.html
index cfc653a..64c8c5e 100644
--- a/chrome/browser/resources/options/advanced_options.html
+++ b/chrome/browser/resources/options/advanced_options.html
@@ -27,6 +27,8 @@
metric="Options_LinkDoctorCheckbox" type="checkbox">
<span i18n-content="linkDoctorPref"></span>
</label>
+ <span class="controlled-setting-indicator"
+ pref="alternate_error_pages.enabled"></span>
</div>
<div class="checkbox">
<label>
diff --git a/chrome/browser/resources/options/controlled_setting.js b/chrome/browser/resources/options/controlled_setting.js
new file mode 100644
index 0000000..0ca4e31
--- /dev/null
+++ b/chrome/browser/resources/options/controlled_setting.js
@@ -0,0 +1,138 @@
+// Copyright (c) 2011 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' : localStrings.getString('controlledSettingPolicy'),
+ 'extension' : localStrings.getString('controlledSettingExtension'),
+ 'recommended' : localStrings.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 =
+ localStrings.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
+ };
+});
diff --git a/chrome/browser/resources/options/options.js b/chrome/browser/resources/options/options.js
index bb0f3d2..35c8fde 100644
--- a/chrome/browser/resources/options/options.js
+++ b/chrome/browser/resources/options/options.js
@@ -50,6 +50,8 @@ function load() {
options.ContentSettingsRadio);
cr.ui.decorate('#content-settings-page input[type=radio].handler-radio',
options.HandlersEnabledRadio);
+ cr.ui.decorate('span.controlled-setting-indicator',
+ options.ControlledSettingIndicator);
var menuOffPattern = /(^\?|&)menu=off($|&)/;
var menuDisabled = menuOffPattern.test(window.location.search);
diff --git a/chrome/browser/resources/options/options_bundle.js b/chrome/browser/resources/options/options_bundle.js
index 3b73385..f6e9939 100644
--- a/chrome/browser/resources/options/options_bundle.js
+++ b/chrome/browser/resources/options/options_bundle.js
@@ -9,6 +9,7 @@
<include src="pref_ui.js"></include>
<include src="deletable_item_list.js"></include>
<include src="inline_editable_list.js"></include>
+<include src="controlled_setting.js"></include>
<include src="options_page.js"></include>
<if expr="pp_ifdef('chromeos')">
<include src="about_page.js"></include>
diff --git a/chrome/browser/resources/options/options_page.css b/chrome/browser/resources/options/options_page.css
index ce77fb6..0af6120 100644
--- a/chrome/browser/resources/options/options_page.css
+++ b/chrome/browser/resources/options/options_page.css
@@ -611,3 +611,126 @@ html[flashPluginSupportsClearSiteData] .clear-plugin-lso-data-disabled {
.displaytable:not([searching='true']) > section:last-child > * {
border-bottom: none;
}
+
+/* Controlled setting indicator and bubble. */
+.controlled-setting-indicator {
+ display: inline-block;
+ /* Establish a containing block for absolutely positioning the bubble. */
+ position: relative;
+ vertical-align: text-bottom;
+}
+
+.controlled-setting-indicator[controlled-by] summary {
+ background-size: contain;
+ height: 16px;
+ width: 16px;
+}
+
+.controlled-setting-indicator summary::-webkit-details-marker {
+ display: none;
+}
+
+.controlled-setting-indicator[controlled-by='policy'] summary {
+ background-image:
+ url('chrome://theme/IDR_CONTROLLED_SETTING_MANDATORY_GRAY');
+}
+
+.controlled-setting-indicator[controlled-by='policy'] summary:hover {
+ background-image:
+ url('chrome://theme/IDR_CONTROLLED_SETTING_MANDATORY');
+}
+
+.controlled-setting-indicator[controlled-by='extension'] summary {
+ background-image:
+ url('chrome://theme/IDR_CONTROLLED_SETTING_EXTENSION_GRAY');
+}
+
+.controlled-setting-indicator[controlled-by='extension'] summary:hover {
+ background-image:
+ url('chrome://theme/IDR_CONTROLLED_SETTING_EXTENSION');
+}
+
+.controlled-setting-indicator[controlled-by='recommended'] summary {
+ background-image:
+ url('chrome://theme/IDR_CONTROLLED_SETTING_RECOMMENDED_GRAY');
+}
+
+.controlled-setting-indicator[controlled-by='recommended'] summary:hover {
+ background-image:
+ url('chrome://theme/IDR_CONTROLLED_SETTING_RECOMMENDED');
+}
+
+.controlled-setting-bubble {
+ -webkit-margin-start: -20px;
+ background-color: white;
+ border-radius: 4px;
+ border: 1px solid #ccc;
+ box-shadow: 0 2px 2px #ddd;
+ margin-top: 10px;
+ padding: 10px;
+ position: absolute;
+ top: 50%;
+ z-index: 10;
+}
+
+html[dir='ltr'] .controlled-setting-bubble {
+ left: 50%;
+}
+
+html[dir='rtl'] .controlled-setting-bubble {
+ right: 50%;
+}
+
+.controlled-setting-bubble::before {
+ -webkit-margin-start: 4px;
+ border-color: #ccc transparent;
+ border-style: solid;
+ border-width: 0 5px 5px;
+ content: '';
+ position: absolute;
+ top: -5px;
+}
+
+.controlled-setting-bubble::after {
+ -webkit-margin-start: 5px;
+ border-color: white transparent;
+ border-style: solid;
+ border-width: 0 4px 4px;
+ content: '';
+ position: absolute;
+ top: -4px;
+}
+
+.controlled-setting-bubble-text {
+ -webkit-padding-start: 30px;
+ background-repeat: no-repeat;
+ margin: 0;
+ min-height: 32px;
+ min-width: 200px;
+}
+
+.controlled-setting-indicator[controlled-by='policy']
+ .controlled-setting-bubble-text {
+ background-image:
+ url('chrome://theme/IDR_CONTROLLED_SETTING_MANDATORY_LARGE');
+}
+
+.controlled-setting-indicator[controlled-by='extension']
+ .controlled-setting-bubble-text {
+ background-image:
+ url('chrome://theme/IDR_CONTROLLED_SETTING_EXTENSION_LARGE');
+}
+
+.controlled-setting-indicator[controlled-by='recommended']
+ .controlled-setting-bubble-text {
+ background-image:
+ url('chrome://theme/IDR_CONTROLLED_SETTING_RECOMMENDED_LARGE');
+}
+
+html[dir='rtl'] .controlled-setting-bubble-text {
+ background-position: right top;
+}
+
+.controlled-setting-bubble-action {
+ padding: 0 !important;
+}