Diff: STRATO-apps/wordpress_03/app/wp-content/themes/blocksy/static/js/dynamic-chunks.js
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
import $script from 'scriptjs'
2
+
3
+
import { handleTrigger } from './frontend/dynamic-chunks/triggers'
4
+
5
+
let loadedChunks = {}
6
+
let intersectionObserver = null
7
+
8
+
export const loadDynamicChunk = (chunkId) => {
9
+
return new Promise((resolve, reject) => {
10
+
let chunk = ct_localizations.dynamic_js_chunks.find(
11
+
(chunk) => chunk.id === chunkId
12
+
)
13
+
14
+
if (!chunk) {
15
+
reject()
16
+
}
17
+
18
+
if (loadedChunks[chunk.id]) {
19
+
resolve({ chunk: loadedChunks[chunk.id], isInitial: false })
20
+
} else {
21
+
loadedChunks[chunk.id] = {
22
+
state: 'loading',
23
+
}
24
+
25
+
if (chunk.global_data) {
26
+
chunk.global_data.map((data) => {
27
+
if (!data.var || !data.data) {
28
+
return
29
+
}
30
+
31
+
window[data.var] = data.data
32
+
})
33
+
}
34
+
35
+
if (chunk.raw_html) {
36
+
if (!document.querySelector(chunk.raw_html.selector)) {
37
+
document.body.insertAdjacentHTML(
38
+
'beforeend',
39
+
chunk.raw_html.html
40
+
)
41
+
}
42
+
}
43
+
44
+
if (chunk.deps) {
45
+
const depsThatAreNotLoadedIds = chunk.deps.filter(
46
+
(id) =>
47
+
!document.querySelector(
48
+
`script[src*="${chunk.deps_data[id]}"]`
49
+
)
50
+
)
51
+
const depsThatAreNotLoaded = depsThatAreNotLoadedIds.map(
52
+
(id) => chunk.deps_data[id]
53
+
)
54
+
55
+
;[...depsThatAreNotLoadedIds, 'root']
56
+
.map((x) => () => {
57
+
return new Promise((depsResolve) => {
58
+
if (x === 'root') {
59
+
$script([chunk.url], () => {
60
+
depsResolve()
61
+
resolve({
62
+
chunk: loadedChunks[chunk.id],
63
+
isInitial: true,
64
+
})
65
+
})
66
+
return
67
+
}
68
+
69
+
$script([chunk.deps_data[x]], () => {
70
+
depsResolve()
71
+
})
72
+
})
73
+
})
74
+
.reduce(
75
+
(before, after) => before.then((_) => after()),
76
+
Promise.resolve()
77
+
)
78
+
} else {
79
+
$script(chunk.url, () => {
80
+
resolve({ chunk: loadedChunks[chunk.id], isInitial: true })
81
+
})
82
+
}
83
+
}
84
+
})
85
+
}
86
+
87
+
const loadChunkWithPayload = (chunk, payload = {}, el = null) => {
88
+
const immediateMount = () => {
89
+
if (!loadedChunks[chunk.id].mount) {
90
+
return
91
+
}
92
+
93
+
if (el) {
94
+
loadedChunks[chunk.id].mount(el, payload)
95
+
} else {
96
+
;[...document.querySelectorAll(chunk.selector)].map((el) => {
97
+
loadedChunks[chunk.id].mount(el, payload)
98
+
})
99
+
}
100
+
}
101
+
102
+
loadDynamicChunk(chunk.id)
103
+
.then(({ isInitial }) => {
104
+
if (isInitial) {
105
+
immediateMount()
106
+
}
107
+
108
+
// This is special case when re-triggered & payload present.
109
+
if (!isInitial && payload) {
110
+
immediateMount()
111
+
}
112
+
})
113
+
.catch((e) => {
114
+
console.error('Cannot load chunk', chunk.id, e)
115
+
})
116
+
}
117
+
118
+
const addChunkToIntersectionObserver = (chunk) => {
119
+
if (!window.IntersectionObserver) {
120
+
return
121
+
}
122
+
123
+
if (!intersectionObserver) {
124
+
intersectionObserver = new IntersectionObserver((entries) => {
125
+
entries.map(({ boundingClientRect, target, isIntersecting }) => {
126
+
const chunk = target.__chunk__
127
+
128
+
if (!isIntersecting && boundingClientRect.y > 0) {
129
+
return
130
+
}
131
+
132
+
let state = `target-before-bottom`
133
+
134
+
if (!isIntersecting && boundingClientRect.y < 0) {
135
+
state = 'target-after-bottom'
136
+
}
137
+
138
+
if (
139
+
state === 'target-before-bottom' &&
140
+
!loadedChunks[chunk.id]
141
+
) {
142
+
return
143
+
}
144
+
145
+
loadChunkWithPayload(chunk, { state, target }, chunk.el)
146
+
})
147
+
})
148
+
}
149
+
150
+
;[...document.querySelectorAll(chunk.selector)].map((el) => {
151
+
if (el.ioObserving) {
152
+
return
153
+
}
154
+
155
+
el.ioObserving = true
156
+
157
+
const target = document.querySelector(chunk.target)
158
+
159
+
if (!target) {
160
+
return
161
+
}
162
+
163
+
target.__chunk__ = { ...chunk, el }
164
+
165
+
intersectionObserver.observe(target)
166
+
})
167
+
}
168
+
169
+
export const mountDynamicChunks = () => {
170
+
ct_localizations.dynamic_js_chunks.map((chunk) => {
171
+
if (!chunk.id) {
172
+
return
173
+
}
174
+
175
+
// This is a potential problem for cases when we have multiple triggers
176
+
if (!document.querySelector(chunk.selector)) {
177
+
return
178
+
}
179
+
180
+
let triggers = []
181
+
182
+
if (chunk.trigger) {
183
+
triggers = Array.isArray(chunk.trigger)
184
+
? chunk.trigger
185
+
: [chunk.trigger]
186
+
}
187
+
188
+
triggers = triggers.map((trigger) => {
189
+
return trigger.trigger
190
+
? trigger
191
+
: {
192
+
trigger,
193
+
selector: chunk.selector,
194
+
}
195
+
})
196
+
197
+
const shouldDoInitialMount =
198
+
// If no triggers, do just initial mount
199
+
triggers.length === 0 ||
200
+
// Or if we have initial mount trigger. Other triggers will still work.
201
+
triggers.find((t) => t.trigger === 'initial-mount')
202
+
203
+
if (shouldDoInitialMount) {
204
+
loadChunkWithPayload(chunk, null)
205
+
}
206
+
207
+
triggers.map((trigger) => {
208
+
// It's a special trigger. Do nothing here.
209
+
if (trigger.trigger === 'initial-mount') {
210
+
return
211
+
}
212
+
213
+
if (trigger.trigger === 'intersection-observer') {
214
+
addChunkToIntersectionObserver(chunk)
215
+
return
216
+
}
217
+
218
+
handleTrigger(trigger, chunk, loadChunkWithPayload, loadedChunks)
219
+
})
220
+
})
221
+
}
222
+
223
+
export const registerDynamicChunk = (id, implementation) => {
224
+
if (loadedChunks[id] && loadedChunks[id].state !== 'loading') {
225
+
return
226
+
}
227
+
228
+
loadedChunks[id] = implementation
229
+
}
230
+