diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-23 17:21:03 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-23 16:25:15 +0000 |
commit | c551f43206405019121bd2b2c93714319a0a3300 (patch) | |
tree | 1f48c30631c421fd4bbb3c36da20183c8a2ed7d7 /chromium/chrome/browser/resources/settings | |
parent | 7961cea6d1041e3e454dae6a1da660b453efd238 (diff) |
BASELINE: Update Chromium to 79.0.3945.139
Change-Id: I336b7182fab9bca80b709682489c07db112eaca5
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/chrome/browser/resources/settings')
131 files changed, 2226 insertions, 1245 deletions
diff --git a/chromium/chrome/browser/resources/settings/BUILD.gn b/chromium/chrome/browser/resources/settings/BUILD.gn index 4ba0dd05e72..beba5017d3b 100644 --- a/chromium/chrome/browser/resources/settings/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/BUILD.gn @@ -180,5 +180,5 @@ js_library("search_settings") { "//ui/webui/resources/js:cr", "//ui/webui/resources/js:search_highlight_utils", ] - externs_list = [ "$externs_path/pending.js" ] + externs_list = [ "$externs_path/pending_polymer.js" ] } diff --git a/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.html b/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.html index 078fc8f2161..86bd1584a0c 100644 --- a/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.html +++ b/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.html @@ -22,10 +22,19 @@ <settings-animated-pages id="pages" current-route="{{currentRoute}}" section="a11y" focus-config="[[focusConfig_]]"> <div route-path="default"> - <cr-link-row class="hr" id="captions" label="$i18n{captionsTitle}" - on-click="onCaptionsClick_" external$="[[captionSettingsOpensExternally_]]"> +<if expr="chromeos"> + <cr-link-row class="hr" id="subpage-trigger" + label="$i18n{manageAccessibilityFeatures}" + on-click="onManageSystemAccessibilityFeaturesTap_" + sub-label="$i18n{moreFeaturesLinkDescription}" + hidden="[[showOsSettings_]]" external> </cr-link-row> +</if> <if expr="not chromeos"> + <cr-link-row class="hr" id="captions" label="$i18n{captionsTitle}" + on-click="onCaptionsClick_" + external$="[[captionSettingsOpensExternally_]]"> + </cr-link-row> <settings-toggle-button id="a11yImageLabels" hidden$="[[!showAccessibilityLabelsSetting_]]" @@ -36,7 +45,7 @@ </settings-toggle-button> </if> <if expr="chromeos"> - <template is="dom-if" if="[[pageVisibility.webstoreLink]]"> + <template is="dom-if" if="[[showOsSettings_]]"> <settings-toggle-button id="a11yImageLabels" hidden$="[[!showAccessibilityLabelsSetting_]]" @@ -58,7 +67,7 @@ </if> <cr-link-row class="hr" label="$i18n{moreFeaturesLink}" on-click="onMoreFeaturesLinkClick_" sub-label="$i18n{a11yWebStore}" - hidden="[[pageVisibility.webstoreLink]]" external> + hidden="[[showOsSettings_]]" external> </cr-link-row> </div> <if expr="not is_macosx"> @@ -73,7 +82,17 @@ </template> </if> <if expr="chromeos"> - <template is="dom-if" if="[[pageVisibility.webstoreLink]]"> + <template is="dom-if" if="[[showCaptionSettings_]]"> + <template is="dom-if" route-path="/manageAccessibility/captions"> + <settings-subpage + associated-control="[[$$('#subpage-trigger')]]" + page-title="$i18n{captionsTitle}"> + <settings-captions prefs="{{prefs}}"> + </settings-captions> + </settings-subpage> + </template> + </template> + <template is="dom-if" if="[[showOsSettings_]]"> <template is="dom-if" route-path="/manageAccessibility"> <settings-subpage associated-control="[[$$('#subpage-trigger')]]" diff --git a/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.js b/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.js index 31045680975..6b24c8fa880 100644 --- a/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.js +++ b/chromium/chrome/browser/resources/settings/a11y_page/a11y_page.js @@ -68,6 +68,17 @@ Polymer({ }, /** + * Whether to show OS settings. + * @private {boolean} + */ + showOsSettings_: { + type: Boolean, + value: function() { + return loadTimeData.getBoolean('showOSSettings'); + }, + }, + + /** * Whether the caption settings link opens externally. * @private {boolean} */ @@ -86,20 +97,6 @@ Polymer({ return opensExternally; }, }, - - // <if expr="chromeos"> - /** - * Whether to show experimental accessibility features. - * Only used in Chrome OS. - * @private {boolean} - */ - showExperimentalFeatures_: { - type: Boolean, - value: function() { - return loadTimeData.getBoolean('showExperimentalA11yFeatures'); - }, - }, - // </if> }, /** @override */ @@ -136,6 +133,11 @@ Polymer({ onManageAccessibilityFeaturesTap_: function() { settings.navigateTo(settings.routes.MANAGE_ACCESSIBILITY); }, + + /** @private */ + onManageSystemAccessibilityFeaturesTap_: function() { + window.location.href = 'chrome://os-settings/manageAccessibility'; + }, // </if> /** private */ 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 7f290fc3df3..ccc488cb561 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 @@ -80,31 +80,35 @@ label="$i18n{screenMagnifierLabel}" disabled="[[prefs.ash.docked_magnifier.enabled.value]]"> </settings-toggle-button> - <div class="settings-box continuation"> - <div class="start sub-item settings-box-text"> - $i18n{screenMagnifierZoomLabel} + <template is="dom-if" if="[[prefs.settings.a11y.screen_magnifier.value]]"> + <div class="settings-box continuation"> + <div class="start sub-item settings-box-text"> + $i18n{screenMagnifierZoomLabel} + </div> + <settings-dropdown-menu label="$i18n{screenMagnifierZoomLabel}" + pref="{{prefs.settings.a11y.screen_magnifier_scale}}" + menu-options="[[screenMagnifierZoomOptions_]]" + disabled="[[!prefs.settings.a11y.screen_magnifier.value]]"> + </settings-dropdown-menu> </div> - <settings-dropdown-menu label="$i18n{screenMagnifierZoomLabel}" - pref="{{prefs.settings.a11y.screen_magnifier_scale}}" - menu-options="[[screenMagnifierZoomOptions_]]" - disabled="[[!prefs.settings.a11y.screen_magnifier.value]]"> - </settings-dropdown-menu> - </div> + </template> <settings-toggle-button pref="{{prefs.ash.docked_magnifier.enabled}}" label="$i18n{dockedMagnifierLabel}" disabled="[[prefs.settings.a11y.screen_magnifier.value]]"> </settings-toggle-button> - <div class="settings-box continuation"> - <div class="start sub-item settings-box-text"> - $i18n{dockedMagnifierZoomLabel} + <template is="dom-if" if="[[prefs.ash.docked_magnifier.enabled.value]]"> + <div class="settings-box continuation"> + <div class="start sub-item settings-box-text"> + $i18n{dockedMagnifierZoomLabel} + </div> + <settings-dropdown-menu label="$i18n{dockedMagnifierZoomLabel}" + pref="{{prefs.ash.docked_magnifier.scale}}" + menu-options="[[screenMagnifierZoomOptions_]]" + disabled="[[!prefs.ash.docked_magnifier.enabled.value]]"> + </settings-dropdown-menu> </div> - <settings-dropdown-menu label="$i18n{dockedMagnifierZoomLabel}" - pref="{{prefs.ash.docked_magnifier.scale}}" - menu-options="[[screenMagnifierZoomOptions_]]" - disabled="[[!prefs.ash.docked_magnifier.enabled.value]]"> - </settings-dropdown-menu> - </div> + </template> <cr-link-row class="hr" label="$i18n{displaySettingsTitle}" on-click="onDisplayTap_" sub-label="$i18n{displaySettingsDescription}" embedded></cr-link-row> @@ -218,12 +222,14 @@ on-click="onMouseTap_" sub-label="$i18n{mouseSettingsDescription}" embedded></cr-link-row> - <h2>$i18n{audioHeading}</h2> - <settings-toggle-button class="first" + <h2>$i18n{audioAndCaptionsHeading}</h2> + <cr-link-row class="first" label="$i18n{captionsTitle}" + on-click="onCaptionsClick_"></cr-link-row> + <settings-toggle-button pref="{{prefs.settings.a11y.mono_audio}}" label="$i18n{monoAudioLabel}"> </settings-toggle-button> - <settings-toggle-button id="startupSoundEnabled" class="first" + <settings-toggle-button id="startupSoundEnabled" pref=" " on-change="toggleStartupSoundEnabled_" label="$i18n{startupSoundLabel}"> 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 5365829d90f..8828b4fee1a 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 @@ -98,17 +98,6 @@ Polymer({ }, }, - /** - * Whether to show experimental accessibility features. - * @private {boolean} - */ - showExperimentalFeatures_: { - type: Boolean, - value: function() { - return loadTimeData.getBoolean('showExperimentalA11yFeatures'); - }, - }, - showExperimentalSwitchAccess_: { type: Boolean, value: function() { @@ -206,6 +195,11 @@ Polymer({ }, /** @private */ + onCaptionsClick_: function() { + settings.navigateTo(settings.routes.MANAGE_CAPTION_SETTINGS); + }, + + /** @private */ onSelectToSpeakSettingsTap_: function() { chrome.send('showSelectToSpeakSettings'); }, 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 d4781a4d1b7..cdb845116be 100644 --- a/chromium/chrome/browser/resources/settings/about_page/about_page.js +++ b/chromium/chrome/browser/resources/settings/about_page/about_page.js @@ -233,8 +233,8 @@ Polymer({ this.regulatoryInfo_ = info; }); - this.aboutBrowserProxy_.getHasEndOfLife().then(result => { - this.hasEndOfLife_ = result; + this.aboutBrowserProxy_.getEndOfLifeInfo().then(result => { + this.hasEndOfLife_ = !!result.hasEndOfLife; }); this.aboutBrowserProxy_.getEnabledReleaseNotes().then(result => { diff --git a/chromium/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js b/chromium/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js index d1f1373396e..1d5eeb7273d 100644 --- a/chromium/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js +++ b/chromium/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js @@ -27,20 +27,19 @@ let ChannelInfo; /** * @typedef {{ - * arcVersion: string, - * osFirmware: string, - * osVersion: string, + * version: (string|undefined), + * size: (string|undefined), * }} */ -let VersionInfo; +let AboutPageUpdateInfo; /** * @typedef {{ - * version: (string|undefined), - * size: (string|undefined), + * hasEndOfLife: (boolean|undefined), + * eolMessageWithMonthAndYear: (string|undefined), * }} */ -let AboutPageUpdateInfo; +let EndOfLifeInfo; /** * Enumeration of all possible browser channels. @@ -200,18 +199,15 @@ cr.define('settings', function() { /** @return {!Promise<!ChannelInfo>} */ getChannelInfo() {} - /** @return {!Promise<!VersionInfo>} */ - getVersionInfo() {} - /** @return {!Promise<?RegulatoryInfo>} */ getRegulatoryInfo() {} /** * Checks if the device has reached end-of-life status and will no longer * receive updates. - * @return {!Promise<boolean>} + * @return {!Promise<!EndOfLifeInfo>} */ - getHasEndOfLife() {} + getEndOfLifeInfo() {} /** * Request TPM firmware update status from the browser. It results in one or @@ -309,18 +305,13 @@ cr.define('settings', function() { } /** @override */ - getVersionInfo() { - return cr.sendWithPromise('getVersionInfo'); - } - - /** @override */ getRegulatoryInfo() { return cr.sendWithPromise('getRegulatoryInfo'); } /** @override */ - getHasEndOfLife() { - return cr.sendWithPromise('getHasEndOfLife'); + getEndOfLifeInfo() { + return cr.sendWithPromise('getEndOfLifeInfo'); } /** @override */ 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 a974334455c..78ac464caad 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 @@ -19,7 +19,7 @@ <div slot="title">$i18n{aboutChangeChannel}</div> <div slot="body"> <!-- TODO(dbeam): this can be policy-controlled. Show this in the UI. - https://www.chromium.org/administrators/policy-list-3#ChromeOsReleaseChannel + https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ChromeOsReleaseChannel --> <cr-radio-group on-selected-changed="onChannelSelectionChanged_"> <cr-radio-button name="[[browserChannelEnum_.STABLE]]"> diff --git a/chromium/chrome/browser/resources/settings/about_page/detailed_build_info.html b/chromium/chrome/browser/resources/settings/about_page/detailed_build_info.html index 2369486bc71..fa1ae5f812e 100644 --- a/chromium/chrome/browser/resources/settings/about_page/detailed_build_info.html +++ b/chromium/chrome/browser/resources/settings/about_page/detailed_build_info.html @@ -24,15 +24,6 @@ width: 100%; } </style> - <div class="settings-box two-line single-column"> - <div>$i18n{aboutPlatformLabel}</div> - <div class="secondary" id="osVersion">[[versionInfo_.osVersion]]</div> - </div> - <div class="settings-box two-line single-column" - hidden$="[[!shouldShowVersion_(versionInfo_.osFirmware)]]"> - <div>$i18n{aboutFirmwareLabel}</div> - <div class="secondary" id="osFirmware">[[versionInfo_.osFirmware]]</div> - </div> <div class="settings-box two-line"> <div class="start"> <div>$i18n{aboutChannelLabel}</div> @@ -57,29 +48,17 @@ </settings-channel-switcher-dialog> </template> </div> - <div class="settings-box two-line single-column" - hidden$="[[!shouldShowVersion_(versionInfo_.arcVersion)]]"> - <div>$i18n{aboutArcVersionLabel}</div> - <div class="secondary" id="arcVersion">[[versionInfo_.arcVersion]]</div> - </div> - <div class="settings-box two-line single-column"> - <div>V8</div> - <div class="secondary">$i18n{aboutJsEngineVersion}</div> - </div> - <div class="settings-box two-line single-column"> - <div>$i18n{aboutUserAgentLabel}</div> - <div class="secondary">$i18n{aboutUserAgent}</div> - </div> - <div class="settings-box two-line single-column"> - <div>$i18n{aboutCommandLineLabel}</div> - <div id="command-line" class="secondary"> - [[i18n('aboutCommandLine')]] + <div id="endOfLifeSectionContainer" + class="settings-box two-line single-column" + hidden="[[!eolMessageWithMonthAndYear]]"> + <div>$i18n{aboutEndOfLifeTitle}</div> + <div class="secondary" inner-h-t-m-l="[[eolMessageWithMonthAndYear]]"> </div> </div> - <div class="settings-box two-line single-column"> - <div>$i18n{aboutBuildDateLabel}</div> - <div class="secondary">$i18n{aboutBuildDate}</div> - </div> + <cr-link-row class="hr" label="$i18n{aboutBuildDetailsTitle}" + on-click="onBuildDetailsTap_" external> + </cr-link-row> + <div class="hr"></div> </template> <script src="detailed_build_info.js"></script> </dom-module> diff --git a/chromium/chrome/browser/resources/settings/about_page/detailed_build_info.js b/chromium/chrome/browser/resources/settings/about_page/detailed_build_info.js index 18ad3b217ed..ba47cf969b4 100644 --- a/chromium/chrome/browser/resources/settings/about_page/detailed_build_info.js +++ b/chromium/chrome/browser/resources/settings/about_page/detailed_build_info.js @@ -13,9 +13,6 @@ Polymer({ behaviors: [I18nBehavior], properties: { - /** @private {!VersionInfo} */ - versionInfo_: Object, - /** @private */ currentlyOnChannelText_: String, @@ -24,17 +21,17 @@ Polymer({ /** @private */ canChangeChannel_: Boolean, + + eolMessageWithMonthAndYear: { + type: String, + value: '', + }, }, /** @override */ ready: function() { const browserProxy = settings.AboutPageBrowserProxyImpl.getInstance(); browserProxy.pageReady(); - - browserProxy.getVersionInfo().then(versionInfo => { - this.versionInfo_ = versionInfo; - }); - this.updateChannelInfo_(); }, @@ -51,15 +48,6 @@ Polymer({ }, /** - * @param {string} version - * @return {boolean} - * @private - */ - shouldShowVersion_: function(version) { - return version.length > 0; - }, - - /** * @param {boolean} canChangeChannel * @return {string} * @private @@ -93,6 +81,15 @@ Polymer({ this.showChannelSwitcherDialog_ = true; }, + /** + * @param {!Event} e + * @private + */ + onBuildDetailsTap_: function(e) { + e.preventDefault(); + window.open('chrome://version'); + }, + /** @private */ onChannelSwitcherDialogClosed_: function() { this.showChannelSwitcherDialog_ = false; diff --git a/chromium/chrome/browser/resources/settings/android_apps_page/android_apps_page.html b/chromium/chrome/browser/resources/settings/android_apps_page/android_apps_page.html index 39116e40833..91ab92092e9 100644 --- a/chromium/chrome/browser/resources/settings/android_apps_page/android_apps_page.html +++ b/chromium/chrome/browser/resources/settings/android_apps_page/android_apps_page.html @@ -13,6 +13,11 @@ <link rel="import" href="android_apps_browser_proxy.html"> <link rel="import" href="android_apps_subpage.html"> +<!-- Changes to this file should be reflected in + ../chromeos/os_apps_page/os_apps_page.html. + TODO(crbug.com/1006152): This file should be deleted once the split-settings + flag has been removed. --> + <dom-module id="settings-android-apps-page"> <template> <style include="settings-shared"></style> diff --git a/chromium/chrome/browser/resources/settings/android_apps_page/android_apps_subpage.html b/chromium/chrome/browser/resources/settings/android_apps_page/android_apps_subpage.html index b0d86e21b93..92340b7c23c 100644 --- a/chromium/chrome/browser/resources/settings/android_apps_page/android_apps_subpage.html +++ b/chromium/chrome/browser/resources/settings/android_apps_page/android_apps_subpage.html @@ -18,13 +18,21 @@ <template is="dom-if" if="[[androidAppsInfo.settingsAppAvailable]]" restamp> <cr-link-row id="manageApps" icon-class="icon-external" label="$i18n{androidAppsManageApps}" - on-click="onManageAndroidAppsTap_"> + on-click="onManageAndroidAppsTap_" external> </cr-link-row> </template> - <template is="dom-if" if="[[allowRemove_(prefs.arc.enabled.*)]]"> - <cr-link-row id="remove" class="hr" on-click="onRemoveTap_" - label="$i18n{androidAppsRemove}"></cr-link-row> + <!-- Use 'restamp' so tests can check if the row exists. --> + <template is="dom-if" if="[[allowRemove_(prefs.arc.enabled.*)]]" restamp> + <div id="remove" class="settings-box"> + <div id="androidRemoveLabel" class="start"> + $i18n{androidAppsRemove} + </div> + <cr-button on-click="onRemoveTap_" + aria-labelledby="androidRemoveLabel"> + $i18n{androidAppsRemoveButton} + </cr-button> + </div> </template> <!-- Confirm disable android apps dialog --> diff --git a/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.js b/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.js index 2551cf3b191..582ae814c9e 100644 --- a/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.js +++ b/chromium/chrome/browser/resources/settings/appearance_page/appearance_page.js @@ -339,7 +339,7 @@ Polymer({ }, /** - * @see content::ZoomValuesEqual(). + * @see blink::PageZoomValuesEqual(). * @param {number} zoom1 * @param {number} zoom2 * @return {boolean} diff --git a/chromium/chrome/browser/resources/settings/autofill_page/autofill_section.js b/chromium/chrome/browser/resources/settings/autofill_page/autofill_section.js index 652a4aa59c3..ba786243f76 100644 --- a/chromium/chrome/browser/resources/settings/autofill_page/autofill_section.js +++ b/chromium/chrome/browser/resources/settings/autofill_page/autofill_section.js @@ -13,16 +13,18 @@ */ class AutofillManager { /** - * Add an observer to the list of addresses. - * @param {function(!Array<!AutofillManager.AddressEntry>):void} listener + * Add an observer to the list of personal data. + * @param {function(!Array<!AutofillManager.AddressEntry>, + * !Array<!PaymentsManager.CreditCardEntry>):void} listener */ - addAddressListChangedListener(listener) {} + setPersonalDataManagerListener(listener) {} /** - * Remove an observer from the list of addresses. - * @param {function(!Array<!AutofillManager.AddressEntry>):void} listener + * Remove an observer from the list of personal data. + * @param {function(!Array<!AutofillManager.AddressEntry>, + * !Array<!PaymentsManager.CreditCardEntry>):void} listener */ - removeAddressListChangedListener(listener) {} + removePersonalDataManagerListener(listener) {} /** * Request the list of addresses. @@ -49,13 +51,13 @@ AutofillManager.AddressEntry; */ class AutofillManagerImpl { /** @override */ - addAddressListChangedListener(listener) { - chrome.autofillPrivate.onAddressListChanged.addListener(listener); + setPersonalDataManagerListener(listener) { + chrome.autofillPrivate.onPersonalDataChanged.addListener(listener); } /** @override */ - removeAddressListChangedListener(listener) { - chrome.autofillPrivate.onAddressListChanged.removeListener(listener); + removePersonalDataManagerListener(listener) { + chrome.autofillPrivate.onPersonalDataChanged.removeListener(listener); } /** @override */ @@ -117,21 +119,30 @@ Polymer({ autofillManager_: null, /** - * @type {?function(!Array<!AutofillManager.AddressEntry>)} + * @type {?function(!Array<!AutofillManager.AddressEntry>, + * !Array<!PaymentsManager.CreditCardEntry>)} * @private */ - setAddressesListener_: null, + setPersonalDataListener_: null, /** @override */ attached: function() { // Create listener functions. /** @type {function(!Array<!AutofillManager.AddressEntry>)} */ - const setAddressesListener = list => { - this.addresses = list; + const setAddressesListener = addressList => { + this.addresses = addressList; + }; + + /** + * @type {function(!Array<!AutofillManager.AddressEntry>, + * !Array<!PaymentsManager.CreditCardEntry>)} + */ + const setPersonalDataListener = (addressList, cardList) => { + this.addresses = addressList; }; // Remember the bound reference in order to detach. - this.setAddressesListener_ = setAddressesListener; + this.setPersonalDataListener_ = setPersonalDataListener; // Set the managers. These can be overridden by tests. this.autofillManager_ = AutofillManagerImpl.getInstance(); @@ -140,7 +151,8 @@ Polymer({ this.autofillManager_.getAddressList(setAddressesListener); // Listen for changes. - this.autofillManager_.addAddressListChangedListener(setAddressesListener); + this.autofillManager_.setPersonalDataManagerListener( + setPersonalDataListener); // Record that the user opened the address settings. chrome.metricsPrivate.recordUserAction('AutofillAddressesViewed'); @@ -148,9 +160,12 @@ Polymer({ /** @override */ detached: function() { - this.autofillManager_.removeAddressListChangedListener( - /** @type {function(!Array<!AutofillManager.AddressEntry>)} */ ( - this.setAddressesListener_)); + this.autofillManager_.removePersonalDataManagerListener( + /** + @type {function(!Array<!AutofillManager.AddressEntry>, + !Array<!PaymentsManager.CreditCardEntry>)} + */ + (this.setPersonalDataListener_)); }, /** diff --git a/chromium/chrome/browser/resources/settings/autofill_page/password_list_item.html b/chromium/chrome/browser/resources/settings/autofill_page/password_list_item.html index 847f192031d..922166b2951 100644 --- a/chromium/chrome/browser/resources/settings/autofill_page/password_list_item.html +++ b/chromium/chrome/browser/resources/settings/autofill_page/password_list_item.html @@ -50,8 +50,7 @@ } </style> <div class="list-item" focus-row-container> - <div class="website-column no-min-width" - title="[[item.entry.urls.link]]"> + <div class="website-column no-min-width"> <site-favicon url="[[item.entry.urls.link]]"></site-favicon> <a id="originUrl" target="_blank" class="no-min-width" href="[[item.entry.urls.link]]" @@ -64,14 +63,17 @@ </a> </div> <input id="username" class="username-column password-field" - readonly tabindex="-1" value="[[item.entry.username]]"> + aria-label="$i18n{editPasswordUsernameLabel}" + readonly value="[[item.entry.username]]" + focus-row-control focus-type="username"> <div class="password-column"> <template is="dom-if" if="[[!item.entry.federationText]]"> <input id="password" aria-label=$i18n{editPasswordPasswordLabel} type="[[getPasswordInputType_(item.password)]]" on-click="onReadonlyInputTap_" class="password-field" readonly disabled$="[[!item.password]]" - value="[[getPassword_(item.password)]]"> + value="[[getPassword_(item.password)]]" + focus-row-control focus-type="passwordField"> <cr-icon-button id="showPasswordButton" class$="[[getIconClass_(item.password)]]" on-click="onShowPasswordButtonTap_" diff --git a/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.html b/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.html index 58e376e7433..2f569d3e4dc 100644 --- a/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.html +++ b/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.html @@ -10,12 +10,14 @@ <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/html/list_property_update_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/polymer/v1_0/iron-a11y-announcer/iron-a11y-announcer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html"> -<link rel="import" href="../controls/settings_toggle_button.html"> <link rel="import" href="../controls/extension_controlled_indicator.html"> +<link rel="import" href="../controls/settings_toggle_button.html"> <link rel="import" href="../global_scroll_target_behavior.html"> +<link rel="import" href="../people_page/sync_browser_proxy.html"> <link rel="import" href="../prefs/prefs.html"> <link rel="import" href="../prefs/prefs_behavior.html"> <link rel="import" href="../settings_shared_css.html"> @@ -73,16 +75,6 @@ </extension-controlled-indicator> </div> </template> - <settings-toggle-button id="passwordsLeakDetectionCheckbox" - pref="{{prefs.profile.password_manager_leak_detection}}" - checked="[[getCheckedLeakDetection_( - userSignedIn_, prefs.profile.password_manager_leak_detection)]]" - label="$i18n{passwordsLeakDetectionLabel}" - sub-label="[[getPasswordsLeakDetectionSubLabel_( - userSignedIn_, prefs.profile.password_manager_leak_detection)]]" - hidden$="[[!passwordsLeakDetectionEnabled_]]" - disabled="[[!userSignedIn_]]"> - </settings-toggle-button> <settings-toggle-button id="autosigninCheckbox" pref="{{prefs.credentials_enable_autosignin}}" label="$i18n{passwordsAutosigninLabel}" @@ -108,7 +100,8 @@ </div> <div class="list-frame"> <div id="savedPasswordsHeaders" class="list-item column-header" - hidden$="[[!hasSome_(savedPasswords, savedPasswords.splices)]]"> + hidden$="[[!hasSome_(savedPasswords, savedPasswords.splices)]]" + aria-hidden="true"> <div class="website-column">$i18n{editPasswordWebsiteLabel}</div> <div class="username-column"> $i18n{editPasswordUsernameLabel} diff --git a/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.js b/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.js index a98d69646d4..0eabb41138a 100644 --- a/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.js +++ b/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.js @@ -102,12 +102,6 @@ Polymer({ }, /** @private */ - passwordsLeakDetectionEnabled_: { - type: Boolean, - value: loadTimeData.getBoolean('passwordsLeakDetectionEnabled'), - }, - - /** @private */ showExportPasswords_: { type: Boolean, computed: 'hasPasswords_(savedPasswords.splices)', @@ -125,23 +119,12 @@ Polymer({ /** @private */ showPasswordEditDialog_: Boolean, - // <if expr="not chromeos"> - /** @private {Array<!settings.StoredAccount>} */ - storedAccounts_: Object, - // </if> - /** @private {settings.SyncPrefs} */ syncPrefs_: Object, /** @private {settings.SyncStatus} */ syncStatus_: Object, - /** @private */ - userSignedIn_: { - type: Boolean, - computed: 'computeUserSignedIn_(syncStatus_, storedAccounts_)', - }, - /** Filter on the saved passwords and exceptions. */ filter: { type: String, @@ -266,13 +249,6 @@ Polymer({ syncBrowserProxy.getSyncStatus().then(syncStatusChanged); this.addWebUIListener('sync-status-changed', syncStatusChanged); - // <if expr="not chromeos"> - const storedAccountsChanged = storedAccounts => this.storedAccounts_ = - storedAccounts; - syncBrowserProxy.getStoredAccounts().then(storedAccountsChanged); - this.addWebUIListener('stored-accounts-updated', storedAccountsChanged); - // </if> - const syncPrefsChanged = syncPrefs => this.syncPrefs_ = syncPrefs; syncBrowserProxy.sendSyncPrefsChanged(); this.addWebUIListener('sync-prefs-changed', syncPrefsChanged); @@ -363,24 +339,6 @@ Polymer({ }, /** - * @return {boolean} - * @private - */ - computeUserSignedIn_: function() { - return (!!this.syncStatus_ && !!this.syncStatus_.signedIn) || - (!!this.storedAccounts_ && this.storedAccounts_.length > 0); - }, - - /** - * @return {boolean} - * @private - */ - getCheckedLeakDetection_: function() { - return this.userSignedIn_ && - !!this.getPref('profile.password_manager_leak_detection').value; - }, - - /** * @param {string} filter * @return {!Array<!PasswordManagerProxy.UiEntryWithPassword>} * @private @@ -396,20 +354,6 @@ Polymer({ }, /** - * @return {string} - * @private - */ - getPasswordsLeakDetectionSubLabel_: function() { - if (this.userSignedIn_) { - return this.i18n('passwordsLeakDetectionSignedInDescription'); - } - if (this.getPref('profile.password_manager_leak_detection').value) { - return this.i18n('passwordsLeakDetectionSignedOutEnabledDescription'); - } - return this.i18n('passwordsLeakDetectionSignedOutDisabledDescription'); - }, - - /** * @param {string} filter * @return {function(!chrome.passwordsPrivate.ExceptionEntry): boolean} * @private @@ -426,7 +370,9 @@ Polymer({ onMenuRemovePasswordTap_: function() { this.passwordManager_.removeSavedPassword( this.activePassword.item.entry.id); - cr.toastManager.getInstance().show(this.i18n('passwordDeleted'), false); + cr.toastManager.getInstance().show( + this.i18n('passwordDeleted'), + /* showUndo */ true); /** @type {CrActionMenuElement} */ (this.$.menu).close(); }, @@ -544,6 +490,6 @@ Polymer({ showImportOrExportPasswords_: function( showExportPasswords, showImportPasswords) { return showExportPasswords || showImportPasswords; - } + }, }); })(); diff --git a/chromium/chrome/browser/resources/settings/autofill_page/payments_section.html b/chromium/chrome/browser/resources/settings/autofill_page/payments_section.html index 5836b23e617..2109d3395fd 100644 --- a/chromium/chrome/browser/resources/settings/autofill_page/payments_section.html +++ b/chromium/chrome/browser/resources/settings/autofill_page/payments_section.html @@ -42,6 +42,20 @@ pref="{{prefs.autofill.credit_card_enabled}}"> </settings-toggle-button> <template is="dom-if" + if="[[shouldShowFidoToggle_( + prefs.autofill.credit_card_enabled.value, + userIsFidoVerifiable_)]]"> + <settings-toggle-button + class="settings-box first" + id="autofillCreditCardFIDOAuthToggle" + aria-label="$i18n{creditCards}" no-extension-indicator + label="$i18n{enableCreditCardFIDOAuthLabel}" + sub-label="$i18n{enableCreditCardFIDOAuthSublabel}" + pref="{{prefs.autofill.credit_card_fido_auth_enabled}}" + on-change="setFIDOAuthenticationEnabledState_"> + </settings-toggle-button> + </template> + <template is="dom-if" if="[[prefs.autofill.credit_card_enabled.extensionId]]"> <div class="settings-box continuation"> <extension-controlled-indicator class="start" diff --git a/chromium/chrome/browser/resources/settings/autofill_page/payments_section.js b/chromium/chrome/browser/resources/settings/autofill_page/payments_section.js index 03d51d23ebf..0c71a4b46c6 100644 --- a/chromium/chrome/browser/resources/settings/autofill_page/payments_section.js +++ b/chromium/chrome/browser/resources/settings/autofill_page/payments_section.js @@ -13,16 +13,18 @@ */ class PaymentsManager { /** - * Add an observer to the list of credit cards. - * @param {function(!Array<!PaymentsManager.CreditCardEntry>):void} listener + * Add an observer to the list of personal data. + * @param {function(!Array<!AutofillManager.AddressEntry>, + * !Array<!PaymentsManager.CreditCardEntry>):void} listener */ - addCreditCardListChangedListener(listener) {} + setPersonalDataManagerListener(listener) {} /** - * Remove an observer from the list of credit cards. - * @param {function(!Array<!PaymentsManager.CreditCardEntry>):void} listener + * Remove an observer from the list of personal data. + * @param {function(!Array<!AutofillManager.AddressEntry>, + * !Array<!PaymentsManager.CreditCardEntry>):void} listener */ - removeCreditCardListChangedListener(listener) {} + removePersonalDataManagerListener(listener) {} /** * Request the list of credit cards. @@ -51,6 +53,11 @@ class PaymentsManager { * Logs that the server cards edit link was clicked. */ logServerCardLinkClicked() {} + + /** + * Enables FIDO authentication for card unmasking. + */ + setCreditCardFIDOAuthEnabledState(enabled) {} } /** @typedef {chrome.autofillPrivate.CreditCardEntry} */ @@ -62,13 +69,13 @@ PaymentsManager.CreditCardEntry; */ class PaymentsManagerImpl { /** @override */ - addCreditCardListChangedListener(listener) { - chrome.autofillPrivate.onCreditCardListChanged.addListener(listener); + setPersonalDataManagerListener(listener) { + chrome.autofillPrivate.onPersonalDataChanged.addListener(listener); } /** @override */ - removeCreditCardListChangedListener(listener) { - chrome.autofillPrivate.onCreditCardListChanged.removeListener(listener); + removePersonalDataManagerListener(listener) { + chrome.autofillPrivate.onPersonalDataChanged.removeListener(listener); } /** @override */ @@ -100,6 +107,11 @@ class PaymentsManagerImpl { logServerCardLinkClicked() { chrome.autofillPrivate.logServerCardLinkClicked(); } + + /** @override */ + setCreditCardFIDOAuthEnabledState(enabled) { + chrome.autofillPrivate.setCreditCardFIDOAuthEnabledState(enabled); + } } cr.addSingletonGetter(PaymentsManagerImpl); @@ -126,6 +138,18 @@ Polymer({ }, /** + * Set to true if user can be verified through FIDO authentication. + * @private + */ + userIsFidoVerifiable_: { + type: Boolean, + value: function() { + return loadTimeData.getBoolean( + 'fidoAuthenticationAvailableForAutofill'); + }, + }, + + /** * The model for any credit card related action menus or dialogs. * @private {?chrome.autofillPrivate.CreditCardEntry} */ @@ -170,21 +194,39 @@ Polymer({ PaymentsManager_: null, /** - * @type {?function(!Array<!PaymentsManager.CreditCardEntry>)} + * @type {?function(!Array<!AutofillManager.AddressEntry>, + * !Array<!PaymentsManager.CreditCardEntry>)} * @private */ - setCreditCardsListener_: null, + setPersonalDataListener_: null, /** @override */ attached: function() { // Create listener function. /** @type {function(!Array<!PaymentsManager.CreditCardEntry>)} */ - const setCreditCardsListener = list => { - this.creditCards = list; + const setCreditCardsListener = cardList => { + this.creditCards = cardList; + }; + + // Update |userIsFidoVerifiable_| based on the availability of a platform + // authenticator. + if (window.PublicKeyCredential) { + window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable() + .then(r => { + this.userIsFidoVerifiable_ = this.userIsFidoVerifiable_ && r; + }); + } + + /** + * @type {function(!Array<!AutofillManager.AddressEntry>, + * !Array<!PaymentsManager.CreditCardEntry>)} + */ + const setPersonalDataListener = (addressList, cardList) => { + this.creditCards = cardList; }; // Remember the bound reference in order to detach. - this.setCreditCardsListener_ = setCreditCardsListener; + this.setPersonalDataListener_ = setPersonalDataListener; // Set the managers. These can be overridden by tests. this.paymentsManager_ = PaymentsManagerImpl.getInstance(); @@ -193,8 +235,8 @@ Polymer({ this.paymentsManager_.getCreditCardList(setCreditCardsListener); // Listen for changes. - this.paymentsManager_.addCreditCardListChangedListener( - setCreditCardsListener); + this.paymentsManager_.setPersonalDataManagerListener( + setPersonalDataListener); // Record that the user opened the payments settings. chrome.metricsPrivate.recordUserAction('AutofillCreditCardsViewed'); @@ -202,9 +244,12 @@ Polymer({ /** @override */ detached: function() { - this.paymentsManager_.removeCreditCardListChangedListener( - /** @type {function(!Array<!PaymentsManager.CreditCardEntry>)} */ ( - this.setCreditCardsListener_)); + this.paymentsManager_.removePersonalDataManagerListener( + /** + @type {function(!Array<!AutofillManager.AddressEntry>, + !Array<!PaymentsManager.CreditCardEntry>)} + */ + (this.setPersonalDataListener_)); }, /** @@ -311,6 +356,25 @@ Polymer({ }, /** + * @param {boolean} creditCardEnabled + * @return {boolean} Whether or not the user is verifiable through FIDO + * authentication. + * @private + */ + shouldShowFidoToggle_: function(creditCardEnabled, userIsFidoVerifiable) { + return creditCardEnabled && userIsFidoVerifiable; + }, + + /** + * Listens for the enable-authentication event, and calls the private API. + * @private + */ + setFIDOAuthenticationEnabledState_: function() { + this.paymentsManager_.setCreditCardFIDOAuthEnabledState( + this.$$('#autofillCreditCardFIDOAuthToggle').checked); + }, + + /** * @param {!Array<!PaymentsManager.CreditCardEntry>} creditCards * @param {boolean} creditCardEnabled * @return {boolean} Whether to show the migration button. diff --git a/chromium/chrome/browser/resources/settings/basic_page/BUILD.gn b/chromium/chrome/browser/resources/settings/basic_page/BUILD.gn index ab89a35dd33..5cbc3c1c317 100644 --- a/chromium/chrome/browser/resources/settings/basic_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/basic_page/BUILD.gn @@ -23,5 +23,5 @@ js_library("basic_page") { "//ui/webui/resources/js:load_time_data", "//ui/webui/resources/js:web_ui_listener_behavior", ] - externs_list = [ "$externs_path/pending.js" ] + externs_list = [ "$externs_path/pending_polymer.js" ] } 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 46deb873d7d..7c40d63c9d1 100644 --- a/chromium/chrome/browser/resources/settings/basic_page/basic_page.html +++ b/chromium/chrome/browser/resources/settings/basic_page/basic_page.html @@ -119,8 +119,7 @@ $i18nRaw{osSettingsBannerText} </div> <cr-icon-button class="icon-clear" - id="hideOSSettings" - aria-label="$i18n{clear}" + title="$i18n{close}" on-click="onOSSettingsBannerClosed_"> </cr-icon-button> </div> 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 f2f0131a77c..f12eb098ddc 100644 --- a/chromium/chrome/browser/resources/settings/basic_page/basic_page.js +++ b/chromium/chrome/browser/resources/settings/basic_page/basic_page.js @@ -153,11 +153,6 @@ Polymer({ this.showChangePassword = visibility; }); - if (loadTimeData.getBoolean('passwordProtectionAvailable')) { - settings.ChangePasswordBrowserProxyImpl.getInstance() - .initializeChangePasswordHandler(); - } - if (settings.AndroidAppsBrowserProxyImpl) { this.addWebUIListener( 'android-apps-info-update', this.androidAppsInfoUpdate_.bind(this)); diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn index b883f4e20f1..75b6aea70fc 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/os_a11y_page/BUILD.gn @@ -7,10 +7,12 @@ import("//third_party/closure_compiler/compile_js.gni") js_type_check("closure_compile") { deps = [ ":os_a11y_page", + "../../a11y_page:captions_subpage", "../../a11y_page:externs", "../../a11y_page:manage_a11y_page", "../../a11y_page:switch_access_subpage", "../../a11y_page:tts_subpage", + "../../appearance_page:fonts_browser_proxy", ] } diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn index b54af0ac04f..664cc90da69 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/os_apps_page/BUILD.gn @@ -13,8 +13,13 @@ js_type_check("closure_compile") { js_library("os_apps_page") { deps = [ "../../:route", + "../../android_apps_page:android_apps_browser_proxy", + "../../android_apps_page:android_apps_subpage", + "../../prefs:prefs_behavior", "../../settings_page:settings_animated_pages", "app_management_page", + "//ui/webui/resources/js:cr", + "//ui/webui/resources/js:i18n_behavior", ] externs_list = [ "$externs_path/metrics_private.js" ] diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn index c9841d1a9d7..b0e0b80ace2 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn @@ -19,11 +19,9 @@ js_type_check("closure_compile") { ":fake_page_handler", ":main_view", ":permission_item", - ":permission_toggle", ":pin_to_shelf_item", ":pwa_permission_view", ":reducers", - ":router", ":store", ":store_client", ":toggle_row", @@ -62,7 +60,6 @@ js_library("app_management_page") { ":actions", ":browser_proxy", ":main_view", - ":router", ":store", ":store_client", ] @@ -75,6 +72,7 @@ js_library("app_permission_view") { ":dom_switch", ":pwa_permission_view", ":store_client", + "../../..:route", ] } @@ -133,14 +131,8 @@ js_library("main_view") { js_library("permission_item") { deps = [ ":fake_page_handler", - ":permission_toggle", ":store_client", - ":util", - ] -} - -js_library("permission_toggle") { - deps = [ + ":toggle_row", ":util", ] } @@ -171,14 +163,6 @@ js_library("reducers") { ] } -js_library("router") { - deps = [ - ":actions", - ":constants", - ":store_client", - ] -} - js_library("store") { deps = [ ":reducers", @@ -218,6 +202,7 @@ js_library("uninstall_button") { ":util", "//ui/webui/resources/cr_elements/cr_button:cr_button", "//ui/webui/resources/cr_elements/policy:cr_tooltip_icon", + "//ui/webui/resources/js:i18n_behavior", ] } diff --git a/chromium/chrome/browser/resources/settings/chromeos/os_settings_ui/BUILD.gn b/chromium/chrome/browser/resources/settings/chromeos/os_settings_ui/BUILD.gn index 058863d4b69..6aa19594fe9 100644 --- a/chromium/chrome/browser/resources/settings/chromeos/os_settings_ui/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/chromeos/os_settings_ui/BUILD.gn @@ -18,7 +18,7 @@ js_library("os_settings_ui") { "../os_settings_main:os_settings_main", "../os_toolbar", "//ui/webui/resources/cr_elements:cr_container_shadow_behavior", - "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types", + "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_strings", "//ui/webui/resources/cr_elements/cr_drawer:cr_drawer", "//ui/webui/resources/cr_elements/cr_toolbar:cr_toolbar_search_field", "//ui/webui/resources/cr_elements/policy:cr_policy_indicator_behavior", diff --git a/chromium/chrome/browser/resources/settings/controls/controlled_button.html b/chromium/chrome/browser/resources/settings/controls/controlled_button.html index af328098f62..79fb7d2e405 100644 --- a/chromium/chrome/browser/resources/settings/controls/controlled_button.html +++ b/chromium/chrome/browser/resources/settings/controls/controlled_button.html @@ -42,7 +42,7 @@ } </style> - <cr-button class$="[[getClass_(actionButton)]]" + <cr-button class$="[[actionClass_]]" disabled="[[!buttonEnabled_(enforced_, disabled)]]"> [[label]] </cr-button> diff --git a/chromium/chrome/browser/resources/settings/controls/controlled_button.js b/chromium/chrome/browser/resources/settings/controls/controlled_button.js index 43f07fd36c0..e751237cab2 100644 --- a/chromium/chrome/browser/resources/settings/controls/controlled_button.js +++ b/chromium/chrome/browser/resources/settings/controls/controlled_button.js @@ -11,11 +11,6 @@ Polymer({ ], properties: { - actionButton: { - type: Boolean, - value: false, - }, - endJustified: { type: Boolean, value: false, @@ -31,6 +26,12 @@ Polymer({ }, /** @private */ + actionClass_: { + type: String, + value: '' + }, + + /** @private */ enforced_: { type: Boolean, computed: 'isPrefEnforced(pref.*)', @@ -38,6 +39,18 @@ Polymer({ }, }, + /** @override */ + attached: function() { + if (this.classList.contains('action-button')) { + this.actionClass_ = 'action-button'; + } + }, + + /** Focus on the inner cr-button. */ + focus: function() { + this.$$('cr-button').focus(); + }, + /** * @param {!Event} e * @private @@ -49,15 +62,6 @@ Polymer({ }, /** - * @param {!boolean} actionButton - * @return {string} Class of the cr-button. - * @private - */ - getClass_: function(actionButton) { - return actionButton ? 'action-button' : ''; - }, - - /** * @param {!boolean} enforced * @param {!boolean} disabled * @return {boolean} True if the button should be enabled. diff --git a/chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.html b/chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.html index 4a0026ee454..810fd0b8b00 100644 --- a/chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.html +++ b/chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.html @@ -13,13 +13,16 @@ } #passwordPrompt { - padding: 0; + padding-bottom: 20px; + padding-inline-end: 0; + padding-inline-start: 0; } </style> <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">$i18n{passwordPromptTitle}</div> <div slot="body"> - <div id="passwordPrompt" class="settings-box first line-only"> + <div id="passwordPrompt" class="settings-box first" + hidden="[[!passwordPromptText]]"> [[passwordPromptText]] </div> <cr-input id="passwordInput" type="password" diff --git a/chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.js b/chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.js index 2fc160bfb77..574dd209c16 100644 --- a/chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.js +++ b/chromium/chrome/browser/resources/settings/controls/password_prompt_dialog.js @@ -34,6 +34,7 @@ Polymer({ passwordPromptText: { type: String, notify: true, + value: '', }, /** diff --git a/chromium/chrome/browser/resources/settings/device_page/BUILD.gn b/chromium/chrome/browser/resources/settings/device_page/BUILD.gn index d7d0c1e13fd..1826cc4de8d 100644 --- a/chromium/chrome/browser/resources/settings/device_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/device_page/BUILD.gn @@ -12,7 +12,6 @@ js_type_check("closure_compile") { ":display_layout", ":display_overscan_dialog", ":drag_behavior", - ":drive_cache_dialog", ":keyboard", ":layout_behavior", ":night_light_slider", @@ -148,10 +147,3 @@ js_library("storage") { "//ui/webui/resources/js/cr/ui:focus_without_ink", ] } - -js_library("drive_cache_dialog") { - deps = [ - "//ui/webui/resources/js:i18n_behavior", - ] - externs_list = [ "$externs_path/chrome_send.js" ] -} diff --git a/chromium/chrome/browser/resources/settings/device_page/display.html b/chromium/chrome/browser/resources/settings/device_page/display.html index 5b906f084eb..cee6fafa793 100644 --- a/chromium/chrome/browser/resources/settings/device_page/display.html +++ b/chromium/chrome/browser/resources/settings/device_page/display.html @@ -241,12 +241,13 @@ pref="{{prefs.ash.night_light.enabled}}" sub-label="$i18n{displayNightLightText}"> </settings-toggle-button> + <div id="nightLightSettingsDiv" class="settings-box continuation start layout vertical"> <!-- Color temperature slider --> <div id="nightLightTemperatureDiv" class="settings-box indented continuation" - disabled$="[[!prefs.ash.night_light.enabled.value]]"> + hidden$="[[!prefs.ash.night_light.enabled.value]]"> <div class="start text-area" id="colorTemperatureLabel"> $i18n{displayNightLightTemperatureLabel} </div> @@ -254,8 +255,7 @@ aria-labelledby="colorTemperatureLabel" min="0" max="100" scale="100" label-min="$i18n{displayNightLightTempSliderMinLabel}" label-max="$i18n{displayNightLightTempSliderMaxLabel}" - pref="{{prefs.ash.night_light.color_temperature}}" - disabled$="[[!prefs.ash.night_light.enabled.value]]"> + pref="{{prefs.ash.night_light.color_temperature}}"> </settings-slider> </div> <!-- Schedule settings --> @@ -278,7 +278,7 @@ </div> <!-- Custom schedule slider --> <iron-collapse id="nightLightCustomScheduleCollapse" - opened="[[shouldOpenCustomScheduleCollapse_]]"> + opened="[[shouldOpenCustomScheduleCollapse_]]"> <div class="settings-box indented continuation"> <div class="start text-area layout vertical"> <div class="settings-box continuation self-stretch"> diff --git a/chromium/chrome/browser/resources/settings/device_page/drive_cache_dialog.html b/chromium/chrome/browser/resources/settings/device_page/drive_cache_dialog.html deleted file mode 100644 index 00e43a44464..00000000000 --- a/chromium/chrome/browser/resources/settings/device_page/drive_cache_dialog.html +++ /dev/null @@ -1,31 +0,0 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.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="../settings_shared_css.html"> - -<dom-module id="settings-drive-cache-dialog"> - <template> - <style include="settings-shared"></style> - <cr-dialog id="dialog" close-text="$i18n{close}"> - <div slot="title"> - $i18n{storageClearDriveCacheDialogTitle} - </div> - <div slot="body"> - <span>$i18n{storageClearDriveCacheDialogDescription}</span> - </div> - <div slot="button-container"> - <cr-button id="cancelButton" class="cancel-button" - on-click="onCancelTap_"> - $i18n{cancel} - </cr-button> - <cr-button id="deleteButton" class="action-button" - on-click="onDeleteTap_"> - $i18n{storageDeleteAllButtonTitle} - </cr-button> - </div> - </cr-dialog> - </template> - <script src="drive_cache_dialog.js"></script> -</dom-module> diff --git a/chromium/chrome/browser/resources/settings/device_page/drive_cache_dialog.js b/chromium/chrome/browser/resources/settings/device_page/drive_cache_dialog.js deleted file mode 100644 index fd63087ec6a..00000000000 --- a/chromium/chrome/browser/resources/settings/device_page/drive_cache_dialog.js +++ /dev/null @@ -1,31 +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 - * 'settings-drive-cache-dialog' is the dialog to delete Google Drive temporary - * offline files. - */ -Polymer({ - is: 'settings-drive-cache-dialog', - - behaviors: [ - I18nBehavior, - ], - - open: function() { - this.$.dialog.showModal(); - }, - - /** @private */ - onCancelTap_: function() { - this.$.dialog.cancel(); - }, - - /** @private */ - onDeleteTap_: function() { - chrome.send('clearDriveCache'); - this.$.dialog.close(); - }, -}); diff --git a/chromium/chrome/browser/resources/settings/device_page/keyboard.js b/chromium/chrome/browser/resources/settings/device_page/keyboard.js index 4c189aa6727..a636592e369 100644 --- a/chromium/chrome/browser/resources/settings/device_page/keyboard.js +++ b/chromium/chrome/browser/resources/settings/device_page/keyboard.js @@ -155,7 +155,7 @@ Polymer({ onShowLanguageInputTap_: function() { settings.navigateTo( - settings.routes.LANGUAGES, + settings.routes.LANGUAGES_DETAILS, /* dynamicParams */ null, /* removeSearch */ true); }, diff --git a/chromium/chrome/browser/resources/settings/device_page/pointers.html b/chromium/chrome/browser/resources/settings/device_page/pointers.html index fff070da29c..6a628f2f5b2 100644 --- a/chromium/chrome/browser/resources/settings/device_page/pointers.html +++ b/chromium/chrome/browser/resources/settings/device_page/pointers.html @@ -46,7 +46,7 @@ <template is="dom-if" if="[[allowDisableAcceleration_]]"> <settings-toggle-button id="mouseAcceleration" pref="{{prefs.settings.mouse.acceleration}}" - label="$i18n{pointerAccelerationLabel}"> + label="$i18n{mouseAccelerationLabel}"> </settings-toggle-button> </template> <div class="settings-box"> @@ -75,7 +75,7 @@ <template is="dom-if" if="[[allowDisableAcceleration_]]"> <settings-toggle-button id="touchpadAcceleration" pref="{{prefs.settings.touchpad.acceleration}}" - label="$i18n{pointerAccelerationLabel}"> + label="$i18n{touchpadAccelerationLabel}"> </settings-toggle-button> </template> <div class="settings-box"> diff --git a/chromium/chrome/browser/resources/settings/device_page/storage.html b/chromium/chrome/browser/resources/settings/device_page/storage.html index f0a518e2572..6526d4f1fb1 100644 --- a/chromium/chrome/browser/resources/settings/device_page/storage.html +++ b/chromium/chrome/browser/resources/settings/device_page/storage.html @@ -8,7 +8,6 @@ <link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> -<link rel="import" href="drive_cache_dialog.html"> <link rel="import" href="storage_external.html"> <link rel="import" href="../prefs/prefs.html"> <link rel="import" href="../route.html"> @@ -201,20 +200,6 @@ <cr-link-row id="downloadsSize" class="hr" on-click="onDownloadsTap_" label="$i18n{storageItemDownloads}" sub-label="$i18n{storageSizeComputing}" external></cr-link-row> - <template is="dom-if" if="[[driveEnabled_]]"> - <div class="settings-box two-line" on-click="onDriveCacheTap_" - actionable$="[[hasDriveCache_]]" > - <div class="start"> - $i18n{storageItemDriveCache} - <div id="driveCacheSize" class="secondary"> - $i18n{storageSizeComputing} - </div> - </div> - <cr-icon-button class="icon-delete-gray" id="deleteButton" - aria-label="$i18n{storageItemDriveCache}" - aria-describedby="driveSizeCache"></cr-icon-button> - </div> - </template> <cr-link-row id="browsingDataSize" class="hr" on-click="onBrowsingDataTap_" label="$i18n{storageItemBrowsingData}" sub-label="$i18n{storageSizeComputing}" external></cr-link-row> @@ -238,10 +223,6 @@ on-click="onExternalStoragePreferencesTap_" label="$i18n{storageExternal}"></cr-link-row> </template> - - <settings-drive-cache-dialog id="storageDriveCache" - on-close="onCloseDriveCacheDialog_"> - </settings-drive-cache-dialog> </template> <script src="storage.js"></script> </dom-module> diff --git a/chromium/chrome/browser/resources/settings/device_page/storage.js b/chromium/chrome/browser/resources/settings/device_page/storage.js index 2717462da66..ae7598fdbba 100644 --- a/chromium/chrome/browser/resources/settings/device_page/storage.js +++ b/chromium/chrome/browser/resources/settings/device_page/storage.js @@ -37,12 +37,6 @@ Polymer({ behaviors: [settings.RouteObserverBehavior, WebUIListenerBehavior], properties: { - /** @private */ - driveEnabled_: { - type: Boolean, - value: false, - }, - androidEnabled: Boolean, /** @private */ @@ -68,12 +62,6 @@ Polymer({ } }, - /** @private */ - hasDriveCache_: { - type: Boolean, - value: false, - }, - /** @private {settings.StorageSizeStat} */ sizeStat_: Object, }, @@ -94,9 +82,6 @@ Polymer({ 'storage-downloads-size-changed', this.handleDownloadsSizeChanged_.bind(this)); this.addWebUIListener( - 'storage-drive-cache-size-changed', - this.handleDriveCacheSizeChanged_.bind(this)); - this.addWebUIListener( 'storage-browsing-data-size-changed', this.handleBrowsingDataSizeChanged_.bind(this)); this.addWebUIListener( @@ -111,9 +96,6 @@ Polymer({ this.handleOtherUsersSizeChanged_.bind(this)); } this.addWebUIListener( - 'storage-drive-enabled-changed', - this.handleDriveEnabledChanged_.bind(this)); - this.addWebUIListener( 'storage-android-running-changed', this.handleAndroidRunningChanged_.bind(this)); }, @@ -146,18 +128,6 @@ Polymer({ }, /** - * Handler for tapping the "Offline files" item. - * @param {!Event} e - * @private - */ - onDriveCacheTap_: function(e) { - e.preventDefault(); - if (this.hasDriveCache_) { - this.$.storageDriveCache.open(); - } - }, - - /** * Handler for tapping the "Browsing data" item. * @private */ @@ -221,19 +191,6 @@ Polymer({ }, /** - * @param {string} size Formatted string representing the size of Offline - * files. - * @param {boolean} hasCache True if the device has at least one offline file. - * @private - */ - handleDriveCacheSizeChanged_: function(size, hasCache) { - if (this.driveEnabled_) { - this.$$('#driveCacheSize').textContent = size; - this.hasDriveCache_ = hasCache; - } - }, - - /** * @param {string} size Formatted string representing the size of Browsing * data. * @private @@ -275,14 +232,6 @@ Polymer({ }, /** - * @param {boolean} enabled True if Google Drive is enabled. - * @private - */ - handleDriveEnabledChanged_: function(enabled) { - this.driveEnabled_ = enabled; - }, - - /** * @param {boolean} running True if Android (ARC) is running. * @private */ @@ -362,9 +311,4 @@ Polymer({ return ''; } }, - - /** @private */ - onCloseDriveCacheDialog_: function() { - cr.ui.focusWithoutInk(assert(this.$$('#deleteButton'))); - }, }); diff --git a/chromium/chrome/browser/resources/settings/device_page/storage_external.html b/chromium/chrome/browser/resources/settings/device_page/storage_external.html index 922c2613d1f..da2d3cafc7d 100644 --- a/chromium/chrome/browser/resources/settings/device_page/storage_external.html +++ b/chromium/chrome/browser/resources/settings/device_page/storage_external.html @@ -15,7 +15,7 @@ </style> <div class="settings-box first"> <span> - $i18n{storageAndroidAppsExternalDrivesNote} + $i18nRaw{storageAndroidAppsExternalDrivesNote} </span> </div> <h2>$i18n{storageExternalStorageListHeader}</h2> diff --git a/chromium/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.html b/chromium/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.html index 131565b3c41..52053aae4d7 100644 --- a/chromium/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.html +++ b/chromium/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.html @@ -58,12 +58,9 @@ <div class="label"> $i18n{googleAssistantEnableHotword} </div> - <div class="secondary label" hidden="[[!hotwordDefaultOn_]]"> + <div class="secondary label"> $i18n{googleAssistantEnableHotwordWithoutDspDescription} </div> - <div class="secondary label" hidden="[[hotwordDefaultOn_]]"> - $i18n{googleAssistantEnableHotwordDescription} - </div> </div> <template is="dom-if" if="[[hotwordEnforced_]]" restamp> <cr-policy-pref-indicator id="hotword-policy-pref-indicator" @@ -87,7 +84,7 @@ </select> </div> <template is="dom-if" if="[[shouldShowVoiceMatchSettings_]]"> - <div class="settings-box"> + <div class="settings-box continuation embedded"> <div class="start text-area settings-box-text"> <div class="label"> $i18n{googleAssistantVoiceSettings} diff --git a/chromium/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.js b/chromium/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.js index 559d65184d1..5237e0168f7 100644 --- a/chromium/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.js +++ b/chromium/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.js @@ -15,8 +15,8 @@ const DspHotwordState = { /** * Indicates user's activity control consent status. * - * Note: This should be kept in sync with ash::mojom::ConsentStatus in - * ash/public/mojom/voice_interaction_controller.mojom + * Note: This should be kept in sync with ConsentStatus in + * chromeos/services/assistant/public/cpp/assistant_prefs.h * @enum {number} */ const ConsentStatus = { @@ -97,12 +97,6 @@ Polymer({ }, /** @private */ - hotwordDefaultOn_: { - type: Boolean, - value: false, - }, - - /** @private */ dspHotwordState_: { type: DspHotwordState, } @@ -166,20 +160,17 @@ Polymer({ this.setPrefValue('settings.voice_interaction.hotword.enabled', true); this.setPrefValue( 'settings.voice_interaction.hotword.always_on', false); - this.hotwordDefaultOn_ = true; this.browserProxy_.syncVoiceModelStatus(); break; case DspHotwordState.ALWAYS_ON: this.setPrefValue('settings.voice_interaction.hotword.enabled', true); this.setPrefValue('settings.voice_interaction.hotword.always_on', true); - this.hotwordDefaultOn_ = false; this.browserProxy_.syncVoiceModelStatus(); break; case DspHotwordState.OFF: this.setPrefValue('settings.voice_interaction.hotword.enabled', false); this.setPrefValue( 'settings.voice_interaction.hotword.always_on', false); - this.hotwordDefaultOn_ = false; break; default: console.error('Invalid Dsp hotword settings state'); @@ -205,6 +196,7 @@ Polymer({ this.refreshDspHotwordState_(); this.shouldShowVoiceMatchSettings_ = + !loadTimeData.getBoolean('voiceMatchDisabled') && this.getPref('settings.voice_interaction.hotword.enabled.value') && (this.getPref( 'settings.voice_interaction.activity_control.consent_status.value') == @@ -220,14 +212,11 @@ Polymer({ /** @private */ refreshDspHotwordState_: function() { if (!this.getPref('settings.voice_interaction.hotword.enabled.value')) { - this.hotwordDefaultOn_ = false; this.dspHotwordState_ = DspHotwordState.OFF; } else if (this.getPref( 'settings.voice_interaction.hotword.always_on.value')) { - this.hotwordDefaultOn_ = false; this.dspHotwordState_ = DspHotwordState.ALWAYS_ON; } else { - this.hotwordDefaultOn_ = true; this.dspHotwordState_ = DspHotwordState.DEFAULT_ON; } diff --git a/chromium/chrome/browser/resources/settings/icons.html b/chromium/chrome/browser/resources/settings/icons.html index ad722128231..595f018d907 100644 --- a/chromium/chrome/browser/resources/settings/icons.html +++ b/chromium/chrome/browser/resources/settings/icons.html @@ -74,6 +74,7 @@ NOTE: Chrome OS icons go in ./chromeos/os_icons.html. <g id="pdf"><path d="M7 11.5h1v-1H7v1zM19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-9.5 8.5c0 .83-.67 1.5-1.5 1.5H7v2H5.5V9H8c.83 0 1.5.67 1.5 1.5v1zm10-1H17v1h1.5V13H17v2h-1.5V9h4v1.5zm-5 3c0 .83-.67 1.5-1.5 1.5h-2.5V9H13c.83 0 1.5.67 1.5 1.5v3zm-2.5 0h1v-3h-1v3z"></path><path fill="none" d="M0 0h24v24H0z"></path></g> <g id="palette"><path d="M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9c.83 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.01-.23-.26-.38-.61-.38-.99 0-.83.67-1.5 1.5-1.5H16c2.76 0 5-2.24 5-5 0-4.42-4.03-8-9-8zm-5.5 9c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9 8 9.67 8 10.5 7.33 12 6.5 12zm3-4C8.67 8 8 7.33 8 6.5S8.67 5 9.5 5s1.5.67 1.5 1.5S10.33 8 9.5 8zm5 0c-.83 0-1.5-.67-1.5-1.5S13.67 5 14.5 5s1.5.67 1.5 1.5S15.33 8 14.5 8zm3 4c-.83 0-1.5-.67-1.5-1.5S16.67 9 17.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"></path></g> <g id="payment-handler"><path d="M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z"></path></g> + <g id="insecure-content"><path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"></path></g> <g id="photo"><path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"></path></g> <g id="power-settings-new"><path d="M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42C17.99 7.86 19 9.81 19 12c0 3.87-3.13 7-7 7s-7-3.13-7-7c0-2.19 1.01-4.14 2.58-5.42L6.17 5.17C4.23 6.82 3 9.26 3 12c0 4.97 4.03 9 9 9s9-4.03 9-9c0-2.74-1.23-5.18-3.17-6.83z"></path></g> <g id="protocol-handler"><path d="M21.72 11.33l-6.644-7.035a.97.97 0 0 0-1.38-.01l-1.67 1.72-1.617-1.712a.97.97 0 0 0-1.38-.01l-6.737 6.935c-.187.191-.29.447-.292.719-.002.272.099.529.28.722l6.644 7.034a.949.949 0 0 0 1.38.011l1.671-1.718 1.615 1.71a.949.949 0 0 0 1.381.01l6.74-6.935a1.054 1.054 0 0 0 .01-1.44zM6.947 12.464l3.657 3.785-.974.98-5.273-5.456 5.349-5.378.929.962-3.677 3.7a.998.998 0 0 0-.292.702 1 1 0 0 0 .28.705zm7.35 4.768l-.931-.963 3.68-3.7a1.012 1.012 0 0 0 .007-1.407l-3.656-3.784.974-.98 5.273 5.456-5.348 5.378z"></path></g> diff --git a/chromium/chrome/browser/resources/settings/internet_page/BUILD.gn b/chromium/chrome/browser/resources/settings/internet_page/BUILD.gn index 7b8a8fa0718..5aa49429248 100644 --- a/chromium/chrome/browser/resources/settings/internet_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/internet_page/BUILD.gn @@ -28,7 +28,6 @@ js_library("internet_page") { "//chromeos/services/network_config/public/mojom:mojom_js_library_for_compile", "//ui/webui/resources/cr_components/chromeos/network:mojo_interface_provider", "//ui/webui/resources/cr_elements/chromeos/network:cr_network_listener_behavior", - "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types", "//ui/webui/resources/js:assert", "//ui/webui/resources/js:i18n_behavior", "//ui/webui/resources/js:web_ui_listener_behavior", @@ -51,7 +50,6 @@ js_library("internet_config") { deps = [ "..:route", "//ui/webui/resources/cr_components/chromeos/network:network_config", - "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types", "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog", "//ui/webui/resources/js:assert", "//ui/webui/resources/js:i18n_behavior", @@ -67,7 +65,6 @@ js_library("internet_detail_page") { ":tether_connection_dialog", "..:route", "//ui/webui/resources/cr_elements/chromeos/network:cr_network_listener_behavior", - "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types", "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior_mojo", "//ui/webui/resources/js:assert", "//ui/webui/resources/js:i18n_behavior", @@ -82,7 +79,6 @@ js_library("internet_detail_page") { js_library("internet_known_networks_page") { deps = [ "//ui/webui/resources/cr_elements/chromeos/network:cr_network_listener_behavior", - "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types", "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu", "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior_mojo", "//ui/webui/resources/js:assert", @@ -122,7 +118,6 @@ js_library("network_proxy_section") { js_library("network_summary") { deps = [ "//ui/webui/resources/cr_elements/chromeos/network:cr_network_listener_behavior", - "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types", "//ui/webui/resources/js:assert", "//ui/webui/resources/js/chromeos:onc_mojo", ] @@ -131,7 +126,7 @@ js_library("network_summary") { js_library("network_summary_item") { deps = [ - "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types", + "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_strings", "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior_mojo", "//ui/webui/resources/js:assert", "//ui/webui/resources/js:i18n_behavior", 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 df873613ea5..65ef26edeee 100644 --- a/chromium/chrome/browser/resources/settings/internet_page/internet_config.html +++ b/chromium/chrome/browser/resources/settings/internet_page/internet_config.html @@ -1,7 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_components/chromeos/network/network_config.html"> -<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> @@ -23,13 +22,11 @@ <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title"> - [[getDialogTitle_(managedProperties_, showConnect)]] + [[getDialogTitle_(name, type, showConnect)]] </div> <div slot="body"> <network-config id="networkConfig" class="flex" - networking-private="[[networkingPrivate]]" - global-policy="[[globalPolicy]]" - managed-properties="{{managedProperties_}}" + guid="[[guid]]" name="{{name}}" type="{{type}}" 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 0b3760d0477..d5bd42d5da2 100644 --- a/chromium/chrome/browser/resources/settings/internet_page/internet_config.js +++ b/chromium/chrome/browser/resources/settings/internet_page/internet_config.js @@ -12,15 +12,6 @@ Polymer({ behaviors: [I18nBehavior], properties: { - /** - * Interface for networkingPrivate calls, passed from internet_page. - * @type {NetworkingPrivate} - */ - networkingPrivate: Object, - - /** @type {!chrome.networkingPrivate.GlobalPolicy|undefined} */ - globalPolicy: Object, - /** @private */ shareAllowEnable_: { type: Boolean, @@ -44,13 +35,14 @@ Polymer({ guid: String, /** - * The type of network to be configured. - * @type {!chrome.networkingPrivate.NetworkType} + * The type of network to be configured as a string. May be set initially or + * updated by network-config. */ type: String, /** - * The name of network (for display while the network details are fetched). + * The name of the network. May be set initially or updated by + * network-config. */ name: String, @@ -66,14 +58,6 @@ Polymer({ enableSave_: Boolean, /** - * 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.ManagedProperties} - */ - managedProperties_: Object, - - /** * Set by network-config when a configuration error occurs. * @private */ @@ -89,14 +73,6 @@ Polymer({ dialog.showModal(); } - // Set managedProperties for new configurations and for existing - // configurations until the current properties are loaded. - assert(this.type && this.type != CrOnc.Type.ALL); - this.managedProperties_ = { - GUID: this.guid, - Name: {Active: this.name}, - Type: this.type, - }; this.$.networkConfig.init(); }, @@ -113,7 +89,6 @@ Polymer({ */ onClose_: function(event) { this.close(); - event.stopPropagation(); }, /** @@ -121,18 +96,10 @@ Polymer({ * @private */ getDialogTitle_: function() { - // If no properties are available yet, wait until they are set as part of - // open(). - if (!this.managedProperties_) { - return ''; - } - - const name = /** @type {string} */ ( - CrOnc.getActiveValue(this.managedProperties_.Name)); - if (name && !this.showConnect) { - return this.i18n('internetConfigName', HTMLEscape(name)); + if (this.name && !this.showConnect) { + return this.i18n('internetConfigName', HTMLEscape(this.name)); } - const type = this.i18n('OncType' + this.managedProperties_.Type); + const type = this.i18n('OncType' + this.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 c78ca56e50b..2d27c7dc86d 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 @@ -8,7 +8,6 @@ <link rel="import" href="chrome://resources/cr_components/chromeos/network/network_siminfo.html"> <link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_icon.html"> <link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_listener_behavior.html"> -<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.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_toggle/cr_toggle.html"> @@ -68,10 +67,15 @@ paper-spinner-lite { @apply --cr-icon-height-width; } + .warning { color: var(--cr-secondary-text-color); margin-inline-start: var(--settings-controlled-by-spacing); } + + #mac-address-container { + border-top: none; + } </style> <!-- Title section: Icon + name + connection state. --> <div id="titleDiv" class="settings-box first"> @@ -83,9 +87,9 @@ <div id="networkState" class="title settings-box-text" connected$="[[isConnectedState_(managedProperties_)]]" error$="[[isConnectionErrorState_( - managedProperties_, outOfRange_)]]"> + managedProperties_, outOfRange_, deviceState_)]]"> [[getStateText_(managedProperties_, propertiesReceived_, - outOfRange_)]] + outOfRange_, deviceState_)]] </div> <template is="dom-if" if="[[isPolicySource(managedProperties_.source))]]"> @@ -118,17 +122,18 @@ </cr-button> <!-- Use policy properties from vpn_config_allowed to indicate when that pref disables buttons in this row. --> - <controlled-button id="connect" action-button on-click="onConnectTap_" + <controlled-button id="connect" class="action-button" + on-click="onConnectTap_" hidden$="[[!showConnect_(managedProperties_, globalPolicy, - managedNetworkAvailable)]]" + managedNetworkAvailable, deviceState_)]]" disabled="[[!enableConnect_(managedProperties_, defaultNetwork, propertiesReceived_, outOfRange_, globalPolicy, - managedNetworkAvailable)]]" + managedNetworkAvailable, deviceState_)]]" label="$i18n{networkButtonConnect}" pref="[[getFakeVpnConfigPrefForEnforcement_(managedProperties_, prefs.vpn_config_allowed)]]"> </controlled-button> - <controlled-button id="disconnect" action-button + <controlled-button id="disconnect" class="action-button" on-click="onDisconnectTap_" hidden$="[[!showDisconnect_(managedProperties_)]]" label="$i18n{networkButtonDisconnect}" @@ -324,6 +329,7 @@ <!-- MAC Address. --> <div class="settings-box two-line single-column stretch indented" + id="mac-address-container" hidden$="[[!deviceState_.macAddress]]"> <div>$i18n{OncMacAddress}</div> <div class="secondary">[[deviceState_.macAddress]]</div> 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 3dd71d9ff20..7c15915a2c8 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 @@ -104,12 +104,6 @@ Polymer({ }, /** - * Interface for networkingPrivate calls, passed from internet_page. - * @type {NetworkingPrivate} - */ - networkingPrivate: Object, - - /** * The network AutoConnect state as a fake preference object. * @private {!chrome.settingsPrivate.PrefObject|undefined} */ @@ -205,12 +199,7 @@ Polymer({ /** @private {settings.InternetPageBrowserProxy} */ browserProxy_: null, - /** - * This UI will use both the networkingPrivate extension API and the - * networkConfig mojo API until we provide all of the required functionality - * in networkConfig. TODO(stevenjb): Remove use of networkingPrivate api. - * @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} - */ + /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */ networkConfig_: null, /** @override */ @@ -355,10 +344,9 @@ Polymer({ if (!this.didSetFocus_) { // Focus a button once the initial state is set. this.didSetFocus_ = true; - const button = this.$$('#titleDiv .action-button:not([hidden])') || - this.$$('#titleDiv cr-button:not([hidden])'); + const button = this.$$('#titleDiv .action-button:not([hidden])'); if (button) { - setTimeout(() => button.focus()); + Polymer.RenderStatus.afterNextRender(this, () => button.focus()); } } @@ -389,7 +377,7 @@ Polymer({ if (!this.propertiesReceived_) { return; } - const config = {}; + const config = this.getDefaultConfigProperties_(); config.autoConnect = {value: !!this.autoConnectPref_.value}; this.setMojoNetworkProperties_(config); }, @@ -441,7 +429,7 @@ Polymer({ if (!this.propertiesReceived_) { return; } - const config = {}; + const config = this.getDefaultConfigProperties_(); config.priority = {value: this.preferNetwork_ ? 1 : 0}; this.setMojoNetworkProperties_(config); }, @@ -451,7 +439,7 @@ Polymer({ const filter = { filter: mojom.FilterType.kVisible, networkType: mojom.NetworkType.kAll, - limit: mojom.kNoLimit, + limit: mojom.NO_LIMIT, }; this.networkConfig_.getNetworkState(this.guid).then(response => { if (response.result) { @@ -522,10 +510,25 @@ Polymer({ this.close(); return; } + const managedProperties = OncMojo.getDefaultManagedProperties( networkState.type, networkState.guid, networkState.name); managedProperties.connectable = networkState.connectable; managedProperties.connectionState = networkState.connectionState; + switch (networkState.type) { + case mojom.NetworkType.kCellular: + managedProperties.typeProperties.cellular.signalStrength = + networkState.typeState.cellular.signalStrength; + break; + case mojom.NetworkType.kTether: + managedProperties.typeProperties.tether.signalStrength = + networkState.typeState.tether.signalStrength; + break; + case mojom.NetworkType.kWiFi: + managedProperties.typeProperties.wifi.signalStrength = + networkState.typeState.wifi.signalStrength; + break; + } this.managedProperties_ = managedProperties; this.propertiesReceived_ = true; @@ -544,6 +547,14 @@ Polymer({ }, /** + * @return {!mojom.ConfigProperties} + * @private + */ + getDefaultConfigProperties_: function() { + return OncMojo.getDefaultConfigProperties(this.managedProperties_.type); + }, + + /** * @param {!mojom.ConfigProperties} config * @private */ @@ -565,15 +576,17 @@ Polymer({ * @param {!mojom.ManagedProperties} managedProperties * @param {boolean} propertiesReceived * @param {boolean} outOfRange + * @param {?OncMojo.DeviceStateProperties} deviceState * @return {string} The text to display for the network connection state. * @private */ - getStateText_: function(managedProperties, propertiesReceived, outOfRange) { + getStateText_: function( + managedProperties, propertiesReceived, outOfRange, deviceState) { if (!managedProperties || !propertiesReceived) { return ''; } - if (outOfRange) { + if (this.isOutOfRangeOrNotEnabled_(outOfRange, deviceState)) { return managedProperties.type == mojom.NetworkType.kTether ? this.i18n('tetherPhoneOutOfRange') : this.i18n('networkOutOfRange'); @@ -581,11 +594,11 @@ Polymer({ if (managedProperties.type == mojom.NetworkType.kCellular && !managedProperties.connectable) { - if (managedProperties.cellular.homeProvider && - managedProperties.cellular.homeProvider.name) { + if (managedProperties.typeProperties.cellular.homeProvider && + managedProperties.typeProperties.cellular.homeProvider.name) { return this.i18n( 'cellularContactSpecificCarrier', - managedProperties.cellular.homeProvider.name); + managedProperties.typeProperties.cellular.homeProvider.name); } return this.i18n('cellularContactDefaultCarrier'); } @@ -614,11 +627,11 @@ Polymer({ if (!this.isCellular_(managedProperties)) { return ''; } - if (!managedProperties.cellular.allowRoaming) { + if (!managedProperties.typeProperties.cellular.allowRoaming) { return this.i18n('networkAllowDataRoamingDisabled'); } - return managedProperties.cellular.roamingState == 'Roaming' ? + return managedProperties.typeProperties.cellular.roamingState == 'Roaming' ? this.i18n('networkAllowDataRoamingEnabledRoaming') : this.i18n('networkAllowDataRoamingEnabledHome'); }, @@ -636,11 +649,13 @@ Polymer({ /** * @param {!mojom.ManagedProperties|undefined} managedProperties * @param {boolean} outOfRange + * @param {?OncMojo.DeviceStateProperties} deviceState * @return {boolean} True if the network shown cannot initiate a connection. * @private */ - isConnectionErrorState_: function(managedProperties, outOfRange) { - if (outOfRange) { + isConnectionErrorState_: function( + managedProperties, outOfRange, deviceState) { + if (this.isOutOfRangeOrNotEnabled_(outOfRange, deviceState)) { return true; } @@ -710,7 +725,8 @@ Polymer({ this.isPolicySource(managedProperties.source)) { return false; } - const hexSsid = OncMojo.getActiveString(managedProperties.wifi.hexSsid); + const hexSsid = + OncMojo.getActiveString(managedProperties.typeProperties.wifi.hexSsid); return !!globalPolicy.allowOnlyPolicyNetworksToConnect || (!!globalPolicy.allowOnlyPolicyNetworksToConnectIfAvailable && !!managedNetworkAvailable) || @@ -722,11 +738,12 @@ Polymer({ * @param {!mojom.ManagedProperties} managedProperties * @param {!mojom.GlobalPolicy} globalPolicy * @param {boolean} managedNetworkAvailable + * @param {?OncMojo.DeviceStateProperties} deviceState * @return {boolean} * @private */ showConnect_: function( - managedProperties, globalPolicy, managedNetworkAvailable) { + managedProperties, globalPolicy, managedNetworkAvailable, deviceState) { if (!managedProperties) { return false; } @@ -741,15 +758,24 @@ Polymer({ if (this.isArcVpn_(managedProperties)) { return false; } + if (managedProperties.connectionState != mojom.ConnectionStateType.kNotConnected) { return false; } + + if (deviceState && + deviceState.deviceState != + chromeos.networkConfig.mojom.DeviceStateType.kEnabled) { + return false; + } + // Cellular is not configurable, so we always show the connect button, and // disable it if 'connectable' is false. if (managedProperties.type == mojom.NetworkType.kCellular) { return true; } + // If 'connectable' is false we show the configure button. return managedProperties.connectable && managedProperties.type != mojom.NetworkType.kEthernet; @@ -801,7 +827,8 @@ Polymer({ if (!this.isCellular_(managedProperties)) { return false; } - const activation = managedProperties.cellular.activationState; + const activation = + managedProperties.typeProperties.cellular.activationState; return activation == mojom.ActivationStateType.kNotActivated || activation == mojom.ActivationStateType.kPartiallyActivated; }, @@ -828,7 +855,8 @@ Polymer({ return false; } if (type == mojom.NetworkType.kWiFi && - managedProperties.wifi.security == mojom.SecurityType.kNone) { + managedProperties.typeProperties.wifi.security == + mojom.SecurityType.kNone) { return false; } if (type == mojom.NetworkType.kWiFi && @@ -916,18 +944,20 @@ Polymer({ return false; } - const paymentPortal = managedProperties.cellular.paymentPortal; + const paymentPortal = + managedProperties.typeProperties.cellular.paymentPortal; if (!paymentPortal || !paymentPortal.url) { return false; } // Only show for connected networks or LTE networks with a valid MDN. if (!this.isConnectedState_(managedProperties)) { - const technology = managedProperties.cellular.networkTechnology; + const technology = + managedProperties.typeProperties.cellular.networkTechnology; if (technology != 'LTE' && technology != 'LTEAdvanced') { return false; } - if (!managedProperties.cellular.mdn) { + if (!managedProperties.typeProperties.cellular.mdn) { return false; } } @@ -942,14 +972,16 @@ Polymer({ * @param {boolean} outOfRange * @param {!mojom.GlobalPolicy} globalPolicy * @param {boolean} managedNetworkAvailable + * @param {?OncMojo.DeviceStateProperties} deviceState * @return {boolean} Whether or not to enable the network connect button. * @private */ enableConnect_: function( managedProperties, defaultNetwork, propertiesReceived, outOfRange, - globalPolicy, managedNetworkAvailable) { + globalPolicy, managedNetworkAvailable, deviceState) { if (!this.showConnect_( - managedProperties, globalPolicy, managedNetworkAvailable)) { + managedProperties, globalPolicy, managedNetworkAvailable, + deviceState)) { return false; } if (!propertiesReceived || outOfRange) { @@ -1017,7 +1049,7 @@ Polymer({ /** @private */ onConnectTap_: function() { if (this.managedProperties_.type == mojom.NetworkType.kTether && - (!this.managedProperties_.tether.hasConnectedToHost)) { + (!this.managedProperties_.typeProperties.tether.hasConnectedToHost)) { this.showTetherDialog_(); return; } @@ -1054,9 +1086,13 @@ Polymer({ /** @private */ onForgetTap_: function() { - this.networkingPrivate.forgetNetwork(this.guid); - // A forgotten network no longer has a valid GUID, close the subpage. - this.close(); + this.networkConfig_.forgetNetwork(this.guid).then(response => { + if (!response.success) { + console.error('Froget network failed for: ' + this.guid); + } + // A forgotten network no longer has a valid GUID, close the subpage. + this.close(); + }); }, /** @private */ @@ -1102,8 +1138,9 @@ Polymer({ return loadTimeData.getBoolean('showHiddenNetworkWarning') && !!this.autoConnectPref_ && !!this.autoConnectPref_.value && !!this.managedProperties_ && - !!this.managedProperties_.type == mojom.NetworkType.kWiFi && - !!OncMojo.getActiveValue(this.managedProperties_.wifi.hiddenSsid); + this.managedProperties_.type == mojom.NetworkType.kWiFi && + !!OncMojo.getActiveValue( + this.managedProperties_.typeProperties.wifi.hiddenSsid); }, /** @@ -1120,7 +1157,7 @@ Polymer({ } const field = e.detail.field; const value = e.detail.value; - const config = {}; + const config = this.getDefaultConfigProperties_(); const valueType = typeof value; if (valueType != 'string' && valueType != 'number' && valueType != 'boolean' && !Array.isArray(value)) { @@ -1130,10 +1167,17 @@ Polymer({ return; } OncMojo.setConfigProperty(config, field, value); - // Ensure any required configuration properties are also set. - if (this.managedProperties_.vpn && config.vpn && - config.vpn.type === undefined) { - config.vpn.type = this.managedProperties_.vpn.type; + // Ensure that any required configuration properties for partial + // configurations are set. + const vpnConfig = config.typeConfig.vpn; + if (vpnConfig) { + vpnConfig.type = this.managedProperties_.typeProperties.vpn.type; + if (vpnConfig.openVpn && vpnConfig.openVpn.saveCredentials == undefined) { + vpnConfig.openVpn.saveCredentials = false; + } + if (vpnConfig.l2tp && vpnConfig.l2tp.saveCredentials == undefined) { + vpnConfig.l2tp.saveCredentials = false; + } } this.setMojoNetworkProperties_(config); }, @@ -1146,8 +1190,9 @@ Polymer({ if (!this.propertiesReceived_) { return; } + const config = this.getDefaultConfigProperties_(); const apn = event.detail; - const config = {cellular: {apn: apn}}; + config.typeConfig.cellular = {apn: apn}; this.setMojoNetworkProperties_(config); }, @@ -1180,7 +1225,9 @@ Polymer({ if (!this.propertiesReceived_) { return; } - this.setMojoNetworkProperties_({proxySettings: event.detail}); + const config = this.getDefaultConfigProperties_(); + config.proxySettings = event.detail; + this.setMojoNetworkProperties_(config); }, /** @@ -1226,7 +1273,7 @@ Polymer({ return this.isArcVpn_(managedProperties) && this.prefs.arc && this.prefs.arc.vpn && this.prefs.arc.vpn.always_on && this.prefs.arc.vpn.always_on.vpn_package && - OncMojo.getActiveValue(managedProperties.vpn.host) === + OncMojo.getActiveValue(managedProperties.typeProperties.vpn.host) === this.prefs.arc.vpn.always_on.vpn_package.value; }, @@ -1289,7 +1336,8 @@ Polymer({ */ hasVisibleFields_: function(fields) { for (let i = 0; i < fields.length; ++i) { - const value = this.get(fields[i], this.managedProperties_); + const key = OncMojo.getManagedPropertyKey(fields[i]); + const value = this.get(key, this.managedProperties_); if (value !== undefined && value !== '') { return true; } @@ -1316,39 +1364,44 @@ Polymer({ } /** @type {!Array<string>} */ const fields = []; - const type = this.managedProperties_.type; - if (type == mojom.NetworkType.kCellular) { - fields.push('cellular.activationState', 'cellular.servingOperator.name'); - if (this.managedProperties_.restrictedConnectivity) { - fields.push('restrictedConnectivity'); - } - } else if (type == mojom.NetworkType.kTether) { - fields.push( - 'tether.batteryPercentage', 'tether.signalStrength', - 'tether.carrier'); - } else if (type == mojom.NetworkType.kVPN) { - const vpnType = this.managedProperties_.vpn.type; - switch (vpnType) { - case mojom.VpnType.kExtension: - fields.push('vpn.providerName'); - break; - case mojom.VpnType.kArc: - fields.push('vpn.type'); - fields.push('vpn.providerName'); - break; - case mojom.VpnType.kOpenVPN: - fields.push( - 'vpn.type', 'vpn.host', 'vpn.openVpn.username', - 'vpn.openVpn.extraHosts'); - break; - case mojom.VpnType.kL2TPIPsec: - fields.push('vpn.type', 'vpn.host', 'vpn.l2tp.username'); - break; - } - } else if (type == mojom.NetworkType.kWiFi) { - if (this.managedProperties_.restrictedConnectivity) { - fields.push('restrictedConnectivity'); - } + switch (this.managedProperties_.type) { + case mojom.NetworkType.kCellular: + fields.push( + 'cellular.activationState', 'cellular.servingOperator.name'); + if (this.managedProperties_.restrictedConnectivity) { + fields.push('restrictedConnectivity'); + } + break; + case mojom.NetworkType.kTether: + fields.push( + 'tether.batteryPercentage', 'tether.signalStrength', + 'tether.carrier'); + break; + case mojom.NetworkType.kVPN: + const vpnType = this.managedProperties_.typeProperties.vpn.type; + switch (vpnType) { + case mojom.VpnType.kExtension: + fields.push('vpn.providerName'); + break; + case mojom.VpnType.kArc: + fields.push('vpn.type'); + fields.push('vpn.providerName'); + break; + case mojom.VpnType.kOpenVPN: + fields.push( + 'vpn.type', 'vpn.host', 'vpn.openVpn.username', + 'vpn.openVpn.extraHosts'); + break; + case mojom.VpnType.kL2TPIPsec: + fields.push('vpn.type', 'vpn.host', 'vpn.l2tp.username'); + break; + } + break; + case mojom.NetworkType.kWiFi: + if (this.managedProperties_.restrictedConnectivity) { + fields.push('restrictedConnectivity'); + } + break; } return fields; }, @@ -1368,7 +1421,7 @@ Polymer({ /** @dict */ const editFields = {}; const type = this.managedProperties_.type; if (type == mojom.NetworkType.kVPN) { - const vpnType = this.managedProperties_.vpn.type; + const vpnType = this.managedProperties_.typeProperties.vpn.type; if (vpnType != mojom.VpnType.kExtension) { editFields['vpn.host'] = 'String'; } @@ -1391,15 +1444,19 @@ Polymer({ /** @type {!Array<string>} */ const fields = []; const type = this.managedProperties_.type; - if (type == mojom.NetworkType.kCellular) { - fields.push( - 'cellular.family', 'cellular.networkTechnology', - 'cellular.servingOperator.code'); - } else if (type == mojom.NetworkType.kWiFi) { - fields.push( - 'wifi.ssid', 'wifi.bssid', 'wifi.signalStrength', 'wifi.security', - 'wifi.eap.outer', 'wifi.eap.inner', 'wifi.eap.subjectMatch', - 'wifi.eap.identity', 'wifi.eap.anonymousIdentity', 'wifi.frequency'); + switch (type) { + case mojom.NetworkType.kCellular: + fields.push( + 'cellular.family', 'cellular.networkTechnology', + 'cellular.servingOperator.code'); + break; + case mojom.NetworkType.kWiFi: + fields.push( + 'wifi.ssid', 'wifi.bssid', 'wifi.signalStrength', 'wifi.security', + 'wifi.eap.outer', 'wifi.eap.inner', 'wifi.eap.subjectMatch', + 'wifi.eap.identity', 'wifi.eap.anonymousIdentity', + 'wifi.frequency'); + break; } return fields; }, @@ -1520,7 +1577,7 @@ Polymer({ showCellularChooseNetwork_: function(managedProperties) { return !!managedProperties && managedProperties.type == mojom.NetworkType.kCellular && - managedProperties.cellular.supportNetworkScan; + managedProperties.typeProperties.cellular.supportNetworkScan; }, /** @@ -1543,7 +1600,7 @@ Polymer({ showCellularSim_: function(managedProperties) { return !!managedProperties && managedProperties.type == mojom.NetworkType.kCellular && - managedProperties.cellular.family != 'CDMA'; + managedProperties.typeProperties.cellular.family != 'CDMA'; }, /** @@ -1554,7 +1611,7 @@ Polymer({ isArcVpn_: function(managedProperties) { return !!managedProperties && managedProperties.type == mojom.NetworkType.kVPN && - managedProperties.vpn.type == mojom.VpnType.kArc; + managedProperties.typeProperties.vpn.type == mojom.VpnType.kArc; }, /** @@ -1565,7 +1622,7 @@ Polymer({ isThirdPartyVpn_: function(managedProperties) { return !!managedProperties && managedProperties.type == mojom.NetworkType.kVPN && - managedProperties.vpn.type == mojom.VpnType.kExtension; + managedProperties.typeProperties.vpn.type == mojom.VpnType.kExtension; }, /** @@ -1608,5 +1665,18 @@ Polymer({ } return true; }, + + /** + * @param {boolean} outOfRange + * @param {?OncMojo.DeviceStateProperties} deviceState + * @return {boolean} + * @private + */ + isOutOfRangeOrNotEnabled_: function(outOfRange, deviceState) { + return outOfRange || + (!!deviceState && + deviceState.deviceState != + chromeos.networkConfig.mojom.DeviceStateType.kEnabled); + }, }); })(); diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js b/chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js index 2e42c952c87..3351442766d 100644 --- a/chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js +++ b/chromium/chrome/browser/resources/settings/internet_page/internet_known_networks_page.js @@ -18,20 +18,14 @@ Polymer({ properties: { /** * The type of networks to list. - * @type {CrOnc.Type} + * @type {chromeos.networkConfig.mojom.NetworkType|undefined} */ networkType: { - type: String, + type: Number, observer: 'networkTypeChanged_', }, /** - * Interface for networkingPrivate calls, passed from internet_page. - * @type {NetworkingPrivate} - */ - networkingPrivate: Object, - - /** * List of all network state data for the network type. * @private {!Array<!OncMojo.NetworkStateProperties>} */ @@ -60,12 +54,7 @@ Polymer({ /** @private {string} */ selectedGuid_: '', - /** - * This UI will use both the networkingPrivate extension API and the - * networkConfig mojo API until we provide all of the required functionality - * in networkConfig. TODO(stevenjb): Remove use of networkingPrivate api. - * @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} - */ + /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */ networkConfig_: null, /** @override */ @@ -90,13 +79,13 @@ Polymer({ * @private */ refreshNetworks_: function() { - if (!this.networkType) { + if (this.networkType === undefined) { return; } const filter = { filter: chromeos.networkConfig.mojom.FilterType.kConfigured, - limit: chromeos.networkConfig.mojom.kNoLimit, - networkType: OncMojo.getNetworkTypeFromString(this.networkType), + limit: chromeos.networkConfig.mojom.NO_LIMIT, + networkType: this.networkType, }; this.networkConfig_.getNetworkStateList(filter).then(response => { this.networkStateList_ = response.result; @@ -201,19 +190,29 @@ Polymer({ /** @private */ onRemovePreferredTap_: function() { - this.setProperties_({priority: {value: 0}}); + assert(this.networkType !== undefined); + const config = OncMojo.getDefaultConfigProperties(this.networkType); + config.priority = {value: 0}; + this.setProperties_(config); /** @type {!CrActionMenuElement} */ (this.$.dotsMenu).close(); }, /** @private */ onAddPreferredTap_: function() { - this.setProperties_({priority: {value: 1}}); + assert(this.networkType !== undefined); + const config = OncMojo.getDefaultConfigProperties(this.networkType); + config.priority = {value: 1}; + this.setProperties_(config); /** @type {!CrActionMenuElement} */ (this.$.dotsMenu).close(); }, /** @private */ onForgetTap_: function() { - this.networkingPrivate.forgetNetwork(this.selectedGuid_); + this.networkConfig_.forgetNetwork(this.selectedGuid_).then(response => { + if (!response.success) { + console.error('Froget network failed for: ' + this.selectedGuid_); + } + }); /** @type {!CrActionMenuElement} */ (this.$.dotsMenu).close(); }, diff --git a/chromium/chrome/browser/resources/settings/internet_page/internet_page.html b/chromium/chrome/browser/resources/settings/internet_page/internet_page.html index 10eeff05b0a..f9b99636a51 100644 --- a/chromium/chrome/browser/resources/settings/internet_page/internet_page.html +++ b/chromium/chrome/browser/resources/settings/internet_page/internet_page.html @@ -1,7 +1,7 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_components/chromeos/network/mojo_interface_provider.html"> -<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_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_icon_button/cr_icon_button.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> @@ -49,13 +49,12 @@ </cr-expand-button> <template is="dom-if" if="[[addConnectionExpanded_]]"> <div class="list-frame vertical-list"> - <template is="dom-if" - if="[[deviceIsEnabled_(deviceStates, 'WiFi')]]"> + <template is="dom-if" if="[[wifiIsEnabled_(deviceStates)]]"> <div actionable class="list-item" on-click="onAddWiFiTap_"> <div class="start settings-box-text"> $i18n{internetAddWiFi} </div> - <cr-icon-button class$="[[getAddNetworkClass_('WiFi')]]" + <cr-icon-button class="icon-add-wifi" aria-label="$i18n{internetAddWiFi}"></cr-icon-button> </div> </template> @@ -63,7 +62,7 @@ <div class="start settings-box-text"> $i18n{internetAddVPN} </div> - <cr-icon-button class$="[[getAddNetworkClass_('VPN')]]" + <cr-icon-button class="icon-add-circle" aria-label="$i18n{internetAddVPN}"></cr-icon-button> </div> <template is="dom-repeat" items="[[vpnProviders_]]"> @@ -96,7 +95,6 @@ <settings-internet-detail-page prefs="{{prefs}}" default-network="[[defaultNetwork]]" global-policy="[[globalPolicy_]]" - networking-private="[[networkingPrivate]]" managed-network-available="[[managedNetworkAvailable]]"> </settings-internet-detail-page> </settings-subpage> @@ -105,8 +103,7 @@ <template is="dom-if" route-path="/knownNetworks" no-search restamp> <settings-subpage page-title="$i18n{internetKnownNetworksPageTitle}"> <settings-internet-known-networks-page - network-type="[[knownNetworksType_]]" - networking-private="[[networkingPrivate]]"> + network-type="[[knownNetworksType_]]"> </settings-internet-known-networks-page> </settings-subpage> </template> @@ -128,10 +125,10 @@ </settings-animated-pages> - <internet-config id="configDialog" - networking-private="[[networkingPrivate]]" - global-policy="[[globalPolicy_]]"> - </internet-config> + <template is="dom-if" if="[[showInternetConfig_]]" restamp> + <internet-config id="configDialog" on-close="onInternetConfigClose_"> + </internet-config> + </template> </template> <script src="internet_page.js"></script> 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 1737c822b40..8f2b2d7b745 100644 --- a/chromium/chrome/browser/resources/settings/internet_page/internet_page.js +++ b/chromium/chrome/browser/resources/settings/internet_page/internet_page.js @@ -22,14 +22,6 @@ Polymer({ ], properties: { - /** - * Interface for networkingPrivate calls. May be overriden by tests. - * @type {NetworkingPrivate} - */ - networkingPrivate: { - type: Object, - value: chrome.networkingPrivate, - }, /** Preferences state. */ prefs: { @@ -65,16 +57,18 @@ Polymer({ showSpinner_: Boolean, /** - * The network type for the networks subpage. Used in the subpage header. + * The network type for the networks subpage when shown. + * @type {chromeos.networkConfig.mojom.NetworkType} * @private */ - subpageType_: String, + subpageType_: Number, /** - * The network type for the known networks subpage. + * The network type for the known networks subpage when shown. + * @type {chromeos.networkConfig.mojom.NetworkType} * @private */ - knownNetworksType_: String, + knownNetworksType_: Number, /** * Whether the 'Add connection' section is expanded. @@ -109,6 +103,12 @@ Polymer({ } }, + /** @private {boolean} */ + showInternetConfig_: { + type: Boolean, + value: false, + }, + /** @private {!Map<string, Element>} */ focusConfig_: { type: Object, @@ -118,8 +118,11 @@ Polymer({ }, }, - /** @private {string} Type of last detail page visited. */ - detailType_: '', + /** + * Type of last detail page visited + * @private {chromeos.networkConfig.mojom.NetworkType|undefined} + */ + detailType_: undefined, // Element event listeners listeners: { @@ -134,12 +137,7 @@ Polymer({ /** @private {?settings.InternetPageBrowserProxy} */ browserProxy_: null, - /** - * This UI will use both the networkingPrivate extension API and the - * networkConfig mojo API until we provide all of the required functionality - * in networkConfig. TODO(stevenjb): Remove use of networkingPrivate api. - * @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} - */ + /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */ networkConfig_: null, /** @override */ @@ -170,7 +168,7 @@ Polymer({ const queryParams = settings.getQueryParameters(); const type = queryParams.get('type'); if (type) { - this.subpageType_ = type; + this.subpageType_ = OncMojo.getNetworkTypeFromString(type); } } else if (route == settings.routes.KNOWN_NETWORKS) { // Handle direct navigation to the known networks page, @@ -178,7 +176,7 @@ Polymer({ const queryParams = settings.getQueryParameters(); const type = queryParams.get('type'); if (type) { - this.knownNetworksType_ = type; + this.knownNetworksType_ = OncMojo.getNetworkTypeFromString(type); } } else if ( route != settings.routes.INTERNET && route != settings.routes.BASIC) { @@ -201,9 +199,9 @@ Polymer({ if (subPage) { element = subPage.$$('#networkList'); } - } else if (this.detailType_) { - const rowForDetailType = - this.$$('network-summary').$$(`#${this.detailType_}`); + } else if (this.detailType_ !== undefined) { + const oncType = OncMojo.getNetworkTypeString(this.detailType_); + const rowForDetailType = this.$$('network-summary').$$(`#${oncType}`); // Note: It is possible that the row is no longer present in the DOM // (e.g., when a Cellular dongle is unplugged or when Instant Tethering @@ -219,7 +217,7 @@ Polymer({ } }, - /** CrosNetworkConfigObserver impl */ + /** CrNetworkListenerBehavior override */ onVpnProvidersChanged: function() { this.networkConfig_.getVpnProviders().then(response => { const providers = response.providers; @@ -246,33 +244,48 @@ Polymer({ * @private */ onShowConfig_: function(event) { + const type = OncMojo.getNetworkTypeFromString(event.detail.type); if (!event.detail.guid) { // New configuration - this.showConfig_(true /* configAndConnect */, event.detail.type); + this.showConfig_(true /* configAndConnect */, type); } else { this.showConfig_( - false /* configAndConnect */, event.detail.type, event.detail.guid, + false /* configAndConnect */, type, event.detail.guid, event.detail.name); } }, /** * @param {boolean} configAndConnect - * @param {string} type + * @param {chromeos.networkConfig.mojom.NetworkType} type * @param {?string=} opt_guid * @param {?string=} opt_name * @private */ showConfig_: function(configAndConnect, type, opt_guid, opt_name) { - assert(type != CrOnc.Type.CELLULAR && type != CrOnc.Type.TETHER); - const configDialog = - /** @type {!InternetConfigElement} */ (this.$.configDialog); - configDialog.type = - /** @type {chrome.networkingPrivate.NetworkType} */ (type); - configDialog.guid = opt_guid || ''; - configDialog.name = opt_name || ''; - configDialog.showConnect = configAndConnect; - configDialog.open(); + assert( + type != chromeos.networkConfig.mojom.NetworkType.kCellular && + type != chromeos.networkConfig.mojom.NetworkType.kTether); + if (this.showInternetConfig_) { + return; + } + this.showInternetConfig_ = true; + // Async call to ensure dialog is stamped. + setTimeout(() => { + const configDialog = + /** @type {!InternetConfigElement} */ (this.$$('#configDialog')); + assert(!!configDialog); + configDialog.type = OncMojo.getNetworkTypeString(type); + configDialog.guid = opt_guid || ''; + configDialog.name = opt_name || ''; + configDialog.showConnect = configAndConnect; + configDialog.open(); + }); + }, + + /** @private */ + onInternetConfigClose_: function() { + this.showInternetConfig_ = false; }, /** @@ -281,11 +294,10 @@ Polymer({ */ onShowDetail_: function(event) { const networkState = event.detail; - const oncType = OncMojo.getNetworkTypeString(networkState.type); - this.detailType_ = oncType; + this.detailType_ = networkState.type; const params = new URLSearchParams; params.append('guid', networkState.guid); - params.append('type', oncType); + params.append('type', OncMojo.getNetworkTypeString(networkState.type)); params.append('name', OncMojo.getNetworkStateDisplayName(networkState)); settings.navigateTo(settings.routes.NETWORK_DETAIL, params); }, @@ -306,39 +318,31 @@ Polymer({ // The shared Cellular/Tether subpage is referred to as "Mobile". // TODO(khorimoto): Remove once Cellular/Tether are split into their own // sections. - if (this.subpageType_ == CrOnc.Type.CELLULAR || - this.subpageType_ == CrOnc.Type.TETHER) { + if (this.subpageType_ == mojom.NetworkType.kCellular || + this.subpageType_ == mojom.NetworkType.kTether) { return this.i18n('OncTypeMobile'); } - return this.i18n('OncType' + this.subpageType_); - }, - - /** - * @param {string} type - * @return {string} - * @private - */ - getAddNetworkClass_: function(type) { - return type == CrOnc.Type.WI_FI ? 'icon-add-wifi' : 'icon-add-circle'; + return this.i18n( + 'OncType' + OncMojo.getNetworkTypeString(this.subpageType_)); }, /** - * @param {string} subpageType + * @param {chromeos.networkConfig.mojom.NetworkType} subpageType * @param {!Object<!OncMojo.DeviceStateProperties>|undefined} deviceStates * @return {!OncMojo.DeviceStateProperties|undefined} * @private */ getDeviceState_: function(subpageType, deviceStates) { - if (!subpageType) { + if (subpageType === undefined) { return undefined; } // If both Tether and Cellular are enabled, use the Cellular device state // when directly navigating to the Tether page. - if (subpageType == CrOnc.Type.TETHER && + if (subpageType == mojom.NetworkType.kTether && this.deviceStates[mojom.NetworkType.kCellular]) { - subpageType = CrOnc.Type.CELLULAR; + subpageType = mojom.NetworkType.kCellular; } - return deviceStates[OncMojo.getNetworkTypeFromString(subpageType)]; + return deviceStates[subpageType]; }, /** @@ -356,7 +360,8 @@ Polymer({ * @private */ onDeviceStatesChanged_: function(newValue, oldValue) { - const wifiDeviceState = this.getDeviceState_(CrOnc.Type.WI_FI, newValue); + const wifiDeviceState = + this.getDeviceState_(mojom.NetworkType.kWiFi, newValue); let managedNetworkAvailable = false; if (wifiDeviceState) { managedNetworkAvailable = !!wifiDeviceState.managedNetworkAvailable; @@ -366,9 +371,7 @@ Polymer({ this.managedNetworkAvailable = managedNetworkAvailable; } - if (this.detailType_ && - !this.deviceStates[OncMojo.getNetworkTypeFromString( - this.detailType_)]) { + if (this.detailType_ && !this.deviceStates[this.detailType_]) { // If the device type associated with the current network has been // removed (e.g., due to unplugging a Cellular dongle), the details page, // if visible, displays controls which are no longer functional. If this @@ -385,22 +388,26 @@ Polymer({ * @private */ onShowKnownNetworks_: function(event) { - const oncType = OncMojo.getNetworkTypeString(event.detail); - this.detailType_ = oncType; - this.knownNetworksType_ = oncType; + const type = event.detail; + this.detailType_ = type; + this.knownNetworksType_ = type; const params = new URLSearchParams; - params.append('type', oncType); + params.append('type', OncMojo.getNetworkTypeString(type)); settings.navigateTo(settings.routes.KNOWN_NETWORKS, params); }, /** @private */ onAddWiFiTap_: function() { - this.showConfig_(true /* configAndConnect */, CrOnc.Type.WI_FI); + this.showConfig_( + true /* configAndConnect */, + chromeos.networkConfig.mojom.NetworkType.kWiFi); }, /** @private */ onAddVPNTap_: function() { - this.showConfig_(true /* configAndConnect */, CrOnc.Type.VPN); + this.showConfig_( + true /* configAndConnect */, + chromeos.networkConfig.mojom.NetworkType.kVPN); }, /** @@ -417,11 +424,10 @@ Polymer({ * @private */ showNetworksSubpage_: function(type) { - const oncType = OncMojo.getNetworkTypeString(type); - this.detailType_ = oncType; + this.detailType_ = type; const params = new URLSearchParams; - params.append('type', oncType); - this.subpageType_ = oncType; + params.append('type', OncMojo.getNetworkTypeString(type)); + this.subpageType_ = type; settings.navigateTo(settings.routes.INTERNET_NETWORKS, params); }, @@ -452,14 +458,13 @@ Polymer({ /** * @param {!Array<!OncMojo.DeviceStateProperties>} deviceStates - * @param {string} type * @return {boolean} * @private */ - deviceIsEnabled_: function(deviceStates, type) { - const device = deviceStates[OncMojo.getNetworkTypeFromString(type)]; - return !!device && - device.deviceState == + wifiIsEnabled_: function(deviceStates) { + const wifi = deviceStates[mojom.NetworkType.kWiFi]; + return !!wifi && + wifi.deviceState == chromeos.networkConfig.mojom.DeviceStateType.kEnabled; }, @@ -497,15 +502,15 @@ Polymer({ */ onNetworkConnect_: function(event) { const networkState = event.detail.networkState; - const oncType = OncMojo.getNetworkTypeString(networkState.type); + const type = networkState.type; const displayName = OncMojo.getNetworkStateDisplayName(networkState); if (!event.detail.bypassConnectionDialog && - networkState.type == mojom.NetworkType.kTether && - !networkState.tether.hasConnectedToHost) { + type == mojom.NetworkType.kTether && + !networkState.typeState.tether.hasConnectedToHost) { const params = new URLSearchParams; params.append('guid', networkState.guid); - params.append('type', oncType); + params.append('type', OncMojo.getNetworkTypeString(type)); params.append('name', displayName); params.append('showConfigure', true.toString()); @@ -513,10 +518,10 @@ Polymer({ return; } - const isMobile = OncMojo.networkTypeIsMobile(networkState.type); + const isMobile = OncMojo.networkTypeIsMobile(type); if (!isMobile && (!networkState.connectable || !!networkState.errorState)) { this.showConfig_( - true /* configAndConnect */, oncType, networkState.guid, displayName); + true /* configAndConnect */, type, networkState.guid, displayName); return; } @@ -532,7 +537,7 @@ Polymer({ case mojom.StartConnectResult.kNotConfigured: if (!isMobile) { this.showConfig_( - true /* configAndConnect */, oncType, networkState.guid, + true /* configAndConnect */, type, networkState.guid, displayName); } return; 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 9996d3b6538..8ce6c994e2f 100644 --- a/chromium/chrome/browser/resources/settings/internet_page/internet_subpage.js +++ b/chromium/chrome/browser/resources/settings/internet_page/internet_subpage.js @@ -120,12 +120,7 @@ Polymer({ /** @private {settings.InternetPageBrowserProxy} */ browserProxy_: null, - /** - * This UI will use both the networkingPrivate extension API and the - * networkConfig mojo API until we provide all of the required functionality - * in networkConfig. TODO(stevenjb): Remove use of networkingPrivate api. - * @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} - */ + /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */ networkConfig_: null, /** @override */ @@ -275,7 +270,7 @@ Polymer({ } const filter = { filter: chromeos.networkConfig.mojom.FilterType.kVisible, - limit: chromeos.networkConfig.mojom.kNoLimit, + limit: chromeos.networkConfig.mojom.NO_LIMIT, networkType: this.deviceState.type, }; this.networkConfig_.getNetworkStateList(filter).then(response => { @@ -298,7 +293,7 @@ Polymer({ this.tetherDeviceState) { const filter = { filter: chromeos.networkConfig.mojom.FilterType.kVisible, - limit: chromeos.networkConfig.mojom.kNoLimit, + limit: chromeos.networkConfig.mojom.NO_LIMIT, networkType: mojom.NetworkType.kTether, }; this.networkConfig_.getNetworkStateList(filter).then(response => { @@ -314,7 +309,7 @@ Polymer({ const thirdPartyVpns = {}; networkStates.forEach(state => { assert(state.type == mojom.NetworkType.kVPN); - switch (state.vpn.type) { + switch (state.typeState.vpn.type) { case mojom.VpnType.kL2TPIPsec: case mojom.VpnType.kOpenVPN: builtinNetworkStates.push(state); @@ -326,7 +321,7 @@ Polymer({ } // Otherwise Arc VPNs are treated the same as Extension VPNs. case mojom.VpnType.kExtension: - const providerId = state.vpn.providerId; + const providerId = state.typeState.vpn.providerId; thirdPartyVpns[providerId] = thirdPartyVpns[providerId] || []; thirdPartyVpns[providerId].push(state); break; @@ -354,7 +349,7 @@ Polymer({ for (const vpnList of Object.values(thirdPartyVpns)) { assert(vpnList.length > 0); // All vpns in the list will have the same type and provider id. - const vpn = vpnList[0].vpn; + const vpn = vpnList[0].typeState.vpn; const provider = { type: vpn.type, providerId: vpn.providerId, @@ -584,7 +579,8 @@ Polymer({ (!!this.globalPolicy.allowOnlyPolicyNetworksToConnectIfAvailable && !!this.deviceState && !!this.deviceState.managedNetworkAvailable) || (!!this.globalPolicy.blockedHexSsids && - this.globalPolicy.blockedHexSsids.includes(state.wifi.hexSsid)); + this.globalPolicy.blockedHexSsids.includes( + state.typeState.wifi.hexSsid)); }, /** diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_proxy_section.html b/chromium/chrome/browser/resources/settings/internet_page/network_proxy_section.html index a061a6e92ab..f44b433b079 100644 --- a/chromium/chrome/browser/resources/settings/internet_page/network_proxy_section.html +++ b/chromium/chrome/browser/resources/settings/internet_page/network_proxy_section.html @@ -1,7 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_components/chromeos/network/network_proxy.html"> -<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_proxy_section.js b/chromium/chrome/browser/resources/settings/internet_page/network_proxy_section.js index 3827c8cbf37..f04803663de 100644 --- a/chromium/chrome/browser/resources/settings/internet_page/network_proxy_section.js +++ b/chromium/chrome/browser/resources/settings/internet_page/network_proxy_section.js @@ -60,12 +60,12 @@ Polymer({ }, /** - * @return {!OncMojo.ManagedProperty|undefined} + * @return {!mojom.ManagedString|undefined} * @private */ getProxySettingsTypeProperty_: function() { - return /** @type {!OncMojo.ManagedProperty|undefined} */ ( - this.get('proxySettings.type', this.managedProperties)); + const proxySettings = this.managedProperties.proxySettings; + return proxySettings ? proxySettings.type : undefined; }, /** diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_summary.js b/chromium/chrome/browser/resources/settings/internet_page/network_summary.js index ac6a45c2d31..bc02417ee3e 100644 --- a/chromium/chrome/browser/resources/settings/internet_page/network_summary.js +++ b/chromium/chrome/browser/resources/settings/internet_page/network_summary.js @@ -149,7 +149,7 @@ Polymer({ getNetworkStates_: function(deviceStateList) { const filter = { filter: chromeos.networkConfig.mojom.FilterType.kVisible, - limit: chromeos.networkConfig.mojom.kNoLimit, + limit: chromeos.networkConfig.mojom.NO_LIMIT, networkType: mojom.NetworkType.kAll, }; this.networkConfig_.getNetworkStateList(filter).then(response => { diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_summary_item.html b/chromium/chrome/browser/resources/settings/internet_page/network_summary_item.html index 5b26c96577a..4c6312d3dc0 100644 --- a/chromium/chrome/browser/resources/settings/internet_page/network_summary_item.html +++ b/chromium/chrome/browser/resources/settings/internet_page/network_summary_item.html @@ -2,7 +2,7 @@ <link rel="import" href="chrome://resources/cr_components/chromeos/network/network_siminfo.html"> <link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_icon.html"> -<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_strings.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html"> diff --git a/chromium/chrome/browser/resources/settings/internet_page/network_summary_item.js b/chromium/chrome/browser/resources/settings/internet_page/network_summary_item.js index 09cbcd3965e..7b26f618a41 100644 --- a/chromium/chrome/browser/resources/settings/internet_page/network_summary_item.js +++ b/chromium/chrome/browser/resources/settings/internet_page/network_summary_item.js @@ -132,7 +132,12 @@ Polymer({ const connectionState = networkState.connectionState; const name = OncMojo.getNetworkStateDisplayName(networkState); if (OncMojo.connectionStateIsConnected(connectionState)) { - return name; + // Ethernet networks always have the display name 'Ethernet' so we use the + // state text 'Connected' to avoid repeating the label in the sublabel. + // See http://crbug.com/989907 for details. + return networkState.type == mojom.NetworkType.kEthernet ? + CrOncStrings.networkListItemConnected : + name; } if (connectionState == mojom.ConnectionStateType.kConnecting) { return name ? @@ -282,14 +287,22 @@ Polymer({ const type = deviceState.type; if (type == mojom.NetworkType.kTether || (type == mojom.NetworkType.kCellular && this.tetherDeviceState)) { - // The "Mobile data" subpage should always be shown if Tether networks are + // The "Mobile data" subpage should always be shown if Tether is // available, even if there are currently no associated networks. return true; } - const minlen = - (type == mojom.NetworkType.kWiFi || type == mojom.NetworkType.kVPN) ? - 1 : - 2; + let minlen; + if (type == mojom.NetworkType.kVPN) { + // VPN subpage provides provider info so show if there are any networks. + minlen = 1; + } else if (type == mojom.NetworkType.kWiFi) { + // WiFi subpage includes 'Known Networks' so always show, even if the + // technology is still enabling / scanning, or none are visible. + minlen = 0; + } else { + // By default, only show the subpage if there are 2+ networks + minlen = 2; + } return networkStateList.length >= minlen; }, diff --git a/chromium/chrome/browser/resources/settings/internet_page/tether_connection_dialog.js b/chromium/chrome/browser/resources/settings/internet_page/tether_connection_dialog.js index 5a7c6beff6f..cce1a1de45c 100644 --- a/chromium/chrome/browser/resources/settings/internet_page/tether_connection_dialog.js +++ b/chromium/chrome/browser/resources/settings/internet_page/tether_connection_dialog.js @@ -79,27 +79,20 @@ Polymer({ * @private */ getBatteryPercentageAsString_: function(managedProperties) { - const percentage = this.get('tether.batteryPercentage', managedProperties); - if (percentage === undefined) { - return ''; - } - return percentage.toString(); + return managedProperties.typeProperties.tether.batteryPercentage.toString(); }, /** * Retrieves an image that corresponds to signal strength of the tether host. * Custom icons are used here instead of a <cr-network-icon> because this * dialog uses a special color scheme. - * * @param {!mojom.ManagedProperties} managedProperties * @return {string} The name of the icon to be used to represent the network's - * signal strength. + * signal strength. */ getSignalStrengthIconName_: function(managedProperties) { - let signalStrength = this.get('tether.signalStrength', managedProperties); - if (signalStrength === undefined) { - signalStrength = 4; - } + const signalStrength = + managedProperties.typeProperties.tether.signalStrength; return 'os-settings:signal-cellular-' + Math.min(4, Math.max(signalStrength, 0)) + '-bar'; }, diff --git a/chromium/chrome/browser/resources/settings/languages_page/edit_dictionary_page.html b/chromium/chrome/browser/resources/settings/languages_page/edit_dictionary_page.html index c3732a62e48..a6905ca7fbf 100644 --- a/chromium/chrome/browser/resources/settings/languages_page/edit_dictionary_page.html +++ b/chromium/chrome/browser/resources/settings/languages_page/edit_dictionary_page.html @@ -56,9 +56,12 @@ scroll-target="[[subpageScrollTarget]]"> <template> <div class="list-item"> - <div class="word text-elide">[[item]]</div> + <div id$="word[[index]]" class="word text-elide">[[item]]</div> <cr-icon-button class="icon-clear" on-click="onRemoveWordTap_" - tabindex$="[[tabIndex]]"></cr-icon-button> + tabindex$="[[tabIndex]]" + title="$i18n{deleteDictionaryWordButton}" + aria-describedby$="word[[index]]"> + </cr-icon-button> </div> </template> </iron-list> diff --git a/chromium/chrome/browser/resources/settings/manifest.json b/chromium/chrome/browser/resources/settings/manifest.json index c7a72e04e30..acbaa3c103e 100644 --- a/chromium/chrome/browser/resources/settings/manifest.json +++ b/chromium/chrome/browser/resources/settings/manifest.json @@ -1,5 +1,5 @@ { - "name": "Settings", + "name": "$i18nRaw{name}", "display": "standalone", "icons": [ { diff --git a/chromium/chrome/browser/resources/settings/multidevice_page/BUILD.gn b/chromium/chrome/browser/resources/settings/multidevice_page/BUILD.gn index 7818234969e..a35e2871de8 100644 --- a/chromium/chrome/browser/resources/settings/multidevice_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/multidevice_page/BUILD.gn @@ -109,7 +109,6 @@ if (is_chromeos) { ":multidevice_feature_behavior", "..:route", "//ui/webui/resources/cr_elements/chromeos/network:cr_network_listener_behavior", - "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types", "//ui/webui/resources/js/chromeos:onc_mojo", ] externs_list = [ "$externs_path/networking_private.js" ] diff --git a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_subpage.html b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_subpage.html index 2e75dd98bd0..55a72bcb020 100644 --- a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_subpage.html +++ b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_subpage.html @@ -31,10 +31,6 @@ #feature-items-container { @apply --settings-list-frame-padding; } - - #forget-device-container { - border-top: var(--cr-separator-line); - } </style> <div class="settings-box first"> <div id="status-text-container" @@ -99,11 +95,17 @@ </template> </div> </template> - <div id="forget-device-container"> - <cr-link-row id="forget-device" class="hr" - on-click="handleForgetDeviceClick_" - label="$i18n{multideviceForgetDevice}" - sub-label="$i18n{multideviceForgetDeviceSummary}"></cr-link-row> + <div class="settings-box two-line"> + <div id="forget-device-label" class="start"> + $i18n{multideviceForgetDevice} + <div class="secondary"> + $i18n{multideviceForgetDeviceSummary} + </div> + </div> + <cr-button on-click="handleForgetDeviceClick_" + aria-labelledby="forgetDeviceLabel"> + $i18n{multideviceForgetDeviceDisconnect} + </cr-button> </div> <cr-dialog id="forgetDeviceDialog"> <div slot="title">$i18n{multideviceForgetDevice}</div> @@ -120,7 +122,7 @@ <cr-button id="confirmButton" class="action-button" on-click="onForgetDeviceDialogConfirmClick_"> - $i18n{confirm} + $i18n{multideviceForgetDeviceDisconnect} </cr-button> </div> </cr-dialog> diff --git a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_tether_item.html b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_tether_item.html index 326a4c50e00..4809023c3b1 100644 --- a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_tether_item.html +++ b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_tether_item.html @@ -1,6 +1,5 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_icon.html"> <link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_network_listener_behavior.html"> <link rel="import" href="chrome://resources/html/chromeos/onc_mojo.html"> diff --git a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_tether_item.js b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_tether_item.js index fe69ece9bc2..d9ab5429c4c 100644 --- a/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_tether_item.js +++ b/chromium/chrome/browser/resources/settings/multidevice_page/multidevice_tether_item.js @@ -165,6 +165,6 @@ Polymer({ * @private */ getTetherNetworkUrlSearchParams_: function() { - return new URLSearchParams('type=' + CrOnc.Type.TETHER); + return new URLSearchParams('type=Tether'); }, }); diff --git a/chromium/chrome/browser/resources/settings/os_settings_manifest.json b/chromium/chrome/browser/resources/settings/os_settings_manifest.json index b5aa51b98e5..adbabe2f7bb 100644 --- a/chromium/chrome/browser/resources/settings/os_settings_manifest.json +++ b/chromium/chrome/browser/resources/settings/os_settings_manifest.json @@ -1,5 +1,5 @@ { - "name": "Settings", + "name": "$i18nRaw{name}", "display": "standalone", "icons": [ { diff --git a/chromium/chrome/browser/resources/settings/os_settings_resources.grd b/chromium/chrome/browser/resources/settings/os_settings_resources.grd index 8338d49eb90..9d683c7b298 100644 --- a/chromium/chrome/browser/resources/settings/os_settings_resources.grd +++ b/chromium/chrome/browser/resources/settings/os_settings_resources.grd @@ -121,12 +121,6 @@ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_PERMISSION_ITEM_HTML" file="chromeos/os_apps_page/app_management_page/permission_item.html" type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_PERMISSION_TOGGLE_JS" - file="chromeos/os_apps_page/app_management_page/permission_toggle.js" - type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_PERMISSION_TOGGLE_HTML" - file="chromeos/os_apps_page/app_management_page/permission_toggle.html" - type="chrome_html" /> <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_PIN_TO_SHELF_ITEM_JS" file="chromeos/os_apps_page/app_management_page/pin_to_shelf_item.js" type="chrome_html" /> @@ -157,12 +151,6 @@ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_CHROME_APP_PERMISSION_VIEW_HTML" file="chromeos/os_apps_page/app_management_page/chrome_app_permission_view.html" type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_ROUTER_JS" - file="chromeos/os_apps_page/app_management_page/router.js" - type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_ROUTER_HTML" - file="chromeos/os_apps_page/app_management_page/router.html" - type="chrome_html" /> <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_ICONS_HTML" file="chromeos/os_apps_page/app_management_page/icons.html" type="chrome_html" /> @@ -172,6 +160,18 @@ <structure name="IDR_OS_SETTINGS_APP_MANAGEMENT_PAGE_APP_UNINSTALL_BUTTON_HTML" file="chromeos/os_apps_page/app_management_page/uninstall_button.html" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_CAPTIONS_SUBPAGE_JS" + file="a11y_page/captions_subpage.js" + type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_CAPTIONS_SUBPAGE_HTML" + file="a11y_page/captions_subpage.html" + type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_FONTS_BROWSER_PROXY_HTML" + file="appearance_page/fonts_browser_proxy.html" + type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_FONTS_BROWSER_PROXY_JS" + file="appearance_page/fonts_browser_proxy.js" + type="chrome_html" /> <structure name="IDR_OS_SETTINGS_MANAGE_A11Y_PAGE_JS" file="a11y_page/manage_a11y_page.js" type="chrome_html" /> @@ -517,12 +517,6 @@ <structure name="IDR_OS_SETTINGS_DEVICE_DISPLAY_OVERSCAN_DIALOG_JS" file="device_page/display_overscan_dialog.js" type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_DEVICE_DRIVE_CACHE_DIALOG_HTML" - file="device_page/drive_cache_dialog.html" - type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_DEVICE_DRIVE_CACHE_DIALOG_JS" - file="device_page/drive_cache_dialog.js" - type="chrome_html" /> <structure name="IDR_OS_SETTINGS_DEVICE_KEYBOARD_HTML" file="device_page/keyboard.html" type="chrome_html" /> @@ -775,11 +769,17 @@ <structure name="IDR_OS_SETTINGS_CUPS_PRINTERS_ENTRY_JS" file="printing_page/cups_printers_entry.js" type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_CUPS_PRINTERS_ENTRY_LIST_HTML" - file="printing_page/cups_printers_entry_list.html" + <structure name="IDR_OS_SETTINGS_CUPS_PRINTERS_ENTRY_LIST_BEHAVIOR_HTML" + file="printing_page/cups_printers_entry_list_behavior.html" + type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_CUPS_PRINTERS_ENTRY_LIST_BEHAVIOR_JS" + file="printing_page/cups_printers_entry_list_behavior.js" + type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_CUPS_PRINTERS_ENTRY_MANAGER_HTML" + file="printing_page/cups_printers_entry_manager.html" type="chrome_html" /> - <structure name="IDR_OS_SETTINGS_CUPS_PRINTERS_ENTRY_LIST_JS" - file="printing_page/cups_printers_entry_list.js" + <structure name="IDR_OS_SETTINGS_CUPS_PRINTERS_ENTRY_MANAGER_JS" + file="printing_page/cups_printers_entry_manager.js" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_CUPS_PRINTERS_LIST_HTML" file="printing_page/cups_printers_list.html" diff --git a/chromium/chrome/browser/resources/settings/people_page/account_manager.html b/chromium/chrome/browser/resources/settings/people_page/account_manager.html index 3addbf6027c..f5d9d8bc29f 100644 --- a/chromium/chrome/browser/resources/settings/people_page/account_manager.html +++ b/chromium/chrome/browser/resources/settings/people_page/account_manager.html @@ -4,6 +4,7 @@ <link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html"> +<link rel="import" href="chrome://resources/cr_elements/policy/cr_tooltip_icon.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/html/icon.html"> <link rel="import" href="chrome://resources/html/util.html"> @@ -44,8 +45,17 @@ margin-inline-start: 60px; } - #account-list-header { - padding-bottom: 8px; + .secondary-accounts-policy-indicator { + margin-inline-end: 12px; + } + + .settings-box.user-message { + align-items: flex-end; + } + + #account-list-header > h2 { + padding-bottom: 12px; + padding-top: 12px; } cr-policy-indicator { @@ -54,7 +64,8 @@ } #add-account-button { - margin-top: var(--add-account-margin-top); + margin-bottom: 12px; + margin-top: 12px; } #add-account-icon { @@ -88,6 +99,11 @@ .management-status { color: var(--cr-secondary-text-color); } + + .tooltip-primary-account { + margin-inline-end: 12px; + margin-inline-start: 12px; + } </style> <div class="settings-box first"> @@ -99,14 +115,21 @@ </span> </div> + <div id="settings-box-user-message" class="settings-box first user-message" + hidden="[[isSecondaryGoogleAccountSigninAllowed_()]]"> + <cr-policy-pref-indicator class="secondary-accounts-policy-indicator" + pref= + "[[prefs.account_manager.secondary_google_account_signin_allowed]]"> + </cr-policy-pref-indicator> + <div id="user-message-text" class="secondary"> + [[getSecondaryAccountsDisabledUserMessage_()]] + </div> + </div> + <div class="settings-box first"> <div id="account-list-header" class="flex"> <h2>$i18n{accountListHeader}</h2> </div> - <cr-policy-indicator - hidden="[[isSecondaryGoogleAccountSigninAllowed_()]]" - indicator-type="userPolicy"> - </cr-policy-indicator> <cr-button disabled="[[!isSecondaryGoogleAccountSigninAllowed_()]]" id="add-account-button" on-tap="addAccount_"> <div id="add-account-icon"></div> @@ -152,6 +175,11 @@ <!-- If this is the Device Account, display the management status --> <template is="dom-if" if="[[item.isDeviceAccount]]"> + <cr-tooltip-icon icon-class="cr:info-outline" + class="tooltip-primary-account" + tooltip-text="$i18n{accountManagerPrimaryAccountTooltip}" + icon-aria-label="$i18n{accountManagerPrimaryAccountTooltip}"> + </cr-tooltip-icon> <span class="management-status"> [[getManagementLabel_(item)]] </span> diff --git a/chromium/chrome/browser/resources/settings/people_page/account_manager.js b/chromium/chrome/browser/resources/settings/people_page/account_manager.js index 8613c1262a3..e5cecdcd17f 100644 --- a/chromium/chrome/browser/resources/settings/people_page/account_manager.js +++ b/chromium/chrome/browser/resources/settings/people_page/account_manager.js @@ -70,6 +70,17 @@ Polymer({ }, /** + * @return {string} 'Secondary Accounts disabled' message depending on + * account type + * @private + */ + getSecondaryAccountsDisabledUserMessage_: function() { + return loadTimeData.getBoolean('isChild') + ? this.i18n('accountManagerSecondaryAccountsDisabledChildText') + : this.i18n('accountManagerSecondaryAccountsDisabledText'); + }, + + /** * @param {string} iconUrl * @return {string} A CSS image-set for multiple scale factors. * @private diff --git a/chromium/chrome/browser/resources/settings/people_page/setup_pin_dialog.html b/chromium/chrome/browser/resources/settings/people_page/setup_pin_dialog.html index ec1fb7827e3..093bace2c14 100644 --- a/chromium/chrome/browser/resources/settings/people_page/setup_pin_dialog.html +++ b/chromium/chrome/browser/resources/settings/people_page/setup_pin_dialog.html @@ -13,6 +13,10 @@ <style include="settings-shared"> #pinKeyboardDiv { justify-content: center; + }; + + #pinKeyboard { + --cr-input-placeholder-letter-spacing: normal; } </style> <cr-dialog id="dialog" on-close="close" @@ -28,7 +32,8 @@ on-set-pin-done="onSetPinDone_" set-modes="{{setModes}}" quick-unlock-private="[[quickUnlockPrivate]]" - write-uma="[[writeUma_]]"> + write-uma="[[writeUma_]]" + enable-placeholder> </setup-pin-keyboard> </div> </div> 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 fd28dad676a..e65b7efd44b 100644 --- a/chromium/chrome/browser/resources/settings/people_page/sync_page.js +++ b/chromium/chrome/browser/resources/settings/people_page/sync_page.js @@ -506,7 +506,10 @@ Polymer({ case settings.PageStatus.PASSPHRASE_FAILED: if (this.pageStatus_ == this.pages_.CONFIGURE && this.syncPrefs && this.syncPrefs.passphraseRequired) { - this.$$('#existingPassphraseInput').invalid = true; + const passphraseInput = /** @type {!CrInputElement} */ ( + this.$$('#existingPassphraseInput')); + passphraseInput.invalid = true; + passphraseInput.focusInput(); } return; } diff --git a/chromium/chrome/browser/resources/settings/people_page/user_list.html b/chromium/chrome/browser/resources/settings/people_page/user_list.html index f6ba5eba5bd..dbc871abac2 100644 --- a/chromium/chrome/browser/resources/settings/people_page/user_list.html +++ b/chromium/chrome/browser/resources/settings/people_page/user_list.html @@ -47,8 +47,10 @@ <div class="user layout horizontal center two-line"> <img class="user-icon" src="[[getProfilePictureUrl_(item)]]"> <div class="flex layout vertical user-info no-min-width"> - <div class="text-elide">[[getUserName_(item)]]</div> - <div class="secondary text-elide" + <div class="text-elide" title="[[getTooltip_(item)]]"> + [[getUserName_(item)]] + </div> + <div class="secondary text-elide" title="[[item.displayEmail]]" hidden$="[[!shouldShowEmail_(item)]]"> [[item.displayEmail]] </div> diff --git a/chromium/chrome/browser/resources/settings/people_page/user_list.js b/chromium/chrome/browser/resources/settings/people_page/user_list.js index 66786887296..066f71f607c 100644 --- a/chromium/chrome/browser/resources/settings/people_page/user_list.js +++ b/chromium/chrome/browser/resources/settings/people_page/user_list.js @@ -123,4 +123,14 @@ Polymer({ shouldShowEmail_: function(user) { return !user.isSupervised && user.name != user.displayEmail; }, + + /** + * Use this function to prevent tooltips from displaying for user names. We + * only want to display tooltips for email addresses. + * @param {chrome.usersPrivate.User} user + * @private + */ + getTooltip_: function(user) { + return !this.shouldShowEmail_(user) ? user.displayEmail : ''; + }, }); diff --git a/chromium/chrome/browser/resources/settings/people_page/users_add_user_dialog.html b/chromium/chrome/browser/resources/settings/people_page/users_add_user_dialog.html index e1caa97fc46..cbcbc0b24d5 100644 --- a/chromium/chrome/browser/resources/settings/people_page/users_add_user_dialog.html +++ b/chromium/chrome/browser/resources/settings/people_page/users_add_user_dialog.html @@ -10,17 +10,17 @@ <dom-module id="settings-users-add-user-dialog"> <template> <style include="settings-shared"> - cr-input { - width: var(--settings-input-max-width); - --cr-input-error-display: none; + cr-dialog::part(dialog) { + width: 320px; } </style> <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">$i18n{addUsers}</div> <div slot="body"> <cr-input id="addUserInput" label="$i18n{addUsersEmail}" - invalid="[[shouldShowError_(isEmail_, isEmpty_)]]" - on-value-changed="onInput_" autofocus> + invalid="[[shouldShowError_(errorCode_)]]" + on-value-changed="onInput_" + error-message="[[getErrorString_(errorCode_)]]" autofocus> </cr-input> </div> <div slot="button-container"> diff --git a/chromium/chrome/browser/resources/settings/people_page/users_add_user_dialog.js b/chromium/chrome/browser/resources/settings/people_page/users_add_user_dialog.js index 3721024821d..a68a908b4b6 100644 --- a/chromium/chrome/browser/resources/settings/people_page/users_add_user_dialog.js +++ b/chromium/chrome/browser/resources/settings/people_page/users_add_user_dialog.js @@ -29,11 +29,26 @@ const EMAIL_REGEX = new RegExp( '^\\s*([\\w\\.!#\\$%&\'\\*\\+-\\/=\\?\\^`\\{\\|\\}~]+)@' + '([A-Za-z0-9\-]{2,63}\\..+)\\s*$'); +/** @enum {number} */ +const UserAddError = { + NO_ERROR: 0, + INVALID_EMAIL: 1, + USER_EXISTS: 2, +}; + Polymer({ is: 'settings-users-add-user-dialog', + behaviors: [I18nBehavior], + properties: { /** @private */ + errorCode_: { + type: Number, + value: UserAddError.NO_ERROR, + }, + + /** @private */ isEmail_: { type: Boolean, value: false, @@ -46,6 +61,8 @@ Polymer({ }, }, + usersPrivate_: chrome.usersPrivate, + open: function() { this.$.addUserInput.value = ''; this.onInput_(); @@ -74,11 +91,20 @@ Polymer({ userEmail = emailMatches[1] + '@' + emailMatches[2]; } - chrome.usersPrivate.addWhitelistedUser( - userEmail, - /* callback */ function(success) {}); - this.$.addUserInput.value = ''; - this.$.dialog.close(); + this.usersPrivate_.isWhitelistedUser(userEmail, doesUserExist => { + if (doesUserExist) { + // This user email had been saved previously + this.errorCode_ = UserAddError.USER_EXISTS; + return; + } + + this.$.dialog.close(); + this.usersPrivate_.addWhitelistedUser( + userEmail, + /* callback */ function(success) {}); + + this.$.addUserInput.value = ''; + }); }, /** @@ -99,6 +125,13 @@ Polymer({ const input = this.$.addUserInput.value; this.isEmail_ = NAME_ONLY_REGEX.test(input) || EMAIL_REGEX.test(input); this.isEmpty_ = input.length == 0; + + if (!this.isEmail_ && !this.isEmpty_) { + this.errorCode_ = UserAddError.INVALID_EMAIL; + return; + } + + this.errorCode_ = UserAddError.NO_ERROR; }, /** @@ -106,7 +139,20 @@ Polymer({ * @return {boolean} */ shouldShowError_: function() { - return !this.isEmail_ && !this.isEmpty_; + return this.errorCode_ != UserAddError.NO_ERROR; + }, + + /** + * @private + * @return {string} + */ + getErrorString_: function(errorCode_) { + if (errorCode_ == UserAddError.USER_EXISTS) { + return this.i18n('userExistsError'); + } + //TODO errorString for UserAddError.INVALID_EMAIL crbug/1007481 + + return ''; }, }); diff --git a/chromium/chrome/browser/resources/settings/printing_page/BUILD.gn b/chromium/chrome/browser/resources/settings/printing_page/BUILD.gn index e7619959244..00b021d9f12 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/printing_page/BUILD.gn @@ -21,7 +21,8 @@ js_type_check("closure_compile") { ":cups_printers", ":cups_printers_browser_proxy", ":cups_printers_entry", - ":cups_printers_entry_list", + ":cups_printers_entry_list_behavior", + ":cups_printers_entry_manager", ":cups_printers_list", ":cups_saved_printers", ":printing_browser_proxy", @@ -82,6 +83,10 @@ if (is_chromeos) { deps = [ ":cups_printer_types", ":cups_printers_browser_proxy", + ":cups_printers_entry", + ":cups_printers_entry_list_behavior", + ":cups_printers_entry_manager", + "//ui/webui/resources/js:list_property_update_behavior", "//ui/webui/resources/js:web_ui_listener_behavior", ] } @@ -102,6 +107,7 @@ if (is_chromeos) { deps = [ ":cups_nearby_printers", ":cups_printers_browser_proxy", + ":cups_printers_entry_manager", ":cups_saved_printers", "..:route", "//ui/webui/resources/cr_components/chromeos/network:mojo_interface_provider", @@ -128,14 +134,22 @@ if (is_chromeos) { ] } - js_library("cups_printers_entry_list") { + js_library("cups_printers_entry_list_behavior") { deps = [ ":cups_printer_types", - ":cups_printers_browser_proxy", "//ui/webui/resources/js:list_property_update_behavior", ] } + js_library("cups_printers_entry_manager") { + deps = [ + ":cups_printer_types", + ":cups_printers_browser_proxy", + "//ui/webui/resources/js:assert", + "//ui/webui/resources/js:cr", + ] + } + js_library("cups_printers_list") { deps = [ ":cups_printers_browser_proxy", @@ -149,7 +163,11 @@ if (is_chromeos) { deps = [ ":cups_printer_types", ":cups_printers_browser_proxy", + ":cups_printers_entry", + ":cups_printers_entry_list_behavior", + ":cups_printers_entry_manager", "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu", + "//ui/webui/resources/js:list_property_update_behavior", "//ui/webui/resources/js:web_ui_listener_behavior", ] } diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html b/chromium/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html index 7c9a314bf87..f19b1047748 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html @@ -78,7 +78,8 @@ <template> <style include="cups-printer-shared"></style> <add-printer-dialog> - <div slot="dialog-title">$i18n{addPrintersManuallyTitle}</div> + <div slot="dialog-title"> + $i18n{addPrintersManuallyTitle} <div id="general-error-container" hidden="[[!errorText_]]"> <div id="general-error"> <iron-icon id="general-error-icon" icon="cr:warning"></iron-icon> @@ -87,6 +88,7 @@ </div> </div> </div> + </div> <div slot="dialog-body"> <div class="settings-box first two-line"> <cr-input class="printer-name-input" autofocus diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js b/chromium/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js index 7f78d1dfb77..6b2ceffcc92 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js @@ -445,7 +445,7 @@ Polymer({ .getNetworkStateList({ filter: chromeos.networkConfig.mojom.FilterType.kActive, networkType: chromeos.networkConfig.mojom.NetworkType.kAll, - limit: chromeos.networkConfig.mojom.kNoLimit, + limit: chromeos.networkConfig.mojom.NO_LIMIT, }) .then((responseParams) => { this.onActiveNetworksChanged(responseParams.result); diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.html b/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.html index 7d6bf1824d2..da0573be5ea 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.html +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.html @@ -1,26 +1,39 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/html/list_property_update_behavior.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html"> <link rel="import" href="cups_printer_types.html"> <link rel="import" href="cups_printers_browser_proxy.html"> -<link rel="import" href="cups_printers_entry_list.html"> +<link rel="import" href="cups_printers_entry_list_behavior.html"> +<link rel="import" href="cups_printers_entry.html"> +<link rel="import" href="cups_printers_entry_manager.html"> <link rel="import" href="../settings_shared_css.html"> <dom-module id="settings-cups-nearby-printers"> <template> - <style include="settings-shared"> - #noPrinterMessage { - margin-inline-start: 60px; + <style include="cups-printer-shared"> + :host { + display: flex; + flex-direction: column; + } + + #no-search-results { margin-top: 20px; } </style> - <settings-cups-printers-entry-list printers="[[nearbyPrinters_]]" - search-term="[[searchTerm]]"> - </settings-cups-printers-entry-list> - <div class="secondary" id="noPrinterMessage" - hidden="[[!shouldShowNoNearbyPrinterMessage_(searchTerm, - nearbyPrinters_)]]"> - $i18n{noPrinterNearbyMessage} + + <iron-list class="list-frame vertical-list flex-auto" id="printerEntryList" + items="[[filteredPrinters_]]"> + <template> + <settings-cups-printers-entry printer-entry="[[item]]"> + </settings-cups-printers-entry> + </template> + </iron-list> + <div id="no-search-results" + hidden="[[!showNoSearchResultsMessage_(searchTerm, + filteredPrinters_.*)]]"> + $i18n{noSearchResults} </div> </template> <script src="cups_nearby_printers.js"></script> diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.js b/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.js index aa4912c4010..f4020c2e390 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.js +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.js @@ -9,20 +9,16 @@ Polymer({ is: 'settings-cups-nearby-printers', - behaviors: [WebUIListenerBehavior], + // ListPropertyUpdateBehavior is used in CupsPrintersEntryListBehavior. + behaviors: [ + CupsPrintersEntryListBehavior, + ListPropertyUpdateBehavior, + WebUIListenerBehavior, + ], properties: { /** - * @type {!Array<!PrinterListEntry>} - * @private - */ - nearbyPrinters_: { - type: Array, - value: () => [], - }, - - /** - * Search term for filtering |nearbyPrinters_|. + * Search term for filtering |nearbyPrinters|. * @type {string} */ searchTerm: { @@ -30,6 +26,12 @@ Polymer({ value: '', }, + /** @type {?CupsPrinterInfo} */ + activePrinter: { + type: Object, + notify: true, + }, + /** * @type {number} * @private @@ -39,48 +41,47 @@ Polymer({ value: -1, }, - /** @type {?CupsPrinterInfo} */ - activePrinter: { - type: Object, - notify: true, + /** + * List of printers filtered through a search term. + * @type {!Array<!PrinterListEntry>} + * @private + */ + filteredPrinters_: { + type: Array, + value: () => [], }, }, listeners: { 'add-automatic-printer': 'onAddAutomaticPrinter_', + 'query-discovered-printer': 'onQueryDiscoveredPrinter_', }, - /** @override */ - attached: function() { - settings.CupsPrintersBrowserProxyImpl.getInstance() - .startDiscoveringPrinters(); - this.addWebUIListener( - 'on-nearby-printers-changed', this.onNearbyPrintersChanged_.bind(this)); - }, + observers: [ + 'onSearchOrPrintersChanged_(nearbyPrinters.*, searchTerm)' + ], /** - * @param {!Array<!CupsPrinterInfo>} automaticPrinters - * @param {!Array<!CupsPrinterInfo>} discoveredPrinters + * Redoes the search whenever |searchTerm| or |nearbyPrinters| changes. * @private */ - onNearbyPrintersChanged_: function(automaticPrinters, discoveredPrinters) { - if (!automaticPrinters && !discoveredPrinters) { + onSearchOrPrintersChanged_: function() { + if (!this.nearbyPrinters) { return; } - - const printers = /** @type{!Array<!PrinterListEntry>} */ ([]); - - for (const printer of automaticPrinters) { - printers.push({printerInfo: printer, - printerType: PrinterType.AUTOMATIC}); - } - - for (const printer of discoveredPrinters) { - printers.push({printerInfo: printer, - printerType: PrinterType.DISCOVERED}); - } - - this.nearbyPrinters_ = printers; + // Filter printers through |searchTerm|. If |searchTerm| is empty, + // |filteredPrinters_| is just |nearbyPrinters|. + const updatedPrinters = this.searchTerm ? + this.nearbyPrinters.filter( + item => settings.printing.matchesSearchTerm( + item.printerInfo,this.searchTerm)) : + this.nearbyPrinters.slice(); + + updatedPrinters.sort(settings.printing.sortPrinters); + + this.updateList( + 'filteredPrinters_', printer => printer.printerInfo.printerId, + updatedPrinters); }, /** @@ -100,18 +101,38 @@ Polymer({ }, /** + * @param {!CustomEvent<{item: !PrinterListEntry}>} e + * @private + */ + onQueryDiscoveredPrinter_: function(e) { + const item = e.detail.item; + this.setActivePrinter_(item); + + // This is a workaround to ensure type safety on the params of the casted + // function. We do this because the closure compiler does not work well with + // rejected js promises. + const queryDiscoveredPrinterFailed = /** @type {!Function}) */( + this.onQueryDiscoveredPrinterFailed_.bind(this)); + settings.CupsPrintersBrowserProxyImpl.getInstance() + .addDiscoveredPrinter(item.printerInfo.printerId) + .then( + this.onQueryDiscoveredPrinterSucceeded_.bind(this, + item.printerInfo.printerName), + queryDiscoveredPrinterFailed); + }, + + /** * Retrieves the index of |item| in |nearbyPrinters_| and sets that printer as * the active printer. * @param {!PrinterListEntry} item * @private */ setActivePrinter_: function(item) { - this.activePrinterListEntryIndex_ = - this.nearbyPrinters_.findIndex( - printer => printer.printerInfo == item.printerInfo); + this.activePrinterListEntryIndex_ = this.nearbyPrinters.findIndex( + printer => printer.printerInfo.printerId == item.printerInfo.printerId); this.activePrinter = - this.get(['nearbyPrinters_', this.activePrinterListEntryIndex_]) + this.get(['nearbyPrinters', this.activePrinterListEntryIndex_]) .printerInfo; }, @@ -140,10 +161,32 @@ Polymer({ }, /** - * @return {boolean} Returns true if noPrinterMessage should be visible. + * Handler for queryDiscoveredPrinter success. + * @param {string} printerName + * @param {!PrinterSetupResult} result + * @private + */ + onQueryDiscoveredPrinterSucceeded_: function(printerName, result) { + this.fire( + 'show-cups-printer-toast', + {resultCode: result, printerName: printerName}); + }, + + /** + * Handler for queryDiscoveredPrinter failure. + * @param {!CupsPrinterInfo} printer + * @private + */ + onQueryDiscoveredPrinterFailed_: function(printer) { + this.fire('open-manufacturer-model-dialog-for-specified-printer', + {item: /** @type {CupsPrinterInfo} */(printer)}); + }, + + /** + * @return {boolean} Returns true if the no search message should be visible. * @private */ - shouldShowNoNearbyPrinterMessage_: function() { - return !this.searchTerm && !this.nearbyPrinters_.length; + showNoSearchResultsMessage_: function() { + return !!this.searchTerm && !this.filteredPrinters_.length; } });
\ No newline at end of file diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printer_dialog_util.js b/chromium/chrome/browser/resources/settings/printing_page/cups_printer_dialog_util.js index 15542cb8d1c..46b1be62226 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_printer_dialog_util.js +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printer_dialog_util.js @@ -141,6 +141,40 @@ cr.define('settings.printing', function() { } } + /** + * We sort by printer type, which is based off of a maintained list in + * cups_printers_types.js. If the types are the same, we sort alphabetically. + * @param {!PrinterListEntry} first + * @param {!PrinterListEntry} second + * @return {number} + */ + function sortPrinters(first, second) { + if (first.printerType == second.printerType) { + return settings.printing.alphabeticalSort( + first.printerInfo, second.printerInfo); + } + + return first.printerType - second.printerType; + } + + /** + * @param {!CupsPrinterInfo} printer + * @param {string} searchTerm + * @return {boolean} True if the printer has |searchTerm| in its name. + */ + function matchesSearchTerm(printer, searchTerm) { + return printer.printerName.toLowerCase().includes(searchTerm.toLowerCase()); + } + + /** + * @param {!PrinterListEntry} first + * @param {!PrinterListEntry} second + * @return {boolean} + */ + function arePrinterIdsEqual(first, second) { + return first.printerInfo.printerId == second.printerInfo.printerId; + } + return { isNetworkProtocol: isNetworkProtocol, isNameAndAddressValid: isNameAndAddressValid, @@ -148,5 +182,8 @@ cr.define('settings.printing', function() { getBaseName: getBaseName, alphabeticalSort: alphabeticalSort, getErrorText: getErrorText, + sortPrinters: sortPrinters, + matchesSearchTerm: matchesSearchTerm, + arePrinterIdsEqual: arePrinterIdsEqual, }; }); diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html b/chromium/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html index cda0410aaa6..68ee364dca0 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html @@ -68,6 +68,10 @@ width: 100%; } + .flex-auto { + flex: 1 1 auto; + } + .list-item { background: none; border: none; @@ -109,6 +113,10 @@ font-size: 10px; margin-inline-start: 5px; } + + #no-search-results { + text-align: center; + } </style> </template> </dom-module> diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers.html b/chromium/chrome/browser/resources/settings/printing_page/cups_printers.html index 6777282b161..c5b866a04bc 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers.html +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers.html @@ -16,6 +16,7 @@ <link rel="import" href="cups_add_printer_dialog.html"> <link rel="import" href="cups_edit_printer_dialog.html"> <link rel="import" href="cups_printer_shared_css.html"> +<link rel="import" href="cups_printers_entry_manager.html"> <link rel="import" href="cups_printers_list.html"> <link rel="import" href="cups_saved_printers.html"> <link rel="import" href="cups_nearby_printers.html"> @@ -142,7 +143,6 @@ <settings-cups-saved-printers id="savedPrinters" active-printer="{{activePrinter}}" - saved-printers="[[savedPrinters_]]" search-term="[[searchTerm]]"> </settings-cups-saved-printers> </div> @@ -197,7 +197,7 @@ </settings-cups-edit-printer-dialog> </template> - <cr-toast id="errorToast" duration="3000"> + <cr-toast id="errorToast" duration="3000" role="alert"> <div class="error-message" id="addPrinterDoneMessage"> [[addPrinterResultText_]] </div> diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers.js b/chromium/chrome/browser/resources/settings/printing_page/cups_printers.js index 21109350ab6..ece618460ad 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers.js +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers.js @@ -81,11 +81,16 @@ Polymer({ /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */ networkConfig_: null, + /** @private {settings.printing.CupsPrintersEntryManager} */ + entryManager_: null, + /** @override */ created: function() { this.networkConfig_ = network_config.MojoInterfaceProviderImpl.getInstance() .getMojoServiceRemote(); + this.entryManager_ = + settings.printing.CupsPrintersEntryManager.getInstance(); }, /** @override */ @@ -94,7 +99,7 @@ Polymer({ .getNetworkStateList({ filter: chromeos.networkConfig.mojom.FilterType.kActive, networkType: chromeos.networkConfig.mojom.NetworkType.kAll, - limit: chromeos.networkConfig.mojom.kNoLimit, + limit: chromeos.networkConfig.mojom.NO_LIMIT, }) .then((responseParams) => { this.onActiveNetworksChanged(responseParams.result); @@ -110,7 +115,6 @@ Polymer({ this.updateCupsPrintersList_(); }, - /** * settings.RouteObserverBehavior * @param {!settings.Route} route @@ -119,10 +123,14 @@ Polymer({ currentRouteChanged: function(route) { if (route != settings.routes.CUPS_PRINTERS) { cr.removeWebUIListener('on-printers-changed'); + this.entryManager_.removeWebUIListeners(); return; } + + this.entryManager_.addWebUIListeners(); cr.addWebUIListener( 'on-printers-changed', this.onPrintersChanged_.bind(this)); + this.updateCupsPrintersList_(); }, /** @@ -148,17 +156,15 @@ Polymer({ * }>} event * @private */ - openResultToast_: function(event) { + openResultToast_: function(event) { const printerName = event.detail.printerName; switch (event.detail.resultCode) { case PrinterSetupResult.SUCCESS: - this.updateCupsPrintersList_(); this.addPrinterResultText_ = loadTimeData.getStringF('printerAddedSuccessfulMessage', printerName); break; case PrinterSetupResult.EDIT_SUCCESS: - this.updateCupsPrintersList_(); this.addPrinterResultText_ = loadTimeData.getStringF('printerEditedSuccessfulMessage', printerName); @@ -203,6 +209,7 @@ Polymer({ printer => /** @type {!PrinterListEntry} */({ printerInfo: printer, printerType: PrinterType.SAVED})); + this.entryManager_.setSavedPrintersList(this.savedPrinters_); } else { this.printers = cupsPrintersList.printerList; } diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.html b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.html index c8df839a0ee..8d7c6b5145c 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.html +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.html @@ -29,7 +29,7 @@ <template is="dom-if" if="[[isDiscoveredPrinter_(printerEntry.printerType)]]"> <cr-button id="setupPrinterButton" - on-click="onOpenManufacturerModelDialogTap_"> + on-click="onAddDiscoveredPrinterTap_"> $i18n{setupPrinter} </cr-button> </template> diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.js b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.js index fe225dcf9fa..5734b7717ae 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.js +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.js @@ -33,9 +33,8 @@ Polymer({ }); }, - onOpenManufacturerModelDialogTap_: function(e) { - this.fire('open-manufacturer-model-dialog-for-specified-printer', - {item: this.printerEntry.printerInfo}); + onAddDiscoveredPrinterTap_: function(e) { + this.fire('query-discovered-printer', {item: this.printerEntry}); }, onAddAutomaticPrinterTap_: function() { diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.html b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.html deleted file mode 100644 index bf9fbaf1f9f..00000000000 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.html +++ /dev/null @@ -1,42 +0,0 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="chrome://resources/html/list_property_update_behavior.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html"> -<link rel="import" href="cups_printer_dialog_util.html"> -<link rel="import" href="cups_printer_types.html"> -<link rel="import" href="cups_printers_browser_proxy.html"> -<link rel="import" href="cups_printers_entry.html"> -<link rel="import" href="../settings_shared_css.html"> - -<dom-module id="settings-cups-printers-entry-list"> - <template> - <style include="settings-shared"> - :host { - display: flex; - flex-direction: column; - } - - iron-list { - flex: 1 1 auto; - } - - #no-search-results { - margin-top: 20px; - text-align: center; - } - - </style> - <iron-list class="list-frame vertical-list" id="printerEntryList" - items="[[filteredPrinters_]]"> - <template> - <settings-cups-printers-entry printer-entry="[[item]]"> - </settings-cups-printers-entry> - </template> - </iron-list> - <div id="no-search-results" - hidden="[[!showNoSearchResultsMessage_]]"> - $i18n{noSearchResults} - </div> - </template> - <script src="cups_printers_entry_list.js"></script> -</dom-module> diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.js b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.js deleted file mode 100644 index 3fe5f69bd12..00000000000 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.js +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2019 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-cups-printers-entry-list' is a component for a list - * of PrinterListEntry's. - */ -Polymer({ - is: 'settings-cups-printers-entry-list', - - behaviors: [ - ListPropertyUpdateBehavior, - ], - - properties: { - /** - * List of printers. - * @type {!Array<!PrinterListEntry>} - */ - printers: { - type: Array, - value: () => [], - }, - - /** - * List of printers filtered through a search term. - * @type {!Array<!PrinterListEntry>} - * @private - */ - filteredPrinters_: { - type: Array, - value: () => [], - }, - - /** - * Search term for filtering |printers|. - * @type {string} - */ - searchTerm: { - type: String, - value: '', - }, - - /** - * Whether to show the no search results message. - * @type {boolean} - * @private - */ - showNoSearchResultsMessage_: { - type: Boolean, - value: false, - }, - }, - - observers: [ - 'onSearchChanged_(printers.*, searchTerm)' - ], - - /** - * Redoes the search whenever |searchTerm| or |printers| changes. - * @private - */ - onSearchChanged_: function() { - if (!this.printers) { - return; - } - // Filter printers through |searchTerm|. If |searchTerm| is empty, - // |filteredPrinters_| is just |printers|. - const updatedPrinters = this.searchTerm ? - this.printers.filter( - item =>this.matchesSearchTerm_(item.printerInfo,this.searchTerm)) : - this.printers.slice(); - - updatedPrinters.sort(this.sortPrinters_); - - this.updateList('filteredPrinters_', printer => printer.printerInfo, - updatedPrinters); - - this.showNoSearchResultsMessage_ = - !!this.searchTerm && !this.filteredPrinters_.length; - }, - - - /** - * @param {!PrinterListEntry} first - * @param {!PrinterListEntry} second - * @return {number} - * @private - */ - sortPrinters_: function(first, second) { - if (first.printerType == second.printerType) { - return settings.printing.alphabeticalSort( - first.printerInfo, second.printerInfo); - } - - // PrinterType sort order maintained in cups_printer_types.js - return first.printerType - second.printerType; - }, - - /** - * @param {!CupsPrinterInfo} printer - * @param {string} searchTerm - * @return {boolean} True if the printer has |searchTerm| in its name. - * @private - */ - matchesSearchTerm_: function(printer, searchTerm) { - return printer.printerName.toLowerCase().includes(searchTerm.toLowerCase()); - } -}); diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list_behavior.html b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list_behavior.html new file mode 100644 index 00000000000..6f30319498f --- /dev/null +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list_behavior.html @@ -0,0 +1,2 @@ +<link rel="import" href="cups_printer_types.html"> +<script src="cups_printers_entry_list_behavior.js"></script>
\ No newline at end of file diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list_behavior.js b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list_behavior.js new file mode 100644 index 00000000000..59588b24629 --- /dev/null +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list_behavior.js @@ -0,0 +1,98 @@ +// Copyright 2019 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 Polymer behavior for observing CupsPrintersEntryManager events. + * Use this behavior if you want to receive a dynamically updated list of both + * saved and nearby printers. + */ + +/** @polymerBehavior */ +const CupsPrintersEntryListBehavior = { + properties: { + /** @private {!settings.printing.CupsPrintersEntryManager} */ + entryManager_: Object, + + /** @type {!Array<!PrinterListEntry>} */ + savedPrinters: { + type: Array, + value: () => [], + }, + + /** @type {!Array<!PrinterListEntry>} */ + nearbyPrinters: { + type: Array, + value: () => [], + }, + }, + + /** @override */ + created: function() { + this.entryManager_ = + settings.printing.CupsPrintersEntryManager.getInstance(); + }, + + /** @override */ + attached: function() { + this.entryManager_.addOnSavedPrintersChangedListener( + this.onSavedPrintersChanged_.bind(this)); + this.entryManager_.addOnNearbyPrintersChangedListener( + this.onNearbyPrintersChanged_.bind(this)); + + // Initialize saved and nearby printers list. + this.onSavedPrintersChanged_( + this.entryManager_.savedPrinters, [] /* printerAdded */, + [] /* printerRemoved */); + this.onNearbyPrintersChanged_(this.entryManager_.nearbyPrinters); + }, + + /** @override */ + detached: function() { + this.entryManager_.removeOnSavedPrintersChangedListener( + this.onSavedPrintersChanged_.bind(this)); + this.entryManager_.removeOnNearbyPrintersChangedListener( + this.onNearbyPrintersChanged_.bind(this)); + }, + + /** + * Non-empty params indicate the applicable change to be notified. + * @param {!Array<!PrinterListEntry>} savedPrinters + * @param {!Array<!PrinterListEntry>} addedPrinters + * @param {!Array<!PrinterListEntry>} removedPrinters + * @private + */ + onSavedPrintersChanged_: function( + savedPrinters, addedPrinters, removedPrinters) { + this.updateList( + 'savedPrinters', printer => printer.printerInfo.printerId, + savedPrinters); + + assert(!(addedPrinters.length && removedPrinters.length)); + + if (addedPrinters.length) { + this.onSavedPrintersAdded(addedPrinters); + } else if (removedPrinters.length) { + this.onSavedPrintersRemoved(removedPrinters); + } + }, + + /** + * @param {!Array<!PrinterListEntry>} printerList + * @private + */ + onNearbyPrintersChanged_: function(printerList) { + this.updateList( + 'nearbyPrinters', printer => printer.printerInfo.printerId, + printerList); + }, + + // CupsPrintersEntryListBehavior methods. Override these in the + // implementations. + + /** @param{!Array<!PrinterListEntry>} addedPrinters */ + onSavedPrintersAdded: function(addedPrinters) {}, + + /** @param{!Array<!PrinterListEntry>} removedPrinters */ + onSavedPrintersRemoved: function(removedPrinters) {}, +};
\ No newline at end of file diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_manager.html b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_manager.html new file mode 100644 index 00000000000..d8e4aac3867 --- /dev/null +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_manager.html @@ -0,0 +1,5 @@ +<link rel="import" href="chrome://resources/html/assert.html"> +<link rel="import" href="chrome://resources/html/cr.html"> +<link rel="import" href="cups_printer_types.html"> +<link rel="import" href="cups_printers_browser_proxy.html"> +<script src="cups_printers_entry_manager.js"></script>
\ No newline at end of file diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_manager.js b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_manager.js new file mode 100644 index 00000000000..86908fbb3c3 --- /dev/null +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_manager.js @@ -0,0 +1,182 @@ +// Copyright 2019 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 which provides the client with metadata about a change + * to a list of saved printers. The first parameter is the updated list of + * printers after the change, the second parameter is the newly-added printer + * (if it exists), and the third parameter is the newly-removed printer + * (if it exists). + * @typedef {!function(!Array<!PrinterListEntry>, !Array<!PrinterListEntry>, + * !Array<!PrinterListEntry>): void} + */ +let PrintersListWithDeltasCallback; + +/** + * Function which provides the client with a list that contains the nearby + * printers list. The parameter is the updated list of printers after any + * changes. + * @typedef {function(!Array<!PrinterListEntry>): void} + */ +let PrintersListCallback; + +cr.define('settings.printing', function() { + /** + * Finds the printers that are in |firstArr| but not in |secondArr|. + * @param {!Array<!PrinterListEntry>} firstArr + * @param {!Array<!PrinterListEntry>} secondArr + * @return {!Array<!PrinterListEntry>} + * @private + */ + function findDifference_(firstArr, secondArr) { + return firstArr.filter((firstArrEntry) => { + return !secondArr.some( + p => p.printerInfo.printerId == firstArrEntry.printerInfo.printerId); + }); + } + + /** + * Class for managing printer entries. Holds both Saved and Nearby printers + * and notifies observers of any applicable changes to either printer lists. + */ + class CupsPrintersEntryManager { + constructor() { + /** @private {!Array<!PrinterListEntry>} */ + this.savedPrinters_ = []; + + /** @private {!Array<!PrinterListEntry>} */ + this.nearbyPrinters_ = []; + + /** @private {!Array<PrintersListWithDeltasCallback>} */ + this.onSavedPrintersChangedListeners_ = []; + + /** @type {!Array<PrintersListCallback>} */ + this.onNearbyPrintersChangedListeners_ = []; + } + + addWebUIListeners() { + // TODO(1005905): Add on-printers-changed listener here once legacy code + // is removed. + cr.addWebUIListener( + 'on-nearby-printers-changed', this.setNearbyPrintersList.bind(this)); + settings.CupsPrintersBrowserProxyImpl.getInstance() + .startDiscoveringPrinters(); + } + + removeWebUIListeners() { + cr.removeWebUIListener('on-nearby-printers-changed'); + } + + /** @return {!Array<!PrinterListEntry>} */ + get savedPrinters() { + return this.savedPrinters_; + } + + /** @return {!Array<!PrinterListEntry>} */ + get nearbyPrinters() { + return this.nearbyPrinters_; + } + + /** @param {PrintersListWithDeltasCallback} listener */ + addOnSavedPrintersChangedListener(listener) { + this.onSavedPrintersChangedListeners_.push(listener); + } + + /** @param {PrintersListWithDeltasCallback} listener */ + removeOnSavedPrintersChangedListener(listener) { + this.onSavedPrintersChangedListeners_ = + this.onSavedPrintersChangedListeners_.filter(lis => lis != listener); + } + + /** @param {PrintersListCallback} listener */ + addOnNearbyPrintersChangedListener(listener) { + this.onNearbyPrintersChangedListeners_.push(listener); + } + + /** @param {PrintersListCallback} listener */ + removeOnNearbyPrintersChangedListener(listener) { + this.onNearbyPrintersChangedListeners_ = + this.onNearbyPrintersChangedListeners_.filter(lis => lis != listener); + } + + /** + * Sets the saved printers list and notifies observers of any applicable + * changes. + * @param {!Array<!PrinterListEntry>} printerList + */ + setSavedPrintersList(printerList) { + if (printerList.length > this.savedPrinters_.length) { + const diff = findDifference_(printerList, this.savedPrinters_); + this.savedPrinters_ = printerList; + this.notifyOnSavedPrintersChangedListeners_( + this.savedPrinters_, diff, [] /* printersRemoved */); + return; + } + + if (printerList.length < this.savedPrinters_.length) { + const diff = findDifference_(this.savedPrinters_, printerList); + this.savedPrinters_ = printerList; + this.notifyOnSavedPrintersChangedListeners_( + this.savedPrinters_, [] /* printersAdded */, diff); + return; + } + + this.savedPrinters_ = printerList; + this.notifyOnSavedPrintersChangedListeners_( + this.savedPrinters_, [] /* printersAdded */, + [] /* printersRemoved */); + } + + /** + * Sets the nearby printers list and notifies observers of any applicable + * changes. + * @param {!Array<!CupsPrinterInfo>} automaticPrinters + * @param {!Array<!CupsPrinterInfo>} discoveredPrinters + */ + setNearbyPrintersList(automaticPrinters, discoveredPrinters) { + if (!automaticPrinters && !discoveredPrinters) { + return; + } + + this.nearbyPrinters_ = []; + + for (const printer of automaticPrinters) { + this.nearbyPrinters_.push( + {printerInfo: printer, printerType: PrinterType.AUTOMATIC}); + } + + for (const printer of discoveredPrinters) { + this.nearbyPrinters_.push( + {printerInfo: printer, printerType: PrinterType.DISCOVERED}); + } + + this.notifyOnNearbyPrintersChangedListeners_(); + } + + /** + * Non-empty/null fields indicate the applicable change to be notified. + * @param {!Array<!PrinterListEntry>} savedPrinters + * @param {!Array<!PrinterListEntry>} addedPrinter + * @param {!Array<!PrinterListEntry>} removedPrinter + * @private + */ + notifyOnSavedPrintersChangedListeners_( + savedPrinters, addedPrinter, removedPrinter) { + this.onSavedPrintersChangedListeners_.forEach( + listener => listener(savedPrinters, addedPrinter, removedPrinter)); + } + + /** @private */ + notifyOnNearbyPrintersChangedListeners_() { + this.onNearbyPrintersChangedListeners_.forEach( + listener => listener(this.nearbyPrinters_)); + } + } + + cr.addSingletonGetter(CupsPrintersEntryManager); + + return { + CupsPrintersEntryManager: CupsPrintersEntryManager, + }; +});
\ No newline at end of file diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.html b/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.html index 1bb09c08fc0..c89d0230a99 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.html +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.html @@ -1,14 +1,52 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html"> +<link rel="import" href="chrome://resources/html/list_property_update_behavior.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.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/iron-list/iron-list.html"> <link rel="import" href="cups_printer_types.html"> <link rel="import" href="cups_printers_browser_proxy.html"> -<link rel="import" href="cups_printers_entry_list.html"> +<link rel="import" href="cups_printers_entry_list_behavior.html"> +<link rel="import" href="cups_printers_entry.html"> <link rel="import" href="../settings_shared_css.html"> <dom-module id="settings-cups-saved-printers"> <template> + <style include="cups-printer-shared iron-flex iron-flex-alignment + iron-flex-factors"> + :host { + display: flex; + flex-direction: column; + } + + #no-search-results { + margin-bottom: 20px; + } + + /** Height of iron list row entry. */ + #show-more-container { + min-height: var(--settings-row-min-height); + } + + /** Border line that is the same size as a list entry's border. */ + #show-more-line-separator { + border-bottom: var(--cr-separator-line); + left: 60px; + position: relative; + right: 20px; + width: 596px; + } + + #show-more-icon { + --cr-icon-button-margin-end: 0; + } + + #show-more-text { + flex: 1; + } + </style> + <cr-action-menu> <button id="editButton" class="dropdown-item" on-click="onEditTap_"> $i18n{editPrinter} @@ -18,10 +56,32 @@ </button> </cr-action-menu> - <style include="settings-shared"></style> - <settings-cups-printers-entry-list printers="[[savedPrinters]]" - search-term="[[searchTerm]]"> - </settings-cups-printers-entry-list> + <iron-list class="list-frame vertical-list flex-auto" id="printerEntryList" + items="[[filteredPrinters_]]"> + <template> + <settings-cups-printers-entry printer-entry="[[item]]"> + </settings-cups-printers-entry> + </template> + </iron-list> + <template is="dom-if" id="show-more-button-section" + if="[[shouldPrinterListBeCollapsed_(searchTerm, savedPrinters.*, + newPrinters_.*, hasShowMoreBeenTapped_)]]" restamp> + <div id="show-more-line-separator"></div> + <div class="list-frame layout horizontal" id="show-more-container"> + <div id="show-more-text">$i18n{showMorePrinters}</div> + <cr-icon-button class="action-button" id="show-more-icon" + iron-icon="cr:expand-more" + on-click="onShowMoreTap_" + title=$i18n{showMorePrinters}> + </cr-icon-button> + </div> + </template> + + <div id="no-search-results" + hidden="[[!showNoSearchResultsMessage_(searchTerm, + filteredPrinters_.*)]]"> + $i18n{noSearchResults} + </div> </template> <script src="cups_saved_printers.js"></script> </dom-module> diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.js b/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.js index 85ef694f1ec..948bc0526ab 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.js +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.js @@ -2,6 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +(function() { + +// If the Show more button is visible, the minimum number of printers we show +// is 3. +const kMinVisiblePrinters = 3; + +/** + * Move a printer's position in |printerArr| from |fromIndex| to |toIndex|. + * @param {!Array<!PrinterListEntry>} printerArr + * @param {number} fromIndex + * @param {number} toIndex + */ +function moveEntryInPrinters(printerArr, fromIndex, toIndex) { + const element = printerArr[fromIndex]; + printerArr.splice(fromIndex, 1); + printerArr.splice(toIndex, 0, element); +} + /** * @fileoverview 'settings-cups-saved-printers' is a list container for Saved * Printers. @@ -9,16 +27,14 @@ Polymer({ is: 'settings-cups-saved-printers', + // ListPropertyUpdateBehavior is used in CupsPrintersEntryListBehavior. behaviors: [ - WebUIListenerBehavior, + CupsPrintersEntryListBehavior, + ListPropertyUpdateBehavior, + WebUIListenerBehavior, ], properties: { - /** @type {!Array<!PrinterListEntry>} */ - savedPrinters: { - type: Array, - }, - /** * Search term for filtering |savedPrinters|. * @type {string} @@ -28,6 +44,12 @@ Polymer({ value: '', }, + /** @type {?CupsPrinterInfo} */ + activePrinter: { + type: Object, + notify: true, + }, + /** * @type {number} * @private @@ -37,10 +59,36 @@ Polymer({ value: -1, }, - /** @type {?CupsPrinterInfo} */ - activePrinter: { - type: Object, - notify: true, + /** + * List of printers filtered through a search term. + * @type {!Array<!PrinterListEntry>} + * @private + */ + filteredPrinters_: { + type: Array, + value: () => [], + }, + + /** + * Array of new PrinterListEntry's that were added during this session. + * @type {!Array<!PrinterListEntry>} + * @private + */ + newPrinters_: { + type: Array, + value: () => [], + }, + + /** + * Keeps track of whether the user has tapped the Show more button. A search + * term will expand the collapsed list, so we need to keep track of whether + * the list expanded because of a search term or because the user tapped on + * the Show more button. + * @private + */ + hasShowMoreBeenTapped_: { + type: Boolean, + value: false, }, }, @@ -48,23 +96,50 @@ Polymer({ 'open-action-menu': 'onOpenActionMenu_', }, + observers: [ + 'onSearchOrPrintersChanged_(savedPrinters.*, searchTerm,' + + 'hasShowMoreBeenTapped_, newPrinters_.*)' + ], + /** @private {settings.CupsPrintersBrowserProxy} */ browserProxy_: null, + /** + * The number of printers we display if hidden printers are allowed. + * kMinVisiblePrinters is the default value and we never show fewer printers + * if the Show more button is visible. + */ + visiblePrinterCounter_: kMinVisiblePrinters, + /** @override */ created: function() { this.browserProxy_ = settings.CupsPrintersBrowserProxyImpl.getInstance(); }, /** + * Redoes the search whenever |searchTerm| or |savedPrinters| changes. + * @private + */ + onSearchOrPrintersChanged_: function() { + if (!this.savedPrinters) { + return; + } + + const updatedPrinters = this.getVisiblePrinters_(); + + this.updateList( + 'filteredPrinters_', printer => printer.printerInfo.printerId, + updatedPrinters); + }, + + /** * @param {!CustomEvent<{target: !HTMLElement, item: !PrinterListEntry}>} e * @private */ onOpenActionMenu_: function(e) { const item = /** @type {!PrinterListEntry} */(e.detail.item); - this.activePrinterListEntryIndex_ = - this.savedPrinters.findIndex( - printer => printer.printerInfo == item.printerInfo); + this.activePrinterListEntryIndex_ = this.savedPrinters.findIndex( + printer => printer.printerInfo.printerId == item.printerInfo.printerId); this.activePrinter = this.get(['savedPrinters', this.activePrinterListEntryIndex_]) .printerInfo; @@ -90,7 +165,131 @@ Polymer({ }, /** @private */ + onShowMoreTap_: function() { + this.hasShowMoreBeenTapped_ = true; + }, + + /** + * Gets the printers to be shown in the UI. These printers are filtered + * by the search term, alphabetically sorted (if applicable), and are the + * printers not hidden by the Show more section. + * @return {!Array<!PrinterListEntry>} Returns only the visible printers. + * @private + */ + getVisiblePrinters_: function() { + // Filter printers through |searchTerm|. If |searchTerm| is empty, + // |filteredPrinters_| is just |savedPrinters|. + const updatedPrinters = this.searchTerm ? + this.savedPrinters.filter( + item => settings.printing.matchesSearchTerm( + item.printerInfo, this.searchTerm)) : + this.savedPrinters.slice(); + + updatedPrinters.sort(settings.printing.sortPrinters); + + this.moveNewlyAddedPrinters_(updatedPrinters, 0 /* toIndex */); + + if (this.shouldPrinterListBeCollapsed_()) { + // If the Show more button is visible, we only display the first + // N < |visiblePrinterCounter_| printers and the rest are hidden. + return updatedPrinters.filter( + (printer, idx) => idx < this.visiblePrinterCounter_); + } + return updatedPrinters; + }, + + /** @private */ closeActionMenu_: function() { this.$$('cr-action-menu').close(); + }, + + /** + * @return {boolean} Returns true if the no search message should be visible. + * @private + */ + showNoSearchResultsMessage_: function() { + return !!this.searchTerm && !this.filteredPrinters_.length; + }, + + /** @param{!Array<!PrinterListEntry>} addedPrinters */ + onSavedPrintersAdded: function(addedPrinters) { + const currArr = this.newPrinters_.slice(); + for (const printer of addedPrinters) { + this.visiblePrinterCounter_++; + currArr.push(printer); + } + + this.set('newPrinters_', currArr); + }, + + /** @param{!Array<!PrinterListEntry>} removedPrinters */ + onSavedPrintersRemoved: function(removedPrinters) { + const currArr = this.newPrinters_.slice(); + for (const printer of removedPrinters) { + const newPrinterRemovedIdx = currArr.findIndex( + p => p.printerInfo.printerId == printer.printerInfo.printerId); + // If the removed printer is a recently added printer, remove it from + // |currArr|. + if (newPrinterRemovedIdx > -1) { + currArr.splice(newPrinterRemovedIdx, 1); + } + + this.visiblePrinterCounter_ = Math.max( + kMinVisiblePrinters, --this.visiblePrinterCounter_); + } + + this.set('newPrinters_', currArr); + }, + + /** + * Keeps track of whether the Show more button should be visible which means + * that the printer list is collapsed. There are two ways a collapsed list + * may be expanded: the Show more button is tapped or if there is a search + * term. + * @return {boolean} True if the printer list should be collapsed. + * @private + */ + shouldPrinterListBeCollapsed_: function() { + // If |searchTerm| is set, never collapse the list. + if (this.searchTerm) { + return false; + } + + // If |hasShowMoreBeenTapped_| is set to true, never collapse the list. + if (this.hasShowMoreBeenTapped_) { + return false; + } + + // If the total number of saved printers does not exceed the number of + // visible printers, there is no need for the list to be collapsed. + if (this.savedPrinters.length - this.visiblePrinterCounter_ < 1) { + return false; + } + + return true; + }, + + /** + * Moves printers that are in |newPrinters_| to position |toIndex| of + * |printerArr|. This moves all recently added printers to the top of the + * printer list. + * @param {!Array<!PrinterListEntry>} printerArr + * @param {number} toIndex + * @private + */ + moveNewlyAddedPrinters_: function(printerArr, toIndex) { + if (!this.newPrinters_.length) { + return; + } + + // We have newly added printers, move them to the top of the list. + for (const printer of this.newPrinters_) { + const idx = printerArr.findIndex( + p => p.printerInfo.printerId == printer.printerInfo.printerId); + if (idx > -1) { + moveEntryInPrinters(printerArr, idx, toIndex); + } + } } }); +})(); 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 491eff1b6aa..34d663a378f 100644 --- a/chromium/chrome/browser/resources/settings/privacy_page/personalization_options.html +++ b/chromium/chrome/browser/resources/settings/privacy_page/personalization_options.html @@ -2,10 +2,12 @@ <link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.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="../controls/settings_toggle_button.html"> <link rel="import" href="../lifetime_browser_proxy.html"> <link rel="import" href="../people_page/sync_browser_proxy.html"> +<link rel="import" href="../prefs/prefs.html"> <link rel="import" href="../prefs/prefs_behavior.html"> <link rel="import" href="../route.html"> <link rel="import" href="../settings_shared_css.html"> @@ -43,10 +45,23 @@ label="$i18n{safeBrowsingEnableProtection}" sub-label="$i18n{safeBrowsingEnableProtectionDesc}"> </settings-toggle-button> + <settings-toggle-button id="passwordsLeakDetectionCheckbox" + pref="{{prefs.profile.password_manager_leak_detection}}" + checked="[[getCheckedLeakDetection_( + userSignedIn_, passwordsLeakDetectionAvailable_)]]" + label="$i18n{passwordsLeakDetectionLabel}" + sub-label="[[getPasswordsLeakDetectionSubLabel_( + userSignedIn_, passwordsLeakDetectionAvailable_)]]" + hidden$="[[!passwordsLeakDetectionEnabled_]]" + disabled="[[getDisabledLeakDetection_( + userSignedIn_, prefs.*)]]"> + </settings-toggle-button> <settings-toggle-button pref="{{prefs.safebrowsing.scout_reporting_enabled}}" + checked="[[getCheckedExtendedSafeBrowsing_(prefs.*)]]" label="$i18n{safeBrowsingEnableExtendedReporting}" - sub-label="$i18n{safeBrowsingEnableExtendedReportingDesc}"> + sub-label="$i18n{safeBrowsingEnableExtendedReportingDesc}" + disabled="[[getDisabledExtendedSafeBrowsing_(prefs.*)]]"> </settings-toggle-button> <if expr="_google_chrome"> <if expr="chromeos"> 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 f3a7ad0b10b..5d066a1dee6 100644 --- a/chromium/chrome/browser/resources/settings/privacy_page/personalization_options.js +++ b/chromium/chrome/browser/resources/settings/privacy_page/personalization_options.js @@ -13,6 +13,7 @@ Polymer({ is: 'settings-personalization-options', behaviors: [ + I18nBehavior, PrefsBehavior, WebUIListenerBehavior, ], @@ -34,6 +35,29 @@ Polymer({ /** @type {settings.SyncStatus} */ syncStatus: Object, + // <if expr="not chromeos"> + /** @private {Array<!settings.StoredAccount>} */ + storedAccounts_: Object, + // </if> + + /** @private */ + userSignedIn_: { + type: Boolean, + computed: 'computeUserSignedIn_(syncStatus, storedAccounts_)', + }, + + /** @private */ + passwordsLeakDetectionAvailable_: { + type: Boolean, + computed: 'computePasswordsLeakDetectionAvailable_(prefs.*)', + }, + + /** @private */ + passwordsLeakDetectionEnabled_: { + type: Boolean, + value: loadTimeData.getBoolean('passwordsLeakDetectionEnabled'), + }, + // <if expr="_google_chrome and not chromeos"> // TODO(dbeam): make a virtual.* pref namespace and set/get this normally // (but handled differently in C++). @@ -61,6 +85,84 @@ Polymer({ this.addWebUIListener('metrics-reporting-change', setMetricsReportingPref); this.browserProxy_.getMetricsReporting().then(setMetricsReportingPref); // </if> + // <if expr="not chromeos"> + const storedAccountsChanged = storedAccounts => this.storedAccounts_ = + storedAccounts; + const syncBrowserProxy = settings.SyncBrowserProxyImpl.getInstance(); + syncBrowserProxy.getStoredAccounts().then(storedAccountsChanged); + this.addWebUIListener('stored-accounts-updated', storedAccountsChanged); + // </if> + + // Even though we already set checked="[[getCheckedLeakDetection_(...)]]" + // in the DOM, this might be overridden within prefValueChanged_ of + // SettingsBooleanControlBehaviorImpl which gets invoked once we navigate to + // sync_page.html. Re-computing the checked value here once fixes this + // problem. + this.$.passwordsLeakDetectionCheckbox.checked = + this.getCheckedLeakDetection_(); + }, + + /** + * @return {boolean} + * @private + */ + computeUserSignedIn_: function() { + return (!!this.syncStatus && !!this.syncStatus.signedIn) ? + !this.syncStatus.hasError : + (!!this.storedAccounts_ && this.storedAccounts_.length > 0); + }, + + /** + * @return {boolean} + * @private + */ + computePasswordsLeakDetectionAvailable_: function() { + return !!this.getPref('profile.password_manager_leak_detection').value && + !!this.getPref('safebrowsing.enabled').value; + }, + + /** + * @return {boolean} + * @private + */ + getCheckedLeakDetection_: function() { + return this.userSignedIn_ && this.passwordsLeakDetectionAvailable_; + }, + + /** + * @return {string} + * @private + */ + getPasswordsLeakDetectionSubLabel_: function() { + if (!this.userSignedIn_ && this.passwordsLeakDetectionAvailable_) { + return this.i18n('passwordsLeakDetectionSignedOutEnabledDescription'); + } + return ''; + }, + + /** + * @return {boolean} + * @private + */ + getDisabledLeakDetection_: function() { + return !this.userSignedIn_ || !this.getPref('safebrowsing.enabled').value; + }, + + /** + * @return {boolean} + * @private + */ + getCheckedExtendedSafeBrowsing_: function() { + return !!this.getPref('safebrowsing.enabled').value && + !!this.getPref('safebrowsing.scout_reporting_enabled').value; + }, + + /** + * @return {boolean} + * @private + */ + getDisabledExtendedSafeBrowsing_: function() { + return !this.getPref('safebrowsing.enabled').value; }, // <if expr="_google_chrome and not chromeos"> diff --git a/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.html index 1ad29354d5c..9b9618c956d 100644 --- a/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.html +++ b/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.html @@ -303,6 +303,23 @@ </category-setting-exceptions> </settings-subpage> </template> + <template is="dom-if" if="[[enableInsecureContentContentSetting_]]"> + <template is="dom-if" route-path="/content/insecureContent" no-search> + <settings-subpage + page-title="$i18n{siteSettingsCategoryInsecureContent}" + search-label="$i18n{siteSettingsAllSitesSearch}" + search-term="{{searchFilter_}}"> + <div class="settings-box first"> + $i18n{siteSettingsInsecureContentBlock} + </div> + <category-setting-exceptions + category="[[ContentSettingsTypes.MIXEDSCRIPT]]" + block-header="$i18n{siteSettingsBlock}" + search-filter="[[searchFilter_]]"> + </category-setting-exceptions> + </settings-subpage> + </template> + </template> <template is="dom-if" route-path="/content/location" no-search> <settings-subpage page-title="$i18n{siteSettingsCategoryLocation}" search-label="$i18n{siteSettingsAllSitesSearch}" @@ -664,7 +681,7 @@ </settings-subpage> </template> </template> - <template is="dom-if" if="[[enableBluetoothScanningContentSetting_]]"> + <template is="dom-if" if="[[enableExperimentalWebPlatformFeatures_]]"> <template is="dom-if" route-path="/content/bluetoothScanning" no-search> <settings-subpage page-title="$i18n{siteSettingsBluetoothScanning}" search-label="$i18n{siteSettingsAllSitesSearch}" 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 57b42d06dee..a7b63fd525e 100644 --- a/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.js +++ b/chromium/chrome/browser/resources/settings/privacy_page/privacy_page.js @@ -136,10 +136,10 @@ Polymer({ }, /** @private */ - enableBluetoothScanningContentSetting_: { + enableInsecureContentContentSetting_: { type: Boolean, value: function() { - return loadTimeData.getBoolean('enableBluetoothScanningContentSetting'); + return loadTimeData.getBoolean('enableInsecureContentContentSetting'); } }, diff --git a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.html b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.html index 7569eead29a..e1d92c209a0 100644 --- a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.html +++ b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.html @@ -27,12 +27,20 @@ padding-inline-end: 12px; } + .list-item .name { + word-break: break-word; + } + .name { flex: 3; } - #dialog::part(body-container) { - overflow-y: hidden; + .icon-placeholder { + width: var(--cr-icon-ripple-size); + } + + #outer { + padding: 0 var(--cr-section-padding); } </style> @@ -51,40 +59,53 @@ <div id="pinPrompt"> <p>$i18n{securityKeysBioEnrollmentPinPrompt}</p> - <settings-security-keys-pin-field id="pin"> + <settings-security-keys-pin-field + id="pin" label="$i18n{securityKeysPIN}"> </settings-security-keys-pin-field> </div> <div id="enrollments"> <div class="settings-box first"> - <p class="start" hidden="[[hasSome_(enrollments_)]]"> - $i18n{securityKeysBioEnrollmentNoEnrollments}</p> - <p class="start" hidden="[[!hasSome_(enrollments_)]]"> - $i18n{securityKeysBioEnrollmentLabel}</p> + <h2 class="start">$i18n{securityKeysBioEnrollmentLabel}</h2> <cr-button id="addButton" on-click="addButtonClick_" - hidden="[[!addButtonVisible_]]" class="secondary-button header-aligned-button"> $i18n{add} </cr-button> </div> - <div id="container"> - <iron-list id="enrollmentList" items="[[enrollments_]]" - class="cr-separators"> - <template> - <div class="list-item"> - <iron-icon icon="cr-fingerprint-icon:enrollment-done"> - </iron-icon> - <div class="name" aria-label="[[item.name]]"> - [[item.name]] + + + <div id="outer"> + <div id="header" class="list-item column-header" + hidden="[[!hasSome_(enrollments_)]]"> + <div class="name"> + $i18n{securityKeysBioEnrollmentNameLabel} + </div> + <div class="icon-placeholder"></div> + </div> + + <div id="container" hidden="[[!hasSome_(enrollments_)]]"> + <iron-list id="enrollmentList" items="[[enrollments_]]" + class="cr-separators"> + <template> + <div class="list-item"> + <iron-icon icon="cr-fingerprint-icon:enrollment-done"> + </iron-icon> + <div class="name" aria-label="[[item.name]]"> + [[item.name]] + </div> + <cr-icon-button class="icon-clear" + aria-label="i18n{securityKeysBioEnrollmentDelete}" + on-click="deleteEnrollment_" + disabled="[[deleteInProgress_]]"> + </cr-icon-button> </div> - <cr-icon-button class="icon-clear" - aria-label="i18n{securityKeysBioEnrollmentDelete}" - on-click="deleteEnrollment_" - disabled="[[deleteInProgress_]]"> - </cr-icon-button> - </div> - </template> - </iron-list> + </template> + </iron-list> + </div> + + <p hidden="[[hasSome_(enrollments_)]]"> + $i18n{securityKeysBioEnrollmentNoEnrollments} + </p> </div> </div> @@ -93,18 +114,31 @@ <cr-fingerprint-progress-arc id="arc"></cr-fingerprint-progress-arc> </div> + <div id="chooseName"> + <p>$i18n{securityKeysBioEnrollmentChooseName}</p> + <cr-input type="text" id="enrollmentName" + value="{{recentEnrollmentName_}}" + label="$i18n{securityKeysBioEnrollmentNameLabel}" + on-input="onEnrollmentNameInput_" + spellcheck="false"> + </cr-input> + </div> + <div id="error">[[errorMsg_]]</div> </iron-pages> </div> <div slot="button-container"> - <cr-button id="cancelButton" class="cancel-button" - on-click="cancel_" hidden="[[!cancelButtonVisible_]]"> + <cr-button id="cancelButton" class="cancel-button" on-click="cancel_" + hidden="[[!cancelButtonVisible_]]" + disabled="[[cancelButtonDisabled_]]"> $i18n{cancel} </cr-button> - <cr-button id="okButton" class="action-button" - on-click="okButtonClick_" hidden="[[!okButtonVisible_]]"> - $i18n{ok} + <cr-button id="confirmButton" class="action-button" + hidden="[[!confirmButtonVisible_]]" + disabled="[[confirmButtonDisabled_]]" + on-click="confirmButtonClick_"> + $i18n{continue} </cr-button> <cr-button id="doneButton" class="action-button" on-click="done_" hidden="[[!doneButtonVisible_]]"> diff --git a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.js b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.js index 1f251c65aa4..43253425f32 100644 --- a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.js +++ b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.js @@ -20,12 +20,18 @@ Polymer({ properties: { /** @private */ - addButtonVisible_: Boolean, + cancelButtonDisabled_: Boolean, /** @private */ cancelButtonVisible_: Boolean, /** @private */ + confirmButtonDisabled_: Boolean, + + /** @private */ + confirmButtonVisible_: Boolean, + + /** @private */ deleteInProgress_: Boolean, /** @@ -48,14 +54,17 @@ Polymer({ enrollments_: Array, /** @private */ - okButtonVisible_: Boolean, + recentEnrollmentName_: String, }, /** @private {?settings.SecurityKeysBioEnrollProxyImpl} */ browserProxy_: null, - /** @private */ - maxSamples_: Number, + /** @private {number} */ + maxSamples_: -1, + + /** @private {string} */ + recentEnrollmentId_: '', /** @override */ attached: function() { @@ -65,8 +74,9 @@ Polymer({ this.addWebUIListener( 'security-keys-bio-enroll-status', this.onEnrolling_.bind(this)); this.browserProxy_ = settings.SecurityKeysBioEnrollProxyImpl.getInstance(); - this.browserProxy_.startBioEnroll().then( - this.collectPIN_.bind(this), () => {}); + this.browserProxy_.startBioEnroll().then(() => { + this.collectPIN_(); + }); }, /** @private */ @@ -87,17 +97,17 @@ Polymer({ /** @private */ submitPIN_: function() { if (!this.$.pin.validate()) { + this.confirmButtonDisabled_ = false; return; } - this.browserProxy_.providePIN(this.$.pin.value).then((retries) => { + this.browserProxy_.providePIN(this.$.pin.value).then(retries => { + this.confirmButtonDisabled_ = false; if (retries != null) { this.$.pin.showIncorrectPINError(retries); return; } - - this.browserProxy_.enumerateEnrollments().then( - this.onEnrollments_.bind(this)); - }, () => {}); + this.showEnrollmentsPage_(); + }); }, /** @@ -114,33 +124,39 @@ Polymer({ dialogPageChanged_: function() { switch (this.dialogPage_) { case 'initial': - this.addButtonVisible_ = false; this.cancelButtonVisible_ = true; - this.okButtonVisible_ = false; + this.cancelButtonDisabled = false; + this.confirmButtonVisible_ = false; this.doneButtonVisible_ = false; break; case 'pinPrompt': - this.addButtonVisible_ = false; this.cancelButtonVisible_ = true; - this.okButtonVisible_ = true; + this.cancelButtonDisabled = false; + this.confirmButtonVisible_ = true; + this.confirmButtonDisabled_ = false; this.doneButtonVisible_ = false; break; case 'enrollments': - this.addButtonVisible_ = true; this.cancelButtonVisible_ = false; - this.okButtonVisible_ = false; + this.confirmButtonVisible_ = false; this.doneButtonVisible_ = true; break; case 'enroll': - this.addButtonVisible_ = false; this.cancelButtonVisible_ = true; - this.okButtonVisible_ = false; + this.cancelButtonDisabled = false; + this.confirmButtonVisible_ = false; + this.doneButtonVisible_ = false; + break; + case 'chooseName': + this.cancelButtonVisible_ = false; + this.confirmButtonVisible_ = true; + this.confirmButtonDisabled_ = !this.recentEnrollmentName_.length; this.doneButtonVisible_ = false; + this.$.enrollmentName.focus(); break; case 'error': - this.addButtonVisible_ = false; this.cancelButtonVisible_ = false; - this.okButtonVisible_ = false; + this.confirmButtonVisible_ = false; this.doneButtonVisible_ = true; break; default: @@ -155,12 +171,15 @@ Polymer({ this.maxSamples_ = -1; // Reset maxSamples_ before enrolling starts. this.$.arc.reset(); - this.cancelButtonVisible_ = true; - this.okButtonVisible_ = false; + + this.recentEnrollmentId_ = ''; + this.recentEnrollmentName_ = ''; this.dialogPage_ = 'enroll'; - this.browserProxy_.startEnrolling().then( - this.onEnrolling_.bind(this), () => {}); + + this.browserProxy_.startEnrolling().then(response => { + this.onEnrolling_(response); + }); }, /** @@ -168,6 +187,11 @@ Polymer({ * @param {!EnrollmentStatus} response */ onEnrolling_: function(response) { + if (response.code == Ctap2Status.ERR_KEEPALIVE_CANCEL) { + this.showEnrollmentsPage_(); + return; + } + if (this.maxSamples_ == -1 && response.status != null) { if (response.status == 0) { // If the first sample is valid, remaining is one less than max samples @@ -186,21 +210,37 @@ Polymer({ 100 - (100 * response.remaining / this.maxSamples_), response.remaining == 0); if (response.remaining == 0) { + assert(response.enrollment); + this.recentEnrollmentId_ = response.enrollment.id; + this.recentEnrollmentName_ = response.enrollment.name; this.cancelButtonVisible_ = false; - this.okButtonVisible_ = true; + this.confirmButtonVisible_ = true; + this.confirmButtonDisabled_ = false; + this.$.confirmButton.focus(); } this.fire('bio-enroll-dialog-ready-for-testing'); }, /** @private */ - okButtonClick_: function() { + confirmButtonClick_: function() { + // Disable |confirmButton| while PIN verification or template enumeration is + // pending. Resetting |dialogPage_| will re-enable it. + this.confirmButtonDisabled_ = true; switch (this.dialogPage_) { case 'pinPrompt': this.submitPIN_(); break; case 'enroll': - this.browserProxy_.enumerateEnrollments().then( - this.onEnrollments_.bind(this), () => {}); + assert(!!this.recentEnrollmentId_.length); + this.dialogPage_ = 'chooseName'; + break; + case 'chooseName': + this.browserProxy_ + .renameEnrollment( + this.recentEnrollmentId_, this.recentEnrollmentName_) + .then(enrollments => { + this.onEnrollments_(enrollments); + }); break; default: assertNotReached(); @@ -208,24 +248,27 @@ Polymer({ }, /** @private */ + showEnrollmentsPage_: function() { + this.browserProxy_.enumerateEnrollments().then(enrollments => { + this.onEnrollments_(enrollments); + }); + }, + + /** @private */ cancel_: function() { if (this.dialogPage_ == 'enroll') { - this.browserProxy_.cancelEnrollment().then( - this.cancelEnroll_.bind(this), () => {}); + // Cancel an ongoing enrollment. Will cause the pending + // enumerateEnrollments() promise to be resolved and proceed to the + // enrollments page. + this.cancelButtonDisabled_ = true; + this.browserProxy_.cancelEnrollment(); } else { + // On any other screen, simply close the dialog. this.done_(); } }, /** @private */ - cancelEnroll_: function() { - // Cancelling from the enrolling screen redirects to the enrollments - // list, so request another enumeration to display. - this.browserProxy_.enumerateEnrollments().then( - this.onEnrollments_.bind(this), () => {}); - }, - - /** @private */ done_: function() { this.$.dialog.close(); }, @@ -268,6 +311,11 @@ Polymer({ this.deleteInProgress_ = false; this.onEnrollments_(enrollments); }); - } + }, + + /** @private */ + onEnrollmentNameInput_: function() { + this.confirmButtonDisabled_ = !this.recentEnrollmentName_.length; + }, }); })(); diff --git a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_browser_proxy.js b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_browser_proxy.js index 00a55d9f52d..ba01514b632 100644 --- a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_browser_proxy.js +++ b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_browser_proxy.js @@ -5,6 +5,16 @@ cr.exportPath('settings'); /** + * Ctap2Status contains a subset of CTAP2 status codes. See + * device::CtapDeviceResponseCode for the full list. + * @enum{number} + */ +const Ctap2Status = { + OK: 0x0, + ERR_KEEPALIVE_CANCEL: 0x2D, +}; + +/** * Credential represents a CTAP2 resident credential enumerated from a security * key. * @@ -28,15 +38,19 @@ let Credential; /** * EnrollmentStatus represents the current status of an enrollment suboperation, - * where 'remaining' indicates the number of samples left, 'status' indicates - * the last enrollment status, and 'code' indicates the CtapDeviceResponseCode. + * where 'remaining' is the number of samples left, 'status' is the last + * enrollment status, 'code' indicates the final CtapDeviceResponseCode of the + * operation, and 'enrollment' contains the new Enrollment. + * * For each enrollment sample, 'status' is set - when the enrollment operation - * reaches an end state, 'code' is set. A 'code' of CtapDeviceResponseCode 0 - * indicates successful enrollment. + * reaches an end state, 'code' and, if successful, 'enrollment' are set. |OK| + * indicates successful enrollment. A code of |ERR_KEEPALIVE_CANCEL| indicates + * user-initated cancellation. * * @typedef {{status: ?number, - * code: ?number, - * remaining: number}} + * code: ?Ctap2Status, + * remaining: number, + * enrollment: ?Enrollment}} * @see chrome/browser/ui/webui/settings/settings_security_key_handler.cc */ let EnrollmentStatus; @@ -197,9 +211,6 @@ cr.define('settings', function() { * Cancel an ongoing enrollment suboperation. This can safely be called at * any time and only has an impact when the authenticator is currently * sampling. - * - * @return {!Promise} resolves when the ongoing enrollment suboperation has - * been cancelled. */ cancelEnrollment() {} @@ -211,6 +222,15 @@ cr.define('settings', function() { */ deleteEnrollment(id) {} + /** + * Renames the enrollment with the given ID. + * + * @param {string} id + * @param {string} name + * @return {!Promise<!Array<!Enrollment>>} The updated list of enrollments. + */ + renameEnrollment(id, name) {} + /** Cancels all outstanding operations. */ close() {} } @@ -303,7 +323,7 @@ cr.define('settings', function() { /** @override */ cancelEnrollment() { - return cr.sendWithPromise('securityKeyBioEnrollCancel'); + return chrome.send('securityKeyBioEnrollCancel'); } /** @override */ @@ -312,6 +332,11 @@ cr.define('settings', function() { } /** @override */ + renameEnrollment(id, name) { + return cr.sendWithPromise('securityKeyBioEnrollRename', id, name); + } + + /** @override */ close() { return chrome.send('securityKeyBioEnrollClose'); } diff --git a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html index 0045f54d6a2..070ed2d6abb 100644 --- a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html +++ b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html @@ -69,7 +69,8 @@ <div id="pinPrompt"> <p>$i18nRaw{securityKeysCredentialManagementPinPrompt}</p> - <settings-security-keys-pin-field id="pin"> + <settings-security-keys-pin-field + id="pin" label="$i18n{securityKeysPIN}"> </settings-security-keys-pin-field> </div> @@ -92,9 +93,9 @@ </div> <div class="user">[[formatUser_(item)]]</div> <cr-checkbox on-change="checkedCredentialsChanged_" - data-id$="[[item.id]]" - checked="[[credentialIsChecked_(item.id)]]" - disabled="[[deleteInProgress_]]"></cr-checkbox> + data-id$="[[item.id]]" + checked="[[credentialIsChecked_(item.id)]]" + disabled="[[deleteInProgress_]]"></cr-checkbox> </div> </template> </iron-list> diff --git a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.js b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.js index 146f22674b3..062c329e254 100644 --- a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.js +++ b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.js @@ -98,7 +98,9 @@ Polymer({ if (!this.$.pin.validate()) { return; } + this.confirmButtonDisabled_ = true; this.browserProxy_.providePIN(this.$.pin.value).then((retries) => { + this.confirmButtonDisabled_ = false; if (retries != null) { this.$.pin.showIncorrectPINError(retries); this.collectPin_(); @@ -258,9 +260,11 @@ Polymer({ assert(this.credentials_ && this.credentials_.length > 0); assert(this.checkedCredentialIds_.size > 0); + this.confirmButtonDisabled_ = true; this.deleteInProgress_ = true; this.browserProxy_.deleteCredentials(Array.from(this.checkedCredentialIds_)) .then((err) => { + this.confirmButtonDisabled_ = false; this.deleteInProgress_ = false; this.onError_(err); }); diff --git a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.html b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.html index bd62a4001c0..f185cba1363 100644 --- a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.html +++ b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.html @@ -3,6 +3,7 @@ <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-announcer/iron-a11y-announcer.html"> <link rel="import" href="../i18n_setup.html"> <link rel="import" href="../settings_shared_css.html"> diff --git a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.js b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.js index abace08a7e0..72159d830d7 100644 --- a/chromium/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.js +++ b/chromium/chrome/browser/resources/settings/privacy_page/security_keys_pin_field.js @@ -18,7 +18,10 @@ Polymer({ label: String, /** The validation error label of the input field. */ - error: String, + error: { + type: String, + observer: 'errorChanged_', + }, /** The value of the input field. */ value: String, @@ -32,6 +35,10 @@ Polymer({ /** @override */ attached: function() { + Polymer.RenderStatus.afterNextRender(this, function() { + Polymer.IronA11yAnnouncer.requestAvailability(); + }); + this.inputVisible_ = false; }, @@ -158,4 +165,11 @@ Polymer({ return ''; }, + + /** @private */ + errorChanged_: function() { + // Make screen readers announce changes to the PIN validation error + // label. + this.fire('iron-announce', {text: this.error}); + }, }); diff --git a/chromium/chrome/browser/resources/settings/route.js b/chromium/chrome/browser/resources/settings/route.js index 244cb3be580..091bb933e2e 100644 --- a/chromium/chrome/browser/resources/settings/route.js +++ b/chromium/chrome/browser/resources/settings/route.js @@ -13,6 +13,8 @@ * ACCOUNT_MANAGER: (undefined|!settings.Route), * ADVANCED: (undefined|!settings.Route), * ADDRESSES: (undefined|!settings.Route), + * APP_MANAGEMENT: (undefined|!settings.Route), + * APP_MANAGEMENT_DETAIL: (undefined|!settings.Route), * APPS: (undefined|!settings.Route), * ANDROID_APPS: (undefined|!settings.Route), * ANDROID_APPS_DETAILS: (undefined|!settings.Route), @@ -58,6 +60,7 @@ * LANGUAGES_DETAILS: (undefined|!settings.Route), * LOCK_SCREEN: (undefined|!settings.Route), * MANAGE_ACCESSIBILITY: (undefined|!settings.Route), + * MANAGE_CAPTION_SETTINGS: (undefined|!settings.Route), * MANAGE_PROFILE: (undefined|!settings.Route), * MANAGE_SWITCH_ACCESS_SETTINGS: (undefined|!settings.Route), * MANAGE_TTS_SETTINGS: (undefined|!settings.Route), @@ -95,6 +98,7 @@ * SITE_SETTINGS_FLASH: (undefined|!settings.Route), * SITE_SETTINGS_HANDLERS: (undefined|!settings.Route), * SITE_SETTINGS_IMAGES: (undefined|!settings.Route), + * SITE_SETTINGS_MIXEDSCRIPT: (undefined|!settings.Route), * SITE_SETTINGS_JAVASCRIPT: (undefined|!settings.Route), * SITE_SETTINGS_SENSORS: (undefined|!settings.Route), * SITE_SETTINGS_SOUND: (undefined|!settings.Route), @@ -326,6 +330,10 @@ cr.define('settings', function() { r.SITE_SETTINGS_DATA_DETAILS = r.SITE_SETTINGS_SITE_DATA.createChild('/cookies/detail'); r.SITE_SETTINGS_IMAGES = r.SITE_SETTINGS.createChild('images'); + if (loadTimeData.getBoolean('enableInsecureContentContentSetting')) { + r.SITE_SETTINGS_MIXEDSCRIPT = + r.SITE_SETTINGS.createChild('insecureContent'); + } r.SITE_SETTINGS_JAVASCRIPT = r.SITE_SETTINGS.createChild('javascript'); r.SITE_SETTINGS_SOUND = r.SITE_SETTINGS.createChild('sound'); r.SITE_SETTINGS_SENSORS = r.SITE_SETTINGS.createChild('sensors'); @@ -352,7 +360,7 @@ cr.define('settings', function() { r.SITE_SETTINGS_PAYMENT_HANDLER = r.SITE_SETTINGS.createChild('paymentHandler'); } - if (loadTimeData.getBoolean('enableBluetoothScanningContentSetting')) { + if (loadTimeData.getBoolean('enableExperimentalWebPlatformFeatures')) { r.SITE_SETTINGS_BLUETOOTH_SCANNING = r.SITE_SETTINGS.createChild('bluetoothScanning'); } @@ -453,7 +461,10 @@ cr.define('settings', function() { r.FINGERPRINT = r.LOCK_SCREEN.createChild('/lockScreen/fingerprint'); } - if (loadTimeData.valueExists('androidAppsVisible') && + // Show Android Apps page in the browser if split settings is turned off. + if (!loadTimeData.getBoolean('isOSSettings') && + loadTimeData.getBoolean('showOSSettings') && + loadTimeData.valueExists('androidAppsVisible') && loadTimeData.getBoolean('androidAppsVisible')) { r.ANDROID_APPS = r.BASIC.createSection('/androidApps', 'androidApps'); r.ANDROID_APPS_DETAILS = @@ -524,13 +535,21 @@ cr.define('settings', function() { r.RESET = r.ADVANCED.createSection('/reset', 'reset'); } + const showAppManagement = loadTimeData.valueExists('showAppManagement') && + loadTimeData.getBoolean('showAppManagement'); + const showAndroidApps = loadTimeData.valueExists('androidAppsVisible') && + loadTimeData.getBoolean('androidAppsVisible'); // Apps - if (loadTimeData.valueExists('showApps') && - loadTimeData.getBoolean('showApps')) { + if (showAppManagement || showAndroidApps) { r.APPS = r.BASIC.createSection('/apps', 'apps'); - r.APP_MANAGEMENT = r.APPS.createChild('/app-management'); - r.APP_MANAGEMENT_DETAIL = - r.APP_MANAGEMENT.createChild('/app-management/detail'); + if (showAppManagement) { + r.APP_MANAGEMENT = r.APPS.createChild('/app-management'); + r.APP_MANAGEMENT_DETAIL = + r.APP_MANAGEMENT.createChild('/app-management/detail'); + } + if (showAndroidApps) { + r.ANDROID_APPS_DETAILS = r.APPS.createChild('/androidAppsDetails'); + } } } else { assert(r.ADVANCED, 'ADVANCED route should exist'); @@ -573,6 +592,9 @@ cr.define('settings', function() { } r.MANAGE_TTS_SETTINGS = r.MANAGE_ACCESSIBILITY.createChild('/manageAccessibility/tts'); + + r.MANAGE_CAPTION_SETTINGS = + r.MANAGE_ACCESSIBILITY.createChild('/manageAccessibility/captions'); } // </if> @@ -727,12 +749,16 @@ cr.define('settings', function() { * Initialize the route and query params from the URL. */ initializeRouteFromUrl() { - this.recordMetrics(window.location.pathname); - assert(!this.initializeRouteFromUrlCalled_); this.initializeRouteFromUrlCalled_ = true; const route = this.getRouteForPath(window.location.pathname); + + // Record all correct paths entered on the settings page, and + // as all incorrect paths are routed to the main settings page, + // record all incorrect paths as hitting the main settings page. + this.recordMetrics(route ? route.path : this.routes_.BASIC.path); + // Never allow direct navigation to ADVANCED. if (route && route != this.routes_.ADVANCED) { this.currentRoute = route; @@ -751,6 +777,7 @@ cr.define('settings', function() { assert(!urlPath.startsWith('chrome://')); assert(!urlPath.startsWith('settings')); assert(urlPath.startsWith('/')); + assert(!urlPath.match(/\?/g)); chrome.metricsPrivate.recordSparseHashable( 'WebUI.Settings.PathVisited', urlPath); } 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 83d8b346ed4..4469b4298cc 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 @@ -41,7 +41,10 @@ <div class="list-item" focus-row-container> <div id="name-column"> - <site-favicon favicon-url="[[engine.iconURL]]"></site-favicon> + <site-favicon + favicon-url="[[engine.iconURL]]" + url="[[engine.url]]"> + </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_settings.js b/chromium/chrome/browser/resources/settings/search_settings.js index a98f501303f..60facec8de0 100644 --- a/chromium/chrome/browser/resources/settings/search_settings.js +++ b/chromium/chrome/browser/resources/settings/search_settings.js @@ -149,11 +149,15 @@ cr.define('settings', function() { let associatedControl = null; // Find corresponding SETTINGS-SECTION parent and make it visible. let parent = node; - while (parent && parent.nodeName !== 'SETTINGS-SECTION') { + while (parent.nodeName !== 'SETTINGS-SECTION') { parent = parent.nodeType == Node.DOCUMENT_FRAGMENT_NODE ? parent.host : parent.parentNode; - if (parent && parent.nodeName == 'SETTINGS-SUBPAGE') { + if (!parent) { + // |node| wasn't inside a SETTINGS-SECTION. + return null; + } + if (parent.nodeName == 'SETTINGS-SUBPAGE') { // TODO(dpapad): Cast to SettingsSubpageElement here. associatedControl = assert( parent.associatedControl, @@ -161,9 +165,7 @@ cr.define('settings', function() { parent.pageTitle + ', but was not found.'); } } - if (parent) { - parent.hiddenBySearch = false; - } + parent.hiddenBySearch = false; // Need to add the search bubble after the parent SETTINGS-SECTION has // become visible, otherwise |offsetWidth| returns zero. 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 4dabc3f833b..0bcf8487656 100644 --- a/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.html +++ b/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.html @@ -176,7 +176,8 @@ <iron-icon icon="settings:power-settings-new"></iron-icon> $i18n{onStartup} </a> - <cr-button id="advancedButton" aria-active-attribute="aria-expanded" + <cr-button id="advancedButton" + aria-expanded$="[[boolToString_(advancedOpened)]]" on-click="onAdvancedButtonToggle_" hidden="[[!pageVisibility.advancedSettings]]"> <span>$i18n{advancedPageTitle}</span> 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 38bce70ccb4..c604ae4bcbf 100644 --- a/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.js +++ b/chromium/chrome/browser/resources/settings/settings_menu/settings_menu.js @@ -27,12 +27,12 @@ Polymer({ /** @param {!settings.Route} newRoute */ currentRouteChanged: function(newRoute) { - const currentPath = newRoute.path; - // Focus the initially selected path. const anchors = this.root.querySelectorAll('a'); for (let i = 0; i < anchors.length; ++i) { - if (anchors[i].getAttribute('href') == currentPath) { + const anchorRoute = + settings.router.getRouteForPath(anchors[i].getAttribute('href')); + if (anchorRoute && anchorRoute.contains(newRoute)) { this.setSelectedUrl_(anchors[i].href); return; } @@ -95,4 +95,13 @@ Polymer({ chrome.metricsPrivate.recordUserAction( 'SettingsMenu_ExtensionsLinkClicked'); }, + + /** + * @param {boolean} bool + * @return {string} + * @private + */ + boolToString_: function(bool) { + return bool.toString(); + }, }); diff --git a/chromium/chrome/browser/resources/settings/settings_page/BUILD.gn b/chromium/chrome/browser/resources/settings/settings_page/BUILD.gn index f6f20fe035e..ac38ed67f66 100644 --- a/chromium/chrome/browser/resources/settings/settings_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/settings_page/BUILD.gn @@ -33,7 +33,7 @@ js_library("settings_animated_pages") { "//ui/webui/resources/js:util", "//ui/webui/resources/js/cr/ui:focus_without_ink", ] - externs_list = [ "$externs_path/pending.js" ] + externs_list = [ "$externs_path/pending_polymer.js" ] } js_library("settings_section") { diff --git a/chromium/chrome/browser/resources/settings/settings_page/settings_subpage.html b/chromium/chrome/browser/resources/settings/settings_page/settings_subpage.html index c48064bcaf2..b4ea404e35f 100644 --- a/chromium/chrome/browser/resources/settings/settings_page/settings_subpage.html +++ b/chromium/chrome/browser/resources/settings/settings_page/settings_subpage.html @@ -75,7 +75,7 @@ <cr-icon-button class="icon-arrow-back" id="closeButton" on-click="onTapBack_" aria-label="$i18n{back}"></cr-icon-button> <template is="dom-if" if="[[titleIcon]]"> - <img id="title-icon" src="[[titleIcon]]"> + <img id="title-icon" src="[[titleIcon]]" aria-hidden="true"> </template> <h1 class="cr-title-text">[[pageTitle]]</h1> <slot name="subpage-title-extra"></slot> diff --git a/chromium/chrome/browser/resources/settings/settings_resources.grd b/chromium/chrome/browser/resources/settings/settings_resources.grd index 14f631a9af7..ea0b1a1026a 100644 --- a/chromium/chrome/browser/resources/settings/settings_resources.grd +++ b/chromium/chrome/browser/resources/settings/settings_resources.grd @@ -563,12 +563,6 @@ <structure name="IDR_SETTINGS_DEVICE_DISPLAY_OVERSCAN_DIALOG_JS" file="device_page/display_overscan_dialog.js" type="chrome_html" /> - <structure name="IDR_SETTINGS_DEVICE_DRIVE_CACHE_DIALOG_HTML" - file="device_page/drive_cache_dialog.html" - type="chrome_html" /> - <structure name="IDR_SETTINGS_DEVICE_DRIVE_CACHE_DIALOG_JS" - file="device_page/drive_cache_dialog.js" - type="chrome_html" /> <structure name="IDR_SETTINGS_DEVICE_KEYBOARD_HTML" file="device_page/keyboard.html" type="chrome_html" /> @@ -987,11 +981,17 @@ <structure name="IDR_SETTINGS_CUPS_PRINTERS_ENTRY_JS" file="printing_page/cups_printers_entry.js" type="chrome_html" /> - <structure name="IDR_SETTINGS_CUPS_PRINTERS_ENTRY_LIST_HTML" - file="printing_page/cups_printers_entry_list.html" + <structure name="IDR_SETTINGS_CUPS_PRINTERS_ENTRY_LIST_BEHAVIOR_HTML" + file="printing_page/cups_printers_entry_list_behavior.html" + type="chrome_html" /> + <structure name="IDR_SETTINGS_CUPS_PRINTERS_ENTRY_LIST_BEHAVIOR_JS" + file="printing_page/cups_printers_entry_list_behavior.js" + type="chrome_html" /> + <structure name="IDR_SETTINGS_CUPS_PRINTERS_ENTRY_MANAGER_HTML" + file="printing_page/cups_printers_entry_manager.html" type="chrome_html" /> - <structure name="IDR_SETTINGS_CUPS_PRINTERS_ENTRY_LIST_JS" - file="printing_page/cups_printers_entry_list.js" + <structure name="IDR_SETTINGS_CUPS_PRINTERS_ENTRY_MANAGER_JS" + file="printing_page/cups_printers_entry_manager.js" type="chrome_html" /> <structure name="IDR_SETTINGS_CUPS_PRINTERS_LIST_HTML" file="printing_page/cups_printers_list.html" diff --git a/chromium/chrome/browser/resources/settings/settings_ui/BUILD.gn b/chromium/chrome/browser/resources/settings/settings_ui/BUILD.gn index ae564bee278..8cbb5556ae7 100644 --- a/chromium/chrome/browser/resources/settings/settings_ui/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/settings_ui/BUILD.gn @@ -17,7 +17,7 @@ js_library("settings_ui") { "../prefs", "../settings_main:settings_main", "//ui/webui/resources/cr_elements:cr_container_shadow_behavior", - "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_types", + "//ui/webui/resources/cr_elements/chromeos/network:cr_onc_strings", "//ui/webui/resources/cr_elements/cr_drawer:cr_drawer", "//ui/webui/resources/cr_elements/cr_toolbar:cr_toolbar", "//ui/webui/resources/cr_elements/cr_toolbar:cr_toolbar_search_field", 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 286257d15ea..5f25212f6be 100644 --- a/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.html +++ b/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.html @@ -21,7 +21,7 @@ <link rel="import" href="../settings_vars_css.html"> <if expr="chromeos"> -<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_types.html"> +<link rel="import" href="chrome://resources/cr_elements/chromeos/network/cr_onc_strings.html"> </if> <dom-module id="settings-ui"> 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 fdbbef286d5..f3b8d60d861 100644 --- a/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.js +++ b/chromium/chrome/browser/resources/settings/settings_ui/settings_ui.js @@ -152,8 +152,12 @@ Polymer({ loadTimeData.getString('networkListItemConnectingTo'), networkListItemInitializing: loadTimeData.getString('networkListItemInitializing'), + networkListItemNotAvailable: + loadTimeData.getString('networkListItemNotAvailable'), networkListItemScanning: loadTimeData.getString('networkListItemScanning'), + networkListItemSimCardLocked: + loadTimeData.getString('networkListItemSimCardLocked'), networkListItemNotConnected: loadTimeData.getString('networkListItemNotConnected'), networkListItemNoNetwork: diff --git a/chromium/chrome/browser/resources/settings/site_favicon.js b/chromium/chrome/browser/resources/settings/site_favicon.js index e905bd54e35..b6d516d0e71 100644 --- a/chromium/chrome/browser/resources/settings/site_favicon.js +++ b/chromium/chrome/browser/resources/settings/site_favicon.js @@ -17,7 +17,7 @@ Polymer({ /** @private */ getBackgroundImage_: function() { - let backgroundImage = 'none'; + let backgroundImage = cr.icon.getFavicon(''); if (this.faviconUrl) { const url = this.ensureUrlHasScheme_(this.faviconUrl); backgroundImage = cr.icon.getFavicon(url); 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 938cfebaeac..6b38253df50 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 @@ -30,6 +30,10 @@ contentSetting)]]"> $i18n{incognitoSiteOnly} </cr-checkbox> + <cr-checkbox id="thirdParties" + hidden$="[[shouldHideThirdPartyCookieCheckbox_(category)]]"> + $i18n{siteSettingsCookiesThirdPartyExceptionLabel} + </cr-checkbox> </div> <div slot="button-container"> <cr-button class="cancel-button" on-click="onCancelTap_"> 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 973e15fca05..a9962dde633 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 @@ -86,9 +86,18 @@ Polymer({ */ onSubmit_: function() { assert(!this.$.add.disabled); + let primaryPattern = this.site_; + let secondaryPattern = settings.SITE_EXCEPTION_WILDCARD; + + if (this.$.thirdParties.checked) { + primaryPattern = settings.SITE_EXCEPTION_WILDCARD; + secondaryPattern = this.site_; + } + this.browserProxy.setCategoryPermissionForPattern( - this.site_, this.site_, this.category, this.contentSetting, + primaryPattern, secondaryPattern, this.category, this.contentSetting, this.$.incognito.checked); + this.$.dialog.close(); }, @@ -104,4 +113,13 @@ Polymer({ this.$.incognito.checked = false; } }, + + /** + * @return {boolean} + * @private + */ + shouldHideThirdPartyCookieCheckbox_: function() { + return this.category !== settings.ContentSettingsTypes.COOKIES || + !loadTimeData.getBoolean('showImprovedCookieControlsForThirdParties'); + }, }); 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 554bc6992dc..a3e2d3277eb 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 @@ -103,6 +103,7 @@ Polymer({ case settings.ContentSettingsTypes.BACKGROUND_SYNC: case settings.ContentSettingsTypes.IMAGES: case settings.ContentSettingsTypes.JAVASCRIPT: + case settings.ContentSettingsTypes.MIXEDSCRIPT: case settings.ContentSettingsTypes.SOUND: case settings.ContentSettingsTypes.SENSORS: case settings.ContentSettingsTypes.PAYMENT_HANDLER: @@ -176,10 +177,22 @@ Polymer({ if (update.source !== undefined && update.source != ContentSettingProvider.PREFERENCE) { basePref.enforcement = chrome.settingsPrivate.Enforcement.ENFORCED; - basePref.controlledBy = - update.source == ContentSettingProvider.EXTENSION ? - chrome.settingsPrivate.ControlledBy.EXTENSION : - chrome.settingsPrivate.ControlledBy.USER_POLICY; + switch (update.source) { + case ContentSettingProvider.POLICY: + basePref.controlledBy = + chrome.settingsPrivate.ControlledBy.DEVICE_POLICY; + break; + case ContentSettingProvider.SUPERVISED_USER: + basePref.controlledBy = chrome.settingsPrivate.ControlledBy.PARENT; + break; + case ContentSettingProvider.EXTENSION: + basePref.controlledBy = chrome.settingsPrivate.ControlledBy.EXTENSION; + break; + default: + basePref.controlledBy = + chrome.settingsPrivate.ControlledBy.USER_POLICY; + break; + } } const prefValue = this.computeIsSettingEnabled(update.setting); diff --git a/chromium/chrome/browser/resources/settings/site_settings/category_setting_exceptions.html b/chromium/chrome/browser/resources/settings/site_settings/category_setting_exceptions.html index 01d7cb15355..6fb8781c59a 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/category_setting_exceptions.html +++ b/chromium/chrome/browser/resources/settings/site_settings/category_setting_exceptions.html @@ -1,7 +1,9 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> <link rel="import" href="constants.html"> <link rel="import" href="site_list.html"> +<link rel="import" href="site_settings_prefs_browser_proxy.html"> <dom-module id="category-setting-exceptions"> <template> @@ -9,7 +11,7 @@ category="[[category]]" category-subtype="[[ContentSetting.BLOCK]]" category-header="[[blockHeader]]" - read-only-list="[[readOnlyList]]" + read-only-list="[[getReadOnlyList_(readOnlyList, defaultManaged_)]]" search-filter="[[searchFilter]]" hidden$="[[!showBlockSiteList_]]"> </site-list> @@ -17,14 +19,14 @@ category="[[category]]" category-subtype="[[ContentSetting.SESSION_ONLY]]" category-header="$i18n{siteSettingsSessionOnly}" - read-only-list="[[readOnlyList]]" + read-only-list="[[getReadOnlyList_(readOnlyList, defaultManaged_)]]" search-filter="[[searchFilter]]"> </site-list> <site-list category="[[category]]" category-subtype="[[ContentSetting.ALLOW]]" category-header="$i18n{siteSettingsAllow}" - read-only-list="[[readOnlyList]]" + read-only-list="[[getReadOnlyList_(readOnlyList, defaultManaged_)]]" search-filter="[[searchFilter]]" hidden$="[[!showAllowSiteList_]]"> </site-list> diff --git a/chromium/chrome/browser/resources/settings/site_settings/category_setting_exceptions.js b/chromium/chrome/browser/resources/settings/site_settings/category_setting_exceptions.js index 212204450a9..44997259653 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/category_setting_exceptions.js +++ b/chromium/chrome/browser/resources/settings/site_settings/category_setting_exceptions.js @@ -10,6 +10,8 @@ Polymer({ is: 'category-setting-exceptions', + behaviors: [SiteSettingsBehavior, WebUIListenerBehavior], + properties: { /** @@ -30,6 +32,12 @@ Polymer({ }, /** + * True if the default value is managed by a policy. + * @private + */ + defaultManaged_: Boolean, + + /** * The heading text for the blocked exception list. */ blockHeader: String, @@ -54,9 +62,15 @@ Polymer({ }, }, + observers: [ + 'updateDefaultManaged_(category)', + ], + /** @override */ ready: function() { this.ContentSetting = settings.ContentSetting; + this.addWebUIListener( + 'contentSettingCategoryChanged', this.updateDefaultManaged_.bind(this)); }, /** @@ -69,4 +83,32 @@ Polymer({ return this.category != settings.ContentSettingsTypes.NATIVE_FILE_SYSTEM_WRITE; }, + + /** + * Updates whether or not the default value is managed by a policy. + * @private + */ + updateDefaultManaged_: function() { + if (this.category === undefined) { + return; + } + + this.browserProxy.getDefaultValueForContentType(this.category) + .then(update => { + this.defaultManaged_ = + update.source === settings.SiteSettingSource.POLICY; + }); + }, + + /** + * Returns true if this list is explicitly marked as readonly by a consumer + * of this component or if the default value for these exceptions are managed + * by a policy. User should not be able to set exceptions to managed default + * values. + * @return {boolean} + * @private + */ + getReadOnlyList_: function() { + return this.readOnlyList || this.defaultManaged_; + } }); diff --git a/chromium/chrome/browser/resources/settings/site_settings/constants.js b/chromium/chrome/browser/resources/settings/site_settings/constants.js index a7cf78b84ad..f073aa9b3db 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/constants.js +++ b/chromium/chrome/browser/resources/settings/site_settings/constants.js @@ -36,6 +36,7 @@ settings.ContentSettingsTypes = { CLIPBOARD: 'clipboard', SENSORS: 'sensors', PAYMENT_HANDLER: 'payment-handler', + MIXEDSCRIPT: 'mixed-script', BLUETOOTH_SCANNING: 'bluetooth-scanning', NATIVE_FILE_SYSTEM_WRITE: 'native-file-system-write', }; @@ -121,3 +122,10 @@ settings.SortMethod = { MOST_VISITED: 'most-visited', STORAGE: 'data-stored', }; + +/** + * String representation of the wildcard used for universal + * match for SiteExceptions. + * @type {string} + */ +settings.SITE_EXCEPTION_WILDCARD = '*'; 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 9fc485db610..f1a028c92b5 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/site_data.html +++ b/chromium/chrome/browser/resources/settings/site_settings/site_data.html @@ -44,7 +44,7 @@ </cr-button> <cr-button disabled$="[[isLoading_]]" id="removeThirdPartyCookies" on-click="onRemoveThirdPartyCookiesTap_" - hidden$="[[!enableRemovingAllThirdPartyCookies_]]"> + hidden$="[[!showRemoveThirdPartyCookies_(sites.length, filter)]]"> $i18n{siteSettingsCookieRemoveAllThirdParty} </cr-button> </div> 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 644aedc4ac0..cd6370aa91c 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/site_data.js +++ b/chromium/chrome/browser/resources/settings/site_settings/site_data.js @@ -75,15 +75,6 @@ Polymer({ /** @private */ listBlurred_: Boolean, - - /** @private */ - enableRemovingAllThirdPartyCookies_: { - type: Boolean, - value: function() { - return loadTimeData.getBoolean('enableRemovingAllThirdPartyCookies') && - (this.sites.length > 0); - } - }, }, /** @private {settings.LocalDataBrowserProxy} */ @@ -287,4 +278,13 @@ Polymer({ new URLSearchParams('site=' + event.model.item.site)); this.lastSelected_ = event.model; }, + + /** + * @private + * @return {boolean} + */ + showRemoveThirdPartyCookies_: function() { + return loadTimeData.getBoolean('enableRemovingAllThirdPartyCookies') && + this.sites.length > 0 && this.filter.length == 0; + }, }); diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_details.html b/chromium/chrome/browser/resources/settings/site_settings/site_details.html index 1472652cc9e..fb24557a8e0 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/site_details.html +++ b/chromium/chrome/browser/resources/settings/site_settings/site_details.html @@ -207,13 +207,20 @@ icon="settings:payment-handler" id="paymentHandler" label="$i18n{siteSettingsPaymentHandler}"> </site-details-permission> - <template is="dom-if" if="[[enableBluetoothScanningContentSetting_]]"> + <template is="dom-if" if="[[enableExperimentalWebPlatformFeatures_]]"> <site-details-permission category="{{ContentSettingsTypes.BLUETOOTH_SCANNING}}" icon="settings:bluetooth-scanning" id="bluetoothScanning" label="$i18n{siteSettingsBluetoothScanning}"> </site-details-permission> </template> + <template is="dom-if" if="[[enableInsecureContentContentSetting_]]"> + <site-details-permission + category="{{ContentSettingsTypes.MIXEDSCRIPT}}" + icon="settings:insecure-content" id="mixed-script" + label="$i18n{siteSettingsInsecureContent}"> + </site-details-permission> + </template> </div> <website-usage-private-api id="usageApi" diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_details.js b/chromium/chrome/browser/resources/settings/site_settings/site_details.js index 875533a5f19..df765e0e3af 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/site_details.js +++ b/chromium/chrome/browser/resources/settings/site_settings/site_details.js @@ -63,19 +63,19 @@ Polymer({ }, /** @private */ - enableBluetoothScanningContentSetting_: { + enableNativeFileSystemWriteContentSetting_: { type: Boolean, value: function() { - return loadTimeData.getBoolean('enableBluetoothScanningContentSetting'); + return loadTimeData.getBoolean( + 'enableNativeFileSystemWriteContentSetting'); } }, /** @private */ - enableNativeFileSystemWriteContentSetting_: { + enableInsecureContentContentSetting_: { type: Boolean, value: function() { - return loadTimeData.getBoolean( - 'enableNativeFileSystemWriteContentSetting'); + return loadTimeData.getBoolean('enableInsecureContentContentSetting'); } }, }, @@ -185,7 +185,9 @@ Polymer({ exceptionList.forEach((exception, i) => { // |exceptionList| should be in the same order as // |categoryList|. - permissionsMap[categoryList[i]].site = exception; + if (permissionsMap[categoryList[i]]) { + permissionsMap[categoryList[i]].site = exception; + } }); // The displayName won't change, so just use the first 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 f296bf59503..da644580de1 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 @@ -36,16 +36,17 @@ <site-favicon url="[[model.origin]]"></site-favicon> <div class="middle no-min-width"> <div class="text-elide"> - <span class="url-directionality">[[model.displayName]]</span> + <span class="url-directionality">[[computeDisplayName_(model)]] + </span> </div> <!-- This div must not contain extra whitespace. --> <div class="secondary text-elide" - id="siteDescription">[[siteDescription_]]</div> + id="siteDescription">[[computeSiteDescription_(model)]]</div> </div> <template is="dom-if" if="[[allowNavigateToSiteDetail_]]"> <cr-icon-button class="subpage-arrow" - aria-label$="[[model.displayName]]" + aria-label$="[[computeDisplayName_(model)]]" aria-describedby="siteDescription" focus-row-control focus-type="site-details"></cr-icon-button> <div class="separator"></div> diff --git a/chromium/chrome/browser/resources/settings/site_settings/site_list_entry.js b/chromium/chrome/browser/resources/settings/site_settings/site_list_entry.js index fda7071af91..b296f31a34a 100644 --- a/chromium/chrome/browser/resources/settings/site_settings/site_list_entry.js +++ b/chromium/chrome/browser/resources/settings/site_settings/site_list_entry.js @@ -55,12 +55,6 @@ Polymer({ }, /** @private */ - siteDescription_: { - type: String, - computed: 'computeSiteDescription_(model)', - }, - - /** @private */ showPolicyPrefIndicator_: { type: Boolean, computed: 'computeShowPolicyPrefIndicator_(model)', @@ -126,34 +120,59 @@ Polymer({ }, /** + * Returns the appropriate display name to show for the exception. + * This can, for example, be the website that is affected itself, + * or the website whose third parties are also affected. + * @return {string} + */ + computeDisplayName_: function() { + if (this.model.embeddingOrigin && + this.model.category === settings.ContentSettingsTypes.COOKIES && + this.model.origin.trim() == settings.SITE_EXCEPTION_WILDCARD) { + return this.model.embeddingOrigin; + } + return this.model.displayName; + }, + + /** * Returns the appropriate site description to display. This can, for example, * be blank, an 'embedded on <site>' or 'Current incognito session' (or a * mix of the last two). - * @return {string} The site description. + * @return {string} */ computeSiteDescription_: function() { - let displayName = ''; + let description = ''; + if (this.model.embeddingOrigin) { - displayName = loadTimeData.getStringF( - 'embeddedOnHost', this.sanitizePort(this.model.embeddingOrigin)); + if (this.model.category === settings.ContentSettingsTypes.COOKIES && + this.model.origin.trim() == settings.SITE_EXCEPTION_WILDCARD) { + description = + loadTimeData.getString( + 'siteSettingsCookiesThirdPartyExceptionLabel'); + } else { + description = loadTimeData.getStringF( + 'embeddedOnHost', this.sanitizePort(this.model.embeddingOrigin)); + } } else if (this.category == settings.ContentSettingsTypes.GEOLOCATION) { - displayName = loadTimeData.getString('embeddedOnAnyHost'); + description = loadTimeData.getString('embeddedOnAnyHost'); } // <if expr="chromeos"> if (this.model.category === settings.ContentSettingsTypes.NOTIFICATIONS && this.model.showAndroidSmsNote) { - displayName = loadTimeData.getString('androidSmsNote'); + description = loadTimeData.getString('androidSmsNote'); } // </if> if (this.model.incognito) { - if (displayName.length > 0) { - return loadTimeData.getStringF('embeddedIncognitoSite', displayName); + if (description.length > 0) { + description = + loadTimeData.getStringF('embeddedIncognitoSite', description); + } else { + description = loadTimeData.getString('incognitoSite'); } - return loadTimeData.getString('incognitoSite'); } - return displayName; + return description; }, /** 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 af45a352e33..545c49afcba 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 @@ -196,17 +196,20 @@ const SiteSettingsBehaviorImpl = { settings.ContentSettingsTypes.SERIAL_PORTS, 'enableExperimentalWebPlatformFeatures'); addOrRemoveSettingWithFlag( + settings.ContentSettingsTypes.BLUETOOTH_SCANNING, + 'enableExperimentalWebPlatformFeatures'); + addOrRemoveSettingWithFlag( settings.ContentSettingsTypes.ADS, 'enableSafeBrowsingSubresourceFilter'); addOrRemoveSettingWithFlag( settings.ContentSettingsTypes.PAYMENT_HANDLER, 'enablePaymentHandlerContentSetting'); addOrRemoveSettingWithFlag( - settings.ContentSettingsTypes.BLUETOOTH_SCANNING, - 'enableBluetoothScanningContentSetting'); - addOrRemoveSettingWithFlag( settings.ContentSettingsTypes.NATIVE_FILE_SYSTEM_WRITE, 'enableNativeFileSystemWriteContentSetting'); + addOrRemoveSettingWithFlag( + settings.ContentSettingsTypes.MIXEDSCRIPT, + 'enableInsecureContentContentSetting'); return this.contentTypes_.slice(0); }, 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 267e480c034..2b826c3b5a2 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 @@ -14,8 +14,16 @@ * @enum {string} */ const ContentSettingProvider = { + POLICY: 'policy', + SUPERVISED_USER: 'supervised_user', EXTENSION: 'extension', + INSTALLED_WEBAPP_PROVIDER: 'installed_webapp_provider', + NOTIFICATION_ANDROID: 'notification_android', + EPHEMERAL: 'ephemeral', PREFERENCE: 'preference', + DEFAULT: 'default', + TESTS: 'tests', + TESTS_OTHER: 'tests_other' }; /** @@ -426,12 +434,9 @@ cr.define('settings', function() { /** @override */ setCategoryPermissionForPattern( primaryPattern, secondaryPattern, contentType, value, incognito) { - // TODO(dschuyler): It may be incorrect for JS to send the embeddingOrigin - // pattern. Look into removing this parameter from site_settings_handler. - // Ignoring the |secondaryPattern| and using '' instead is a quick-fix. chrome.send( 'setCategoryPermissionForPattern', - [primaryPattern, '', contentType, value, incognito]); + [primaryPattern, secondaryPattern, contentType, value, incognito]); } /** @override */ diff --git a/chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.html b/chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.html index a2adc7f829b..3db16d2d4f1 100644 --- a/chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.html +++ b/chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.html @@ -247,7 +247,16 @@ '$i18nPolymer{siteSettingsPaymentHandlerBlock}')]]"></cr-link-row> </template> - <template is="dom-if" if="[[enableBluetoothScanningContentSetting_]]"> + <template is="dom-if" if="[[enableInsecureContentContentSetting_]]"> + <cr-link-row class="hr two-line" data-route="SITE_SETTINGS_MIXEDSCRIPT" + label="$i18n{siteSettingsInsecureContent}" + on-click="onTapNavigate_" + start-icon="settings:insecure-content" + sub-label="$i18n{siteSettingsInsecureContentBlock}" + </cr-link-row> + </template> + + <template is="dom-if" if="[[enableExperimentalWebPlatformFeatures_]]"> <cr-link-row class="hr two-line" data-route="SITE_SETTINGS_BLUETOOTH_SCANNING" id="bluetooth-scanning" label="$i18n{siteSettingsBluetoothScanning}" diff --git a/chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.js b/chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.js index 25bee399e1c..588b6d078aa 100644 --- a/chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.js +++ b/chromium/chrome/browser/resources/settings/site_settings_page/site_settings_page.js @@ -60,10 +60,10 @@ Polymer({ }, /** @private */ - enableBluetoothScanningContentSetting_: { + enableInsecureContentContentSetting_: { type: Boolean, value: function() { - return loadTimeData.getBoolean('enableBluetoothScanningContentSetting'); + return loadTimeData.getBoolean('enableInsecureContentContentSetting'); } }, @@ -130,7 +130,7 @@ Polymer({ pairs.push([R.SITE_SETTINGS_SERIAL_PORTS, 'serial-ports']); } - if (this.enableBluetoothScanningContentSetting_) { + if (this.enableExperimentalWebPlatformFeatures_) { pairs.push([R.SITE_SETTINGS_BLUETOOTH_SCANNING, 'bluetooth-scanning']); } @@ -140,6 +140,10 @@ Polymer({ ]); } + if (this.enableInsecureContentContentSetting_) { + pairs.push([R.SITE_SETTINGS_MIXEDSCRIPT, 'mixed-script']); + } + pairs.forEach(([route, id]) => { this.focusConfig.set(route.path, () => this.async(() => { cr.ui.focusWithoutInk(assert(this.$$(`#${id}`))); |