This commit is contained in:
Kristján Oddsson 2022-03-30 15:28:04 +01:00
Родитель 70a8da9cc4
Коммит 373a2928db
1 изменённых файлов: 47 добавлений и 41 удалений

Просмотреть файл

@ -1,25 +1,27 @@
const privateData = new WeakMap()
const observer = new IntersectionObserver(entries => {
for(const entry of entries) {
if (entry.isIntersecting) {
const {target} = entry
observer.unobserve(target)
if (!(target instanceof IncludeFragmentElement)) return
if (target.loading === 'lazy') {
handleData(target)
const observer = new IntersectionObserver(
entries => {
for (const entry of entries) {
if (entry.isIntersecting) {
const {target} = entry
observer.unobserve(target)
if (!(target instanceof IncludeFragmentElement)) return
if (target.loading === 'lazy') {
handleData(target)
}
}
}
},
{
// Currently the threshold is set to 256px from the bottom of the viewport
// with a threshold of 0.1. This means the element will not load until about
// 2 keyboard-down-arrow presses away from being visible in the viewport,
// giving us some time to fetch it before the contents are made visible
rootMargin: '0px 0px 256px 0px',
threshold: 0.01
}
}, {
// Currently the threshold is set to 256px from the bottom of the viewport
// with a threshold of 0.1. This means the element will not load until about
// 2 keyboard-down-arrow presses away from being visible in the viewport,
// giving us some time to fetch it before the contents are made visible
rootMargin: '0px 0px 256px 0px',
threshold: 0.01
})
)
// Functional stand in for the W3 spec "queue a task" paradigm
function task(): Promise<void> {
@ -35,7 +37,9 @@ async function handleData(el: IncludeFragmentElement) {
// eslint-disable-next-line github/no-inner-html
template.innerHTML = html
const fragment = document.importNode(template.content, true)
const canceled = !el.dispatchEvent(new CustomEvent('include-fragment-replace', {cancelable: true, detail: {fragment}}))
const canceled = !el.dispatchEvent(
new CustomEvent('include-fragment-replace', {cancelable: true, detail: {fragment}})
)
if (canceled) return
el.replaceWith(fragment)
el.dispatchEvent(new CustomEvent('include-fragment-replaced'))
@ -81,25 +85,28 @@ function fetchDataWithEvents(el: IncludeFragmentElement) {
}
return response.text()
})
.then(data => {
// Dispatch `load` and `loadend` async to allow
// the `load()` promise to resolve _before_ these
// events are fired.
task().then(() => {
el.dispatchEvent(new Event('load'))
el.dispatchEvent(new Event('loadend'))
})
return data
}, error => {
// Dispatch `error` and `loadend` async to allow
// the `load()` promise to resolve _before_ these
// events are fired.
task().then(() => {
el.dispatchEvent(new Event('error'))
el.dispatchEvent(new Event('loadend'))
})
throw error
})
.then(
data => {
// Dispatch `load` and `loadend` async to allow
// the `load()` promise to resolve _before_ these
// events are fired.
task().then(() => {
el.dispatchEvent(new Event('load'))
el.dispatchEvent(new Event('loadend'))
})
return data
},
error => {
// Dispatch `error` and `loadend` async to allow
// the `load()` promise to resolve _before_ these
// events are fired.
task().then(() => {
el.dispatchEvent(new Event('error'))
el.dispatchEvent(new Event('loadend'))
})
throw error
}
)
}
function isWildcard(accept: string | null) {
@ -107,7 +114,6 @@ function isWildcard(accept: string | null) {
}
export default class IncludeFragmentElement extends HTMLElement {
static get observedAttributes(): string[] {
return ['src', 'loading']
}
@ -127,12 +133,12 @@ export default class IncludeFragmentElement extends HTMLElement {
this.setAttribute('src', val)
}
get loading(): 'eager'|'lazy' {
get loading(): 'eager' | 'lazy' {
if (this.getAttribute('loading') === 'lazy') return 'lazy'
return 'eager'
}
set loading(value: 'eager'|'lazy') {
set loading(value: 'eager' | 'lazy') {
this.setAttribute('loading', value)
}
@ -148,7 +154,7 @@ export default class IncludeFragmentElement extends HTMLElement {
return getData(this)
}
attributeChangedCallback(attribute: string, oldVal:string|null): void {
attributeChangedCallback(attribute: string, oldVal: string | null): void {
if (attribute === 'src') {
// Source changed after attached so replace element.
if (this.isConnected && this.loading === 'eager') {