diff options
author | mnissler@chromium.org <mnissler@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-29 09:44:53 +0000 |
---|---|---|
committer | mnissler@chromium.org <mnissler@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-29 09:44:53 +0000 |
commit | 2059f0af42601a45f490e8ac8b235ff0fa2f817b (patch) | |
tree | 2e448214d0c88ec06713e5157a151baf36626a7e | |
parent | b5db7eb44d6ca0f915843aae274d2bbd27fa18ab (diff) | |
download | chromium_src-2059f0af42601a45f490e8ac8b235ff0fa2f817b.zip chromium_src-2059f0af42601a45f490e8ac8b235ff0fa2f817b.tar.gz chromium_src-2059f0af42601a45f490e8ac8b235ff0fa2f817b.tar.bz2 |
Controlled settings indicator and bubble for chrome://preferences.
The idea is that every setting that is under control by an external entity (e.g. policy, extension) will be annotated with an icon that, when click on, will show a bubble with more information. This implements the indicator icon and bubble. Going through the prefs UI and inserting the thing at the appropriate places is left for subsequent CLs :)
BUG=chromium:104955
TEST=No observable changes.
Review URL: http://codereview.chromium.org/8480037
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@111897 0039d316-1c4b-4281-b951-d872f2087c98
17 files changed, 329 insertions, 9 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index d2d7504..692871f 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -8572,40 +8572,71 @@ Keep your key file in a safe place. You will need it to create new versions of y </message> </if> + <message name="IDS_OPTIONS_CONTROLLED_SETTING_APPLY_RECOMMENDATION" desc="Link text displayed in the controlled settings bubble for applying the recommendation."> + Apply recommendation + </message> + <if expr="pp_ifdef('chromeos')"> <message name="IDS_OPTIONS_POLICY_MANAGED_PREFS" desc="Banner displayed in case there are policy-managed options the user won't be able to change."> - Some settings are being managed by your administrator. + Some settings are managed by your administrator. </message> <message name="IDS_OPTIONS_EXTENSION_MANAGED_PREFS" desc="Banner displayed in case there are extension-managed options the user won't be able to change."> - Some settings are being managed by an extension. + Some settings are managed by an extension. </message> <message name="IDS_OPTIONS_POLICY_EXTENSION_MANAGED_PREFS" desc="Banner displayed in case there are policy- and extension-managed options the user won't be able to change."> - Some settings have been disabled by your administrator and others are being managed by an extension. + Some settings have been disabled by your administrator and others are managed by an extension. </message> <message name="IDS_OPTIONS_UNMODIFIABLE_PREFS" desc="Banner displayed in case there are options that the user won't be able to change."> Some settings cannot be modified by the user. </message> + <message name="IDS_OPTIONS_CONTROLLED_SETTING_POLICY" desc="Text displayed in the controlled settings bubble in case the setting is forced by policy."> + This setting is enforced by your administrator. + </message> + <message name="IDS_OPTIONS_CONTROLLED_SETTING_EXTENSION" desc="Text displayed in the controlled settings bubble in case the setting controlled by an extension."> + This setting is managed by an extension. + </message> + <message name="IDS_OPTIONS_CONTROLLED_SETTING_RECOMMENDED" desc="Text displayed in the controlled settings bubble in case the setting has a policy-supplied default value."> + Your administrator recommends a specific value for this setting. + </message> </if> <if expr="not pp_ifdef('chromeos') and is_posix"> <message name="IDS_OPTIONS_POLICY_MANAGED_PREFS" desc="Banner displayed in case there are policy-managed options the user won't be able to change."> - Some preferences have been disabled by your administrator. + Some preferences are managed by your administrator. </message> <message name="IDS_OPTIONS_EXTENSION_MANAGED_PREFS" desc="Banner displayed in case there are extension-managed options the user won't be able to change."> - Some preferences are being managed by an extension. + Some preferences are managed by an extension. </message> <message name="IDS_OPTIONS_POLICY_EXTENSION_MANAGED_PREFS" desc="Banner displayed in case there are policy- and extension-managed options the user won't be able to change."> - Some preferences have been disabled by your administrator and others are being managed by an extension. + Some preferences have been disabled by your administrator and others are managed by an extension. + </message> + <message name="IDS_OPTIONS_CONTROLLED_SETTING_POLICY" desc="Text displayed in the controlled settings bubble in case the setting is forced by policy."> + This preference is enforced by your administrator. + </message> + <message name="IDS_OPTIONS_CONTROLLED_SETTING_EXTENSION" desc="Text displayed in the controlled settings bubble in case the setting controlled by an extension."> + This preference is managed by an extension. + </message> + <message name="IDS_OPTIONS_CONTROLLED_SETTING_RECOMMENDED" desc="Text displayed in the controlled settings bubble in case the setting has a policy-supplied default value."> + Your administrator recommends a specific value for this preference. </message> </if> <if expr="is_win"> <message name="IDS_OPTIONS_POLICY_MANAGED_PREFS" desc="Banner displayed in case there are policy-managed options the user won't be able to change."> - Some options have been disabled by your administrator. + Some options are managed by your administrator. </message> <message name="IDS_OPTIONS_EXTENSION_MANAGED_PREFS" desc="Banner displayed in case there are extension-managed options the user won't be able to change."> - Some options are being managed by an extension. + Some options are managed by an extension. </message> <message name="IDS_OPTIONS_POLICY_EXTENSION_MANAGED_PREFS" desc="Banner displayed in case there are policy- and extension-managed options the user won't be able to change."> - Some options have been disabled by your administrator and others are being managed by an extension. + Some options have been disabled by your administrator and others are managed by an extension. + </message> + <message name="IDS_OPTIONS_CONTROLLED_SETTING_POLICY" desc="Text displayed in the controlled settings bubble in case the setting is forced by policy."> + This option is enforced by your administrator. + </message> + <message name="IDS_OPTIONS_CONTROLLED_SETTING_EXTENSION" desc="Text displayed in the controlled settings bubble in case the setting controlled by an extension."> + This option is managed by an extension. + </message> + <message name="IDS_OPTIONS_CONTROLLED_SETTING_RECOMMENDED" desc="Text displayed in the controlled settings bubble in case the setting has a policy-supplied default value."> + Your administrator recommends a specific value for this option. </message> </if> diff --git a/chrome/app/theme/controlled_setting_extension.png b/chrome/app/theme/controlled_setting_extension.png Binary files differnew file mode 100644 index 0000000..af8f450 --- /dev/null +++ b/chrome/app/theme/controlled_setting_extension.png diff --git a/chrome/app/theme/controlled_setting_extension_gray.png b/chrome/app/theme/controlled_setting_extension_gray.png Binary files differnew file mode 100644 index 0000000..86df1e5 --- /dev/null +++ b/chrome/app/theme/controlled_setting_extension_gray.png diff --git a/chrome/app/theme/controlled_setting_extension_large.png b/chrome/app/theme/controlled_setting_extension_large.png Binary files differnew file mode 100644 index 0000000..593b591 --- /dev/null +++ b/chrome/app/theme/controlled_setting_extension_large.png diff --git a/chrome/app/theme/controlled_setting_mandatory.png b/chrome/app/theme/controlled_setting_mandatory.png Binary files differnew file mode 100644 index 0000000..700fd86 --- /dev/null +++ b/chrome/app/theme/controlled_setting_mandatory.png diff --git a/chrome/app/theme/controlled_setting_mandatory_gray.png b/chrome/app/theme/controlled_setting_mandatory_gray.png Binary files differnew file mode 100644 index 0000000..b6e6963 --- /dev/null +++ b/chrome/app/theme/controlled_setting_mandatory_gray.png diff --git a/chrome/app/theme/controlled_setting_mandatory_large.png b/chrome/app/theme/controlled_setting_mandatory_large.png Binary files differnew file mode 100644 index 0000000..203fc43 --- /dev/null +++ b/chrome/app/theme/controlled_setting_mandatory_large.png diff --git a/chrome/app/theme/controlled_setting_recommended.png b/chrome/app/theme/controlled_setting_recommended.png Binary files differnew file mode 100644 index 0000000..b421adf --- /dev/null +++ b/chrome/app/theme/controlled_setting_recommended.png diff --git a/chrome/app/theme/controlled_setting_recommended_gray.png b/chrome/app/theme/controlled_setting_recommended_gray.png Binary files differnew file mode 100644 index 0000000..1e4fc75 --- /dev/null +++ b/chrome/app/theme/controlled_setting_recommended_gray.png diff --git a/chrome/app/theme/controlled_setting_recommended_large.png b/chrome/app/theme/controlled_setting_recommended_large.png Binary files differnew file mode 100644 index 0000000..42feff02 --- /dev/null +++ b/chrome/app/theme/controlled_setting_recommended_large.png diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index 6a54281..98c54f5 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd @@ -397,6 +397,15 @@ <include name="IDR_UPDATE_UPTODATE" file="update_uptodate.png" type="BINDATA" /> <include name="IDR_WARNING" file="alert_small.png" type="BINDATA" /> <include name="IDR_MANAGED" file="managed_small.png" type="BINDATA" /> + <include name="IDR_CONTROLLED_SETTING_MANDATORY_GRAY" file="controlled_setting_mandatory_gray.png" type="BINDATA" /> + <include name="IDR_CONTROLLED_SETTING_MANDATORY" file="controlled_setting_mandatory.png" type="BINDATA" /> + <include name="IDR_CONTROLLED_SETTING_MANDATORY_LARGE" file="controlled_setting_mandatory_large.png" type="BINDATA" /> + <include name="IDR_CONTROLLED_SETTING_EXTENSION_GRAY" file="controlled_setting_extension_gray.png" type="BINDATA" /> + <include name="IDR_CONTROLLED_SETTING_EXTENSION" file="controlled_setting_extension.png" type="BINDATA" /> + <include name="IDR_CONTROLLED_SETTING_EXTENSION_LARGE" file="controlled_setting_extension_large.png" type="BINDATA" /> + <include name="IDR_CONTROLLED_SETTING_RECOMMENDED_GRAY" file="controlled_setting_recommended_gray.png" type="BINDATA" /> + <include name="IDR_CONTROLLED_SETTING_RECOMMENDED" file="controlled_setting_recommended.png" type="BINDATA" /> + <include name="IDR_CONTROLLED_SETTING_RECOMMENDED_LARGE" file="controlled_setting_recommended_large.png" type="BINDATA" /> <if expr="pp_ifdef('_google_chrome')"> <include name="IDR_WEBSTORE_ICON" file="google_chrome/webstore_icon.png" type="BINDATA" /> <include name="IDR_WEBSTORE_ICON_16" file="google_chrome/webstore_icon_16.png" type="BINDATA" /> 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; +} diff --git a/chrome/browser/ui/webui/options/core_options_handler.cc b/chrome/browser/ui/webui/options/core_options_handler.cc index da97e4a..d03f7d7 100644 --- a/chrome/browser/ui/webui/options/core_options_handler.cc +++ b/chrome/browser/ui/webui/options/core_options_handler.cc @@ -62,6 +62,17 @@ void CoreOptionsHandler::GetStaticLocalizedValues( localized_strings->SetString("policyAndExtensionManagedPrefsBannerText", l10n_util::GetStringUTF16(IDS_OPTIONS_POLICY_EXTENSION_MANAGED_PREFS)); + // Controlled settings bubble. + localized_strings->SetString("controlledSettingPolicy", + l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTING_POLICY)); + localized_strings->SetString("controlledSettingExtension", + l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTING_EXTENSION)); + localized_strings->SetString("controlledSettingRecommended", + l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTING_RECOMMENDED)); + localized_strings->SetString("controlledSettingApplyRecommendation", + l10n_util::GetStringUTF16( + IDS_OPTIONS_CONTROLLED_SETTING_APPLY_RECOMMENDATION)); + // Search RegisterTitle(localized_strings, "searchPage", IDS_OPTIONS_SEARCH_PAGE_TITLE); localized_strings->SetString("searchPlaceholder", @@ -261,6 +272,9 @@ DictionaryValue* CoreOptionsHandler::CreateValueForPref( dict->SetString("controlledBy", "policy"); } else if (controlling_pref->IsExtensionControlled()) { dict->SetString("controlledBy", "extension"); + } else if (controlling_pref->IsUserModifiable() && + !controlling_pref->IsDefaultValue()) { + dict->SetString("controlledBy", "recommended"); } dict->SetBoolean("disabled", !controlling_pref->IsUserModifiable()); return dict; |