Branch data Line data Source code
1 : 48 : // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
2 : : // SPDX-FileCopyrightText: 2021 Evan Welsh <contact@evanwelsh.com>
3 : :
4 : : import {trimAsciiWhitespace} from './util.js';
5 : :
6 : : // Data derived from https://encoding.spec.whatwg.org/encodings.json
7 : 48 : const encodingMap = {
8 : 48 : 'utf-8': [
9 : : 'unicode-1-1-utf-8',
10 : : 'unicode11utf8',
11 : : 'unicode20utf8',
12 : : 'utf-8',
13 : : 'utf8',
14 : : 'x-unicode20utf8',
15 : : ],
16 : 48 : ibm866: ['866', 'cp866', 'csibm866', 'ibm866'],
17 : 48 : 'iso-8859-2': [
18 : : 'csisolatin2',
19 : : 'iso-8859-2',
20 : : 'iso-ir-101',
21 : : 'iso8859-2',
22 : : 'iso88592',
23 : : 'iso_8859-2',
24 : : 'iso_8859-2:1987',
25 : : 'l2',
26 : : 'latin2',
27 : : ],
28 : 48 : 'iso-8859-3': [
29 : : 'csisolatin3',
30 : : 'iso-8859-3',
31 : : 'iso-ir-109',
32 : : 'iso8859-3',
33 : : 'iso88593',
34 : : 'iso_8859-3',
35 : : 'iso_8859-3:1988',
36 : : 'l3',
37 : : 'latin3',
38 : : ],
39 : 48 : 'iso-8859-4': [
40 : : 'csisolatin4',
41 : : 'iso-8859-4',
42 : : 'iso-ir-110',
43 : : 'iso8859-4',
44 : : 'iso88594',
45 : : 'iso_8859-4',
46 : : 'iso_8859-4:1988',
47 : : 'l4',
48 : : 'latin4',
49 : : ],
50 : 48 : 'iso-8859-5': [
51 : : 'csisolatincyrillic',
52 : : 'cyrillic',
53 : : 'iso-8859-5',
54 : : 'iso-ir-144',
55 : : 'iso8859-5',
56 : : 'iso88595',
57 : : 'iso_8859-5',
58 : : 'iso_8859-5:1988',
59 : : ],
60 : 48 : 'iso-8859-6': [
61 : : 'arabic',
62 : : 'asmo-708',
63 : : 'csiso88596e',
64 : : 'csiso88596i',
65 : : 'csisolatinarabic',
66 : : 'ecma-114',
67 : : 'iso-8859-6',
68 : : 'iso-8859-6-e',
69 : : 'iso-8859-6-i',
70 : : 'iso-ir-127',
71 : : 'iso8859-6',
72 : : 'iso88596',
73 : : 'iso_8859-6',
74 : : 'iso_8859-6:1987',
75 : : ],
76 : 48 : 'iso-8859-7': [
77 : : 'csisolatingreek',
78 : : 'ecma-118',
79 : : 'elot_928',
80 : : 'greek',
81 : : 'greek8',
82 : : 'iso-8859-7',
83 : : 'iso-ir-126',
84 : : 'iso8859-7',
85 : : 'iso88597',
86 : : 'iso_8859-7',
87 : : 'iso_8859-7:1987',
88 : : 'sun_eu_greek',
89 : : ],
90 : 48 : 'iso-8859-8': [
91 : : 'csiso88598e',
92 : : 'csisolatinhebrew',
93 : : 'hebrew',
94 : : 'iso-8859-8',
95 : : 'iso-8859-8-e',
96 : : 'iso-ir-138',
97 : : 'iso8859-8',
98 : : 'iso88598',
99 : : 'iso_8859-8',
100 : : 'iso_8859-8:1988',
101 : : 'visual',
102 : : ],
103 : 48 : 'iso-8859-8-i': ['csiso88598i', 'iso-8859-8-i', 'logical'],
104 : 48 : 'iso-8859-10': [
105 : : 'csisolatin6',
106 : : 'iso-8859-10',
107 : : 'iso-ir-157',
108 : : 'iso8859-10',
109 : : 'iso885910',
110 : : 'l6',
111 : : 'latin6',
112 : : ],
113 : 48 : 'iso-8859-13': ['iso-8859-13', 'iso8859-13', 'iso885913'],
114 : 48 : 'iso-8859-14': ['iso-8859-14', 'iso8859-14', 'iso885914'],
115 : 48 : 'iso-8859-15': [
116 : : 'csisolatin9',
117 : : 'iso-8859-15',
118 : : 'iso8859-15',
119 : : 'iso885915',
120 : : 'iso_8859-15',
121 : : 'l9',
122 : : ],
123 : 48 : 'iso-8859-16': ['iso-8859-16'],
124 : 48 : 'koi8-r': ['cskoi8r', 'koi', 'koi8', 'koi8-r', 'koi8_r'],
125 : 48 : 'koi8-u': ['koi8-ru', 'koi8-u'],
126 : 48 : macintosh: ['csmacintosh', 'mac', 'macintosh', 'x-mac-roman'],
127 : 48 : 'windows-874': [
128 : : 'dos-874',
129 : : 'iso-8859-11',
130 : : 'iso8859-11',
131 : : 'iso885911',
132 : : 'tis-620',
133 : : 'windows-874',
134 : : ],
135 : 48 : 'windows-1250': ['cp1250', 'windows-1250', 'x-cp1250'],
136 : 48 : 'windows-1251': ['cp1251', 'windows-1251', 'x-cp1251'],
137 : 48 : 'windows-1252': [
138 : : 'ansi_x3.4-1968',
139 : : 'ascii',
140 : : 'cp1252',
141 : : 'cp819',
142 : : 'csisolatin1',
143 : : 'ibm819',
144 : : 'iso-8859-1',
145 : : 'iso-ir-100',
146 : : 'iso8859-1',
147 : : 'iso88591',
148 : : 'iso_8859-1',
149 : : 'iso_8859-1:1987',
150 : : 'l1',
151 : : 'latin1',
152 : : 'us-ascii',
153 : : 'windows-1252',
154 : : 'x-cp1252',
155 : : ],
156 : 48 : 'windows-1253': ['cp1253', 'windows-1253', 'x-cp1253'],
157 : 48 : 'windows-1254': [
158 : : 'cp1254',
159 : : 'csisolatin5',
160 : : 'iso-8859-9',
161 : : 'iso-ir-148',
162 : : 'iso8859-9',
163 : : 'iso88599',
164 : : 'iso_8859-9',
165 : : 'iso_8859-9:1989',
166 : : 'l5',
167 : : 'latin5',
168 : : 'windows-1254',
169 : : 'x-cp1254',
170 : : ],
171 : 48 : 'windows-1255': ['cp1255', 'windows-1255', 'x-cp1255'],
172 : 48 : 'windows-1256': ['cp1256', 'windows-1256', 'x-cp1256'],
173 : 48 : 'windows-1257': ['cp1257', 'windows-1257', 'x-cp1257'],
174 : 48 : 'windows-1258': ['cp1258', 'windows-1258', 'x-cp1258'],
175 : 48 : 'x-mac-cyrillic': ['x-mac-cyrillic', 'x-mac-ukrainian'],
176 : 48 : gbk: [
177 : : 'chinese',
178 : : 'csgb2312',
179 : : 'csiso58gb231280',
180 : : 'gb2312',
181 : : 'gb_2312',
182 : : 'gb_2312-80',
183 : : 'gbk',
184 : : 'iso-ir-58',
185 : : 'x-gbk',
186 : : ],
187 : 48 : gb18030: ['gb18030'],
188 : 48 : big5: [
189 : : 'big5',
190 : : // Unlike the standard WHATWG encoder
191 : : // the Hong Kong Supplementary Character Set
192 : : // is not bundled in big5 by iconv
193 : : // "big5-hkscs",
194 : : 'cn-big5',
195 : : 'csbig5',
196 : : 'x-x-big5',
197 : : ],
198 : 48 : 'euc-jp': ['cseucpkdfmtjapanese', 'euc-jp', 'x-euc-jp'],
199 : 48 : 'iso-2022-jp': ['csiso2022jp', 'iso-2022-jp'],
200 : 48 : shift_jis: [
201 : : 'csshiftjis',
202 : : 'ms932',
203 : : 'ms_kanji',
204 : : 'shift-jis',
205 : : 'shift_jis',
206 : : 'sjis',
207 : : 'windows-31j',
208 : : 'x-sjis',
209 : : ],
210 : 48 : 'euc-kr': [
211 : : 'cseuckr',
212 : : 'csksc56011987',
213 : : 'euc-kr',
214 : : 'iso-ir-149',
215 : : 'korean',
216 : : 'ks_c_5601-1987',
217 : : 'ks_c_5601-1989',
218 : : 'ksc5601',
219 : : 'ksc_5601',
220 : : 'windows-949',
221 : : ],
222 : 48 : 'utf-16be': ['unicodefffe', 'utf-16be'],
223 : 48 : 'utf-16le': [
224 : : 'csunicode',
225 : : 'iso-10646-ucs-2',
226 : : 'ucs-2',
227 : : 'unicode',
228 : : 'unicodefeff',
229 : : 'utf-16',
230 : : 'utf-16le',
231 : : ],
232 : : };
233 : :
234 : : /**
235 : : * Construct a map from each potential label to the canonical label
236 : : * for an encoding.
237 : : */
238 : 96 : const encodings = new Map(
239 [ + - ][ + - ]: 1872 : Object.entries(encodingMap).flatMap(([encoding, labels]) => {
[ + - ][ + - ]
240 : 12384 : return labels.map(label => [label, encoding]);
241 : : })
242 : : );
243 : :
244 : : // Maps WHATWG specified labels to the appropriate iconv
245 : : // encoding label if iconv does not support the WHATWG label.
246 : : //
247 : : // Mapping here preserves the WHATWG as the label on the
248 : : // TextDecoder so this change is transparent to API users.
249 : 96 : const internalEncodings = new Map([
250 : : // iso-8859-8-i is functionally equivalent to iso-8859-8
251 : : // as we are not encoding or decoding control characters.
252 : 48 : ['iso-8859-8-i', 'iso-8859-8'],
253 : : // iconv follows a different naming convention for this
254 : : // encoding
255 : 48 : ['x-mac-cyrillic', 'MacCyrillic'],
256 : : // Support HKSCS as a standalone encoding, iconv doesn't
257 : : // bundle it with Big5 like WHATWG does...
258 : 48 : ['big5-hkscs', 'big5-hkscs'],
259 : : ]);
260 : :
261 : : /**
262 : : * @typedef Encoding
263 : : * @property {string} internalLabel
264 : : * @property {string} label
265 : : */
266 : :
267 : : /**
268 : : * @param {string} label the encoding label
269 : : * @returns {Encoding | null}
270 : : */
271 : 347 : export function getEncodingFromLabel(label) {
272 : 347 : const formattedLabel = trimAsciiWhitespace(label.toLowerCase());
273 : :
274 : 347 : let canonicalLabel = encodings.get(formattedLabel);
275 : :
276 : : // Lookup an internal mapping using the canonical name, if found, or
277 : : // the formatted label otherwise.
278 : : //
279 : : // x-mac-ukrainian > x-mac-cyrillic > MacCyrillic
280 : : // (canonical label) (internal label)
281 : : //
282 : : // big5-hkscs > undefined > big5-hkscs
283 : : // (canonical label) (internal label)
284 : : //
285 : 694 : let internalLabel = internalEncodings.get(
286 [ + + ]: 347 : canonicalLabel ?? formattedLabel
287 : : );
288 : :
289 : : // If both the canonical label and the internal encoding
290 : : // are not found, this encoding is unsupported.
291 [ + + ][ + + ]: 347 : if (!canonicalLabel && !internalLabel)
292 : 1 : return null;
293 : :
294 [ + + ]: 346 : if (internalLabel) {
295 : 6 : return {
296 [ + + ]: 6 : label: canonicalLabel ?? formattedLabel,
297 : 6 : internalLabel,
298 : : };
299 : : }
300 : :
301 : 340 : return {
302 : 340 : label: canonicalLabel,
303 : 340 : internalLabel: canonicalLabel,
304 : : };
305 : 347 : }
|