Commit 93d28f05 authored by sauski's avatar sauski Committed by Commit Bot

Add Focus support to the Recent Permissions Element

The Recent Permissions polymer element introduced in a previous CL did
not support re-focusing upon a back navigation. This CL extents the
element to support this.

Bug: 1032584
Change-Id: I20d038d27ea55f7f6146e661277f9640d1350a4d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2086262
Commit-Queue: Theodore Olsauskas-Warren <sauski@google.com>
Reviewed-by: default avatardpapad <dpapad@chromium.org>
Cr-Commit-Position: refs/heads/master@{#748789}
parent 03a25075
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
<div class="list-item secondary">$i18n{noRecentPermissions}</div> <div class="list-item secondary">$i18n{noRecentPermissions}</div>
</div> </div>
<template is="dom-repeat" id="recentPermissionsList" <template is="dom-repeat" id="recentPermissionsList"
items="[[recentSitePermissionsList_]]"> items="[[recentSitePermissionsList_]]" on-dom-change="onDomChange_">
<div class$="settings-box [[getClassForIndex_(index)]]"> <div class$="settings-box [[getClassForIndex_(index)]]">
<div class="start row-aligned link-button" <div class="start row-aligned link-button"
on-click="onRecentSitePermissionClick_" actionable on-click="onRecentSitePermissionClick_" actionable
...@@ -76,12 +76,13 @@ ...@@ -76,12 +76,13 @@
[[getPermissionsText_(item)]] [[getPermissionsText_(item)]]
</div> </div>
</div> </div>
<cr-icon-button class="subpage-arrow" <cr-icon-button id="siteEntryButton_[[index]]" class="subpage-arrow"
hidden$="[[item.incognito]]" hidden$="[[item.incognito]]"
aria-label$="[[getDisplayName_(item)]]" aria-label$="[[getDisplayName_(item)]]"
aria-describedby$="displayName_[[index]]" aria-describedby$="displayName_[[index]]"
focus-row-control focus-type="show-detail"></cr-icon-button> focus-row-control focus-type="show-detail"></cr-icon-button>
<cr-tooltip-icon class="incognito-icon" <cr-tooltip-icon id="incognitoInfoIcon_[[index]]"
class="incognito-icon"
hidden$="[[!item.incognito]]" hidden$="[[!item.incognito]]"
disabled$="[[item.incognito]]" disabled$="[[item.incognito]]"
icon-aria-label="$i18n{incognitoSiteExceptionDesc}" icon-aria-label="$i18n{incognitoSiteExceptionDesc}"
......
...@@ -16,10 +16,15 @@ Polymer({ ...@@ -16,10 +16,15 @@ Polymer({
/** @type boolean */ /** @type boolean */
noRecentPermissions: { noRecentPermissions: {
type: Boolean, type: Boolean,
computed: 'noRecentPermissions_(recentSitePermissionsList_)', computed: 'computeNoRecentPermissions_(recentSitePermissionsList_)',
notify: true, notify: true,
}, },
/**
* @private {boolean}
*/
shouldFocusAfterPopulation_: Boolean,
/** /**
* List of recent site permissions grouped by source. * List of recent site permissions grouped by source.
* @type {!Array<RecentSitePermissions>} * @type {!Array<RecentSitePermissions>}
...@@ -29,6 +34,37 @@ Polymer({ ...@@ -29,6 +34,37 @@ Polymer({
type: Array, type: Array,
value: () => [], value: () => [],
}, },
/** @type {!Map<string, (string|Function)>} */
focusConfig: {
type: Object,
observer: 'focusConfigChanged_',
},
},
/**
* When navigating to a site details sub-page, |lastSelected_| holds the
* origin and incognito bit associated with the link that sent the user there,
* as well as the index in recent permission list for that entry. This allows
* for an intelligent re-focus upon a back navigation.
* @private {!{origin: string, incognito: boolean, index: number}|null}
*/
lastSelected_: null,
/**
* @param {!Map<string, string>} newConfig
* @param {?Map<string, string>} oldConfig
* @private
*/
focusConfigChanged_(newConfig, oldConfig) {
// focusConfig is set only once on the parent, so this observer should
// only fire once.
assert(!oldConfig);
this.focusConfig.set(
settings.routes.SITE_SETTINGS_SITE_DETAILS.path, () => {
this.shouldFocusAfterPopulation_ = true;
});
}, },
/** /**
...@@ -52,6 +88,7 @@ Polymer({ ...@@ -52,6 +88,7 @@ Polymer({
/** /**
* Perform internationalization for the given content settings type. * Perform internationalization for the given content settings type.
* @param {string} contentSettingsType
* @return {string} The localised content setting type string * @return {string} The localised content setting type string
* @private * @private
*/ */
...@@ -212,7 +249,7 @@ Polymer({ ...@@ -212,7 +249,7 @@ Polymer({
* @return {boolean} * @return {boolean}
* @private * @private
*/ */
noRecentPermissions_() { computeNoRecentPermissions_() {
return this.recentSitePermissionsList_.length === 0; return this.recentSitePermissionsList_.length === 0;
}, },
...@@ -220,6 +257,7 @@ Polymer({ ...@@ -220,6 +257,7 @@ Polymer({
* Called for when incognito is enabled or disabled. Only called on change * Called for when incognito is enabled or disabled. Only called on change
* (opening N incognito windows only fires one message). Another message is * (opening N incognito windows only fires one message). Another message is
* sent when the *last* incognito window closes. * sent when the *last* incognito window closes.
* @param {boolean} hasIncognito
* @private * @private
*/ */
onIncognitoStatusChanged_(hasIncognito) { onIncognitoStatusChanged_(hasIncognito) {
...@@ -233,7 +271,7 @@ Polymer({ ...@@ -233,7 +271,7 @@ Polymer({
/** /**
* A handler for selecting a recent site permissions entry. * A handler for selecting a recent site permissions entry.
* @param {!{model: !{index: number}}} e * @param {!{model: !{item: !RecentSitePermissions, index: number}}} e
* @private * @private
*/ */
onRecentSitePermissionClick_(e) { onRecentSitePermissionClick_(e) {
...@@ -242,6 +280,11 @@ Polymer({ ...@@ -242,6 +280,11 @@ Polymer({
settings.routes.SITE_SETTINGS_SITE_DETAILS, settings.routes.SITE_SETTINGS_SITE_DETAILS,
new URLSearchParams({site: origin})); new URLSearchParams({site: origin}));
this.browserProxy.recordAction(settings.AllSitesAction.ENTER_SITE_DETAILS); this.browserProxy.recordAction(settings.AllSitesAction.ENTER_SITE_DETAILS);
this.lastSelected_ = {
index: e.model.index,
origin: e.model.item.origin,
incognito: e.model.item.incognito,
};
}, },
/** /**
...@@ -270,6 +313,39 @@ Polymer({ ...@@ -270,6 +313,39 @@ Polymer({
tooltip.show(); tooltip.show();
}, },
/**
* Called after the list has finished populating and |lastSelected_| contains
* a valid entry that should attempt to be focused. If lastSelected_ cannot
* be found the index where it used to be is focused. This may result in
* focusing another link arrow, or an incognito information icon. If the
* recent permission list is empty, focus is lost.
* @private
*/
focusLastSelected_() {
if (this.noRecentPermissions) {
return;
}
const currentIndex =
this.recentSitePermissionsList_.findIndex(function(permissions) {
return permissions.origin === this.lastSelected_.origin &&
permissions.incognito === this.lastSelected_.incognito;
});
const fallbackIndex = Math.min(
this.lastSelected_.index, this.recentSitePermissionsList_.length - 1);
const index = currentIndex > -1 ? currentIndex : fallbackIndex;
if (this.recentSitePermissionsList_[index].incognito) {
cr.ui.focusWithoutInk(
assert(/** @type {{getFocusableElement: Function}} */ (
this.$$(`#incognitoInfoIcon_${index}`))
.getFocusableElement()));
} else {
cr.ui.focusWithoutInk(assert(this.$$(`#siteEntryButton_${index}`)));
}
},
/** /**
* Retrieve the list of recently changed permissions and implicitly trigger * Retrieve the list of recently changed permissions and implicitly trigger
* the update of the display list. * the update of the display list.
...@@ -280,4 +356,16 @@ Polymer({ ...@@ -280,4 +356,16 @@ Polymer({
await this.browserProxy.getRecentSitePermissions( await this.browserProxy.getRecentSitePermissions(
this.getCategoryList(), 3); this.getCategoryList(), 3);
}, },
/**
* Called when the dom-repeat DOM has changed. This allows updating the
* focused element after the elements have been adjusted.
* @private
*/
onDomChange_() {
if (this.shouldFocusAfterPopulation_) {
this.focusLastSelected_();
this.shouldFocusAfterPopulation_ = false;
}
},
}); });
...@@ -26,7 +26,8 @@ ...@@ -26,7 +26,8 @@
<h2 class="first">$i18n{siteSettingsRecentPermissionsSectionLabel}</h2> <h2 class="first">$i18n{siteSettingsRecentPermissionsSectionLabel}</h2>
</div> </div>
<settings-recent-site-permissions id="recentSitePermissions" <settings-recent-site-permissions id="recentSitePermissions"
no-recent-permissions="{{noRecentSitePermissions_}}"> no-recent-permissions="{{noRecentSitePermissions_}}"
focus-config="[[focusConfig]]">
</settings-recent-site-permissions> </settings-recent-site-permissions>
</template> </template>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment