@file-viewer/core 2.2.9 → 2.4.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/dist/contracts/types.d.ts +80 -4
- package/dist/headless.d.ts +5 -5
- package/dist/headless.js +3 -3
- package/dist/i18n/messages.d.ts +3 -2
- package/dist/i18n/messages.de.d.ts +6 -0
- package/dist/i18n/messages.de.js +455 -0
- package/dist/i18n/messages.ja.js +15 -0
- package/dist/i18n/messages.js +36 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +3 -3
- package/dist/platform/assets.d.ts +16 -2
- package/dist/platform/assets.js +109 -18
- package/dist/registry/capabilities.d.ts +2 -2
- package/dist/registry/formats.d.ts +5 -331
- package/dist/registry/formats.generated.d.ts +613 -0
- package/dist/registry/formats.generated.js +1125 -0
- package/dist/registry/formats.js +10 -224
- package/dist/renderers/index.d.ts +285 -2
- package/dist/rendering/dispatcher.d.ts +9 -0
- package/dist/rendering/dispatcher.js +7 -0
- package/dist/rendering/handler.d.ts +1 -1
- package/dist/rendering/handler.js +35 -2
- package/dist/source/index.d.ts +2 -0
- package/dist/source/index.js +1 -0
- package/dist/source/textEncoding.d.ts +14 -0
- package/dist/source/textEncoding.js +156 -0
- package/dist/viewer/state.js +9 -4
- package/package.json +1 -1
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
const normalizeEncoding = (encoding) => {
|
|
2
|
+
const normalized = String(encoding || 'auto').trim().toLowerCase().replace('_', '-');
|
|
3
|
+
if (normalized === 'utf8' || normalized === 'utf-8') {
|
|
4
|
+
return 'utf-8';
|
|
5
|
+
}
|
|
6
|
+
if (normalized === 'utf16' || normalized === 'utf-16' || normalized === 'utf16le' || normalized === 'utf-16le') {
|
|
7
|
+
return 'utf-16le';
|
|
8
|
+
}
|
|
9
|
+
if (normalized === 'utf16be' || normalized === 'utf-16be') {
|
|
10
|
+
return 'utf-16be';
|
|
11
|
+
}
|
|
12
|
+
if (normalized === 'gbk' || normalized === 'cp936' || normalized === 'gb2312') {
|
|
13
|
+
return 'gbk';
|
|
14
|
+
}
|
|
15
|
+
if (normalized === 'gb18030') {
|
|
16
|
+
return 'gb18030';
|
|
17
|
+
}
|
|
18
|
+
return 'auto';
|
|
19
|
+
};
|
|
20
|
+
const isContinuationByte = (value) => {
|
|
21
|
+
return value !== undefined && value >= 0x80 && value <= 0xbf;
|
|
22
|
+
};
|
|
23
|
+
// Validate bytes directly because older WebViews can accept the fatal option
|
|
24
|
+
// while still replacing malformed input. That would hide the GB18030 fallback.
|
|
25
|
+
export const isValidFileViewerUtf8 = (bytes) => {
|
|
26
|
+
for (let index = 0; index < bytes.length;) {
|
|
27
|
+
const first = bytes[index];
|
|
28
|
+
if (first === undefined) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
if (first <= 0x7f) {
|
|
32
|
+
index += 1;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
const second = bytes[index + 1];
|
|
36
|
+
const third = bytes[index + 2];
|
|
37
|
+
const fourth = bytes[index + 3];
|
|
38
|
+
if (first >= 0xc2 && first <= 0xdf && isContinuationByte(second)) {
|
|
39
|
+
index += 2;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (first === 0xe0 &&
|
|
43
|
+
second !== undefined && second >= 0xa0 && second <= 0xbf &&
|
|
44
|
+
isContinuationByte(third)) {
|
|
45
|
+
index += 3;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (((first >= 0xe1 && first <= 0xec) || (first >= 0xee && first <= 0xef)) &&
|
|
49
|
+
isContinuationByte(second) &&
|
|
50
|
+
isContinuationByte(third)) {
|
|
51
|
+
index += 3;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (first === 0xed &&
|
|
55
|
+
second !== undefined && second >= 0x80 && second <= 0x9f &&
|
|
56
|
+
isContinuationByte(third)) {
|
|
57
|
+
index += 3;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (first === 0xf0 &&
|
|
61
|
+
second !== undefined && second >= 0x90 && second <= 0xbf &&
|
|
62
|
+
isContinuationByte(third) &&
|
|
63
|
+
isContinuationByte(fourth)) {
|
|
64
|
+
index += 4;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (first >= 0xf1 && first <= 0xf3 &&
|
|
68
|
+
isContinuationByte(second) &&
|
|
69
|
+
isContinuationByte(third) &&
|
|
70
|
+
isContinuationByte(fourth)) {
|
|
71
|
+
index += 4;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (first === 0xf4 &&
|
|
75
|
+
second !== undefined && second >= 0x80 && second <= 0x8f &&
|
|
76
|
+
isContinuationByte(third) &&
|
|
77
|
+
isContinuationByte(fourth)) {
|
|
78
|
+
index += 4;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
return true;
|
|
84
|
+
};
|
|
85
|
+
const inferBomlessUtf16 = (bytes) => {
|
|
86
|
+
const sampleLength = Math.min(bytes.length - (bytes.length % 2), 4096);
|
|
87
|
+
if (sampleLength < 4) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
let evenNulls = 0;
|
|
91
|
+
let oddNulls = 0;
|
|
92
|
+
for (let index = 0; index < sampleLength; index += 2) {
|
|
93
|
+
evenNulls += bytes[index] === 0 ? 1 : 0;
|
|
94
|
+
oddNulls += bytes[index + 1] === 0 ? 1 : 0;
|
|
95
|
+
}
|
|
96
|
+
const pairs = sampleLength / 2;
|
|
97
|
+
if (oddNulls / pairs >= 0.3 && evenNulls / pairs <= 0.05) {
|
|
98
|
+
return 'utf-16le';
|
|
99
|
+
}
|
|
100
|
+
if (evenNulls / pairs >= 0.3 && oddNulls / pairs <= 0.05) {
|
|
101
|
+
return 'utf-16be';
|
|
102
|
+
}
|
|
103
|
+
return null;
|
|
104
|
+
};
|
|
105
|
+
export const resolveFileViewerTextEncoding = (bytes, encoding = 'auto') => {
|
|
106
|
+
const normalized = normalizeEncoding(encoding);
|
|
107
|
+
if (normalized !== 'auto') {
|
|
108
|
+
return {
|
|
109
|
+
encoding: normalized === 'gbk' ? 'gb18030' : normalized,
|
|
110
|
+
bomLength: normalized === 'utf-8' && bytes[0] === 0xef && bytes[1] === 0xbb && bytes[2] === 0xbf
|
|
111
|
+
? 3
|
|
112
|
+
: (normalized === 'utf-16le' && bytes[0] === 0xff && bytes[1] === 0xfe) ||
|
|
113
|
+
(normalized === 'utf-16be' && bytes[0] === 0xfe && bytes[1] === 0xff)
|
|
114
|
+
? 2
|
|
115
|
+
: 0
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
if (bytes[0] === 0xef && bytes[1] === 0xbb && bytes[2] === 0xbf) {
|
|
119
|
+
return { encoding: 'utf-8', bomLength: 3 };
|
|
120
|
+
}
|
|
121
|
+
if (bytes[0] === 0xff && bytes[1] === 0xfe) {
|
|
122
|
+
return { encoding: 'utf-16le', bomLength: 2 };
|
|
123
|
+
}
|
|
124
|
+
if (bytes[0] === 0xfe && bytes[1] === 0xff) {
|
|
125
|
+
return { encoding: 'utf-16be', bomLength: 2 };
|
|
126
|
+
}
|
|
127
|
+
const utf16 = inferBomlessUtf16(bytes);
|
|
128
|
+
if (utf16) {
|
|
129
|
+
return { encoding: utf16, bomLength: 0 };
|
|
130
|
+
}
|
|
131
|
+
return isValidFileViewerUtf8(bytes)
|
|
132
|
+
? { encoding: 'utf-8', bomLength: 0 }
|
|
133
|
+
: { encoding: 'gb18030', bomLength: 0 };
|
|
134
|
+
};
|
|
135
|
+
export const createFileViewerTextDecoder = (encoding) => {
|
|
136
|
+
if (typeof TextDecoder === 'undefined') {
|
|
137
|
+
throw new Error('Text decoding requires the browser TextDecoder API.');
|
|
138
|
+
}
|
|
139
|
+
try {
|
|
140
|
+
return new TextDecoder(encoding);
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
if (encoding === 'gb18030' && error instanceof RangeError) {
|
|
144
|
+
throw Object.assign(new Error('This browser does not provide GB18030 text decoding. Use a current browser or select UTF-8 explicitly.'), { cause: error });
|
|
145
|
+
}
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
export const decodeFileViewerTextBuffer = (data, encoding = 'auto') => {
|
|
150
|
+
const bytes = new Uint8Array(data);
|
|
151
|
+
const resolved = resolveFileViewerTextEncoding(bytes, encoding);
|
|
152
|
+
return {
|
|
153
|
+
text: createFileViewerTextDecoder(resolved.encoding).decode(bytes.subarray(resolved.bomLength)),
|
|
154
|
+
encoding: resolved.encoding
|
|
155
|
+
};
|
|
156
|
+
};
|
package/dist/viewer/state.js
CHANGED
|
@@ -31,6 +31,9 @@ const extensionLabel = (extension, i18n) => {
|
|
|
31
31
|
if (locale === 'ja-JP') {
|
|
32
32
|
return '現在のファイル';
|
|
33
33
|
}
|
|
34
|
+
if (locale === 'de-DE') {
|
|
35
|
+
return 'aktuelle Datei';
|
|
36
|
+
}
|
|
34
37
|
return 'current file';
|
|
35
38
|
};
|
|
36
39
|
const rendererPackageById = {
|
|
@@ -178,7 +181,9 @@ export const createFileViewerUnsupportedState = (extension = '', theme = DEFAULT
|
|
|
178
181
|
? `;如果需要极致裁剪,也可以只安装 ${installHint.rendererPackage}`
|
|
179
182
|
: locale === 'ja-JP'
|
|
180
183
|
? `;厳密に最小構成へ絞る場合は ${installHint.rendererPackage} のみをインストールすることもできます`
|
|
181
|
-
:
|
|
184
|
+
: locale === 'de-DE'
|
|
185
|
+
? `; für eine strikt minimale Konfiguration installieren Sie nur ${installHint.rendererPackage}`
|
|
186
|
+
: `; for a strict custom cut, install only ${installHint.rendererPackage}`
|
|
182
187
|
: '';
|
|
183
188
|
return createFileViewerStateDescriptor({
|
|
184
189
|
state: 'unsupported',
|
|
@@ -270,9 +275,9 @@ export const formatFileViewerErrorMessage = (prefix, error, i18n) => {
|
|
|
270
275
|
if (!detail) {
|
|
271
276
|
return prefix;
|
|
272
277
|
}
|
|
273
|
-
return resolveFileViewerLocale(i18n) === '
|
|
274
|
-
? `${prefix}
|
|
275
|
-
: `${prefix}
|
|
278
|
+
return resolveFileViewerLocale(i18n) === 'zh-CN' || resolveFileViewerLocale(i18n) === 'ja-JP'
|
|
279
|
+
? `${prefix}:${detail}`
|
|
280
|
+
: `${prefix}: ${detail}`;
|
|
276
281
|
};
|
|
277
282
|
export const createFileViewerErrorState = (extension = '', error = undefined, theme = DEFAULT_FILE_VIEWER_STATE_THEME, i18n) => createFileViewerStateDescriptor({
|
|
278
283
|
state: 'error',
|
package/package.json
CHANGED