forked from cybrespace/pinafore
go back to having Timeline.html manage focus
This commit is contained in:
parent
7a9cb22269
commit
cd968245e1
|
@ -7,8 +7,7 @@
|
|||
{{else}}
|
||||
<article class="notification-article"
|
||||
tabindex="0"
|
||||
aria-posinset="{{index}}" aria-setsize="{{length}}"
|
||||
ref:node >
|
||||
aria-posinset="{{index}}" aria-setsize="{{length}}" >
|
||||
<StatusHeader :notification :notificationId :status :statusId :timelineType
|
||||
:account :accountId :uuid isStatusInNotification="true" />
|
||||
</article>
|
||||
|
@ -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
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
aria-posinset="{{index}}"
|
||||
aria-setsize="{{length}}"
|
||||
aria-label="{{ariaLabel}}"
|
||||
on:recalculateHeight
|
||||
ref:node >
|
||||
on:recalculateHeight >
|
||||
{{#if showHeader}}
|
||||
<StatusHeader :notification :notificationId :status :statusId :timelineType
|
||||
:account :accountId :uuid :isStatusInNotification />
|
||||
|
@ -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 <article> 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')
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -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]
|
||||
|
|
|
@ -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 <article class=status> elements because they already have a div wrapper.
|
||||
let elementToFocus = element.parentElement.querySelector(selector)
|
||||
console.log('restoreFocus', selector, elementToFocus)
|
||||
if (elementToFocus) {
|
||||
elementToFocus.focus()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue