diff options
Diffstat (limited to 'chromium/chrome/browser/resources/settings/autofill_page')
3 files changed, 134 insertions, 27 deletions
diff --git a/chromium/chrome/browser/resources/settings/autofill_page/BUILD.gn b/chromium/chrome/browser/resources/settings/autofill_page/BUILD.gn index 84a9f949cac..1afa9c4b7ef 100644 --- a/chromium/chrome/browser/resources/settings/autofill_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/autofill_page/BUILD.gn @@ -117,14 +117,16 @@ js_library("passwords_section") { ":password_list_item", ":password_manager_proxy", "..:global_scroll_target_behavior", + "../people_page:sync_browser_proxy", "//third_party/polymer/v1_0/components-chromium/iron-a11y-announcer:iron-a11y-announcer-extracted", "//third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior:iron-a11y-keys-behavior-extracted", "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu", - "//ui/webui/resources/cr_elements/cr_toast:cr_toast", + "//ui/webui/resources/cr_elements/cr_toast:cr_toast_manager", "//ui/webui/resources/js:assert", "//ui/webui/resources/js:i18n_behavior", "//ui/webui/resources/js:list_property_update_behavior", "//ui/webui/resources/js:util", + "//ui/webui/resources/js:web_ui_listener_behavior", "//ui/webui/resources/js/cr/ui:focus_without_ink", ] externs_list = [ "$externs_path/passwords_private.js" ] 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 1e7b7923b1a..58e376e7433 100644 --- a/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.html +++ b/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.html @@ -3,7 +3,7 @@ <link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html"> <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/cr_toast/cr_toast.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_toast/cr_toast_manager.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.html"> @@ -17,6 +17,7 @@ <link rel="import" href="../controls/extension_controlled_indicator.html"> <link rel="import" href="../global_scroll_target_behavior.html"> <link rel="import" href="../prefs/prefs.html"> +<link rel="import" href="../prefs/prefs_behavior.html"> <link rel="import" href="../settings_shared_css.html"> <link rel="import" href="../site_favicon.html"> <link rel="import" href="password_edit_dialog.html"> @@ -72,12 +73,23 @@ </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}" sub-label="$i18n{passwordsAutosigninDescription}"> </settings-toggle-button> - <div id="manageLink" class="settings-box first two-line"> + <div id="manageLink" class="settings-box first two-line" + hidden$="[[hidePasswordsLink_]]"> <!-- This span lays out the url correctly, relative to the label. --> <span>$i18nRaw{managePasswordsLabel}</span> </div> @@ -163,12 +175,11 @@ </settings-password-prompt-dialog> </template> </if> - <cr-toast id="undoToast" duration="[[toastDuration_]]"> - <div id="undoLabel">$i18n{passwordDeleted}</div> - <cr-button on-click="onUndoButtonTap_"> - $i18n{undoRemovePassword} - </cr-button> - </cr-toast> + <cr-toast-manager on-undo-click="onUndoButtonTap_" + undo-label="$i18n{undoRemovePassword}" + undo-description="$i18n{undoDescription}" + duration="[[toastDuration_]]"> + </cr-toast-manager> <div class="settings-box block first"> <h2>$i18n{passwordExceptionsHeading}</h2> </div> 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 1f552fdf4ec..a98d69646d4 100644 --- a/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.js +++ b/chromium/chrome/browser/resources/settings/autofill_page/passwords_section.js @@ -36,9 +36,11 @@ Polymer({ behaviors: [ I18nBehavior, + WebUIListenerBehavior, ListPropertyUpdateBehavior, Polymer.IronA11yKeysBehavior, settings.GlobalScrollTargetBehavior, + PrefsBehavior, ], properties: { @@ -94,6 +96,18 @@ Polymer({ }, /** @private */ + hidePasswordsLink_: { + type: Boolean, + computed: 'computeHidePasswordsLink_(syncPrefs_, syncStatus_)', + }, + + /** @private */ + passwordsLeakDetectionEnabled_: { + type: Boolean, + value: loadTimeData.getBoolean('passwordsLeakDetectionEnabled'), + }, + + /** @private */ showExportPasswords_: { type: Boolean, computed: 'hasPasswords_(savedPasswords.splices)', @@ -111,6 +125,23 @@ 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, @@ -156,11 +187,14 @@ Polymer({ }, /** - * The element to return focus to, when the currently active dialog is - * closed. - * @private {?HTMLElement} + * A stack of the elements that triggered dialog to open and should therefore + * receive focus when that dialog is closed. The bottom of the stack is the + * element that triggered the earliest open dialog and top of the stack is the + * element that triggered the most recent (i.e. active) dialog. If no dialog + * is open, the stack is empty. + * @private {!Array<Element>} */ - activeDialogAnchor_: null, + activeDialogAnchorStack_: [], /** * @type {PasswordManagerProxy} @@ -210,7 +244,7 @@ Polymer({ this.tokenRequestManager_ = new settings.BlockingRequestManager(); } else { this.tokenRequestManager_ = new settings.BlockingRequestManager( - () => this.showPasswordPromptDialog_ = true); + this.openPasswordPromptDialog_.bind(this)); } // </if> @@ -226,6 +260,23 @@ Polymer({ this.notifySplices('savedPasswords', []); + const syncBrowserProxy = settings.SyncBrowserProxyImpl.getInstance(); + + const syncStatusChanged = syncStatus => this.syncStatus_ = syncStatus; + 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); + Polymer.RenderStatus.afterNextRender(this, function() { Polymer.IronA11yAnnouncer.requestAvailability(); }); @@ -243,9 +294,8 @@ Polymer({ * @type {function(!Array<PasswordManagerProxy.ExceptionEntry>):void} */ (this.setPasswordExceptionsListener_)); - - if (this.$.undoToast.open) { - this.$.undoToast.hide(); + if (cr.toastManager.getInstance().isToastOpen) { + cr.toastManager.getInstance().hide(); } }, @@ -273,6 +323,12 @@ Polymer({ onPasswordPromptClosed_: function() { this.showPasswordPromptDialog_ = false; + cr.ui.focusWithoutInk(assert(this.activeDialogAnchorStack_.pop())); + }, + + openPasswordPromptDialog_: function() { + this.activeDialogAnchorStack_.push(getDeepActiveElement()); + this.showPasswordPromptDialog_ = true; }, // </if> @@ -290,8 +346,7 @@ Polymer({ /** @private */ onPasswordEditDialogClosed_: function() { this.showPasswordEditDialog_ = false; - cr.ui.focusWithoutInk(assert(this.activeDialogAnchor_)); - this.activeDialogAnchor_ = null; + cr.ui.focusWithoutInk(assert(this.activeDialogAnchorStack_.pop())); // Trigger a re-evaluation of the activePassword as the visibility state of // the password might have changed. @@ -299,6 +354,33 @@ Polymer({ }, /** + * @return {boolean} + * @private + */ + computeHidePasswordsLink_: function() { + return !!this.syncStatus_ && !!this.syncStatus_.signedIn && + !!this.syncPrefs_ && !!this.syncPrefs_.encryptAllData; + }, + + /** + * @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 @@ -314,6 +396,20 @@ 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 @@ -330,8 +426,7 @@ Polymer({ onMenuRemovePasswordTap_: function() { this.passwordManager_.removeSavedPassword( this.activePassword.item.entry.id); - this.fire('iron-announce', {text: this.$.undoLabel.textContent}); - this.$.undoToast.show(); + cr.toastManager.getInstance().show(this.i18n('passwordDeleted'), false); /** @type {CrActionMenuElement} */ (this.$.menu).close(); }, @@ -344,7 +439,7 @@ Polymer({ const activeElement = getDeepActiveElement(); if (!activeElement || !isEditable(activeElement)) { this.passwordManager_.undoRemoveSavedPasswordOrException(); - this.$.undoToast.hide(); + cr.toastManager.getInstance().hide(); // Preventing the default is necessary to not conflict with a possible // search action. event.preventDefault(); @@ -353,7 +448,7 @@ Polymer({ onUndoButtonTap_: function() { this.passwordManager_.undoRemoveSavedPasswordOrException(); - this.$.undoToast.hide(); + cr.toastManager.getInstance().hide(); }, /** * Fires an event that should delete the password exception. @@ -376,7 +471,7 @@ Polymer({ this.activePassword = /** @type {!PasswordListItemElement} */ (event.detail.listItem); menu.showAt(target); - this.activeDialogAnchor_ = target; + this.activeDialogAnchorStack_.push(target); }, /** @@ -389,7 +484,7 @@ Polymer({ /** @type {!HTMLElement} */ (this.$$('#exportImportMenuButton')); menu.showAt(target); - this.activeDialogAnchor_ = target; + this.activeDialogAnchorStack_.push(target); }, /** @@ -413,8 +508,7 @@ Polymer({ /** @private */ onPasswordsExportDialogClosed_: function() { this.showPasswordsExportDialog_ = false; - cr.ui.focusWithoutInk(assert(this.activeDialogAnchor_)); - this.activeDialogAnchor_ = null; + cr.ui.focusWithoutInk(assert(this.activeDialogAnchorStack_.pop())); }, /** |