single-file-core 1.5.94 → 1.5.96
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/core/helper.js +17 -2
- package/core/lib/processor-helper-common.js +3 -8
- package/core/util.js +1 -7
- package/css-tree-build/build.js +0 -1
- package/eslint.config.mjs +23 -0
- package/modules/template-formatter.js +11 -20
- package/package.json +3 -2
- package/processors/compression/compression-extract.js +8 -7
- package/processors/compression/compression-router.js +26 -1
- package/processors/compression/compression.js +1 -0
- package/processors/frame-tree/content/content-frame-tree.js +2 -2
- package/processors/hooks/content/content-hooks-frames-web.js +129 -89
- package/processors/hooks/content/content-hooks-frames.js +27 -17
- package/single-file-infobar.js +5 -4
- package/single-file.js +1 -7
- package/vendor/zip/z-worker.js +1 -1
- package/vendor/zip/zip.js +113 -3
- package/vendor/zip/zip.min.js +1 -1
- package/zip-build/package-lock.json +4 -4
- package/zip-build/package.json +1 -1
- package/zip-build/reserved-property-names.json +9 -3
package/core/helper.js
CHANGED
|
@@ -91,6 +91,8 @@ const CustomEvent = globalThis.CustomEvent;
|
|
|
91
91
|
const MutationObserver = globalThis.MutationObserver;
|
|
92
92
|
const URL = globalThis.URL;
|
|
93
93
|
const DOMParser = globalThis.DOMParser;
|
|
94
|
+
const Uint8Array = globalThis.Uint8Array;
|
|
95
|
+
const btoa = globalThis.btoa;
|
|
94
96
|
|
|
95
97
|
export {
|
|
96
98
|
initUserScriptHandler,
|
|
@@ -105,6 +107,7 @@ export {
|
|
|
105
107
|
getShadowRoot,
|
|
106
108
|
appendInfobar,
|
|
107
109
|
getContentSize,
|
|
110
|
+
getDataURI,
|
|
108
111
|
digest,
|
|
109
112
|
getValidFilename,
|
|
110
113
|
parseDocContent,
|
|
@@ -297,7 +300,10 @@ function markInvalidNesting(doc) {
|
|
|
297
300
|
|
|
298
301
|
function addTrackIds(element, index = 0, parentTrackId = "") {
|
|
299
302
|
const trackId = parentTrackId ? `${parentTrackId}.${index + 1}` : `${index + 1}`;
|
|
300
|
-
element.
|
|
303
|
+
const tagName = element.tagName.toUpperCase();
|
|
304
|
+
if (!(parentTrackId && (tagName == "BODY" || tagName == "HEAD" || tagName == "HTML"))) {
|
|
305
|
+
element.setAttribute(NESTING_TRACK_ID_ATTRIBUTE_NAME, trackId);
|
|
306
|
+
}
|
|
301
307
|
Array.from(element.children).forEach((child, indexChild) => addTrackIds(child, indexChild, trackId));
|
|
302
308
|
}
|
|
303
309
|
|
|
@@ -338,7 +344,7 @@ function fixInvalidNesting(document, NESTING_TRACK_ID_ATTRIBUTE_NAME, preventCle
|
|
|
338
344
|
if (idParts.length > 1) {
|
|
339
345
|
const parentId = idParts.slice(0, -1).join(".");
|
|
340
346
|
const expectedParent = trackIds[parentId];
|
|
341
|
-
if (expectedParent && element.parentElement !== expectedParent) {
|
|
347
|
+
if (expectedParent && element.parentElement !== expectedParent && !element.contains(expectedParent)) {
|
|
342
348
|
expectedParent.appendChild(element);
|
|
343
349
|
}
|
|
344
350
|
}
|
|
@@ -793,6 +799,15 @@ function getContentSize(content) {
|
|
|
793
799
|
return new Blob([content]).size;
|
|
794
800
|
}
|
|
795
801
|
|
|
802
|
+
async function getDataURI(blob) {
|
|
803
|
+
const bytes = new Uint8Array(await blob.arrayBuffer());
|
|
804
|
+
let content = "";
|
|
805
|
+
for (let offset = 0; offset < bytes.length; offset += 8192) {
|
|
806
|
+
content += String.fromCharCode(...bytes.subarray(offset, offset + 8192));
|
|
807
|
+
}
|
|
808
|
+
return "data:" + (blob.type || "application/octet-stream") + ";base64," + btoa(content);
|
|
809
|
+
}
|
|
810
|
+
|
|
796
811
|
async function digest(algo, text) {
|
|
797
812
|
try {
|
|
798
813
|
const data = new TextEncoder("utf-8").encode(text);
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
|
|
24
24
|
import {
|
|
25
25
|
normalizeFontFamily,
|
|
26
|
-
getFontWeight
|
|
26
|
+
getFontWeight,
|
|
27
|
+
getDataURI
|
|
27
28
|
} from "./../helper.js";
|
|
28
29
|
|
|
29
30
|
const DATA_URI_PREFIX = "data:";
|
|
@@ -60,7 +61,6 @@ const FONT_STRETCHES = {
|
|
|
60
61
|
"ultra-expanded": "200%"
|
|
61
62
|
};
|
|
62
63
|
const Blob = globalThis.Blob;
|
|
63
|
-
const FileReader = globalThis.FileReader;
|
|
64
64
|
const Image = globalThis.Image;
|
|
65
65
|
const OffscreenCanvas = globalThis.OffscreenCanvas;
|
|
66
66
|
|
|
@@ -710,10 +710,5 @@ async function resizeImage(doc, dataURI, { imageReductionFactor }) {
|
|
|
710
710
|
|
|
711
711
|
function toDataURI(content, contentType, charset) {
|
|
712
712
|
const blob = content instanceof Blob ? content : new Blob([content], { type: (contentType || "") + (charset ? ";charset=" + charset : "") });
|
|
713
|
-
return
|
|
714
|
-
const reader = new FileReader();
|
|
715
|
-
reader.onload = () => resolve(reader.result);
|
|
716
|
-
reader.onerror = () => reject(new Error(reader.error));
|
|
717
|
-
reader.readAsDataURL(blob);
|
|
718
|
-
});
|
|
713
|
+
return getDataURI(blob);
|
|
719
714
|
}
|
package/core/util.js
CHANGED
|
@@ -66,7 +66,6 @@ const CONTENT_TYPE_OCTET_STREAM = "application/octet-stream";
|
|
|
66
66
|
const URL = globalThis.URL;
|
|
67
67
|
const DOMParser = globalThis.DOMParser;
|
|
68
68
|
const Blob = globalThis.Blob;
|
|
69
|
-
const FileReader = globalThis.FileReader;
|
|
70
69
|
const fetch = (url, options) => {
|
|
71
70
|
options.cache = "force-cache";
|
|
72
71
|
options.referrerPolicy = "strict-origin-when-cross-origin";
|
|
@@ -351,12 +350,7 @@ async function getFetchResponse(resourceURL, options, data, charset, contentType
|
|
|
351
350
|
if (data) {
|
|
352
351
|
if (options.asBinary) {
|
|
353
352
|
if (options.inline) {
|
|
354
|
-
|
|
355
|
-
reader.readAsDataURL(new Blob([data], { type: contentType + (options.charset ? ";charset=" + options.charset : "") }));
|
|
356
|
-
data = await new Promise((resolve, reject) => {
|
|
357
|
-
reader.addEventListener("load", () => resolve(reader.result), false);
|
|
358
|
-
reader.addEventListener("error", reject, false);
|
|
359
|
-
});
|
|
353
|
+
data = await helper.getDataURI(new Blob([data], { type: contentType + (options.charset ? ";charset=" + options.charset : "") }));
|
|
360
354
|
} else {
|
|
361
355
|
data = new Uint8Array(data);
|
|
362
356
|
}
|
package/css-tree-build/build.js
CHANGED
|
@@ -4,7 +4,6 @@ import { build } from "esbuild";
|
|
|
4
4
|
|
|
5
5
|
const require = createRequire(import.meta.url);
|
|
6
6
|
const packagePath = require.resolve("css-tree/package.json");
|
|
7
|
-
const tokenStreamPath = packagePath.replace(/package\.json$/, "lib/tokenizer/TokenStream.js");
|
|
8
7
|
const licensePath = packagePath.replace(/package\.json$/, "LICENSE");
|
|
9
8
|
const { version } = JSON.parse(readFileSync(packagePath));
|
|
10
9
|
|
package/eslint.config.mjs
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import js from "@eslint/js";
|
|
2
2
|
|
|
3
3
|
export default [
|
|
4
|
+
{
|
|
5
|
+
ignores: [
|
|
6
|
+
"vendor/**",
|
|
7
|
+
"zip-build/lib/**"
|
|
8
|
+
]
|
|
9
|
+
},
|
|
4
10
|
js.configs.recommended,
|
|
5
11
|
{
|
|
6
12
|
languageOptions: {
|
|
@@ -27,5 +33,22 @@ export default [
|
|
|
27
33
|
"warn"
|
|
28
34
|
]
|
|
29
35
|
}
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
files: ["test/sfz-harness/**"],
|
|
39
|
+
languageOptions: {
|
|
40
|
+
globals: {
|
|
41
|
+
Deno: "readonly",
|
|
42
|
+
setTimeout: "readonly",
|
|
43
|
+
Blob: "readonly",
|
|
44
|
+
TextDecoder: "readonly",
|
|
45
|
+
TextEncoder: "readonly",
|
|
46
|
+
URL: "readonly",
|
|
47
|
+
performance: "readonly"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
rules: {
|
|
51
|
+
"no-console": "off"
|
|
52
|
+
}
|
|
30
53
|
}
|
|
31
54
|
];
|
|
@@ -27,7 +27,6 @@ import { parse } from "./template-parser.js";
|
|
|
27
27
|
import { getContentSize, digest, getValidFilename } from "./../core/helper.js";
|
|
28
28
|
|
|
29
29
|
const Blob = globalThis.Blob;
|
|
30
|
-
const FileReader = globalThis.FileReader;
|
|
31
30
|
const URL = globalThis.URL;
|
|
32
31
|
const Intl = globalThis.Intl;
|
|
33
32
|
const URLSearchParams = globalThis.URLSearchParams;
|
|
@@ -17187,6 +17186,10 @@ async function evalTemplate(template = "", options, content, doc, context = {})
|
|
|
17187
17186
|
variables[prefix + "minutes-utc"] = { getter: () => String(date.getUTCMinutes()).padStart(2, "0") };
|
|
17188
17187
|
variables[prefix + "seconds-utc"] = { getter: () => String(date.getUTCSeconds()).padStart(2, "0") };
|
|
17189
17188
|
variables[prefix + "time-ms"] = { getter: () => String(date.getTime()) };
|
|
17189
|
+
variables[prefix + "weekday-locale"] = { getter: () => date.toLocaleDateString(undefined, { weekday: "long" }) };
|
|
17190
|
+
variables[prefix + "weekday-short-locale"] = { getter: () => date.toLocaleDateString(undefined, { weekday: "short" }) };
|
|
17191
|
+
variables[prefix + "weekday-utc"] = { getter: () => date.toLocaleDateString(undefined, { weekday: "long", timeZone: "UTC" }) };
|
|
17192
|
+
variables[prefix + "weekday-short-utc"] = { getter: () => date.toLocaleDateString(undefined, { weekday: "short", timeZone: "UTC" }) };
|
|
17190
17193
|
}
|
|
17191
17194
|
}
|
|
17192
17195
|
|
|
@@ -17259,26 +17262,14 @@ function getLastSegment(url, replacementCharacter) {
|
|
|
17259
17262
|
return lastSegment;
|
|
17260
17263
|
}
|
|
17261
17264
|
|
|
17262
|
-
function truncateText(content, maxSize) {
|
|
17265
|
+
async function truncateText(content, maxSize) {
|
|
17263
17266
|
const blob = new Blob([content]);
|
|
17264
|
-
const
|
|
17265
|
-
|
|
17266
|
-
|
|
17267
|
-
|
|
17268
|
-
|
|
17269
|
-
|
|
17270
|
-
if (content.startsWith(reader.result)) {
|
|
17271
|
-
resolve(reader.result);
|
|
17272
|
-
} else {
|
|
17273
|
-
truncateText(content, maxSize - 1)
|
|
17274
|
-
.then(resolve)
|
|
17275
|
-
.catch(reject);
|
|
17276
|
-
}
|
|
17277
|
-
},
|
|
17278
|
-
false
|
|
17279
|
-
);
|
|
17280
|
-
reader.addEventListener("error", reject, false);
|
|
17281
|
-
});
|
|
17267
|
+
const result = await blob.slice(0, maxSize).text();
|
|
17268
|
+
if (content.startsWith(result)) {
|
|
17269
|
+
return result;
|
|
17270
|
+
} else {
|
|
17271
|
+
return truncateText(content, maxSize - 1);
|
|
17272
|
+
}
|
|
17282
17273
|
}
|
|
17283
17274
|
|
|
17284
17275
|
function getFilenameExtension(options) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "single-file-core",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.96",
|
|
4
4
|
"description": "SingleFile Core",
|
|
5
5
|
"author": "Gildas Lormeau",
|
|
6
6
|
"license": "AGPL-3.0-or-later",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
},
|
|
21
21
|
"homepage": "https://github.com/gildas-lormeau/single-file-core#readme",
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"eslint": "^9.39.
|
|
23
|
+
"@eslint/js": "^9.39.5",
|
|
24
|
+
"eslint": "^10.9.1"
|
|
24
25
|
}
|
|
25
26
|
}
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* Source.
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
-
/* global zip, Blob,
|
|
24
|
+
/* global zip, Blob, btoa, URL */
|
|
25
25
|
|
|
26
26
|
export {
|
|
27
27
|
extract
|
|
@@ -220,12 +220,13 @@ async function extract(content, { password, prompt = () => { }, zipOptions = { u
|
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
async function getDataURI(textContent, mimeType) {
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}
|
|
223
|
+
const blob = new Blob([textContent], { type: mimeType });
|
|
224
|
+
const bytes = new Uint8Array(await blob.arrayBuffer());
|
|
225
|
+
let content = "";
|
|
226
|
+
for (let offset = 0; offset < bytes.length; offset += 8192) {
|
|
227
|
+
content += String.fromCharCode(...bytes.subarray(offset, offset + 8192));
|
|
228
|
+
}
|
|
229
|
+
return ("data:" + (blob.type || "application/octet-stream") + ";base64," + btoa(content)).replace(CHARSET_UTF8, "");
|
|
229
230
|
}
|
|
230
231
|
|
|
231
232
|
function replaceAll(string, search, replacement) {
|
|
@@ -69,6 +69,7 @@ async function router(content, { extract, display }) {
|
|
|
69
69
|
const manifest = JSON.parse(await pagesEntry.getData(new zip.TextWriter()));
|
|
70
70
|
const tocEntry = entries.find(entry => entry.filename == TOC_FILENAME);
|
|
71
71
|
const { pages } = manifest;
|
|
72
|
+
const pageTransitions = manifest.pageTransitions || "auto";
|
|
72
73
|
const aliases = new Map(Object.entries(manifest.aliases || {}));
|
|
73
74
|
pages.forEach(page => {
|
|
74
75
|
urlToPath.set(stripFragment(page.url), page.path);
|
|
@@ -141,7 +142,7 @@ async function router(content, { extract, display }) {
|
|
|
141
142
|
const willRender = routed && path != currentPath && isRenderablePath(path);
|
|
142
143
|
// the whole render and scroll sequence runs inside the view transition
|
|
143
144
|
// so that the crossfade ends on the final scroll position
|
|
144
|
-
if (willRender && document.startViewTransition && !prefersReducedMotion()) {
|
|
145
|
+
if (willRender && document.startViewTransition && pageTransitionEnabled() && !prefersReducedMotion()) {
|
|
145
146
|
await document.startViewTransition(update).updateCallbackDone;
|
|
146
147
|
} else {
|
|
147
148
|
await update();
|
|
@@ -324,6 +325,30 @@ async function router(content, { extract, display }) {
|
|
|
324
325
|
return node;
|
|
325
326
|
}
|
|
326
327
|
|
|
328
|
+
// "auto" approximates the cross-document opt-in of live sites: the transition
|
|
329
|
+
// runs when the displayed page itself contains an @view-transition rule set
|
|
330
|
+
// to navigation: auto, so pages without transitions stay instant
|
|
331
|
+
function pageTransitionEnabled() {
|
|
332
|
+
if (pageTransitions == "fade") {
|
|
333
|
+
return true;
|
|
334
|
+
}
|
|
335
|
+
if (pageTransitions == "none") {
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
return Array.from(document.styleSheets).some(styleSheet => {
|
|
339
|
+
try {
|
|
340
|
+
return containsViewTransitionRule(styleSheet.cssRules);
|
|
341
|
+
} catch {
|
|
342
|
+
return false;
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function containsViewTransitionRule(cssRules) {
|
|
348
|
+
return Array.from(cssRules).some(cssRule => cssRule.navigation == "auto" ||
|
|
349
|
+
(cssRule.cssRules && cssRule.cssRules.length && containsViewTransitionRule(cssRule.cssRules)));
|
|
350
|
+
}
|
|
351
|
+
|
|
327
352
|
function prefersReducedMotion() {
|
|
328
353
|
return Boolean(globalThis.matchMedia && globalThis.matchMedia("(prefers-reduced-motion: reduce)").matches);
|
|
329
354
|
}
|
|
@@ -397,8 +397,8 @@ function sendMessage(targetWindow, message, useChannel) {
|
|
|
397
397
|
}
|
|
398
398
|
}
|
|
399
399
|
|
|
400
|
-
function getFrameData(document,
|
|
401
|
-
const docData = helper.preProcessDoc(document,
|
|
400
|
+
function getFrameData(document, win, windowId, options, scrolling) {
|
|
401
|
+
const docData = helper.preProcessDoc(document, win, options);
|
|
402
402
|
const content = helper.serialize(document);
|
|
403
403
|
helper.postProcessDoc(document, docData.markedElements, docData.invalidElements);
|
|
404
404
|
const baseURI = document.baseURI.split("#")[0];
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* Source.
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
-
(
|
|
24
|
+
(() => {
|
|
25
25
|
|
|
26
26
|
const LOAD_DEFERRED_IMAGES_START_EVENT = "single-file-load-deferred-images-start";
|
|
27
27
|
const LOAD_DEFERRED_IMAGES_END_EVENT = "single-file-load-deferred-images-end";
|
|
@@ -71,8 +71,8 @@
|
|
|
71
71
|
const Element = globalThis.Element;
|
|
72
72
|
const UIEvent = globalThis.UIEvent;
|
|
73
73
|
const Event = globalThis.Event;
|
|
74
|
-
const
|
|
75
|
-
const
|
|
74
|
+
const Uint8Array = globalThis.Uint8Array;
|
|
75
|
+
const btoa = globalThis.btoa;
|
|
76
76
|
const JSON = globalThis.JSON;
|
|
77
77
|
const MutationObserver = globalThis.MutationObserver;
|
|
78
78
|
const URL = globalThis.URL;
|
|
@@ -88,83 +88,126 @@
|
|
|
88
88
|
new MutationObserver(init).observe(document, { childList: true });
|
|
89
89
|
|
|
90
90
|
function init() {
|
|
91
|
-
document.addEventListener(LOAD_DEFERRED_IMAGES_START_EVENT,
|
|
92
|
-
document.addEventListener(LOAD_DEFERRED_IMAGES_KEEP_ZOOM_LEVEL_START_EVENT,
|
|
93
|
-
document.addEventListener(LOAD_DEFERRED_IMAGES_END_EVENT,
|
|
94
|
-
document.addEventListener(LOAD_DEFERRED_IMAGES_KEEP_ZOOM_LEVEL_END_EVENT,
|
|
91
|
+
document.addEventListener(LOAD_DEFERRED_IMAGES_START_EVENT, onLoadDeferredImagesStart);
|
|
92
|
+
document.addEventListener(LOAD_DEFERRED_IMAGES_KEEP_ZOOM_LEVEL_START_EVENT, onLoadDeferredImagesKeepZoomLevelStart);
|
|
93
|
+
document.addEventListener(LOAD_DEFERRED_IMAGES_END_EVENT, onLoadDeferredImagesEnd);
|
|
94
|
+
document.addEventListener(LOAD_DEFERRED_IMAGES_KEEP_ZOOM_LEVEL_END_EVENT, onLoadDeferredImagesKeepZoomLevelEnd);
|
|
95
95
|
document.addEventListener(LOAD_DEFERRED_IMAGES_RESET_EVENT, resetScreenSize);
|
|
96
|
-
document.addEventListener(LOAD_DEFERRED_IMAGES_RESET_ZOOM_LEVEL_EVENT,
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
document.documentElement.style.setProperty("min-height", minHeight, minHeightPriority);
|
|
106
|
-
document.documentElement.style.removeProperty("-sf-transform");
|
|
107
|
-
document.documentElement.style.removeProperty("-sf-transform-origin");
|
|
108
|
-
document.documentElement.style.removeProperty("-sf-min-height");
|
|
109
|
-
resetScreenSize();
|
|
110
|
-
});
|
|
111
|
-
document.addEventListener(DISPATCH_SCROLL_START_EVENT, () => { dispatchScrollEvent = true; });
|
|
112
|
-
document.addEventListener(DISPATCH_SCROLL_END_EVENT, () => { dispatchScrollEvent = false; });
|
|
113
|
-
document.addEventListener(BLOCK_COOKIES_START_EVENT, () => {
|
|
114
|
-
try {
|
|
115
|
-
document.__defineGetter__("cookie", () => { throw new Error("document.cookie temporary blocked by SingleFile"); });
|
|
116
|
-
// eslint-disable-next-line no-unused-vars
|
|
117
|
-
} catch (error) {
|
|
118
|
-
// ignored
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
document.addEventListener(BLOCK_COOKIES_END_EVENT, () => { delete document.cookie; });
|
|
122
|
-
document.addEventListener(BLOCK_STORAGE_START_EVENT, () => {
|
|
123
|
-
if (!globalThis._singleFile_localStorage) {
|
|
124
|
-
globalThis._singleFile_localStorage = globalThis.localStorage;
|
|
125
|
-
globalThis.__defineGetter__("localStorage", () => { throw new Error("localStorage temporary blocked by SingleFile"); });
|
|
126
|
-
}
|
|
127
|
-
if (!globalThis._singleFile_indexedDB) {
|
|
128
|
-
globalThis._singleFile_indexedDB = globalThis.indexedDB;
|
|
129
|
-
globalThis.__defineGetter__("indexedDB", () => { throw new Error("indexedDB temporary blocked by SingleFile"); });
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
document.addEventListener(BLOCK_STORAGE_END_EVENT, () => {
|
|
133
|
-
if (globalThis._singleFile_localStorage) {
|
|
134
|
-
delete globalThis.localStorage;
|
|
135
|
-
globalThis.localStorage = globalThis._singleFile_localStorage;
|
|
136
|
-
delete globalThis._singleFile_localStorage;
|
|
137
|
-
}
|
|
138
|
-
if (!globalThis._singleFile_indexedDB) {
|
|
139
|
-
delete globalThis.indexedDB;
|
|
140
|
-
globalThis.indexedDB = globalThis._singleFile_indexedDB;
|
|
141
|
-
delete globalThis._singleFile_indexedDB;
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
document.addEventListener(FETCH_SUPPORTED_REQUEST_EVENT, () =>
|
|
145
|
-
document.dispatchEvent(new CustomEvent(FETCH_SUPPORTED_RESPONSE_EVENT)));
|
|
146
|
-
document.addEventListener(FETCH_REQUEST_EVENT, async event => {
|
|
147
|
-
const { url, options } = JSON.parse(event.detail);
|
|
148
|
-
let detail;
|
|
149
|
-
try {
|
|
150
|
-
const response = await fetch(url, options);
|
|
151
|
-
detail = { url, response: await response.arrayBuffer(), headers: [...response.headers], status: response.status };
|
|
152
|
-
} catch (error) {
|
|
153
|
-
detail = { url, error: error && (error.message || error.toString()) };
|
|
154
|
-
}
|
|
155
|
-
document.dispatchEvent(new CustomEvent(FETCH_RESPONSE_EVENT, { detail }));
|
|
156
|
-
});
|
|
96
|
+
document.addEventListener(LOAD_DEFERRED_IMAGES_RESET_ZOOM_LEVEL_EVENT, onLoadDeferredImagesResetZoomLevel);
|
|
97
|
+
document.addEventListener(DISPATCH_SCROLL_START_EVENT, onDispatchScrollStart);
|
|
98
|
+
document.addEventListener(DISPATCH_SCROLL_END_EVENT, onDispatchScrollEnd);
|
|
99
|
+
document.addEventListener(BLOCK_COOKIES_START_EVENT, onBlockCookiesStart);
|
|
100
|
+
document.addEventListener(BLOCK_COOKIES_END_EVENT, onBlockCookiesEnd);
|
|
101
|
+
document.addEventListener(BLOCK_STORAGE_START_EVENT, onBlockStorageStart);
|
|
102
|
+
document.addEventListener(BLOCK_STORAGE_END_EVENT, onBlockStorageEnd);
|
|
103
|
+
document.addEventListener(FETCH_SUPPORTED_REQUEST_EVENT, onFetchSupportedRequest);
|
|
104
|
+
document.addEventListener(FETCH_REQUEST_EVENT, onFetchRequest);
|
|
157
105
|
document.addEventListener(GET_ADOPTED_STYLESHEETS_REQUEST_EVENT, getAdoptedStylesheetsListener);
|
|
158
|
-
document.addEventListener(BOOTSTRAP_EVENT,
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
106
|
+
document.addEventListener(BOOTSTRAP_EVENT, onBootstrap);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function onLoadDeferredImagesStart() {
|
|
110
|
+
loadDeferredImagesStart();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function onLoadDeferredImagesKeepZoomLevelStart() {
|
|
114
|
+
loadDeferredImagesStart(true);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function onLoadDeferredImagesEnd() {
|
|
118
|
+
loadDeferredImagesEnd();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function onLoadDeferredImagesKeepZoomLevelEnd() {
|
|
122
|
+
loadDeferredImagesEnd(true);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function onLoadDeferredImagesResetZoomLevel() {
|
|
126
|
+
const transform = document.documentElement.style.getPropertyValue("-sf-transform");
|
|
127
|
+
const transformPriority = document.documentElement.style.getPropertyPriority("-sf-transform");
|
|
128
|
+
const transformOrigin = document.documentElement.style.getPropertyValue("-sf-transform-origin");
|
|
129
|
+
const transformOriginPriority = document.documentElement.style.getPropertyPriority("-sf-transform-origin");
|
|
130
|
+
const minHeight = document.documentElement.style.getPropertyValue("-sf-min-height");
|
|
131
|
+
const minHeightPriority = document.documentElement.style.getPropertyPriority("-sf-min-height");
|
|
132
|
+
document.documentElement.style.setProperty("transform", transform, transformPriority);
|
|
133
|
+
document.documentElement.style.setProperty("transform-origin", transformOrigin, transformOriginPriority);
|
|
134
|
+
document.documentElement.style.setProperty("min-height", minHeight, minHeightPriority);
|
|
135
|
+
document.documentElement.style.removeProperty("-sf-transform");
|
|
136
|
+
document.documentElement.style.removeProperty("-sf-transform-origin");
|
|
137
|
+
document.documentElement.style.removeProperty("-sf-min-height");
|
|
138
|
+
resetScreenSize();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function onDispatchScrollStart() {
|
|
142
|
+
dispatchScrollEvent = true;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function onDispatchScrollEnd() {
|
|
146
|
+
dispatchScrollEvent = false;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function onBlockCookiesStart() {
|
|
150
|
+
try {
|
|
151
|
+
document.__defineGetter__("cookie", () => { throw new Error("document.cookie temporary blocked by SingleFile"); });
|
|
152
|
+
// eslint-disable-next-line no-unused-vars
|
|
153
|
+
} catch (error) {
|
|
154
|
+
// ignored
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function onBlockCookiesEnd() {
|
|
159
|
+
delete document.cookie;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function onBlockStorageStart() {
|
|
163
|
+
if (!globalThis._singleFile_localStorage) {
|
|
164
|
+
globalThis._singleFile_localStorage = globalThis.localStorage;
|
|
165
|
+
globalThis.__defineGetter__("localStorage", () => { throw new Error("localStorage temporary blocked by SingleFile"); });
|
|
166
|
+
}
|
|
167
|
+
if (!globalThis._singleFile_indexedDB) {
|
|
168
|
+
globalThis._singleFile_indexedDB = globalThis.indexedDB;
|
|
169
|
+
globalThis.__defineGetter__("indexedDB", () => { throw new Error("indexedDB temporary blocked by SingleFile"); });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function onBlockStorageEnd() {
|
|
174
|
+
if (globalThis._singleFile_localStorage) {
|
|
175
|
+
delete globalThis.localStorage;
|
|
176
|
+
globalThis.localStorage = globalThis._singleFile_localStorage;
|
|
177
|
+
delete globalThis._singleFile_localStorage;
|
|
178
|
+
}
|
|
179
|
+
if (!globalThis._singleFile_indexedDB) {
|
|
180
|
+
delete globalThis.indexedDB;
|
|
181
|
+
globalThis.indexedDB = globalThis._singleFile_indexedDB;
|
|
182
|
+
delete globalThis._singleFile_indexedDB;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function onFetchSupportedRequest() {
|
|
187
|
+
document.dispatchEvent(new CustomEvent(FETCH_SUPPORTED_RESPONSE_EVENT));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
async function onFetchRequest(event) {
|
|
191
|
+
const { url, options } = JSON.parse(event.detail);
|
|
192
|
+
let detail;
|
|
193
|
+
try {
|
|
194
|
+
const response = await fetch(url, options);
|
|
195
|
+
detail = { url, response: await response.arrayBuffer(), headers: [...response.headers], status: response.status };
|
|
196
|
+
} catch (error) {
|
|
197
|
+
detail = { url, error: error && (error.message || error.toString()) };
|
|
198
|
+
}
|
|
199
|
+
document.dispatchEvent(new CustomEvent(FETCH_RESPONSE_EVENT, { detail }));
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function onBootstrap(event) {
|
|
203
|
+
try {
|
|
204
|
+
if (globalThis.bootstrap && event.detail.data) {
|
|
205
|
+
globalThis.bootstrap(event.detail.data);
|
|
166
206
|
}
|
|
167
|
-
|
|
207
|
+
// eslint-disable-next-line no-unused-vars
|
|
208
|
+
} catch (error) {
|
|
209
|
+
// ignored
|
|
210
|
+
}
|
|
168
211
|
}
|
|
169
212
|
|
|
170
213
|
function loadDeferredImagesStart(keepZoomLevel) {
|
|
@@ -521,18 +564,15 @@
|
|
|
521
564
|
}
|
|
522
565
|
});
|
|
523
566
|
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
detail.src = "url(" + reader.result + ")";
|
|
530
|
-
resolve(detail);
|
|
531
|
-
});
|
|
532
|
-
} else {
|
|
533
|
-
resolve(detail);
|
|
567
|
+
if (detail.src instanceof ArrayBuffer) {
|
|
568
|
+
const bytes = new Uint8Array(detail.src);
|
|
569
|
+
let content = "";
|
|
570
|
+
for (let offset = 0; offset < bytes.length; offset += 8192) {
|
|
571
|
+
content += String.fromCharCode(...bytes.subarray(offset, offset + 8192));
|
|
534
572
|
}
|
|
535
|
-
|
|
573
|
+
detail.src = "url(data:application/octet-stream;base64," + btoa(content) + ")";
|
|
574
|
+
}
|
|
575
|
+
return detail;
|
|
536
576
|
}
|
|
537
577
|
|
|
538
578
|
function dispatchResizeEvent() {
|
|
@@ -547,4 +587,4 @@
|
|
|
547
587
|
}
|
|
548
588
|
}
|
|
549
589
|
|
|
550
|
-
})(
|
|
590
|
+
})();
|
|
@@ -65,26 +65,36 @@ new MutationObserver(init).observe(document, { childList: true });
|
|
|
65
65
|
|
|
66
66
|
function init() {
|
|
67
67
|
if (document instanceof Document) {
|
|
68
|
-
document.addEventListener(NEW_FONT_FACE_EVENT,
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
fontFaces.set(JSON.stringify(key), detail);
|
|
73
|
-
});
|
|
74
|
-
document.addEventListener(DELETE_FONT_EVENT, event => {
|
|
75
|
-
const detail = event.detail;
|
|
76
|
-
const key = Object.assign({}, detail);
|
|
77
|
-
delete key.src;
|
|
78
|
-
fontFaces.delete(JSON.stringify(key));
|
|
79
|
-
});
|
|
80
|
-
document.addEventListener(CLEAR_FONTS_EVENT, () => fontFaces = new Map());
|
|
81
|
-
document.addEventListener(NEW_WORKLET_EVENT, event => {
|
|
82
|
-
const detail = event.detail;
|
|
83
|
-
worklets.set(detail.moduleURL, detail);
|
|
84
|
-
});
|
|
68
|
+
document.addEventListener(NEW_FONT_FACE_EVENT, onNewFontFace);
|
|
69
|
+
document.addEventListener(DELETE_FONT_EVENT, onDeleteFont);
|
|
70
|
+
document.addEventListener(CLEAR_FONTS_EVENT, onClearFonts);
|
|
71
|
+
document.addEventListener(NEW_WORKLET_EVENT, onNewWorklet);
|
|
85
72
|
}
|
|
86
73
|
}
|
|
87
74
|
|
|
75
|
+
function onNewFontFace(event) {
|
|
76
|
+
const detail = event.detail;
|
|
77
|
+
const key = Object.assign({}, detail);
|
|
78
|
+
delete key.src;
|
|
79
|
+
fontFaces.set(JSON.stringify(key), detail);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function onDeleteFont(event) {
|
|
83
|
+
const detail = event.detail;
|
|
84
|
+
const key = Object.assign({}, detail);
|
|
85
|
+
delete key.src;
|
|
86
|
+
fontFaces.delete(JSON.stringify(key));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function onClearFonts() {
|
|
90
|
+
fontFaces.clear();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function onNewWorklet(event) {
|
|
94
|
+
const detail = event.detail;
|
|
95
|
+
worklets.set(detail.moduleURL, detail);
|
|
96
|
+
}
|
|
97
|
+
|
|
88
98
|
export {
|
|
89
99
|
getFontsData,
|
|
90
100
|
getWorkletsData,
|
package/single-file-infobar.js
CHANGED
|
@@ -21,11 +21,11 @@
|
|
|
21
21
|
* Source.
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
-
/* global
|
|
24
|
+
/* global document */
|
|
25
25
|
|
|
26
26
|
import { appendInfobar, refreshInfobarInfo, extractInfobarData } from "./core/infobar.js";
|
|
27
27
|
|
|
28
|
-
(
|
|
28
|
+
(() => {
|
|
29
29
|
|
|
30
30
|
const browser = globalThis.browser;
|
|
31
31
|
const MutationObserver = globalThis.MutationObserver;
|
|
@@ -36,7 +36,8 @@ import { appendInfobar, refreshInfobarInfo, extractInfobarData } from "./core/in
|
|
|
36
36
|
if (globalThis.window == globalThis.top) {
|
|
37
37
|
document.addEventListener("single-file-display-infobar", displayIcon, false);
|
|
38
38
|
if (document.documentElement.getAttribute("data-sfz") == "" && !mutationObserver) {
|
|
39
|
-
mutationObserver = new MutationObserver(init)
|
|
39
|
+
mutationObserver = new MutationObserver(init);
|
|
40
|
+
mutationObserver.observe(document, { childList: true });
|
|
40
41
|
} else {
|
|
41
42
|
if (document.readyState == "loading") {
|
|
42
43
|
document.addEventListener("DOMContentLoaded", displayIcon, false);
|
|
@@ -77,4 +78,4 @@ import { appendInfobar, refreshInfobarInfo, extractInfobarData } from "./core/in
|
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
})(
|
|
81
|
+
})();
|