diff --git a/routes/_components/status/Notification.html b/routes/_components/status/Notification.html index a9f68b95..7d8893ea 100644 --- a/routes/_components/status/Notification.html +++ b/routes/_components/status/Notification.html @@ -7,8 +7,7 @@ {{else}}
+ aria-posinset="{{index}}" aria-setsize="{{length}}" >
@@ -32,16 +31,8 @@ import Status from './Status.html' import StatusHeader from './StatusHeader.html' import { store } from '../../_store/store' - import { restoreFocus } from '../../_utils/restoreFocus' export default { - oncreate() { - let focusSelector = this.get('focusSelector') - if (this.refs.node && focusSelector && - this.store.getForCurrentTimeline('shouldRestoreFocus')) { - restoreFocus(this.refs.node, focusSelector) - } - }, components: { Status, StatusHeader diff --git a/routes/_components/status/Status.html b/routes/_components/status/Status.html index 1fe95634..1e728d17 100644 --- a/routes/_components/status/Status.html +++ b/routes/_components/status/Status.html @@ -5,8 +5,7 @@ aria-posinset="{{index}}" aria-setsize="{{length}}" aria-label="{{ariaLabel}}" - on:recalculateHeight - ref:node > + on:recalculateHeight > {{#if showHeader}} @@ -103,7 +102,6 @@ import { goto } from 'sapper/runtime.js' import { registerClickDelegate, unregisterClickDelegate } from '../../_utils/delegate' import { classname } from '../../_utils/classname' - import { restoreFocus } from '../../_utils/restoreFocus' export default { oncreate() { @@ -112,11 +110,6 @@ // the whole
is clickable in this case registerClickDelegate(delegateKey, (e) => this.onClickOrKeydown(e)) } - let focusSelector = this.get('focusSelector') - if (this.refs.node && focusSelector && - this.store.getForCurrentTimeline('shouldRestoreFocus')) { - restoreFocus(this.refs.node, focusSelector) - } }, ondestroy() { let delegateKey = this.get('delegateKey') diff --git a/routes/_components/timeline/Timeline.html b/routes/_components/timeline/Timeline.html index cae6ea0a..853dc0ed 100644 --- a/routes/_components/timeline/Timeline.html +++ b/routes/_components/timeline/Timeline.html @@ -79,6 +79,7 @@ console.log('timeline oncreate()') this.setupFocus() setupTimeline() + this.restoreFocus() this.setupStreaming() }, ondestroy() { @@ -98,7 +99,7 @@ VirtualListComponent: (timelineType) => { return timelineType === 'notifications' ? NotificationVirtualListItem : StatusVirtualListItem }, - makeProps: ($currentInstance, timelineType, timelineValue, $lastFocusedElementSelector) => async (itemId) => { + makeProps: ($currentInstance, timelineType, timelineValue) => async (itemId) => { let res = { timelineType, timelineValue @@ -108,12 +109,6 @@ } else { res.status = await database.getStatus($currentInstance, itemId) } - if ($lastFocusedElementSelector && $lastFocusedElementSelector.includes(itemId)) { - // this selector is guaranteed to contain the statusId. false positives - // (e.g. notification id "1" matches notification id "11") are okay - // because Status.html won't be able to find the selector which is fine. - res.focusSelector = $lastFocusedElementSelector - } return res }, label: (timeline, $currentInstance, timelineType, timelineValue) => { @@ -177,16 +172,6 @@ }, onScrollTopChanged(scrollTop) { this.set({scrollTop: scrollTop}) - if (!this.get('observedOnScrollTopChanged')) { - // ignore the first scroll top change, e.g. - // because we forced a scroll top change - this.set({observedOnScrollTopChanged: true}) - } else { - // after that, don't allow statuses/notifications to call focus() - // after we've already started scrolling. that causes scrolling to - // jump around - this.store.setForCurrentTimeline({shouldRestoreFocus: false}) - } }, onScrollToBottom() { if (!this.store.get('initialized') || @@ -244,8 +229,7 @@ setupFocus() { this.onPushState = this.onPushState.bind(this) this.store.setForCurrentTimeline({ - ignoreBlurEvents: false, - shouldRestoreFocus: true + ignoreBlurEvents: false }) window.addEventListener('pushState', this.onPushState) }, @@ -289,7 +273,22 @@ } catch (err) { console.error('unable to clear focus', err) } - } + }, + restoreFocus() { + let lastFocusedElementSelector = this.store.get('lastFocusedElementSelector') + if (!lastFocusedElementSelector) { + return + } + console.log('restoreFocus', lastFocusedElementSelector) + requestAnimationFrame(() => { + requestAnimationFrame(() => { + let element = document.querySelector(lastFocusedElementSelector) + if (element) { + element.focus() + } + }) + }) + }, } } \ No newline at end of file diff --git a/routes/_store/computations/timelineComputations.js b/routes/_store/computations/timelineComputations.js index c299fe3c..47990143 100644 --- a/routes/_store/computations/timelineComputations.js +++ b/routes/_store/computations/timelineComputations.js @@ -18,7 +18,6 @@ export function timelineComputations (store) { computeForTimeline(store, 'showHeader', false) computeForTimeline(store, 'shouldShowHeader', false) computeForTimeline(store, 'timelineItemIdsAreStale', false) - computeForTimeline(store, 'shouldRestoreFocus', false) store.compute('firstTimelineItemId', ['timelineItemIds'], (timelineItemIds) => { return timelineItemIds && timelineItemIds[0] diff --git a/routes/_utils/restoreFocus.js b/routes/_utils/restoreFocus.js deleted file mode 100644 index 962031ea..00000000 --- a/routes/_utils/restoreFocus.js +++ /dev/null @@ -1,9 +0,0 @@ -export function restoreFocus (element, selector) { - // Have to check from the parent because otherwise this element itself wouldn't match. - // This is fine for
elements because they already have a div wrapper. - let elementToFocus = element.parentElement.querySelector(selector) - console.log('restoreFocus', selector, elementToFocus) - if (elementToFocus) { - elementToFocus.focus() - } -}