frond-js 0.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/LICENSE +21 -0
- package/README.en.md +247 -0
- package/README.md +211 -0
- package/dist/abort-BY8vBk0v.d.cts +99 -0
- package/dist/abort-BY8vBk0v.d.ts +99 -0
- package/dist/adapter-3G46J3CA.cjs +503 -0
- package/dist/adapter-3ONQWJVQ.js +501 -0
- package/dist/adapter-55QHWRSE.js +124 -0
- package/dist/adapter-DF34GBWJ.cjs +19 -0
- package/dist/adapter-EXTNILTC.cjs +126 -0
- package/dist/adapter-GOFC7TMC.js +284 -0
- package/dist/adapter-LRJTQ47I.cjs +286 -0
- package/dist/adapter-TWWZML4A.js +17 -0
- package/dist/adapter-ZM5FQTJT.js +1415 -0
- package/dist/adapter-ZRNSDQUV.cjs +1417 -0
- package/dist/chunk-2SUG7YFZ.cjs +108 -0
- package/dist/chunk-B2L2YVXD.js +89 -0
- package/dist/chunk-D4KWSEZD.js +393 -0
- package/dist/chunk-EZTIZO6R.cjs +430 -0
- package/dist/chunk-G7DLWGBW.cjs +103 -0
- package/dist/chunk-GTGLDLJD.cjs +479 -0
- package/dist/chunk-IIV6VIUJ.cjs +83 -0
- package/dist/chunk-JDTHZQUK.js +102 -0
- package/dist/chunk-JJVXT3AC.js +30 -0
- package/dist/chunk-LIXRYQL2.js +473 -0
- package/dist/chunk-NABYHI6X.cjs +400 -0
- package/dist/chunk-SJVOYNTF.js +425 -0
- package/dist/chunk-SLI2YL25.cjs +252 -0
- package/dist/chunk-U4264IQH.js +78 -0
- package/dist/chunk-UY2YRCFC.js +250 -0
- package/dist/chunk-WCZTTQ7Z.cjs +32 -0
- package/dist/core/index.cjs +162 -0
- package/dist/core/index.d.cts +321 -0
- package/dist/core/index.d.ts +321 -0
- package/dist/core/index.js +49 -0
- package/dist/default-DRLIJX73.js +1183 -0
- package/dist/default-UK52WOO5.cjs +1192 -0
- package/dist/formats/epub/index.cjs +29 -0
- package/dist/formats/epub/index.d.cts +286 -0
- package/dist/formats/epub/index.d.ts +286 -0
- package/dist/formats/epub/index.js +11 -0
- package/dist/index.cjs +655 -0
- package/dist/index.d.cts +335 -0
- package/dist/index.d.ts +335 -0
- package/dist/index.js +600 -0
- package/dist/render/index.cjs +2 -0
- package/dist/render/index.d.cts +116 -0
- package/dist/render/index.d.ts +116 -0
- package/dist/render/index.js +1 -0
- package/dist/types-B76GOMxj.d.ts +129 -0
- package/dist/types-B7mslPBY.d.cts +166 -0
- package/dist/types-B7mslPBY.d.ts +166 -0
- package/dist/types-BH88rUYt.d.cts +129 -0
- package/dist/types-C-5eHSRH.d.ts +379 -0
- package/dist/types-CPUqTEPW.d.cts +379 -0
- package/dist/types-DQYmArgv.d.cts +17 -0
- package/dist/types-DQYmArgv.d.ts +17 -0
- package/package.json +115 -0
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkG7DLWGBW_cjs = require('./chunk-G7DLWGBW.cjs');
|
|
4
|
+
|
|
5
|
+
// src/core/xml/parse.ts
|
|
6
|
+
var PREDEFINED_ENTITIES = /* @__PURE__ */ new Map([
|
|
7
|
+
["lt", "<"],
|
|
8
|
+
["gt", ">"],
|
|
9
|
+
["amp", "&"],
|
|
10
|
+
["quot", '"'],
|
|
11
|
+
["apos", "'"]
|
|
12
|
+
]);
|
|
13
|
+
var COMMENT_OPEN = "<!--";
|
|
14
|
+
var COMMENT_CLOSE = "-->";
|
|
15
|
+
var CDATA_OPEN = "<![CDATA[";
|
|
16
|
+
var CDATA_CLOSE = "]]>";
|
|
17
|
+
var DOCTYPE_OPEN = "<!DOCTYPE";
|
|
18
|
+
var PROCESSING_INSTRUCTION_CLOSE = "?>";
|
|
19
|
+
var CODE_TAB = 9;
|
|
20
|
+
var CODE_LF = 10;
|
|
21
|
+
var CODE_CR = 13;
|
|
22
|
+
var CODE_SPACE = 32;
|
|
23
|
+
var CODE_BANG = 33;
|
|
24
|
+
var CODE_QUOTE = 34;
|
|
25
|
+
var CODE_HASH = 35;
|
|
26
|
+
var CODE_APOS = 39;
|
|
27
|
+
var CODE_SLASH = 47;
|
|
28
|
+
var CODE_LT = 60;
|
|
29
|
+
var CODE_EQ = 61;
|
|
30
|
+
var CODE_GT = 62;
|
|
31
|
+
var CODE_QUESTION = 63;
|
|
32
|
+
var CODE_OPEN_BRACKET = 91;
|
|
33
|
+
var CODE_CLOSE_BRACKET = 93;
|
|
34
|
+
var CODE_LOWER_X = 120;
|
|
35
|
+
var CODE_BOM = 65279;
|
|
36
|
+
var MAX_CODE_POINT = 1114111;
|
|
37
|
+
var DEFAULT_MAX_DEPTH = 512;
|
|
38
|
+
function isWhitespaceCode(code) {
|
|
39
|
+
return code === CODE_SPACE || code === CODE_TAB || code === CODE_LF || code === CODE_CR;
|
|
40
|
+
}
|
|
41
|
+
function isNameTerminator(code) {
|
|
42
|
+
return Number.isNaN(code) || isWhitespaceCode(code) || code === CODE_LT || code === CODE_GT || code === CODE_SLASH || code === CODE_EQ || code === CODE_QUESTION || code === CODE_QUOTE || code === CODE_APOS || code === CODE_BANG;
|
|
43
|
+
}
|
|
44
|
+
function normalizeNewlines(value) {
|
|
45
|
+
return value.includes("\r") ? value.replace(/\r\n?/g, "\n") : value;
|
|
46
|
+
}
|
|
47
|
+
function parseDecimalDigits(text) {
|
|
48
|
+
if (text === "") return void 0;
|
|
49
|
+
let value = 0;
|
|
50
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
51
|
+
const code = text.charCodeAt(index);
|
|
52
|
+
if (code < 48 || code > 57) return void 0;
|
|
53
|
+
value = value * 10 + (code - 48);
|
|
54
|
+
if (value > MAX_CODE_POINT) return void 0;
|
|
55
|
+
}
|
|
56
|
+
return value;
|
|
57
|
+
}
|
|
58
|
+
function parseHexDigits(text) {
|
|
59
|
+
if (text === "") return void 0;
|
|
60
|
+
let value = 0;
|
|
61
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
62
|
+
const code = text.charCodeAt(index);
|
|
63
|
+
let digit;
|
|
64
|
+
if (code >= 48 && code <= 57) {
|
|
65
|
+
digit = code - 48;
|
|
66
|
+
} else if (code >= 97 && code <= 102) {
|
|
67
|
+
digit = code - 97 + 10;
|
|
68
|
+
} else if (code >= 65 && code <= 70) {
|
|
69
|
+
digit = code - 65 + 10;
|
|
70
|
+
} else {
|
|
71
|
+
return void 0;
|
|
72
|
+
}
|
|
73
|
+
value = value * 16 + digit;
|
|
74
|
+
if (value > MAX_CODE_POINT) return void 0;
|
|
75
|
+
}
|
|
76
|
+
return value;
|
|
77
|
+
}
|
|
78
|
+
function decodeReference(body) {
|
|
79
|
+
if (body === "") return void 0;
|
|
80
|
+
if (body.charCodeAt(0) !== CODE_HASH) return PREDEFINED_ENTITIES.get(body);
|
|
81
|
+
const digits = body.slice(1);
|
|
82
|
+
if (digits === "") return void 0;
|
|
83
|
+
let codePoint;
|
|
84
|
+
if (digits.charCodeAt(0) === CODE_LOWER_X) {
|
|
85
|
+
codePoint = parseHexDigits(digits.slice(1));
|
|
86
|
+
} else {
|
|
87
|
+
codePoint = parseDecimalDigits(digits);
|
|
88
|
+
}
|
|
89
|
+
if (codePoint === void 0 || codePoint > MAX_CODE_POINT) return void 0;
|
|
90
|
+
return String.fromCodePoint(codePoint);
|
|
91
|
+
}
|
|
92
|
+
function decodeEntities(raw) {
|
|
93
|
+
if (!raw.includes("&")) return raw;
|
|
94
|
+
let result = "";
|
|
95
|
+
let cursor = 0;
|
|
96
|
+
for (; ; ) {
|
|
97
|
+
const amp = raw.indexOf("&", cursor);
|
|
98
|
+
if (amp === -1) return result + raw.slice(cursor);
|
|
99
|
+
result += raw.slice(cursor, amp);
|
|
100
|
+
const semicolon = raw.indexOf(";", amp + 1);
|
|
101
|
+
if (semicolon === -1) {
|
|
102
|
+
return result + raw.slice(amp);
|
|
103
|
+
}
|
|
104
|
+
const decoded = decodeReference(raw.slice(amp + 1, semicolon));
|
|
105
|
+
result += decoded ?? raw.slice(amp, semicolon + 1);
|
|
106
|
+
cursor = semicolon + 1;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function splitName(name) {
|
|
110
|
+
const colon = name.indexOf(":");
|
|
111
|
+
if (colon === -1) return { prefix: "", localName: name };
|
|
112
|
+
return { prefix: name.slice(0, colon), localName: name.slice(colon + 1) };
|
|
113
|
+
}
|
|
114
|
+
var XmlParser = class {
|
|
115
|
+
#source;
|
|
116
|
+
#label;
|
|
117
|
+
#maxDepth;
|
|
118
|
+
#pos = 0;
|
|
119
|
+
/** 当前**已进入**的元素层数(根元素为 0 → 进入后即 1)。由 `#parseElement` 维护。 */
|
|
120
|
+
#depth = 0;
|
|
121
|
+
constructor(source, label, maxDepth) {
|
|
122
|
+
this.#source = source;
|
|
123
|
+
this.#label = label;
|
|
124
|
+
this.#maxDepth = maxDepth;
|
|
125
|
+
}
|
|
126
|
+
parseDocument() {
|
|
127
|
+
if (this.#source.charCodeAt(0) === CODE_BOM) this.#pos = 1;
|
|
128
|
+
for (; ; ) {
|
|
129
|
+
this.#skipMisc();
|
|
130
|
+
if (this.#startsWith(DOCTYPE_OPEN)) {
|
|
131
|
+
this.#skipDoctype();
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
if (this.#atEnd()) this.#fail("\u6587\u6863\u7F3A\u5C11\u6839\u5143\u7D20", this.#pos);
|
|
137
|
+
const root = this.#parseElement();
|
|
138
|
+
this.#skipMisc();
|
|
139
|
+
if (!this.#atEnd()) this.#fail("\u6839\u5143\u7D20\u4E4B\u540E\u5B58\u5728\u591A\u4F59\u5185\u5BB9", this.#pos);
|
|
140
|
+
return root;
|
|
141
|
+
}
|
|
142
|
+
// -- 位置与错误 ----------------------------------------------------------
|
|
143
|
+
#atEnd() {
|
|
144
|
+
return this.#pos >= this.#source.length;
|
|
145
|
+
}
|
|
146
|
+
#startsWith(text) {
|
|
147
|
+
return this.#source.startsWith(text, this.#pos);
|
|
148
|
+
}
|
|
149
|
+
#skipWhitespace() {
|
|
150
|
+
while (isWhitespaceCode(this.#source.charCodeAt(this.#pos))) this.#pos += 1;
|
|
151
|
+
}
|
|
152
|
+
#fail(reason, offset) {
|
|
153
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`XML \u89E3\u6790\u5931\u8D25\uFF1A${reason}\uFF08\u6E90: ${this.#label}\uFF0C\u504F\u79FB ${String(offset)}\uFF09`);
|
|
154
|
+
}
|
|
155
|
+
// -- 跳过类构造 ----------------------------------------------------------
|
|
156
|
+
#skipMisc() {
|
|
157
|
+
for (; ; ) {
|
|
158
|
+
const code = this.#source.charCodeAt(this.#pos);
|
|
159
|
+
if (isWhitespaceCode(code)) {
|
|
160
|
+
this.#pos += 1;
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
if (this.#startsWith(COMMENT_OPEN)) {
|
|
164
|
+
this.#skipComment();
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (this.#startsWith("<?")) {
|
|
168
|
+
this.#skipProcessingInstruction();
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
#skipComment() {
|
|
175
|
+
const start = this.#pos;
|
|
176
|
+
const end = this.#source.indexOf(COMMENT_CLOSE, start + COMMENT_OPEN.length);
|
|
177
|
+
if (end === -1) this.#fail("\u6CE8\u91CA\u672A\u95ED\u5408", start);
|
|
178
|
+
this.#pos = end + COMMENT_CLOSE.length;
|
|
179
|
+
}
|
|
180
|
+
#skipProcessingInstruction() {
|
|
181
|
+
const start = this.#pos;
|
|
182
|
+
const end = this.#source.indexOf(PROCESSING_INSTRUCTION_CLOSE, start + 2);
|
|
183
|
+
if (end === -1) this.#fail("\u5904\u7406\u6307\u4EE4\u672A\u95ED\u5408", start);
|
|
184
|
+
this.#pos = end + PROCESSING_INSTRUCTION_CLOSE.length;
|
|
185
|
+
}
|
|
186
|
+
/** 跳过 DOCTYPE。内部子集用方括号计数,引号内的 `>` 不视为结束。 */
|
|
187
|
+
#skipDoctype() {
|
|
188
|
+
const start = this.#pos;
|
|
189
|
+
let index = start + DOCTYPE_OPEN.length;
|
|
190
|
+
let depth = 0;
|
|
191
|
+
while (index < this.#source.length) {
|
|
192
|
+
const code = this.#source.charCodeAt(index);
|
|
193
|
+
if (code === CODE_QUOTE || code === CODE_APOS) {
|
|
194
|
+
const close = this.#source.indexOf(String.fromCharCode(code), index + 1);
|
|
195
|
+
if (close === -1) this.#fail("DOCTYPE \u4E2D\u7684\u5F15\u53F7\u672A\u95ED\u5408", index);
|
|
196
|
+
index = close + 1;
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
if (code === CODE_OPEN_BRACKET) {
|
|
200
|
+
depth += 1;
|
|
201
|
+
} else if (code === CODE_CLOSE_BRACKET) {
|
|
202
|
+
depth -= 1;
|
|
203
|
+
} else if (code === CODE_GT && depth <= 0) {
|
|
204
|
+
this.#pos = index + 1;
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
index += 1;
|
|
208
|
+
}
|
|
209
|
+
this.#fail("DOCTYPE \u672A\u95ED\u5408", start);
|
|
210
|
+
}
|
|
211
|
+
// -- 元素 ----------------------------------------------------------------
|
|
212
|
+
#parseElement() {
|
|
213
|
+
if (this.#depth >= this.#maxDepth) {
|
|
214
|
+
this.#fail(
|
|
215
|
+
`\u5143\u7D20\u5D4C\u5957\u8D85\u8FC7\u4E0A\u9650 ${String(this.#maxDepth)} \u5C42 \u2014\u2014 \u7578\u5F62\u6587\u6863\u5E38\u4EE5\u6781\u6DF1\u5D4C\u5957\u89E6\u53D1\u5BBF\u4E3B\u6808\u6EA2\u51FA\uFF0C\u6545\u6309\u89E3\u6790\u5931\u8D25\u5904\u7406\u800C\u975E\u7EE7\u7EED\u9012\u5F52`,
|
|
216
|
+
this.#pos
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
const { name, attributes, selfClosing } = this.#parseStartTag();
|
|
220
|
+
const { prefix, localName } = splitName(name);
|
|
221
|
+
if (selfClosing) {
|
|
222
|
+
return { type: "element", name, prefix, localName, attributes, children: [] };
|
|
223
|
+
}
|
|
224
|
+
this.#depth += 1;
|
|
225
|
+
const children = this.#parseContent(name);
|
|
226
|
+
this.#depth -= 1;
|
|
227
|
+
return { type: "element", name, prefix, localName, attributes, children };
|
|
228
|
+
}
|
|
229
|
+
#parseStartTag() {
|
|
230
|
+
const start = this.#pos;
|
|
231
|
+
if (this.#source.charCodeAt(this.#pos) !== CODE_LT) {
|
|
232
|
+
this.#fail('\u671F\u671B\u5143\u7D20\u8D77\u59CB\u6807\u8BB0 "<"', start);
|
|
233
|
+
}
|
|
234
|
+
this.#pos += 1;
|
|
235
|
+
const name = this.#readName();
|
|
236
|
+
if (name === "") this.#fail("\u5143\u7D20\u540D\u7F3A\u5931", start);
|
|
237
|
+
const attributes = /* @__PURE__ */ new Map();
|
|
238
|
+
for (; ; ) {
|
|
239
|
+
const beforeSpace = this.#pos;
|
|
240
|
+
this.#skipWhitespace();
|
|
241
|
+
const hadSpace = this.#pos > beforeSpace;
|
|
242
|
+
const code = this.#source.charCodeAt(this.#pos);
|
|
243
|
+
if (code === CODE_SLASH) {
|
|
244
|
+
if (this.#source.charCodeAt(this.#pos + 1) !== CODE_GT) {
|
|
245
|
+
this.#fail('\u81EA\u95ED\u5408\u6807\u8BB0\u683C\u5F0F\u9519\u8BEF\uFF0C\u671F\u671B "/>"', this.#pos);
|
|
246
|
+
}
|
|
247
|
+
this.#pos += 2;
|
|
248
|
+
return { name, attributes, selfClosing: true };
|
|
249
|
+
}
|
|
250
|
+
if (code === CODE_GT) {
|
|
251
|
+
this.#pos += 1;
|
|
252
|
+
return { name, attributes, selfClosing: false };
|
|
253
|
+
}
|
|
254
|
+
if (!hadSpace) this.#fail("\u5C5E\u6027\u4E4B\u95F4\u7F3A\u5C11\u7A7A\u767D\u5206\u9694", this.#pos);
|
|
255
|
+
const attributeStart = this.#pos;
|
|
256
|
+
const attributeName = this.#readName();
|
|
257
|
+
if (attributeName === "") this.#fail("\u5C5E\u6027\u540D\u7F3A\u5931", attributeStart);
|
|
258
|
+
if (attributes.has(attributeName)) {
|
|
259
|
+
this.#fail(`\u5C5E\u6027 "${attributeName}" \u91CD\u590D`, attributeStart);
|
|
260
|
+
}
|
|
261
|
+
this.#skipWhitespace();
|
|
262
|
+
if (this.#source.charCodeAt(this.#pos) !== CODE_EQ) {
|
|
263
|
+
this.#fail(`\u5C5E\u6027 "${attributeName}" \u7F3A\u5C11 "="`, this.#pos);
|
|
264
|
+
}
|
|
265
|
+
this.#pos += 1;
|
|
266
|
+
this.#skipWhitespace();
|
|
267
|
+
const quote = this.#source.charCodeAt(this.#pos);
|
|
268
|
+
if (quote !== CODE_QUOTE && quote !== CODE_APOS) {
|
|
269
|
+
this.#fail(`\u5C5E\u6027 "${attributeName}" \u7684\u503C\u5FC5\u987B\u7528\u5F15\u53F7\u5305\u88F9`, this.#pos);
|
|
270
|
+
}
|
|
271
|
+
this.#pos += 1;
|
|
272
|
+
const close = this.#source.indexOf(String.fromCharCode(quote), this.#pos);
|
|
273
|
+
if (close === -1) {
|
|
274
|
+
this.#fail(`\u5C5E\u6027 "${attributeName}" \u7684\u5F15\u53F7\u672A\u95ED\u5408`, this.#pos);
|
|
275
|
+
}
|
|
276
|
+
const rawValue = this.#source.slice(this.#pos, close);
|
|
277
|
+
attributes.set(attributeName, decodeEntities(normalizeNewlines(rawValue)));
|
|
278
|
+
this.#pos = close + 1;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
#parseContent(expectedName) {
|
|
282
|
+
const children = [];
|
|
283
|
+
for (; ; ) {
|
|
284
|
+
if (this.#atEnd()) this.#fail(`\u5143\u7D20 <${expectedName}> \u672A\u95ED\u5408`, this.#pos);
|
|
285
|
+
if (this.#source.charCodeAt(this.#pos) !== CODE_LT) {
|
|
286
|
+
children.push(this.#readText());
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
const next = this.#source.charCodeAt(this.#pos + 1);
|
|
290
|
+
if (next === CODE_SLASH) {
|
|
291
|
+
this.#parseEndTag(expectedName);
|
|
292
|
+
return children;
|
|
293
|
+
}
|
|
294
|
+
if (this.#startsWith(COMMENT_OPEN)) {
|
|
295
|
+
this.#skipComment();
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
if (this.#startsWith(CDATA_OPEN)) {
|
|
299
|
+
children.push(this.#readCdata());
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
if (next === CODE_QUESTION) {
|
|
303
|
+
this.#skipProcessingInstruction();
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
if (next === CODE_BANG) {
|
|
307
|
+
this.#fail('\u5143\u7D20\u5185\u5BB9\u4E2D\u4E0D\u5141\u8BB8\u51FA\u73B0 "<!" \u58F0\u660E', this.#pos);
|
|
308
|
+
}
|
|
309
|
+
children.push(this.#parseElement());
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
#parseEndTag(expectedName) {
|
|
313
|
+
const start = this.#pos;
|
|
314
|
+
this.#pos += 2;
|
|
315
|
+
const name = this.#readName();
|
|
316
|
+
if (name === "") this.#fail("\u7ED3\u675F\u6807\u8BB0\u7F3A\u5C11\u5143\u7D20\u540D", start);
|
|
317
|
+
this.#skipWhitespace();
|
|
318
|
+
if (this.#source.charCodeAt(this.#pos) !== CODE_GT) {
|
|
319
|
+
this.#fail(`\u7ED3\u675F\u6807\u8BB0 </${name}> \u683C\u5F0F\u9519\u8BEF\uFF0C\u671F\u671B ">"`, this.#pos);
|
|
320
|
+
}
|
|
321
|
+
this.#pos += 1;
|
|
322
|
+
if (name !== expectedName) {
|
|
323
|
+
this.#fail(`\u6807\u7B7E\u4E0D\u5339\u914D\uFF1A\u671F\u671B </${expectedName}>\uFF0C\u5B9E\u9645 </${name}>`, start);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
#readName() {
|
|
327
|
+
const start = this.#pos;
|
|
328
|
+
while (!isNameTerminator(this.#source.charCodeAt(this.#pos))) this.#pos += 1;
|
|
329
|
+
return this.#source.slice(start, this.#pos);
|
|
330
|
+
}
|
|
331
|
+
#readText() {
|
|
332
|
+
const start = this.#pos;
|
|
333
|
+
const next = this.#source.indexOf("<", this.#pos);
|
|
334
|
+
this.#pos = next === -1 ? this.#source.length : next;
|
|
335
|
+
const raw = this.#source.slice(start, this.#pos);
|
|
336
|
+
return { type: "text", value: decodeEntities(normalizeNewlines(raw)), cdata: false };
|
|
337
|
+
}
|
|
338
|
+
#readCdata() {
|
|
339
|
+
const start = this.#pos;
|
|
340
|
+
const contentStart = start + CDATA_OPEN.length;
|
|
341
|
+
const end = this.#source.indexOf(CDATA_CLOSE, contentStart);
|
|
342
|
+
if (end === -1) this.#fail("CDATA \u6BB5\u672A\u95ED\u5408", start);
|
|
343
|
+
this.#pos = end + CDATA_CLOSE.length;
|
|
344
|
+
return {
|
|
345
|
+
type: "text",
|
|
346
|
+
value: normalizeNewlines(this.#source.slice(contentStart, end)),
|
|
347
|
+
cdata: true
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
function parseXml(source, options) {
|
|
352
|
+
return new XmlParser(
|
|
353
|
+
source,
|
|
354
|
+
options?.source ?? "<anonymous>",
|
|
355
|
+
options?.maxDepth ?? DEFAULT_MAX_DEPTH
|
|
356
|
+
).parseDocument();
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// src/core/xml/query.ts
|
|
360
|
+
function findAll(root, localName) {
|
|
361
|
+
const matched = [];
|
|
362
|
+
const walk = (node) => {
|
|
363
|
+
for (const child of node.children) {
|
|
364
|
+
if (child.type !== "element") continue;
|
|
365
|
+
if (child.localName === localName) matched.push(child);
|
|
366
|
+
walk(child);
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
walk(root);
|
|
370
|
+
return matched;
|
|
371
|
+
}
|
|
372
|
+
function findFirst(root, localName) {
|
|
373
|
+
for (const child of root.children) {
|
|
374
|
+
if (child.type !== "element") continue;
|
|
375
|
+
if (child.localName === localName) return child;
|
|
376
|
+
const found = findFirst(child, localName);
|
|
377
|
+
if (found !== void 0) return found;
|
|
378
|
+
}
|
|
379
|
+
return void 0;
|
|
380
|
+
}
|
|
381
|
+
function getAttribute(element, name) {
|
|
382
|
+
return element.attributes.get(name);
|
|
383
|
+
}
|
|
384
|
+
function getText(element) {
|
|
385
|
+
let text = "";
|
|
386
|
+
for (const child of element.children) {
|
|
387
|
+
text += child.type === "text" ? child.value : getText(child);
|
|
388
|
+
}
|
|
389
|
+
return text;
|
|
390
|
+
}
|
|
391
|
+
function isElement(node) {
|
|
392
|
+
return node.type === "element";
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
exports.findAll = findAll;
|
|
396
|
+
exports.findFirst = findFirst;
|
|
397
|
+
exports.getAttribute = getAttribute;
|
|
398
|
+
exports.getText = getText;
|
|
399
|
+
exports.isElement = isElement;
|
|
400
|
+
exports.parseXml = parseXml;
|