diff options
Diffstat (limited to 'chromium/chrome/browser/resources/settings')
156 files changed, 2117 insertions, 2514 deletions
diff --git a/chromium/chrome/browser/resources/settings/BUILD.gn b/chromium/chrome/browser/resources/settings/BUILD.gn index 94da713a1ce..173d4320e07 100644 --- a/chromium/chrome/browser/resources/settings/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/BUILD.gn @@ -2,11 +2,11 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("../optimize_webui.gni") import("//chrome/common/features.gni") import("//third_party/closure_compiler/compile_js.gni") import("//tools/grit/grit_rule.gni") import("//ui/webui/webui_features.gni") +import("../optimize_webui.gni") if (optimize_webui) { settings_pak_file = "settings_resources.pak" @@ -72,6 +72,7 @@ group("closure_compile") { "android_apps_page:closure_compile", "animation:closure_compile", "appearance_page:closure_compile", + "autofill_page:closure_compile", "basic_page:closure_compile", "bluetooth_page:closure_compile", "change_password_page:closure_compile", @@ -87,7 +88,6 @@ group("closure_compile") { "languages_page:closure_compile", "multidevice_page:closure_compile", "on_startup_page:closure_compile", - "passwords_and_forms_page:closure_compile", "people_page:closure_compile", "prefs:closure_compile", "printing_page:closure_compile", @@ -112,6 +112,7 @@ js_type_check("settings_resources") { ":focus_row_behavior", ":global_scroll_target_behavior", ":lifetime_browser_proxy", + ":open_window_proxy", ":page_visibility", ":route", ":search_settings", @@ -154,6 +155,12 @@ js_library("lifetime_browser_proxy") { externs_list = [ "$externs_path/chrome_send.js" ] } +js_library("open_window_proxy") { + deps = [ + "//ui/webui/resources/js:cr", + ] +} + js_library("route") { deps = [ ":page_visibility", diff --git a/chromium/chrome/browser/resources/settings/OWNERS b/chromium/chrome/browser/resources/settings/OWNERS index 61b58777ab2..a34bf8b5f11 100644 --- a/chromium/chrome/browser/resources/settings/OWNERS +++ b/chromium/chrome/browser/resources/settings/OWNERS @@ -1,3 +1,4 @@ +dbeam@chromium.org dpapad@chromium.org dschuyler@chromium.org hcarmona@chromium.org diff --git a/chromium/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html b/chromium/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html index 71f76807b88..10e2836550e 100644 --- a/chromium/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html +++ b/chromium/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html @@ -169,7 +169,7 @@ pref="{{prefs.settings.a11y.caret_highlight}}" label="$i18n{caretHighlightLabel}"> </settings-toggle-button> - <template is="dom-if" if="[[showExperimentalFeatures_]]"> + <template is="dom-if" if="[[showExperimentalSwitchAccess_]]"> <settings-toggle-button pref="{{prefs.settings.a11y.switch_access}}" label="$i18n{switchAccessLabel}"> @@ -204,7 +204,8 @@ pref="{{prefs.settings.a11y.autoclick}}" label="$i18n{clickOnStopLabel}"> </settings-toggle-button> - <div class="settings-box continuation"> + <div class="settings-box continuation" + hidden$="[[!prefs.settings.a11y.autoclick.value]]"> <div class="start sub-item">$i18n{delayBeforeClickLabel}</div> <settings-dropdown-menu label="$i18n{delayBeforeClickLabel}" pref="{{prefs.settings.a11y.autoclick_delay_ms}}" @@ -212,6 +213,38 @@ disabled="[[!prefs.settings.a11y.autoclick.value]]"> </settings-dropdown-menu> </div> + <template is="dom-if" if="[[showExperimentalAutoclick_]]"> + <div class="settings-box continuation" + hidden$="[[!prefs.settings.a11y.autoclick.value]]"> + <div class="start sub-item" id="autoclickEventTypeLabel"> + $i18n{autoclickEventTypeLabel} + </div> + <settings-dropdown-menu aria-labeledby="autoclickEventTypeLabel" + pref="{{prefs.settings.a11y.autoclick_event_type}}" + menu-options="[[autoClickEventTypeOptions_]]" + disabled="[[!prefs.settings.a11y.autoclick.value]]"> + </settings-dropdown-menu> + </div> + <div class="sub-item"> + <settings-toggle-button class="continuation sub-item" + hidden$="[[!prefs.settings.a11y.autoclick.value]]" + pref="{{prefs.settings.a11y.autoclick_revert_to_left_click}}" + label="$i18n{autoclickRevertToLeftClick}"> + </settings-toggle-button> + </div> + <div class="settings-box continuation" + hidden$="[[!prefs.settings.a11y.autoclick.value]]"> + <div class="start sub-item" id="autoclickMovementThresholdLabel"> + $i18n{autoclickMovementThresholdLabel} + </div> + <settings-dropdown-menu + aria-labelledby="autoclickMovementThresholdLabel" + pref="{{prefs.settings.a11y.autoclick_movement_threshold}}" + menu-options="[[autoClickMovementThresholdOptions_]]" + disabled="[[!prefs.settings.a11y.autoclick.value]]"> + </settings-dropdown-menu> + </div> + </template> <settings-toggle-button pref="{{prefs.settings.a11y.large_cursor_enabled}}" label="$i18n{largeMouseCursorLabel}"> diff --git a/chromium/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js b/chromium/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js index d8acc989fc0..1a9ddd294d4 100644 --- a/chromium/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js +++ b/chromium/chrome/browser/resources/settings/a11y_page/manage_a11y_page.js @@ -69,6 +69,73 @@ Polymer({ }, }, + autoClickEventTypeOptions_: { + readOnly: true, + type: Array, + value: function() { + // These values correspond to the i18n values in settings_strings.grdp + // and the enums in accessibility_controller.mojom, AutoclickEventType. + // If these values get changed then those strings need to be changed as + // well. + return [ + { + // mojom::AutoclickEventType::kLeftClick + value: 0, + name: loadTimeData.getString('autoclickEventTypeLeftClick') + }, + { + // mojom::AutoclickEventType::kRightClick + value: 1, + name: loadTimeData.getString('autoclickEventTypeRightClick') + }, + { + // mojom::AutoclickEventType::kDragAndDrop + value: 2, + name: loadTimeData.getString('autoclickEventTypeDragAndDrop') + }, + { + // mojom::AutoclickEventType::kDoubleClick + value: 3, + name: loadTimeData.getString('autoclickEventTypeDoubleClick') + }, + { + // mojom::AutoclickEventType::kNoAction + value: 4, + name: loadTimeData.getString('autoclickEventTypeNoAction') + }, + ]; + }, + }, + + autoClickMovementThresholdOptions_: { + readOnly: true, + type: Array, + value: function() { + return [ + { + value: 5, + name: loadTimeData.getString('autoclickMovementThresholdExtraSmall') + }, + { + value: 10, + name: loadTimeData.getString('autoclickMovementThresholdSmall') + }, + { + value: 20, + name: loadTimeData.getString('autoclickMovementThresholdDefault') + }, + { + value: 30, + name: loadTimeData.getString('autoclickMovementThresholdLarge') + }, + { + value: 40, + name: loadTimeData.getString('autoclickMovementThresholdExtraLarge') + }, + ]; + }, + }, + /** * Whether to show experimental accessibility features. * @private {boolean} @@ -80,6 +147,22 @@ Polymer({ }, }, + showExperimentalAutoclick_: { + type: Boolean, + value: function() { + return loadTimeData.getBoolean( + 'showExperimentalAccessibilityAutoclick'); + }, + }, + + showExperimentalSwitchAccess_: { + type: Boolean, + value: function() { + return loadTimeData.getBoolean( + 'showExperimentalAccessibilitySwitchAccess'); + }, + }, + /** * Whether the docked magnifier flag is enabled. * @private {boolean} diff --git a/chromium/chrome/browser/resources/settings/about_page/about_page.html b/chromium/chrome/browser/resources/settings/about_page/about_page.html index 8465305ee1d..207d4920586 100644 --- a/chromium/chrome/browser/resources/settings/about_page/about_page.html +++ b/chromium/chrome/browser/resources/settings/about_page/about_page.html @@ -11,7 +11,10 @@ <link rel="import" href="../settings_page/settings_section.html"> <link rel="import" href="../settings_page_css.html"> <link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="../settings_vars_css.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_link_row/cr_link_row.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> @@ -37,6 +40,25 @@ --about-page-image-space: 10px; } + settings-section[section='about'] { + --settings-section-header: { + display: none; + }; + } + + h1 { + color: var(--cr-primary-text-color); + font-size: 108%; + font-weight: 400; + letter-spacing: .25px; + margin-bottom: 12px; + margin-inline-end: 3px; + margin-inline-start: 3px; + margin-top: var(--settings-page-vertical-margin); + padding-bottom: 4px; + padding-top: 8px; + } + .info-section { margin-bottom: 12px; } @@ -87,6 +109,7 @@ } </if> </style> + <h1>$i18n{aboutPageTitle}</h1> <div> <settings-section page-title="$i18n{aboutPageTitle}" section="about"> <settings-animated-pages id="pages" section="about" @@ -217,32 +240,19 @@ </div> </template> </if> - <div id="help" class="settings-box" on-click="onHelpTap_" - actionable> - <div class="start">$i18n{aboutGetHelpUsingChrome}</div> - <paper-icon-button-light class="icon-external"> - <button aria-labelledby="help"></button> - </paper-icon-button-light> - </div> + <cr-link-row class="hr" icon-class="icon-external" id="help" + on-click="onHelpTap_" label="$i18n{aboutGetHelpUsingChrome}"> + </cr-link-row> <if expr="_google_chrome"> - <div id="reportIssue" class="settings-box" actionable - on-click="onReportIssueTap_"> - <div class="start">$i18n{aboutReportAnIssue}</div> - <paper-icon-button-light class="subpage-arrow"> - <button aria-labelledby="reportIssue"></button> - </paper-icon-button-light> - </div> + <cr-link-row class="hr" icon-class="subpage-arrow" id="reportIssue" + on-click="onReportIssueTap_" label="$i18n{aboutReportAnIssue}"> + </cr-link-row> </if> <if expr="chromeos"> - <div class="settings-box" on-click="onDetailedBuildInfoTap_" - actionable> - <div class="start">$i18n{aboutDetailedBuildInfo}</div> - <paper-icon-button-light class="subpage-arrow"> - <button id="detailed-build-info-trigger" - aria-label="$i18n{aboutDetailedBuildInfo}"> - </button> - </paper-icon-button-light> - </div> + <cr-link-row class="hr" icon-class="subpage-arrow" + id="detailed-build-info-trigger" + on-click="onDetailedBuildInfoTap_" + label="$i18n{aboutDetailedBuildInfo}"></cr-link-row> </if> </neon-animatable> <if expr="chromeos"> @@ -286,7 +296,8 @@ </div> </if> <img src="[[regulatoryInfo_.url]]" alt="[[regulatoryInfo_.text]]" - hidden$="[[!shouldShowRegulatoryInfo_(regulatoryInfo_)]]"> + hidden$="[[!shouldShowRegulatoryInfo_(regulatoryInfo_)]]" + role="presentation"> </div> </if> </settings-section> diff --git a/chromium/chrome/browser/resources/settings/about_page/about_page.js b/chromium/chrome/browser/resources/settings/about_page/about_page.js index 70e53fcf316..256b6243c42 100644 --- a/chromium/chrome/browser/resources/settings/about_page/about_page.js +++ b/chromium/chrome/browser/resources/settings/about_page/about_page.js @@ -638,4 +638,8 @@ Polymer({ // </if> return this.showUpdateStatus_; }, + + focusSection: function() { + this.$$('settings-section[section="about"]').show(); + }, }); diff --git a/chromium/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html b/chromium/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html index b2daa381021..8dcad3fd879 100644 --- a/chromium/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html +++ b/chromium/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html @@ -2,9 +2,9 @@ <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> <link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_radio_group/cr_radio_group.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-selector/iron-selector.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-group/paper-radio-group.html"> <link rel="import" href="about_page_browser_proxy.html"> <link rel="import" href="../settings_shared_css.html"> @@ -21,8 +21,7 @@ <!-- TODO(dbeam): this can be policy-controlled. Show this in the UI. https://www.chromium.org/administrators/policy-list-3#ChromeOsReleaseChannel --> - <paper-radio-group selectable="cr-radio-button" - on-paper-radio-group-changed="onChannelSelectionChanged_"> + <cr-radio-group on-selected-changed="onChannelSelectionChanged_"> <cr-radio-button name="[[browserChannelEnum_.STABLE]]"> $i18n{aboutChannelDialogStable} </cr-radio-button> @@ -32,7 +31,7 @@ <cr-radio-button name="[[browserChannelEnum_.DEV]]"> $i18n{aboutChannelDialogDev} </cr-radio-button> - </paper-radio-group> + </cr-radio-group> <iron-selector id="warningSelector"> <div> <h2>$i18n{aboutDelayedWarningTitle}</h2> diff --git a/chromium/chrome/browser/resources/settings/about_page/channel_switcher_dialog.js b/chromium/chrome/browser/resources/settings/about_page/channel_switcher_dialog.js index a5e2fe93746..09ec8618d78 100644 --- a/chromium/chrome/browser/resources/settings/about_page/channel_switcher_dialog.js +++ b/chromium/chrome/browser/resources/settings/about_page/channel_switcher_dialog.js @@ -55,8 +55,8 @@ Polymer({ this.currentChannel_ = info.currentChannel; this.targetChannel_ = info.targetChannel; // Pre-populate radio group with target channel. - const radioGroup = this.$$('paper-radio-group'); - radioGroup.select(this.targetChannel_); + const radioGroup = this.$$('cr-radio-group'); + radioGroup.selected = this.targetChannel_; radioGroup.focus(); }); }, @@ -73,7 +73,7 @@ Polymer({ /** @private */ onChangeChannelTap_: function() { - const selectedChannel = this.$$('paper-radio-group').selected; + const selectedChannel = this.$$('cr-radio-group').selected; this.browserProxy_.setChannel(selectedChannel, false); this.$.dialog.close(); this.fire('target-channel-changed', selectedChannel); @@ -81,7 +81,7 @@ Polymer({ /** @private */ onChangeChannelAndPowerwashTap_: function() { - const selectedChannel = this.$$('paper-radio-group').selected; + const selectedChannel = this.$$('cr-radio-group').selected; this.browserProxy_.setChannel(selectedChannel, true); this.$.dialog.close(); this.fire('target-channel-changed', selectedChannel); @@ -108,7 +108,7 @@ Polymer({ /** @private */ onChannelSelectionChanged_: function() { - const selectedChannel = this.$$('paper-radio-group').selected; + const selectedChannel = this.$$('cr-radio-group').selected; // Selected channel is the same as the target channel so only show 'cancel'. if (selectedChannel == this.targetChannel_) { diff --git a/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.html b/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.html index 720d25d126a..c35f9399b87 100644 --- a/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.html +++ b/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.html @@ -179,6 +179,9 @@ <settings-toggle-button pref="{{prefs.webkit.webprefs.tabs_to_links}}" label="$i18n{tabsToLinks}"> </settings-toggle-button> + <settings-toggle-button pref="{{prefs.browser.confirm_to_quit}}" + label="$i18n{warnBeforeQuitting}"> + </settings-toggle-button> </if> </neon-animatable> <template is="dom-if" route-path="/fonts"> diff --git a/chromium/chrome/browser/resources/settings/appearance_page/home_url_input.js b/chromium/chrome/browser/resources/settings/appearance_page/home_url_input.js index 870e6c10fa7..e0302aef552 100644 --- a/chromium/chrome/browser/resources/settings/appearance_page/home_url_input.js +++ b/chromium/chrome/browser/resources/settings/appearance_page/home_url_input.js @@ -122,7 +122,7 @@ Polymer({ /** * This function prevents unwanted change of selection of the containing - * paper-radio-group, when the user traverses the input with arrow keys. + * cr-radio-group, when the user traverses the input with arrow keys. * @param {!Event} e * @private */ diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/BUILD.gn b/chromium/chrome/browser/resources/settings/autofill_page/BUILD.gn index 94a052ae64e..feb6b084a4c 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/autofill_page/BUILD.gn @@ -7,23 +7,24 @@ import("//third_party/closure_compiler/compile_js.gni") js_type_check("closure_compile") { deps = [ ":address_edit_dialog", + ":autofill_page", ":autofill_section", ":credit_card_edit_dialog", ":password_edit_dialog", ":password_list_item", ":password_manager_proxy", - ":passwords_and_forms_page", ":passwords_section", ":payments_section", ":show_password_behavior", ] } -js_library("passwords_and_forms_page") { +js_library("autofill_page") { deps = [ ":autofill_section", ":passwords_section", ":payments_section", + "..:open_window_proxy", "..:route", "../prefs:prefs_behavior", "../settings_page:settings_animated_pages", diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/address_edit_dialog.html b/chromium/chrome/browser/resources/settings/autofill_page/address_edit_dialog.html index 5ceba365497..5ceba365497 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/address_edit_dialog.html +++ b/chromium/chrome/browser/resources/settings/autofill_page/address_edit_dialog.html diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/address_edit_dialog.js b/chromium/chrome/browser/resources/settings/autofill_page/address_edit_dialog.js index a184152c8af..1ec36ce4685 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/address_edit_dialog.js +++ b/chromium/chrome/browser/resources/settings/autofill_page/address_edit_dialog.js @@ -92,23 +92,9 @@ Polymer({ // Default to the last country used if no country code is provided. const countryCode = this.countryCode_ || this.countries_[0].countryCode; this.countryInfo.getAddressFormat(countryCode).then(format => { - let filteredComponent = - format.components.map(component => component.row.filter(c => { - return ( - loadTimeData.getBoolean('EnableCompanyName') || - c.field !== chrome.autofillPrivate.AddressField.COMPANY_NAME); - })); - this.addressWrapper_ = - filteredComponent - .filter(component => { - return (component && component.length > 0); - }) - .map(component => { - return component.map(c => { - return new settings.address.AddressComponentUI( - this.address, c); - }); - }); + this.addressWrapper_ = format.components.map( + component => component.row.map( + c => new settings.address.AddressComponentUI(this.address, c))); // Flush dom before resize and savability updates. Polymer.dom.flush(); diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.html b/chromium/chrome/browser/resources/settings/autofill_page/autofill_page.html index c2a503efeb1..773bf44366a 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.html +++ b/chromium/chrome/browser/resources/settings/autofill_page/autofill_page.html @@ -1,59 +1,52 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_elements/cr_link_row/cr_link_row.html"> -<link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/cr.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> <link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="autofill_section.html"> <link rel="import" href="passwords_section.html"> <link rel="import" href="payments_section.html"> -<link rel="import" href="../controls/extension_controlled_indicator.html"> -<link rel="import" href="../controls/settings_toggle_button.html"> <link rel="import" href="../prefs/prefs.html"> <link rel="import" href="../prefs/prefs_behavior.html"> +<link rel="import" href="../open_window_proxy.html"> <link rel="import" href="../route.html"> <link rel="import" href="../settings_page/settings_animated_pages.html"> <link rel="import" href="../settings_page/settings_subpage.html"> <link rel="import" href="../settings_shared_css.html"> -<dom-module id="settings-passwords-and-forms-page"> +<dom-module id="settings-autofill-page"> <template> - <style include="settings-shared iron-flex"></style> - <settings-animated-pages id="pages" section="passwordsAndForms" + <style include="settings-shared"> + cr-link-row { + --cr-link-row-icon-width: 40px; + border-top: var(--settings-separator-line); + } + </style> + <settings-animated-pages id="pages" section="autofill" focus-config="[[focusConfig_]]"> <neon-animatable route-path="default"> - <cr-link-row icon-class="subpage-arrow" - id="autofillManagerButton" label="$i18n{autofill}" - sub-label="$i18n{autofillDetail}" on-click="onAutofillTap_"> + <cr-link-row id="passwordManagerButton" start-icon="settings20:vpn-key" + label="$i18n{passwords}" icon-class="subpage-arrow" + on-click="onPasswordsClick_"></cr-link-row> + <cr-link-row id="paymentManagerButton" + start-icon="settings20:credit-card" label="$i18n{creditCards}" + icon-class="subpage-arrow" on-click="onPaymentsClick_"> </cr-link-row> - <cr-link-row icon-class="subpage-arrow" - id="paymentManagerButton" label="$i18n{creditCards}" - sub-label="$i18n{creditCardsDetail}" on-click="onPaymentsTap_"> + <cr-link-row id="addressesManagerButton" + start-icon="settings20:location-on" label="$i18n{addressesTitle}" + icon-class="subpage-arrow" on-click="onAddressesClick_"> </cr-link-row> - <div class="settings-box two-line"> - <div class="start two-line" on-click="onPasswordsTap_" actionable - id="passwordManagerButton"> - <div class="flex"> - $i18n{passwords} - <div class="secondary" id="passwordsSecondary"> - $i18n{passwordsDetail} - </div> - </div> - <paper-icon-button-light class="subpage-arrow"> - <button aria-label="$i18n{passwords}" - aria-describedby="passwordsSecondary"></button> - </paper-icon-button-light> - </div> - </div> </neon-animatable> - <template is="dom-if" route-path="/autofill"> + <template is="dom-if" route-path="/passwords"> <settings-subpage - associated-control="[[$$('#autofillManagerButton')]]" - page-title="$i18n{autofill}"> - <settings-autofill-section id="autofillSection" prefs="{{prefs}}"> - </settings-autofill-section> + associated-control="[[$$('#passwordManagerButton')]]" + page-title="$i18n{passwords}" + learn-more-url="$i18n{passwordManagerLearnMoreURL}" + search-label="$i18n{searchPasswords}" + search-term="{{passwordFilter_}}"> + <passwords-section id="passwordSection" filter="[[passwordFilter_]]" + prefs="{{prefs}}"> + </passwords-section> </settings-subpage> </template> <template is="dom-if" route-path="/payments"> @@ -61,23 +54,19 @@ associated-control="[[$$('#paymentManagerButton')]]" page-title="$i18n{creditCards}" learn-more-url="$i18n{paymentMethodsLearnMoreURL}"> - <settings-payments-section id="paymentSection" prefs="{{prefs}}"> + <settings-payments-section id="paymentsSection" prefs="{{prefs}}"> </settings-payments-section> </settings-subpage> </template> - <template is="dom-if" route-path="/passwords"> + <template is="dom-if" route-path="/addresses"> <settings-subpage - associated-control="[[$$('#passwordManagerButton')]]" - page-title="$i18n{passwords}" - learn-more-url="$i18n{passwordManagerLearnMoreURL}" - search-label="$i18n{searchPasswords}" - search-term="{{passwordFilter_}}"> - <passwords-section id="passwordSection" filter="[[passwordFilter_]]" - prefs="{{prefs}}"> - </passwords-section> + associated-control="[[$$('#addressesManagerButton')]]" + page-title="$i18n{addressesTitle}"> + <settings-autofill-section id="autofillSection" prefs="{{prefs}}"> + </settings-autofill-section> </settings-subpage> </template> </settings-animated-pages> </template> - <script src="passwords_and_forms_page.js"></script> + <script src="autofill_page.js"></script> </dom-module> diff --git a/chromium/chrome/browser/resources/settings/autofill_page/autofill_page.js b/chromium/chrome/browser/resources/settings/autofill_page/autofill_page.js new file mode 100644 index 00000000000..4e9c3437081 --- /dev/null +++ b/chromium/chrome/browser/resources/settings/autofill_page/autofill_page.js @@ -0,0 +1,68 @@ +// Copyright 2015 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. + +/** + * @fileoverview + * 'settings-autofill-page' is the settings page containing settings for + * passwords, payment methods and addresses. + */ +Polymer({ + is: 'settings-autofill-page', + + behaviors: [PrefsBehavior], + + properties: { + /** @private Filter applied to passwords and password exceptions. */ + passwordFilter_: String, + + /** @private {!Map<string, string>} */ + focusConfig_: { + type: Object, + value: function() { + const map = new Map(); + if (settings.routes.PASSWORDS) { + map.set(settings.routes.PASSWORDS.path, '#passwordManagerButton'); + } + if (settings.routes.PAYMENTS) { + map.set(settings.routes.PAYMENTS.path, '#paymentManagerButton'); + } + if (settings.routes.ADDRESSES) { + map.set(settings.routes.ADDRESSES.path, '#addressesManagerButton'); + } + + return map; + }, + }, + }, + + /** + * Shows the manage addresses sub page. + * @param {!Event} event + * @private + */ + onAddressesClick_: function(event) { + settings.navigateTo(settings.routes.ADDRESSES); + }, + + /** + * Shows the manage payment methods sub page. + * @private + */ + onPaymentsClick_: function() { + settings.navigateTo(settings.routes.PAYMENTS); + }, + + /** + * Shows a page to manage passwords. This is either the passwords sub page or + * the Google Password Manager page. + * @private + */ + onPasswordsClick_: function() { + PasswordManagerImpl.getInstance().recordPasswordsPageAccessInSettings(); + loadTimeData.getBoolean('navigateToGooglePasswordManager') ? + settings.OpenWindowProxyImpl.getInstance().openURL( + loadTimeData.getString('googlePasswordManagerUrl')) : + settings.navigateTo(settings.routes.PASSWORDS); + }, +}); diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/autofill_section.html b/chromium/chrome/browser/resources/settings/autofill_page/autofill_section.html index 40e1bafdde8..77e48e1fb43 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/autofill_section.html +++ b/chromium/chrome/browser/resources/settings/autofill_page/autofill_section.html @@ -28,7 +28,7 @@ </style> <settings-toggle-button id="autofillProfileToggle" class="settings-box first" - aria-label="$i18n{autofill}" no-extension-indicator + aria-label="$i18n{addressesTitle}" no-extension-indicator label="$i18n{enableProfilesLabel}" sub-label="$i18n{enableProfilesSublabel}" pref="{{prefs.autofill.profile_enabled}}"> diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/autofill_section.js b/chromium/chrome/browser/resources/settings/autofill_page/autofill_section.js index 25bd70563bf..25bd70563bf 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/autofill_section.js +++ b/chromium/chrome/browser/resources/settings/autofill_page/autofill_section.js diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/credit_card_edit_dialog.html b/chromium/chrome/browser/resources/settings/autofill_page/credit_card_edit_dialog.html index 7138118d0c4..7138118d0c4 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/credit_card_edit_dialog.html +++ b/chromium/chrome/browser/resources/settings/autofill_page/credit_card_edit_dialog.html diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/credit_card_edit_dialog.js b/chromium/chrome/browser/resources/settings/autofill_page/credit_card_edit_dialog.js index 05e007984fe..a9f6c9de057 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/credit_card_edit_dialog.js +++ b/chromium/chrome/browser/resources/settings/autofill_page/credit_card_edit_dialog.js @@ -81,7 +81,7 @@ Polymer({ const date = new Date(); let firstYear = date.getFullYear(); - let lastYear = firstYear + 9; // Show next 9 years (10 total). + let lastYear = firstYear + 19; // Show next 19 years (20 total). let selectedYear = parseInt(this.creditCard.expirationYear, 10); // |selectedYear| must be valid and between first and last years. diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html b/chromium/chrome/browser/resources/settings/autofill_page/password_edit_dialog.html index 0cb6594b004..0cb6594b004 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html +++ b/chromium/chrome/browser/resources/settings/autofill_page/password_edit_dialog.html diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.js b/chromium/chrome/browser/resources/settings/autofill_page/password_edit_dialog.js index 2b353fb80d6..2b353fb80d6 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.js +++ b/chromium/chrome/browser/resources/settings/autofill_page/password_edit_dialog.js diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/password_list_item.html b/chromium/chrome/browser/resources/settings/autofill_page/password_list_item.html index cebf8673079..03ac15c5a69 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/password_list_item.html +++ b/chromium/chrome/browser/resources/settings/autofill_page/password_list_item.html @@ -4,6 +4,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="../focus_row_behavior.html"> <link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="../site_favicon.html"> <link rel="import" href="passwords_shared_css.html"> <link rel="import" href="show_password_behavior.html"> @@ -29,6 +30,10 @@ font-family: inherit; font-size: inherit; line-height: inherit; + } + + #username, + #password:not([type='password']) { text-overflow: ellipsis; } @@ -47,6 +52,7 @@ <div class="list-item" focus-row-container> <div class="website-column no-min-width" title="[[item.entry.loginPair.urls.link]]"> + <site-favicon url="[[item.entry.loginPair.urls.link]]"></site-favicon> <a id="originUrl" target="_blank" class="no-min-width" href="[[item.entry.loginPair.urls.link]]" focus-row-control focus-type="originUrl"> diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/password_list_item.js b/chromium/chrome/browser/resources/settings/autofill_page/password_list_item.js index 0c97de354b1..0c97de354b1 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/password_list_item.js +++ b/chromium/chrome/browser/resources/settings/autofill_page/password_list_item.js diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/password_manager_proxy.html b/chromium/chrome/browser/resources/settings/autofill_page/password_manager_proxy.html index e33c98a3d6b..e33c98a3d6b 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/password_manager_proxy.html +++ b/chromium/chrome/browser/resources/settings/autofill_page/password_manager_proxy.html diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/password_manager_proxy.js b/chromium/chrome/browser/resources/settings/autofill_page/password_manager_proxy.js index 3450e910b82..7c18929be5e 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/password_manager_proxy.js +++ b/chromium/chrome/browser/resources/settings/autofill_page/password_manager_proxy.js @@ -34,11 +34,16 @@ class PasswordManagerProxy { getSavedPasswordList(callback) {} /** + * Log that the Passwords page was accessed from the Chrome Settings WebUI. + */ + recordPasswordsPageAccessInSettings() {} + + /** * Should remove the saved password and notify that the list has changed. - * @param {number} index The index for the password entry being removed. - * No-op if |index| is not in the list. + * @param {number} id The id for the password entry being removed. + * No-op if |id| is not in the list. */ - removeSavedPassword(index) {} + removeSavedPassword(id) {} /** * Add an observer to the list of password exceptions. @@ -63,10 +68,10 @@ class PasswordManagerProxy { /** * Should remove the password exception and notify that the list has changed. - * @param {number} index The index for the exception url entry being removed. - * No-op if |index| is not in the list. + * @param {number} id The id for the exception url entry being removed. + * No-op if |id| is not in the list. */ - removeException(index) {} + removeException(id) {} /** * Should undo the last saved password or exception removal and notify that @@ -76,12 +81,12 @@ class PasswordManagerProxy { /** * Gets the saved password for a given login pair. - * @param {number} index The index for password entry that should be - * retrieved. No-op if |index| is not in the list. + * @param {number} id The id for password entry that should be + * retrieved. No-op if |id| is not in the list. * @param {function(!PasswordManagerProxy.PlaintextPasswordEvent):void} * callback */ - getPlaintextPassword(index, callback) {} + getPlaintextPassword(id, callback) {} /** * Triggers the dialogue for importing passwords. @@ -114,6 +119,8 @@ class PasswordManagerProxy { * listener */ removePasswordsFileExportProgressListener(listener) {} + + cancelExportPasswords() {} } /** @typedef {chrome.passwordsPrivate.PasswordUiEntry} */ @@ -161,8 +168,13 @@ class PasswordManagerImpl { } /** @override */ - removeSavedPassword(index) { - chrome.passwordsPrivate.removeSavedPassword(index); + recordPasswordsPageAccessInSettings() { + chrome.passwordsPrivate.recordPasswordsPageAccessInSettings(); + } + + /** @override */ + removeSavedPassword(id) { + chrome.passwordsPrivate.removeSavedPassword(id); } /** @override */ @@ -183,8 +195,8 @@ class PasswordManagerImpl { } /** @override */ - removeException(index) { - chrome.passwordsPrivate.removePasswordException(index); + removeException(id) { + chrome.passwordsPrivate.removePasswordException(id); } /** @override */ @@ -193,17 +205,17 @@ class PasswordManagerImpl { } /** @override */ - getPlaintextPassword(index, callback) { + getPlaintextPassword(id, callback) { const listener = function(reply) { // Only handle the reply for our loginPair request. - if (reply.index == index) { + if (reply.id == id) { chrome.passwordsPrivate.onPlaintextPasswordRetrieved.removeListener( listener); callback(reply); } }; chrome.passwordsPrivate.onPlaintextPasswordRetrieved.addListener(listener); - chrome.passwordsPrivate.requestPlaintextPassword(index); + chrome.passwordsPrivate.requestPlaintextPassword(id); } /** @override */ @@ -231,6 +243,11 @@ class PasswordManagerImpl { chrome.passwordsPrivate.onPasswordsFileExportProgress.removeListener( listener); } + + /** @override */ + cancelExportPasswords() { + chrome.passwordsPrivate.cancelExportPasswords(); + } } cr.addSingletonGetter(PasswordManagerImpl); diff --git a/chromium/chrome/browser/resources/settings/autofill_page/passwords_export_dialog.html b/chromium/chrome/browser/resources/settings/autofill_page/passwords_export_dialog.html new file mode 100644 index 00000000000..a46cee60547 --- /dev/null +++ b/chromium/chrome/browser/resources/settings/autofill_page/passwords_export_dialog.html @@ -0,0 +1,82 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-progress/paper-progress.html"> +<link rel="import" href="../settings_shared_css.html"> + +<dom-module id="passwords-export-dialog"> + <template> + <style include="settings-shared iron-flex"> + paper-progress { + width: 100%; + --paper-progress-active-color: var(--google-blue-500); + } + .action-button { + margin-inline-start: 8px; + } + </style> + <template is="dom-if" if="[[showStartDialog_]]" restamp> + <cr-dialog id="dialog_start" close-text="$i18n{close}" show-on-attach> + <div slot="title">$i18n{exportPasswordsTitle}</div> + <div slot="body"> + <div class="layout horizontal center"> + <div>$i18n{exportPasswordsDescription}</div> + </div> + </div> + <div slot="button-container"> + <paper-button class="secondary-button header-aligned-button" + on-click="onCancelButtonTap_" id="cancelButton"> + $i18n{cancel} + </paper-button> + <paper-button class="action-button header-aligned-button" + on-click="onExportTap_" id="exportPasswordsButton"> + $i18n{exportPasswords} + </paper-button> + </div> + </cr-dialog> + </template> + + <template is="dom-if" if="[[showProgressDialog_]]" restamp> + <cr-dialog id="dialog_progress" no-cancel="true" show-on-attach> + <div slot="title">$i18n{exportingPasswordsTitle}</div> + <div slot="body"> + <paper-progress indeterminate class="blue"></paper-progress> + </div> + <div slot="button-container"> + <paper-button id="cancel_progress_button" + class="secondary-button header-aligned-button" + on-click="onCancelProgressButtonTap_"> + $i18n{cancel} + </paper-button> + </div> + </cr-dialog> + </template> + + <template is="dom-if" if="[[showErrorDialog_]]" restamp> + <cr-dialog id="dialog_error" close-text="$i18n{close}" show-on-attach> + <div slot="title">[[exportErrorMessage]]</div> + <div slot="body"> + $i18n{exportPasswordsFailTips} + <ul> + <li>$i18n{exportPasswordsFailTipsEnoughSpace}</li> + <li>$i18n{exportPasswordsFailTipsAnotherFolder}</li> + </ul> + </div> + <div slot="button-container"> + <paper-button class="secondary-button header-aligned-button" + on-click="onCancelButtonTap_" id="cancelErrorButton"> + $i18n{cancel} + </paper-button> + <paper-button class="action-button header-aligned-button" + on-click="onExportTap_" id="tryAgainButton"> + $i18n{exportPasswordsTryAgain} + </paper-button> + </div> + </cr-dialog> + </template> + + </template> + <script src="passwords_export_dialog.js"></script> +</dom-module> diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_export_dialog.js b/chromium/chrome/browser/resources/settings/autofill_page/passwords_export_dialog.js index b888dc0c1e4..6b3444712c0 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_export_dialog.js +++ b/chromium/chrome/browser/resources/settings/autofill_page/passwords_export_dialog.js @@ -43,9 +43,20 @@ Polymer({ properties: { /** The error that occurred while exporting. */ exportErrorMessage: String, + + /** @private */ + showStartDialog_: Boolean, + + /** @private */ + showProgressDialog_: Boolean, + + /** @private */ + showErrorDialog_: Boolean, }, - listeners: {'cancel': 'close'}, + listeners: { + 'cancel': 'close', + }, /** * The interface for callbacks to the browser. @@ -157,12 +168,10 @@ Polymer({ this.delayedCompletionToken_ = null; this.passwordManager_.removePasswordsFileExportProgressListener( this.onPasswordsFileExportProgressListener_); - if (this.$.dialog_start.open) - this.$.dialog_start.close(); - if (this.$.dialog_progress.open) - this.$.dialog_progress.close(); - if (this.$.dialog_error.open) - this.$.dialog_error.close(); + this.showStartDialog_ = false; + this.showProgressDialog_ = false; + this.showErrorDialog_ = false; + this.fire('passwords-export-dialog-close'); }, /** @@ -210,16 +219,9 @@ Polymer({ * @private */ switchToDialog_(state) { - this.$.dialog_start.open = false; - this.$.dialog_error.open = false; - this.$.dialog_progress.open = false; - - if (state == States.START) - this.$.dialog_start.showModal(); - if (state == States.ERROR) - this.$.dialog_error.showModal(); - if (state == States.IN_PROGRESS) - this.$.dialog_progress.showModal(); + this.showStartDialog_ = state == States.START; + this.showProgressDialog_ = state == States.IN_PROGRESS; + this.showErrorDialog_ = state == States.ERROR; }, /** diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.html b/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.html index 2d8ef4c9654..8705de3bfd9 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.html +++ b/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.html @@ -17,6 +17,7 @@ <link rel="import" href="../global_scroll_target_behavior.html"> <link rel="import" href="../prefs/prefs.html"> <link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="../site_favicon.html"> <link rel="import" href="password_edit_dialog.html"> <link rel="import" href="passwords_export_dialog.html"> <link rel="import" href="passwords_shared_css.html"> @@ -111,7 +112,7 @@ <template> <password-list-item item="[[item]]" tabindex$="[[tabIndex]]" first$="[[!index]]" iron-list-tab-index="[[tabIndex]]" - last-focused="{{lastFocused_}}"> + last-focused="{{lastFocused_}}" list-blurred="{{listBlurred_}}"> </password-list-item> </template> </iron-list> @@ -137,7 +138,8 @@ </button> </cr-action-menu> <template is="dom-if" if="[[showPasswordsExportDialog_]]" restamp> - <passwords-export-dialog on-close="onPasswordsExportDialogClosed_"> + <passwords-export-dialog + on-passwords-export-dialog-close="onPasswordsExportDialogClosed_"> </passwords-export-dialog> </template> <template is="dom-if" if="[[showPasswordEditDialog_]]" restamp> @@ -158,7 +160,8 @@ <template is="dom-repeat" items="[[passwordExceptions]]" filter="[[passwordExceptionFilter_(filter)]]"> <div class="list-item"> - <div class="start"> + <div class="start website-column"> + <site-favicon url="[[item.urls.link]]"></site-favicon> <a id="exception" href="[[item.urls.link]]" target="_blank"> [[item.urls.shown]] </a> diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.js b/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.js index 51f7116b326..447a034db36 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_section.js +++ b/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.js @@ -78,7 +78,7 @@ Polymer({ /** @override */ subpageRoute: { type: Object, - value: settings.routes.MANAGE_PASSWORDS, + value: settings.routes.PASSWORDS, }, /** @@ -119,6 +119,9 @@ Polymer({ /** @private {!PasswordManagerProxy.UiEntryWithPassword} */ lastFocused_: Object, + + /** @private */ + listBlurred_: Boolean, }, listeners: { @@ -163,29 +166,13 @@ Polymer({ /** @override */ attached: function() { - // The item uid is built from index, origin, and username for the - // following reasons: origin and username are enough to describe and - // uniquely identify an entry. It is impossible to have two entries - // that have the same origin and username, but different passwords, - // as the password update logic prevents these cases. The entry is - // required to force a refresh of entries, after a removal or undo of - // a removal has taken place. All entries before the point of - // modification are uneffected, but the ones following need to be - // refreshed. Including the index in the uid achieves this effect. - // See https://crbug.com/862119 how this could lead to bugs otherwise. - const getItemUid = - item => [item.entry.index, item.entry.loginPair.urls.origin, - item.entry.loginPair.username] - .join('_'); - // Create listener functions. const setSavedPasswordsListener = list => { const newList = list.map(entry => ({entry: entry, password: ''})); - this.updateList('savedPasswords', getItemUid, newList); - this.savedPasswords.forEach((item, index) => { - item.password = ''; - this.$.passwordList.notifyPath(`items.${index}.password`); - }); + // Because the backend guarantees that item.entry.id uniquely identifies a + // given entry and is stable with regard to mutations to the list, it is + // sufficient to just use this id to create a item uid. + this.updateList('savedPasswords', item => item.entry.id, newList); }; const setPasswordExceptionsListener = list => { @@ -284,7 +271,7 @@ Polymer({ */ onMenuRemovePasswordTap_: function() { this.passwordManager_.removeSavedPassword( - this.activePassword.item.entry.index); + this.activePassword.item.entry.id); this.fire('iron-announce', {text: this.$.undoLabel.textContent}); this.$.undoToast.show(); /** @type {CrActionMenuElement} */ (this.$.menu).close(); @@ -316,7 +303,7 @@ Polymer({ * @private */ onRemoveExceptionButtonTap_: function(e) { - this.passwordManager_.removeException(e.model.item.index); + this.passwordManager_.removeException(e.model.item.id); }, /** @@ -389,8 +376,13 @@ Polymer({ */ showPassword_: function(event) { this.passwordManager_.getPlaintextPassword( - /** @type {!number} */ (event.detail.item.entry.index), item => { - event.detail.set('item.password', item.plaintextPassword); + /** @type {!number} */ (event.detail.item.entry.id), item => { + // Note: We are explicitly not using event.detail.set() here, as that + // would not trigger notifyPath if event.detail.item.password is + // already equal to item.plaintextPassword. See crbug/910081 for more + // details. + event.detail.item.password = item.plaintextPassword; + event.detail.notifyPath('item.password'); }); }, diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_shared_css.html b/chromium/chrome/browser/resources/settings/autofill_page/passwords_shared_css.html index 62693628167..9c26b98da57 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_shared_css.html +++ b/chromium/chrome/browser/resources/settings/autofill_page/passwords_shared_css.html @@ -12,10 +12,15 @@ } .website-column { + align-items: center; display: flex; flex: 1; } + .website-column > a { + color: var(--google-grey-900); + } + .username-column { flex: 1; margin: 0 8px; @@ -47,6 +52,11 @@ text-overflow: ellipsis; white-space: nowrap; } + + site-favicon { + margin-inline-end: 16px; + min-width: 16px; + } </style> </template> </dom-module> diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/payments_section.html b/chromium/chrome/browser/resources/settings/autofill_page/payments_section.html index 2a98ce1f445..d0f5cd446d2 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/payments_section.html +++ b/chromium/chrome/browser/resources/settings/autofill_page/payments_section.html @@ -75,7 +75,7 @@ prefs.autofill.credit_card_enabled.value)]]" on-click="onMigrateCreditCardsClick_" actionable> <div class="start"> - [[migrateCreditCardsLabel_]] + $i18n{migrateCreditCardsLabel} <div class="secondary"> [[migratableCreditCardsInfo_]] </div> diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/payments_section.js b/chromium/chrome/browser/resources/settings/autofill_page/payments_section.js index 2166bfa9b4f..068da8fef94 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/payments_section.js +++ b/chromium/chrome/browser/resources/settings/autofill_page/payments_section.js @@ -46,6 +46,11 @@ class PaymentsManager { * Migrate the local credit cards. */ migrateCreditCards() {} + + /** + * Logs that the server cards edit link was clicked. + */ + logServerCardLinkClicked() {} } /** @typedef {chrome.autofillPrivate.CreditCardEntry} */ @@ -90,6 +95,11 @@ class PaymentsManagerImpl { migrateCreditCards() { chrome.autofillPrivate.migrateCreditCards(); } + + /** @override */ + logServerCardLinkClicked() { + chrome.autofillPrivate.logServerCardLinkClicked(); + } } cr.addSingletonGetter(PaymentsManagerImpl); @@ -122,9 +132,6 @@ Polymer({ showCreditCardDialog_: Boolean, /** @private */ - migrateCreditCardsLabel_: String, - - /** @private */ migratableCreditCardsInfo_: String, /** @@ -346,6 +353,7 @@ Polymer({ /** @private */ onRemoteEditCreditCardTap_: function() { + this.paymentsManager_.logServerCardLinkClicked(); window.open(loadTimeData.getString('manageCreditCardsUrl')); }, @@ -472,11 +480,6 @@ Polymer({ if (numberOfMigratableCreditCard == 0) return false; - // Update the display label depends on the number of migratable credit - // cards. - this.migrateCreditCardsLabel_ = numberOfMigratableCreditCard == 1 ? - this.i18n('migrateCreditCardsLabelSingle') : - this.i18n('migrateCreditCardsLabelMultiple'); // Update the display text depends on the number of migratable credit cards. this.migratableCreditCardsInfo_ = numberOfMigratableCreditCard == 1 ? this.i18n('migratableCardsInfoSingle') : diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/show_password_behavior.html b/chromium/chrome/browser/resources/settings/autofill_page/show_password_behavior.html index 73ee8c03754..73ee8c03754 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/show_password_behavior.html +++ b/chromium/chrome/browser/resources/settings/autofill_page/show_password_behavior.html diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/show_password_behavior.js b/chromium/chrome/browser/resources/settings/autofill_page/show_password_behavior.js index ae1bfe04aae..25cdf666e0e 100644 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/show_password_behavior.js +++ b/chromium/chrome/browser/resources/settings/autofill_page/show_password_behavior.js @@ -74,7 +74,8 @@ const ShowPasswordBehavior = { }, }; -/** @typedef {{ +/** + * @typedef {{ * entry: !chrome.passwordsPrivate.PasswordUiEntry, * password: string * }} diff --git a/chromium/chrome/browser/resources/settings/basic_page/basic_page.html b/chromium/chrome/browser/resources/settings/basic_page/basic_page.html index 2e8fb6c622b..a99337c3d25 100644 --- a/chromium/chrome/browser/resources/settings/basic_page/basic_page.html +++ b/chromium/chrome/browser/resources/settings/basic_page/basic_page.html @@ -3,6 +3,7 @@ <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> <link rel="import" href="../appearance_page/appearance_page.html"> +<link rel="import" href="../autofill_page/autofill_page.html"> <link rel="import" href="../change_password_page/change_password_page.html"> <link rel="import" href="../controls/settings_idle_load.html"> <link rel="import" href="../on_startup_page/on_startup_page.html"> @@ -137,11 +138,19 @@ <settings-section page-title="$i18n{peoplePageTitle}" section="people"> <settings-people-page prefs="{{prefs}}" - autofill-home-enabled="[[autofillHomeEnabled]]" page-visibility="[[pageVisibility]]"> </settings-people-page> </settings-section> </template> + <template is="dom-if" if="[[showPage_(pageVisibility.autofill)]]" + restamp> + <settings-section page-title="$i18n{autofillPageTitle}" + section="autofill"> + <settings-autofill-page prefs="{{prefs}}" + page-visibility="[[pageVisibility]]"> + </settings-autofill-page> + </settings-section> + </template> <template is="dom-if" if="[[showPage_(pageVisibility.appearance)]]" restamp> <settings-section page-title="$i18n{appearancePageTitle}" @@ -220,9 +229,8 @@ inSearchMode, hasExpandedSection_)]]"> <div id="toggleSpacer"></div> <h2 id="toggleContainer"> - <paper-button id="advancedToggle" - aria-active-attribute="aria-expanded" - on-click="advancedToggleClicked_"> + <paper-button id="advancedToggle" on-click="advancedToggleClicked_" + aria-expanded$="[[boolToString_(advancedToggleExpanded)]]"> <span>$i18n{advancedPageTitle}</span> <iron-icon icon="[[getArrowIcon_(advancedToggleExpanded)]]"> </iron-icon> @@ -255,16 +263,6 @@ </settings-privacy-page> </settings-section> </template> - <template is="dom-if" if="[[shouldShowPasswordsAndForms_( - autofillHomeEnabled, pageVisibility)]]" - restamp> - <settings-section - page-title="$i18n{passwordsAndAutofillPageTitle}" - section="passwordsAndForms"> - <settings-passwords-and-forms-page prefs="{{prefs}}"> - </settings-passwords-and-forms-page> - </settings-section> - </template> <template is="dom-if" if="[[showPage_(pageVisibility.languages)]]" restamp> <settings-section page-title="$i18n{languagesPageTitle}" diff --git a/chromium/chrome/browser/resources/settings/basic_page/basic_page.js b/chromium/chrome/browser/resources/settings/basic_page/basic_page.js index d1cfd95862f..503d28346af 100644 --- a/chromium/chrome/browser/resources/settings/basic_page/basic_page.js +++ b/chromium/chrome/browser/resources/settings/basic_page/basic_page.js @@ -28,10 +28,6 @@ Polymer({ havePlayStoreApp: Boolean, // </if> - // TODO(jdoerrie): https://crbug.com/854562. - // Remove once Autofill Home is launched. - autofillHomeEnabled: Boolean, - /** @type {!AndroidAppsInfo|undefined} */ androidAppsInfo: Object, @@ -162,6 +158,12 @@ Polymer({ return visibility !== false; }, + focusSection: function() { + const section = this.getSection(settings.getCurrentRoute().section); + assert(section); + section.show(); + }, + /** * Queues a task to search the basic sections, then another for the advanced * sections. @@ -254,19 +256,6 @@ Polymer({ }, /** - * @return {boolean} Whether to show the passwords and forms settings page. - * TODO(jdoerrie): https://crbug.com/854562. With Autofill Home enabled, - * the passwords and autofill sections are moved from the advanced page - * to the people page. Remove once Autofill Home is fully launched. - * @private - */ - shouldShowPasswordsAndForms_: function() { - const visibility = /** @type {boolean|undefined} */ ( - this.get('pageVisibility.passwordAndForms')); - return !this.autofillHomeEnabled && this.showPage_(visibility); - }, - - /** * Hides everything but the newly expanded subpage. * @private */ @@ -381,4 +370,13 @@ Polymer({ getArrowIcon_: function(opened) { return opened ? 'cr:arrow-drop-up' : 'cr:arrow-drop-down'; }, + + /** + * @param {boolean} bool + * @return {string} + * @private + */ + boolToString_: function(bool) { + return bool.toString(); + }, }); diff --git a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js index f532340394a..8c3ddb39bc9 100644 --- a/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js +++ b/chromium/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js @@ -162,11 +162,14 @@ Polymer({ }, /** + * @param {boolean} bluetoothToggleState * @return {string} * @private */ - getIcon_: function() { - if (!this.bluetoothToggleState_) + getIcon_: function(bluetoothToggleState) { + // Don't use |this.bluetoothToggleState_| here, since it has not been + // updated yet to the latest value. + if (!bluetoothToggleState) return 'settings:bluetooth-disabled'; return 'cr:bluetooth'; }, diff --git a/chromium/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.html b/chromium/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.html index 58c03b73681..b57ce4d8b70 100644 --- a/chromium/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.html +++ b/chromium/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.html @@ -35,9 +35,9 @@ width: 100%; } - /* Used by |chromeCleanupPoweredByHTML| */ - #powered-by-logo { - content: url(chrome://settings/partner-logo.svg); + /* Apply a fixed height to the <svg> tag inside #powered-by-logo. + Used by |chromeCleanupPoweredByHTML|. */ + #powered-by-logo > svg { height: 22px; } diff --git a/chromium/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.html b/chromium/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.html index fcc7a40491c..1a086904cc3 100644 --- a/chromium/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.html +++ b/chromium/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.html @@ -113,7 +113,7 @@ <div>$i18n{clearBrowsingData}</div> </div> <div slot="header"> - <paper-tabs noink on-selected-changed="recordTabChange_" + <paper-tabs noink on-selected-changed="recordTabChange_" autoselect selected="{{prefs.browser.last_clear_browsing_data_tab.value}}"> <paper-tab id="basicTabTitle">$i18n{basicPageTitle}</paper-tab> <paper-tab id="advancedTabTitle">$i18n{advancedPageTitle}</paper-tab> diff --git a/chromium/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.js b/chromium/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.js index 8108941b439..ba8db324139 100644 --- a/chromium/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.js +++ b/chromium/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.js @@ -22,6 +22,7 @@ Polymer({ /** * The current sync status, supplied by SyncBrowserProxy. + * TODO(dpapad): make |syncStatus| private. * @type {?settings.SyncStatus} */ syncStatus: Object, @@ -389,10 +390,19 @@ Polymer({ if (e.target.tagName === 'A') { e.preventDefault(); if (!this.syncStatus.hasError) { + chrome.metricsPrivate.recordUserAction('ClearBrowsingData_Sync_Pause'); this.syncBrowserProxy_.pauseSync(); } else if (this.isSyncPaused_) { + chrome.metricsPrivate.recordUserAction('ClearBrowsingData_Sync_SignIn'); this.syncBrowserProxy_.startSignIn(); } else { + if (this.hasPassphraseError_) { + chrome.metricsPrivate.recordUserAction( + 'ClearBrowsingData_Sync_NavigateToPassphrase'); + } else { + chrome.metricsPrivate.recordUserAction( + 'ClearBrowsingData_Sync_NavigateToError'); + } // In any other error case, navigate to the sync page. settings.navigateTo(settings.routes.SYNC); } @@ -431,6 +441,6 @@ Polymer({ * @private */ shouldShowFooter_: function() { - return this.diceEnabled_ && !!this.syncStatus.signedIn; + return this.diceEnabled_ && !!this.syncStatus && !!this.syncStatus.signedIn; }, }); diff --git a/chromium/chrome/browser/resources/settings/controls/controlled_button.html b/chromium/chrome/browser/resources/settings/controls/controlled_button.html index e76e3584ea7..062e4c2072f 100644 --- a/chromium/chrome/browser/resources/settings/controls/controlled_button.html +++ b/chromium/chrome/browser/resources/settings/controls/controlled_button.html @@ -31,8 +31,6 @@ } :host(:not([end-justified])) cr-policy-pref-indicator { - margin-inline-end: calc( - var(--cr-controlled-by-spacing) - var(--justify-margin)); margin-inline-start: var(--cr-controlled-by-spacing); } @@ -44,7 +42,10 @@ } </style> - <paper-button disabled="[[enforced_]]">[[label]]</paper-button> + <paper-button class$="[[getClass_(actionButton)]]" + disabled="[[!buttonEnabled_(enforced_, disabled)]]"> + [[label]] + </paper-button> <template is="dom-if" if="[[hasPrefPolicyIndicator(pref.*)]]" restamp> <cr-policy-pref-indicator pref="[[pref]]" on-click="onIndicatorTap_" diff --git a/chromium/chrome/browser/resources/settings/controls/controlled_button.js b/chromium/chrome/browser/resources/settings/controls/controlled_button.js index 49d46860349..eef0645228c 100644 --- a/chromium/chrome/browser/resources/settings/controls/controlled_button.js +++ b/chromium/chrome/browser/resources/settings/controls/controlled_button.js @@ -11,6 +11,11 @@ Polymer({ ], properties: { + actionButton: { + type: Boolean, + value: false, + }, + endJustified: { type: Boolean, value: false, @@ -19,6 +24,12 @@ Polymer({ label: String, + disabled: { + type: Boolean, + value: false, + reflectToAttribute: true, + }, + /** @private */ enforced_: { type: Boolean, @@ -36,4 +47,23 @@ Polymer({ e.preventDefault(); e.stopPropagation(); }, + + /** + * @param {!boolean} actionButton + * @return {string} Class of the paper-button. + * @private + */ + getClass_: function(actionButton) { + return actionButton ? "action-button" : ""; + }, + + /** + * @param {!boolean} enforced + * @param {!boolean} disabled + * @return {boolean} True if the button should be enabled. + * @private + */ + buttonEnabled_(enforced, disabled) { + return !enforced && !disabled; + } }); diff --git a/chromium/chrome/browser/resources/settings/controls/controlled_radio_button.js b/chromium/chrome/browser/resources/settings/controls/controlled_radio_button.js index 19bbcef638b..3c0a4ab90d0 100644 --- a/chromium/chrome/browser/resources/settings/controls/controlled_radio_button.js +++ b/chromium/chrome/browser/resources/settings/controls/controlled_radio_button.js @@ -10,39 +10,14 @@ Polymer({ CrRadioButtonBehavior, ], - properties: { - disabled: { - type: Boolean, - computed: 'computeDisabled_(pref.*)', - reflectToAttribute: true, - observer: 'disabledChanged_', - }, - - name: { - type: String, - notify: true, - }, - }, - - /** - * @return {boolean} Whether the button is disabled. - * @private - */ - computeDisabled_: function() { - return this.pref.enforcement == chrome.settingsPrivate.Enforcement.ENFORCED; - }, - - /** - * @param {boolean} current - * @param {boolean} previous - * @private - */ - disabledChanged_: function(current, previous) { - if (previous === undefined && !this.disabled) - return; + observers: [ + 'updateDisabled_(pref.enforcement)', + ], - this.setAttribute('tabindex', this.disabled ? -1 : 0); - this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false'); + /** @private */ + updateDisabled_: function() { + this.disabled = + this.pref.enforcement == chrome.settingsPrivate.Enforcement.ENFORCED; }, /** diff --git a/chromium/chrome/browser/resources/settings/controls/pref_control_behavior.js b/chromium/chrome/browser/resources/settings/controls/pref_control_behavior.js index cf53c6dcad4..70f6fab682f 100644 --- a/chromium/chrome/browser/resources/settings/controls/pref_control_behavior.js +++ b/chromium/chrome/browser/resources/settings/controls/pref_control_behavior.js @@ -30,7 +30,7 @@ const PrefControlBehavior = { */ validatePref_: function() { CrSettingsPrefs.initialized.then(() => { - if (!this.pref) { + if (this.pref === undefined) { let error = 'Pref not found for element ' + this.tagName; if (this.id) error += '#' + this.id; diff --git a/chromium/chrome/browser/resources/settings/controls/settings_radio_group.html b/chromium/chrome/browser/resources/settings/controls/settings_radio_group.html index 8bc90c2aeba..1e37711850a 100644 --- a/chromium/chrome/browser/resources/settings/controls/settings_radio_group.html +++ b/chromium/chrome/browser/resources/settings/controls/settings_radio_group.html @@ -1,7 +1,7 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-group/paper-radio-group.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_radio_group/cr_radio_group.html"> <link rel="import" href="pref_control_behavior.html"> <link rel="import" href="../prefs/pref_util.html"> <link rel="import" href="../settings_shared_css.html"> @@ -10,10 +10,10 @@ <template> <style include="settings-shared"></style> <div>[[label]]</div> - <paper-radio-group selected="{{selected}}" - selectable="cr-radio-button, controlled-radio-button"> + <cr-radio-group selected="[[selected]]" + on-selected-changed="onSelectedChanged_"> <slot></slot> - </paper-radio-group> + </cr-radio-group> </template> <script src="settings_radio_group.js"></script> </dom-module> diff --git a/chromium/chrome/browser/resources/settings/controls/settings_radio_group.js b/chromium/chrome/browser/resources/settings/controls/settings_radio_group.js index 3e5885b1dac..00a1f202626 100644 --- a/chromium/chrome/browser/resources/settings/controls/settings_radio_group.js +++ b/chromium/chrome/browser/resources/settings/controls/settings_radio_group.js @@ -4,8 +4,8 @@ /** * @fileoverview - * `cr-radio-group` wraps a radio-group and set of radio-buttons that control - * a supplied preference. + * `settings-radio-group` wraps cr-radio-group and set of radio-buttons that + * control a supplied preference. * * Example: * <settings-radio-group pref="{{prefs.settings.foo}}" @@ -18,10 +18,7 @@ Polymer({ behaviors: [PrefControlBehavior], properties: { - /** - * IronSelectableBehavior selected attribute. - */ - selected: {type: String, notify: true, observer: 'selectedChanged_'}, + selected: String, }, hostAttributes: { @@ -39,10 +36,12 @@ Polymer({ }, /** @private */ - selectedChanged_: function(selected) { + onSelectedChanged_: function() { if (!this.pref) return; + this.selected = this.$$('cr-radio-group').selected; this.set( - 'pref.value', Settings.PrefUtil.stringToPrefValue(selected, this.pref)); + 'pref.value', + Settings.PrefUtil.stringToPrefValue(this.selected, this.pref)); }, }); diff --git a/chromium/chrome/browser/resources/settings/controls/settings_toggle_button.html b/chromium/chrome/browser/resources/settings/controls/settings_toggle_button.html index 60612bf0836..91963de86f8 100644 --- a/chromium/chrome/browser/resources/settings/controls/settings_toggle_button.html +++ b/chromium/chrome/browser/resources/settings/controls/settings_toggle_button.html @@ -46,7 +46,7 @@ #labelWrapper, ::slotted([slot='more-actions']) { - margin-inline-end: var(--settings-control-label-spacing); + margin-inline-end: var(--settings-control-label-spacing) !important; } cr-policy-pref-indicator { diff --git a/chromium/chrome/browser/resources/settings/device_page/device_page.js b/chromium/chrome/browser/resources/settings/device_page/device_page.js index 46c32cde32e..853e5249b63 100644 --- a/chromium/chrome/browser/resources/settings/device_page/device_page.js +++ b/chromium/chrome/browser/resources/settings/device_page/device_page.js @@ -61,8 +61,9 @@ Polymer({ hideStorageInfo_: { type: Boolean, value: function() { - return loadTimeData.valueExists('hideStorageInfo') && - loadTimeData.getBoolean('hideStorageInfo'); + // TODO(crbug.com/868747): Show an explanatory message instead. + return loadTimeData.valueExists('isDemoSession') && + loadTimeData.getBoolean('isDemoSession'); }, readOnly: true, }, diff --git a/chromium/chrome/browser/resources/settings/device_page/device_page_browser_proxy.js b/chromium/chrome/browser/resources/settings/device_page/device_page_browser_proxy.js index 3a1a47e19d4..3c477e64375 100644 --- a/chromium/chrome/browser/resources/settings/device_page/device_page_browser_proxy.js +++ b/chromium/chrome/browser/resources/settings/device_page/device_page_browser_proxy.js @@ -90,8 +90,8 @@ cr.define('settings', function() { /** Initializes the keyboard WebUI handler. */ initializeKeyboard() {} - /** Shows the Ash keyboard shortcuts overlay. */ - showKeyboardShortcutsOverlay() {} + /** Shows the Ash keyboard shortcut viewer. */ + showKeyboardShortcutViewer() {} /** Requests a power status update. */ updatePowerStatus() {} @@ -173,8 +173,8 @@ cr.define('settings', function() { } /** @override */ - showKeyboardShortcutsOverlay() { - chrome.send('showKeyboardShortcutsOverlay'); + showKeyboardShortcutViewer() { + chrome.send('showKeyboardShortcutViewer'); } /** @override */ diff --git a/chromium/chrome/browser/resources/settings/device_page/display.html b/chromium/chrome/browser/resources/settings/device_page/display.html index 8c7b74251e8..44197195574 100644 --- a/chromium/chrome/browser/resources/settings/device_page/display.html +++ b/chromium/chrome/browser/resources/settings/device_page/display.html @@ -4,6 +4,7 @@ <link rel="import" href="chrome://resources/cr_elements/cr_link_row/cr_link_row.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html"> <link rel="import" href="chrome://resources/cr_elements/paper_tabs_style_css.html"> +<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html"> <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> @@ -54,6 +55,10 @@ padding-inline-start: 0 } + .settings-box > cr-policy-pref-indicator { + margin-inline-end: var(--cr-controlled-by-spacing); + } + #controlsDiv > .settings-box:first-of-type { border-top: none; } @@ -146,10 +151,20 @@ [[logicalResolutionText_]] </div> </div> + <template is="dom-if" if="[[isDisplayScaleManagedByPolicy_( + selectedDisplay, prefs.cros.device_display_resolution)]]"> + <cr-policy-pref-indicator + pref="[[prefs.cros.device_display_resolution]]" + icon-aria-label="$i18n{displayResolutionText}"> + </cr-policy-pref-indicator> + </template> <settings-slider id="displaySizeSlider" ticks="[[zoomValues_]]" pref="{{selectedZoomPref_}}" label-min="$i18n{displaySizeSliderMinLabel}" label-max="$i18n{displaySizeSliderMaxLabel}" + disabled="[[isDisplayScaleMandatory_( + selectedDisplay, + prefs.cros.device_display_resolution)]]" on-value-changed="onDisplaySizeSliderDrag_"> </settings-slider> </div> @@ -163,8 +178,17 @@ $i18n{displayResolutionSublabel} </div> </div> + <template is="dom-if" if="[[isDisplayResolutionManagedByPolicy_( + prefs.cros.device_display_resolution)]]"> + <cr-policy-pref-indicator + pref="[[prefs.cros.device_display_resolution]]" + icon-aria-label="$i18n{displayResolutionText}"> + </cr-policy-pref-indicator> + </template> <settings-dropdown-menu id="displayModeSelector" pref="{{selectedModePref_}}" + disabled="[[isDisplayResolutionMandatory_( + prefs.cros.device_display_resolution)]]" label="Display Mode Menu" menu-options="[[displayModeList_]]"> </settings-dropdown-menu> @@ -174,6 +198,13 @@ <div id="displayOrientation" class="start text-area"> $i18n{displayOrientation} </div> + <template is="dom-if" if="[[isDevicePolicyEnabled_( + prefs.cros.display_rotation_default)]]"> + <cr-policy-pref-indicator + pref="[[prefs.cros.display_rotation_default]]" + icon-aria-label="$i18n{displayOrientation}"> + </cr-policy-pref-indicator> + </template> <select class="md-select" value="[[selectedDisplay.rotation]]" disabled="[[selectedDisplay.isTabletMode]]" aria-labelledby="displayOrientation" diff --git a/chromium/chrome/browser/resources/settings/device_page/display.js b/chromium/chrome/browser/resources/settings/device_page/display.js index cbe128d4462..51ddbb4e8d9 100644 --- a/chromium/chrome/browser/resources/settings/device_page/display.js +++ b/chromium/chrome/browser/resources/settings/device_page/display.js @@ -18,6 +18,20 @@ const NightLightScheduleType = { CUSTOM: 2, }; +/** + * @typedef {{ + * value: (!{ + * recommended: (boolean|undefined), + * external_width: (number|undefined), + * external_height: (number|undefined), + * external_use_native: (boolean|undefined), + * external_scale_percentage: (number|undefined), + * internal_scale_percentage: (number|undefined) + * }|null) + * }} + */ +let DisplayResolutionPrefObject; + cr.define('settings.display', function() { const systemDisplayApi = /** @type {!SystemDisplay} */ (chrome.system.display); @@ -182,7 +196,7 @@ Polymer({ 'updateNightLightScheduleSettings_(prefs.ash.night_light.schedule_type.*,' + ' prefs.ash.night_light.enabled.*)', 'onSelectedModeChange_(selectedModePref_.value)', - 'onSelectedZoomChange_(selectedZoomPref_.value)', + 'onSelectedZoomChange_(selectedZoomPref_.value)' ], /** @private {number} Selected mode index received from chrome. */ @@ -285,6 +299,69 @@ Polymer({ }, /** + * Checks if the given device policy is enabled. + * @param {DisplayResolutionPrefObject} policyPref + * @return {boolean} + * @private + */ + isDevicePolicyEnabled_: function(policyPref) { + return policyPref !== undefined && policyPref.value !== null; + }, + + /** + * Checks if display resolution is managed by device policy. + * @param {DisplayResolutionPrefObject} resolutionPref + * @return {boolean} + * @private + */ + isDisplayResolutionManagedByPolicy_: function(resolutionPref) { + return this.isDevicePolicyEnabled_(resolutionPref) && + (resolutionPref.value.external_use_native !== undefined || + (resolutionPref.value.external_width !== undefined && + resolutionPref.value.external_height !== undefined)); + }, + + /** + * Checks if display resolution is managed by policy and the policy + * is mandatory. + * @param {DisplayResolutionPrefObject} resolutionPref + * @return {boolean} + * @private + */ + isDisplayResolutionMandatory_: function(resolutionPref) { + return this.isDisplayResolutionManagedByPolicy_(resolutionPref) && + !resolutionPref.value.recommended; + }, + + /** + * Checks if display scale factor is managed by device policy. + * @param {chrome.system.display.DisplayUnitInfo} selectedDisplay + * @param {DisplayResolutionPrefObject} resolutionPref + * @return {boolean} + * @private + */ + isDisplayScaleManagedByPolicy_: function(selectedDisplay, resolutionPref) { + if (!this.isDevicePolicyEnabled_(resolutionPref) || !selectedDisplay) + return false; + if (selectedDisplay.isInternal) + return resolutionPref.value.internal_scale_percentage !== undefined; + return resolutionPref.value.external_scale_percentage !== undefined; + }, + + /** + * Checks if display scale factor is managed by policy and the policy + * is mandatory. + * @param {DisplayResolutionPrefObject} resolutionPref + * @return {boolean} + * @private + */ + isDisplayScaleMandatory_: function(selectedDisplay, resolutionPref) { + return this.isDisplayScaleManagedByPolicy_( + selectedDisplay, resolutionPref) && + !resolutionPref.value.recommended; + }, + + /** * Returns the list of display modes that is shown to the user in a drop down * menu. * @param {!chrome.system.display.DisplayUnitInfo} selectedDisplay diff --git a/chromium/chrome/browser/resources/settings/device_page/keyboard.html b/chromium/chrome/browser/resources/settings/device_page/keyboard.html index 30cdd396a7b..51a87e18b0a 100644 --- a/chromium/chrome/browser/resources/settings/device_page/keyboard.html +++ b/chromium/chrome/browser/resources/settings/device_page/keyboard.html @@ -129,11 +129,11 @@ </settings-slider> </div> </iron-collapse> - <div id="keyboardOverlay" class="settings-box" - on-click="onShowKeyboardShortcutsOverlayTap_" actionable> - <div class="start">$i18n{showKeyboardShortcutsOverlay}</div> + <div id="keyboardShortcutViewer" class="settings-box" + on-click="onShowKeyboardShortcutViewerTap_" actionable> + <div class="start">$i18n{showKeyboardShortcutViewer}</div> <paper-icon-button-light class="icon-external"> - <button aria-label="$i18n{showKeyboardShortcutsOverlay}"></button> + <button aria-label="$i18n{showKeyboardShortcutViewer}"></button> </paper-icon-button-light> </div> <div class="settings-box" on-click="onShowLanguageInputTap_" actionable> diff --git a/chromium/chrome/browser/resources/settings/device_page/keyboard.js b/chromium/chrome/browser/resources/settings/device_page/keyboard.js index 46b8761e420..e128c39d83c 100644 --- a/chromium/chrome/browser/resources/settings/device_page/keyboard.js +++ b/chromium/chrome/browser/resources/settings/device_page/keyboard.js @@ -143,9 +143,9 @@ Polymer({ this.showAppleCommandKey_ = keyboardParams['showAppleCommandKey']; }, - onShowKeyboardShortcutsOverlayTap_: function() { + onShowKeyboardShortcutViewerTap_: function() { settings.DevicePageBrowserProxyImpl.getInstance() - .showKeyboardShortcutsOverlay(); + .showKeyboardShortcutViewer(); }, onShowLanguageInputTap_: function() { diff --git a/chromium/chrome/browser/resources/settings/downloads_page/BUILD.gn b/chromium/chrome/browser/resources/settings/downloads_page/BUILD.gn index a4c1ddd2ed5..044f3b72730 100644 --- a/chromium/chrome/browser/resources/settings/downloads_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/downloads_page/BUILD.gn @@ -6,12 +6,12 @@ import("//third_party/closure_compiler/compile_js.gni") js_type_check("closure_compile") { deps = [ - ":add_smb_share_dialog", ":downloads_browser_proxy", ":downloads_page", - ":smb_browser_proxy", - ":smb_shares_page", ] + if (is_chromeos) { + deps += [ ":smb_shares_page" ] + } } js_library("downloads_browser_proxy") { @@ -21,32 +21,19 @@ js_library("downloads_browser_proxy") { ] } -js_library("smb_shares_page") { - deps = [ - ":add_smb_share_dialog", - "..:route", - "//ui/webui/resources/js:web_ui_listener_behavior", - ] -} - -js_library("add_smb_share_dialog") { - deps = [ - ":smb_browser_proxy", - "//ui/webui/resources/js:i18n_behavior", - "//ui/webui/resources/js:web_ui_listener_behavior", - ] -} - -js_library("smb_browser_proxy") { - deps = [ - "//ui/webui/resources/js:cr", - ] +if (is_chromeos) { + js_library("smb_shares_page") { + deps = [ + "..:route", + "//ui/webui/resources/cr_components/chromeos/smb_shares:smb_browser_proxy", + "//ui/webui/resources/js:web_ui_listener_behavior", + ] + } } js_library("downloads_page") { deps = [ ":downloads_browser_proxy", - ":smb_browser_proxy", "..:page_visibility", "..:route", "../prefs:prefs_behavior", diff --git a/chromium/chrome/browser/resources/settings/downloads_page/add_smb_share_dialog.html b/chromium/chrome/browser/resources/settings/downloads_page/add_smb_share_dialog.html deleted file mode 100644 index 8c30c6d4c6a..00000000000 --- a/chromium/chrome/browser/resources/settings/downloads_page/add_smb_share_dialog.html +++ /dev/null @@ -1,93 +0,0 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.html"> -<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> -<link rel="import" href="chrome://resources/html/md_select_css.html"> -<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> -<link rel="import" href="../settings_shared_css.html"> -<link rel="import" href="../settings_vars_css.html"> -<link rel="import" href="smb_browser_proxy.html"> - -<dom-module id="settings-add-smb-share-dialog"> - <template> - <style include="settings-shared md-select"> - #dialog [slot=body] { - height: 350px; - } - - .md-select { - width: 100%; - } - - .label { - @apply --cr-form-field-label; - } - - cr-input { - --cr-input-error-display: none; - } - - cr-searchable-drop-down { - display: block; - --cr-searchable-drop-down-width: 472px; - } - - .md-select, - cr-input:not(:last-child), - cr-searchable-drop-down { - margin-bottom: var(--cr-form-field-bottom-spacing); - } - </style> - - <cr-dialog id="dialog"> - <div slot="title">$i18n{addSmbShare}</div> - <div slot="body" spellcheck="false"> - <cr-searchable-drop-down id="address" label="$i18n{smbShareUrl}" - value="{{mountUrl_}}" items="[[discoveredShares_]]" - placeholder="\\server\share" on-change="onURLChanged_" - update-value-on-input autofocus> - </cr-searchable-drop-down> - <cr-input id="name" label="$i18n{smbShareName}" value="{{mountName_}}" - maxlength="64"> - </cr-input> - <div id="authentication-method" hidden="[[!isActiveDirectory_]]"> - <div id="authentication-label" class="label"> - $i18n{smbShareAuthenticationMethod} - </div> - <select class="md-select" aria-labelledby="authentication-label" - value="{{authenticationMethod_::change}}"> - <option value="kerberos"> - $i18n{smbShareKerberosAuthentication} - </option> - <option value="credentials"> - $i18n{smbShareStandardAuthentication} - </option> - </select> - </div> - <div id="credentials" - hidden="[[!shouldShowCredentialUI_(authenticationMethod_)]]"> - <cr-input id="username" label="$i18n{smbShareUsername}" - value="{{username_}}"> - </cr-input> - <cr-input id="password" type="password" - label="$i18n{smbSharePassword}" value="{{password_}}"> - </cr-input> - </div> - </div> - <div slot="button-container"> - <paper-button class="cancel-button" on-click="cancel_" id="cancel"> - $i18n{cancel}</paper-button> - <paper-button id="actionButton" class="action-button" - on-click="onAddButtonTap_" - disabled="[[!canAddShare_(mountUrl_)]]"> - $i18n{add} - </paper-button> - </div> - </cr-dialog> - </template> - <script src="add_smb_share_dialog.js"></script> -</dom-module> - diff --git a/chromium/chrome/browser/resources/settings/downloads_page/add_smb_share_dialog.js b/chromium/chrome/browser/resources/settings/downloads_page/add_smb_share_dialog.js deleted file mode 100644 index bed31c98d5c..00000000000 --- a/chromium/chrome/browser/resources/settings/downloads_page/add_smb_share_dialog.js +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2018 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. - -/** - * @fileoverview 'settings-add-smb-share-dialog' is a component for adding - * an SMB Share. - */ - -Polymer({ - is: 'settings-add-smb-share-dialog', - - behaviors: [WebUIListenerBehavior], - - properties: { - /** @private {string} */ - mountUrl_: { - type: String, - value: '', - }, - - /** @private {string} */ - mountName_: { - type: String, - value: '', - }, - - /** @private {string} */ - username_: { - type: String, - value: '', - }, - - /** @private {string} */ - password_: { - type: String, - value: '', - }, - /** @private {!Array<string>}*/ - discoveredShares_: { - type: Array, - value: function() { - return []; - }, - }, - - /** @private */ - isActiveDirectory_: { - type: Boolean, - value: function() { - return loadTimeData.getBoolean('isActiveDirectoryUser'); - }, - }, - - /** @private */ - authenticationMethod_: { - type: String, - value: function() { - return loadTimeData.getBoolean('isActiveDirectoryUser') ? - SmbAuthMethod.KERBEROS : - SmbAuthMethod.CREDENTIALS; - }, - }, - }, - - /** @private {?settings.SmbBrowserProxy} */ - browserProxy_: null, - - /** @override */ - created: function() { - this.browserProxy_ = settings.SmbBrowserProxyImpl.getInstance(); - }, - - /** @override */ - attached: function() { - this.browserProxy_.startDiscovery(); - this.$.dialog.showModal(); - - this.addWebUIListener('on-shares-found', this.onSharesFound_.bind(this)); - }, - - /** @private */ - cancel_: function() { - this.$.dialog.cancel(); - }, - - /** @private */ - onAddButtonTap_: function() { - this.browserProxy_.smbMount( - this.mountUrl_, this.mountName_.trim(), this.username_, this.password_, - this.authenticationMethod_); - this.$.dialog.close(); - }, - - /** @private */ - onURLChanged_: function() { - const parts = this.mountUrl_.split('\\'); - this.mountName_ = parts[parts.length - 1]; - }, - - /** - * @return {boolean} - * @private - */ - canAddShare_: function() { - return !!this.mountUrl_; - }, - - /** - * @param {!Array<string>} shares - * @private - */ - onSharesFound_: function(shares) { - this.discoveredShares_ = this.discoveredShares_.concat(shares); - }, - - /** - * @return {boolean} - * @private - */ - shouldShowCredentialUI_: function() { - return this.authenticationMethod_ == SmbAuthMethod.CREDENTIALS; - }, -}); diff --git a/chromium/chrome/browser/resources/settings/downloads_page/downloads_page.html b/chromium/chrome/browser/resources/settings/downloads_page/downloads_page.html index b2b2be9f94f..3557cf187b6 100644 --- a/chromium/chrome/browser/resources/settings/downloads_page/downloads_page.html +++ b/chromium/chrome/browser/resources/settings/downloads_page/downloads_page.html @@ -52,15 +52,13 @@ label="$i18n{disconnectGoogleDriveAccount}" hidden="[[!pageVisibility.googleDrive]]"> </settings-toggle-button> - <template is="dom-if" if="[[enableSmbSettings_]]"> - <div id="smbShares" class="settings-box" - on-click="onTapSmbShares_" actionable> - <div class="start"> $i18n{smbSharesTitle} </div> - <paper-icon-button-light class="subpage-arrow"> - <button aria-label="$i18n{smbSharesTitle}"></button> - </paper-icon-button-light> - </div> - </template> + <div id="smbShares" class="settings-box" + on-click="onTapSmbShares_" actionable> + <div class="start"> $i18n{smbSharesTitle} </div> + <paper-icon-button-light class="subpage-arrow"> + <button aria-label="$i18n{smbSharesTitle}"></button> + </paper-icon-button-light> + </div> </if> <template is="dom-if" if="[[autoOpenDownloads_]]" restamp> <div class="settings-box"> @@ -77,15 +75,13 @@ </neon-animatable> <if expr="chromeos"> - <template is="dom-if" if="[[enableSmbSettings_]]"> - <template is="dom-if" route-path="/smbShares"> - <settings-subpage - associated-control="[[$$('#smbShares')]]" - page-title="$i18n{smbSharesTitle}"> - <settings-smb-shares-page prefs="[[prefs]]"> - </settings-smb-shares-page> - </settings-subpage> - </template> + <template is="dom-if" route-path="/smbShares"> + <settings-subpage + associated-control="[[$$('#smbShares')]]" + page-title="$i18n{smbSharesTitle}"> + <settings-smb-shares-page prefs="[[prefs]]"> + </settings-smb-shares-page> + </settings-subpage> </template> </if> </settings-animated-pages> diff --git a/chromium/chrome/browser/resources/settings/downloads_page/downloads_page.js b/chromium/chrome/browser/resources/settings/downloads_page/downloads_page.js index 11c89e7c8c4..7ed19e857e2 100644 --- a/chromium/chrome/browser/resources/settings/downloads_page/downloads_page.js +++ b/chromium/chrome/browser/resources/settings/downloads_page/downloads_page.js @@ -43,18 +43,6 @@ Polymer({ // <if expr="chromeos"> /** - * Whether Smb Shares settings should be fetched and displayed. - * @private - */ - enableSmbSettings_: { - type: Boolean, - value: function() { - return loadTimeData.getBoolean('enableNativeSmbSetting'); - }, - readOnly: true, - }, - - /** * The download location string that is suitable to display in the UI. */ downloadLocation_: String, diff --git a/chromium/chrome/browser/resources/settings/downloads_page/smb_browser_proxy.js b/chromium/chrome/browser/resources/settings/downloads_page/smb_browser_proxy.js deleted file mode 100644 index 59ca15fd9c0..00000000000 --- a/chromium/chrome/browser/resources/settings/downloads_page/smb_browser_proxy.js +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2018 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. - -/** - * @fileoverview A helper object used from the "SMB Share" section to - * interact with the browser. Used only on Chrome OS. - */ - -/** - * @enum {number} - * These values must be kept in sync with the SmbMountResult enum in - * chrome/browser/chromeos/smb_client/smb_service.h. - */ -const SmbMountResult = { - SUCCESS: 0, - UNKNOWN_FAILURE: 1, - AUTHENTICATION_FAILED: 2, - NOT_FOUND: 3, - UNSUPPORTED_DEVICE: 4, - MOUNT_EXISTS: 5, - INVALID_URL: 6, -}; - -/** @enum {string} */ -const SmbAuthMethod = { - KERBEROS: 'kerberos', - CREDENTIALS: 'credentials', -}; - -cr.define('settings', function() { - /** @interface */ - class SmbBrowserProxy { - /** - * Attempts to mount an Smb filesystem with the provided url. - * @param {string} smbUrl File Share URL. - * @param {string} smbName Display name for the File Share. - * @param {string} username - * @param {string} password - * @param {string} authMethod - */ - smbMount(smbUrl, smbName, username, password, authMethod) {} - - /** - * Starts the file share discovery process. - */ - startDiscovery() {} - } - - /** @implements {settings.SmbBrowserProxy} */ - class SmbBrowserProxyImpl { - /** @override */ - smbMount(smbUrl, smbName, username, password, authMethod) { - chrome.send('smbMount', [ - smbUrl, smbName, username, password, - authMethod == SmbAuthMethod.KERBEROS - ]); - } - - /** @override */ - startDiscovery() { - chrome.send('startDiscovery'); - } - } - - cr.addSingletonGetter(SmbBrowserProxyImpl); - - return { - SmbBrowserProxy: SmbBrowserProxy, - SmbBrowserProxyImpl: SmbBrowserProxyImpl, - }; - -}); diff --git a/chromium/chrome/browser/resources/settings/downloads_page/smb_shares_page.html b/chromium/chrome/browser/resources/settings/downloads_page/smb_shares_page.html index 584488ae30d..308abd07d48 100644 --- a/chromium/chrome/browser/resources/settings/downloads_page/smb_shares_page.html +++ b/chromium/chrome/browser/resources/settings/downloads_page/smb_shares_page.html @@ -1,16 +1,14 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_toast/cr_toast.html"> +<link rel="import" href="chrome://resources/cr_components/chromeos/smb_shares/add_smb_share_dialog.html"> <link rel="import" href="chrome://resources/html/action_link.html"> <link rel="import" href="chrome://resources/html/action_link_css.html"> <link rel="import" href="chrome://resources/html/assert.html"> -<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/html/md_select_css.html"> <link rel="import" href="../route.html"> <link rel="import" href="../settings_shared_css.html"> <link rel="import" href="../settings_vars_css.html"> -<link rel="import" href="add_smb_share_dialog.html"> <dom-module id="settings-smb-shares-page"> <template> @@ -39,15 +37,10 @@ </paper-button> </div> <template is="dom-if" if="[[showAddSmbDialog_]]" restamp> - <settings-add-smb-share-dialog on-close="onAddSmbDialogClosed_"> - </settings-add-smb-share-dialog> + <add-smb-share-dialog on-close="onAddSmbDialogClosed_" + last-url="[[prefs.network_file_shares.most_recently_used_url.value]]" + </add-smb-share-dialog> </template> - - <cr-toast id="errorToast" duration="3000"> - <div class="error-message" id="addShareDoneMessage"> - [[addShareResultText_]] - </div> - </cr-toast> </template> <script src="smb_shares_page.js"></script> </dom-module> diff --git a/chromium/chrome/browser/resources/settings/downloads_page/smb_shares_page.js b/chromium/chrome/browser/resources/settings/downloads_page/smb_shares_page.js index f9a8ecc35d1..28515494b40 100644 --- a/chromium/chrome/browser/resources/settings/downloads_page/smb_shares_page.js +++ b/chromium/chrome/browser/resources/settings/downloads_page/smb_shares_page.js @@ -6,7 +6,6 @@ Polymer({ is: 'settings-smb-shares-page', behaviors: [ - WebUIListenerBehavior, settings.RouteObserverBehavior, ], @@ -21,9 +20,6 @@ Polymer({ /** @private */ showAddSmbDialog_: Boolean, - - /** @private */ - addShareResultText_: String, }, /** @@ -38,11 +34,6 @@ Polymer({ } }, - /** @override */ - attached: function() { - this.addWebUIListener('on-add-smb-share', this.onAddShare_.bind(this)); - }, - /** @private */ onAddShareTap_: function() { this.showAddSmbDialog_ = true; @@ -52,42 +43,4 @@ Polymer({ onAddSmbDialogClosed_: function() { this.showAddSmbDialog_ = false; }, - - /** - * @param {SmbMountResult} result - * @private - */ - onAddShare_: function(result) { - switch (result) { - case SmbMountResult.SUCCESS: - this.addShareResultText_ = - loadTimeData.getString('smbShareAddedSuccessfulMessage'); - break; - case SmbMountResult.AUTHENTICATION_FAILED: - this.addShareResultText_ = - loadTimeData.getString('smbShareAddedAuthFailedMessage'); - break; - case SmbMountResult.NOT_FOUND: - this.addShareResultText_ = - loadTimeData.getString('smbShareAddedNotFoundMessage'); - break; - case SmbMountResult.UNSUPPORTED_DEVICE: - this.addShareResultText_ = - loadTimeData.getString('smbShareAddedUnsupportedDeviceMessage'); - break; - case SmbMountResult.MOUNT_EXISTS: - this.addShareResultText_ = - loadTimeData.getString('smbShareAddedMountExistsMessage'); - break; - case SmbMountResult.INVALID_URL: - this.addShareResultText_ = - loadTimeData.getString('smbShareAddedInvalidURLMessage'); - break; - default: - this.addShareResultText_ = - loadTimeData.getString('smbShareAddedErrorMessage'); - } - this.$.errorToast.show(); - }, - }); diff --git a/chromium/chrome/browser/resources/settings/focus_row_behavior.js b/chromium/chrome/browser/resources/settings/focus_row_behavior.js index 0c5dce1fd1b..5593e53dbeb 100644 --- a/chromium/chrome/browser/resources/settings/focus_row_behavior.js +++ b/chromium/chrome/browser/resources/settings/focus_row_behavior.js @@ -19,7 +19,6 @@ class FocusRowDelegate { */ onFocus(row, e) { this.listItem_.lastFocused = e.path[0]; - this.listItem_.tabIndex = -1; } /** @@ -53,7 +52,9 @@ class VirtualFocusRow extends cr.ui.FocusRow { * behavior, which encapsulates focus controls of mouse and keyboards. * To use this behavior: * - The parent element should pass a "last-focused" attribute double-bound - * to the row items, to track the last-focused element across rows. + * to the row items, to track the last-focused element across rows, and + * a "list-blurred" attribute double-bound to the row items, to track + * whether the list of row items has been blurred. * - There must be a container in the extending element with the * [focus-row-container] attribute that contains all focusable controls. * - On each of the focusable controls, there must be a [focus-row-control] @@ -86,8 +87,19 @@ const FocusRowBehavior = { type: Number, observer: 'ironListTabIndexChanged_', }, + + listBlurred: { + type: Boolean, + notify: true, + }, }, + /** @private {?Element} */ + firstControl_: null, + + /** @private {!Array<!MutationObserver>} */ + controlObservers_: [], + /** @override */ attached: function() { this.classList.add('no-outline'); @@ -114,13 +126,42 @@ const FocusRowBehavior = { this.unlisten(this, 'dom-change', 'addItems_'); this.unlisten(this, 'mousedown', 'onMouseDown_'); this.unlisten(this, 'blur', 'onBlur_'); + this.removeObservers_(); if (this.row_) this.row_.destroy(); }, /** @private */ + updateFirstControl_: function() { + const newFirstControl = this.row_.getFirstFocusable(); + if (newFirstControl === this.firstControl_) + return; + + if (this.firstControl_) + this.unlisten(this.firstControl_, 'keydown', 'onFirstControlKeydown_'); + this.firstControl_ = newFirstControl; + if (this.firstControl_) { + this.listen( + /** @type {!Element} */ (this.firstControl_), 'keydown', + 'onFirstControlKeydown_'); + } + }, + + /** @private */ + removeObservers_: function() { + if (this.firstControl_) + this.unlisten(this.firstControl_, 'keydown', 'onFirstControlKeydown_'); + if (this.controlObservers_.length > 0) + this.controlObservers_.forEach(observer => { + observer.disconnect(); + }); + this.controlObservers_ = []; + }, + + /** @private */ addItems_: function() { if (this.row_) { + this.removeObservers_(); this.row_.destroy(); const controls = this.root.querySelectorAll('[focus-row-control]'); @@ -130,28 +171,91 @@ const FocusRowBehavior = { control.getAttribute('focus-type'), /** @type {!HTMLElement} */ (cr.ui.FocusRow.getFocusableElement(control))); + this.addMutationObservers_(assert(control)); + }); + this.updateFirstControl_(); + } + }, + + /** + * @return {!MutationObserver} + * @private + */ + createObserver_: function() { + return new MutationObserver(mutations => { + const mutation = mutations[0]; + if (mutation.attributeName === 'style' && mutation.oldValue) { + const newStyle = + window.getComputedStyle(/** @type {!Element} */ (mutation.target)); + const oldDisplayValue = mutation.oldValue.match(/^display:(.*)(?=;)/); + const oldVisibilityValue = + mutation.oldValue.match(/^visibility:(.*)(?=;)/); + // Return early if display and visibility have not changed. + if (oldDisplayValue && newStyle.display === oldDisplayValue[1].trim() && + oldVisibilityValue && + newStyle.visibility === oldVisibilityValue[1].trim()) { + return; + } + } + this.updateFirstControl_(); + }); + }, + + /** + * The first focusable control changes if hidden, disabled, or style.display + * changes for the control or any of its ancestors. Add mutation observers to + * watch for these changes in order to ensure the first control keydown + * listener is always on the correct element. + * @param {!Element} control + * @private + */ + addMutationObservers_: function(control) { + let current = control; + while (current && current != this.root) { + const currentObserver = this.createObserver_(); + currentObserver.observe(current, { + attributes: true, + attributeFilter: ['hidden', 'disabled', 'style'], + attributeOldValue: true, }); + this.controlObservers_.push(currentObserver); + current = current.parentNode; } }, /** * This function gets called when the row itself receives the focus event. + * @param {!Event} e The focus event * @private */ - onFocus_: function() { + onFocus_: function(e) { if (this.mouseFocused_) { this.mouseFocused_ = false; // Consume and reset flag. return; } - if (this.lastFocused) { + // If focus is being restored from outside the item and the event is fired + // by the list item itself, focus the first control so that the user can tab + // through all the controls. When the user shift-tabs back to the row, or + // focus is restored to the row from a dropdown on the last item, the last + // child item will be focused before the row itself. Since this is the + // desired behavior, do not shift focus to the first item in these cases. + const restoreFocusToFirst = + this.listBlurred && e.composedPath()[0] === this; + + if (this.lastFocused && !restoreFocusToFirst) { this.row_.getEquivalentElement(this.lastFocused).focus(); } else { - const firstFocusable = assert(this.row_.getFirstFocusable()); + const firstFocusable = assert(this.firstControl_); firstFocusable.focus(); } + this.listBlurred = false; + }, - this.tabIndex = -1; + /** @param {!KeyboardEvent} e */ + onFirstControlKeydown_: function(e) { + if (e.shiftKey && e.key === 'Tab') + this.focus(); }, /** @private */ @@ -165,8 +269,16 @@ const FocusRowBehavior = { this.mouseFocused_ = true; // Set flag to not do any control-focusing. }, - /** @private */ - onBlur_: function() { + /** + * @param {!Event} e + * @private + */ + onBlur_: function(e) { this.mouseFocused_ = false; // Reset flag since it's not active anymore. - } + + const node = + e.relatedTarget ? /** @type {!Node} */ (e.relatedTarget) : null; + if (!this.parentNode.contains(node)) + this.listBlurred = true; + }, }; diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_config.html b/chromium/chrome/browser/resources/settings/internet_page/internet_config.html index 8e2b173b0db..4b10a25ecb9 100644 --- a/chromium/chrome/browser/resources/settings/internet_page/internet_config.html +++ b/chromium/chrome/browser/resources/settings/internet_page/internet_config.html @@ -24,12 +24,12 @@ </style> <cr-dialog id="dialog" close-text="$i18n{close}"> - <div slot="title">[[getDialogTitle_(networkProperties_)]]</div> + <div slot="title">[[getDialogTitle_(managedProperties_)]]</div> <div slot="body"> <network-config id="networkConfig" class="flex" networking-private="[[networkingPrivate]]" global-policy="[[globalPolicy]]" - network-properties="{{networkProperties_}}" + managed-properties="{{managedProperties_}}" enable-connect="{{enableConnect_}}" enable-save="{{enableSave_}}" share-allow-enable="[[shareAllowEnable_]]" share-default="[[shareDefault_]]" diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_config.js b/chromium/chrome/browser/resources/settings/internet_page/internet_config.js index d93e5869e3d..a72e299cc89 100644 --- a/chromium/chrome/browser/resources/settings/internet_page/internet_config.js +++ b/chromium/chrome/browser/resources/settings/internet_page/internet_config.js @@ -69,9 +69,9 @@ Polymer({ * The current properties if an existing network is being configured, or * a minimal subset for a new network. Note: network-config may modify * this (specifically .name). - * @private {!chrome.networkingPrivate.NetworkProperties} + * @private {!chrome.networkingPrivate.ManagedProperties} */ - networkProperties_: Object, + managedProperties_: Object, /** * Set by network-config when a configuration error occurs. @@ -88,12 +88,12 @@ Polymer({ if (!dialog.open) dialog.showModal(); - // Set networkProperties for new configurations and for existing + // Set managedProperties for new configurations and for existing // configurations until the current properties are loaded. assert(this.type && this.type != CrOnc.Type.ALL); - this.networkProperties_ = { + this.managedProperties_ = { GUID: this.guid, - Name: this.name, + Name: {Active: this.name}, Type: this.type, }; this.$.networkConfig.init(); @@ -120,10 +120,11 @@ Polymer({ * @private */ getDialogTitle_: function() { - const name = this.networkProperties_.Name; + const name = /** @type {string} */ ( + CrOnc.getActiveValue(this.managedProperties_.Name)); if (name) return this.i18n('internetConfigName', HTMLEscape(name)); - const type = this.i18n('OncType' + this.networkProperties_.Type); + const type = this.i18n('OncType' + this.managedProperties_.Type); return this.i18n('internetJoinType', type); }, diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.html b/chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.html index 7e9234ebc35..47874202a04 100644 --- a/chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.html +++ b/chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.html @@ -19,6 +19,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> +<link rel="import" href="../controls/controlled_button.html"> <link rel="import" href="../controls/settings_toggle_button.html"> <link rel="import" href="../prefs/prefs.html"> <link rel="import" href="../route.html"> @@ -46,7 +47,8 @@ } cr-policy-network-indicator, - cr-policy-indicator { + cr-policy-indicator, + cr-policy-pref-indicator { margin-inline-start: var(--settings-controlled-by-spacing); } @@ -81,7 +83,9 @@ </template> </div> <paper-button on-click="onForgetTap_" - hidden$="[[!showForget_(networkProperties)]]"> + hidden$="[[!showForget_(networkProperties)]]" + disabled="[[disableForget_(networkProperties, + prefs.vpn_config_allowed)]]"> $i18n{networkButtonForget} </paper-button> <paper-button on-click="onViewAccountTap_" @@ -95,21 +99,27 @@ <paper-button on-click="onConfigureTap_" hidden$="[[!showConfigure_(networkProperties, globalPolicy, managedNetworkAvailable)]]" - disabled="[[disableConfigure_(networkProperties)]]"> + disabled="[[disableConfigure_(networkProperties, + prefs.vpn_config_allowed)]]"> $i18n{networkButtonConfigure} </paper-button> - <paper-button class="action-button" on-click="onConnectTap_" + <controlled-button id="connect" action-button on-click="onConnectTap_" hidden$="[[!showConnect_(networkProperties, globalPolicy, managedNetworkAvailable)]]" disabled="[[!enableConnect_(networkProperties, defaultNetwork, networkPropertiesReceived_, outOfRange_, globalPolicy, - managedNetworkAvailable)]]"> - $i18n{networkButtonConnect} - </paper-button> - <paper-button class="action-button" on-click="onDisconnectTap_" - hidden$="[[!showDisconnect_(networkProperties)]]"> - $i18n{networkButtonDisconnect} - </paper-button> + managedNetworkAvailable)]]" + label="$i18n{networkButtonConnect}" + pref="[[getVpnConfigPrefFromValue_(networkProperties, + prefs.vpn_config_allowed)]]"> + </controlled-button> + <controlled-button id="disconnect" action-button + on-click="onDisconnectTap_" + hidden$="[[!showDisconnect_(networkProperties)]]" + label="$i18n{networkButtonDisconnect}" + pref="[[getVpnConfigPrefFromValue_(networkProperties, + prefs.vpn_config_allowed)]]"> + </controlled-button> </div> <!-- Disabled by policy / Shared messages. --> @@ -170,6 +180,30 @@ </cr-toggle> </div> </template> + <!-- Always-on VPN. --> + <template is="dom-if" + if="[[showAlwaysOnVpn_(networkProperties)]]"> + <div class="settings-box"> + <div id="AlwaysOnVpnToggleLabel" class="start"> + $i18n{networkAlwaysOnVpn} + </div> + <cr-toggle checked="{{alwaysOnVpn_}}" + disabled="[[!enableAlwaysOnVpn_(networkProperties, + prefs.vpn_config_allowed)]]" + aria-labelledby="AlwaysOnVpnToggleLabel" + on-change="onAlwaysOnVpnChange_"> + </cr-toggle> + <template is="dom-if" + if="[[!enableAlwaysOnVpn_(networkProperties, + prefs.vpn_config_allowed)]]"> + <cr-policy-pref-indicator + pref="[[getVpnConfigPrefFromValue_(networkProperties, + prefs.vpn_config_allowed)]]" on-click="onIndicatorTap_" + icon-aria-label="AlwaysOnVpnToggleLabel"> + </cr-policy-pref-indicator> + </template> + </div> + </template> <!-- Data roaming (Cellular only). --> <template is="dom-if" if="[[isCellular_(networkProperties)]]"> <settings-toggle-button id="allowDataRoaming" diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.js b/chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.js index a11649de559..d3ceb3eb7e6 100644 --- a/chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.js +++ b/chromium/chrome/browser/resources/settings/internet_page/internet_detail_page.js @@ -115,6 +115,15 @@ Polymer({ }, /** + * State of the Always-on VPN toggle. + * @private + */ + alwaysOnVpn_: { + type: Boolean, + value: false, + }, + + /** * The network preferred state. * @private */ @@ -143,6 +152,10 @@ Polymer({ proxyExpanded_: Boolean, }, + observers: [ + 'onAlwaysOnPrefChanged_(prefs.arc.vpn.always_on.*)', + ], + listeners: { 'network-list-changed': 'checkNetworkExists_', 'networks-changed': 'updateNetworkDetails_' @@ -605,10 +618,26 @@ Polymer({ /** * @param {!CrOnc.NetworkProperties} networkProperties + * @param {!chrome.settingsPrivate.PrefObject} vpn_config_allowed + * @return {boolean} + * @private + */ + disableForget_: function(networkProperties, vpn_config_allowed) { + return this.isVpn_(networkProperties) && vpn_config_allowed && + !vpn_config_allowed.value; + }, + + /** + * @param {!CrOnc.NetworkProperties} networkProperties + * @param {!chrome.settingsPrivate.PrefObject} vpn_config_allowed * @return {boolean} * @private */ - disableConfigure_: function(networkProperties) { + disableConfigure_: function(networkProperties, vpn_config_allowed) { + if (this.isVpn_(networkProperties) && vpn_config_allowed && + !vpn_config_allowed.value) { + return true; + } return this.isPolicySource(networkProperties.Source) && !this.hasRecommendedFields_(networkProperties); }, @@ -698,6 +727,36 @@ Polymer({ }, /** + * @param {!CrOnc.NetworkProperties} networkProperties + * @return {boolean} Whether or not we are looking at VPN configuration. + * @private + */ + isVpn_: function(networkProperties) { + return networkProperties.Type == CrOnc.Type.VPN; + }, + + /** + * @param {!CrOnc.NetworkProperties} networkProperties + * @param {!chrome.settingsPrivate.PrefObject} prefButtonAllowed + * @return {Object} Fake pref that is enforced + * whenever the original pref is true + * @private + */ + getVpnConfigPrefFromValue_: function(networkProperties, prefButtonAllowed) { + if (!this.isVpn_(networkProperties) || !prefButtonAllowed) { + return null; + } + let fakePref = Object.assign({}, prefButtonAllowed); + if (prefButtonAllowed.value) { + delete fakePref.enforcement; + delete fakePref.controlledBy; + } else { + fakePref.enforcement = chrome.settingsPrivate.Enforcement.ENFORCED; + } + return fakePref; + }, + + /** * @return {!TetherConnectionDialogElement} * @private */ @@ -992,6 +1051,48 @@ Polymer({ /** * @param {!CrOnc.NetworkProperties} networkProperties + * @return {boolean} Whether the toggle for the Always-on VPN feature is + * displayed. + * @private + */ + showAlwaysOnVpn_: function(networkProperties) { + return this.isArcVpn_(networkProperties) && this.prefs.arc && + this.prefs.arc.vpn && this.prefs.arc.vpn.always_on && + this.prefs.arc.vpn.always_on.vpn_package && + networkProperties.VPN.Host.Active === + this.prefs.arc.vpn.always_on.vpn_package.value; + }, + + /** + * @param {!CrOnc.NetworkProperties} networkProperties + * @param {!chrome.settingsPrivate.PrefObject} vpnConfigAllowed + * @return {boolean} Whether the toggle for the Always-on VPN feature is + * enabled. + * @private + */ + enableAlwaysOnVpn_: function(networkProperties, vpnConfigAllowed) { + return this.isArcVpn_(networkProperties) && vpnConfigAllowed && + !!vpnConfigAllowed.value; + }, + + /** @private */ + onAlwaysOnPrefChanged_: function() { + if (this.prefs.arc && this.prefs.arc.vpn && this.prefs.arc.vpn.always_on && + this.prefs.arc.vpn.always_on.lockdown) { + this.alwaysOnVpn_ = this.prefs.arc.vpn.always_on.lockdown.value; + } + }, + + /** @private */ + onAlwaysOnVpnChange_: function() { + if (this.prefs.arc && this.prefs.arc.vpn && this.prefs.arc.vpn.always_on && + this.prefs.arc.vpn.always_on.lockdown) { + this.set('prefs.arc.vpn.always_on.lockdown.value', this.alwaysOnVpn_); + } + }, + + /** + * @param {!CrOnc.NetworkProperties} networkProperties * @param {!chrome.networkingPrivate.GlobalPolicy} globalPolicy * @param {boolean} managedNetworkAvailable * @return {boolean} True if the prefer network checkbox should be shown. @@ -999,10 +1100,16 @@ Polymer({ */ showPreferNetwork_: function( networkProperties, globalPolicy, managedNetworkAvailable) { - // TODO(stevenjb): Resolve whether or not we want to allow "preferred" for - // networkProperties.Type == CrOnc.Type.ETHERNET. + if (!networkProperties) + return false; + + const type = networkProperties.Type; + if (type == CrOnc.Type.ETHERNET || type == CrOnc.Type.CELLULAR || + this.isArcVpn_(networkProperties)) { + return false; + } + return this.isRemembered_(networkProperties) && - !this.isArcVpn_(networkProperties) && !this.isBlockedByPolicy_( networkProperties, globalPolicy, managedNetworkAvailable); }, diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_page.js b/chromium/chrome/browser/resources/settings/internet_page/internet_page.js index 103624689c5..abae0e0114b 100644 --- a/chromium/chrome/browser/resources/settings/internet_page/internet_page.js +++ b/chromium/chrome/browser/resources/settings/internet_page/internet_page.js @@ -110,7 +110,11 @@ Polymer({ networksChangeSubscriberSelectors_: { type: Array, value: function() { - return ['network-summary', 'settings-internet-detail-page']; + return [ + 'network-summary', + 'settings-internet-detail-page', + 'settings-internet-subpage', + ]; } }, diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_subpage.js b/chromium/chrome/browser/resources/settings/internet_page/internet_subpage.js index e3285f70fac..29db908a849 100644 --- a/chromium/chrome/browser/resources/settings/internet_page/internet_subpage.js +++ b/chromium/chrome/browser/resources/settings/internet_page/internet_subpage.js @@ -113,7 +113,10 @@ Polymer({ }, }, - listeners: {'network-list-changed': 'getNetworkStateList_'}, + listeners: { + 'network-list-changed': 'getNetworkStateList_', + 'networks-changed': 'getNetworkStateList_', + }, observers: ['deviceStateChanged_(networkingPrivate, deviceState)'], diff --git a/chromium/chrome/browser/resources/settings/languages_page/add_languages_dialog.js b/chromium/chrome/browser/resources/settings/languages_page/add_languages_dialog.js index 77c6b94a521..610e3d758ce 100644 --- a/chromium/chrome/browser/resources/settings/languages_page/add_languages_dialog.js +++ b/chromium/chrome/browser/resources/settings/languages_page/add_languages_dialog.js @@ -84,15 +84,9 @@ Polymer({ const filterValue = this.filterValue_ ? this.filterValue_.toLowerCase() : null; return this.languages.supported.filter(language => { - const isAvailableLanguage = - !this.languageHelper.isLanguageEnabled(language.code); - - if (!isAvailableLanguage) + if (!this.languageHelper.canEnableLanguage(language)) return false; - if (this.languageHelper.isLanguageCodeForArcIme(language.code)) - return false; // internal use only - if (filterValue === null) return true; diff --git a/chromium/chrome/browser/resources/settings/languages_page/languages.js b/chromium/chrome/browser/resources/settings/languages_page/languages.js index 6c81d0d59f5..f15055d4934 100644 --- a/chromium/chrome/browser/resources/settings/languages_page/languages.js +++ b/chromium/chrome/browser/resources/settings/languages_page/languages.js @@ -392,17 +392,12 @@ Polymer({ /** @type {!Array<string>} */ (translateBlockedPref.value)); for (let i = 0; i < this.languages.enabled.length; i++) { - if (this.languages.enabled[i].language.code == - this.languages.prospectiveUILanguage) { - continue; - } - // This conversion primarily strips away the region part. - // For example "fr-CA" --> "fr". - const translateCode = this.convertLanguageCodeForTranslate( - this.languages.enabled[i].language.code); + const language = this.languages.enabled[i].language; + const translateEnabled = this.isTranslateEnabled_( + language.code, !!language.supportsTranslate, translateBlockedSet, + this.languages.translateTarget, this.languages.prospectiveUILanguage); this.set( - 'languages.enabled.' + i + '.translateEnabled', - !translateBlockedSet.has(translateCode)); + 'languages.enabled.' + i + '.translateEnabled', translateEnabled); } }, @@ -427,7 +422,7 @@ Polymer({ language.supportsUI = !!language.supportsUI; language.supportsTranslate = !!language.supportsTranslate; language.supportsSpellcheck = !!language.supportsSpellcheck; - language.isProhibitedUILocale = !!language.isProhibitedUILocale; + language.isProhibitedLanguage = !!language.isProhibitedLanguage; this.supportedLanguageMap_.set(language.code, language); } @@ -542,13 +537,9 @@ Polymer({ const languageState = /** @type {LanguageState} */ ({}); languageState.language = language; languageState.spellCheckEnabled = !!spellCheckSet.has(code); - // Translate is considered disabled if this language maps to any translate - // language that is blocked. - const translateCode = this.convertLanguageCodeForTranslate(code); - languageState.translateEnabled = !!language.supportsTranslate && - !translateBlockedSet.has(translateCode) && - translateCode != translateTarget && - (!prospectiveUILanguage || code != prospectiveUILanguage); + languageState.translateEnabled = this.isTranslateEnabled_( + code, !!language.supportsTranslate, translateBlockedSet, + translateTarget, prospectiveUILanguage); languageState.isManaged = !!spellCheckForcedSet.has(code); languageState.downloadDictionaryFailureCount = 0; enabledLanguageStates.push(languageState); @@ -556,6 +547,29 @@ Polymer({ return enabledLanguageStates; }, + /** + * True iff we translate pages that are in the given language. + * @param {string} code Language code. + * @param {boolean} supportsTranslate If translation supports the given + * language. + * @param {!Set<string>} translateBlockedSet Set of languages for which + * translation is blocked. + * @param {string} translateTarget Language code of the default translate + * target language. + * @param {(string|undefined)} prospectiveUILanguage Prospective UI display + * language. Only defined on Windows and Chrome OS. + * @return {boolean} + * @private + */ + isTranslateEnabled_: function( + code, supportsTranslate, translateBlockedSet, translateTarget, + prospectiveUILanguage) { + const translateCode = this.convertLanguageCodeForTranslate(code); + return supportsTranslate && !translateBlockedSet.has(translateCode) && + translateCode != translateTarget && + (!prospectiveUILanguage || code != prospectiveUILanguage); + }, + // <if expr="not is_macosx"> /** * Updates the dictionary download status for languages in @@ -811,6 +825,17 @@ Polymer({ }, /** + * @param {!chrome.languageSettingsPrivate.Language} language + * @return {boolean} true if the given language can be enabled + */ + canEnableLanguage(language) { + return !( + this.isLanguageEnabled(language.code) || + language.isProhibitedLanguage || + this.isLanguageCodeForArcIme(language.code) /* internal use only */); + }, + + /** * Moves the language in the list of enabled languages either up (toward the * front of the list) or down (toward the back). * @param {string} languageCode diff --git a/chromium/chrome/browser/resources/settings/languages_page/languages_page.html b/chromium/chrome/browser/resources/settings/languages_page/languages_page.html index a979b391e55..948ac4ecd1b 100644 --- a/chromium/chrome/browser/resources/settings/languages_page/languages_page.html +++ b/chromium/chrome/browser/resources/settings/languages_page/languages_page.html @@ -177,6 +177,7 @@ </template> <div class="list-item"> <a is="action-link" class="list-button" id="addLanguages" + disabled="[[!canEnableSomeSupportedLanguage_(languages)]]" on-click="onAddLanguagesTap_"> $i18n{addLanguages} </a> @@ -333,7 +334,7 @@ detailLanguage_, languages.prospectiveUILanguage)]]"> <span>$i18n{displayInThisLanguage}</span> <iron-icon class="policy" icon="cr20:domain" hidden$="[[ - !detailLanguage_.language.isProhibitedUILocale]]"> + !detailLanguage_.language.isProhibitedLanguage]]"> </iron-icon> </cr-checkbox> </if> diff --git a/chromium/chrome/browser/resources/settings/languages_page/languages_page.js b/chromium/chrome/browser/resources/settings/languages_page/languages_page.js index 1e7beeb2d68..622ec263840 100644 --- a/chromium/chrome/browser/resources/settings/languages_page/languages_page.js +++ b/chromium/chrome/browser/resources/settings/languages_page/languages_page.js @@ -155,6 +155,19 @@ Polymer({ }, /** + * Checks if there are supported languages that are not enabled but can be + * enabled. + * @param {LanguagesModel|undefined} languages + * @return {boolean} True if there is at least one available language. + * @private + */ + canEnableSomeSupportedLanguage_: function(languages) { + return languages == undefined || languages.supported.some(language => { + return this.languageHelper.canEnableLanguage(language); + }); + }, + + /** * Used to determine which "Move" buttons to show for ordering enabled * languages. * @param {number} n @@ -166,6 +179,9 @@ Polymer({ if (this.languages == undefined || this.detailLanguage_ == undefined) return false; + if (n >= this.languages.enabled.length) + return false; + const compareLanguage = assert(this.languages.enabled[n]); return this.detailLanguage_.language == compareLanguage.language; }, @@ -304,9 +320,9 @@ Polymer({ if (languageState.language.code == prospectiveUILanguage) return true; - // Check if the language is prohibited by the current "AllowedUILocales" + // Check if the language is prohibited by the current "AllowedLanguages" // policy. - if (languageState.language.isProhibitedUILocale) + if (languageState.language.isProhibitedLanguage) return true; // Otherwise, the prospective language can be changed to this language. diff --git a/chromium/chrome/browser/resources/settings/languages_page/languages_types.js b/chromium/chrome/browser/resources/settings/languages_page/languages_types.js index 2186c699bfc..e86905dd7f1 100644 --- a/chromium/chrome/browser/resources/settings/languages_page/languages_types.js +++ b/chromium/chrome/browser/resources/settings/languages_page/languages_types.js @@ -132,6 +132,12 @@ class LanguageHelper { canDisableLanguage(languageCode) {} /** + * @param {!chrome.languageSettingsPrivate.Language} language + * @return {boolean} true if the given language can be enabled + */ + canEnableLanguage(language) {} + + /** * Moves the language in the list of enabled languages by the given offset. * @param {string} languageCode * @param {boolean} upDirection True if we need to move toward the front, diff --git a/chromium/chrome/browser/resources/settings/lazy_load.html b/chromium/chrome/browser/resources/settings/lazy_load.html index d5582b2f6f7..24e38535c00 100644 --- a/chromium/chrome/browser/resources/settings/lazy_load.html +++ b/chromium/chrome/browser/resources/settings/lazy_load.html @@ -4,7 +4,6 @@ <link rel="import" href="a11y_page/a11y_page.html"> <link rel="import" href="downloads_page/downloads_page.html"> <link rel="import" href="languages_page/languages_page.html"> - <link rel="import" href="passwords_and_forms_page/passwords_and_forms_page.html"> <link rel="import" href="printing_page/printing_page.html"> <link rel="import" href="privacy_page/privacy_page.html"> <link rel="import" href="reset_page/reset_page.html"> diff --git a/chromium/chrome/browser/resources/settings/manifest.json b/chromium/chrome/browser/resources/settings/manifest.json new file mode 100644 index 00000000000..c7a72e04e30 --- /dev/null +++ b/chromium/chrome/browser/resources/settings/manifest.json @@ -0,0 +1,13 @@ +{ + "name": "Settings", + "display": "standalone", + "icons": [ + { + "src": "icon-192.png", + "sizes": "192x192", + "type": "image/png" + } + ], + "start_url": "/", + "theme_color": "#254FAE" +} diff --git a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_page.html b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_page.html index 3f6c5212ac0..78aba32d3fd 100644 --- a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_page.html +++ b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_page.html @@ -91,7 +91,7 @@ </neon-animatable> <template is="dom-if" route-path="/multidevice/features" restamp> <settings-subpage associated-control="[[$$('#multidevice-item')]]" - page-title="[[pageContentData.hostDeviceName]]"> + page-title="[[getLabelText_(pageContentData)]]"> <settings-multidevice-subpage page-content-data="[[pageContentData]]"> </settings-multidevice-subpage> @@ -99,7 +99,9 @@ </template> <template is="dom-if" route-path="/multidevice/features/smartLock" restamp> - <settings-subpage page-title="$i18n{easyUnlockSectionTitle}"> + <settings-subpage + associated-control="[[$$('#multidevice-item')]]" + page-title="$i18n{easyUnlockSectionTitle}"> <settings-multidevice-smartlock-subpage prefs="{{prefs}}" page-content-data="[[pageContentData]]"> diff --git a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_radio_button.js b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_radio_button.js index c2163e01f53..e5d121758f1 100644 --- a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_radio_button.js +++ b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_radio_button.js @@ -9,28 +9,6 @@ Polymer({ CrRadioButtonBehavior, ], - properties: { - disabled: { - type: Boolean, - reflectToAttribute: true, - observer: 'disabledChanged_', - }, - - name: { - type: String, - notify: true, - }, - }, - - /** - * Updates attributes of the control to reflect its disabled state. - * @private - */ - disabledChanged_: function() { - this.setAttribute('tabindex', this.disabled ? -1 : 0); - this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false'); - }, - /** * Prevents on-click handles on the control from being activated when the * indicator is clicked. diff --git a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_smartlock_subpage.html b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_smartlock_subpage.html index 68fbc04bf21..0db389f7f01 100644 --- a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_smartlock_subpage.html +++ b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_smartlock_subpage.html @@ -1,6 +1,7 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_radio_group/cr_radio_group.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> <link rel="import" href="multidevice_constants.html"> <link rel="import" href="multidevice_browser_proxy.html"> @@ -36,24 +37,22 @@ </div> <iron-collapse opened="[[smartLockEnabled_]]"> <div class="list-frame"> - <paper-radio-group + <cr-radio-group selected="[[smartLockSignInEnabled_]]" selectable="multidevice-radio-button" - on-paper-radio-group-changed= - "onSmartLockSignInEnabledChanged_"> + disabled="[[!smartLockSignInAllowed_]]" + on-selected-changed="onSmartLockSignInEnabledChanged_"> <multidevice-radio-button - disabled$="[[!smartLockSignInAllowed_]]" name="disabled" class="list-item underbar" label="$i18n{easyUnlockUnlockDeviceOnly}"> </multidevice-radio-button> <multidevice-radio-button - disabled$="[[!smartLockSignInAllowed_]]" name="enabled" class="list-item" label="$i18n{easyUnlockUnlockDeviceAndAllowSignin}"> </multidevice-radio-button> - </paper-radio-group> + </cr-radio-group> </div> </iron-collapse> <template is="dom-if" if="[[showPasswordPromptDialog_]]" restamp> diff --git a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_smartlock_subpage.js b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_smartlock_subpage.js index 885cd841ea7..e230adc112c 100644 --- a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_smartlock_subpage.js +++ b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_smartlock_subpage.js @@ -147,8 +147,8 @@ Polymer({ * radio group representing the pref. * @private */ - onSmartLockSignInEnabledChanged_: function(event) { - const radioGroup = event.target; + onSmartLockSignInEnabledChanged_: function() { + const radioGroup = this.$$('cr-radio-group'); const enabled = radioGroup.selected == settings.SignInEnabledState.ENABLED; if (!enabled) { diff --git a/chromium/chrome/browser/resources/settings/on_startup_page/startup_url_entry.html b/chromium/chrome/browser/resources/settings/on_startup_page/startup_url_entry.html index 42ecafb7e51..02b1ccc2c14 100644 --- a/chromium/chrome/browser/resources/settings/on_startup_page/startup_url_entry.html +++ b/chromium/chrome/browser/resources/settings/on_startup_page/startup_url_entry.html @@ -3,11 +3,11 @@ <link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html"> <link rel="import" href="chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> -<link rel="import" href="chrome://resources/html/icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="startup_urls_page_browser_proxy.html"> <link rel="import" href="../focus_row_behavior.html"> <link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="../site_favicon.html"> <dom-module id="settings-startup-url-entry"> <template> @@ -17,9 +17,7 @@ } </style> <div class="list-item" focus-row-container> - <div class="favicon-image" - style="background-image: [[getIconSet_(model.url)]]"> - </div> + <site-favicon url="[[model.url]]"></site-favicon> <div class="middle hide-overflow"> <div class="text-elide">[[model.title]]</div> <div class="text-elide secondary">[[model.url]]</div> diff --git a/chromium/chrome/browser/resources/settings/on_startup_page/startup_url_entry.js b/chromium/chrome/browser/resources/settings/on_startup_page/startup_url_entry.js index 756fdd9ee81..f4ea18d13cf 100644 --- a/chromium/chrome/browser/resources/settings/on_startup_page/startup_url_entry.js +++ b/chromium/chrome/browser/resources/settings/on_startup_page/startup_url_entry.js @@ -32,15 +32,6 @@ Polymer({ model: Object, }, - /** - * @param {string} url Location of an image to get a set of icons for. - * @return {string} A set of icon URLs. - * @private - */ - getIconSet_: function(url) { - return cr.icon.getFavicon(url); - }, - /** @private */ onRemoveTap_: function() { this.$$('cr-action-menu').close(); diff --git a/chromium/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html b/chromium/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html index 93cd7cd0c94..040d1e8bb74 100644 --- a/chromium/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html +++ b/chromium/chrome/browser/resources/settings/on_startup_page/startup_urls_page.html @@ -41,7 +41,7 @@ <template> <settings-startup-url-entry model="[[item]]" first$="[[!index]]" tabindex$="[[tabIndex]]" iron-list-tab-index="[[tabIndex]]" - last-focused="{{lastFocused_}}" + last-focused="{{lastFocused_}}" list-blurred="{{listBlurred_}}" editable="[[shouldAllowUrlsEdit_( prefs.session.startup_urls.enforcement)]]"> </settings-startup-url-entry> diff --git a/chromium/chrome/browser/resources/settings/on_startup_page/startup_urls_page.js b/chromium/chrome/browser/resources/settings/on_startup_page/startup_urls_page.js index c526302dee2..1ac8914c6b3 100644 --- a/chromium/chrome/browser/resources/settings/on_startup_page/startup_urls_page.js +++ b/chromium/chrome/browser/resources/settings/on_startup_page/startup_urls_page.js @@ -29,6 +29,9 @@ Polymer({ /** @private {Object}*/ lastFocused_: Object, + + /** @private */ + listBlurred_: Boolean, }, /** @private {?settings.StartupUrlsPageBrowserProxy} */ diff --git a/chromium/chrome/browser/resources/settings/downloads_page/smb_browser_proxy.html b/chromium/chrome/browser/resources/settings/open_window_proxy.html index 2d494727081..14336c432cb 100644 --- a/chromium/chrome/browser/resources/settings/downloads_page/smb_browser_proxy.html +++ b/chromium/chrome/browser/resources/settings/open_window_proxy.html @@ -1,2 +1,2 @@ <link rel="import" href="chrome://resources/html/cr.html"> -<script src="smb_browser_proxy.js"> </script>
\ No newline at end of file +<script src="open_window_proxy.js"></script> diff --git a/chromium/chrome/browser/resources/settings/open_window_proxy.js b/chromium/chrome/browser/resources/settings/open_window_proxy.js new file mode 100644 index 00000000000..5aab78cd5d2 --- /dev/null +++ b/chromium/chrome/browser/resources/settings/open_window_proxy.js @@ -0,0 +1,36 @@ +// Copyright 2018 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. + +/** + * @fileoverview A helper object used to open a URL in a new tab. + * the browser. + */ + +cr.exportPath('settings'); + +cr.define('settings', function() { + /** @interface */ + class OpenWindowProxy { + /** + * Opens the specified URL in a new tab. + * @param {string} url + */ + openURL(url) {} + } + + /** @implements {settings.OpenWindowProxy} */ + class OpenWindowProxyImpl { + /** @override */ + openURL(url) { + window.open(url); + } + } + + cr.addSingletonGetter(OpenWindowProxyImpl); + + return { + OpenWindowProxy: OpenWindowProxy, + OpenWindowProxyImpl: OpenWindowProxyImpl, + }; +}); diff --git a/chromium/chrome/browser/resources/settings/page_visibility.js b/chromium/chrome/browser/resources/settings/page_visibility.js index 419bd55a686..478a9bf84dc 100644 --- a/chromium/chrome/browser/resources/settings/page_visibility.js +++ b/chromium/chrome/browser/resources/settings/page_visibility.js @@ -7,12 +7,12 @@ * @typedef {{ * advancedSettings: (boolean|undefined), * appearance: (boolean|undefined|AppearancePageVisibility), + * autofill: (boolean|undefined), * dateTime: (boolean|undefined|DateTimePageVisibility), * defaultBrowser: (boolean|undefined), * downloads: (boolean|undefined|DownloadsPageVisibility), * multidevice: (boolean|undefined), * onStartup: (boolean|undefined), - * passwordsAndForms: (boolean|undefined), * people: (boolean|undefined), * privacy: (boolean|undefined|PrivacyPageVisibility), * reset:(boolean|undefined), @@ -65,7 +65,7 @@ cr.define('settings', function() { // to work around closure compiler. // <if expr="not chromeos"> pageVisibility = { - passwordsAndForms: false, + autofill: false, people: false, onStartup: false, reset: false, @@ -76,7 +76,7 @@ cr.define('settings', function() { // </if> // <if expr="chromeos"> pageVisibility = { - passwordsAndForms: false, + autofill: false, people: false, onStartup: false, reset: false, @@ -103,7 +103,7 @@ cr.define('settings', function() { // after a property is set. // <if expr="chromeos"> pageVisibility = { - passwordsAndForms: true, + autofill: true, people: true, onStartup: true, reset: true, diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.js b/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.js deleted file mode 100644 index eadb3769d0c..00000000000 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.js +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2015 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. - -Polymer({ - is: 'settings-passwords-and-forms-page', - - behaviors: [PrefsBehavior], - - properties: { - /** @private Filter applied to passwords and password exceptions. */ - passwordFilter_: String, - - /** @type {?Map<string, string>} */ - focusConfig: Object, - }, - - /** @override */ - ready: function() { - this.focusConfig_ = new Map(); - if (settings.routes.AUTOFILL) { - this.focusConfig_.set( - settings.routes.AUTOFILL.path, '#autofillManagerButton'); - } - if (settings.routes.MANAGE_PASSWORDS) { - this.focusConfig_.set( - settings.routes.MANAGE_PASSWORDS.path, - '#passwordManagerButton .subpage-arrow button'); - } - }, - - /** - * Shows the manage autofill sub page. - * @param {!Event} event - * @private - */ - onAutofillTap_: function(event) { - settings.navigateTo(settings.routes.AUTOFILL); - }, - - /** - * Shows the manage payment methods sub page. - * @private - */ - onPaymentsTap_: function() { - settings.navigateTo(settings.routes.PAYMENTS); - }, - - /** - * Shows the manage passwords sub page. - * @private - */ - onPasswordsTap_: function() { - settings.navigateTo(settings.routes.MANAGE_PASSWORDS); - }, -}); diff --git a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_export_dialog.html b/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_export_dialog.html deleted file mode 100644 index bb85a7e20b2..00000000000 --- a/chromium/chrome/browser/resources/settings/passwords_and_forms_page/passwords_export_dialog.html +++ /dev/null @@ -1,75 +0,0 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> -<link rel="import" href="../settings_shared_css.html"> - -<dom-module id="passwords-export-dialog"> - <template> - <style include="settings-shared iron-flex"> - paper-progress { - width: 100%; - --paper-progress-active-color: var(--google-blue-500); - } - .action-button { - margin-inline-start: 8px; - } - </style> - <cr-dialog id="dialog_start" close-text="$i18n{close}"> - <div slot="title">$i18n{exportPasswordsTitle}</div> - <div slot="body"> - <div class="layout horizontal center"> - <div>$i18n{exportPasswordsDescription}</div> - </div> - </div> - <div slot="button-container"> - <paper-button class="secondary-button header-aligned-button" - on-click="onCancelButtonTap_" id="cancelButton"> - $i18n{cancel} - </paper-button> - <paper-button class="action-button header-aligned-button" - on-click="onExportTap_" id="exportPasswordsButton"> - $i18n{exportPasswords} - </paper-button> - </div> - </cr-dialog> - - <cr-dialog id="dialog_progress" no-cancel="true"> - <div slot="title">$i18n{exportingPasswordsTitle}</div> - <div slot="body"> - <paper-progress indeterminate class="blue"></paper-progress> - </div> - <div slot="button-container"> - <paper-button id="cancel_progress_button" - class="secondary-button header-aligned-button" - on-click="onCancelProgressButtonTap_"> - $i18n{cancel} - </paper-button> - </div> - </cr-dialog> - - <cr-dialog id="dialog_error" close-text="$i18n{close}"> - <div slot="title">[[exportErrorMessage]]</div> - <div slot="body"> - $i18n{exportPasswordsFailTips} - <ul> - <li>$i18n{exportPasswordsFailTipsEnoughSpace}</li> - <li>$i18n{exportPasswordsFailTipsAnotherFolder}</li> - </ul> - </div> - <div slot="button-container"> - <paper-button class="secondary-button header-aligned-button" - on-click="onCancelButtonTap_" id="cancelErrorButton"> - $i18n{cancel} - </paper-button> - <paper-button class="action-button header-aligned-button" - on-click="onExportTap_" id="tryAgainButton"> - $i18n{exportPasswordsTryAgain} - </paper-button> - </div> - </cr-dialog> - - </template> - <script src="passwords_export_dialog.js"></script> -</dom-module> diff --git a/chromium/chrome/browser/resources/settings/people_page/BUILD.gn b/chromium/chrome/browser/resources/settings/people_page/BUILD.gn index ba5fd559a80..e1f615b8d59 100644 --- a/chromium/chrome/browser/resources/settings/people_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/people_page/BUILD.gn @@ -10,8 +10,6 @@ js_type_check("closure_compile") { ":account_manager_browser_proxy", ":change_picture", ":change_picture_browser_proxy", - ":easy_unlock_browser_proxy", - ":easy_unlock_turn_off_dialog", ":fingerprint_browser_proxy", ":fingerprint_list", ":import_data_browser_proxy", @@ -72,22 +70,6 @@ js_library("change_picture_browser_proxy") { ] } -js_library("easy_unlock_browser_proxy") { - deps = [ - "//ui/webui/resources/js:cr", - ] -} - -js_library("easy_unlock_turn_off_dialog") { - deps = [ - ":easy_unlock_browser_proxy", - "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog", - "//ui/webui/resources/js:cr", - "//ui/webui/resources/js:i18n_behavior", - "//ui/webui/resources/js:web_ui_listener_behavior", - ] -} - js_library("fingerprint_browser_proxy") { deps = [ "//ui/webui/resources/js:cr", @@ -117,8 +99,6 @@ js_library("import_data_browser_proxy") { js_library("lock_screen") { deps = [ - ":easy_unlock_browser_proxy", - ":easy_unlock_turn_off_dialog", ":fingerprint_browser_proxy", ":lock_screen_password_prompt_dialog", ":lock_state_behavior", @@ -177,6 +157,7 @@ js_library("people_page") { ":profile_info_browser_proxy", ":signout_dialog", ":sync_browser_proxy", + "..:open_window_proxy", "..:page_visibility", "..:route", "../settings_page:settings_animated_pages", diff --git a/chromium/chrome/browser/resources/settings/people_page/easy_unlock_browser_proxy.html b/chromium/chrome/browser/resources/settings/people_page/easy_unlock_browser_proxy.html deleted file mode 100644 index cd7138a6872..00000000000 --- a/chromium/chrome/browser/resources/settings/people_page/easy_unlock_browser_proxy.html +++ /dev/null @@ -1 +0,0 @@ -<script src="easy_unlock_browser_proxy.js"></script> diff --git a/chromium/chrome/browser/resources/settings/people_page/easy_unlock_browser_proxy.js b/chromium/chrome/browser/resources/settings/people_page/easy_unlock_browser_proxy.js deleted file mode 100644 index 008e6c94931..00000000000 --- a/chromium/chrome/browser/resources/settings/people_page/easy_unlock_browser_proxy.js +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2016 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. - -/** - * @fileoverview A helper object used from the the People section to interact - * with the Easy Unlock functionality of the browser. ChromeOS only. - */ -cr.exportPath('settings'); - -cr.define('settings', function() { - /** @interface */ - class EasyUnlockBrowserProxy { - /** - * Returns a true promise if Easy Unlock is already enabled on the device. - * @return {!Promise<boolean>} - */ - getEnabledStatus() {} - - /** - * Starts the Easy Unlock setup flow. - */ - startTurnOnFlow() {} - - /** - * Returns the Easy Unlock turn off flow status. - * @return {!Promise<string>} - */ - getTurnOffFlowStatus() {} - - /** - * Begins the Easy Unlock turn off flow. - */ - startTurnOffFlow() {} - - /** - * Cancels any in-progress Easy Unlock turn-off flows. - */ - cancelTurnOffFlow() {} - } - - /** - * @implements {settings.EasyUnlockBrowserProxy} - */ - class EasyUnlockBrowserProxyImpl { - /** @override */ - getEnabledStatus() { - return cr.sendWithPromise('easyUnlockGetEnabledStatus'); - } - - /** @override */ - startTurnOnFlow() { - chrome.send('easyUnlockStartTurnOnFlow'); - } - - /** @override */ - getTurnOffFlowStatus() { - return cr.sendWithPromise('easyUnlockGetTurnOffFlowStatus'); - } - - /** @override */ - startTurnOffFlow() { - chrome.send('easyUnlockStartTurnOffFlow'); - } - - /** @override */ - cancelTurnOffFlow() { - chrome.send('easyUnlockCancelTurnOffFlow'); - } - } - - // The singleton instance_ is replaced with a test version of this wrapper - // during testing. - cr.addSingletonGetter(EasyUnlockBrowserProxyImpl); - - return { - EasyUnlockBrowserProxy: EasyUnlockBrowserProxy, - EasyUnlockBrowserProxyImpl: EasyUnlockBrowserProxyImpl, - }; -}); diff --git a/chromium/chrome/browser/resources/settings/people_page/easy_unlock_turn_off_dialog.html b/chromium/chrome/browser/resources/settings/people_page/easy_unlock_turn_off_dialog.html deleted file mode 100644 index df78b847b84..00000000000 --- a/chromium/chrome/browser/resources/settings/people_page/easy_unlock_turn_off_dialog.html +++ /dev/null @@ -1,37 +0,0 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> -<link rel="import" href="chrome://resources/html/i18n_behavior.html"> -<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner-lite.html"> -<link rel="import" href="../i18n_setup.html"> -<link rel="import" href="easy_unlock_browser_proxy.html"> -<link rel="import" href="../settings_shared_css.html"> - -<dom-module id="easy-unlock-turn-off-dialog"> - <template> - <style include="settings-shared"></style> - <cr-dialog id="dialog" close-text="$i18n{close}"> - <div slot="title">[[getTitleText_(status_)]]</div> - <div slot="body"> - [[getDescriptionText_(status_)]] - </div> - <div slot="button-container" - hidden="[[isButtonBarHidden_(status_)]]"> - <paper-spinner-lite active="[[isSpinnerActive_(status_)]]"> - </paper-spinner-lite> - <paper-button class="cancel-button" on-click="onCancelTap_" - hidden="[[isCancelButtonHidden_(status_)]]"> - $i18n{cancel} - </paper-button> - <paper-button id="turnOff" class="action-button" - on-click="onTurnOffTap_" - disabled="[[!isTurnOffButtonEnabled_(status_)]]"> - [[getTurnOffButtonText_(status_)]] - </paper-button> - </div> - </cr-dialog> - </template> - <script src="easy_unlock_turn_off_dialog.js"></script> -</dom-module> diff --git a/chromium/chrome/browser/resources/settings/people_page/easy_unlock_turn_off_dialog.js b/chromium/chrome/browser/resources/settings/people_page/easy_unlock_turn_off_dialog.js deleted file mode 100644 index 1e4ad8f6f1c..00000000000 --- a/chromium/chrome/browser/resources/settings/people_page/easy_unlock_turn_off_dialog.js +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright 2016 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. - -/** - * @fileoverview A dialog allowing the user to turn off the Easy Unlock feature. - */ - -cr.exportPath('settings'); - -/** - * Possible UI statuses for the EasyUnlockTurnOffDialogElement. - * See easy_unlock_settings_handler.cc. - * @enum {string} - */ -settings.EasyUnlockTurnOffStatus = { - UNKNOWN: 'unknown', - OFFLINE: 'offline', - IDLE: 'idle', - PENDING: 'pending', - SERVER_ERROR: 'server-error', -}; - -(function() { - -Polymer({ - is: 'easy-unlock-turn-off-dialog', - - behaviors: [I18nBehavior, WebUIListenerBehavior], - - properties: { - /** @private {!settings.EasyUnlockTurnOffStatus} */ - status_: { - type: String, - value: settings.EasyUnlockTurnOffStatus.UNKNOWN, - }, - }, - - /** @private {settings.EasyUnlockBrowserProxy} */ - browserProxy_: null, - - /** @override */ - attached: function() { - this.browserProxy_ = settings.EasyUnlockBrowserProxyImpl.getInstance(); - - this.addWebUIListener( - 'easy-unlock-enabled-status', - this.handleEasyUnlockEnabledStatusChanged_.bind(this)); - - this.addWebUIListener('easy-unlock-turn-off-flow-status', status => { - this.status_ = status; - }); - - // Since the dialog text depends on the status, defer opening until we have - // retrieved the turn off status to prevent UI flicker. - this.getTurnOffStatus_().then(status => { - this.status_ = status; - this.$.dialog.showModal(); - }); - }, - - /** - * @return {!Promise<!settings.EasyUnlockTurnOffStatus>} - * @private - */ - getTurnOffStatus_: function() { - return navigator.onLine ? - this.browserProxy_.getTurnOffFlowStatus() : - Promise.resolve(settings.EasyUnlockTurnOffStatus.OFFLINE); - }, - - /** - * This dialog listens for Easy Unlock to become disabled. This signals - * that the turnoff process has succeeded. Regardless of whether the turnoff - * was initiated from this tab or another, this closes the dialog. - * @param {boolean} easyUnlockEnabled - * @private - */ - handleEasyUnlockEnabledStatusChanged_: function(easyUnlockEnabled) { - const dialog = /** @type {!CrDialogElement} */ (this.$.dialog); - if (!easyUnlockEnabled && dialog.open) - this.onCancelTap_(); - }, - - /** @private */ - onCancelTap_: function() { - this.browserProxy_.cancelTurnOffFlow(); - this.$.dialog.close(); - }, - - /** @private */ - onTurnOffTap_: function() { - this.browserProxy_.startTurnOffFlow(); - }, - - /** - * @param {!settings.EasyUnlockTurnOffStatus} status - * @return {string} - * @private - */ - getTitleText_: function(status) { - switch (status) { - case settings.EasyUnlockTurnOffStatus.OFFLINE: - return this.i18n('easyUnlockTurnOffOfflineTitle'); - case settings.EasyUnlockTurnOffStatus.UNKNOWN: - case settings.EasyUnlockTurnOffStatus.IDLE: - case settings.EasyUnlockTurnOffStatus.PENDING: - return this.i18n('easyUnlockTurnOffTitle'); - case settings.EasyUnlockTurnOffStatus.SERVER_ERROR: - return this.i18n('easyUnlockTurnOffErrorTitle'); - } - assertNotReached(); - }, - - /** - * @param {!settings.EasyUnlockTurnOffStatus} status - * @return {string} - * @private - */ - getDescriptionText_: function(status) { - switch (status) { - case settings.EasyUnlockTurnOffStatus.OFFLINE: - return this.i18n('easyUnlockTurnOffOfflineMessage'); - case settings.EasyUnlockTurnOffStatus.UNKNOWN: - case settings.EasyUnlockTurnOffStatus.IDLE: - case settings.EasyUnlockTurnOffStatus.PENDING: - return this.i18n('easyUnlockTurnOffDescription'); - case settings.EasyUnlockTurnOffStatus.SERVER_ERROR: - return this.i18n('easyUnlockTurnOffErrorMessage'); - } - assertNotReached(); - }, - - /** - * @param {!settings.EasyUnlockTurnOffStatus} status - * @return {string} - * @private - */ - getTurnOffButtonText_: function(status) { - switch (status) { - case settings.EasyUnlockTurnOffStatus.OFFLINE: - return ''; - case settings.EasyUnlockTurnOffStatus.UNKNOWN: - case settings.EasyUnlockTurnOffStatus.IDLE: - case settings.EasyUnlockTurnOffStatus.PENDING: - return this.i18n('easyUnlockTurnOffButton'); - case settings.EasyUnlockTurnOffStatus.SERVER_ERROR: - return this.i18n('retry'); - } - assertNotReached(); - }, - - /** - * @param {!settings.EasyUnlockTurnOffStatus} status - * @return {boolean} - * @private - */ - isButtonBarHidden_: function(status) { - return status == settings.EasyUnlockTurnOffStatus.OFFLINE; - }, - - /** - * @param {!settings.EasyUnlockTurnOffStatus} status - * @return {boolean} - * @private - */ - isSpinnerActive_: function(status) { - return status == settings.EasyUnlockTurnOffStatus.PENDING; - }, - - /** - * @param {!settings.EasyUnlockTurnOffStatus} status - * @return {boolean} - * @private - */ - isCancelButtonHidden_: function(status) { - return status == settings.EasyUnlockTurnOffStatus.SERVER_ERROR; - }, - - /** - * @param {!settings.EasyUnlockTurnOffStatus} status - * @return {boolean} - * @private - */ - isTurnOffButtonEnabled_: function(status) { - return status == settings.EasyUnlockTurnOffStatus.IDLE || - status == settings.EasyUnlockTurnOffStatus.SERVER_ERROR; - }, -}); - -})(); diff --git a/chromium/chrome/browser/resources/settings/people_page/lock_screen.html b/chromium/chrome/browser/resources/settings/people_page/lock_screen.html index b3cc906b22e..928777426e0 100644 --- a/chromium/chrome/browser/resources/settings/people_page/lock_screen.html +++ b/chromium/chrome/browser/resources/settings/people_page/lock_screen.html @@ -2,15 +2,13 @@ <link rel="import" href="chrome://resources/cr_components/chromeos/quick_unlock/lock_screen_constants.html"> <link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_radio_group/cr_radio_group.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html"> <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-group/paper-radio-group.html"> <link rel="import" href="../controls/settings_toggle_button.html"> -<link rel="import" href="easy_unlock_browser_proxy.html"> -<link rel="import" href="easy_unlock_turn_off_dialog.html"> <link rel="import" href="fingerprint_browser_proxy.html"> <link rel="import" href="lock_state_behavior.html"> <link rel="import" href="lock_screen_password_prompt_dialog.html"> @@ -32,14 +30,6 @@ padding-top: 24px; } - #easyUnlock .start { - /* When the easy unlock toggle is shown, the easy unlock section's - * content becomes squashed to the top and bottom edges. Use padding to - * ensure the easy unlock content looks correct. - */ - padding: 11px 0; - } - #lockOptionsDiv { display: block; } @@ -58,14 +48,6 @@ margin: auto; } - #easyUnlockSettingsCollapsible { - @apply --settings-list-frame-padding; - } - - .no-padding { - padding: 0; - } - .underbar { border-bottom: var(--settings-separator-line); } @@ -93,9 +75,9 @@ </template> </div> <div class="list-frame" > - <paper-radio-group id="unlockType" + <cr-radio-group id="unlockType" disabled$="[[quickUnlockDisabledByPolicy_]]" - selected="{{selectedUnlockType}}" selectable="cr-radio-button"> + selected="{{selectedUnlockType}}"> <cr-radio-button name="password" class="list-item underbar"> <div class="start"> $i18n{lockScreenPasswordOnly} @@ -121,7 +103,7 @@ </div> </template> </cr-radio-button> - </paper-radio-group> + </cr-radio-group> </div> </div> </template> @@ -132,8 +114,7 @@ </h2> <div class="list-frame"> <settings-radio-group - pref="{{prefs.ash.message_center.lock_screen_mode}}" - selectable="cr-radio-button"> + pref="{{prefs.ash.message_center.lock_screen_mode}}"> <template is="dom-if" if="[[lockScreenHideSensitiveNotificationSupported_]]"> <cr-radio-button name="hideSensitive" class="list-item underbar" @@ -173,58 +154,6 @@ </div> </template> - <template is="dom-if" if="[[easyUnlockAvailable_( - multideviceSettingsEnabled_, easyUnlockAllowed_, - easyUnlockInLegacyHostMode_)]]"> - <div id="easyUnlock" class="settings-box two-line"> - <div class="start"> - <div>$i18n{easyUnlockSectionTitle}</div> - <div class="secondary"> - [[getEasyUnlockDescription_(easyUnlockEnabled_, - '$i18nPolymer{easyUnlockDescription}', - '$i18nPolymer{easyUnlockSetupIntro}')]] - <a target="_blank" href="$i18n{easyUnlockLearnMoreURL}"> - $i18n{learnMore} - </a> - </div> - </div> - <template is="dom-if" if="[[easyUnlockAvailable_( - multideviceSettingsEnabled_, easyUnlockAllowed_, - easyUnlockInLegacyHostMode_)]]"> - <div class="separator"></div> - <template is="dom-if" if="[[!easyUnlockEnabled_]]"> - <paper-button id="easyUnlockSetup" class="secondary-button" - on-click="onEasyUnlockSetupTap_"> - $i18n{easyUnlockSetupButton} - </paper-button> - </template> - <template is="dom-if" if="[[easyUnlockEnabled_]]"> - <paper-button id="easyUnlockTurnOff" class="secondary-button" - on-click="onEasyUnlockTurnOffTap_"> - $i18n{easyUnlockTurnOffButton} - </paper-button> - </template> - </template> - </div> - <iron-collapse opened="[[easyUnlockEnabled_]]" - id="easyUnlockSettingsCollapsible"> - <settings-toggle-button - class="continuation no-padding underbar" - pref="{{prefs.proximity_auth.is_chromeos_login_enabled}}" - label="$i18n{easyUnlockAllowSignInLabel}"> - </settings-toggle-button> - <div class="settings-box continuation no-padding"> - <div class="start"> - $i18n{easyUnlockProximityThresholdLabel} - </div> - <settings-dropdown-menu - pref="{{prefs.easy_unlock.proximity_threshold}}" - menu-options="[[easyUnlockProximityThresholdMapping_]]"> - </settings-dropdown-menu> - </div> - </iron-collapse> - </template> - <template is="dom-if" if="[[showPasswordPromptDialog_]]" restamp> <settings-lock-screen-password-prompt-dialog id="lockScreenPasswordPrompt" @@ -238,12 +167,6 @@ on-close="onSetupPinDialogClose_"> </settings-setup-pin-dialog> </template> - - <template is="dom-if" if="[[showEasyUnlockTurnOffDialog_]]" restamp> - <easy-unlock-turn-off-dialog id="easyUnlockTurnOffDialog" - on-close="onEasyUnlockTurnOffDialogClose_"> - </easy-unlock-turn-off-dialog> - </template> </div> </template> diff --git a/chromium/chrome/browser/resources/settings/people_page/lock_screen.js b/chromium/chrome/browser/resources/settings/people_page/lock_screen.js index 52bfe6f1012..f93305d5579 100644 --- a/chromium/chrome/browser/resources/settings/people_page/lock_screen.js +++ b/chromium/chrome/browser/resources/settings/people_page/lock_screen.js @@ -14,18 +14,6 @@ * </settings-lock-screen> */ -/** - * Possible values of the proximity threshold displayed to the user. - * This should be kept in sync with the enum defined here: - * components/proximity_auth/proximity_monitor_impl.cc - */ -settings.EasyUnlockProximityThreshold = { - VERY_CLOSE: 0, - CLOSE: 1, - FAR: 2, - VERY_FAR: 3, -}; - Polymer({ is: 'settings-lock-screen', @@ -114,80 +102,6 @@ Polymer({ }, /** - * True if Easy Unlock is allowed on this machine. - */ - easyUnlockAllowed_: { - type: Boolean, - value: function() { - return loadTimeData.getBoolean('easyUnlockAllowed'); - }, - readOnly: true, - }, - - /** - * True if Easy Unlock is enabled. - */ - easyUnlockEnabled_: { - type: Boolean, - value: function() { - return loadTimeData.getBoolean('easyUnlockEnabled'); - }, - }, - - /** - * True if Easy Unlock is in legacy host mode. - * - * TODO(crbug.com/894585): Remove this legacy special case after M71. - */ - easyUnlockInLegacyHostMode_: { - type: Boolean, - value: function() { - return loadTimeData.getBoolean('easyUnlockInLegacyHostMode'); - }, - }, - - /** - * True if Multidevice Setup is enabled. - * @private {boolean} - */ - multideviceSettingsEnabled_: { - type: Boolean, - value: function() { - return loadTimeData.getBoolean('enableMultideviceSettings'); - }, - }, - - /** - * Returns the proximity threshold mapping to be displayed in the - * threshold selector dropdown menu. - */ - easyUnlockProximityThresholdMapping_: { - type: Array, - value: function() { - return [ - { - value: settings.EasyUnlockProximityThreshold.VERY_CLOSE, - name: - loadTimeData.getString('easyUnlockProximityThresholdVeryClose') - }, - { - value: settings.EasyUnlockProximityThreshold.CLOSE, - name: loadTimeData.getString('easyUnlockProximityThresholdClose') - }, - { - value: settings.EasyUnlockProximityThreshold.FAR, - name: loadTimeData.getString('easyUnlockProximityThresholdFar') - }, - { - value: settings.EasyUnlockProximityThreshold.VERY_FAR, - name: loadTimeData.getString('easyUnlockProximityThresholdVeryFar') - } - ]; - }, - readOnly: true, - }, - - /** * Whether notifications on the lock screen are enable by the feature flag. * @private */ @@ -214,21 +128,12 @@ Polymer({ }, /** @private */ - showEasyUnlockTurnOffDialog_: { - type: Boolean, - value: false, - }, - - /** @private */ showPasswordPromptDialog_: Boolean, /** @private */ showSetupPinDialog_: Boolean, }, - /** @private {?settings.EasyUnlockBrowserProxy} */ - easyUnlockBrowserProxy_: null, - /** @private {?settings.FingerprintBrowserProxy} */ fingerprintBrowserProxy_: null, @@ -240,19 +145,9 @@ Polymer({ if (this.shouldAskForPassword_(settings.getCurrentRoute())) this.openPasswordPromptDialog_(); - this.easyUnlockBrowserProxy_ = - settings.EasyUnlockBrowserProxyImpl.getInstance(); this.fingerprintBrowserProxy_ = settings.FingerprintBrowserProxyImpl.getInstance(); this.updateNumFingerprints_(); - - if (this.easyUnlockAllowed_) { - this.addWebUIListener( - 'easy-unlock-enabled-status', - this.handleEasyUnlockEnabledStatusChanged_.bind(this)); - this.easyUnlockBrowserProxy_.getEnabledStatus().then( - this.handleEasyUnlockEnabledStatusChanged_.bind(this)); - } }, /** @@ -395,51 +290,6 @@ Polymer({ return route == settings.routes.LOCK_SCREEN && !this.setModes_; }, - /** - * Handler for when the Easy Unlock enabled status has changed. - * @private - */ - handleEasyUnlockEnabledStatusChanged_: function(easyUnlockEnabled) { - this.easyUnlockEnabled_ = easyUnlockEnabled; - this.showEasyUnlockTurnOffDialog_ = - easyUnlockEnabled && this.showEasyUnlockTurnOffDialog_; - }, - - /** @private */ - onEasyUnlockSetupTap_: function() { - this.easyUnlockBrowserProxy_.startTurnOnFlow(); - }, - - /** - * @param {!Event} e - * @private - */ - onEasyUnlockTurnOffTap_: function(e) { - // Prevent the end of the tap event from focusing what is underneath the - // button. - e.preventDefault(); - this.showEasyUnlockTurnOffDialog_ = true; - }, - - /** @private */ - onEasyUnlockTurnOffDialogClose_: function() { - this.showEasyUnlockTurnOffDialog_ = false; - - // Restores focus on close to either the turn-off or set-up button, - // whichever is being displayed. - cr.ui.focusWithoutInk(assert(this.$$('.secondary-button'))); - }, - - /** - * @param {boolean} enabled - * @param {!string} enabledStr - * @param {!string} disabledStr - * @private - */ - getEasyUnlockDescription_: function(enabled, enabledStr, disabledStr) { - return enabled ? enabledStr : disabledStr; - }, - /** @private */ updateNumFingerprints_: function() { if (this.fingerprintUnlockEnabled_ && this.fingerprintBrowserProxy_) { @@ -460,15 +310,4 @@ Polymer({ return this.i18n('lockScreenOptionsLoginLock'); return this.i18n('lockScreenOptionsLock'); }, - - /** - * @return {boolean} Whether Easy Unlock is available. - * @private - */ - easyUnlockAvailable_: function( - multiDeviceEnabled, easyUnlockAllowed, easyUnlockInLegacyHostMode) { - return ( - (!multiDeviceEnabled || easyUnlockInLegacyHostMode) && - easyUnlockAllowed); - }, }); diff --git a/chromium/chrome/browser/resources/settings/people_page/manage_profile.js b/chromium/chrome/browser/resources/settings/people_page/manage_profile.js index 7f38ab1b061..d00a74d592a 100644 --- a/chromium/chrome/browser/resources/settings/people_page/manage_profile.js +++ b/chromium/chrome/browser/resources/settings/people_page/manage_profile.js @@ -78,8 +78,8 @@ Polymer({ /** @protected */ currentRouteChanged: function() { if (settings.getCurrentRoute() == settings.routes.MANAGE_PROFILE) { - this.$.name.value = this.profileName; - + if (this.profileName) + this.$.name.value = this.profileName; if (loadTimeData.getBoolean('profileShortcutsEnabled')) { this.browserProxy_.getProfileShortcutStatus().then(status => { if (status == ProfileShortcutStatus.PROFILE_SHORTCUT_SETTING_HIDDEN) { diff --git a/chromium/chrome/browser/resources/settings/people_page/people_page.html b/chromium/chrome/browser/resources/settings/people_page/people_page.html index b5ad0881c12..118ab0e2427 100644 --- a/chromium/chrome/browser/resources/settings/people_page/people_page.html +++ b/chromium/chrome/browser/resources/settings/people_page/people_page.html @@ -12,18 +12,17 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="../controls/settings_toggle_button.html"> -<link rel="import" href="sync_page.html"> <link rel="import" href="profile_info_browser_proxy.html"> <link rel="import" href="sync_browser_proxy.html"> +<link rel="import" href="sync_page.html"> <link rel="import" href="../icons.html"> +<link rel="import" href="../open_window_proxy.html"> <link rel="import" href="../route.html"> <link rel="import" href="../settings_page/settings_animated_pages.html"> <link rel="import" href="../settings_page/settings_subpage.html"> -<link rel="import" href="../passwords_and_forms_page/autofill_section.html"> -<link rel="import" href="../passwords_and_forms_page/passwords_section.html"> -<link rel="import" href="../passwords_and_forms_page/payments_section.html"> <link rel="import" href="../settings_shared_css.html"> <link rel="import" href="signout_dialog.html"> +<link rel="import" href="sync_controls.html"> <if expr="chromeos"> <link rel="import" href="account_manager.html"> @@ -253,29 +252,18 @@ <template is="dom-if" if="[[unifiedConsentEnabled_]]"> <cr-link-row id="sync-setup" - start-icon="settings20:googleg" label="$i18n{syncAndNonPersonalizedServices}" icon-class="subpage-arrow" on-click="onSyncTap_"> </cr-link-row> </template> - <template is="dom-if" if="[[autofillHomeEnabled]]"> - <cr-link-row id="passwordManagerButton" - start-icon="settings20:vpn-key" - label="$i18n{passwords}" icon-class="subpage-arrow" - on-click="onPasswordsTap_"></cr-link-row> - <cr-link-row id="paymentManagerButton" - start-icon="settings20:credit-card" - label="$i18n{creditCards}" icon-class="subpage-arrow" - on-click="onPaymentsTap_"></cr-link-row> - <cr-link-row id="addressesManagerButton" - start-icon="settings20:location-on" - label="$i18n{addressesTitle}" icon-class="subpage-arrow" - on-click="onAutofillTap_"></cr-link-row> - </template> - <if expr="not chromeos"> <template is="dom-if" if="[[diceEnabled_]]"> + <cr-link-row id="manage-google-account" + label="$i18n{manageGoogleAccount}" icon-class="icon-external" + hidden="[[!shouldShowGoogleAccount_]]" + on-click="openGoogleAccount_"></cr-link-row> + <div class="settings-box" id="edit-profile" on-click="onProfileTap_" actionable> <div class="start">$i18n{profileNameAndPicture}</div> @@ -312,16 +300,11 @@ </paper-icon-button-light> </div> </template> -</if> - <div id="manage-other-people-subpage-trigger" - class="settings-box" on-click="onManageOtherPeople_" actionable - hidden="[[isChild_]]"> - <div class="start">$i18n{manageOtherPeople}</div> - <paper-icon-button-light class="subpage-arrow"> - <button aria-label="$i18n{manageOtherPeople}"></button> - </paper-icon-button-light> - </div> + <cr-link-row id="manage-other-people-subpage-trigger" + label="$i18n{manageOtherPeople}" icon-class="subpage-arrow" + on-click="onManageOtherPeople_"></cr-link-row> +</if> <if expr="not chromeos"> <div class="settings-box" on-click="onImportDataTap_" actionable> @@ -356,34 +339,13 @@ </settings-subpage> </template> - <template is="dom-if" if="[[autofillHomeEnabled]]"> - <template is="dom-if" route-path="/passwords"> - <settings-subpage - associated-control="[[$$('#passwordManagerButton')]]" - page-title="$i18n{passwords}" - learn-more-url="$i18n{passwordManagerLearnMoreURL}" - search-label="$i18n{searchPasswords}" - search-term="{{passwordFilter_}}"> - <passwords-section id="passwordSection" filter="[[passwordFilter_]]" - prefs="{{prefs}}"> - </passwords-section> - </settings-subpage> - </template> - <template is="dom-if" route-path="/autofill"> - <settings-subpage - associated-control="[[$$('#addressesManagerButton')]]" - page-title="$i18n{autofill}"> - <settings-autofill-section id="autofillSection" prefs="{{prefs}}"> - </settings-autofill-section> - </settings-subpage> - </template> - <template is="dom-if" route-path="/payments"> - <settings-subpage - associated-control="[[$$('#paymentManagerButton')]]" - page-title="$i18n{creditCards}" - learn-more-url="$i18n{paymentMethodsLearnMoreURL}"> - <settings-payments-section id="paymentsSection" prefs="{{prefs}}"> - </settings-payments-section> + <template is="dom-if" if="[[unifiedConsentEnabled_]]"> + <template is="dom-if" route-path="/syncSetup/advanced" no-search> + <settings-subpage page-title="$i18n{syncAdvancedPageTitle}" + learn-more-url="$i18n{syncAndGoogleServicesLearnMoreURL}"> + <settings-sync-controls sync-status="[[syncStatus]]" + on-sync-setup-cancel="cancelSyncSetup_"> + </settings-sync-controls> </settings-subpage> </template> </template> diff --git a/chromium/chrome/browser/resources/settings/people_page/people_page.js b/chromium/chrome/browser/resources/settings/people_page/people_page.js index 20329865650..c5286925c20 100644 --- a/chromium/chrome/browser/resources/settings/people_page/people_page.js +++ b/chromium/chrome/browser/resources/settings/people_page/people_page.js @@ -25,9 +25,6 @@ Polymer({ notify: true, }, - /** @private Filter applied to passwords and password exceptions. */ - passwordFilter_: String, - // <if expr="not chromeos"> /** * This flag is used to conditionally show a set of new sign-in UIs to the @@ -58,9 +55,13 @@ Polymer({ }, }, - // TODO(jdoerrie): https://crbug.com/854562. - // Remove once Autofill Home is launched. - autofillHomeEnabled: Boolean, + // <if expr="not chromeos"> + /** + * Stored accounts to the system, supplied by SyncBrowserProxy. + * @type {?Array<!settings.StoredAccount>} + */ + storedAccounts: Object, + // </if> /** * The current sync status, supplied by SyncBrowserProxy. @@ -87,6 +88,14 @@ Polymer({ profileName_: String, // <if expr="not chromeos"> + /** @private {boolean} */ + shouldShowGoogleAccount_: { + type: Boolean, + value: false, + computed: 'computeShouldShowGoogleAccount_(storedAccounts, syncStatus,' + + 'storedAccounts.length, syncStatus.signedIn, syncStatus.hasError)', + }, + /** @private */ showImportDataDialog_: { type: Boolean, @@ -129,20 +138,11 @@ Polymer({ value: function() { const map = new Map(); if (settings.routes.SYNC) { - const syncId = loadTimeData.getBoolean('unifiedConsentEnabled') ? - '#sync-setup' : - '#sync-status'; - map.set(settings.routes.SYNC.path, `${syncId} .subpage-arrow button`); - } - if (settings.routes.MANAGE_PASSWORDS) { map.set( - settings.routes.MANAGE_PASSWORDS.path, '#passwordManagerButton'); - } - if (settings.routes.AUTOFILL) { - map.set(settings.routes.AUTOFILL.path, '#addressesManagerButton'); - } - if (settings.routes.PAYMENTS) { - map.set(settings.routes.PAYMENTS.path, '#paymentManagerButton'); + settings.routes.SYNC.path, + loadTimeData.getBoolean('unifiedConsentEnabled') ? + '#sync-setup' : + '#sync-status .subpage-arrow button'); } // <if expr="not chromeos"> if (settings.routes.MANAGE_PROFILE) { @@ -167,7 +167,7 @@ Polymer({ if (settings.routes.ACCOUNTS) { map.set( settings.routes.ACCOUNTS.path, - '#manage-other-people-subpage-trigger .subpage-arrow button'); + '#manage-other-people-subpage-trigger'); } if (settings.routes.ACCOUNT_MANAGER) { map.set( @@ -209,7 +209,14 @@ Polymer({ this.handleSyncStatus_.bind(this)); this.addWebUIListener( 'sync-status-changed', this.handleSyncStatus_.bind(this)); + // <if expr="not chromeos"> + const handleStoredAccounts = accounts => { + this.storedAccounts = accounts; + }; + this.syncBrowserProxy_.getStoredAccounts().then(handleStoredAccounts); + this.addWebUIListener('stored-accounts-updated', handleStoredAccounts); + this.addWebUIListener('sync-settings-saved', () => { /** @type {!CrToastElement} */ (this.$.toast).show(); }); @@ -295,6 +302,20 @@ Polymer({ } }, + // <if expr="not chromeos"> + /** + * @return {boolean} + * @private + */ + computeShouldShowGoogleAccount_: function() { + if (this.storedAccounts === undefined || this.syncStatus === undefined) + return false; + + return (this.storedAccounts.length > 0 || !!this.syncStatus.signedIn) && + !this.syncStatus.hasError; + }, + // </if> + /** @private */ onProfileTap_: function() { // <if expr="chromeos"> @@ -310,33 +331,6 @@ Polymer({ this.syncBrowserProxy_.startSignIn(); }, - /** - * Shows the manage passwords sub page. - * @param {!Event} event - * @private - */ - onPasswordsTap_: function(event) { - settings.navigateTo(settings.routes.MANAGE_PASSWORDS); - }, - - /** - * Shows the manage autofill addresses sub page. - * @param {!Event} event - * @private - */ - onAutofillTap_: function(event) { - settings.navigateTo(settings.routes.AUTOFILL); - }, - - /** - * Shows the manage payment information sub page. - * @param {!Event} event - * @private - */ - onPaymentsTap_: function(event) { - settings.navigateTo(settings.routes.PAYMENTS); - }, - /** @private */ onDisconnectDialogClosed_: function(e) { this.showSignoutDialog_ = false; @@ -364,13 +358,13 @@ Polymer({ onSyncTap_: function() { // When unified-consent is enabled, users can go to sync subpage regardless // of sync status. - // TODO(scottchen): figure out how to deal with sync error states in the - // subpage (https://crbug.com/824546). if (this.unifiedConsentEnabled_) { settings.navigateTo(settings.routes.SYNC); return; } + // TODO(crbug.com/862983): Remove this code once UnifiedConsent is rolled + // out to 100%. assert(this.syncStatus.signedIn); assert(this.syncStatus.syncSystemEnabled); @@ -427,17 +421,12 @@ Polymer({ onAccountManagerTap_: function(e) { settings.navigateTo(settings.routes.ACCOUNT_MANAGER); }, - // </if> /** @private */ onManageOtherPeople_: function() { - // <if expr="not chromeos"> - this.syncBrowserProxy_.manageOtherPeople(); - // </if> - // <if expr="chromeos"> settings.navigateTo(settings.routes.ACCOUNTS); - // </if> }, + // </if> // <if expr="not chromeos"> /** @@ -462,6 +451,15 @@ Polymer({ }, /** + * Open URL for managing your Google Account. + * @private + */ + openGoogleAccount_: function() { + settings.OpenWindowProxyImpl.getInstance().openURL( + loadTimeData.getString('googleAccountUrl')); + }, + + /** * @return {boolean} * @private */ @@ -583,4 +581,9 @@ Polymer({ return this.i18n('lockScreenTitleLoginLock'); return this.i18n('lockScreenTitleLock'); }, + + /** @private */ + cancelSyncSetup_: function() { + this.$$('settings-sync-page').cancelSyncSetup(); + }, }); diff --git a/chromium/chrome/browser/resources/settings/people_page/sync_account_control.html b/chromium/chrome/browser/resources/settings/people_page/sync_account_control.html index 7726f002f48..74dce2d6c5f 100644 --- a/chromium/chrome/browser/resources/settings/people_page/sync_account_control.html +++ b/chromium/chrome/browser/resources/settings/people_page/sync_account_control.html @@ -201,12 +201,11 @@ disabled="[[syncStatus.setupInProgress]]"> $i18n{turnOffSync} </paper-button> - <paper-button id="sync-paused-button" class="action-button" - hidden="[[!shouldShowSigninAgainButton_( - syncStatus.signedIn, syncStatus.hasError, - syncStatus.statusAction)]]" - on-click="onSigninTap_" disabled="[[syncStatus.setupInProgress]]"> - $i18n{signInAgain} + <paper-button id="sync-error-button" class="action-button" + hidden="[[!shouldShowErrorActionButton_(syncStatus)]]" + on-click="onErrorButtonTap_" + disabled="[[syncStatus.setupInProgress]]"> + [[syncStatus.statusActionText]] </paper-button> </div> <template is="dom-if" if="[[!syncStatus.signedIn]]" restamp> diff --git a/chromium/chrome/browser/resources/settings/people_page/sync_account_control.js b/chromium/chrome/browser/resources/settings/people_page/sync_account_control.js index 20323a6e889..0e598e678d8 100644 --- a/chromium/chrome/browser/resources/settings/people_page/sync_account_control.js +++ b/chromium/chrome/browser/resources/settings/people_page/sync_account_control.js @@ -250,18 +250,23 @@ Polymer({ * @private */ shouldShowTurnOffButton_: function() { - return !this.hideButtons && !!this.syncStatus.signedIn && - !this.embeddedInSubpage; + return !this.hideButtons && !!this.syncStatus.signedIn; }, /** * @return {boolean} * @private */ - shouldShowSigninAgainButton_: function() { + shouldShowErrorActionButton_: function() { + if (this.embeddedInSubpage && + this.syncStatus.statusAction == + settings.StatusAction.ENTER_PASSPHRASE) { + // In a subpage the passphrase button is not required. + return false; + } return !this.hideButtons && !!this.syncStatus.signedIn && - this.embeddedInSubpage && !!this.syncStatus.hasError && - this.syncStatus.statusAction == settings.StatusAction.REAUTHENTICATE; + !!this.syncStatus.hasError && + this.syncStatus.statusAction != settings.StatusAction.NO_ACTION; }, /** @@ -284,9 +289,34 @@ Polymer({ }, /** @private */ + onErrorButtonTap_: function() { + switch (this.syncStatus.statusAction) { + case settings.StatusAction.REAUTHENTICATE: + this.syncBrowserProxy_.startSignIn(); + break; + case settings.StatusAction.SIGNOUT_AND_SIGNIN: + if (this.syncStatus.domain) + settings.navigateTo(settings.routes.SIGN_OUT); + else { + // Silently sign the user out without deleting their profile and + // prompt them to sign back in. + this.syncBrowserProxy_.signOut(false); + this.syncBrowserProxy_.startSignIn(); + } + break; + case settings.StatusAction.UPGRADE_CLIENT: + settings.navigateTo(settings.routes.ABOUT); + break; + case settings.StatusAction.ENTER_PASSPHRASE: + case settings.StatusAction.CONFIRM_SYNC_SETTINGS: + default: + settings.navigateTo(settings.routes.SYNC); + } + }, + + /** @private */ onSigninTap_: function() { this.syncBrowserProxy_.startSignIn(); - // Need to close here since one menu item also triggers this function. if (this.$$('#menu')) { /** @type {!CrActionMenuElement} */ (this.$$('#menu')).close(); diff --git a/chromium/chrome/browser/resources/settings/people_page/sync_browser_proxy.js b/chromium/chrome/browser/resources/settings/people_page/sync_browser_proxy.js index b2ab725ef47..fffa2eceed2 100644 --- a/chromium/chrome/browser/resources/settings/people_page/sync_browser_proxy.js +++ b/chromium/chrome/browser/resources/settings/people_page/sync_browser_proxy.js @@ -30,6 +30,7 @@ settings.StoredAccount; * signedInUsername: (string|undefined), * signinAllowed: (boolean|undefined), * statusAction: (!settings.StatusAction), + * statusActionText: (string|undefined), * statusText: (string|undefined), * supervisedUser: (boolean|undefined), * syncSystemEnabled: (boolean|undefined)}} @@ -97,9 +98,6 @@ settings.StatusAction = { * typedUrlsEnforced: boolean, * typedUrlsRegistered: boolean, * typedUrlsSynced: boolean, - * userEventsEnforced: boolean, - * userEventsRegistered: boolean, - * userEventsSynced: boolean, * }} */ settings.SyncPrefs; @@ -143,11 +141,6 @@ cr.define('settings', function() { pauseSync() {} /** - * Opens the multi-profile user manager. - */ - manageOtherPeople() {} - - /** * @return {number} the number of times the sync account promo was shown. */ getPromoImpressionCount() {} @@ -220,13 +213,6 @@ cr.define('settings', function() { * Opens the Google Activity Controls url in a new tab. */ openActivityControlsUrl() {} - - /** - * Function to invoke when the unified consent toggle state changes, to - * notify the C++ layer. - * @param {boolean} toggleChecked - */ - unifiedConsentToggleChanged(toggleChecked) {} } /** @@ -250,11 +236,6 @@ cr.define('settings', function() { } /** @override */ - manageOtherPeople() { - chrome.send('SyncSetupManageOtherPeople'); - } - - /** @override */ getPromoImpressionCount() { return parseInt( window.localStorage.getItem(PROMO_IMPRESSION_COUNT_KEY), 10) || @@ -319,11 +300,6 @@ cr.define('settings', function() { chrome.metricsPrivate.recordUserAction( 'Signin_AccountSettings_GoogleActivityControlsClicked'); } - - /** @override */ - unifiedConsentToggleChanged(toggleChecked) { - chrome.send('UnifiedConsentToggleChanged', [toggleChecked]); - } } cr.addSingletonGetter(SyncBrowserProxyImpl); diff --git a/chromium/chrome/browser/resources/settings/people_page/sync_controls.html b/chromium/chrome/browser/resources/settings/people_page/sync_controls.html new file mode 100644 index 00000000000..4ddc7d6c241 --- /dev/null +++ b/chromium/chrome/browser/resources/settings/people_page/sync_controls.html @@ -0,0 +1,201 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/html/util.html"> +<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> +<link rel="import" href="sync_browser_proxy.html"> +<link rel="import" href="../route.html"> +<link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="../settings_vars_css.html"> + +<if expr="not chromeos"> +<link rel="import" href="chrome://resources/cr_elements/cr_toast/cr_toast.html"> +</if> + +<dom-module id="settings-sync-controls"> + <template> + <style include="settings-shared"> + #sync-data-types .list-item:not([hidden]) ~ .list-item:not([hidden]) { + border-top: var(--settings-separator-line); + } + + .list-item { + display: flex; + } + + .list-item > div { + flex: 1; + } + +<if expr="not chromeos"> + #toast { + color: white; + left: 0; + z-index: 1; + } + + :host-context([dir='rtl']) #toast { + left: auto; + right: 0; + } +</if> + </style> + + <div class="settings-box first"> + <div id="syncEverythingCheckboxLabel" class="start"> + $i18n{syncEverythingCheckboxLabel} + </div> + <cr-toggle id="syncAllDataTypesControl" + checked="{{syncPrefs.syncAllDataTypes}}" + on-change="onSyncAllDataTypesChanged_" + aria-labelledby="syncEverythingCheckboxLabel"> + </cr-toggle> + </div> + + <div class="list-frame" id="sync-data-types"> + <div class="list-item" hidden="[[!syncPrefs.appsRegistered]]"> + <div id="appCheckboxLabel"> + $i18n{appCheckboxLabel} + </div> + <cr-toggle checked="{{syncPrefs.appsSynced}}" + on-change="onSingleSyncDataTypeChanged_" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.appsEnforced)]]" + aria-labelledby="appCheckboxLabel"> + </cr-toggle> + </div> + + <div class="list-item" hidden="[[!syncPrefs.bookmarksRegistered]]"> + <div id="bookmarksCheckboxLabel"> + $i18n{bookmarksCheckboxLabel} + </div> + <cr-toggle checked="{{syncPrefs.bookmarksSynced}}" + on-change="onSingleSyncDataTypeChanged_" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.bookmarksEnforced)]]" + aria-labelledby="bookmarksCheckboxLabel"> + </cr-toggle> + </div> + + <div class="list-item" hidden="[[!syncPrefs.extensionsRegistered]]"> + <div id="extensionsCheckboxLabel"> + $i18n{extensionsCheckboxLabel} + </div> + <cr-toggle checked="{{syncPrefs.extensionsSynced}}" + on-change="onSingleSyncDataTypeChanged_" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.extensionsEnforced)]]" + aria-labelledby="extensionsCheckboxLabel"> + </cr-toggle> + </div> + + <div class="list-item" hidden="[[!syncPrefs.typedUrlsRegistered]]"> + <div id="historyCheckboxLabel"> + $i18n{historyCheckboxLabel} + </div> + <!-- TypedUrls has a special on-change handler to deal with user + events. --> + <cr-toggle id="historyToggle" + checked="{{syncPrefs.typedUrlsSynced}}" + on-change="onTypedUrlsDataTypeChanged_" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.typedUrlsEnforced)]]" + aria-labelledby="historyCheckboxLabel"> + </cr-toggle> + </div> + + <div class="list-item" hidden="[[!syncPrefs.preferencesRegistered]]"> + <div id="settingsCheckboxLabel"> + $i18n{settingsCheckboxLabel} + </div> + <cr-toggle checked="{{syncPrefs.preferencesSynced}}" + on-change="onSingleSyncDataTypeChanged_" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, + syncPrefs.preferencesEnforced)]]" + aria-labelledby="settingsCheckboxLabel"> + </cr-toggle> + </div> + + <div class="list-item" hidden="[[!syncPrefs.themesRegistered]]"> + <div id="themesAndWallpapersCheckboxLabel"> + $i18n{themesAndWallpapersCheckboxLabel} + </div> + <cr-toggle checked="{{syncPrefs.themesSynced}}" + on-change="onSingleSyncDataTypeChanged_" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.themesEnforced)]]" + aria-labelledby="themesAndWallpapersCheckboxLabel"> + </cr-toggle> + </div> + + <div class="list-item" hidden="[[!syncPrefs.tabsRegistered]]"> + <div id="openTabsCheckboxLabel"> + $i18n{openTabsCheckboxLabel} + </div> + <cr-toggle checked="{{syncPrefs.tabsSynced}}" + on-change="onSingleSyncDataTypeChanged_" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.tabsEnforced)]]" + aria-labelledby="openTabsCheckboxLabel"> + </cr-toggle> + </div> + + <div class="list-item" hidden="[[!syncPrefs.passwordsRegistered]]"> + <div id="passwordsCheckboxLabel"> + $i18n{passwordsCheckboxLabel} + </div> + <cr-toggle checked="{{syncPrefs.passwordsSynced}}" + on-change="onSingleSyncDataTypeChanged_" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.passwordsEnforced)]]" + aria-labelledby="passwordsCheckboxLabel"> + </cr-toggle> + </div> + + <div class="list-item" hidden="[[!syncPrefs.autofillRegistered]]"> + <div id="autofillCheckboxLabel"> + $i18n{autofillCheckboxLabel} + </div> + <!-- Autofill has a special on-change handler to deal with + Payments integration. --> + <cr-toggle checked="{{syncPrefs.autofillSynced}}" + on-change="onAutofillDataTypeChanged_" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.autofillEnforced)]]" + aria-labelledby="autofillCheckboxLabel"> + </cr-toggle> + </div> + + <div class="list-item" hidden="[[!syncPrefs.autofillRegistered]]"> + <!-- The Payments integration checkbox is a special case in many + ways. It's visible only if autofill is registered. It's + disabled and unchecked if autofill is unchecked.--> + <div> + $i18n{enablePaymentsIntegrationCheckboxLabel} + <a href="$i18nRaw{autofillHelpURL}" target="_blank"> + $i18n{learnMore} + </a> + </div> + <cr-toggle checked="{{syncPrefs.paymentsIntegrationEnabled}}" + on-change="onSingleSyncDataTypeChanged_" + disabled="[[shouldPaymentsCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.autofillSynced)]]" + aria-label="$i18n{enablePaymentsIntegrationCheckboxLabel}"> + </cr-toggle> + </div> + </div> + +<if expr="not chromeos"> + <cr-toast id="toast" + open="[[shouldShowSyncSetupToast_(syncStatus.setupInProgress)]]"> + <div>$i18n{syncWillStart}</div> + <paper-button on-click="onCancelSyncClick_"> + $i18n{cancelSync} + </paper-button> + </cr-toast> +</if> + </template> + <script src="sync_controls.js"></script> +</dom-module> diff --git a/chromium/chrome/browser/resources/settings/people_page/sync_controls.js b/chromium/chrome/browser/resources/settings/people_page/sync_controls.js new file mode 100644 index 00000000000..d910e9fbf58 --- /dev/null +++ b/chromium/chrome/browser/resources/settings/people_page/sync_controls.js @@ -0,0 +1,192 @@ +// Copyright 2018 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. + +(function() { + +/** + * Names of the individual data type properties to be cached from + * settings.SyncPrefs when the user checks 'Sync All'. + * @type {!Array<string>} + */ +const SyncPrefsIndividualDataTypes = [ + 'appsSynced', + 'extensionsSynced', + 'preferencesSynced', + 'autofillSynced', + 'typedUrlsSynced', + 'themesSynced', + 'bookmarksSynced', + 'passwordsSynced', + 'tabsSynced', + 'paymentsIntegrationEnabled', +]; + +/** + * @fileoverview + * 'settings-sync-controls' contains all sync data type controls. + */ +Polymer({ + is: 'settings-sync-controls', + + behaviors: [WebUIListenerBehavior], + + properties: { + /** + * The current sync preferences, supplied by SyncBrowserProxy. + * @type {settings.SyncPrefs|undefined} + */ + syncPrefs: Object, + + /** + * The current sync status, supplied by the parent. + * @type {settings.SyncStatus} + */ + syncStatus: { + type: Object, + observer: 'syncStatusChanged_', + }, + }, + + /** @private {?settings.SyncBrowserProxy} */ + browserProxy_: null, + + /** + * Caches the individually selected synced data types. This is used to + * be able to restore the selections after checking and unchecking Sync All. + * @private {?Object} + */ + cachedSyncPrefs_: null, + + /** @override */ + created: function() { + this.browserProxy_ = settings.SyncBrowserProxyImpl.getInstance(); + }, + + /** @override */ + attached: function() { + this.addWebUIListener( + 'sync-prefs-changed', this.handleSyncPrefsChanged_.bind(this)); + + if (settings.getCurrentRoute() == settings.routes.SYNC_ADVANCED) + this.browserProxy_.didNavigateToSyncPage(); + }, + + /** + * Handler for when the sync preferences are updated. + * @private + */ + handleSyncPrefsChanged_: function(syncPrefs) { + this.syncPrefs = syncPrefs; + + // If autofill is not registered or synced, force Payments integration off. + if (!this.syncPrefs.autofillRegistered || !this.syncPrefs.autofillSynced) + this.set('syncPrefs.paymentsIntegrationEnabled', false); + }, + + /** + * Handler for when the sync all data types checkbox is changed. + * @param {!Event} event + * @private + */ + onSyncAllDataTypesChanged_: function(event) { + if (event.target.checked) { + this.set('syncPrefs.syncAllDataTypes', true); + + // Cache the previously selected preference before checking every box. + this.cachedSyncPrefs_ = {}; + for (const dataType of SyncPrefsIndividualDataTypes) { + // These are all booleans, so this shallow copy is sufficient. + this.cachedSyncPrefs_[dataType] = this.syncPrefs[dataType]; + + this.set(['syncPrefs', dataType], true); + } + } else if (this.cachedSyncPrefs_) { + // Restore the previously selected preference. + for (const dataType of SyncPrefsIndividualDataTypes) { + this.set(['syncPrefs', dataType], this.cachedSyncPrefs_[dataType]); + } + } + + this.onSingleSyncDataTypeChanged_(); + }, + + /** + * Handler for when any sync data type checkbox is changed (except autofill). + * @private + */ + onSingleSyncDataTypeChanged_: function() { + assert(this.syncPrefs); + this.browserProxy_.setSyncDatatypes(this.syncPrefs); + }, + + /** + * Handler for when the autofill data type checkbox is changed. + * @private + */ + onAutofillDataTypeChanged_: function() { + this.set( + 'syncPrefs.paymentsIntegrationEnabled', this.syncPrefs.autofillSynced); + + this.onSingleSyncDataTypeChanged_(); + }, + + /** + * Handler for when the autofill data type checkbox is changed. + * @private + */ + onTypedUrlsDataTypeChanged_: function() { + this.onSingleSyncDataTypeChanged_(); + }, + + /** + * @param {boolean} syncAllDataTypes + * @param {boolean} enforced + * @return {boolean} Whether the sync checkbox should be disabled. + */ + shouldSyncCheckboxBeDisabled_: function(syncAllDataTypes, enforced) { + return syncAllDataTypes || enforced; + }, + + /** + * @param {boolean} syncAllDataTypes + * @param {boolean} autofillSynced + * @return {boolean} Whether the sync checkbox should be disabled. + */ + shouldPaymentsCheckboxBeDisabled_: function( + syncAllDataTypes, autofillSynced) { + return syncAllDataTypes || !autofillSynced; + }, + + /** + * @private + * @return {boolean} + */ + shouldShowSyncSetupToast_: function() { + return settings.getCurrentRoute() == settings.routes.SYNC_ADVANCED && + this.syncStatus.setupInProgress; + }, + + /** @private */ + onCancelSyncClick_: function() { + this.fire('sync-setup-cancel'); + }, + + /** @private */ + syncStatusChanged_: function(syncStatus) { + // When the sync controls are embedded, the parent has to take care of + // showing/hiding them. + if (settings.getCurrentRoute() != settings.routes.SYNC_ADVANCED || + !syncStatus) + return; + + // Navigate to main sync page when the sync controls page should *not* be + // available. + if (!syncStatus.signedIn || !!syncStatus.disabled || + (!!syncStatus.hasError && + syncStatus.statusAction !== settings.StatusAction.ENTER_PASSPHRASE)) { + settings.navigateTo(settings.routes.SYNC); + } + }, +}); +})(); diff --git a/chromium/chrome/browser/resources/settings/people_page/sync_page.html b/chromium/chrome/browser/resources/settings/people_page/sync_page.html index 07ea937a40b..118a87f1fb8 100644 --- a/chromium/chrome/browser/resources/settings/people_page/sync_page.html +++ b/chromium/chrome/browser/resources/settings/people_page/sync_page.html @@ -3,17 +3,15 @@ <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/html/util.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_expand_button/cr_expand_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html"> <link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_radio_group/cr_radio_group.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-group/paper-radio-group.html"> <link rel="import" href="sync_browser_proxy.html"> +<link rel="import" href="sync_controls.html"> <link rel="import" href="../icons.html"> <link rel="import" href="../privacy_page/personalization_options.html"> <link rel="import" href="../route.html"> @@ -27,8 +25,12 @@ <dom-module id="settings-sync-page"> <template> <style include="settings-shared iron-flex"> - #sync-section-toggle:not([actionable]) { - opacity: var(--cr-disabled-opacity); + h2 { + font-size: var(--cr-title-text_-_font-size); + } + + #sync-separator { + border-bottom: var(--settings-separator-line); } #create-password-box { @@ -63,11 +65,11 @@ align-items: center; } - #sync-data-types .list-item:not([hidden]) ~ .list-item:not([hidden]) { - border-top: var(--settings-separator-line); + #other-sync-items { + padding-bottom: 8px; } - #other-sync-items > .list-item { + #other-sync-items > .list-item:not(.first) { border-top: var(--settings-separator-line); } @@ -75,6 +77,11 @@ margin-right: 8px; } + #disabled-by-admin-icon { + text-align: center; + width: 40px; + } + <if expr="not chromeos"> #toast { color: white; @@ -104,6 +111,11 @@ </template> </if> + <div class="settings-box first" hidden="[[!syncStatus.managed]]"> + <iron-icon id="disabled-by-admin-icon" icon="cr20:domain"></iron-icon> + <div class="middle">$i18n{syncDisabledByAdministrator}</div> + </div> + <template is="dom-if" if="[[shouldShowExistingPassphraseBelowAccount_( unifiedConsentEnabled, syncPrefs.passphraseRequired)]]"> <div id="existingPassphrase" class="list-frame"> @@ -137,32 +149,13 @@ </div> </template> - <!-- A change of the unified consent toggle state is automatically handled - in the C++ code after a change in the pref is observed. --> - <settings-toggle-button id="unifiedConsentToggle" class="first" - pref="{{prefs.unified_consent_given}}" - label="$i18n{syncUnifiedConsentToggleTitle}" - on-settings-boolean-control-change="onUnifiedConsentToggleChange_" - hidden="[[!shouldShowUnifiedConsentToggle_(unifiedConsentEnabled, - syncStatus.disabled, syncStatus.signedIn)]]" - disabled="[[syncPrefs.encryptAllData]]"> - </settings-toggle-button> - <div class="settings-box two-line" id="sync-section-toggle" - actionable$="[[!syncSectionDisabled_]]" - on-click="toggleExpandButton_" - hidden="[[!shouldShowSyncControls_(unifiedConsentEnabled, - syncStatus.disabled)]]"> - <div class="start"> - <div>$i18n{sync}</div> - <div class="secondary">$i18n{syncDescription}</div> + <div id="sync-separator" hidden="[[!syncSectionDisabled_]]"></div> + + <div id="sync-section" hidden="[[syncSectionDisabled_]]"> + <div class="settings-box first" hidden="[[!unifiedConsentEnabled]]"> + <h2 class="start">$i18n{sync}</h2> </div> - <cr-expand-button expanded="{{syncSectionOpened_}}" - disabled$="[[syncSectionDisabled_]]" alt="$i18n{syncExpandA11yLabel}"> - </cr-expand-button> - </div> - <iron-collapse id="sync-section" opened="[[syncSectionOpened_]]" - hidden="[[syncSectionDisabled_]]"> <div id="[[pages_.SPINNER]]" class="settings-box first" hidden$="[[!isStatus_(pages_.SPINNER, pageStatus_)]]"> $i18n{syncLoading} @@ -174,7 +167,7 @@ <div id="[[pages_.CONFIGURE]]" hidden$="[[!isStatus_(pages_.CONFIGURE, pageStatus_)]]"> <!-- TODO(http://crbug.com/862983) Remove this section once the Unified - Consent feature is launched. --> + Consent feature is launched. --> <template is="dom-if" if="[[shouldShowExistingPassphraseInSyncSection_( unifiedConsentEnabled, syncPrefs.passphraseRequired)]]"> <div id="existingPassphrase" class="list-frame"> @@ -205,194 +198,26 @@ </div> </template> - <div class="settings-box first" hidden="[[unifiedConsentEnabled]]"> - <div id="syncEverythingCheckboxLabel" class="start"> - $i18n{syncEverythingCheckboxLabel} - </div> - <cr-toggle id="syncAllDataTypesControl" - checked="{{syncPrefs.syncAllDataTypes}}" - on-change="onSyncAllDataTypesChanged_" - aria-labelledby="syncEverythingCheckboxLabel"> - </cr-toggle> - </div> - - <div class="list-frame" id="sync-data-types"> - <div class="layout horizontal list-item" - hidden="[[!syncPrefs.appsRegistered]]"> - <div id="appCheckboxLabel" class="flex"> - $i18n{appCheckboxLabel} - </div> - <cr-toggle checked="{{syncPrefs.appsSynced}}" - on-change="onSingleSyncDataTypeChanged_" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.appsEnforced)]]" - aria-labelledby="appCheckboxLabel"> - </cr-toggle> - </div> - - <div class="layout horizontal list-item" - hidden="[[!syncPrefs.autofillRegistered]]"> - <div id="autofillCheckboxLabel" class="flex"> - $i18n{autofillCheckboxLabel} - </div> - <!-- Autofill has a special on-change handler to deal with - Payments integration. --> - <cr-toggle checked="{{syncPrefs.autofillSynced}}" - on-change="onAutofillDataTypeChanged_" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.autofillEnforced)]]" - aria-labelledby="autofillCheckboxLabel"> - </cr-toggle> - </div> - - <div class="layout horizontal list-item" - hidden="[[!syncPrefs.bookmarksRegistered]]"> - <div id="bookmarksCheckboxLabel" class="flex"> - $i18n{bookmarksCheckboxLabel} - </div> - <cr-toggle checked="{{syncPrefs.bookmarksSynced}}" - on-change="onSingleSyncDataTypeChanged_" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.bookmarksEnforced)]]" - aria-labelledby="bookmarksCheckboxLabel"> - </cr-toggle> - </div> - - <div class="layout horizontal list-item" - hidden="[[!syncPrefs.extensionsRegistered]]"> - <div id="extensionsCheckboxLabel" class="flex"> - $i18n{extensionsCheckboxLabel} - </div> - <cr-toggle checked="{{syncPrefs.extensionsSynced}}" - on-change="onSingleSyncDataTypeChanged_" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.extensionsEnforced)]]" - aria-labelledby="extensionsCheckboxLabel"> - </cr-toggle> - </div> - - <div class="layout horizontal list-item" - hidden="[[!syncPrefs.typedUrlsRegistered]]"> - <div id="historyCheckboxLabel" class="flex"> - $i18n{historyCheckboxLabel} - </div> - <!-- TypedUrls has a special on-change handler to deal with user - events. --> - <cr-toggle id="historyToggle" - checked="{{syncPrefs.typedUrlsSynced}}" - on-change="onTypedUrlsDataTypeChanged_" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.typedUrlsEnforced)]]" - aria-labelledby="historyCheckboxLabel"> - </cr-toggle> - </div> - - <div class="layout horizontal list-item" - hidden="[[!syncPrefs.passwordsRegistered]]"> - <div id="passwordsCheckboxLabel" class="flex"> - $i18n{passwordsCheckboxLabel} - </div> - <cr-toggle checked="{{syncPrefs.passwordsSynced}}" - on-change="onSingleSyncDataTypeChanged_" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.passwordsEnforced)]]" - aria-labelledby="passwordsCheckboxLabel"> - </cr-toggle> - </div> - - <div class="layout horizontal list-item" - hidden="[[!syncPrefs.preferencesRegistered]]"> - <div id="settingsCheckboxLabel" class="flex"> - $i18n{settingsCheckboxLabel} - </div> - <cr-toggle checked="{{syncPrefs.preferencesSynced}}" - on-change="onSingleSyncDataTypeChanged_" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, - syncPrefs.preferencesEnforced)]]" - aria-labelledby="settingsCheckboxLabel"> - </cr-toggle> - </div> - - <div class="layout horizontal list-item" - hidden="[[!syncPrefs.themesRegistered]]"> - <div id="themesAndWallpapersCheckboxLabel" class="flex"> - $i18n{themesAndWallpapersCheckboxLabel} - </div> - <cr-toggle checked="{{syncPrefs.themesSynced}}" - on-change="onSingleSyncDataTypeChanged_" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.themesEnforced)]]" - aria-labelledby="themesAndWallpapersCheckboxLabel"> - </cr-toggle> - </div> - - <div class="layout horizontal list-item" - hidden="[[!syncPrefs.tabsRegistered]]"> - <div id="openTabsCheckboxLabel" class="flex"> - $i18n{openTabsCheckboxLabel} - </div> - <cr-toggle checked="{{syncPrefs.tabsSynced}}" - on-change="onSingleSyncDataTypeChanged_" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.tabsEnforced)]]" - aria-labelledby="openTabsCheckboxLabel"> - </cr-toggle> - </div> + <template is="dom-if" if="[[!unifiedConsentEnabled]]"> + <settings-sync-controls sync-status="syncStatus"> + </settings-sync-controls> + </template> - <div class="layout horizontal list-item" - hidden="[[!syncPrefs.autofillRegistered]]"> - <!-- The Payments integration checkbox is a special case in many - ways. It's visible only if autofill is registered. It's - disabled and unchecked if autofill is unchecked.--> - <div class="flex"> - $i18n{enablePaymentsIntegrationCheckboxLabel} - <a href="$i18nRaw{autofillHelpURL}" target="_blank"> - $i18n{learnMore} - </a> - </div> - <cr-toggle - checked="{{syncPrefs.paymentsIntegrationEnabled}}" - on-change="onSingleSyncDataTypeChanged_" - disabled="[[shouldPaymentsCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.autofillSynced)]]" - aria-label="$i18n{enablePaymentsIntegrationCheckboxLabel}"> - </cr-toggle> - </div> + <div id="other-sync-items" + class$="[[getListFrameClass_(unifiedConsentEnabled)]]"> - <!-- User events is disabled and unchecked if data is encrypted or - typed urls are disabled. --> <template is="dom-if" if="[[unifiedConsentEnabled]]"> - <div hidden="[[!syncPrefs.userEventsRegistered]]" - class$="[[getPassphraseHintLines_(syncPrefs.encryptAllData)]] - layout horizontal list-item"> - <div class="start" id="userEventsCheckboxLabel"> - $i18n{userEventsCheckboxLabel} - <div class="secondary"> - $i18n{userEventsCheckboxText} - <div id="reset-sync-message-box-user-events" - hidden="[[!syncPrefs.encryptAllData]]"> - <iron-icon icon="settings:info-outline" - class="passphrase-reset-icon"> - </iron-icon> - $i18nRaw{passphraseResetHintToggle} - </div> - </div> + <div id="sync-advanced-row" class="list-item first" + on-click="onSyncAdvancedTap_" actionable> + <div class="start"> + $i18n{syncAdvancedPageTitle} </div> - <cr-toggle id="userEventsToggle" - checked="{{userEventsToggleValue}}" - on-change="onUserEventsSyncDataTypeChanged_" - disabled="[[shouldUserEventsCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.typedUrlsSynced, - syncPrefs.userEventsEnforced, syncPrefs.encryptAllData)]]" - aria-labelledby="userEventsCheckboxLabel"> - </cr-toggle> + <paper-icon-button-light class="subpage-arrow"> + <button aria-label="$i18n{syncAdvancedPageTitle}"></button> + </paper-icon-button-light> </div> </template> - </div> - <div id="other-sync-items" - class$="[[getListFrameClass_(unifiedConsentEnabled)]]"> <template is="dom-if" if="[[driveSuggestAvailable_]]"> <settings-toggle-button class$="[[getListItemClass_(unifiedConsentEnabled)]]" @@ -444,19 +269,15 @@ <div id="encryptionRadioGroupContainer" class="list-frame" hidden="[[syncPrefs.passphraseRequired]]"> - <paper-radio-group disabled$="[[syncPrefs.encryptAllData]]" + <cr-radio-group disabled$="[[syncPrefs.encryptAllData]]" selected="[[selectedEncryptionRadio_( syncPrefs.passphraseTypeIsCustom)]]" - selectable="cr-radio-button" - on-paper-radio-group-changed= - "onEncryptionRadioSelectionChanged_"> - <cr-radio-button name="encrypt-with-google" - class="list-item" disabled="[[syncPrefs.encryptAllData]]" + on-selected-changed="onEncryptionRadioSelectionChanged_"> + <cr-radio-button name="encrypt-with-google" class="list-item" aria-label="$i18n{encryptWithGoogleCredentialsLabel}"> $i18n{encryptWithGoogleCredentialsLabel} </cr-radio-button> - <cr-radio-button name="encrypt-with-passphrase" - class="list-item" disabled="[[syncPrefs.encryptAllData]]"> + <cr-radio-button name="encrypt-with-passphrase" class="list-item"> <span hidden="[[!syncPrefs.fullEncryptionBody]]"> [[syncPrefs.fullEncryptionBody]] </span> @@ -465,7 +286,7 @@ $i18nRaw{encryptWithSyncPassphraseLabel} </span> </cr-radio-button> - </paper-radio-group> + </cr-radio-group> </div> <template is="dom-if" if="[[creatingNewPassphrase_]]"> @@ -497,34 +318,22 @@ </div> </div> - </iron-collapse> + </div> + <template is="dom-if" if="[[unifiedConsentEnabled]]"> - <div class="settings-box two-line" id="personalize-section-toggle" - actionable on-click="toggleExpandButton_"> - <div class="start"> - <div>$i18n{nonPersonalizedServicesSectionLabel}</div> - <div class="secondary"> - $i18n{nonPersonalizedServicesSectionDesc} - </div> - </div> - <cr-expand-button expanded="{{personalizeSectionOpened_}}" - alt="$i18n{nonPersonalizedServicesExpandA11yLabel}"> - </cr-expand-button> + <div class="settings-box first"> + <h2>$i18n{nonPersonalizedServicesSectionLabel}</h2> </div> - <iron-collapse id="personalize-section" - opened="[[personalizeSectionOpened_]]"> - <settings-personalization-options class="list-frame" prefs="{{prefs}}" - page-visibility="[[pageVisibility]]" - unified-consent-enabled="[[unifiedConsentEnabled]]" - unified-consent-given="{{prefs.unified_consent_given.value}}"> - </settings-personalization-options> - </iron-collapse> + <settings-personalization-options class="list-frame" prefs="{{prefs}}" + page-visibility="[[pageVisibility]]" + unified-consent-enabled="[[unifiedConsentEnabled]]"> + </settings-personalization-options> </template> <if expr="not chromeos"> <cr-toast id="toast" open="[[syncStatus.setupInProgress]]"> <div>$i18n{syncWillStart}</div> - <paper-button on-click="onCancelSyncClick_"> + <paper-button on-click="cancelSyncSetup"> $i18n{cancelSync} </paper-button> </cr-toast> diff --git a/chromium/chrome/browser/resources/settings/people_page/sync_page.js b/chromium/chrome/browser/resources/settings/people_page/sync_page.js index 7acfee58646..bfd3ec9105c 100644 --- a/chromium/chrome/browser/resources/settings/people_page/sync_page.js +++ b/chromium/chrome/browser/resources/settings/people_page/sync_page.js @@ -15,24 +15,6 @@ const RadioButtonNames = { }; /** - * Names of the individual data type properties to be cached from - * settings.SyncPrefs when the user checks 'Sync All'. - * @type {!Array<string>} - */ -const SyncPrefsIndividualDataTypes = [ - 'appsSynced', - 'extensionsSynced', - 'preferencesSynced', - 'autofillSynced', - 'typedUrlsSynced', - 'themesSynced', - 'bookmarksSynced', - 'passwordsSynced', - 'tabsSynced', - 'paymentsIntegrationEnabled', -]; - -/** * @fileoverview * 'settings-sync-page' is the settings page containing sync settings. */ @@ -88,7 +70,6 @@ Polymer({ /** @type {settings.SyncStatus} */ syncStatus: { type: Object, - observer: 'onSyncStatusChanged_', }, /** @@ -146,18 +127,6 @@ Polymer({ }, /** @private */ - personalizeSectionOpened_: { - type: Boolean, - value: true, - }, - - /** @private */ - syncSectionOpened_: { - type: Boolean, - value: true, - }, - - /** @private */ driveSuggestAvailable_: { type: Boolean, value: function() { @@ -165,11 +134,6 @@ Polymer({ } }, - // The toggle for user events is not reflected directly on - // syncPrefs.userEventsSynced, because this sync preference must only be - // updated if there is no passphrase and typedUrls are synced as well. - userEventsToggleValue: Boolean, - // <if expr="not chromeos"> diceEnabled: Boolean, // </if> @@ -177,12 +141,6 @@ Polymer({ unifiedConsentEnabled: Boolean, }, - observers: [ - // Depends on signedIn_ so that the sync section is updated on signin - // changes, even though the actual value of signedIn_ is not used. - 'onSyncSectionOpenedShouldChange_(signedIn_, syncSectionDisabled_)', - ], - /** @private {?settings.SyncBrowserProxy} */ browserProxy_: null, @@ -211,13 +169,6 @@ Polymer({ */ didAbort_: false, - /** - * Caches the individually selected synced data types. This is used to - * be able to restore the selections after checking and unchecking Sync All. - * @private {?Object} - */ - cachedSyncPrefs_: null, - /** @override */ created: function() { this.browserProxy_ = settings.SyncBrowserProxyImpl.getInstance(); @@ -233,10 +184,18 @@ Polymer({ if (settings.getCurrentRoute() == settings.routes.SYNC) this.onNavigateToPage_(); }, + /** + * Can be called from subpages to notify this page (=main sync page) that sync + * setup was cancelled. + */ + cancelSyncSetup: function() { + this.didAbort_ = true; + settings.navigateTo(settings.routes.BASIC); + }, /** @override */ detached: function() { - if (settings.getCurrentRoute() == settings.routes.SYNC) + if (settings.routes.SYNC.contains(settings.getCurrentRoute())) this.onNavigateAwayFromPage_(); if (this.beforeunloadCallback_) { @@ -269,7 +228,7 @@ Polymer({ currentRouteChanged: function() { if (settings.getCurrentRoute() == settings.routes.SYNC) this.onNavigateToPage_(); - else + else if (!settings.routes.SYNC.contains(settings.getCurrentRoute())) this.onNavigateAwayFromPage_(); }, @@ -317,20 +276,6 @@ Polymer({ }, /** - * Handles the change event for the unfied consent toggle. - * @private - */ - onUnifiedConsentToggleChange_: function() { - const checked = this.$$('#unifiedConsentToggle').checked; - this.browserProxy_.unifiedConsentToggleChanged(checked); - - if (!checked) { - this.syncSectionOpened_ = !this.syncSectionDisabled_; - this.personalizeSectionOpened_ = true; - } - }, - - /** * Handler for when the sync preferences are updated. * @private */ @@ -338,15 +283,6 @@ Polymer({ this.syncPrefs = syncPrefs; this.pageStatus_ = settings.PageStatus.CONFIGURE; - // If autofill is not registered or synced, force Payments integration off. - if (!this.syncPrefs.autofillRegistered || !this.syncPrefs.autofillSynced) - this.set('syncPrefs.paymentsIntegrationEnabled', false); - - this.set( - 'userEventsToggleValue', - this.syncPrefs.userEventsSynced && this.syncPrefs.typedUrlsSynced && - !this.syncPrefs.encryptAllData); - // Hide the new passphrase box if the sync data has been encrypted. if (this.syncPrefs.encryptAllData) this.creatingNewPassphrase_ = false; @@ -363,87 +299,12 @@ Polymer({ } }, - /** - * Handler for when the sync all data types checkbox is changed. - * @param {!Event} event - * @private - */ - onSyncAllDataTypesChanged_: function(event) { - if (event.target.checked) { - this.set('syncPrefs.syncAllDataTypes', true); - - // Cache the previously selected preference before checking every box. - this.cachedSyncPrefs_ = {}; - for (const dataType of SyncPrefsIndividualDataTypes) { - // These are all booleans, so this shallow copy is sufficient. - this.cachedSyncPrefs_[dataType] = this.syncPrefs[dataType]; - - this.set(['syncPrefs', dataType], true); - } - } else if (this.cachedSyncPrefs_) { - // Restore the previously selected preference. - for (const dataType of SyncPrefsIndividualDataTypes) { - this.set(['syncPrefs', dataType], this.cachedSyncPrefs_[dataType]); - } - } - - this.onSingleSyncDataTypeChanged_(); - }, - - /** - * Handler for when any sync data type checkbox is changed (except autofill). - * @private - */ - onSingleSyncDataTypeChanged_: function() { - assert(this.syncPrefs); - this.browserProxy_.setSyncDatatypes(this.syncPrefs) - .then(this.handlePageStatusChanged_.bind(this)); - }, - /** @private */ onActivityControlsTap_: function() { this.browserProxy_.openActivityControlsUrl(); }, /** - * Handler for when the autofill data type checkbox is changed. - * @private - */ - onAutofillDataTypeChanged_: function() { - this.set( - 'syncPrefs.paymentsIntegrationEnabled', this.syncPrefs.autofillSynced); - - this.onSingleSyncDataTypeChanged_(); - }, - - /** - * Handler for when the autofill data type checkbox is changed. - * @private - */ - onTypedUrlsDataTypeChanged_: function() { - // Enabling typed URLs also resets the user events to ON. |encryptAllData| - // is not expected to change on the fly, and if it changed the user sync - // settings would be reset anyway. - if (!this.syncPrefs.encryptAllData && this.syncPrefs.typedUrlsSynced) - this.set('syncPrefs.userEventsSynced', true); - - this.onSingleSyncDataTypeChanged_(); - }, - - /** - * Handler for when the user events data type checkbox is changed. - * @private - */ - onUserEventsSyncDataTypeChanged_: function() { - // Only update the sync preference when there is no passphrase and typed - // URLs are synced. - assert(!this.syncPrefs.encryptAllData && this.syncPrefs.typedUrlsSynced); - this.set('syncPrefs.userEventsSynced', this.userEventsToggleValue); - - this.onSingleSyncDataTypeChanged_(); - }, - - /** * @param {string} passphrase The passphrase input field value * @param {string} confirmation The passphrase confirmation input field value. * @return {boolean} Whether the passphrase save button should be enabled. @@ -529,11 +390,12 @@ Polymer({ /** * Called when the encryption + * @param {!Event} event * @private */ onEncryptionRadioSelectionChanged_: function(event) { this.creatingNewPassphrase_ = - event.target.selected == RadioButtonNames.ENCRYPT_WITH_PASSPHRASE; + event.detail.value == RadioButtonNames.ENCRYPT_WITH_PASSPHRASE; }, /** @@ -558,38 +420,6 @@ Polymer({ }, /** - * @param {boolean} syncAllDataTypes - * @param {boolean} enforced - * @return {boolean} Whether the sync checkbox should be disabled. - */ - shouldSyncCheckboxBeDisabled_: function(syncAllDataTypes, enforced) { - return syncAllDataTypes || enforced; - }, - - /** - * @param {boolean} syncAllDataTypes - * @param {boolean} autofillSynced - * @return {boolean} Whether the sync checkbox should be disabled. - */ - shouldPaymentsCheckboxBeDisabled_: function( - syncAllDataTypes, autofillSynced) { - return syncAllDataTypes || !autofillSynced; - }, - - /** - * @param {boolean} syncAllDataTypes - * @param {boolean} typedUrlsSynced - * @param {boolean} userEventsEnforced - * @param {boolean} encryptAllData - * @return {boolean} Whether the sync checkbox should be disabled. - */ - shouldUserEventsCheckboxBeDisabled_: function( - syncAllDataTypes, typedUrlsSynced, userEventsEnforced, encryptAllData) { - return syncAllDataTypes || !typedUrlsSynced || userEventsEnforced || - encryptAllData; - }, - - /** * Checks the supplied passphrases to ensure that they are not empty and that * they match each other. Additionally, displays error UI if they are invalid. * @return {boolean} Whether the check was successful (i.e., that the @@ -619,55 +449,6 @@ Polymer({ } }, - /** @private */ - onCancelSyncClick_: function() { - this.didAbort_ = true; - settings.navigateTo(settings.routes.BASIC); - }, - - // Computes the initial layout for the sync section and the personalize - // section. This function only does something on its first call. - onSyncStatusChanged_: function() { - if (!!this.syncStatus && !this.collapsibleSectionsInitialized_) { - this.collapsibleSectionsInitialized_ = true; - this.personalizeSectionOpened_ = - !this.$$('#unifiedConsentToggle').checked || - !!this.syncStatus.setupInProgress; - this.syncSectionOpened_ = - this.personalizeSectionOpened_ && !this.syncSectionDisabled_; - } - }, - - /** - * Collapses the sync section if it becomes disabled, and expands it when it's - * re-enabled. - * @private - */ - onSyncSectionOpenedShouldChange_: function() { - this.syncSectionOpened_ = - !this.syncSectionDisabled_ && !this.$$('#unifiedConsentToggle').checked; - }, - - /** - * Toggles the expand button within the element being listened to. - * @param {!Event} e - * @private - */ - toggleExpandButton_: function(e) { - // The expand button handles toggling itself. - const expandButtonTag = 'CR-EXPAND-BUTTON'; - if (e.target.tagName == expandButtonTag) - return; - - if (!e.currentTarget.hasAttribute('actionable')) - return; - - /** @type {!CrExpandButtonElement} */ - const expandButton = e.currentTarget.querySelector(expandButtonTag); - assert(expandButton); - expandButton.expanded = !expandButton.expanded; - }, - /** * When unified-consent enabled, the non-toggle items on the bottom of sync * section should be wrapped with 'list-frame' in order to be indented @@ -729,22 +510,9 @@ Polymer({ !!this.syncPrefs.passphraseRequired; }, - /** - * @return {boolean} - * @private - */ - shouldShowSyncControls_: function() { - return !!this.unifiedConsentEnabled && this.syncStatus !== undefined && - !this.syncStatus.disabled; - }, - - /** - * @return {boolean} - * @private - */ - shouldShowUnifiedConsentToggle_: function() { - return !!this.unifiedConsentEnabled && this.syncStatus !== undefined && - !this.syncStatus.disabled && !!this.syncStatus.signedIn; + /** @private */ + onSyncAdvancedTap_: function() { + settings.navigateTo(settings.routes.SYNC_ADVANCED); }, }); diff --git a/chromium/chrome/browser/resources/settings/privacy_page/personalization_options.html b/chromium/chrome/browser/resources/settings/privacy_page/personalization_options.html index 843f10eeb1d..eba047b480b 100644 --- a/chromium/chrome/browser/resources/settings/privacy_page/personalization_options.html +++ b/chromium/chrome/browser/resources/settings/privacy_page/personalization_options.html @@ -25,48 +25,39 @@ <settings-toggle-button hidden="[[!pageVisibility.searchPrediction]]" pref="{{prefs.search.suggest_enabled}}" label="$i18n{searchSuggestPref}" - sub-label="$i18n{searchSuggestPrefDesc}" - disabled="[[unifiedConsentGiven]]"> + sub-label="$i18n{searchSuggestPrefDesc}"> </settings-toggle-button> <settings-toggle-button hidden="[[!pageVisibility.networkPrediction]]" pref="{{prefs.net.network_prediction_options}}" label="$i18n{networkPredictionEnabled}" sub-label="$i18n{networkPredictionEnabledDesc}" - numeric-unchecked-value="[[networkPredictionEnum_.NEVER]]" - disabled="[[unifiedConsentGiven]]"> + numeric-unchecked-value="[[networkPredictionEnum_.NEVER]]"> </settings-toggle-button> <settings-toggle-button pref="{{prefs.alternate_error_pages.enabled}}" label="$i18n{linkDoctorPref}" - sub-label="$i18n{linkDoctorPrefDesc}" - disabled="[[unifiedConsentGiven]]"> + sub-label="$i18n{linkDoctorPrefDesc}"> </settings-toggle-button> <settings-toggle-button pref="{{prefs.safebrowsing.enabled}}" label="$i18n{safeBrowsingEnableProtection}" - sub-label="$i18n{safeBrowsingEnableProtectionDesc}" - disabled="[[unifiedConsentGiven]]"> + sub-label="$i18n{safeBrowsingEnableProtectionDesc}"> </settings-toggle-button> - <settings-toggle-button id="safeBrowsingExtendedReportingControl" - pref="[[safeBrowsingExtendedReportingPref_]]" + <settings-toggle-button + pref="{{prefs.safebrowsing.scout_reporting_enabled}}" label="$i18n{safeBrowsingEnableExtendedReporting}" - sub-label="$i18n{safeBrowsingEnableExtendedReportingDesc}" - on-settings-boolean-control-change="onSberChange_" - no-set-pref - disabled="[[unifiedConsentGiven]]"> + sub-label="$i18n{safeBrowsingEnableExtendedReportingDesc}"> </settings-toggle-button> <if expr="_google_chrome"> <if expr="chromeos"> <settings-toggle-button pref="{{prefs.cros.metrics.reportingEnabled}}" label="$i18n{enableLogging}" - sub-label="$i18n{enableLoggingDesc}" - disabled="[[unifiedConsentGiven]]"> + sub-label="$i18n{enableLoggingDesc}"> </settings-toggle-button> </if><!-- chromeos --> <if expr="not chromeos"> <settings-toggle-button id="metricsReportingControl" pref="[[metricsReportingPref_]]" label="$i18n{enableLogging}" sub-label="$i18n{enableLoggingDesc}" no-set-pref - on-settings-boolean-control-change="onMetricsReportingChange_" - disabled="[[unifiedConsentGiven]]"> + on-settings-boolean-control-change="onMetricsReportingChange_"> <template is="dom-if" if="[[showRestart_]]" restamp> <paper-button on-click="onRestartTap_" id="restart" slot="more-actions"> @@ -80,16 +71,15 @@ <settings-toggle-button pref="{{prefs.url_keyed_anonymized_data_collection.enabled}}" label="$i18n{urlKeyedAnonymizedDataCollection}" - sub-label="$i18n{urlKeyedAnonymizedDataCollectionDesc}" - disabled="[[unifiedConsentGiven]]"> + sub-label="$i18n{urlKeyedAnonymizedDataCollectionDesc}"> </settings-toggle-button> </template> <if expr="_google_chrome"> - <settings-toggle-button + <settings-toggle-button id="spellCheckControl" pref="{{prefs.spellcheck.use_spelling_service}}" label="$i18n{spellingPref}" sub-label="$i18n{spellingDescription}" - disabled="[[unifiedConsentGiven]]"> + hidden="[[!showSpellCheckControl_(prefs.spellcheck.dictionaries)]]"> </settings-toggle-button> </if><!-- _google_chrome --> </template> diff --git a/chromium/chrome/browser/resources/settings/privacy_page/personalization_options.js b/chromium/chrome/browser/resources/settings/privacy_page/personalization_options.js index 27b0823183e..7db8150aea9 100644 --- a/chromium/chrome/browser/resources/settings/privacy_page/personalization_options.js +++ b/chromium/chrome/browser/resources/settings/privacy_page/personalization_options.js @@ -39,14 +39,6 @@ Polymer({ */ pageVisibility: Object, - /** @private {chrome.settingsPrivate.PrefObject} */ - safeBrowsingExtendedReportingPref_: { - type: Object, - value: function() { - return /** @type {chrome.settingsPrivate.PrefObject} */ ({}); - }, - }, - /** * Used for HTML bindings. This is defined as a property rather than within * the ready callback, because the value needs to be available before @@ -60,8 +52,6 @@ Polymer({ unifiedConsentEnabled: Boolean, - unifiedConsentGiven: Boolean, - // <if expr="_google_chrome and not chromeos"> // TODO(dbeam): make a virtual.* pref namespace and set/get this normally // (but handled differently in C++). @@ -84,10 +74,6 @@ Polymer({ ready: function() { this.browserProxy_ = settings.PrivacyPageBrowserProxyImpl.getInstance(); - const setSber = this.setSafeBrowsingExtendedReporting_.bind(this); - this.addWebUIListener('safe-browsing-extended-reporting-change', setSber); - this.browserProxy_.getSafeBrowsingExtendedReporting().then(setSber); - // <if expr="_google_chrome and not chromeos"> const setMetricsReportingPref = this.setMetricsReportingPref_.bind(this); this.addWebUIListener('metrics-reporting-change', setMetricsReportingPref); @@ -95,42 +81,6 @@ Polymer({ // </if> }, - /** @private */ - onSberChange_: function() { - const enabled = this.$.safeBrowsingExtendedReportingControl.checked; - this.browserProxy_.setSafeBrowsingExtendedReportingEnabled(enabled); - }, - - /** - * TODO(crbug.com/855945): Use this function for the spell check error hint - * @param {!Event} e - * @private - */ - onLanguageLinkBoxClick_: function(e) { - if (e.target.tagName === 'A') { - e.preventDefault(); - settings.navigateTo(settings.routes.LANGUAGES); - } - }, - - /** - * @param {!SberPrefState} sberPrefState SBER enabled and managed state. - * @private - */ - setSafeBrowsingExtendedReporting_: function(sberPrefState) { - // Ignore the next change because it will happen when we set the pref. - const pref = { - key: '', - type: chrome.settingsPrivate.PrefType.BOOLEAN, - value: sberPrefState.enabled, - }; - if (sberPrefState.managed) { - pref.enforcement = chrome.settingsPrivate.Enforcement.ENFORCED; - pref.controlledBy = chrome.settingsPrivate.ControlledBy.USER_POLICY; - } - this.safeBrowsingExtendedReportingPref_ = pref; - }, - // <if expr="_google_chrome and not chromeos"> /** @private */ onMetricsReportingChange_: function() { @@ -174,5 +124,16 @@ Polymer({ settings.LifetimeBrowserProxyImpl.getInstance().restart(); }, // </if> + + /** + * @return {boolean} + * @private + */ + showSpellCheckControl_: function() { + return !this.unifiedConsentEnabled || + (!!this.prefs.spellcheck && + /** @type {!Array<string>} */ + (this.prefs.spellcheck.dictionaries.value).length > 0); + }, }); })(); diff --git a/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.js b/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.js index 75f9ce13a12..6945694b66a 100644 --- a/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.js +++ b/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.js @@ -310,7 +310,9 @@ Polymer({ onMoreSettingsBoxClicked_: function(e) { if (e.target.tagName === 'A') { e.preventDefault(); - settings.navigateTo(settings.routes.SYNC); + // Navigate to sync page, and remove (privacy related) search text to + // avoid the sync page from being hidden. + settings.navigateTo(settings.routes.SYNC, null, true); } }, diff --git a/chromium/chrome/browser/resources/settings/privacy_page/privacy_page_browser_proxy.js b/chromium/chrome/browser/resources/settings/privacy_page/privacy_page_browser_proxy.js index c1e7d9fc333..0cfa4c59e78 100644 --- a/chromium/chrome/browser/resources/settings/privacy_page/privacy_page_browser_proxy.js +++ b/chromium/chrome/browser/resources/settings/privacy_page/privacy_page_browser_proxy.js @@ -7,9 +7,6 @@ /** @typedef {{enabled: boolean, managed: boolean}} */ let MetricsReporting; -/** @typedef {{enabled: boolean, managed: boolean}} */ -let SberPrefState; - cr.define('settings', function() { /** @interface */ class PrivacyPageBrowserProxy { @@ -28,12 +25,6 @@ cr.define('settings', function() { // </if> - /** @return {!Promise<!SberPrefState>} */ - getSafeBrowsingExtendedReporting() {} - - /** @param {boolean} enabled */ - setSafeBrowsingExtendedReportingEnabled(enabled) {} - /** @param {boolean} enabled */ setBlockAutoplayEnabled(enabled) {} } @@ -56,16 +47,6 @@ cr.define('settings', function() { // </if> /** @override */ - getSafeBrowsingExtendedReporting() { - return cr.sendWithPromise('getSafeBrowsingExtendedReporting'); - } - - /** @override */ - setSafeBrowsingExtendedReportingEnabled(enabled) { - chrome.send('setSafeBrowsingExtendedReportingEnabled', [enabled]); - } - - /** @override */ setBlockAutoplayEnabled(enabled) { chrome.send('setBlockAutoplayEnabled', [enabled]); } diff --git a/chromium/chrome/browser/resources/settings/route.js b/chromium/chrome/browser/resources/settings/route.js index 3099fa50bcf..841f8ec0d8d 100644 --- a/chromium/chrome/browser/resources/settings/route.js +++ b/chromium/chrome/browser/resources/settings/route.js @@ -11,6 +11,7 @@ * ACCESSIBILITY: (undefined|!settings.Route), * ACCOUNTS: (undefined|!settings.Route), * ADVANCED: (undefined|!settings.Route), + * ADDRESSES: (undefined|!settings.Route), * ANDROID_APPS: (undefined|!settings.Route), * ANDROID_APPS_DETAILS: (undefined|!settings.Route), * CROSTINI: (undefined|!settings.Route), @@ -48,7 +49,6 @@ * LANGUAGES: (undefined|!settings.Route), * LOCK_SCREEN: (undefined|!settings.Route), * MANAGE_ACCESSIBILITY: (undefined|!settings.Route), - * MANAGE_PASSWORDS: (undefined|!settings.Route), * MANAGE_PROFILE: (undefined|!settings.Route), * MANAGE_TTS_SETTINGS: (undefined|!settings.Route), * MULTIDEVICE: (undefined|!settings.Route), @@ -100,6 +100,7 @@ * STORAGE: (undefined|!settings.Route), * STYLUS: (undefined|!settings.Route), * SYNC: (undefined|!settings.Route), + * SYNC_ADVANCED: (undefined|!settings.Route), * SYSTEM: (undefined|!settings.Route), * TRIGGERED_RESET_DIALOG: (undefined|!settings.Route), * }} @@ -214,10 +215,6 @@ cr.define('settings', function() { /** @type {!SettingsRoutes} */ const r = {}; - const autofillHomeEnabled = - loadTimeData.valueExists('autofillHomeEnabled') && - loadTimeData.getBoolean('autofillHomeEnabled'); - // Root pages. r.BASIC = new Route('/'); r.ABOUT = new Route('/help'); @@ -249,6 +246,13 @@ cr.define('settings', function() { r.FONTS = r.APPEARANCE.createChild('/fonts'); } + if (pageVisibility.autofill !== false) { + r.AUTOFILL = r.BASIC.createSection('/autofill', 'autofill'); + r.PASSWORDS = r.AUTOFILL.createChild('/passwords'); + r.PAYMENTS = r.AUTOFILL.createChild('/payments'); + r.ADDRESSES = r.AUTOFILL.createChild('/addresses'); + } + if (pageVisibility.defaultBrowser !== false) { r.DEFAULT_BROWSER = r.BASIC.createSection('/defaultBrowser', 'defaultBrowser'); @@ -278,11 +282,7 @@ cr.define('settings', function() { if (pageVisibility.people !== false) { r.PEOPLE = r.BASIC.createSection('/people', 'people'); r.SYNC = r.PEOPLE.createChild('/syncSetup'); - if (autofillHomeEnabled) { - r.AUTOFILL = r.PEOPLE.createChild('/autofill'); - r.MANAGE_PASSWORDS = r.PEOPLE.createChild('/passwords'); - r.PAYMENTS = r.PEOPLE.createChild('/payments'); - } + r.SYNC_ADVANCED = r.SYNC.createChild('/syncSetup/advanced'); // <if expr="not chromeos"> r.MANAGE_PROFILE = r.PEOPLE.createChild('/manageProfile'); // </if> @@ -377,14 +377,6 @@ cr.define('settings', function() { } // </if> - if (!autofillHomeEnabled && pageVisibility.passwordsAndForms !== false) { - r.PASSWORDS = - r.ADVANCED.createSection('/passwordsAndForms', 'passwordsAndForms'); - r.AUTOFILL = r.PASSWORDS.createChild('/autofill'); - r.MANAGE_PASSWORDS = r.PASSWORDS.createChild('/passwords'); - r.PAYMENTS = r.PASSWORDS.createChild('/payments'); - } - r.LANGUAGES = r.ADVANCED.createSection('/languages', 'languages'); // <if expr="chromeos"> r.INPUT_METHODS = r.LANGUAGES.createChild('/inputMethods'); diff --git a/chromium/chrome/browser/resources/settings/search_engines_page/omnibox_extension_entry.html b/chromium/chrome/browser/resources/settings/search_engines_page/omnibox_extension_entry.html index b181ac3e909..13113c7629c 100644 --- a/chromium/chrome/browser/resources/settings/search_engines_page/omnibox_extension_entry.html +++ b/chromium/chrome/browser/resources/settings/search_engines_page/omnibox_extension_entry.html @@ -2,12 +2,12 @@ <link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> -<link rel="import" href="chrome://resources/html/icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="../extension_control_browser_proxy.html"> <link rel="import" href="../focus_row_behavior.html"> <link rel="import" href="search_engine_entry_css.html"> <link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="../site_favicon.html"> <dom-module id="settings-omnibox-extension-entry"> <template> @@ -22,15 +22,10 @@ .keyword-column { flex: 7; } - - .favicon-image + span { - margin-inline-end: 8px; - } </style> <div class="list-item" focus-row-container> <div class="name-column"> - <span class="favicon-image" - style="background-image: [[getIconSet_(engine.iconURL)]]"></span> + <site-favicon url="[[engine.iconURL]]"></site-favicon> <span>[[engine.displayName]]</span> </div> <div class="keyword-column">[[engine.keyword]]</div> diff --git a/chromium/chrome/browser/resources/settings/search_engines_page/omnibox_extension_entry.js b/chromium/chrome/browser/resources/settings/search_engines_page/omnibox_extension_entry.js index a678513ea5f..865ac581cc1 100644 --- a/chromium/chrome/browser/resources/settings/search_engines_page/omnibox_extension_entry.js +++ b/chromium/chrome/browser/resources/settings/search_engines_page/omnibox_extension_entry.js @@ -42,15 +42,6 @@ Polymer({ this.$$('cr-action-menu').close(); }, - /** - * @param {string} url - * @return {string} A set of icon URLs. - * @private - */ - getIconSet_: function(url) { - return cr.icon.getFavicon(url); - }, - /** @private */ onDotsTap_: function() { /** @type {!CrActionMenuElement} */ (this.$$('cr-action-menu')) diff --git a/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry.html b/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry.html index 413a1e34eea..951befd13c8 100644 --- a/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry.html +++ b/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry.html @@ -4,13 +4,13 @@ <link rel="import" href="chrome://resources/cr_elements/icons.html"> <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.html"> -<link rel="import" href="chrome://resources/html/icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="../controls/extension_controlled_indicator.html"> <link rel="import" href="../focus_row_behavior.html"> <link rel="import" href="search_engine_entry_css.html"> <link rel="import" href="search_engines_browser_proxy.html"> <link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="../site_favicon.html"> <dom-module id="settings-search-engine-entry"> <template> @@ -30,8 +30,7 @@ word-break: break-word; } - #keyword-column > div, - .favicon-image + div { + #keyword-column > div { margin-inline-end: 8px; } @@ -42,8 +41,7 @@ <div class="list-item" focus-row-container> <div id="name-column"> - <div class="favicon-image" - style="background-image: [[getIconSet_(engine.iconURL)]]"></div> + <site-favicon url="[[engine.iconURL]]"></site-favicon> <div>[[engine.displayName]]</div> </div> <div id="keyword-column"><div>[[engine.keyword]]</div></div> diff --git a/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry.js b/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry.js index 2c8621f16d9..d9bba7635a1 100644 --- a/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry.js +++ b/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry.js @@ -64,16 +64,6 @@ Polymer({ return canBeDefault || canBeEdited || canBeRemoved; }, - /** - * @param {?string} url The icon URL if available. - * @return {string} A set of icon URLs. - * @private - */ - getIconSet_: function(url) { - // Force default icon, if no |engine.iconURL| is available. - return cr.icon.getFavicon(url || ''); - }, - /** @private */ onDeleteTap_: function() { this.browserProxy_.removeSearchEngine(this.engine.modelIndex); diff --git a/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry_css.html b/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry_css.html index 2770ff9ff3f..2bc74223771 100644 --- a/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry_css.html +++ b/chromium/chrome/browser/resources/settings/search_engines_page/search_engine_entry_css.html @@ -1,14 +1,9 @@ <dom-module id="search-engine-entry"> <template> <style> - .favicon-image { - background-repeat: no-repeat; - background-size: contain; - display: inline-block; - height: 20px; + site-favicon { margin-inline-end: 8px; - min-width: 20px; - vertical-align: middle; + min-width: 16px; } .dropdown-content { diff --git a/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_list.html b/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_list.html index 6ebb6002de7..6d05837233f 100644 --- a/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_list.html +++ b/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_list.html @@ -57,7 +57,7 @@ <template> <settings-search-engine-entry engine="[[item]]" tabindex$="[[tabIndex]]" iron-list-tab-index="[[tabIndex]]" - last-focused="{{lastFocused_}}"> + last-focused="{{lastFocused_}}" list-blurred="{{listBlurred_}}"> </settings-search-engine-entry> </template> </iron-list> diff --git a/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_list.js b/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_list.js index 5a015a53ca2..12911500d9b 100644 --- a/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_list.js +++ b/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_list.js @@ -25,6 +25,9 @@ Polymer({ /** @private {Object}*/ lastFocused_: Object, + /** @private */ + listBlurred_: Boolean, + fixedHeight: { type: Boolean, value: false, diff --git a/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_page.html b/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_page.html index b243798f19a..eb76e409d2e 100644 --- a/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_page.html +++ b/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_page.html @@ -74,7 +74,8 @@ <template> <settings-omnibox-extension-entry engine="[[item]]" tabindex$="[[tabIndex]]" iron-list-tab-index="[[tabIndex]]" - last-focused="{{omniboxExtensionlastFocused_}}"> + last-focused="{{omniboxExtensionlastFocused_}}" + list-blurred="{{omniboxExtensionListBlurred_}}"> </settings-omnibox-extension-entry> </template> </iron-list> diff --git a/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_page.js b/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_page.js index 7821d110ea0..37c1c50b032 100644 --- a/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_page.js +++ b/chromium/chrome/browser/resources/settings/search_engines_page/search_engines_page.js @@ -63,6 +63,9 @@ Polymer({ /** @private {HTMLElement} */ omniboxExtensionlastFocused_: Object, + /** @private {boolean} */ + omniboxExtensionListBlurred_: Boolean, + /** @private {?SearchEngine} */ dialogModel_: { type: Object, diff --git a/chromium/chrome/browser/resources/settings/settings_main/settings_main.html b/chromium/chrome/browser/resources/settings/settings_main/settings_main.html index 87bd32f2d53..095b6eec58d 100644 --- a/chromium/chrome/browser/resources/settings/settings_main/settings_main.html +++ b/chromium/chrome/browser/resources/settings/settings_main/settings_main.html @@ -47,14 +47,14 @@ show-crostini="[[showCrostini]]" show-multidevice="[[showMultidevice]]" have-play-store-app="[[havePlayStoreApp]]" - autofill-home-enabled="[[autofillHomeEnabled]]" on-subpage-expand="onSubpageExpand_" in-search-mode="[[inSearchMode_]]" advanced-toggle-expanded="{{advancedToggleExpanded}}"> </settings-basic-page> </template> <template is="dom-if" if="[[showPages_.about]]"> - <settings-about-page in-search-mode="[[inSearchMode_]]" + <settings-about-page role="main" + in-search-mode="[[inSearchMode_]]" prefs="{{prefs}}" show-crostini="[[showCrostini]]"> </settings-about-page> diff --git a/chromium/chrome/browser/resources/settings/settings_main/settings_main.js b/chromium/chrome/browser/resources/settings/settings_main/settings_main.js index 156b830bb14..7a375bc4bf4 100644 --- a/chromium/chrome/browser/resources/settings/settings_main/settings_main.js +++ b/chromium/chrome/browser/resources/settings/settings_main/settings_main.js @@ -81,10 +81,6 @@ Polymer({ showMultidevice: Boolean, havePlayStoreApp: Boolean, - - // TODO(jdoerrie): https://crbug.com/854562. - // Remove once Autofill Home is launched. - autofillHomeEnabled: Boolean, }, /** @override */ @@ -184,6 +180,12 @@ Polymer({ const inAbout = settings.routes.ABOUT.contains(settings.getCurrentRoute()); this.showPages_ = {about: inAbout, settings: !inAbout}; + document.title = inAbout ? + loadTimeData.getStringF( + 'settingsAltPageTitle', loadTimeData.getString('aboutPageTitle')) : + loadTimeData.getString('settings'); + + // Calculate and set the overflow padding. this.updateOverscrollForPage_(); @@ -293,4 +295,10 @@ Polymer({ }, 0); }); }, + + focusSection: function() { + this.$$(this.showPages_.settings ? 'settings-basic-page' : + 'settings-about-page') + .focusSection(); + }, }); diff --git a/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.html b/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.html index 5e2a1583e67..2fcea63a9bf 100644 --- a/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.html +++ b/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.html @@ -109,6 +109,11 @@ <iron-icon icon="cr:person"></iron-icon> $i18n{peoplePageTitle} </a> + <a id="autofill" href="/autofill" + hidden="[[!pageVisibility.autofill]]"> + <iron-icon icon="settings:assignment"></iron-icon> + $i18n{autofillPageTitle} + </a> <a id="appearance" href="/appearance" hidden="[[!pageVisibility.appearance]]"> <iron-icon icon="settings:palette"></iron-icon> @@ -168,13 +173,6 @@ <iron-icon icon="cr:security"></iron-icon> $i18n{privacyPageTitle} </a> - <template is="dom-if" if="[[!autofillHomeEnabled]]"> - <a id="passwordsAndForms" href="/passwordsAndForms" - hidden="[[!pageVisibility.passwordsAndForms]]"> - <iron-icon icon="settings:assignment"></iron-icon> - $i18n{passwordsAndAutofillPageTitle} - </a> - </template> <a href="/languages"> <iron-icon icon="settings:language"></iron-icon> $i18n{languagesPageTitle} diff --git a/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.js b/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.js index 72c54f25a05..5c6717ce225 100644 --- a/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.js +++ b/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.js @@ -17,10 +17,6 @@ Polymer({ notify: true, }, - // TODO(jdoerrie): https://crbug.com/854562. - // Remove once Autofill Home is launched. - autofillHomeEnabled: Boolean, - /** * Dictionary defining page visibility. * @type {!GuestModePageVisibility} diff --git a/chromium/chrome/browser/resources/settings/settings_page/main_page_behavior.js b/chromium/chrome/browser/resources/settings/settings_page/main_page_behavior.js index 5abc16e9982..49ef81a19e8 100644 --- a/chromium/chrome/browser/resources/settings/settings_page/main_page_behavior.js +++ b/chromium/chrome/browser/resources/settings/settings_page/main_page_behavior.js @@ -158,7 +158,7 @@ const MainPageBehaviorImpl = { else promise = this.expandSection_(currentSection); } else if (scrollToSection) { - currentSection.scrollIntoView(); + currentSection.show(); } } else if ( this.tagName == 'SETTINGS-BASIC-PAGE' && settings.routes.ADVANCED && diff --git a/chromium/chrome/browser/resources/settings/settings_page/settings_section.html b/chromium/chrome/browser/resources/settings/settings_page/settings_section.html index 7599a515645..a6336040a34 100644 --- a/chromium/chrome/browser/resources/settings/settings_page/settings_section.html +++ b/chromium/chrome/browser/resources/settings/settings_page/settings_section.html @@ -1,6 +1,7 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> +<link rel="import" href="chrome://resources/html/util.html"> <link rel="import" href="../animation/animation.html"> <dom-module id="settings-section"> @@ -12,11 +13,13 @@ /* Margin so the box-shadow isn't clipped during animations. */ margin-inline-end: 3px; margin-inline-start: 3px; + outline: none; position: relative; } #header { margin-bottom: 12px; + @apply --settings-section-header; } #header .title { diff --git a/chromium/chrome/browser/resources/settings/settings_page/settings_section.js b/chromium/chrome/browser/resources/settings/settings_page/settings_section.js index a4546663464..e7f9d56039c 100644 --- a/chromium/chrome/browser/resources/settings/settings_page/settings_section.js +++ b/chromium/chrome/browser/resources/settings/settings_page/settings_section.js @@ -244,6 +244,15 @@ let SettingsSectionElement = Polymer({ return animation; }, + show: function() { + this.setAttribute('tabindex', '-1'); + this.focus(); + this.scrollIntoView(); + listenOnce(this, ['blur', 'pointerdown'], () => { + this.removeAttribute('tabindex'); + }); + }, + /** * Helper function to animate the card's position and height. * @param {string} position CSS position property. diff --git a/chromium/chrome/browser/resources/settings/settings_resources.grd b/chromium/chrome/browser/resources/settings/settings_resources.grd index d3e899961b0..c2f55be8fde 100644 --- a/chromium/chrome/browser/resources/settings/settings_resources.grd +++ b/chromium/chrome/browser/resources/settings/settings_resources.grd @@ -34,6 +34,10 @@ <structure name="IDR_SETTINGS_TTS_SUBPAGE_HTML" file="a11y_page/tts_subpage.html" type="chrome_html" /> + <structure name="IDR_MD_SETTINGS_MANIFEST" + file="manifest.json" + type="chrome_html" /> + </if> <structure name="IDR_SETTINGS_ABOUT_PAGE_BROWSER_PROXY_HTML" file="about_page/about_page_browser_proxy.html" @@ -581,24 +585,12 @@ type="chrome_html" preprocess="true" /> <if expr="chromeos"> - <structure name="IDR_SETTINGS_SMB_BROWSER_PROXY_HTML" - file="downloads_page/smb_browser_proxy.html" - type="chrome_html" /> - <structure name="IDR_SETTINGS_SMB_BROWSER_PROXY_JS" - file="downloads_page/smb_browser_proxy.js" - type="chrome_html" /> <structure name="IDR_SETTINGS_SMB_SHARES_PAGE_HTML" file="downloads_page/smb_shares_page.html" type="chrome_html" /> <structure name="IDR_SETTINGS_SMB_SHARES_PAGE_JS" file="downloads_page/smb_shares_page.js" type="chrome_html" /> - <structure name="IDR_SETTINGS_ADD_SMB_SHARE_DIALOG_HTML" - file="downloads_page/add_smb_share_dialog.html" - type="chrome_html" /> - <structure name="IDR_SETTINGS_ADD_SMB_SHARE_DIALOG_JS" - file="downloads_page/add_smb_share_dialog.js" - type="chrome_html" /> </if> <structure name="IDR_SETTINGS_I18n_SETUP_HTML" file="i18n_setup.html" @@ -699,77 +691,77 @@ <structure name="IDR_SETTINGS_MEDIA_PICKER_JS" file="site_settings/media_picker.js" type="chrome_html" /> - <structure name="IDR_SETTINGS_PASSWORDS_AND_FORMS_PAGE_HTML" - file="passwords_and_forms_page/passwords_and_forms_page.html" + <structure name="IDR_SETTINGS_AUTOFILL_PAGE_HTML" + file="autofill_page/autofill_page.html" type="chrome_html" /> - <structure name="IDR_SETTINGS_PASSWORDS_AND_FORMS_PAGE_JS" - file="passwords_and_forms_page/passwords_and_forms_page.js" + <structure name="IDR_SETTINGS_AUTOFILL_PAGE_JS" + file="autofill_page/autofill_page.js" type="chrome_html" /> <structure name="IDR_SETTINGS_PASSWORDS_SHARED_CSS_HTML" - file="passwords_and_forms_page/passwords_shared_css.html" + file="autofill_page/passwords_shared_css.html" type="chrome_html" /> <structure name="IDR_SETTINGS_CREDIT_CARD_EDIT_DIALOG_HTML" - file="passwords_and_forms_page/credit_card_edit_dialog.html" + file="autofill_page/credit_card_edit_dialog.html" type="chrome_html" /> <structure name="IDR_SETTINGS_CREDIT_CARD_EDIT_DIALOG_JS" - file="passwords_and_forms_page/credit_card_edit_dialog.js" + file="autofill_page/credit_card_edit_dialog.js" type="chrome_html" /> <structure name="IDR_SETTINGS_AUTOFILL_SECTION_HTML" - file="passwords_and_forms_page/autofill_section.html" + file="autofill_page/autofill_section.html" type="chrome_html" /> <structure name="IDR_SETTINGS_AUTOFILL_SECTION_JS" - file="passwords_and_forms_page/autofill_section.js" + file="autofill_page/autofill_section.js" type="chrome_html" /> <structure name="IDR_SETTINGS_ADDRESS_EDIT_DIALOG_HTML" - file="passwords_and_forms_page/address_edit_dialog.html" + file="autofill_page/address_edit_dialog.html" type="chrome_html" /> <structure name="IDR_SETTINGS_ADDRESS_EDIT_DIALOG_JS" - file="passwords_and_forms_page/address_edit_dialog.js" + file="autofill_page/address_edit_dialog.js" type="chrome_html" /> <structure name="IDR_SETTINGS_SHOW_PASSWORD_BEHAVIOR_HTML" - file="passwords_and_forms_page/show_password_behavior.html" + file="autofill_page/show_password_behavior.html" type="chrome_html" /> <structure name="IDR_SETTINGS_SHOW_PASSWORD_BEHAVIOR_JS" - file="passwords_and_forms_page/show_password_behavior.js" + file="autofill_page/show_password_behavior.js" type="chrome_html" /> <structure name="IDR_SETTINGS_PASSWORD_LIST_ITEM_HTML" - file="passwords_and_forms_page/password_list_item.html" + file="autofill_page/password_list_item.html" type="chrome_html" preprocess="true" /> <structure name="IDR_SETTINGS_PASSWORD_LIST_ITEM_JS" - file="passwords_and_forms_page/password_list_item.js" + file="autofill_page/password_list_item.js" type="chrome_html" /> <structure name="IDR_SETTINGS_PASSWORD_MANAGER_PROXY_HTML" - file="passwords_and_forms_page/password_manager_proxy.html" + file="autofill_page/password_manager_proxy.html" type="chrome_html" /> <structure name="IDR_SETTINGS_PASSWORD_MANAGER_PROXY_JS" - file="passwords_and_forms_page/password_manager_proxy.js" + file="autofill_page/password_manager_proxy.js" type="chrome_html" /> <structure name="IDR_SETTINGS_PASSWORDS_SECTION_HTML" - file="passwords_and_forms_page/passwords_section.html" + file="autofill_page/passwords_section.html" type="chrome_html" /> <structure name="IDR_SETTINGS_PASSWORDS_SECTION_JS" - file="passwords_and_forms_page/passwords_section.js" + file="autofill_page/passwords_section.js" type="chrome_html" preprocess="true" /> <structure name="IDR_SETTINGS_PASSWORD_EDIT_DIALOG_HTML" - file="passwords_and_forms_page/password_edit_dialog.html" + file="autofill_page/password_edit_dialog.html" type="chrome_html" preprocess="true" /> <structure name="IDR_SETTINGS_PASSWORD_EDIT_DIALOG_JS" - file="passwords_and_forms_page/password_edit_dialog.js" + file="autofill_page/password_edit_dialog.js" type="chrome_html" /> <structure name="IDR_SETTINGS_PASSWORDS_EXPORT_DIALOG_HTML" - file="passwords_and_forms_page/passwords_export_dialog.html" + file="autofill_page/passwords_export_dialog.html" type="chrome_html" /> <structure name="IDR_SETTINGS_PASSWORDS_EXPORT_DIALOG_JS" - file="passwords_and_forms_page/passwords_export_dialog.js" + file="autofill_page/passwords_export_dialog.js" type="chrome_html" /> <structure name="IDR_SETTINGS_PAYMENTS_SECTION_HTML" - file="passwords_and_forms_page/payments_section.html" + file="autofill_page/payments_section.html" type="chrome_html" /> <structure name="IDR_SETTINGS_PAYMENTS_SECTION_JS" - file="passwords_and_forms_page/payments_section.js" + file="autofill_page/payments_section.js" type="chrome_html" /> <structure name="IDR_SETTINGS_PEOPLE_PAGE_HTML" file="people_page/people_page.html" @@ -945,6 +937,12 @@ <structure name="IDR_SETTINGS_LOCAL_DATA_BROWSER_PROXY_JS" file="site_settings/local_data_browser_proxy.js" type="chrome_html" /> + <structure name="IDR_SETTINGS_OPEN_WINDOW_PROXY_HTML" + file="open_window_proxy.html" + type="chrome_html" /> + <structure name="IDR_SETTINGS_OPEN_WINDOW_PROXY_JS" + file="open_window_proxy.js" + type="chrome_html" /> <structure name="IDR_SETTINGS_PAGE_VISIBILITY_HTML" file="page_visibility.html" type="chrome_html" /> @@ -998,6 +996,12 @@ file="route.js" type="chrome_html" preprocess="true" /> + <structure name="IDR_SETTINGS_SITE_FAVICON_HTML" + file="site_favicon.html" + type="chrome_html" /> + <structure name="IDR_SETTINGS_SITE_FAVICON_JS" + file="site_favicon.js" + type="chrome_html" /> <structure name="IDR_SETTINGS_SITE_DATA_HTML" file="site_settings/site_data.html" type="chrome_html" /> @@ -1153,7 +1157,16 @@ type="chrome_html" preprocess="true" allowexternalscript="true" /> - <structure name="IDR_SETTINGS_SYNC_PAGE_JS" + <structure name="IDR_SETTINGS_SYNC_CONTROLS_JS" + file="people_page/sync_controls.js" + type="chrome_html" + preprocess="true" /> + <structure name="IDR_SETTINGS_SYNC_CONTROLS_HTML" + file="people_page/sync_controls.html" + type="chrome_html" + preprocess="true" + allowexternalscript="true" /> + <structure name="IDR_SETTINGS_SYNC_PAGE_JS" file="people_page/sync_page.js" type="chrome_html" preprocess="true" /> @@ -1457,22 +1470,6 @@ type="chrome_html" preprocess="true" allowexternalscript="true" /> - <structure name="IDR_SETTINGS_PEOPLE_EASY_UNLOCK_BROWSER_PROXY_JS" - file="people_page/easy_unlock_browser_proxy.js" - type="chrome_html" /> - <structure name="IDR_SETTINGS_PEOPLE_EASY_UNLOCK_BROWSER_PROXY_HTML" - file="people_page/easy_unlock_browser_proxy.html" - type="chrome_html" - preprocess="true" - allowexternalscript="true" /> - <structure name="IDR_SETTINGS_PEOPLE_EASY_UNLOCK_TURN_OFF_DIALOG_JS" - file="people_page/easy_unlock_turn_off_dialog.js" - type="chrome_html" /> - <structure name="IDR_SETTINGS_PEOPLE_EASY_UNLOCK_TURN_OFF_DIALOG_HTML" - file="people_page/easy_unlock_turn_off_dialog.html" - type="chrome_html" - preprocess="true" - allowexternalscript="true" /> <structure name="IDR_SETTINGS_PEOPLE_LOCK_SCREEN_PASSWORD_PROMPT_DIALOG_JS" file="people_page/lock_screen_password_prompt_dialog.js" type="chrome_html" /> diff --git a/chromium/chrome/browser/resources/settings/settings_resources_vulcanized.grd b/chromium/chrome/browser/resources/settings/settings_resources_vulcanized.grd index 46a832e137a..d6163532492 100644 --- a/chromium/chrome/browser/resources/settings/settings_resources_vulcanized.grd +++ b/chromium/chrome/browser/resources/settings/settings_resources_vulcanized.grd @@ -5,7 +5,7 @@ <emit emit_type='prepend'></emit> </output> <output filename="grit/settings_resources_map.cc" - type="resource_file_map_source" /> + type="resource_map_source" /> <output filename="grit/settings_resources_map.h" type="resource_map_header" /> <output filename="settings_resources.pak" type="data_package" /> @@ -18,6 +18,7 @@ <include name="IDR_MD_SETTINGS_LAZY_LOAD_VULCANIZED_HTML" file="${root_gen_dir}\chrome\browser\resources\settings\lazy_load.vulcanized.html" use_base_dir="false" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" /> <include name="IDR_MD_SETTINGS_LAZY_LOAD_VULCANIZED_P2_HTML" file="${root_gen_dir}\chrome\browser\resources\settings\lazy_load.vulcanized.p2.html" use_base_dir="false" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" /> <include name="IDR_MD_SETTINGS_LAZY_LOAD_CRISPER_JS" file="${root_gen_dir}\chrome\browser\resources\settings\lazy_load.crisper.js" use_base_dir="false" flattenhtml="true" type="BINDATA" compress="gzip" /> + <include name="IDR_MD_SETTINGS_MANIFEST" file="manifest.json" type="BINDATA" compress="gzip" /> </includes> </release> </grit> diff --git a/chromium/chrome/browser/resources/settings/settings_shared_css.html b/chromium/chrome/browser/resources/settings/settings_shared_css.html index f78d3de53ca..430570e084e 100644 --- a/chromium/chrome/browser/resources/settings/settings_shared_css.html +++ b/chromium/chrome/browser/resources/settings/settings_shared_css.html @@ -80,7 +80,10 @@ } /* Space out multiple buttons in the same row. */ - .settings-box paper-button + paper-button { + .settings-box paper-button + paper-button, + .settings-box paper-button + controlled-button, + .settings-box controlled-button + controlled-button, + .settings-box controlled-button + paper-button { margin-inline-start: 16px; } @@ -112,11 +115,11 @@ min-height: var(--settings-row-min-height); } - paper-radio-group { + cr-radio-group { width: 100%; } - paper-radio-group:focus { + cr-radio-group:focus { background-color: var(--google-grey-300); outline: none; } @@ -323,13 +326,6 @@ margin: 0 16px; } - .favicon-image { - background-repeat: no-repeat; - background-size: contain; - height: 16px; - width: 16px; - } - .column-header { color: var(--google-grey-refresh-700); font-size: inherit; diff --git a/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.html b/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.html index 88d91ba73e1..04069b85b3e 100644 --- a/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.html +++ b/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.html @@ -4,6 +4,7 @@ <link rel="import" href="chrome://resources/cr_elements/cr_drawer/cr_drawer.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toolbar/cr_toolbar.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> +<link rel="import" href="chrome://resources/html/util.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> <link rel="import" href="../find_shortcut_behavior.html"> <link rel="import" href="../global_scroll_target_behavior.html"> @@ -61,8 +62,8 @@ role="banner" show-menu> </cr-toolbar> - <cr-drawer id="drawer" on-close="onMenuClosed_" - heading="$i18n{settings}" align="$i18n{textdirection}"> + <cr-drawer id="drawer" on-close="onMenuClose_" heading="$i18n{settings}" + align="$i18n{textdirection}"> <div class="drawer-content"> <template is="dom-if" id="drawerTemplate"> <settings-menu page-visibility="[[pageVisibility_]]" @@ -70,7 +71,6 @@ show-crostini="[[showCrostini_]]" show-multidevice="[[showMultidevice_]]" have-play-store-app="[[havePlayStoreApp_]]" - autofill-home-enabled="[[autofillHomeEnabled_]]" on-iron-activate="onIronActivate_" advanced-opened="{{advancedOpened_}}"> </settings-menu> @@ -85,7 +85,6 @@ show-crostini="[[showCrostini_]]" show-multidevice="[[showMultidevice_]]" have-play-store-app="[[havePlayStoreApp_]]" - autofill-home-enabled="[[autofillHomeEnabled_]]" advanced-toggle-expanded="{{advancedOpened_}}"> </settings-main> </div> diff --git a/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.js b/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.js index 37ebe94a487..8bd9c1091bb 100644 --- a/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.js +++ b/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.js @@ -62,13 +62,6 @@ Polymer({ /** @private */ havePlayStoreApp_: Boolean, - /** - * TODO(jdoerrie): https://crbug.com/854562. - * Remove once Autofill Home is launched. - * @private - */ - autofillHomeEnabled_: Boolean, - /** @private */ lastSearchQuery_: { type: String, @@ -92,12 +85,12 @@ Polymer({ */ ready: function() { // Lazy-create the drawer the first time it is opened or swiped into view. - listenOnce(this.$.drawer, 'open-changed', () => { + listenOnce(this.$.drawer, 'cr-drawer-opening', () => { this.$.drawerTemplate.if = true; }); window.addEventListener('popstate', e => { - this.$.drawer.closeDrawer(); + this.$.drawer.cancel(); }); CrPolicyStrings = { @@ -153,9 +146,6 @@ Polymer({ loadTimeData.getBoolean('enableMultideviceSettings'); this.havePlayStoreApp_ = loadTimeData.valueExists('havePlayStoreApp') && loadTimeData.getBoolean('havePlayStoreApp'); - this.autofillHomeEnabled_ = - loadTimeData.valueExists('autofillHomeEnabled') && - loadTimeData.getBoolean('autofillHomeEnabled'); this.addEventListener('show-container', () => { this.$.container.style.visibility = 'visible'; @@ -269,12 +259,11 @@ Polymer({ }, /** - * @param {!Event} event + * Called when a section is selected. * @private */ - onIronActivate_: function(event) { - if (event.detail.item.id != 'advancedSubmenu') - this.$.drawer.closeDrawer(); + onIronActivate_: function() { + this.$.drawer.close(); }, /** @private */ @@ -282,14 +271,25 @@ Polymer({ this.$.drawer.toggle(); }, - /** @private */ - onMenuClosed_: function() { - // Add tab index so that the container can be focused. - this.$.container.setAttribute('tabindex', '-1'); - this.$.container.focus(); - - listenOnce(this.$.container, ['blur', 'pointerdown'], () => { - this.$.container.removeAttribute('tabindex'); - }); + /** + * When this is called, The drawer animation is finished, and the dialog no + * longer has focus. The selected section will gain focus if one was selected. + * Otherwise, the drawer was closed due being canceled, and the main settings + * container is given focus. That way the arrow keys can be used to scroll + * the container, and pressing tab focuses a component in settings. + * @private + */ + onMenuClose_: function() { + if (this.$.drawer.wasCanceled()) { + // Add tab index so that the container can be focused. + this.$.container.setAttribute('tabindex', '-1'); + this.$.container.focus(); + + listenOnce(this.$.container, ['blur', 'pointerdown'], () => { + this.$.container.removeAttribute('tabindex'); + }); + } else { + this.$.main.focusSection(); + } }, }); diff --git a/chromium/chrome/browser/resources/settings/settings_vars_css.html b/chromium/chrome/browser/resources/settings/settings_vars_css.html index 174fcfb2167..6c363ae0443 100644 --- a/chromium/chrome/browser/resources/settings/settings_vars_css.html +++ b/chromium/chrome/browser/resources/settings/settings_vars_css.html @@ -55,7 +55,7 @@ --iron-icon-height: var(--cr-icon-size); --iron-icon-width: var(--cr-icon-size); - --paper-radio-group-item-padding: 0; + --cr-radio-group-item-padding: 0; } </style> </custom-style> diff --git a/chromium/chrome/browser/resources/settings/site_favicon.html b/chromium/chrome/browser/resources/settings/site_favicon.html new file mode 100644 index 00000000000..7ff3ca780bd --- /dev/null +++ b/chromium/chrome/browser/resources/settings/site_favicon.html @@ -0,0 +1,18 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/html/icon.html"> + +<dom-module id="site-favicon"> + <template> + <style> + :host { + background-repeat: no-repeat; + background-size: contain; + display: block; + height: 16px; + width: 16px; + } + </style> + </template> + <script src="site_favicon.js"></script> +</dom-module> diff --git a/chromium/chrome/browser/resources/settings/site_favicon.js b/chromium/chrome/browser/resources/settings/site_favicon.js new file mode 100644 index 00000000000..2da9ef11d15 --- /dev/null +++ b/chromium/chrome/browser/resources/settings/site_favicon.js @@ -0,0 +1,58 @@ +// Copyright 2018 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. + +/** + * @fileoverview 'site-favicon' is the section to display the favicon given the + * site URL. + */ + +Polymer({ + is: 'site-favicon', + + properties: { + url: { + type: String, + value: '', + observer: 'urlChanged_', + } + }, + + /** @private */ + urlChanged_: function() { + let url = this.removePatternWildcard_(this.url); + url = this.ensureUrlHasScheme_(url); + this.style.backgroundImage = cr.icon.getFavicon(url || ''); + }, + + /** + * Removes the wildcard prefix from a pattern string. + * @param {string} pattern The pattern to remove the wildcard from. + * @return {string} The resulting pattern. + * @private + */ + removePatternWildcard_: function(pattern) { + if (!pattern || pattern.length === 0) + return pattern; + + if (pattern.startsWith('http://[*.]')) + return pattern.replace('http://[*.]', 'http://'); + else if (pattern.startsWith('https://[*.]')) + return pattern.replace('https://[*.]', 'https://'); + else if (pattern.startsWith('[*.]')) + return pattern.substring(4, pattern.length); + return pattern; + }, + + /** + * Ensures the URL has a scheme (assumes http if omitted). + * @param {string} url The URL with or without a scheme. + * @return {string} The URL with a scheme, or an empty string. + * @private + */ + ensureUrlHasScheme_: function(url) { + if (!url || url.length === 0) + return url; + return url.includes('://') ? url : 'http://' + url; + }, +});
\ No newline at end of file diff --git a/chromium/chrome/browser/resources/settings/site_settings/add_site_dialog.html b/chromium/chrome/browser/resources/settings/site_settings/add_site_dialog.html index 0c7c49cb111..3b2ddf0f8e2 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/add_site_dialog.html +++ b/chromium/chrome/browser/resources/settings/site_settings/add_site_dialog.html @@ -23,7 +23,7 @@ <cr-input id="site" label="$i18n{addSite}" placeholder="$i18n{addSiteExceptionPlaceholder}" value="{{site_}}" on-input="validate_" - error-message="$i18n{notValidWebAddress}" spellcheck="false" + error-message="{{errorMessage_}}" spellcheck="false" autofocus></cr-input> <cr-checkbox id="incognito" hidden$="[[!showIncognitoSessionOnly_(hasIncognito, diff --git a/chromium/chrome/browser/resources/settings/site_settings/add_site_dialog.js b/chromium/chrome/browser/resources/settings/site_settings/add_site_dialog.js index 808edd7788d..6c55630a1a5 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/add_site_dialog.js +++ b/chromium/chrome/browser/resources/settings/site_settings/add_site_dialog.js @@ -36,6 +36,12 @@ Polymer({ * @private */ site_: String, + + /** + * The error message to display when the pattern is invalid. + * @private + */ + errorMessage_: String, }, /** @override */ @@ -60,10 +66,12 @@ Polymer({ return; } - this.browserProxy.isPatternValid(this.site_).then(isValid => { - this.$.site.invalid = !isValid; - this.$.add.disabled = !isValid; - }); + this.browserProxy.isPatternValidForType(this.site_, this.category) + .then(({isValid, reason}) => { + this.$.site.invalid = !isValid; + this.$.add.disabled = !isValid; + this.errorMessage_ = reason || ''; + }); }, /** @private */ diff --git a/chromium/chrome/browser/resources/settings/site_settings/category_default_setting.js b/chromium/chrome/browser/resources/settings/site_settings/category_default_setting.js index 3db82a17178..b3e92551446 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/category_default_setting.js +++ b/chromium/chrome/browser/resources/settings/site_settings/category_default_setting.js @@ -86,8 +86,12 @@ Polymer({ * @private */ onChangePermissionControl_: function() { - if (this.category == undefined) + if (this.category === undefined || + this.controlParams_.value === undefined || + this.subControlParams_.value === undefined) { + // Do nothing unless all dependencies are defined. return; + } // Don't override user settings with enforced settings. if (this.controlParams_.enforcement == diff --git a/chromium/chrome/browser/resources/settings/site_settings/cookie_info.js b/chromium/chrome/browser/resources/settings/site_settings/cookie_info.js index c7c27b0fd7d..bf563a3d7e6 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/cookie_info.js +++ b/chromium/chrome/browser/resources/settings/site_settings/cookie_info.js @@ -58,8 +58,7 @@ const cookieInfo = { ['created', 'channelIdCreated'] ], 'service_worker': [ - ['origin', 'serviceWorkerOrigin'], ['size', 'serviceWorkerSize'], - ['scopes', 'serviceWorkerScopes'] + ['origin', 'serviceWorkerOrigin'], ['size', 'serviceWorkerSize'] ], 'shared_worker': [['worker', 'sharedWorkerWorker'], ['name', 'sharedWorkerName']], diff --git a/chromium/chrome/browser/resources/settings/site_settings/edit_exception_dialog.html b/chromium/chrome/browser/resources/settings/site_settings/edit_exception_dialog.html index 8cbf2d630fd..3c4e9345729 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/edit_exception_dialog.html +++ b/chromium/chrome/browser/resources/settings/site_settings/edit_exception_dialog.html @@ -14,7 +14,7 @@ <div slot="body"> <cr-input label="$i18n{addSite}" value="{{origin_}}" placeholder="$i18n{addSiteExceptionPlaceholder}" - on-input="validate_" error-message="$i18n{notValidWebAddress}" + on-input="validate_" error-message="{{errorMessage_}}" invalid="[[invalid_]]" autofocus spellcheck="false"> </cr-input> </div> diff --git a/chromium/chrome/browser/resources/settings/site_settings/edit_exception_dialog.js b/chromium/chrome/browser/resources/settings/site_settings/edit_exception_dialog.js index 0ea3758d846..b0ec60219f4 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/edit_exception_dialog.js +++ b/chromium/chrome/browser/resources/settings/site_settings/edit_exception_dialog.js @@ -22,6 +22,12 @@ Polymer({ origin_: String, /** + * The localized error message to display when the pattern is invalid. + * @private + */ + errorMessage_: String, + + /** * Whether the current input is invalid. * @private */ @@ -71,9 +77,11 @@ Polymer({ return; } - this.browserProxy_.isPatternValid(this.origin_).then(isValid => { - this.invalid_ = !isValid; - }); + this.browserProxy_.isPatternValidForType(this.origin_, this.model.category) + .then(({isValid, reason}) => { + this.invalid_ = !isValid; + this.errorMessage_ = reason || ''; + }); }, /** @private */ diff --git a/chromium/chrome/browser/resources/settings/site_settings/protocol_handlers.html b/chromium/chrome/browser/resources/settings/site_settings/protocol_handlers.html index cfea2a1c20e..0e2436e56d2 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/protocol_handlers.html +++ b/chromium/chrome/browser/resources/settings/site_settings/protocol_handlers.html @@ -7,6 +7,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="../i18n_setup.html"> <link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="../site_favicon.html"> <link rel="import" href="site_settings_behavior.html"> <link rel="import" href="site_settings_prefs_browser_proxy.html"> @@ -40,8 +41,7 @@ <template is="dom-repeat" items="[[protocol.handlers]]"> <div class="list-item"> - <div class="favicon-image" style$="[[computeSiteIcon(item.host)]]"> - </div> + <site-favicon url="[[item.host]]"></site-favicon> <div class="middle" > <div class="protocol-host"> <span class="url-directionality">[[item.host]]</span> @@ -76,8 +76,7 @@ <div class="list-frame menu-content vertical-list"> <template is="dom-repeat" items="[[ignoredProtocols]]"> <div class="list-item"> - <div class="favicon-image" style$="[[computeSiteIcon(item.host)]]"> - </div> + <site-favicon url="[[item.host]]"></site-favicon> <div class="middle" > <div class="protocol-host"> <span class="url-directionality">[[item.host]]</span></div> diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_data.html b/chromium/chrome/browser/resources/settings/site_settings/site_data.html index 4fa8b7af5ac..d0e902276fe 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/site_data.html +++ b/chromium/chrome/browser/resources/settings/site_settings/site_data.html @@ -50,7 +50,8 @@ <site-data-entry id$="siteItem_[[item.site]]" actionable model="[[item]]" first$="[[!index]]" tabindex$="[[tabIndex]]" iron-list-tab-index="[[tabIndex]]" last-focused="{{lastFocused_}}" - on-click="onSiteClick_" on-remove-site="onRemoveSite_"> + list-blurred="{{listBlurred_}}" on-click="onSiteClick_" + on-remove-site="onRemoveSite_"> </site-data-entry> </template> </iron-list> diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_data.js b/chromium/chrome/browser/resources/settings/site_settings/site_data.js index 235ea12a488..24aeeafbb9c 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/site_data.js +++ b/chromium/chrome/browser/resources/settings/site_settings/site_data.js @@ -72,6 +72,9 @@ Polymer({ /** @private */ lastFocused_: Object, + + /** @private */ + listBlurred_: Boolean, }, /** @private {settings.LocalDataBrowserProxy} */ @@ -114,19 +117,6 @@ Polymer({ }, /** - * Returns the icon to use for a given site. - * @param {string} url The url of the site to fetch the icon for. - * @return {string} Value for background-image style. - * @private - */ - favicon_: function(url) { - // If the url doesn't have a scheme, inject HTTP as the scheme. Otherwise, - // the URL isn't valid and no icon will be returned. - const urlWithScheme = url.includes('://') ? url : 'http://' + url; - return cr.icon.getFavicon(urlWithScheme); - }, - - /** * @param {!Map<string, (string|Function)>} newConfig * @param {?Map<string, (string|Function)>} oldConfig * @private diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_data_entry.html b/chromium/chrome/browser/resources/settings/site_settings/site_data_entry.html index adce11d0ebc..57b51aa55ef 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/site_data_entry.html +++ b/chromium/chrome/browser/resources/settings/site_settings/site_data_entry.html @@ -6,6 +6,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="../focus_row_behavior.html"> <link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="../site_favicon.html"> <link rel="import" href="cookie_info.html"> <dom-module id="site-data-entry"> @@ -16,9 +17,7 @@ } </style> <div class="settings-box two-line site-item" focus-row-container actionable> - <div class="favicon-image" - style$="background-image: [[favicon_]]"> - </div> + <site-favicon url="[[model.site]]"></site-favicon> <div class="middle"> <span class="url-directionality">[[model.site]]</span> <div class="secondary">[[model.localData]]</div> diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_data_entry.js b/chromium/chrome/browser/resources/settings/site_settings/site_data_entry.js index 7163f97842f..31a59611f81 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/site_data_entry.js +++ b/chromium/chrome/browser/resources/settings/site_settings/site_data_entry.js @@ -18,15 +18,6 @@ Polymer({ properties: { /** @type {!CookieDataSummaryItem} */ model: Object, - - /** - * Icon to use for a given site. - * @private - */ - favicon_: { - type: String, - computed: 'computeFavicon_(model)', - }, }, /** @private {settings.LocalDataBrowserProxy} */ @@ -38,18 +29,6 @@ Polymer({ }, /** - * @return {string} - * @private - */ - computeFavicon_: function() { - const url = this.model.site; - // If the url doesn't have a scheme, inject HTTP as the scheme. Otherwise, - // the URL isn't valid and no icon will be returned. - const urlWithScheme = url.includes('://') ? url : 'http://' + url; - return cr.icon.getFavicon(urlWithScheme); - }, - - /** * Deletes all site data for this site. * @param {!Event} e * @private diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_details_permission.js b/chromium/chrome/browser/resources/settings/site_settings/site_details_permission.js index 5c8f1af077c..11d0c96d882 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/site_details_permission.js +++ b/chromium/chrome/browser/resources/settings/site_settings/site_details_permission.js @@ -32,6 +32,10 @@ Polymer({ * @private */ defaultSetting_: String, + + label: String, + + icon: String, }, observers: ['siteChanged_(site)'], diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_entry.html b/chromium/chrome/browser/resources/settings/site_settings/site_entry.html index cd3876ef5dd..d249253929c 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/site_entry.html +++ b/chromium/chrome/browser/resources/settings/site_settings/site_entry.html @@ -6,6 +6,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="../route.html"> <link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="../site_favicon.html"> <link rel="import" href="local_data_browser_proxy.html"> <link rel="import" href="site_settings_behavior.html"> @@ -48,9 +49,7 @@ <div class$="settings-box list-item [[getClassForIndex_(listIndex)]]"> <div id="toggleButton" class="start row-aligned two-line" on-click="onSiteEntryTap_" actionable aria-expanded="false"> - <div class="favicon-image" - style$="[[getSiteGroupIcon_(siteGroup)]]"> - </div> + <site-favicon url="[[getSiteGroupIcon_(siteGroup)]]"></site-favicon> <div class="middle text-elide" id="displayName"> <div class="site-representation"> <span class="url-directionality">[[displayName_]]</span> @@ -94,9 +93,7 @@ <template is="dom-repeat" items="[[siteGroup.origins]]"> <div class="settings-box list-item" on-click="onOriginTap_" actionable> - <div class="favicon-image" - style$="[[computeSiteIcon(item.origin)]]"> - </div> + <site-favicon url="[[item.origin]]"></site-favicon> <div class="site-representation middle text-elide"> <span id="originSiteRepresentation" class="url-directionality"> [[siteRepresentation_(siteGroup, index)]] diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_entry.js b/chromium/chrome/browser/resources/settings/site_settings/site_entry.js index 2b3e9833329..400689ed083 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/site_entry.js +++ b/chromium/chrome/browser/resources/settings/site_settings/site_entry.js @@ -69,12 +69,27 @@ Polymer({ /** @private {?settings.LocalDataBrowserProxy} */ localDataBrowserProxy_: null, + /** @private {?Element} */ + button_: null, + /** @override */ created: function() { this.localDataBrowserProxy_ = settings.LocalDataBrowserProxyImpl.getInstance(); }, + /** @override */ + detached: function() { + if (this.button_) + this.unlisten(this.button_, 'keydown', 'onButtonKeydown_'); + }, + + /** @param {!KeyboardEvent} e */ + onButtonKeydown_: function(e) { + if (e.shiftKey && e.key === 'Tab') + this.focus(); + }, + /** * Whether the list of origins displayed in this site-entry is a group of * eTLD+1 origins or not. @@ -120,7 +135,14 @@ Polymer({ onSiteGroupChanged_: function(siteGroup) { this.displayName_ = this.siteRepresentation_(siteGroup, -1); - if (!this.grouped_(SiteGroup)) { + // Update the button listener. + if (this.button_) + this.unlisten(this.button_, 'keydown', 'onButtonKeydown_'); + this.button_ = /** @type Element */ + (this.root.querySelector('#toggleButton *:not([hidden]) button')); + this.listen(assert(this.button_), 'keydown', 'onButtonKeydown_'); + + if (!this.grouped_(siteGroup)) { // Ensure ungrouped |siteGroup|s do not get stuck in an opened state. if (this.$.collapseChild.opened) this.toggleCollapsible_(); @@ -182,13 +204,13 @@ Polymer({ * Get an appropriate favicon that represents this group of eTLD+1 sites as a * whole. * @param {SiteGroup} siteGroup The eTLD+1 group of origins. - * @return {string} CSS to apply to show the appropriate favicon. + * @return {string} URL that is used for fetching the favicon * @private */ getSiteGroupIcon_: function(siteGroup) { // TODO(https://crbug.com/835712): Implement heuristic for finding a good // favicon. - return this.computeSiteIcon(siteGroup.origins[0].origin); + return siteGroup.origins[0].origin; }, /** @@ -370,9 +392,6 @@ Polymer({ * @private */ onFocus_: function() { - const button = /** @type Element */ - (this.root.querySelector('#toggleButton *:not([hidden]) button')); - button.focus(); - this.tabIndex = -1; + this.button_.focus(); }, }); diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_list.html b/chromium/chrome/browser/resources/settings/site_settings/site_list.html index 7cf4601cb12..78ef25506a0 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/site_list.html +++ b/chromium/chrome/browser/resources/settings/site_settings/site_list.html @@ -71,14 +71,15 @@ <site-list-entry model="[[item]]" read-only-list="[[readOnlyList]]" on-show-action-menu="onShowActionMenu_" tabindex$="[[tabIndex]]" first$="[[!index]]" iron-list-tab-index="[[tabIndex]]" - last-focused="{{lastFocused_}}" + last-focused="{{lastFocused_}}" list-blurred="{{listBlurred_}}" on-show-tooltip="onShowTooltip_"> </site-list-entry> </template> </iron-list> </div> </div> - <paper-tooltip id="tooltip" manual-mode position="top"> + <paper-tooltip id="tooltip" fit-to-visible-bounds manual-mode + position="top"> [[tooltipText_]] </paper-tooltip> <template is="dom-if" if="[[showEditExceptionDialog_]]" restamp> diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_list.js b/chromium/chrome/browser/resources/settings/site_settings/site_list.js index e814e16bdc5..cb2cfaf8a44 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/site_list.js +++ b/chromium/chrome/browser/resources/settings/site_settings/site_list.js @@ -27,6 +27,8 @@ Polymer({ value: false, }, + categoryHeader: String, + /** * The site serving as the model for the currently open action menu. * @private {?SiteException} @@ -104,6 +106,9 @@ Polymer({ lastFocused_: Object, /** @private */ + listBlurred_: Boolean, + + /** @private */ tooltipText_: String, }, @@ -240,8 +245,15 @@ Polymer({ // potential targets. Since paper-tooltip does not expose a public property // or method to update the target, the private property |_target| is // updated directly. - this.$.tooltip._target = target; - /** @type {{updatePosition: Function}} */ (this.$.tooltip).updatePosition(); + const tooltip = this.$.tooltip; + /** @type {{updatePosition: Function}} */ (tooltip).updatePosition(); + tooltip._target = target; + const parentRect = tooltip.offsetParent.getBoundingClientRect(); + const rect = tooltip.getBoundingClientRect(); + if (parentRect.left + parentRect.width < rect.left + rect.width) { + tooltip.style.right = '0'; + tooltip.style.left = 'auto'; + } const hide = () => { this.$.tooltip.hide(); target.removeEventListener('mouseleave', hide); @@ -268,6 +280,8 @@ Polymer({ if (this.category === settings.ContentSettingsTypes.NOTIFICATIONS && loadTimeData.valueExists('enableMultideviceSettings') && loadTimeData.getBoolean('enableMultideviceSettings') && + loadTimeData.valueExists('multideviceAllowedByPolicy') && + loadTimeData.getBoolean('multideviceAllowedByPolicy') && !this.androidSmsInfo_) { const multideviceSetupProxy = settings.MultiDeviceBrowserProxyImpl.getInstance(); diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_list_entry.html b/chromium/chrome/browser/resources/settings/site_settings/site_list_entry.html index 7ef79012045..5136958daaf 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/site_list_entry.html +++ b/chromium/chrome/browser/resources/settings/site_settings/site_list_entry.html @@ -10,6 +10,7 @@ <link rel="import" href="../icons.html"> <link rel="import" href="../route.html"> <link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="../site_favicon.html"> <link rel="import" href="constants.html"> <link rel="import" href="site_settings_behavior.html"> <link rel="import" href="site_settings_prefs_browser_proxy.html"> @@ -35,9 +36,7 @@ <div class="list-item" focus-row-container> <div class="settings-row" actionable$="[[enableSiteSettings_]]" on-click="onOriginTap_"> - <div class="favicon-image" - style$="[[computeSiteIcon(model.origin)]]"> - </div> + <site-favicon url="[[model.origin]]"></site-favicon> <div class="middle no-min-width"> <div class="text-elide"> <span class="url-directionality">[[model.displayName]]</span> diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_settings_behavior.html b/chromium/chrome/browser/resources/settings/site_settings/site_settings_behavior.html index e5cd47968d6..5f011e4f7b7 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/site_settings_behavior.html +++ b/chromium/chrome/browser/resources/settings/site_settings/site_settings_behavior.html @@ -5,5 +5,4 @@ <link rel="import" href="site_settings_prefs_browser_proxy.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> <link rel="import" href="chrome://resources/html/assert.html"> -<link rel="import" href="chrome://resources/html/icon.html"> <script src="site_settings_behavior.js"></script> diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_settings_behavior.js b/chromium/chrome/browser/resources/settings/site_settings/site_settings_behavior.js index 709450fa5bf..83ef46f9a4b 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/site_settings_behavior.js +++ b/chromium/chrome/browser/resources/settings/site_settings/site_settings_behavior.js @@ -91,33 +91,6 @@ const SiteSettingsBehaviorImpl = { }, /** - * Removes the wildcard prefix from a pattern string. - * @param {string} pattern The pattern to remove the wildcard from. - * @return {string} The resulting pattern. - * @private - */ - removePatternWildcard: function(pattern) { - if (pattern.startsWith('http://[*.]')) - return pattern.replace('http://[*.]', 'http://'); - else if (pattern.startsWith('https://[*.]')) - return pattern.replace('https://[*.]', 'https://'); - else if (pattern.startsWith('[*.]')) - return pattern.substring(4, pattern.length); - return pattern; - }, - - /** - * Returns the icon to use for a given site. - * @param {string} site The url of the site to fetch the icon for. - * @return {string} The background-image style with the favicon. - */ - computeSiteIcon: function(site) { - site = this.removePatternWildcard(site); - const url = this.ensureUrlHasScheme(site); - return 'background-image: ' + cr.icon.getFavicon(url); - }, - - /** * Returns true if the passed content setting is considered 'enabled'. * @param {string} setting * @return {boolean} diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js b/chromium/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js index 883d5d6774c..53f4ce8a2a3 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js +++ b/chromium/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js @@ -19,6 +19,13 @@ const ContentSettingProvider = { }; /** + * Stores information about if a content setting is valid, and why. + * @typedef {{isValid: boolean, + * reason: ?string}} + */ +let IsValid; + +/** * Stores origin information. * @typedef {{origin: string, * engagement: number, @@ -217,11 +224,14 @@ cr.define('settings', function() { isOriginValid(origin) {} /** - * Checks whether a pattern is valid. + * Checks whether a setting is valid. * @param {string} pattern The pattern to check. - * @return {!Promise<boolean>} True if the pattern is valid. + * @param {settings.ContentSettingsTypes} category What kind of setting, + * e.g. Location, Camera, Cookies, etc. + * @return {!Promise<IsValid>} Contains whether or not the pattern is + * valid for the type, and if it is invalid, the reason why. */ - isPatternValid(pattern) {} + isPatternValidForType(pattern, category) {} /** * Gets the list of default capture devices for a given type of media. List @@ -396,8 +406,8 @@ cr.define('settings', function() { } /** @override */ - isPatternValid(pattern) { - return cr.sendWithPromise('isPatternValid', pattern); + isPatternValidForType(pattern, category) { + return cr.sendWithPromise('isPatternValidForType', pattern, category); } /** @override */ diff --git a/chromium/chrome/browser/resources/settings/site_settings/usb_devices.html b/chromium/chrome/browser/resources/settings/site_settings/usb_devices.html index 770b302d6f5..1c6c79d8334 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/usb_devices.html +++ b/chromium/chrome/browser/resources/settings/site_settings/usb_devices.html @@ -4,6 +4,7 @@ <link rel="import" href="../i18n_setup.html"> <link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="../site_favicon.html"> <link rel="import" href="site_settings_behavior.html"> <link rel="import" href="site_settings_prefs_browser_proxy.html"> @@ -29,8 +30,7 @@ <div class="list-frame menu-content vertical-list"> <div class="list-item"> - <div class="favicon-image" - style$="[[computeSiteIcon(item.origin)]]"></div> + <site-favicon url="[[item.origin]]"></site-favicon> <div class="middle"> <span class="url-directionality">[[item.origin]]</span> </div> diff --git a/chromium/chrome/browser/resources/settings/site_settings/zoom_levels.html b/chromium/chrome/browser/resources/settings/site_settings/zoom_levels.html index 559e7613d7e..4342bcf2fe2 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/zoom_levels.html +++ b/chromium/chrome/browser/resources/settings/site_settings/zoom_levels.html @@ -7,6 +7,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="../i18n_setup.html"> <link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="../site_favicon.html"> <link rel="import" href="site_settings_behavior.html"> <link rel="import" href="site_settings_prefs_browser_proxy.html"> @@ -26,7 +27,7 @@ margin-top: 15px; } - .list-item .favicon-image { + .list-item site-favicon { flex-shrink: 0; } @@ -40,9 +41,7 @@ class="cr-separators" risk-selection> <template> <div class="list-item" first$="[[!index]]"> - <div class="favicon-image" - style$="[[computeSiteIcon(item.originForFavicon)]]"> - </div> + <site-favicon url="[[item.originForFavicon]]"></site-favicon> <div class="middle"> <span class="url-directionality">[[item.displayName]]</span> </div> |