@file-viewer/renderer-chm 3.0.1
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/LICENSE +196 -0
- package/README.en.md +13 -0
- package/README.md +13 -0
- package/THIRD_PARTY_NOTICES.md +12 -0
- package/dist/chm.d.ts +2 -0
- package/dist/chm.js +593 -0
- package/dist/chm.worker.d.ts +1 -0
- package/dist/chm.worker.js +2 -0
- package/dist/chm_wasm.js +583 -0
- package/dist/chm_wasm_bg.wasm +0 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +16 -0
- package/dist/model.d.ts +78 -0
- package/dist/model.js +125 -0
- package/dist/security.d.ts +33 -0
- package/dist/security.js +850 -0
- package/dist/style.d.ts +1 -0
- package/dist/style.js +26 -0
- package/dist/workerClient.d.ts +32 -0
- package/dist/workerClient.js +157 -0
- package/dist/workerProtocol.d.ts +70 -0
- package/dist/workerProtocol.js +1 -0
- package/file-viewer.capability.json +38 -0
- package/package.json +92 -0
- package/rust/Cargo.lock +247 -0
- package/rust/Cargo.toml +29 -0
- package/rust/LICENSE +196 -0
- package/rust/NOTICE.md +47 -0
- package/rust/THIRD_PARTY_LICENSES.md +365 -0
- package/rust/src/chm.rs +702 -0
- package/rust/src/core.rs +745 -0
- package/rust/src/error.rs +64 -0
- package/rust/src/lib.rs +104 -0
- package/rust/src/lzx.rs +632 -0
- package/rust/src/metadata.rs +839 -0
- package/rust/src/sitemap.rs +442 -0
package/dist/model.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
export const DEFAULT_CHM_OPTIONS = Object.freeze({
|
|
2
|
+
workerTimeoutMs: 60000,
|
|
3
|
+
maxArchiveBytes: 320 * 1024 * 1024,
|
|
4
|
+
maxEntries: 50000,
|
|
5
|
+
maxEntryBytes: 32 * 1024 * 1024,
|
|
6
|
+
maxTotalDecompressedBytes: 512 * 1024 * 1024,
|
|
7
|
+
maxHtmlBytes: 16 * 1024 * 1024,
|
|
8
|
+
maxSearchTopics: 10000,
|
|
9
|
+
maxSearchResults: 200,
|
|
10
|
+
});
|
|
11
|
+
const MIB = 1024 * 1024;
|
|
12
|
+
export const CHM_HARD_LIMITS = Object.freeze({
|
|
13
|
+
maxArchiveBytes: 1024 * MIB,
|
|
14
|
+
maxEntries: 250000,
|
|
15
|
+
maxEntryBytes: 512 * MIB,
|
|
16
|
+
maxTotalDecompressedBytes: 8 * 1024 * MIB,
|
|
17
|
+
maxHtmlBytes: 64 * MIB,
|
|
18
|
+
});
|
|
19
|
+
const finiteLimit = (value, fallback, minimum, maximum = Number.MAX_SAFE_INTEGER) => {
|
|
20
|
+
if (!Number.isFinite(value) || value == null)
|
|
21
|
+
return fallback;
|
|
22
|
+
return Math.min(maximum, Math.max(minimum, Math.floor(value)));
|
|
23
|
+
};
|
|
24
|
+
export const resolveChmOptions = (options) => ({
|
|
25
|
+
workerTimeoutMs: finiteLimit(options === null || options === void 0 ? void 0 : options.workerTimeoutMs, DEFAULT_CHM_OPTIONS.workerTimeoutMs, 1000),
|
|
26
|
+
maxArchiveBytes: finiteLimit(options === null || options === void 0 ? void 0 : options.maxArchiveBytes, DEFAULT_CHM_OPTIONS.maxArchiveBytes, 1, CHM_HARD_LIMITS.maxArchiveBytes),
|
|
27
|
+
maxEntries: finiteLimit(options === null || options === void 0 ? void 0 : options.maxEntries, DEFAULT_CHM_OPTIONS.maxEntries, 1, CHM_HARD_LIMITS.maxEntries),
|
|
28
|
+
maxEntryBytes: finiteLimit(options === null || options === void 0 ? void 0 : options.maxEntryBytes, DEFAULT_CHM_OPTIONS.maxEntryBytes, 1, CHM_HARD_LIMITS.maxEntryBytes),
|
|
29
|
+
maxTotalDecompressedBytes: finiteLimit(options === null || options === void 0 ? void 0 : options.maxTotalDecompressedBytes, DEFAULT_CHM_OPTIONS.maxTotalDecompressedBytes, 1, CHM_HARD_LIMITS.maxTotalDecompressedBytes),
|
|
30
|
+
maxHtmlBytes: finiteLimit(options === null || options === void 0 ? void 0 : options.maxHtmlBytes, DEFAULT_CHM_OPTIONS.maxHtmlBytes, 1, CHM_HARD_LIMITS.maxHtmlBytes),
|
|
31
|
+
maxSearchTopics: finiteLimit(options === null || options === void 0 ? void 0 : options.maxSearchTopics, DEFAULT_CHM_OPTIONS.maxSearchTopics, 1),
|
|
32
|
+
maxSearchResults: finiteLimit(options === null || options === void 0 ? void 0 : options.maxSearchResults, DEFAULT_CHM_OPTIONS.maxSearchResults, 1),
|
|
33
|
+
});
|
|
34
|
+
const stringValue = (value) => typeof value === 'string' ? value : '';
|
|
35
|
+
const numberValue = (value) => typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
36
|
+
const booleanValue = (value) => value === true;
|
|
37
|
+
const normalizeTopic = (value) => {
|
|
38
|
+
var _a;
|
|
39
|
+
if (!value || typeof value !== 'object')
|
|
40
|
+
return null;
|
|
41
|
+
const source = value;
|
|
42
|
+
const path = stringValue(source.path || source.local || source.url);
|
|
43
|
+
if (!path)
|
|
44
|
+
return null;
|
|
45
|
+
return {
|
|
46
|
+
title: stringValue(source.title || source.name) || path,
|
|
47
|
+
path,
|
|
48
|
+
contextId: numberValue((_a = source.contextId) !== null && _a !== void 0 ? _a : source.context_id),
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
const normalizeNavigationNodes = (value) => {
|
|
52
|
+
if (!Array.isArray(value))
|
|
53
|
+
return [];
|
|
54
|
+
const roots = [];
|
|
55
|
+
const queue = [];
|
|
56
|
+
for (let index = value.length - 1; index >= 0; index -= 1) {
|
|
57
|
+
queue.push({ source: value[index], target: roots });
|
|
58
|
+
}
|
|
59
|
+
while (queue.length) {
|
|
60
|
+
const current = queue.pop();
|
|
61
|
+
if (!(current === null || current === void 0 ? void 0 : current.source) || typeof current.source !== 'object')
|
|
62
|
+
continue;
|
|
63
|
+
const source = current.source;
|
|
64
|
+
const children = [];
|
|
65
|
+
const node = {
|
|
66
|
+
title: stringValue(source.title || source.name || source.keyword) || stringValue(source.path || source.local),
|
|
67
|
+
path: stringValue(source.path || source.local || source.url) || undefined,
|
|
68
|
+
keyword: stringValue(source.keyword) || undefined,
|
|
69
|
+
children,
|
|
70
|
+
};
|
|
71
|
+
current.target.push(node);
|
|
72
|
+
const aliases = Array.isArray(source.locals)
|
|
73
|
+
? source.locals.filter((item) => typeof item === 'string' && Boolean(item))
|
|
74
|
+
: [];
|
|
75
|
+
if (!node.path && aliases.length)
|
|
76
|
+
node.path = aliases[0];
|
|
77
|
+
for (let index = node.path ? 1 : 0; index < aliases.length; index += 1) {
|
|
78
|
+
children.push({ title: `${node.title} · ${index + 1}`, path: aliases[index], children: [] });
|
|
79
|
+
}
|
|
80
|
+
const sourceChildren = Array.isArray(source.children) ? source.children : [];
|
|
81
|
+
for (let index = sourceChildren.length - 1; index >= 0; index -= 1) {
|
|
82
|
+
queue.push({ source: sourceChildren[index], target: children });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return roots;
|
|
86
|
+
};
|
|
87
|
+
export const normalizeChmManifest = (value) => {
|
|
88
|
+
var _a, _b, _c, _d, _e, _f;
|
|
89
|
+
const source = value && typeof value === 'object' ? value : {};
|
|
90
|
+
const topics = Array.isArray(source.topics)
|
|
91
|
+
? source.topics.map(normalizeTopic).filter((topic) => Boolean(topic))
|
|
92
|
+
: [];
|
|
93
|
+
return {
|
|
94
|
+
title: stringValue(source.title),
|
|
95
|
+
homePath: stringValue((_a = source.homePath) !== null && _a !== void 0 ? _a : source.home_path),
|
|
96
|
+
encoding: stringValue(source.encoding) || 'windows-1252',
|
|
97
|
+
language: stringValue(source.language) || undefined,
|
|
98
|
+
topics,
|
|
99
|
+
contents: normalizeNavigationNodes((_b = source.contents) !== null && _b !== void 0 ? _b : source.toc),
|
|
100
|
+
index: normalizeNavigationNodes((_c = source.index) !== null && _c !== void 0 ? _c : source.keywords),
|
|
101
|
+
hasBinaryToc: booleanValue((_d = source.hasBinaryToc) !== null && _d !== void 0 ? _d : source.has_binary_toc),
|
|
102
|
+
hasBinaryIndex: booleanValue((_e = source.hasBinaryIndex) !== null && _e !== void 0 ? _e : source.has_binary_index),
|
|
103
|
+
hasFullTextIndex: booleanValue((_f = source.hasFullTextIndex) !== null && _f !== void 0 ? _f : source.has_full_text_index)
|
|
104
|
+
|| Boolean(source.fullTextIndex && typeof source.fullTextIndex === 'object'
|
|
105
|
+
&& source.fullTextIndex.available),
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
export const normalizeChmEntries = (value) => {
|
|
109
|
+
if (!Array.isArray(value))
|
|
110
|
+
return [];
|
|
111
|
+
return value.flatMap(item => {
|
|
112
|
+
var _a, _b, _c, _d;
|
|
113
|
+
if (!item || typeof item !== 'object')
|
|
114
|
+
return [];
|
|
115
|
+
const source = item;
|
|
116
|
+
const path = stringValue(source.path || source.name);
|
|
117
|
+
if (!path)
|
|
118
|
+
return [];
|
|
119
|
+
return [{
|
|
120
|
+
path,
|
|
121
|
+
size: (_d = numberValue((_c = (_b = (_a = source.size) !== null && _a !== void 0 ? _a : source.length) !== null && _b !== void 0 ? _b : source.byteLength) !== null && _c !== void 0 ? _c : source.byte_length)) !== null && _d !== void 0 ? _d : 0,
|
|
122
|
+
section: numberValue(source.section),
|
|
123
|
+
}];
|
|
124
|
+
});
|
|
125
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare const MAX_CHM_HTML_TEXT_LENGTH: number;
|
|
2
|
+
export declare const MAX_CHM_HTML_MARKUP_TOKENS = 100000;
|
|
3
|
+
export declare const MAX_CHM_SVG_TEXT_LENGTH: number;
|
|
4
|
+
export declare const MAX_CHM_SVG_MARKUP_TOKENS = 50000;
|
|
5
|
+
export declare const MAX_CHM_CSS_TEXT_LENGTH: number;
|
|
6
|
+
export declare const MAX_CHM_SEARCH_TEXT_LENGTH: number;
|
|
7
|
+
export interface ChmResolvedReference {
|
|
8
|
+
kind: 'internal' | 'fragment' | 'external' | 'data' | 'blocked';
|
|
9
|
+
path?: string;
|
|
10
|
+
fragment?: string;
|
|
11
|
+
url?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface SanitizedChmHtmlDocument {
|
|
14
|
+
document: Document;
|
|
15
|
+
html: string;
|
|
16
|
+
title: string;
|
|
17
|
+
resourcePaths: string[];
|
|
18
|
+
}
|
|
19
|
+
export declare const assertChmMarkupBudget: (source: string, maxLength: number, maxTokens: number, kind: "HTML" | "SVG") => void;
|
|
20
|
+
export declare const assertChmSvgSourceSafety: (source: string) => void;
|
|
21
|
+
export declare const normalizeChmPath: (input: string) => string | null;
|
|
22
|
+
export declare const resolveChmReference: (basePath: string, rawUrl: string) => ChmResolvedReference;
|
|
23
|
+
export declare const decodeChmText: (bytes: Uint8Array, fallbackEncoding?: string) => string;
|
|
24
|
+
/** Extract searchable topic text without DOM APIs or backtracking regular expressions. */
|
|
25
|
+
export declare const extractChmSearchText: (html: string, maxOutputLength?: number) => string;
|
|
26
|
+
export declare const MAX_CHM_TOPIC_RESOURCE_PATHS = 2048;
|
|
27
|
+
export declare const MAX_CHM_CSS_RESOURCE_PATHS = 1024;
|
|
28
|
+
export declare const sanitizeChmCss: (css: string, basePath: string, maxResourcePaths?: number) => {
|
|
29
|
+
css: string;
|
|
30
|
+
resourcePaths: string[];
|
|
31
|
+
};
|
|
32
|
+
export declare const sanitizeChmHtmlDocument: (html: string, basePath: string, serialize?: boolean) => SanitizedChmHtmlDocument;
|
|
33
|
+
export declare const CHM_INTERNAL_RESOURCE_SCHEME = "chm-internal:";
|