@netless/app-presentation 0.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -0
- package/build.ts +98 -0
- package/dist/index.d.ts +336 -0
- package/dist/index.global.js +1377 -0
- package/dist/index.js +1373 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1364 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +46 -0
- package/src/app-presentation.ts +392 -0
- package/src/client.d.ts +6 -0
- package/src/icons/arrow-left.ts +15 -0
- package/src/icons/arrow-right.ts +15 -0
- package/src/icons/index.ts +3 -0
- package/src/icons/sidebar.ts +15 -0
- package/src/index.ts +5 -0
- package/src/preload.ts +59 -0
- package/src/presentation.ts +317 -0
- package/src/style.scss +259 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1373 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
// node_modules/.pnpm/@wopjs+disposable@0.1.4/node_modules/@wopjs/disposable/dist/index.mjs
|
|
6
|
+
var isAbortable = (disposable) => disposable && disposable.abortable;
|
|
7
|
+
var invokeDispose = (disposable) => {
|
|
8
|
+
try {
|
|
9
|
+
if (disposable.dispose) {
|
|
10
|
+
disposable.dispose();
|
|
11
|
+
} else {
|
|
12
|
+
disposable();
|
|
13
|
+
}
|
|
14
|
+
} catch (e) {
|
|
15
|
+
console.error(e);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
var methods = {
|
|
19
|
+
size() {
|
|
20
|
+
return this._d.size;
|
|
21
|
+
},
|
|
22
|
+
has(disposable) {
|
|
23
|
+
return this._d.has(disposable);
|
|
24
|
+
},
|
|
25
|
+
add(disposable) {
|
|
26
|
+
const disposables = Array.isArray(disposable) ? disposable : [disposable];
|
|
27
|
+
for (const disposable2 of disposables) {
|
|
28
|
+
if (!this._d.has(disposable2)) {
|
|
29
|
+
this._d.add(disposable2);
|
|
30
|
+
if (isAbortable(disposable2)) {
|
|
31
|
+
disposable2.abortable(() => this.remove(disposable2));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return disposable;
|
|
36
|
+
},
|
|
37
|
+
make(executor) {
|
|
38
|
+
const disposable = executor();
|
|
39
|
+
if (disposable) {
|
|
40
|
+
return this.add(disposable);
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
remove(disposable) {
|
|
44
|
+
return this._d.delete(disposable);
|
|
45
|
+
},
|
|
46
|
+
flush(disposable) {
|
|
47
|
+
if (disposable) {
|
|
48
|
+
if (this.remove(disposable)) {
|
|
49
|
+
invokeDispose(disposable);
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
this.dispose();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
var disposableStore = (disposables) => {
|
|
57
|
+
const disposableStore2 = () => {
|
|
58
|
+
disposableStore2._d.forEach(invokeDispose);
|
|
59
|
+
disposableStore2._d.clear();
|
|
60
|
+
};
|
|
61
|
+
disposableStore2._d = /* @__PURE__ */ new Set();
|
|
62
|
+
disposableStore2.dispose = disposableStore2;
|
|
63
|
+
const store = Object.assign(disposableStore2, methods);
|
|
64
|
+
if (disposables) {
|
|
65
|
+
store.add(disposables);
|
|
66
|
+
}
|
|
67
|
+
return store;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// node_modules/.pnpm/@wopjs+dom@0.1.3/node_modules/@wopjs/dom/dist/index.js
|
|
71
|
+
function addEventListener(target, type, listener, options) {
|
|
72
|
+
target.addEventListener(type, listener, options);
|
|
73
|
+
return () => target.removeEventListener(type, listener, options);
|
|
74
|
+
}
|
|
75
|
+
var listen = addEventListener;
|
|
76
|
+
|
|
77
|
+
// node_modules/.pnpm/vanilla-lazyload@17.8.5/node_modules/vanilla-lazyload/dist/lazyload.esm.js
|
|
78
|
+
var runningOnBrowser = typeof window !== "undefined";
|
|
79
|
+
var isBot = runningOnBrowser && !("onscroll" in window) || typeof navigator !== "undefined" && /(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent);
|
|
80
|
+
var supportsIntersectionObserver = runningOnBrowser && "IntersectionObserver" in window;
|
|
81
|
+
var supportsClassList = runningOnBrowser && "classList" in document.createElement("p");
|
|
82
|
+
var isHiDpi = runningOnBrowser && window.devicePixelRatio > 1;
|
|
83
|
+
var defaultSettings = {
|
|
84
|
+
elements_selector: ".lazy",
|
|
85
|
+
container: isBot || runningOnBrowser ? document : null,
|
|
86
|
+
threshold: 300,
|
|
87
|
+
thresholds: null,
|
|
88
|
+
data_src: "src",
|
|
89
|
+
data_srcset: "srcset",
|
|
90
|
+
data_sizes: "sizes",
|
|
91
|
+
data_bg: "bg",
|
|
92
|
+
data_bg_hidpi: "bg-hidpi",
|
|
93
|
+
data_bg_multi: "bg-multi",
|
|
94
|
+
data_bg_multi_hidpi: "bg-multi-hidpi",
|
|
95
|
+
data_bg_set: "bg-set",
|
|
96
|
+
data_poster: "poster",
|
|
97
|
+
class_applied: "applied",
|
|
98
|
+
class_loading: "loading",
|
|
99
|
+
class_loaded: "loaded",
|
|
100
|
+
class_error: "error",
|
|
101
|
+
class_entered: "entered",
|
|
102
|
+
class_exited: "exited",
|
|
103
|
+
unobserve_completed: true,
|
|
104
|
+
unobserve_entered: false,
|
|
105
|
+
cancel_on_exit: true,
|
|
106
|
+
callback_enter: null,
|
|
107
|
+
callback_exit: null,
|
|
108
|
+
callback_applied: null,
|
|
109
|
+
callback_loading: null,
|
|
110
|
+
callback_loaded: null,
|
|
111
|
+
callback_error: null,
|
|
112
|
+
callback_finish: null,
|
|
113
|
+
callback_cancel: null,
|
|
114
|
+
use_native: false,
|
|
115
|
+
restore_on_error: false
|
|
116
|
+
};
|
|
117
|
+
var getExtendedSettings = (customSettings) => {
|
|
118
|
+
return Object.assign({}, defaultSettings, customSettings);
|
|
119
|
+
};
|
|
120
|
+
var createInstance = function(classObj, options) {
|
|
121
|
+
let event;
|
|
122
|
+
const eventString = "LazyLoad::Initialized";
|
|
123
|
+
const instance = new classObj(options);
|
|
124
|
+
try {
|
|
125
|
+
event = new CustomEvent(eventString, { detail: { instance } });
|
|
126
|
+
} catch (err) {
|
|
127
|
+
event = document.createEvent("CustomEvent");
|
|
128
|
+
event.initCustomEvent(eventString, false, false, { instance });
|
|
129
|
+
}
|
|
130
|
+
window.dispatchEvent(event);
|
|
131
|
+
};
|
|
132
|
+
var autoInitialize = (classObj, options) => {
|
|
133
|
+
if (!options) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (!options.length) {
|
|
137
|
+
createInstance(classObj, options);
|
|
138
|
+
} else {
|
|
139
|
+
for (let i = 0, optionsItem; optionsItem = options[i]; i += 1) {
|
|
140
|
+
createInstance(classObj, optionsItem);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
var SRC = "src";
|
|
145
|
+
var SRCSET = "srcset";
|
|
146
|
+
var SIZES = "sizes";
|
|
147
|
+
var POSTER = "poster";
|
|
148
|
+
var ORIGINALS = "llOriginalAttrs";
|
|
149
|
+
var DATA = "data";
|
|
150
|
+
var statusLoading = "loading";
|
|
151
|
+
var statusLoaded = "loaded";
|
|
152
|
+
var statusApplied = "applied";
|
|
153
|
+
var statusEntered = "entered";
|
|
154
|
+
var statusError = "error";
|
|
155
|
+
var statusNative = "native";
|
|
156
|
+
var dataPrefix = "data-";
|
|
157
|
+
var statusDataName = "ll-status";
|
|
158
|
+
var getData = (element, attribute) => {
|
|
159
|
+
return element.getAttribute(dataPrefix + attribute);
|
|
160
|
+
};
|
|
161
|
+
var setData = (element, attribute, value) => {
|
|
162
|
+
const attrName = dataPrefix + attribute;
|
|
163
|
+
if (value === null) {
|
|
164
|
+
element.removeAttribute(attrName);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
element.setAttribute(attrName, value);
|
|
168
|
+
};
|
|
169
|
+
var getStatus = (element) => getData(element, statusDataName);
|
|
170
|
+
var setStatus = (element, status) => setData(element, statusDataName, status);
|
|
171
|
+
var resetStatus = (element) => setStatus(element, null);
|
|
172
|
+
var hasEmptyStatus = (element) => getStatus(element) === null;
|
|
173
|
+
var hasStatusLoading = (element) => getStatus(element) === statusLoading;
|
|
174
|
+
var hasStatusError = (element) => getStatus(element) === statusError;
|
|
175
|
+
var hasStatusNative = (element) => getStatus(element) === statusNative;
|
|
176
|
+
var statusesAfterLoading = [statusLoading, statusLoaded, statusApplied, statusError];
|
|
177
|
+
var hadStartedLoading = (element) => statusesAfterLoading.indexOf(getStatus(element)) >= 0;
|
|
178
|
+
var safeCallback = (callback, arg1, arg2, arg3) => {
|
|
179
|
+
if (!callback || typeof callback !== "function") {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (arg3 !== void 0) {
|
|
183
|
+
callback(arg1, arg2, arg3);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
if (arg2 !== void 0) {
|
|
187
|
+
callback(arg1, arg2);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
callback(arg1);
|
|
191
|
+
};
|
|
192
|
+
var addClass = (element, className) => {
|
|
193
|
+
if (supportsClassList) {
|
|
194
|
+
element.classList.add(className);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
element.className += (element.className ? " " : "") + className;
|
|
198
|
+
};
|
|
199
|
+
var removeClass = (element, className) => {
|
|
200
|
+
if (supportsClassList) {
|
|
201
|
+
element.classList.remove(className);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
element.className = element.className.replace(new RegExp("(^|\\s+)" + className + "(\\s+|$)"), " ").replace(/^\s+/, "").replace(/\s+$/, "");
|
|
205
|
+
};
|
|
206
|
+
var addTempImage = (element) => {
|
|
207
|
+
element.llTempImage = document.createElement("IMG");
|
|
208
|
+
};
|
|
209
|
+
var deleteTempImage = (element) => {
|
|
210
|
+
delete element.llTempImage;
|
|
211
|
+
};
|
|
212
|
+
var getTempImage = (element) => element.llTempImage;
|
|
213
|
+
var unobserve = (element, instance) => {
|
|
214
|
+
if (!instance)
|
|
215
|
+
return;
|
|
216
|
+
const observer = instance._observer;
|
|
217
|
+
if (!observer)
|
|
218
|
+
return;
|
|
219
|
+
observer.unobserve(element);
|
|
220
|
+
};
|
|
221
|
+
var resetObserver = (observer) => {
|
|
222
|
+
observer.disconnect();
|
|
223
|
+
};
|
|
224
|
+
var unobserveEntered = (element, settings, instance) => {
|
|
225
|
+
if (settings.unobserve_entered)
|
|
226
|
+
unobserve(element, instance);
|
|
227
|
+
};
|
|
228
|
+
var updateLoadingCount = (instance, delta) => {
|
|
229
|
+
if (!instance)
|
|
230
|
+
return;
|
|
231
|
+
instance.loadingCount += delta;
|
|
232
|
+
};
|
|
233
|
+
var decreaseToLoadCount = (instance) => {
|
|
234
|
+
if (!instance)
|
|
235
|
+
return;
|
|
236
|
+
instance.toLoadCount -= 1;
|
|
237
|
+
};
|
|
238
|
+
var setToLoadCount = (instance, value) => {
|
|
239
|
+
if (!instance)
|
|
240
|
+
return;
|
|
241
|
+
instance.toLoadCount = value;
|
|
242
|
+
};
|
|
243
|
+
var isSomethingLoading = (instance) => instance.loadingCount > 0;
|
|
244
|
+
var haveElementsToLoad = (instance) => instance.toLoadCount > 0;
|
|
245
|
+
var getSourceTags = (parentTag) => {
|
|
246
|
+
let sourceTags = [];
|
|
247
|
+
for (let i = 0, childTag; childTag = parentTag.children[i]; i += 1) {
|
|
248
|
+
if (childTag.tagName === "SOURCE") {
|
|
249
|
+
sourceTags.push(childTag);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return sourceTags;
|
|
253
|
+
};
|
|
254
|
+
var forEachPictureSource = (element, fn) => {
|
|
255
|
+
const parent = element.parentNode;
|
|
256
|
+
if (!parent || parent.tagName !== "PICTURE") {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
let sourceTags = getSourceTags(parent);
|
|
260
|
+
sourceTags.forEach(fn);
|
|
261
|
+
};
|
|
262
|
+
var forEachVideoSource = (element, fn) => {
|
|
263
|
+
let sourceTags = getSourceTags(element);
|
|
264
|
+
sourceTags.forEach(fn);
|
|
265
|
+
};
|
|
266
|
+
var attrsSrc = [SRC];
|
|
267
|
+
var attrsSrcPoster = [SRC, POSTER];
|
|
268
|
+
var attrsSrcSrcsetSizes = [SRC, SRCSET, SIZES];
|
|
269
|
+
var attrsData = [DATA];
|
|
270
|
+
var hasOriginalAttrs = (element) => !!element[ORIGINALS];
|
|
271
|
+
var getOriginalAttrs = (element) => element[ORIGINALS];
|
|
272
|
+
var deleteOriginalAttrs = (element) => delete element[ORIGINALS];
|
|
273
|
+
var setOriginalsObject = (element, attributes) => {
|
|
274
|
+
if (hasOriginalAttrs(element)) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
const originals = {};
|
|
278
|
+
attributes.forEach((attribute) => {
|
|
279
|
+
originals[attribute] = element.getAttribute(attribute);
|
|
280
|
+
});
|
|
281
|
+
element[ORIGINALS] = originals;
|
|
282
|
+
};
|
|
283
|
+
var saveOriginalBackgroundStyle = (element) => {
|
|
284
|
+
if (hasOriginalAttrs(element)) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
element[ORIGINALS] = { backgroundImage: element.style.backgroundImage };
|
|
288
|
+
};
|
|
289
|
+
var setOrResetAttribute = (element, attrName, value) => {
|
|
290
|
+
if (!value) {
|
|
291
|
+
element.removeAttribute(attrName);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
element.setAttribute(attrName, value);
|
|
295
|
+
};
|
|
296
|
+
var restoreOriginalAttrs = (element, attributes) => {
|
|
297
|
+
if (!hasOriginalAttrs(element)) {
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
const originals = getOriginalAttrs(element);
|
|
301
|
+
attributes.forEach((attribute) => {
|
|
302
|
+
setOrResetAttribute(element, attribute, originals[attribute]);
|
|
303
|
+
});
|
|
304
|
+
};
|
|
305
|
+
var restoreOriginalBgImage = (element) => {
|
|
306
|
+
if (!hasOriginalAttrs(element)) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const originals = getOriginalAttrs(element);
|
|
310
|
+
element.style.backgroundImage = originals.backgroundImage;
|
|
311
|
+
};
|
|
312
|
+
var manageApplied = (element, settings, instance) => {
|
|
313
|
+
addClass(element, settings.class_applied);
|
|
314
|
+
setStatus(element, statusApplied);
|
|
315
|
+
if (!instance)
|
|
316
|
+
return;
|
|
317
|
+
if (settings.unobserve_completed) {
|
|
318
|
+
unobserve(element, settings);
|
|
319
|
+
}
|
|
320
|
+
safeCallback(settings.callback_applied, element, instance);
|
|
321
|
+
};
|
|
322
|
+
var manageLoading = (element, settings, instance) => {
|
|
323
|
+
addClass(element, settings.class_loading);
|
|
324
|
+
setStatus(element, statusLoading);
|
|
325
|
+
if (!instance)
|
|
326
|
+
return;
|
|
327
|
+
updateLoadingCount(instance, 1);
|
|
328
|
+
safeCallback(settings.callback_loading, element, instance);
|
|
329
|
+
};
|
|
330
|
+
var setAttributeIfValue = (element, attrName, value) => {
|
|
331
|
+
if (!value) {
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
element.setAttribute(attrName, value);
|
|
335
|
+
};
|
|
336
|
+
var setImageAttributes = (element, settings) => {
|
|
337
|
+
setAttributeIfValue(element, SIZES, getData(element, settings.data_sizes));
|
|
338
|
+
setAttributeIfValue(element, SRCSET, getData(element, settings.data_srcset));
|
|
339
|
+
setAttributeIfValue(element, SRC, getData(element, settings.data_src));
|
|
340
|
+
};
|
|
341
|
+
var setSourcesImg = (imgEl, settings) => {
|
|
342
|
+
forEachPictureSource(imgEl, (sourceTag) => {
|
|
343
|
+
setOriginalsObject(sourceTag, attrsSrcSrcsetSizes);
|
|
344
|
+
setImageAttributes(sourceTag, settings);
|
|
345
|
+
});
|
|
346
|
+
setOriginalsObject(imgEl, attrsSrcSrcsetSizes);
|
|
347
|
+
setImageAttributes(imgEl, settings);
|
|
348
|
+
};
|
|
349
|
+
var setSourcesIframe = (iframe, settings) => {
|
|
350
|
+
setOriginalsObject(iframe, attrsSrc);
|
|
351
|
+
setAttributeIfValue(iframe, SRC, getData(iframe, settings.data_src));
|
|
352
|
+
};
|
|
353
|
+
var setSourcesVideo = (videoEl, settings) => {
|
|
354
|
+
forEachVideoSource(videoEl, (sourceEl) => {
|
|
355
|
+
setOriginalsObject(sourceEl, attrsSrc);
|
|
356
|
+
setAttributeIfValue(sourceEl, SRC, getData(sourceEl, settings.data_src));
|
|
357
|
+
});
|
|
358
|
+
setOriginalsObject(videoEl, attrsSrcPoster);
|
|
359
|
+
setAttributeIfValue(videoEl, POSTER, getData(videoEl, settings.data_poster));
|
|
360
|
+
setAttributeIfValue(videoEl, SRC, getData(videoEl, settings.data_src));
|
|
361
|
+
videoEl.load();
|
|
362
|
+
};
|
|
363
|
+
var setSourcesObject = (object, settings) => {
|
|
364
|
+
setOriginalsObject(object, attrsData);
|
|
365
|
+
setAttributeIfValue(object, DATA, getData(object, settings.data_src));
|
|
366
|
+
};
|
|
367
|
+
var setBackground = (element, settings, instance) => {
|
|
368
|
+
const bg1xValue = getData(element, settings.data_bg);
|
|
369
|
+
const bgHiDpiValue = getData(element, settings.data_bg_hidpi);
|
|
370
|
+
const bgDataValue = isHiDpi && bgHiDpiValue ? bgHiDpiValue : bg1xValue;
|
|
371
|
+
if (!bgDataValue)
|
|
372
|
+
return;
|
|
373
|
+
element.style.backgroundImage = `url("${bgDataValue}")`;
|
|
374
|
+
getTempImage(element).setAttribute(SRC, bgDataValue);
|
|
375
|
+
manageLoading(element, settings, instance);
|
|
376
|
+
};
|
|
377
|
+
var setMultiBackground = (element, settings, instance) => {
|
|
378
|
+
const bg1xValue = getData(element, settings.data_bg_multi);
|
|
379
|
+
const bgHiDpiValue = getData(element, settings.data_bg_multi_hidpi);
|
|
380
|
+
const bgDataValue = isHiDpi && bgHiDpiValue ? bgHiDpiValue : bg1xValue;
|
|
381
|
+
if (!bgDataValue) {
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
element.style.backgroundImage = bgDataValue;
|
|
385
|
+
manageApplied(element, settings, instance);
|
|
386
|
+
};
|
|
387
|
+
var setImgsetBackground = (element, settings, instance) => {
|
|
388
|
+
const bgImgSetDataValue = getData(element, settings.data_bg_set);
|
|
389
|
+
if (!bgImgSetDataValue) {
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
const imgSetValues = bgImgSetDataValue.split("|");
|
|
393
|
+
let bgImageValues = imgSetValues.map((value) => `image-set(${value})`);
|
|
394
|
+
element.style.backgroundImage = bgImageValues.join();
|
|
395
|
+
if (element.style.backgroundImage === "") {
|
|
396
|
+
bgImageValues = imgSetValues.map((value) => `-webkit-image-set(${value})`);
|
|
397
|
+
element.style.backgroundImage = bgImageValues.join();
|
|
398
|
+
}
|
|
399
|
+
manageApplied(element, settings, instance);
|
|
400
|
+
};
|
|
401
|
+
var setSourcesFunctions = {
|
|
402
|
+
IMG: setSourcesImg,
|
|
403
|
+
IFRAME: setSourcesIframe,
|
|
404
|
+
VIDEO: setSourcesVideo,
|
|
405
|
+
OBJECT: setSourcesObject
|
|
406
|
+
};
|
|
407
|
+
var setSourcesNative = (element, settings) => {
|
|
408
|
+
const setSourcesFunction = setSourcesFunctions[element.tagName];
|
|
409
|
+
if (!setSourcesFunction) {
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
setSourcesFunction(element, settings);
|
|
413
|
+
};
|
|
414
|
+
var setSources = (element, settings, instance) => {
|
|
415
|
+
const setSourcesFunction = setSourcesFunctions[element.tagName];
|
|
416
|
+
if (!setSourcesFunction) {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
setSourcesFunction(element, settings);
|
|
420
|
+
manageLoading(element, settings, instance);
|
|
421
|
+
};
|
|
422
|
+
var elementsWithLoadEvent = ["IMG", "IFRAME", "VIDEO", "OBJECT"];
|
|
423
|
+
var hasLoadEvent = (element) => elementsWithLoadEvent.indexOf(element.tagName) > -1;
|
|
424
|
+
var checkFinish = (settings, instance) => {
|
|
425
|
+
if (instance && !isSomethingLoading(instance) && !haveElementsToLoad(instance)) {
|
|
426
|
+
safeCallback(settings.callback_finish, instance);
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
var addEventListener2 = (element, eventName, handler) => {
|
|
430
|
+
element.addEventListener(eventName, handler);
|
|
431
|
+
element.llEvLisnrs[eventName] = handler;
|
|
432
|
+
};
|
|
433
|
+
var removeEventListener = (element, eventName, handler) => {
|
|
434
|
+
element.removeEventListener(eventName, handler);
|
|
435
|
+
};
|
|
436
|
+
var hasEventListeners = (element) => {
|
|
437
|
+
return !!element.llEvLisnrs;
|
|
438
|
+
};
|
|
439
|
+
var addEventListeners = (element, loadHandler2, errorHandler2) => {
|
|
440
|
+
if (!hasEventListeners(element))
|
|
441
|
+
element.llEvLisnrs = {};
|
|
442
|
+
const loadEventName = element.tagName === "VIDEO" ? "loadeddata" : "load";
|
|
443
|
+
addEventListener2(element, loadEventName, loadHandler2);
|
|
444
|
+
addEventListener2(element, "error", errorHandler2);
|
|
445
|
+
};
|
|
446
|
+
var removeEventListeners = (element) => {
|
|
447
|
+
if (!hasEventListeners(element)) {
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
const eventListeners = element.llEvLisnrs;
|
|
451
|
+
for (let eventName in eventListeners) {
|
|
452
|
+
const handler = eventListeners[eventName];
|
|
453
|
+
removeEventListener(element, eventName, handler);
|
|
454
|
+
}
|
|
455
|
+
delete element.llEvLisnrs;
|
|
456
|
+
};
|
|
457
|
+
var doneHandler = (element, settings, instance) => {
|
|
458
|
+
deleteTempImage(element);
|
|
459
|
+
updateLoadingCount(instance, -1);
|
|
460
|
+
decreaseToLoadCount(instance);
|
|
461
|
+
removeClass(element, settings.class_loading);
|
|
462
|
+
if (settings.unobserve_completed) {
|
|
463
|
+
unobserve(element, instance);
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
var loadHandler = (event, element, settings, instance) => {
|
|
467
|
+
const goingNative = hasStatusNative(element);
|
|
468
|
+
doneHandler(element, settings, instance);
|
|
469
|
+
addClass(element, settings.class_loaded);
|
|
470
|
+
setStatus(element, statusLoaded);
|
|
471
|
+
safeCallback(settings.callback_loaded, element, instance);
|
|
472
|
+
if (!goingNative)
|
|
473
|
+
checkFinish(settings, instance);
|
|
474
|
+
};
|
|
475
|
+
var errorHandler = (event, element, settings, instance) => {
|
|
476
|
+
const goingNative = hasStatusNative(element);
|
|
477
|
+
doneHandler(element, settings, instance);
|
|
478
|
+
addClass(element, settings.class_error);
|
|
479
|
+
setStatus(element, statusError);
|
|
480
|
+
safeCallback(settings.callback_error, element, instance);
|
|
481
|
+
if (settings.restore_on_error)
|
|
482
|
+
restoreOriginalAttrs(element, attrsSrcSrcsetSizes);
|
|
483
|
+
if (!goingNative)
|
|
484
|
+
checkFinish(settings, instance);
|
|
485
|
+
};
|
|
486
|
+
var addOneShotEventListeners = (element, settings, instance) => {
|
|
487
|
+
const elementToListenTo = getTempImage(element) || element;
|
|
488
|
+
if (hasEventListeners(elementToListenTo)) {
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
const _loadHandler = (event) => {
|
|
492
|
+
loadHandler(event, element, settings, instance);
|
|
493
|
+
removeEventListeners(elementToListenTo);
|
|
494
|
+
};
|
|
495
|
+
const _errorHandler = (event) => {
|
|
496
|
+
errorHandler(event, element, settings, instance);
|
|
497
|
+
removeEventListeners(elementToListenTo);
|
|
498
|
+
};
|
|
499
|
+
addEventListeners(elementToListenTo, _loadHandler, _errorHandler);
|
|
500
|
+
};
|
|
501
|
+
var loadBackground = (element, settings, instance) => {
|
|
502
|
+
addTempImage(element);
|
|
503
|
+
addOneShotEventListeners(element, settings, instance);
|
|
504
|
+
saveOriginalBackgroundStyle(element);
|
|
505
|
+
setBackground(element, settings, instance);
|
|
506
|
+
setMultiBackground(element, settings, instance);
|
|
507
|
+
setImgsetBackground(element, settings, instance);
|
|
508
|
+
};
|
|
509
|
+
var loadRegular = (element, settings, instance) => {
|
|
510
|
+
addOneShotEventListeners(element, settings, instance);
|
|
511
|
+
setSources(element, settings, instance);
|
|
512
|
+
};
|
|
513
|
+
var load = (element, settings, instance) => {
|
|
514
|
+
if (hasLoadEvent(element)) {
|
|
515
|
+
loadRegular(element, settings, instance);
|
|
516
|
+
} else {
|
|
517
|
+
loadBackground(element, settings, instance);
|
|
518
|
+
}
|
|
519
|
+
};
|
|
520
|
+
var loadNative = (element, settings, instance) => {
|
|
521
|
+
element.setAttribute("loading", "lazy");
|
|
522
|
+
addOneShotEventListeners(element, settings, instance);
|
|
523
|
+
setSourcesNative(element, settings);
|
|
524
|
+
setStatus(element, statusNative);
|
|
525
|
+
};
|
|
526
|
+
var removeImageAttributes = (element) => {
|
|
527
|
+
element.removeAttribute(SRC);
|
|
528
|
+
element.removeAttribute(SRCSET);
|
|
529
|
+
element.removeAttribute(SIZES);
|
|
530
|
+
};
|
|
531
|
+
var resetSourcesImg = (element) => {
|
|
532
|
+
forEachPictureSource(element, (sourceTag) => {
|
|
533
|
+
removeImageAttributes(sourceTag);
|
|
534
|
+
});
|
|
535
|
+
removeImageAttributes(element);
|
|
536
|
+
};
|
|
537
|
+
var restoreImg = (imgEl) => {
|
|
538
|
+
forEachPictureSource(imgEl, (sourceEl) => {
|
|
539
|
+
restoreOriginalAttrs(sourceEl, attrsSrcSrcsetSizes);
|
|
540
|
+
});
|
|
541
|
+
restoreOriginalAttrs(imgEl, attrsSrcSrcsetSizes);
|
|
542
|
+
};
|
|
543
|
+
var restoreVideo = (videoEl) => {
|
|
544
|
+
forEachVideoSource(videoEl, (sourceEl) => {
|
|
545
|
+
restoreOriginalAttrs(sourceEl, attrsSrc);
|
|
546
|
+
});
|
|
547
|
+
restoreOriginalAttrs(videoEl, attrsSrcPoster);
|
|
548
|
+
videoEl.load();
|
|
549
|
+
};
|
|
550
|
+
var restoreIframe = (iframeEl) => {
|
|
551
|
+
restoreOriginalAttrs(iframeEl, attrsSrc);
|
|
552
|
+
};
|
|
553
|
+
var restoreObject = (objectEl) => {
|
|
554
|
+
restoreOriginalAttrs(objectEl, attrsData);
|
|
555
|
+
};
|
|
556
|
+
var restoreFunctions = {
|
|
557
|
+
IMG: restoreImg,
|
|
558
|
+
IFRAME: restoreIframe,
|
|
559
|
+
VIDEO: restoreVideo,
|
|
560
|
+
OBJECT: restoreObject
|
|
561
|
+
};
|
|
562
|
+
var restoreAttributes = (element) => {
|
|
563
|
+
const restoreFunction = restoreFunctions[element.tagName];
|
|
564
|
+
if (!restoreFunction) {
|
|
565
|
+
restoreOriginalBgImage(element);
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
restoreFunction(element);
|
|
569
|
+
};
|
|
570
|
+
var resetClasses = (element, settings) => {
|
|
571
|
+
if (hasEmptyStatus(element) || hasStatusNative(element)) {
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
removeClass(element, settings.class_entered);
|
|
575
|
+
removeClass(element, settings.class_exited);
|
|
576
|
+
removeClass(element, settings.class_applied);
|
|
577
|
+
removeClass(element, settings.class_loading);
|
|
578
|
+
removeClass(element, settings.class_loaded);
|
|
579
|
+
removeClass(element, settings.class_error);
|
|
580
|
+
};
|
|
581
|
+
var restore = (element, settings) => {
|
|
582
|
+
restoreAttributes(element);
|
|
583
|
+
resetClasses(element, settings);
|
|
584
|
+
resetStatus(element);
|
|
585
|
+
deleteOriginalAttrs(element);
|
|
586
|
+
};
|
|
587
|
+
var cancelLoading = (element, entry, settings, instance) => {
|
|
588
|
+
if (!settings.cancel_on_exit)
|
|
589
|
+
return;
|
|
590
|
+
if (!hasStatusLoading(element))
|
|
591
|
+
return;
|
|
592
|
+
if (element.tagName !== "IMG")
|
|
593
|
+
return;
|
|
594
|
+
removeEventListeners(element);
|
|
595
|
+
resetSourcesImg(element);
|
|
596
|
+
restoreImg(element);
|
|
597
|
+
removeClass(element, settings.class_loading);
|
|
598
|
+
updateLoadingCount(instance, -1);
|
|
599
|
+
resetStatus(element);
|
|
600
|
+
safeCallback(settings.callback_cancel, element, entry, instance);
|
|
601
|
+
};
|
|
602
|
+
var onEnter = (element, entry, settings, instance) => {
|
|
603
|
+
const dontLoad = hadStartedLoading(element);
|
|
604
|
+
setStatus(element, statusEntered);
|
|
605
|
+
addClass(element, settings.class_entered);
|
|
606
|
+
removeClass(element, settings.class_exited);
|
|
607
|
+
unobserveEntered(element, settings, instance);
|
|
608
|
+
safeCallback(settings.callback_enter, element, entry, instance);
|
|
609
|
+
if (dontLoad)
|
|
610
|
+
return;
|
|
611
|
+
load(element, settings, instance);
|
|
612
|
+
};
|
|
613
|
+
var onExit = (element, entry, settings, instance) => {
|
|
614
|
+
if (hasEmptyStatus(element))
|
|
615
|
+
return;
|
|
616
|
+
addClass(element, settings.class_exited);
|
|
617
|
+
cancelLoading(element, entry, settings, instance);
|
|
618
|
+
safeCallback(settings.callback_exit, element, entry, instance);
|
|
619
|
+
};
|
|
620
|
+
var tagsWithNativeLazy = ["IMG", "IFRAME", "VIDEO"];
|
|
621
|
+
var shouldUseNative = (settings) => settings.use_native && "loading" in HTMLImageElement.prototype;
|
|
622
|
+
var loadAllNative = (elements, settings, instance) => {
|
|
623
|
+
elements.forEach((element) => {
|
|
624
|
+
if (tagsWithNativeLazy.indexOf(element.tagName) === -1) {
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
loadNative(element, settings, instance);
|
|
628
|
+
});
|
|
629
|
+
setToLoadCount(instance, 0);
|
|
630
|
+
};
|
|
631
|
+
var isIntersecting = (entry) => entry.isIntersecting || entry.intersectionRatio > 0;
|
|
632
|
+
var getObserverSettings = (settings) => ({
|
|
633
|
+
root: settings.container === document ? null : settings.container,
|
|
634
|
+
rootMargin: settings.thresholds || settings.threshold + "px"
|
|
635
|
+
});
|
|
636
|
+
var intersectionHandler = (entries, settings, instance) => {
|
|
637
|
+
entries.forEach(
|
|
638
|
+
(entry) => isIntersecting(entry) ? onEnter(entry.target, entry, settings, instance) : onExit(entry.target, entry, settings, instance)
|
|
639
|
+
);
|
|
640
|
+
};
|
|
641
|
+
var observeElements = (observer, elements) => {
|
|
642
|
+
elements.forEach((element) => {
|
|
643
|
+
observer.observe(element);
|
|
644
|
+
});
|
|
645
|
+
};
|
|
646
|
+
var updateObserver = (observer, elementsToObserve) => {
|
|
647
|
+
resetObserver(observer);
|
|
648
|
+
observeElements(observer, elementsToObserve);
|
|
649
|
+
};
|
|
650
|
+
var setObserver = (settings, instance) => {
|
|
651
|
+
if (!supportsIntersectionObserver || shouldUseNative(settings)) {
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
instance._observer = new IntersectionObserver((entries) => {
|
|
655
|
+
intersectionHandler(entries, settings, instance);
|
|
656
|
+
}, getObserverSettings(settings));
|
|
657
|
+
};
|
|
658
|
+
var toArray = (nodeSet) => Array.prototype.slice.call(nodeSet);
|
|
659
|
+
var queryElements = (settings) => settings.container.querySelectorAll(settings.elements_selector);
|
|
660
|
+
var excludeManagedElements = (elements) => toArray(elements).filter(hasEmptyStatus);
|
|
661
|
+
var hasError = (element) => hasStatusError(element);
|
|
662
|
+
var filterErrorElements = (elements) => toArray(elements).filter(hasError);
|
|
663
|
+
var getElementsToLoad = (elements, settings) => excludeManagedElements(elements || queryElements(settings));
|
|
664
|
+
var retryLazyLoad = (settings, instance) => {
|
|
665
|
+
const errorElements = filterErrorElements(queryElements(settings));
|
|
666
|
+
errorElements.forEach((element) => {
|
|
667
|
+
removeClass(element, settings.class_error);
|
|
668
|
+
resetStatus(element);
|
|
669
|
+
});
|
|
670
|
+
instance.update();
|
|
671
|
+
};
|
|
672
|
+
var setOnlineCheck = (settings, instance) => {
|
|
673
|
+
if (!runningOnBrowser) {
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
instance._onlineHandler = () => {
|
|
677
|
+
retryLazyLoad(settings, instance);
|
|
678
|
+
};
|
|
679
|
+
window.addEventListener("online", instance._onlineHandler);
|
|
680
|
+
};
|
|
681
|
+
var resetOnlineCheck = (instance) => {
|
|
682
|
+
if (!runningOnBrowser) {
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
685
|
+
window.removeEventListener("online", instance._onlineHandler);
|
|
686
|
+
};
|
|
687
|
+
var LazyLoad = function(customSettings, elements) {
|
|
688
|
+
const settings = getExtendedSettings(customSettings);
|
|
689
|
+
this._settings = settings;
|
|
690
|
+
this.loadingCount = 0;
|
|
691
|
+
setObserver(settings, this);
|
|
692
|
+
setOnlineCheck(settings, this);
|
|
693
|
+
this.update(elements);
|
|
694
|
+
};
|
|
695
|
+
LazyLoad.prototype = {
|
|
696
|
+
update: function(givenNodeset) {
|
|
697
|
+
const settings = this._settings;
|
|
698
|
+
const elementsToLoad = getElementsToLoad(givenNodeset, settings);
|
|
699
|
+
setToLoadCount(this, elementsToLoad.length);
|
|
700
|
+
if (isBot || !supportsIntersectionObserver) {
|
|
701
|
+
this.loadAll(elementsToLoad);
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
704
|
+
if (shouldUseNative(settings)) {
|
|
705
|
+
loadAllNative(elementsToLoad, settings, this);
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
updateObserver(this._observer, elementsToLoad);
|
|
709
|
+
},
|
|
710
|
+
destroy: function() {
|
|
711
|
+
if (this._observer) {
|
|
712
|
+
this._observer.disconnect();
|
|
713
|
+
}
|
|
714
|
+
resetOnlineCheck(this);
|
|
715
|
+
queryElements(this._settings).forEach((element) => {
|
|
716
|
+
deleteOriginalAttrs(element);
|
|
717
|
+
});
|
|
718
|
+
delete this._observer;
|
|
719
|
+
delete this._settings;
|
|
720
|
+
delete this._onlineHandler;
|
|
721
|
+
delete this.loadingCount;
|
|
722
|
+
delete this.toLoadCount;
|
|
723
|
+
},
|
|
724
|
+
loadAll: function(elements) {
|
|
725
|
+
const settings = this._settings;
|
|
726
|
+
const elementsToLoad = getElementsToLoad(elements, settings);
|
|
727
|
+
elementsToLoad.forEach((element) => {
|
|
728
|
+
unobserve(element, this);
|
|
729
|
+
load(element, settings, this);
|
|
730
|
+
});
|
|
731
|
+
},
|
|
732
|
+
restoreAll: function() {
|
|
733
|
+
const settings = this._settings;
|
|
734
|
+
queryElements(settings).forEach((element) => {
|
|
735
|
+
restore(element, settings);
|
|
736
|
+
});
|
|
737
|
+
}
|
|
738
|
+
};
|
|
739
|
+
LazyLoad.load = (element, customSettings) => {
|
|
740
|
+
const settings = getExtendedSettings(customSettings);
|
|
741
|
+
load(element, settings);
|
|
742
|
+
};
|
|
743
|
+
LazyLoad.resetStatus = (element) => {
|
|
744
|
+
resetStatus(element);
|
|
745
|
+
};
|
|
746
|
+
if (runningOnBrowser) {
|
|
747
|
+
autoInitialize(LazyLoad, window.lazyLoadOptions);
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
// src/icons/sidebar.ts
|
|
751
|
+
function sidebarSVG(namespace) {
|
|
752
|
+
const NS = "http://www.w3.org/2000/svg";
|
|
753
|
+
const $svg = document.createElementNS(NS, "svg");
|
|
754
|
+
$svg.setAttribute("class", `${namespace}-footer-icon-sidebar`);
|
|
755
|
+
$svg.setAttribute("viewBox", "0 0 64 64");
|
|
756
|
+
const $path = document.createElementNS(NS, "path");
|
|
757
|
+
$path.setAttribute("fill", "currentColor");
|
|
758
|
+
$path.setAttribute("d", "M50 8H14c-3.309 0-6 2.691-6 6v36c0 3.309 2.691 6 6 6h36c3.309 0 6-2.691 6-6V14c0-3.309-2.691-6-6-6zM12 50V14c0-1.103.897-2 2-2h8v40h-8c-1.103 0-2-.897-2-2zm40 0c0 1.103-.897 2-2 2H26V12h24c1.103 0 2 .897 2 2z");
|
|
759
|
+
$svg.appendChild($path);
|
|
760
|
+
return $svg;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
// src/icons/arrow-left.ts
|
|
764
|
+
function arrowLeftSVG(namespace) {
|
|
765
|
+
const NS = "http://www.w3.org/2000/svg";
|
|
766
|
+
const $svg = document.createElementNS(NS, "svg");
|
|
767
|
+
$svg.setAttribute("class", `${namespace}-footer-icon-arrow-left`);
|
|
768
|
+
$svg.setAttribute("viewBox", "0 0 500 500");
|
|
769
|
+
const $path = document.createElementNS(NS, "path");
|
|
770
|
+
$path.setAttribute("fill", "currentColor");
|
|
771
|
+
$path.setAttribute("d", "M177.81 249.959L337.473 90.295c2.722-2.865 2.651-7.378-.143-10.1-2.793-2.65-7.163-2.65-9.956 0l-164.75 164.75c-2.793 2.793-2.793 7.306 0 10.1l164.75 164.75c2.865 2.722 7.378 2.65 10.099-.143 2.651-2.794 2.651-7.163 0-9.957L177.809 249.959z");
|
|
772
|
+
$svg.appendChild($path);
|
|
773
|
+
return $svg;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
// src/icons/arrow-right.ts
|
|
777
|
+
function arrowRightSVG(namespace) {
|
|
778
|
+
const NS = "http://www.w3.org/2000/svg";
|
|
779
|
+
const $svg = document.createElementNS(NS, "svg");
|
|
780
|
+
$svg.setAttribute("class", `${namespace}-footer-icon-arrow-right`);
|
|
781
|
+
$svg.setAttribute("viewBox", "0 0 500 500");
|
|
782
|
+
const $path = document.createElementNS(NS, "path");
|
|
783
|
+
$path.setAttribute("fill", "currentColor");
|
|
784
|
+
$path.setAttribute("d", "M322.19 250.041L162.527 409.705c-2.722 2.865-2.651 7.378.143 10.1 2.793 2.65 7.163 2.65 9.956 0l164.75-164.75c2.793-2.793 2.793-7.306 0-10.1l-164.75-164.75c-2.865-2.722-7.378-2.65-10.099.143-2.651 2.794-2.651 7.163 0 9.957l159.664 159.736z");
|
|
785
|
+
$svg.appendChild($path);
|
|
786
|
+
return $svg;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
// src/preload.ts
|
|
790
|
+
var Preload = class {
|
|
791
|
+
constructor(pages) {
|
|
792
|
+
this.pages = pages;
|
|
793
|
+
this.head = 0;
|
|
794
|
+
this.tail = 0;
|
|
795
|
+
this.timer = 0;
|
|
796
|
+
this.links = new Array(pages.length);
|
|
797
|
+
this.touch(0);
|
|
798
|
+
}
|
|
799
|
+
get done() {
|
|
800
|
+
return this.head == 0 && this.tail == this.pages.length;
|
|
801
|
+
}
|
|
802
|
+
touch(index) {
|
|
803
|
+
if (this.done)
|
|
804
|
+
return;
|
|
805
|
+
this.head = this.tail = index;
|
|
806
|
+
this.timer || (this.timer = setTimeout(this.handler.bind(this)));
|
|
807
|
+
}
|
|
808
|
+
handler() {
|
|
809
|
+
const { links } = this;
|
|
810
|
+
while (this.head > 0 && links[this.head])
|
|
811
|
+
this.head--;
|
|
812
|
+
if (!links[this.head]) {
|
|
813
|
+
const link = document.createElement("link");
|
|
814
|
+
links[this.head] = link;
|
|
815
|
+
link.rel = "preload";
|
|
816
|
+
link.as = "image";
|
|
817
|
+
link.href = this.pages[this.head].src;
|
|
818
|
+
document.head.appendChild(link);
|
|
819
|
+
}
|
|
820
|
+
while (links[this.tail])
|
|
821
|
+
this.tail++;
|
|
822
|
+
if (this.tail < this.pages.length && !links[this.tail]) {
|
|
823
|
+
const link = document.createElement("link");
|
|
824
|
+
links[this.tail] = link;
|
|
825
|
+
link.rel = "preload";
|
|
826
|
+
link.as = "image";
|
|
827
|
+
link.href = this.pages[this.tail].src;
|
|
828
|
+
document.head.appendChild(link);
|
|
829
|
+
}
|
|
830
|
+
this.timer = setTimeout(this.handler.bind(this), 2e3);
|
|
831
|
+
}
|
|
832
|
+
dispose() {
|
|
833
|
+
clearTimeout(this.timer);
|
|
834
|
+
for (const link of this.links) {
|
|
835
|
+
link && document.head.contains(link) && document.head.removeChild(link);
|
|
836
|
+
}
|
|
837
|
+
this.links.length = 0;
|
|
838
|
+
}
|
|
839
|
+
};
|
|
840
|
+
|
|
841
|
+
// src/presentation.ts
|
|
842
|
+
var Presentation = class {
|
|
843
|
+
constructor(config) {
|
|
844
|
+
this.namespace = "netless-app-presentation";
|
|
845
|
+
this.dispose = disposableStore();
|
|
846
|
+
this.initialized = false;
|
|
847
|
+
this.showPreview = false;
|
|
848
|
+
this.pageIndex = 0;
|
|
849
|
+
this.previewLazyload = null;
|
|
850
|
+
var _a;
|
|
851
|
+
this.pages = config.pages;
|
|
852
|
+
this.preload = new Preload(this.pages);
|
|
853
|
+
this.dispose.add(this.preload);
|
|
854
|
+
this.readonly = (_a = config.readonly) != null ? _a : false;
|
|
855
|
+
this.dom = document.createElement("div");
|
|
856
|
+
this.dom.className = this.namespace;
|
|
857
|
+
this.contentDOM = document.createElement("div");
|
|
858
|
+
this.contentDOM.className = this.c("content");
|
|
859
|
+
this.previewDOM = document.createElement("div");
|
|
860
|
+
this.previewDOM.className = this.c("preview");
|
|
861
|
+
this.imageDOM = document.createElement("div");
|
|
862
|
+
this.imageDOM.className = this.c("image");
|
|
863
|
+
this.image = document.createElement("img");
|
|
864
|
+
this.whiteboardDOM = document.createElement("div");
|
|
865
|
+
this.whiteboardDOM.className = this.c("wb-view");
|
|
866
|
+
this.footerDOM = document.createElement("div");
|
|
867
|
+
this.footerDOM.className = this.c("footer");
|
|
868
|
+
this.pageNumberInputDOM = document.createElement("input");
|
|
869
|
+
this.pageNumberInputDOM.className = this.c("page-number-input");
|
|
870
|
+
this.initialize();
|
|
871
|
+
}
|
|
872
|
+
initialize() {
|
|
873
|
+
var _a;
|
|
874
|
+
if (this.initialized)
|
|
875
|
+
return;
|
|
876
|
+
this.initialized = true;
|
|
877
|
+
this.dispose.add(() => {
|
|
878
|
+
var _a2;
|
|
879
|
+
return (_a2 = this.previewLazyload) == null ? void 0 : _a2.destroy();
|
|
880
|
+
});
|
|
881
|
+
this.contentDOM.classList.toggle(this.c("readonly"), this.readonly);
|
|
882
|
+
this.dom.appendChild(this.contentDOM);
|
|
883
|
+
const previewMask = this.contentDOM.appendChild(document.createElement("div"));
|
|
884
|
+
previewMask.className = this.c("preview-mask");
|
|
885
|
+
this.dispose.add(listen(previewMask, "click", (ev) => {
|
|
886
|
+
if (this.readonly)
|
|
887
|
+
return;
|
|
888
|
+
if (ev.target == previewMask) {
|
|
889
|
+
this.togglePreview(false);
|
|
890
|
+
}
|
|
891
|
+
}));
|
|
892
|
+
this.contentDOM.appendChild(this.previewDOM);
|
|
893
|
+
this.previewDOM.classList.add("tele-fancy-scrollbar");
|
|
894
|
+
const c_previewPage = this.c("preview-page");
|
|
895
|
+
const c_previewPageName = this.c("preview-page-name");
|
|
896
|
+
for (let index = 0; index < this.pages.length; ++index) {
|
|
897
|
+
const page = this.pages[index];
|
|
898
|
+
const previewSRC = page.thumbnail || this.x_oss_process(page.src);
|
|
899
|
+
const previewPage = document.createElement("a");
|
|
900
|
+
previewPage.className = `${c_previewPage} ${this.c(`preview-page-${index}`)}`;
|
|
901
|
+
previewPage.setAttribute("href", "#");
|
|
902
|
+
previewPage.dataset.pageIndex = String(index);
|
|
903
|
+
const img = document.createElement("img");
|
|
904
|
+
img.width = page.width;
|
|
905
|
+
img.height = page.height;
|
|
906
|
+
img.dataset.src = previewSRC;
|
|
907
|
+
img.dataset.pageIndex = String(index);
|
|
908
|
+
const name = document.createElement("span");
|
|
909
|
+
name.className = c_previewPageName;
|
|
910
|
+
name.textContent = String(index + 1);
|
|
911
|
+
name.dataset.pageIndex = String(index);
|
|
912
|
+
previewPage.appendChild(img);
|
|
913
|
+
previewPage.appendChild(name);
|
|
914
|
+
this.previewDOM.appendChild(previewPage);
|
|
915
|
+
}
|
|
916
|
+
(_a = this.previewLazyload) == null ? void 0 : _a.update();
|
|
917
|
+
this.dispose.add(listen(this.previewDOM, "click", (ev) => {
|
|
918
|
+
var _a2;
|
|
919
|
+
if (this.readonly)
|
|
920
|
+
return;
|
|
921
|
+
const pageIndex = (_a2 = ev.target.dataset) == null ? void 0 : _a2.pageIndex;
|
|
922
|
+
if (pageIndex) {
|
|
923
|
+
ev.preventDefault();
|
|
924
|
+
ev.stopPropagation();
|
|
925
|
+
ev.stopImmediatePropagation();
|
|
926
|
+
this.onNewPageIndex(Number(pageIndex), "preview");
|
|
927
|
+
this.togglePreview(false);
|
|
928
|
+
}
|
|
929
|
+
}));
|
|
930
|
+
this.imageDOM.appendChild(this.image);
|
|
931
|
+
this.contentDOM.appendChild(this.imageDOM);
|
|
932
|
+
this.updateImage();
|
|
933
|
+
this.contentDOM.appendChild(this.whiteboardDOM);
|
|
934
|
+
this.footerDOM.classList.toggle(this.c("readonly"), this.readonly);
|
|
935
|
+
this.dom.appendChild(this.footerDOM);
|
|
936
|
+
const btnSidebar = document.createElement("button");
|
|
937
|
+
btnSidebar.className = `${this.c("footer-btn")} ${this.c("btn-sidebar")}`;
|
|
938
|
+
btnSidebar.appendChild(sidebarSVG(this.namespace));
|
|
939
|
+
this.footerDOM.appendChild(btnSidebar);
|
|
940
|
+
this.dispose.add(listen(btnSidebar, "click", () => {
|
|
941
|
+
if (this.readonly)
|
|
942
|
+
return;
|
|
943
|
+
this.togglePreview();
|
|
944
|
+
}));
|
|
945
|
+
const pageJumps = document.createElement("div");
|
|
946
|
+
pageJumps.className = this.c("page-jumps");
|
|
947
|
+
this.footerDOM.appendChild(pageJumps);
|
|
948
|
+
const btnPageBack = document.createElement("button");
|
|
949
|
+
btnPageBack.className = `${this.c("footer-btn")} ${this.c("btn-page-back")}`;
|
|
950
|
+
btnPageBack.appendChild(arrowLeftSVG(this.namespace));
|
|
951
|
+
pageJumps.appendChild(btnPageBack);
|
|
952
|
+
this.dispose.add(listen(btnPageBack, "click", () => {
|
|
953
|
+
if (this.readonly)
|
|
954
|
+
return;
|
|
955
|
+
if (this.pageIndex > 0)
|
|
956
|
+
this.onNewPageIndex(this.pageIndex - 1, "navigation");
|
|
957
|
+
}));
|
|
958
|
+
const btnPageNext = document.createElement("button");
|
|
959
|
+
btnPageNext.className = `${this.c("footer-btn")} ${this.c("btn-page-next")}`;
|
|
960
|
+
btnPageNext.appendChild(arrowRightSVG(this.namespace));
|
|
961
|
+
pageJumps.appendChild(btnPageNext);
|
|
962
|
+
this.dispose.add(listen(btnPageNext, "click", () => {
|
|
963
|
+
if (this.readonly)
|
|
964
|
+
return;
|
|
965
|
+
if (this.pageIndex < this.pages.length - 1)
|
|
966
|
+
this.onNewPageIndex(this.pageIndex + 1, "navigation");
|
|
967
|
+
}));
|
|
968
|
+
const pageNumber = document.createElement("div");
|
|
969
|
+
pageNumber.className = this.c("page-number");
|
|
970
|
+
this.footerDOM.appendChild(pageNumber);
|
|
971
|
+
pageNumber.appendChild(this.pageNumberInputDOM);
|
|
972
|
+
this.pageNumberInputDOM.value = String(this.pageIndex + 1);
|
|
973
|
+
this.pageNumberInputDOM.disabled = this.readonly;
|
|
974
|
+
this.dispose.add(listen(this.pageNumberInputDOM, "focus", () => {
|
|
975
|
+
if (this.readonly)
|
|
976
|
+
return;
|
|
977
|
+
this.pageNumberInputDOM.select();
|
|
978
|
+
}));
|
|
979
|
+
this.dispose.add(listen(this.pageNumberInputDOM, "change", () => {
|
|
980
|
+
if (this.readonly)
|
|
981
|
+
return;
|
|
982
|
+
if (this.pageNumberInputDOM.value) {
|
|
983
|
+
this.onNewPageIndex(Number(this.pageNumberInputDOM.value) - 1, "input");
|
|
984
|
+
}
|
|
985
|
+
}));
|
|
986
|
+
const totalPage = document.createElement("span");
|
|
987
|
+
totalPage.textContent = ` / ${this.pages.length}`;
|
|
988
|
+
pageNumber.appendChild(totalPage);
|
|
989
|
+
this.dispose.add(listen(window, "keydown", (ev) => {
|
|
990
|
+
if (this.readonly || this.isEditable(ev.target))
|
|
991
|
+
return;
|
|
992
|
+
if ((ev.key == "ArrowUp" || ev.key == "ArrowLeft") && this.pageIndex > 0)
|
|
993
|
+
this.onNewPageIndex(this.pageIndex - 1, "keydown");
|
|
994
|
+
else if ((ev.key == "ArrowDown" || ev.key == "ArrowRight") && this.pageIndex < this.pages.length - 1)
|
|
995
|
+
this.onNewPageIndex(this.pageIndex + 1, "keydown");
|
|
996
|
+
}));
|
|
997
|
+
}
|
|
998
|
+
setDOM(dom) {
|
|
999
|
+
if (this.dom == dom)
|
|
1000
|
+
return;
|
|
1001
|
+
dom.appendChild(this.contentDOM);
|
|
1002
|
+
dom.appendChild(this.footerDOM);
|
|
1003
|
+
this.dom = dom;
|
|
1004
|
+
}
|
|
1005
|
+
setReadonly(readonly) {
|
|
1006
|
+
if (this.readonly == readonly)
|
|
1007
|
+
return;
|
|
1008
|
+
this.contentDOM.classList.toggle(this.c("readonly"), readonly);
|
|
1009
|
+
this.footerDOM.classList.toggle(this.c("readonly"), readonly);
|
|
1010
|
+
this.pageNumberInputDOM.disabled = readonly;
|
|
1011
|
+
this.togglePreview(false);
|
|
1012
|
+
this.readonly = readonly;
|
|
1013
|
+
}
|
|
1014
|
+
setPageIndex(pageIndex) {
|
|
1015
|
+
if (Number.isSafeInteger(pageIndex)) {
|
|
1016
|
+
this.pageIndex = pageIndex;
|
|
1017
|
+
this.pageNumberInputDOM.value = String(pageIndex + 1);
|
|
1018
|
+
this.updateImage();
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
togglePreview(showPreview) {
|
|
1022
|
+
this.showPreview = showPreview != null ? showPreview : !this.showPreview;
|
|
1023
|
+
this.contentDOM.classList.toggle(this.c("preview-active"), this.showPreview);
|
|
1024
|
+
if (this.showPreview) {
|
|
1025
|
+
const previewPageDOM = this.previewDOM.querySelector("." + this.c(`preview-page-${this.pageIndex}`));
|
|
1026
|
+
if (previewPageDOM) {
|
|
1027
|
+
this.previewLazyload || (this.previewLazyload = new LazyLoad({
|
|
1028
|
+
container: this.previewDOM,
|
|
1029
|
+
elements_selector: `.${this.c("preview-page>img")}`
|
|
1030
|
+
}));
|
|
1031
|
+
this.previewDOM.scrollTo({ top: previewPageDOM.offsetTop - 16 });
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
// [origin] means the cause:
|
|
1036
|
+
// - navigation: user clicked on the left / right button on footer
|
|
1037
|
+
// - input: user filled the bottom-right page number input box
|
|
1038
|
+
// - preview: user clicked on the left preview menu's item
|
|
1039
|
+
// - keydown: this navigation is caused by user press left or right
|
|
1040
|
+
// Fastboard dispatchDocsEvent() triggers the "navigation" and "input" cause
|
|
1041
|
+
onNewPageIndex(index, _origin) {
|
|
1042
|
+
if (0 <= index && index < this.pages.length) {
|
|
1043
|
+
this.setPageIndex(index);
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
page() {
|
|
1047
|
+
return this.pages[this.pageIndex];
|
|
1048
|
+
}
|
|
1049
|
+
updateImage() {
|
|
1050
|
+
const page = this.page();
|
|
1051
|
+
if (!page) {
|
|
1052
|
+
this.image.src = "";
|
|
1053
|
+
return;
|
|
1054
|
+
}
|
|
1055
|
+
this.image.width = page.width;
|
|
1056
|
+
this.image.height = page.height;
|
|
1057
|
+
this.image.src = page.src;
|
|
1058
|
+
this.preload.touch(this.pageIndex);
|
|
1059
|
+
}
|
|
1060
|
+
c(className) {
|
|
1061
|
+
return `${this.namespace}-${className}`;
|
|
1062
|
+
}
|
|
1063
|
+
isEditable(el) {
|
|
1064
|
+
if (!el)
|
|
1065
|
+
return false;
|
|
1066
|
+
const { tagName } = el;
|
|
1067
|
+
return tagName == "INPUT" || tagName == "TEXTAREA" || tagName == "SELECT";
|
|
1068
|
+
}
|
|
1069
|
+
x_oss_process(src) {
|
|
1070
|
+
try {
|
|
1071
|
+
const url = new URL(src);
|
|
1072
|
+
url.searchParams.set("x-oss-process", "image/resize,l_50");
|
|
1073
|
+
return url.toString();
|
|
1074
|
+
} catch (err) {
|
|
1075
|
+
console.error(err);
|
|
1076
|
+
return src;
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
};
|
|
1080
|
+
|
|
1081
|
+
// src/style.scss?inline
|
|
1082
|
+
var style_default = ".netless-app-presentation{height:100%;display:flex;flex-flow:column nowrap}.netless-app-presentation-content{position:relative;height:100%;overflow:hidden}.netless-app-presentation-preview-mask{display:none;position:absolute;z-index:200;top:0;left:0;width:100%;height:100%}.netless-app-presentation-preview{display:flex;flex-direction:column;align-items:center;position:absolute;z-index:300;top:0;left:0;width:33%;max-width:200px;height:100%;padding-top:10px;transform:translate(-100%);background:#ededf0e6;box-shadow:inset -1px 0 #0000001c;transition:transform .4s;overflow:auto;overflow-y:scroll}.netless-app-presentation-preview-active .netless-app-presentation-preview-mask{display:block}.netless-app-presentation-preview-active .netless-app-presentation-preview{transform:translate(0)}.netless-app-presentation-preview-page{position:relative;display:block;width:55%;margin-bottom:10px;font-size:0;color:#0000;outline:none;border:7px solid rgba(0,0,0,0);border-radius:4px;transition:border-color .3s;user-select:none}.netless-app-presentation-preview-page:hover,.netless-app-presentation-preview-page.netless-app-presentation-preview-page-active{border-color:#444e601a}.netless-app-presentation-preview-page>img{width:100%;height:auto;box-sizing:border-box;border:1px solid rgba(0,0,0,.5);border-radius:1px;background-color:#fff;box-shadow:0 2px 8px #0000004d}.netless-app-presentation-preview-page-name{position:absolute;top:1px;left:-10px;transform:translate(-100%);text-align:right;font-size:12px;color:#5f5f5f;user-select:none}.netless-app-presentation-footer{box-sizing:border-box;height:26px;display:flex;align-items:center;padding:0 16px;border-top:1px solid #eeeef7;color:#191919}.netless-app-presentation-float-footer{width:100%;min-height:26px;position:absolute;left:0;bottom:0;z-index:2000;background:#f9f9fce6;transition:opacity .4s}.netless-app-presentation-footer-btn{box-sizing:border-box;width:26px;height:26px;font-size:0;margin:0;padding:3px;border:none;border-radius:1px;outline:none;color:currentColor;background:#0000;transition:background .4s;cursor:pointer;user-select:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}.netless-app-presentation-footer-btn:hover{background:#ededf0e6}@media (hover: none){.netless-app-presentation-footer-btn:hover{background:#0000!important}}.netless-app-presentation-footer-btn>svg{width:100%;height:100%}.netless-app-presentation-footer-btn>svg:nth-of-type(2){display:none}.netless-app-presentation-footer-btn.netless-app-presentation-footer-btn-playing>svg:nth-of-type(1){display:none}.netless-app-presentation-footer-btn.netless-app-presentation-footer-btn-playing>svg:nth-of-type(2){display:initial}.netless-app-presentation-footer-btn~.netless-app-presentation-footer-btn{margin-left:15px}.netless-app-presentation-page-jumps{flex:1;display:flex;justify-content:center;align-items:center}.netless-app-presentation-page-number{margin-left:auto;font-size:13px;user-select:none;white-space:nowrap;word-break:keep-all}.netless-app-presentation-page-number-input{border:none;outline:none;width:3em;margin:0;padding:0 2px;text-align:right;font-size:13px;line-height:1;font-weight:400;font-family:inherit;border-radius:2px;color:currentColor;background:#0000;transition:background .4s;user-select:text;-webkit-tap-highlight-color:rgba(0,0,0,0)}.netless-app-presentation-page-number-input:hover,.netless-app-presentation-page-number-input:focus,.netless-app-presentation-page-number-input:active{background:#fff;box-shadow:#63636333 0 2px 8px}.netless-app-presentation-readonly.netless-app-presentation-footer{display:none}.netless-app-presentation-wb-view{position:absolute;top:0;left:0;width:100%;height:100%;z-index:100;overflow:hidden;transition:opacity .2s}.netless-app-presentation-image{width:100%;height:100%;display:flex;align-items:center;justify-content:center}.netless-app-presentation-image>img{max-width:100%;max-height:100%;object-fit:contain}.telebox-color-scheme-dark .netless-app-presentation-page-number-input{color:#a6a6a8}.telebox-color-scheme-dark .netless-app-presentation-page-number-input:active,.telebox-color-scheme-dark .netless-app-presentation-page-number-input:focus,.telebox-color-scheme-dark .netless-app-presentation-page-number-input:hover{color:#222}.telebox-color-scheme-dark .netless-app-presentation-footer{color:#a6a6a8;background:#2d2d33;border-top:none}.telebox-color-scheme-dark .netless-app-presentation-footer-btn:hover{background:#212126}.telebox-color-scheme-dark .netless-app-presentation-preview{background:#323232e6}";
|
|
1083
|
+
|
|
1084
|
+
// src/app-presentation.ts
|
|
1085
|
+
var ppt2page = (ppt) => ppt ? { width: ppt.width, height: ppt.height, src: ppt.src, thumbnail: ppt.previewURL } : null;
|
|
1086
|
+
var createLogger = (room) => {
|
|
1087
|
+
if (room && room.logger) {
|
|
1088
|
+
return (...args) => room.logger.info(...args);
|
|
1089
|
+
} else {
|
|
1090
|
+
return (...args) => console.log(...args);
|
|
1091
|
+
}
|
|
1092
|
+
};
|
|
1093
|
+
var NetlessAppPresentation = {
|
|
1094
|
+
kind: "Presentation",
|
|
1095
|
+
setup(context) {
|
|
1096
|
+
var _a;
|
|
1097
|
+
const view = context.getView();
|
|
1098
|
+
if (!view)
|
|
1099
|
+
throw new Error("[Presentation]: no whiteboard view, make sure you have added options.scenePath in addApp()");
|
|
1100
|
+
const pages = (_a = context.getScenes()) == null ? void 0 : _a.map(({ ppt }) => ppt2page(ppt)).filter(Boolean);
|
|
1101
|
+
if (!pages || pages.length === 0)
|
|
1102
|
+
throw new Error("[Presentation]: empty scenes, make sure you have added options.scenes in addApp()");
|
|
1103
|
+
if (pages[0].src.startsWith("ppt"))
|
|
1104
|
+
throw new Error("[Presentation]: legacy dynamic PPT is unsupported, please use the projector converter and @netless/slide to render it");
|
|
1105
|
+
const scenePath = context.getInitScenePath();
|
|
1106
|
+
const options = context.getAppOptions() || {};
|
|
1107
|
+
const log = options.log || createLogger(context.getRoom());
|
|
1108
|
+
log(`[Presentation] new ${context.appId}`);
|
|
1109
|
+
if (context.isAddApp) {
|
|
1110
|
+
if (pages.length > 100)
|
|
1111
|
+
console.warn(`[Presentation]: too many pages (${pages.length}), may cause performance issues`);
|
|
1112
|
+
const room = context.getRoom();
|
|
1113
|
+
if (room && room.isWritable) {
|
|
1114
|
+
const scenes = room.entireScenes()[scenePath];
|
|
1115
|
+
if (scenes.length < pages.length) {
|
|
1116
|
+
room.putScenes(scenePath, pages.map((_, index) => ({ name: String(index + 1) })));
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
const dispose = disposableStore();
|
|
1121
|
+
dispose.add(() => log(`[Presentation] dispose ${context.appId}`));
|
|
1122
|
+
const page$$ = context.createStorage("page", { index: 0 });
|
|
1123
|
+
let lastIndex = -1;
|
|
1124
|
+
const syncPage = async (index) => {
|
|
1125
|
+
if (lastIndex !== index) {
|
|
1126
|
+
lastIndex = index;
|
|
1127
|
+
context.dispatchAppEvent("pageStateChange", { index, length: pages.length });
|
|
1128
|
+
}
|
|
1129
|
+
if (!context.getIsWritable())
|
|
1130
|
+
return;
|
|
1131
|
+
const scenes = context.getDisplayer().entireScenes()[scenePath];
|
|
1132
|
+
if (!scenes)
|
|
1133
|
+
return;
|
|
1134
|
+
const name = String(index + 1);
|
|
1135
|
+
if (!scenes.some((scene) => scene.name === name)) {
|
|
1136
|
+
await context.addPage({ scene: { name } });
|
|
1137
|
+
}
|
|
1138
|
+
await context.setScenePath(`${scenePath}/${name}`);
|
|
1139
|
+
};
|
|
1140
|
+
const jumpPage = (index) => {
|
|
1141
|
+
if (!context.getIsWritable()) {
|
|
1142
|
+
console.warn("[Presentation]: no permission, make sure you have test room.isWritable");
|
|
1143
|
+
return false;
|
|
1144
|
+
}
|
|
1145
|
+
if (!(0 <= index && index < pages.length)) {
|
|
1146
|
+
console.warn(`[Presentation]: page ${index + 1} out of bounds [1, ${pages.length}]`);
|
|
1147
|
+
return false;
|
|
1148
|
+
}
|
|
1149
|
+
const scenes = context.getDisplayer().entireScenes()[scenePath];
|
|
1150
|
+
if (!scenes) {
|
|
1151
|
+
console.warn(`[Presentation]: no scenes found at ${scenePath}, make sure you have added options.scenePath in addApp()`);
|
|
1152
|
+
return false;
|
|
1153
|
+
}
|
|
1154
|
+
const name = String(index + 1);
|
|
1155
|
+
if (!scenes.some((scene) => scene.name === name)) {
|
|
1156
|
+
context.addPage({ scene: { name } });
|
|
1157
|
+
}
|
|
1158
|
+
page$$.setState({ index });
|
|
1159
|
+
return true;
|
|
1160
|
+
};
|
|
1161
|
+
const prevPage = () => jumpPage(page$$.state.index - 1);
|
|
1162
|
+
const nextPage = () => jumpPage(page$$.state.index + 1);
|
|
1163
|
+
const pageState = () => ({ index: page$$.state.index, length: pages.length });
|
|
1164
|
+
const scaleDocsToFit = () => {
|
|
1165
|
+
const { width, height } = app.page() || {};
|
|
1166
|
+
if (width && height) {
|
|
1167
|
+
view.moveCameraToContain({
|
|
1168
|
+
originX: -width / 2,
|
|
1169
|
+
originY: -height / 2,
|
|
1170
|
+
width,
|
|
1171
|
+
height,
|
|
1172
|
+
animationMode: "immediately"
|
|
1173
|
+
});
|
|
1174
|
+
view.setCameraBound({
|
|
1175
|
+
damping: 1,
|
|
1176
|
+
maxContentMode: () => view.camera.scale,
|
|
1177
|
+
minContentMode: () => view.camera.scale,
|
|
1178
|
+
centerX: 0,
|
|
1179
|
+
centerY: 0,
|
|
1180
|
+
width,
|
|
1181
|
+
height
|
|
1182
|
+
});
|
|
1183
|
+
}
|
|
1184
|
+
};
|
|
1185
|
+
syncPage(page$$.state.index);
|
|
1186
|
+
dispose.add(page$$.addStateChangedListener(() => syncPage(page$$.state.index)));
|
|
1187
|
+
dispose.add(context.emitter.on("roomStateChange", (state) => {
|
|
1188
|
+
var _a2;
|
|
1189
|
+
if ((_a2 = state.sceneState) == null ? void 0 : _a2.scenePath.endsWith("/0")) {
|
|
1190
|
+
syncPage(page$$.state.index);
|
|
1191
|
+
}
|
|
1192
|
+
}));
|
|
1193
|
+
const box = context.getBox();
|
|
1194
|
+
const app = dispose.add(createPresentation(box, pages, jumpPage, page$$));
|
|
1195
|
+
app.contentDOM.dataset.appPresentationVersion = "0.1.0-beta.0";
|
|
1196
|
+
app.scaleDocsToFit = scaleDocsToFit;
|
|
1197
|
+
app.log = log;
|
|
1198
|
+
context.mountView(app.whiteboardDOM);
|
|
1199
|
+
view.disableCameraTransform = true;
|
|
1200
|
+
scaleDocsToFit();
|
|
1201
|
+
dispose.make(() => {
|
|
1202
|
+
view.callbacks.on("onSizeUpdated", scaleDocsToFit);
|
|
1203
|
+
return () => view.callbacks.off("onSizeUpdated", scaleDocsToFit);
|
|
1204
|
+
});
|
|
1205
|
+
dispose.add(context.emitter.on("writableChange", (isWritable) => {
|
|
1206
|
+
app.setReadonly(!isWritable);
|
|
1207
|
+
}));
|
|
1208
|
+
context.emitter.on("destroy", () => dispose());
|
|
1209
|
+
const reportProgress = (progress, result) => {
|
|
1210
|
+
window.postMessage({ type: "@netless/_result_save_pdf_", appId: context.appId, progress, result }, "*");
|
|
1211
|
+
return result;
|
|
1212
|
+
};
|
|
1213
|
+
const base64url = async (url) => {
|
|
1214
|
+
try {
|
|
1215
|
+
const a = new URL(url);
|
|
1216
|
+
a.searchParams.set("t", Date.now().toString());
|
|
1217
|
+
url = a.toString();
|
|
1218
|
+
} catch (e) {
|
|
1219
|
+
}
|
|
1220
|
+
const data = await fetch(url);
|
|
1221
|
+
if (!data.ok)
|
|
1222
|
+
throw new Error(`[Presentation]: failed to fetch ${url} - ${await data.text()}`);
|
|
1223
|
+
const blob = await data.blob();
|
|
1224
|
+
const reader = new FileReader();
|
|
1225
|
+
return new Promise((resolve, reject) => {
|
|
1226
|
+
reader.onload = () => resolve(reader.result);
|
|
1227
|
+
reader.onerror = () => reject(reader.error);
|
|
1228
|
+
reader.readAsDataURL(blob);
|
|
1229
|
+
});
|
|
1230
|
+
};
|
|
1231
|
+
const toPdf = async () => {
|
|
1232
|
+
const MAX = 1920;
|
|
1233
|
+
const firstPage = pages[0];
|
|
1234
|
+
const { width, height } = firstPage;
|
|
1235
|
+
let pdfWidth = Math.floor(width), pdfHeight = Math.floor(height);
|
|
1236
|
+
if (pdfWidth > MAX) {
|
|
1237
|
+
pdfWidth = MAX;
|
|
1238
|
+
pdfHeight = Math.floor(height * pdfWidth / width);
|
|
1239
|
+
}
|
|
1240
|
+
if (pdfHeight > MAX) {
|
|
1241
|
+
pdfHeight = MAX;
|
|
1242
|
+
pdfWidth = Math.floor(width * pdfHeight / height);
|
|
1243
|
+
}
|
|
1244
|
+
const scenes = context.getDisplayer().entireScenes()[scenePath];
|
|
1245
|
+
const stage_canvas = document.createElement("canvas");
|
|
1246
|
+
stage_canvas.width = pdfWidth;
|
|
1247
|
+
stage_canvas.height = pdfHeight;
|
|
1248
|
+
const stage = stage_canvas.getContext("2d");
|
|
1249
|
+
const wb_canvas = document.createElement("canvas");
|
|
1250
|
+
wb_canvas.width = pdfWidth;
|
|
1251
|
+
wb_canvas.height = pdfHeight;
|
|
1252
|
+
const wb = wb_canvas.getContext("2d");
|
|
1253
|
+
if (!wb || !stage)
|
|
1254
|
+
return reportProgress(100, null);
|
|
1255
|
+
const { jsPDF } = await import('jspdf');
|
|
1256
|
+
const pdf = new jsPDF({
|
|
1257
|
+
format: [firstPage.width, firstPage.height],
|
|
1258
|
+
orientation: firstPage.width > firstPage.height ? "l" : "p",
|
|
1259
|
+
compress: true
|
|
1260
|
+
});
|
|
1261
|
+
for (let index = 0; index < pages.length; ++index) {
|
|
1262
|
+
const { width: width2, height: height2, src } = pages[index];
|
|
1263
|
+
const url = await base64url(src);
|
|
1264
|
+
const img = document.createElement("img");
|
|
1265
|
+
await new Promise((resolve) => {
|
|
1266
|
+
img.onload = resolve;
|
|
1267
|
+
img.src = url;
|
|
1268
|
+
});
|
|
1269
|
+
stage.drawImage(img, 0, 0);
|
|
1270
|
+
wb.clearRect(0, 0, pdfWidth, pdfHeight);
|
|
1271
|
+
if (scenes.some((scene) => scene.name == String(index + 1))) {
|
|
1272
|
+
view.screenshotToCanvas(
|
|
1273
|
+
wb,
|
|
1274
|
+
`${scenePath}/${index + 1}`,
|
|
1275
|
+
wb_canvas.width,
|
|
1276
|
+
wb_canvas.height,
|
|
1277
|
+
{ centerX: 0, centerY: 0, scale: Math.min(wb_canvas.width / width2, wb_canvas.height / height2) }
|
|
1278
|
+
);
|
|
1279
|
+
try {
|
|
1280
|
+
const wb_url = wb_canvas.toDataURL("image/png");
|
|
1281
|
+
const wb_img = document.createElement("img");
|
|
1282
|
+
await new Promise((resolve) => {
|
|
1283
|
+
wb_img.onload = resolve;
|
|
1284
|
+
wb_img.src = wb_url;
|
|
1285
|
+
});
|
|
1286
|
+
stage.drawImage(wb_img, 0, 0, pdfWidth, pdfHeight);
|
|
1287
|
+
} catch (err) {
|
|
1288
|
+
console.warn(err);
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
const output = stage_canvas.toDataURL("image/jpeg", 0.6);
|
|
1292
|
+
if (index > 0)
|
|
1293
|
+
pdf.addPage();
|
|
1294
|
+
pdf.addImage(output, "JPEG", 0, 0, pdfWidth, pdfHeight, "", "FAST");
|
|
1295
|
+
stage.clearRect(0, 0, pdfWidth, pdfHeight);
|
|
1296
|
+
const progress = Math.ceil((index + 1) / pages.length * 100);
|
|
1297
|
+
if (progress < 100)
|
|
1298
|
+
reportProgress(progress, null);
|
|
1299
|
+
}
|
|
1300
|
+
const data = pdf.output("arraybuffer");
|
|
1301
|
+
const title = box.title;
|
|
1302
|
+
return reportProgress(100, { pdf: data, title });
|
|
1303
|
+
};
|
|
1304
|
+
dispose.add(listen(window, "message", (ev) => {
|
|
1305
|
+
if (ev.data && ev.data.type == "@netless/_request_save_pdf_" && ev.data.appId == context.appId) {
|
|
1306
|
+
toPdf().catch((err) => {
|
|
1307
|
+
console.warn(err);
|
|
1308
|
+
reportProgress(100, null);
|
|
1309
|
+
});
|
|
1310
|
+
}
|
|
1311
|
+
}));
|
|
1312
|
+
const controller = { app, view, context, jumpPage, prevPage, nextPage, pageState, toPdf, log };
|
|
1313
|
+
dispose.add(listen(window, "message", (ev) => {
|
|
1314
|
+
if (ev.data === "@netless/_presentation_") {
|
|
1315
|
+
if (typeof window !== "undefined")
|
|
1316
|
+
dispose.make(() => {
|
|
1317
|
+
const debug = window._presentation_ || (window._presentation_ = /* @__PURE__ */ new Set());
|
|
1318
|
+
debug.add(controller);
|
|
1319
|
+
return () => debug.delete(controller);
|
|
1320
|
+
});
|
|
1321
|
+
console.log(controller);
|
|
1322
|
+
}
|
|
1323
|
+
}));
|
|
1324
|
+
return controller;
|
|
1325
|
+
}
|
|
1326
|
+
};
|
|
1327
|
+
var AppPresentation = class extends Presentation {
|
|
1328
|
+
constructor(config) {
|
|
1329
|
+
super(config);
|
|
1330
|
+
this.jumpPage = config.jumpPage;
|
|
1331
|
+
}
|
|
1332
|
+
onNewPageIndex(index, origin) {
|
|
1333
|
+
if (origin === "keydown" && this.box && !this.box.focus)
|
|
1334
|
+
return;
|
|
1335
|
+
if (this.log)
|
|
1336
|
+
this.log("[Presentation] user navigate to", index + 1, `(${origin})`);
|
|
1337
|
+
if (0 <= index && index < this.pages.length) {
|
|
1338
|
+
this.jumpPage(index);
|
|
1339
|
+
} else {
|
|
1340
|
+
console.warn(`[Presentation]: page index ${index} out of bounds [0, ${this.pages.length - 1}]`);
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
};
|
|
1344
|
+
var createPresentation = (box, pages, jumpPage, page$$) => {
|
|
1345
|
+
box.mountStyles(style_default);
|
|
1346
|
+
const app = new AppPresentation({ pages, readonly: box.readonly, jumpPage });
|
|
1347
|
+
app.box = box;
|
|
1348
|
+
box.mountContent(app.contentDOM);
|
|
1349
|
+
box.mountFooter(app.footerDOM);
|
|
1350
|
+
app.setPageIndex(page$$.state.index);
|
|
1351
|
+
app.dispose.add(page$$.addStateChangedListener(() => {
|
|
1352
|
+
app.setPageIndex(page$$.state.index);
|
|
1353
|
+
}));
|
|
1354
|
+
return app;
|
|
1355
|
+
};
|
|
1356
|
+
var install = (register, options = {}) => {
|
|
1357
|
+
let app = NetlessAppPresentation;
|
|
1358
|
+
if (options.as) {
|
|
1359
|
+
app = Object.assign({}, app, { kind: options.as });
|
|
1360
|
+
}
|
|
1361
|
+
return register({ kind: app.kind, src: app });
|
|
1362
|
+
};
|
|
1363
|
+
|
|
1364
|
+
// src/index.ts
|
|
1365
|
+
var version = "0.1.0-beta.0";
|
|
1366
|
+
|
|
1367
|
+
exports.NetlessAppPresentation = NetlessAppPresentation;
|
|
1368
|
+
exports.Presentation = Presentation;
|
|
1369
|
+
exports.default = NetlessAppPresentation;
|
|
1370
|
+
exports.install = install;
|
|
1371
|
+
exports.styles = style_default;
|
|
1372
|
+
exports.version = version;
|
|
1373
|
+
//# sourceMappingURL=index.js.map
|