Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6108723

Browse files
committed
Move observer and handleData into the component
1 parent c6106ee commit 6108723

File tree

1 file changed

+49
-48
lines changed

1 file changed

+49
-48
lines changed

src/index.ts

Lines changed: 49 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,5 @@
11
const privateData = new WeakMap()
22

3-
const observer = new IntersectionObserver(
4-
entries => {
5-
for (const entry of entries) {
6-
if (entry.isIntersecting) {
7-
const {target} = entry
8-
observer.unobserve(target)
9-
if (!(target instanceof IncludeFragmentElement)) return
10-
if (target.loading === 'lazy') {
11-
handleData(target)
12-
}
13-
}
14-
}
15-
},
16-
{
17-
// Currently the threshold is set to 256px from the bottom of the viewport
18-
// with a threshold of 0.1. This means the element will not load until about
19-
// 2 keyboard-down-arrow presses away from being visible in the viewport,
20-
// giving us some time to fetch it before the contents are made visible
21-
rootMargin: '0px 0px 256px 0px',
22-
threshold: 0.01
23-
}
24-
)
25-
263
// Functional stand in for the W3 spec "queue a task" paradigm
274
function task(): Promise<void> {
285
return new Promise(resolve => setTimeout(resolve, 0))
@@ -32,27 +9,6 @@ function isWildcard(accept: string | null) {
329
return accept && !!accept.split(',').find(x => x.match(/^\s*\*\/\*/))
3310
}
3411

35-
async function handleData(el: IncludeFragmentElement) {
36-
observer.unobserve(el)
37-
return getData(el).then(
38-
function (html: string) {
39-
const template = document.createElement('template')
40-
// eslint-disable-next-line github/no-inner-html
41-
template.innerHTML = html
42-
const fragment = document.importNode(template.content, true)
43-
const canceled = !el.dispatchEvent(
44-
new CustomEvent('include-fragment-replace', {cancelable: true, detail: {fragment}})
45-
)
46-
if (canceled) return
47-
el.replaceWith(fragment)
48-
el.dispatchEvent(new CustomEvent('include-fragment-replaced'))
49-
},
50-
function () {
51-
el.classList.add('is-error')
52-
}
53-
)
54-
}
55-
5612
function getData(el: IncludeFragmentElement) {
5713
const src = el.src
5814
let data = privateData.get(el)
@@ -157,12 +113,12 @@ export default class IncludeFragmentElement extends HTMLElement {
157113
if (attribute === 'src') {
158114
// Source changed after attached so replace element.
159115
if (this.isConnected && this.loading === 'eager') {
160-
handleData(this)
116+
this.#handleData()
161117
}
162118
} else if (attribute === 'loading') {
163119
// Loading mode changed to Eager after attached so replace element.
164120
if (this.isConnected && oldVal !== 'eager' && this.loading === 'eager') {
165-
handleData(this)
121+
this.#handleData()
166122
}
167123
}
168124
}
@@ -181,10 +137,10 @@ export default class IncludeFragmentElement extends HTMLElement {
181137

182138
connectedCallback(): void {
183139
if (this.src && this.loading === 'eager') {
184-
handleData(this)
140+
this.#handleData()
185141
}
186142
if (this.loading === 'lazy') {
187-
observer.observe(this)
143+
this.#observer.observe(this)
188144
}
189145
}
190146

@@ -210,6 +166,51 @@ export default class IncludeFragmentElement extends HTMLElement {
210166
fetch(request: RequestInfo): Promise<Response> {
211167
return fetch(request)
212168
}
169+
170+
#observer = new IntersectionObserver(
171+
entries => {
172+
for (const entry of entries) {
173+
if (entry.isIntersecting) {
174+
const {target} = entry
175+
this.#observer.unobserve(target)
176+
if (!(target instanceof IncludeFragmentElement)) return
177+
if (target.loading === 'lazy') {
178+
this.#handleData()
179+
}
180+
}
181+
}
182+
},
183+
{
184+
// Currently the threshold is set to 256px from the bottom of the viewport
185+
// with a threshold of 0.1. This means the element will not load until about
186+
// 2 keyboard-down-arrow presses away from being visible in the viewport,
187+
// giving us some time to fetch it before the contents are made visible
188+
rootMargin: '0px 0px 256px 0px',
189+
threshold: 0.01
190+
}
191+
)
192+
193+
#handleData(): Promise<void> {
194+
this.#observer.unobserve(this)
195+
196+
return getData(this).then(
197+
(html: string) => {
198+
const template = document.createElement('template')
199+
// eslint-disable-next-line github/no-inner-html
200+
template.innerHTML = html
201+
const fragment = document.importNode(template.content, true)
202+
const canceled = !this.dispatchEvent(
203+
new CustomEvent('include-fragment-replace', {cancelable: true, detail: {fragment}})
204+
)
205+
if (canceled) return
206+
this.replaceWith(fragment)
207+
this.dispatchEvent(new CustomEvent('include-fragment-replaced'))
208+
},
209+
() => {
210+
this.classList.add('is-error')
211+
}
212+
)
213+
}
213214
}
214215

215216
declare global {

0 commit comments

Comments
 (0)