wikiparser-node 1.0.0-beta.0 → 1.0.0-beta.2
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/config/.schema.json +26 -0
- package/dist/index.d.ts +11 -9
- package/dist/index.js +22 -24
- package/dist/internal.d.ts +44 -0
- package/dist/lib/element.d.ts +42 -32
- package/dist/lib/element.js +59 -56
- package/dist/lib/node.d.ts +29 -36
- package/dist/lib/node.js +33 -48
- package/dist/lib/range.d.ts +132 -0
- package/dist/lib/range.js +387 -0
- package/dist/lib/ranges.d.ts +2 -12
- package/dist/lib/ranges.js +6 -11
- package/dist/lib/text.d.ts +11 -5
- package/dist/lib/text.js +25 -13
- package/dist/lib/title.d.ts +4 -5
- package/dist/lib/title.js +17 -7
- package/dist/mixin/attributesParent.js +6 -3
- package/dist/mixin/fixed.js +8 -5
- package/dist/mixin/hidden.js +7 -3
- package/dist/mixin/singleLine.js +6 -3
- package/dist/mixin/sol.js +6 -3
- package/dist/parser/{brackets.js → braces.js} +34 -26
- package/dist/parser/commentAndExt.js +25 -15
- package/dist/parser/converter.js +16 -9
- package/dist/parser/externalLinks.js +15 -9
- package/dist/parser/hrAndDoubleUnderscore.js +17 -10
- package/dist/parser/html.js +18 -9
- package/dist/parser/links.js +22 -14
- package/dist/parser/list.js +20 -10
- package/dist/parser/magicLinks.js +14 -7
- package/dist/parser/quotes.js +21 -11
- package/dist/parser/selector.js +19 -12
- package/dist/parser/table.js +25 -16
- package/dist/src/arg.d.ts +7 -8
- package/dist/src/arg.js +27 -24
- package/dist/src/atom.d.ts +4 -5
- package/dist/src/atom.js +9 -7
- package/dist/src/attribute.d.ts +13 -13
- package/dist/src/attribute.js +28 -25
- package/dist/src/attributes.d.ts +11 -10
- package/dist/src/attributes.js +40 -45
- package/dist/src/converter.d.ts +5 -7
- package/dist/src/converter.js +22 -16
- package/dist/src/converterFlags.d.ts +11 -12
- package/dist/src/converterFlags.js +17 -14
- package/dist/src/converterRule.d.ts +9 -10
- package/dist/src/converterRule.js +27 -27
- package/dist/src/extLink.d.ts +4 -6
- package/dist/src/extLink.js +25 -22
- package/dist/src/gallery.d.ts +9 -13
- package/dist/src/gallery.js +28 -23
- package/dist/src/heading.d.ts +11 -11
- package/dist/src/heading.js +19 -19
- package/dist/src/hidden.d.ts +4 -5
- package/dist/src/hidden.js +10 -8
- package/dist/src/html.d.ts +15 -12
- package/dist/src/html.js +18 -15
- package/dist/src/imageParameter.d.ts +11 -13
- package/dist/src/imageParameter.js +21 -16
- package/dist/src/imagemap.d.ts +11 -15
- package/dist/src/imagemap.js +26 -21
- package/dist/src/imagemapLink.d.ts +12 -17
- package/dist/src/imagemapLink.js +19 -14
- package/dist/src/index.d.ts +24 -20
- package/dist/src/index.js +65 -75
- package/dist/src/link/base.d.ts +8 -10
- package/dist/src/link/base.js +28 -22
- package/dist/src/link/category.d.ts +2 -3
- package/dist/src/link/category.js +7 -5
- package/dist/src/link/file.d.ts +9 -11
- package/dist/src/link/file.js +53 -26
- package/dist/src/link/galleryImage.d.ts +8 -8
- package/dist/src/link/galleryImage.js +18 -16
- package/dist/src/link/index.d.ts +6 -6
- package/dist/src/link/index.js +14 -16
- package/dist/src/magicLink.d.ts +9 -6
- package/dist/src/magicLink.js +23 -18
- package/dist/src/nested.d.ts +10 -10
- package/dist/src/nested.js +25 -17
- package/dist/src/nowiki/base.d.ts +7 -8
- package/dist/src/nowiki/base.js +10 -8
- package/dist/src/nowiki/comment.d.ts +7 -7
- package/dist/src/nowiki/comment.js +12 -9
- package/dist/src/nowiki/dd.d.ts +2 -3
- package/dist/src/nowiki/dd.js +7 -11
- package/dist/src/nowiki/doubleUnderscore.d.ts +5 -7
- package/dist/src/nowiki/doubleUnderscore.js +11 -8
- package/dist/src/nowiki/hr.d.ts +6 -7
- package/dist/src/nowiki/hr.js +11 -8
- package/dist/src/nowiki/index.d.ts +5 -7
- package/dist/src/nowiki/index.js +8 -6
- package/dist/src/nowiki/list.d.ts +4 -4
- package/dist/src/nowiki/list.js +8 -6
- package/dist/src/nowiki/noinclude.d.ts +3 -3
- package/dist/src/nowiki/noinclude.js +8 -6
- package/dist/src/nowiki/quote.d.ts +6 -7
- package/dist/src/nowiki/quote.js +11 -8
- package/dist/src/onlyinclude.d.ts +3 -5
- package/dist/src/onlyinclude.js +9 -7
- package/dist/src/paramTag/index.d.ts +8 -10
- package/dist/src/paramTag/index.js +15 -13
- package/dist/src/paramTag/inputbox.d.ts +4 -6
- package/dist/src/paramTag/inputbox.js +10 -8
- package/dist/src/parameter.d.ts +11 -12
- package/dist/src/parameter.js +25 -22
- package/dist/src/pre.d.ts +5 -10
- package/dist/src/pre.js +16 -11
- package/dist/src/syntax.d.ts +6 -7
- package/dist/src/syntax.js +12 -10
- package/dist/src/table/base.d.ts +14 -9
- package/dist/src/table/base.js +18 -15
- package/dist/src/table/index.d.ts +24 -17
- package/dist/src/table/index.js +39 -67
- package/dist/src/table/td.d.ts +17 -21
- package/dist/src/table/td.js +20 -28
- package/dist/src/table/tr.d.ts +6 -11
- package/dist/src/table/tr.js +8 -6
- package/dist/src/table/trBase.d.ts +12 -22
- package/dist/src/table/trBase.js +23 -19
- package/dist/src/tagPair/ext.d.ts +10 -10
- package/dist/src/tagPair/ext.js +47 -24
- package/dist/src/tagPair/include.d.ts +6 -7
- package/dist/src/tagPair/include.js +11 -8
- package/dist/src/tagPair/index.d.ts +12 -11
- package/dist/src/tagPair/index.js +13 -11
- package/dist/src/transclude.d.ts +8 -10
- package/dist/src/transclude.js +70 -77
- package/dist/util/debug.js +2 -12
- package/dist/util/diff.js +4 -2
- package/dist/util/lint.js +5 -5
- package/dist/util/string.js +2 -31
- package/package.json +13 -13
- package/dist/util/base.js +0 -26
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AstRange = void 0;
|
|
4
|
+
const index_1 = require("../index");
|
|
5
|
+
/**
|
|
6
|
+
* 计算绝对位置
|
|
7
|
+
* @param referenceNode 容器
|
|
8
|
+
* @param offset 相对位置
|
|
9
|
+
*/
|
|
10
|
+
const getIndex = (referenceNode, offset) => referenceNode.getAbsoluteIndex() + referenceNode.getRelativeIndex(offset);
|
|
11
|
+
/** 模拟Range对象 */
|
|
12
|
+
class AstRange {
|
|
13
|
+
#startContainer;
|
|
14
|
+
#startOffset;
|
|
15
|
+
#endContainer;
|
|
16
|
+
#endOffset;
|
|
17
|
+
/**
|
|
18
|
+
* 未初始化时抛出错误
|
|
19
|
+
* @param start 是否未初始化起点
|
|
20
|
+
* @throws `Error` 未初始化
|
|
21
|
+
*/
|
|
22
|
+
// eslint-disable-next-line class-methods-use-this
|
|
23
|
+
#notInit(start) {
|
|
24
|
+
throw new Error(`请先指定${start ? '起始' : '终止'}位置!`);
|
|
25
|
+
}
|
|
26
|
+
/** 起点容器 */
|
|
27
|
+
get startContainer() {
|
|
28
|
+
return this.#startContainer ?? this.#notInit(true);
|
|
29
|
+
}
|
|
30
|
+
/** 起点位置 */
|
|
31
|
+
get startOffset() {
|
|
32
|
+
return this.#startOffset ?? this.#notInit(true);
|
|
33
|
+
}
|
|
34
|
+
/** 起点绝对位置 */
|
|
35
|
+
get startIndex() {
|
|
36
|
+
const { startContainer, startOffset } = this;
|
|
37
|
+
return getIndex(startContainer, startOffset);
|
|
38
|
+
}
|
|
39
|
+
/** 终点容器 */
|
|
40
|
+
get endContainer() {
|
|
41
|
+
return this.#endContainer ?? this.#notInit(false);
|
|
42
|
+
}
|
|
43
|
+
/** 终点位置 */
|
|
44
|
+
get endOffset() {
|
|
45
|
+
return this.#endOffset ?? this.#notInit(false);
|
|
46
|
+
}
|
|
47
|
+
/** 终点绝对位置 */
|
|
48
|
+
get endIndex() {
|
|
49
|
+
const { endContainer, endOffset } = this;
|
|
50
|
+
return getIndex(endContainer, endOffset);
|
|
51
|
+
}
|
|
52
|
+
/** 起始和终止位置是否重合 */
|
|
53
|
+
get collapsed() {
|
|
54
|
+
return this.startIndex === this.endIndex;
|
|
55
|
+
}
|
|
56
|
+
/** 最近的公共祖先 */
|
|
57
|
+
get commonAncestorContainer() {
|
|
58
|
+
const { startContainer, endContainer } = this;
|
|
59
|
+
let parentNode = startContainer;
|
|
60
|
+
while (!parentNode.contains(endContainer)) {
|
|
61
|
+
({ parentNode } = parentNode);
|
|
62
|
+
}
|
|
63
|
+
return parentNode;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* 设置起点
|
|
67
|
+
* @param startNode 起点容器
|
|
68
|
+
* @param startOffset 起点位置
|
|
69
|
+
* @throws `RangeError` 不在同一个文档
|
|
70
|
+
* @throws `RangeError` offset取值超出范围
|
|
71
|
+
*/
|
|
72
|
+
setStart(startNode, startOffset) {
|
|
73
|
+
const root = this.#endContainer?.getRootNode(), { length } = startNode;
|
|
74
|
+
if (root && root !== startNode.getRootNode()) {
|
|
75
|
+
throw new RangeError('起点不在同一个文档中!');
|
|
76
|
+
}
|
|
77
|
+
else if (startOffset < 0 || startOffset > length) {
|
|
78
|
+
throw new RangeError(`offset取值范围应为 0 ~ ${length}`);
|
|
79
|
+
}
|
|
80
|
+
else if (root && getIndex(startNode, startOffset) > this.endIndex) {
|
|
81
|
+
throw new RangeError('起点不能位于终点之后!');
|
|
82
|
+
}
|
|
83
|
+
this.#startContainer = startNode;
|
|
84
|
+
this.#startOffset = startOffset;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* 设置终点
|
|
88
|
+
* @param endNode 终点容器
|
|
89
|
+
* @param endOffset 终点位置
|
|
90
|
+
* @throws `RangeError` 不在同一个文档
|
|
91
|
+
* @throws `RangeError` offset取值超出范围
|
|
92
|
+
*/
|
|
93
|
+
setEnd(endNode, endOffset) {
|
|
94
|
+
const root = this.#startContainer?.getRootNode(), { length } = endNode;
|
|
95
|
+
if (root && root !== endNode.getRootNode()) {
|
|
96
|
+
throw new RangeError('终点不在同一个文档中!');
|
|
97
|
+
}
|
|
98
|
+
else if (endOffset < 0 || endOffset > length) {
|
|
99
|
+
throw new RangeError(`offset取值范围应为 0 ~ ${length}`);
|
|
100
|
+
}
|
|
101
|
+
else if (root && getIndex(endNode, endOffset) < this.startIndex) {
|
|
102
|
+
throw new RangeError('终点不能位于起点之前!');
|
|
103
|
+
}
|
|
104
|
+
this.#endContainer = endNode;
|
|
105
|
+
this.#endOffset = endOffset;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* 在节点后设置
|
|
109
|
+
* @param method 方法名
|
|
110
|
+
* @param referenceNode 节点
|
|
111
|
+
*/
|
|
112
|
+
#setAfter(method, referenceNode) {
|
|
113
|
+
if (referenceNode.type === 'root') {
|
|
114
|
+
this[method](referenceNode, referenceNode.length);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
const { parentNode } = referenceNode;
|
|
118
|
+
this[method](parentNode, parentNode.childNodes.indexOf(referenceNode) + 1);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* 在节点后设置起点
|
|
123
|
+
* @param referenceNode 节点
|
|
124
|
+
*/
|
|
125
|
+
setStartAfter(referenceNode) {
|
|
126
|
+
this.#setAfter('setStart', referenceNode);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* 在节点后设置终点
|
|
130
|
+
* @param referenceNode 节点
|
|
131
|
+
*/
|
|
132
|
+
setEndAfter(referenceNode) {
|
|
133
|
+
this.#setAfter('setEnd', referenceNode);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* 在节点前设置
|
|
137
|
+
* @param method 方法名
|
|
138
|
+
* @param referenceNode 节点
|
|
139
|
+
*/
|
|
140
|
+
#setBefore(method, referenceNode) {
|
|
141
|
+
if (referenceNode.type === 'root') {
|
|
142
|
+
this[method](referenceNode, 0);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
const { parentNode } = referenceNode;
|
|
146
|
+
this[method](parentNode, parentNode.childNodes.indexOf(referenceNode));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* 在节点前设置起点
|
|
151
|
+
* @param referenceNode 节点
|
|
152
|
+
*/
|
|
153
|
+
setStartBefore(referenceNode) {
|
|
154
|
+
this.#setBefore('setStart', referenceNode);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* 在节点前设置终点
|
|
158
|
+
* @param referenceNode 节点
|
|
159
|
+
*/
|
|
160
|
+
setEndBefore(referenceNode) {
|
|
161
|
+
this.#setBefore('setEnd', referenceNode);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* 根据字符位置设置
|
|
165
|
+
* @param method 方法名
|
|
166
|
+
* @param root 根节点
|
|
167
|
+
* @param index 字符位置
|
|
168
|
+
* @throws `RangeError` 超出有效范围
|
|
169
|
+
*/
|
|
170
|
+
#setIndex(method, root, index) {
|
|
171
|
+
const caretPosition = root.caretPositionFromIndex(index);
|
|
172
|
+
if (caretPosition === undefined) {
|
|
173
|
+
throw new RangeError('字符坐标超出有效的范围!');
|
|
174
|
+
}
|
|
175
|
+
const { offsetNode, offset } = caretPosition;
|
|
176
|
+
if (offsetNode.type === 'text') {
|
|
177
|
+
this[method](offsetNode, offset);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
const i = offsetNode.childNodes.findIndex(child => child.getRelativeIndex() >= offset);
|
|
181
|
+
this[method](offsetNode, i === -1 ? offsetNode.length : i);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* 根据字符位置设置起点
|
|
186
|
+
* @param root 根节点
|
|
187
|
+
* @param index 字符位置
|
|
188
|
+
*/
|
|
189
|
+
setStartIndex(root, index) {
|
|
190
|
+
this.#setIndex('setStart', root, index);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* 根据字符位置设置终点
|
|
194
|
+
* @param root 根节点
|
|
195
|
+
* @param index 字符位置
|
|
196
|
+
*/
|
|
197
|
+
setEndIndex(root, index) {
|
|
198
|
+
this.#setIndex('setEnd', root, index);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* 根据行列号设置
|
|
202
|
+
* @param method 方法名
|
|
203
|
+
* @param root 根节点
|
|
204
|
+
* @param x 列
|
|
205
|
+
* @param y 行
|
|
206
|
+
*/
|
|
207
|
+
#setPoint(method, root, x, y) {
|
|
208
|
+
this.#setIndex(method, root, root.indexFromPos(y, x));
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* 根据行列号设置起点
|
|
212
|
+
* @param root 根节点
|
|
213
|
+
* @param x 列
|
|
214
|
+
* @param y 行
|
|
215
|
+
*/
|
|
216
|
+
setStartPoint(root, x, y) {
|
|
217
|
+
this.#setPoint('setStart', root, x, y);
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* 根据行列号设置终点
|
|
221
|
+
* @param root 根节点
|
|
222
|
+
* @param x 列
|
|
223
|
+
* @param y 行
|
|
224
|
+
*/
|
|
225
|
+
setEndPoint(root, x, y) {
|
|
226
|
+
this.#setPoint('setEnd', root, x, y);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* 设置Range包含整个节点的内容
|
|
230
|
+
* @param referenceNode 节点
|
|
231
|
+
*/
|
|
232
|
+
selectNodeContents(referenceNode) {
|
|
233
|
+
this.#startContainer = referenceNode;
|
|
234
|
+
this.#startOffset = 0;
|
|
235
|
+
this.#endContainer = referenceNode;
|
|
236
|
+
this.#endOffset = referenceNode.length;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* 设置Range包含整个节点
|
|
240
|
+
* @param referenceNode 节点
|
|
241
|
+
*/
|
|
242
|
+
selectNode(referenceNode) {
|
|
243
|
+
if (referenceNode.type === 'root') {
|
|
244
|
+
this.selectNodeContents(referenceNode);
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
const { parentNode } = referenceNode, i = parentNode.childNodes.indexOf(referenceNode);
|
|
248
|
+
this.#startContainer = parentNode;
|
|
249
|
+
this.#startOffset = i;
|
|
250
|
+
this.#endContainer = parentNode;
|
|
251
|
+
this.#endOffset = i + 1;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* 使起始和终止位置重合
|
|
256
|
+
* @param toStart 重合至起始位置
|
|
257
|
+
*/
|
|
258
|
+
collapse(toStart = false) {
|
|
259
|
+
if (toStart) {
|
|
260
|
+
this.#endContainer = this.startContainer;
|
|
261
|
+
this.#endOffset = this.startOffset;
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
this.#startContainer = this.endContainer;
|
|
265
|
+
this.#startOffset = this.endOffset;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* 比较端点和Range的位置
|
|
270
|
+
* @param referenceNode 端点容器
|
|
271
|
+
* @param offset 端点位置
|
|
272
|
+
* @throws `RangeError` 不在同一个文档
|
|
273
|
+
*/
|
|
274
|
+
comparePoint(referenceNode, offset) {
|
|
275
|
+
const { startContainer, startIndex, endIndex } = this;
|
|
276
|
+
if (startContainer.getRootNode() !== referenceNode.getRootNode()) {
|
|
277
|
+
throw new RangeError('待比较的端点不在同一个文档中!');
|
|
278
|
+
}
|
|
279
|
+
const index = getIndex(referenceNode, offset);
|
|
280
|
+
if (index < startIndex) {
|
|
281
|
+
return -1;
|
|
282
|
+
}
|
|
283
|
+
return index > endIndex ? 1 : 0;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* 端点是否在Range中
|
|
287
|
+
* @param referenceNode 端点容器
|
|
288
|
+
* @param offset 端点位置
|
|
289
|
+
* @throws `RangeError` 不在同一个文档
|
|
290
|
+
*/
|
|
291
|
+
isPointInRange(referenceNode, offset) {
|
|
292
|
+
return this.comparePoint(referenceNode, offset) === 0;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* 是否与节点相交
|
|
296
|
+
* @param referenceNode 节点
|
|
297
|
+
* @throws `RangeError` 不在同一个文档
|
|
298
|
+
*/
|
|
299
|
+
intersectsNode(referenceNode) {
|
|
300
|
+
const { startContainer, startIndex, endIndex } = this;
|
|
301
|
+
if (startContainer.getRootNode() !== referenceNode.getRootNode()) {
|
|
302
|
+
throw new RangeError('待比较的端点不在同一个文档中!');
|
|
303
|
+
}
|
|
304
|
+
const index = referenceNode.getAbsoluteIndex();
|
|
305
|
+
return index < endIndex && index + String(referenceNode).length > startIndex;
|
|
306
|
+
}
|
|
307
|
+
/** 复制 */
|
|
308
|
+
cloneRange() {
|
|
309
|
+
const range = new AstRange();
|
|
310
|
+
range.setStart(this.startContainer, this.startOffset);
|
|
311
|
+
range.setEnd(this.endContainer, this.endOffset);
|
|
312
|
+
return range;
|
|
313
|
+
}
|
|
314
|
+
/** 删除 */
|
|
315
|
+
deleteContents() {
|
|
316
|
+
const { startContainer, startOffset } = this;
|
|
317
|
+
let { endContainer, endOffset } = this, parentNode;
|
|
318
|
+
while (!endContainer.contains(startContainer)) {
|
|
319
|
+
({ parentNode } = endContainer);
|
|
320
|
+
if (endContainer.type === 'text') {
|
|
321
|
+
endContainer.deleteData(0, endOffset);
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
for (let i = endOffset - 1; i >= 0; i--) {
|
|
325
|
+
endContainer.removeAt(i);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
endOffset = parentNode.childNodes.indexOf(endContainer);
|
|
329
|
+
endContainer = parentNode;
|
|
330
|
+
}
|
|
331
|
+
while (endContainer !== startContainer) {
|
|
332
|
+
const { childNodes } = endContainer, j = childNodes.findIndex(child => child.contains(startContainer));
|
|
333
|
+
for (let i = endOffset - 1; i > j; i--) {
|
|
334
|
+
endContainer.removeAt(i);
|
|
335
|
+
}
|
|
336
|
+
endContainer = childNodes[j];
|
|
337
|
+
endOffset = endContainer.length;
|
|
338
|
+
}
|
|
339
|
+
if (endContainer.type === 'text') {
|
|
340
|
+
endContainer.deleteData(startOffset, endOffset);
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
for (let i = endOffset - 1; i >= startOffset; i--) {
|
|
344
|
+
endContainer.removeAt(i);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
this.#endContainer = endContainer;
|
|
348
|
+
this.#endOffset = startOffset;
|
|
349
|
+
}
|
|
350
|
+
/** 获取行列位置和大小 */
|
|
351
|
+
getBoundingClientRect() {
|
|
352
|
+
let { startContainer, startOffset, endContainer, endOffset } = this, parentNode;
|
|
353
|
+
while (!startContainer.contains(endContainer)) {
|
|
354
|
+
({ parentNode } = startContainer);
|
|
355
|
+
startOffset = parentNode.childNodes.indexOf(startContainer);
|
|
356
|
+
startContainer = parentNode;
|
|
357
|
+
}
|
|
358
|
+
while (endContainer !== startContainer) {
|
|
359
|
+
({ parentNode } = endContainer);
|
|
360
|
+
endOffset = parentNode.childNodes.indexOf(endContainer) + 1;
|
|
361
|
+
endContainer = parentNode;
|
|
362
|
+
}
|
|
363
|
+
const { top, left } = startContainer.posFromIndex(startContainer.getRelativeIndex(startOffset)), { top: bottom, left: right } = startContainer.posFromIndex(startContainer.getRelativeIndex(endOffset));
|
|
364
|
+
return { top, left, height: bottom - top + 1, width: bottom === top ? right - left : right };
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* 在起始位置插入节点
|
|
368
|
+
* @param newNode 插入的节点
|
|
369
|
+
*/
|
|
370
|
+
insertNode(newNode) {
|
|
371
|
+
const { startContainer, startOffset } = this;
|
|
372
|
+
if (startContainer.type === 'text') {
|
|
373
|
+
startContainer.splitText(startOffset);
|
|
374
|
+
startContainer.after(newNode);
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
startContainer.insertAt(newNode, startOffset);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
/** 范围内的全部文本 */
|
|
381
|
+
toString() {
|
|
382
|
+
const { startContainer, startIndex, endIndex } = this;
|
|
383
|
+
return String(startContainer.getRootNode()).slice(startIndex, endIndex);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
exports.AstRange = AstRange;
|
|
387
|
+
index_1.default.classes['AstRange'] = __filename;
|
package/dist/lib/ranges.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** 模拟Python的Range对象。除`step`至少为`1`外,允许负数、小数或`end < start`的情形。 */
|
|
2
|
-
declare class Range {
|
|
2
|
+
export declare class Range {
|
|
3
3
|
start: number;
|
|
4
4
|
end: number;
|
|
5
5
|
step: number;
|
|
@@ -17,7 +17,7 @@ declare class Range {
|
|
|
17
17
|
applyTo(arr: number | unknown[]): number[];
|
|
18
18
|
}
|
|
19
19
|
/** @extends {Array<number|Range>} */
|
|
20
|
-
declare class Ranges extends Array<number | Range> {
|
|
20
|
+
export declare class Ranges extends Array<number | Range> {
|
|
21
21
|
/** @param a 表达式数组 */
|
|
22
22
|
constructor(a?: number | string | Range | (number | string | Range)[]);
|
|
23
23
|
/**
|
|
@@ -25,14 +25,4 @@ declare class Ranges extends Array<number | Range> {
|
|
|
25
25
|
* @param arr 参考数组
|
|
26
26
|
*/
|
|
27
27
|
applyTo(arr: number | unknown[]): number[];
|
|
28
|
-
/**
|
|
29
|
-
* 检查某个下标是否符合表达式
|
|
30
|
-
* @param str 表达式
|
|
31
|
-
* @param i 待检查的下标
|
|
32
|
-
*/
|
|
33
|
-
static nth(this: void, str: string, i: number): boolean;
|
|
34
|
-
}
|
|
35
|
-
declare namespace Ranges {
|
|
36
|
-
export { Range };
|
|
37
28
|
}
|
|
38
|
-
export = Ranges;
|
package/dist/lib/ranges.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Ranges = exports.Range = void 0;
|
|
4
|
+
const index_1 = require("../index");
|
|
3
5
|
/** 模拟Python的Range对象。除`step`至少为`1`外,允许负数、小数或`end < start`的情形。 */
|
|
4
6
|
class Range {
|
|
5
7
|
start;
|
|
@@ -75,6 +77,7 @@ class Range {
|
|
|
75
77
|
.filter((_, j) => j % this.step === 0);
|
|
76
78
|
}
|
|
77
79
|
}
|
|
80
|
+
exports.Range = Range;
|
|
78
81
|
/** @extends {Array<number|Range>} */
|
|
79
82
|
class Ranges extends Array {
|
|
80
83
|
/** @param a 表达式数组 */
|
|
@@ -117,14 +120,6 @@ class Ranges extends Array {
|
|
|
117
120
|
})),
|
|
118
121
|
].filter(i => i >= 0 && i < length).sort();
|
|
119
122
|
}
|
|
120
|
-
/**
|
|
121
|
-
* 检查某个下标是否符合表达式
|
|
122
|
-
* @param str 表达式
|
|
123
|
-
* @param i 待检查的下标
|
|
124
|
-
*/
|
|
125
|
-
static nth(str, i) {
|
|
126
|
-
return new Ranges(str.split(',')).applyTo(i + 1).includes(i);
|
|
127
|
-
}
|
|
128
123
|
}
|
|
129
|
-
|
|
130
|
-
|
|
124
|
+
exports.Ranges = Ranges;
|
|
125
|
+
index_1.default.classes['Ranges'] = __filename;
|
package/dist/lib/text.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { AstNode } from './node';
|
|
2
|
+
import type { LintError } from '../index';
|
|
3
3
|
/** 文本节点 */
|
|
4
|
-
declare class AstText extends AstNode {
|
|
4
|
+
export declare class AstText extends AstNode {
|
|
5
5
|
#private;
|
|
6
6
|
/** @browser */
|
|
7
7
|
readonly type = "text";
|
|
@@ -28,8 +28,9 @@ declare class AstText extends AstNode {
|
|
|
28
28
|
/**
|
|
29
29
|
* Linter
|
|
30
30
|
* @browser
|
|
31
|
+
* @param start
|
|
31
32
|
*/
|
|
32
|
-
lint(start?: number):
|
|
33
|
+
lint(start?: number): LintError[];
|
|
33
34
|
/**
|
|
34
35
|
* 替换字符串
|
|
35
36
|
* @browser
|
|
@@ -68,5 +69,10 @@ declare class AstText extends AstNode {
|
|
|
68
69
|
* @throws `Error` 没有父节点
|
|
69
70
|
*/
|
|
70
71
|
splitText(offset: number): AstText;
|
|
72
|
+
/**
|
|
73
|
+
* @override
|
|
74
|
+
* @param j 字符位置
|
|
75
|
+
* @throws `RangeError` 超出文本长度范围
|
|
76
|
+
*/
|
|
77
|
+
getRelativeIndex(j?: number): number;
|
|
71
78
|
}
|
|
72
|
-
export = AstText;
|
package/dist/lib/text.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AstText = void 0;
|
|
4
|
+
const index_1 = require("../index");
|
|
5
|
+
const node_1 = require("./node");
|
|
4
6
|
const errorSyntax = /https?:\/\/|\{+|\}+|\[{2,}|\[(?![^[]*\])|(?<=^|\])([^[]*?)\]+|\]{2,}|<\s*\/?([a-z]\w*)/giu, errorSyntaxUrl = /\{+|\}+|\[{2,}|\[(?![^[]*\])|(?<=^|\])([^[]*?)\]+|\]{2,}|<\s*\/?([a-z]\w*)/giu, disallowedTags = [
|
|
5
7
|
'html',
|
|
6
8
|
'base',
|
|
@@ -54,7 +56,7 @@ const errorSyntax = /https?:\/\/|\{+|\}+|\[{2,}|\[(?![^[]*\])|(?<=^|\])([^[]*?)\
|
|
|
54
56
|
'xmp',
|
|
55
57
|
];
|
|
56
58
|
/** 文本节点 */
|
|
57
|
-
class AstText extends AstNode {
|
|
59
|
+
class AstText extends node_1.AstNode {
|
|
58
60
|
/** @browser */
|
|
59
61
|
type = 'text';
|
|
60
62
|
/** @browser */
|
|
@@ -92,6 +94,7 @@ class AstText extends AstNode {
|
|
|
92
94
|
/**
|
|
93
95
|
* Linter
|
|
94
96
|
* @browser
|
|
97
|
+
* @param start
|
|
95
98
|
*/
|
|
96
99
|
lint(start = this.getAbsoluteIndex()) {
|
|
97
100
|
const { data, parentNode, nextSibling, previousSibling } = this, type = parentNode?.type, name = parentNode?.name, nextType = nextSibling?.type, previousType = previousSibling?.type, errorRegex = type === 'free-ext-link' || type === 'ext-link-url' || type === 'image-parameter' && name === 'link'
|
|
@@ -102,12 +105,10 @@ class AstText extends AstNode {
|
|
|
102
105
|
return errors
|
|
103
106
|
.map(({ 0: error, 1: prefix, 2: tag, index }) => {
|
|
104
107
|
if (prefix) {
|
|
105
|
-
/* eslint-disable no-param-reassign */
|
|
106
108
|
index += prefix.length;
|
|
107
109
|
error = error.slice(prefix.length);
|
|
108
|
-
/* eslint-enable no-param-reassign */
|
|
109
110
|
}
|
|
110
|
-
const startIndex = start + index, lines = data.slice(0, index).split('\n'), startLine = lines.length + top - 1, line = lines.at(-1), startCol = lines.length
|
|
111
|
+
const startIndex = start + index, lines = data.slice(0, index).split('\n'), startLine = lines.length + top - 1, line = lines.at(-1), startCol = lines.length === 1 ? left + line.length : line.length, { 0: char, length } = error, endIndex = startIndex + length, end = char === '}' || char === ']' ? endIndex + 1 : startIndex + 49, rootStr = String(root), nextChar = rootStr[endIndex], previousChar = rootStr[startIndex - 1], severity = length > 1 && (char !== '<' || /[\s/>]/u.test(nextChar ?? ''))
|
|
111
112
|
|| char === '{' && (nextChar === char || previousChar === '-')
|
|
112
113
|
|| char === '}' && (previousChar === char || nextChar === '-')
|
|
113
114
|
|| char === '[' && (nextChar === char || type === 'ext-link-text'
|
|
@@ -117,7 +118,7 @@ class AstText extends AstNode {
|
|
|
117
118
|
? 'error'
|
|
118
119
|
: 'warning';
|
|
119
120
|
return (char !== 'h' || index > 0) && (char !== '<' || tags.has(tag.toLowerCase())) && {
|
|
120
|
-
message:
|
|
121
|
+
message: index_1.default.msg('lonely "$1"', char === 'h' ? error : char),
|
|
121
122
|
severity,
|
|
122
123
|
startIndex,
|
|
123
124
|
endIndex,
|
|
@@ -193,10 +194,7 @@ class AstText extends AstNode {
|
|
|
193
194
|
* @throws `Error` 没有父节点
|
|
194
195
|
*/
|
|
195
196
|
splitText(offset) {
|
|
196
|
-
if (
|
|
197
|
-
this.typeError('splitText', 'Number');
|
|
198
|
-
}
|
|
199
|
-
else if (offset > this.length || offset < -this.length) {
|
|
197
|
+
if (offset > this.length || offset < -this.length) {
|
|
200
198
|
throw new RangeError(`错误的断开位置:${offset}`);
|
|
201
199
|
}
|
|
202
200
|
const { parentNode, data } = this;
|
|
@@ -210,6 +208,20 @@ class AstText extends AstNode {
|
|
|
210
208
|
parentNode.setAttribute('childNodes', childNodes);
|
|
211
209
|
return newText;
|
|
212
210
|
}
|
|
211
|
+
/**
|
|
212
|
+
* @override
|
|
213
|
+
* @param j 字符位置
|
|
214
|
+
* @throws `RangeError` 超出文本长度范围
|
|
215
|
+
*/
|
|
216
|
+
getRelativeIndex(j) {
|
|
217
|
+
if (j === undefined) {
|
|
218
|
+
return super.getRelativeIndex();
|
|
219
|
+
}
|
|
220
|
+
else if (j < 0 || j > this.length) {
|
|
221
|
+
throw new RangeError(`超出文本长度范围!`);
|
|
222
|
+
}
|
|
223
|
+
return j;
|
|
224
|
+
}
|
|
213
225
|
}
|
|
214
|
-
|
|
215
|
-
|
|
226
|
+
exports.AstText = AstText;
|
|
227
|
+
index_1.default.classes['AstText'] = __filename;
|
package/dist/lib/title.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import * as Parser from '../index';
|
|
2
1
|
/** MediaWiki页面标题对象 */
|
|
3
|
-
declare class Title {
|
|
2
|
+
export declare class Title {
|
|
4
3
|
/** @browser */
|
|
5
4
|
valid: boolean;
|
|
6
5
|
/** @browser */
|
|
@@ -12,6 +11,7 @@ declare class Title {
|
|
|
12
11
|
main: string;
|
|
13
12
|
prefix: string;
|
|
14
13
|
interwiki: string;
|
|
14
|
+
conversionTable: Map<string, string>;
|
|
15
15
|
redirects: Map<string, string>;
|
|
16
16
|
/** 完整标题 */
|
|
17
17
|
get title(): string;
|
|
@@ -22,13 +22,12 @@ declare class Title {
|
|
|
22
22
|
* @param decode 是否需要解码
|
|
23
23
|
* @param selfLink 是否允许selfLink
|
|
24
24
|
*/
|
|
25
|
-
constructor(str: string, defaultNs?: number, config?:
|
|
25
|
+
constructor(str: string, defaultNs?: number, config?: import("../index").Config, decode?: boolean, selfLink?: boolean);
|
|
26
26
|
/** 完整链接 */
|
|
27
27
|
toString(): string;
|
|
28
28
|
/**
|
|
29
29
|
* 转换
|
|
30
30
|
* @param conversionTable 单向转换表
|
|
31
31
|
*/
|
|
32
|
-
autoConvert(
|
|
32
|
+
autoConvert(): void;
|
|
33
33
|
}
|
|
34
|
-
export = Title;
|
package/dist/lib/title.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Title = void 0;
|
|
2
4
|
const string_1 = require("../util/string");
|
|
3
|
-
const
|
|
5
|
+
const index_1 = require("../index");
|
|
4
6
|
/** MediaWiki页面标题对象 */
|
|
5
7
|
class Title {
|
|
6
8
|
/** @browser */
|
|
@@ -14,10 +16,17 @@ class Title {
|
|
|
14
16
|
main = '';
|
|
15
17
|
prefix = '';
|
|
16
18
|
interwiki = '';
|
|
19
|
+
conversionTable = new Map();
|
|
17
20
|
redirects = new Map();
|
|
18
21
|
/** 完整标题 */
|
|
19
22
|
get title() {
|
|
20
|
-
|
|
23
|
+
let title = `${this.interwiki && `${this.interwiki}:`}${this.prefix}${this.main.replaceAll(' ', '_')}`;
|
|
24
|
+
const redirected = this.redirects.get(title);
|
|
25
|
+
if (redirected) {
|
|
26
|
+
return redirected;
|
|
27
|
+
}
|
|
28
|
+
this.autoConvert();
|
|
29
|
+
title = `${this.interwiki && `${this.interwiki}:`}${this.prefix}${this.main.replaceAll(' ', '_')}`;
|
|
21
30
|
return this.redirects.get(title) ?? title;
|
|
22
31
|
}
|
|
23
32
|
/**
|
|
@@ -27,7 +36,7 @@ class Title {
|
|
|
27
36
|
* @param decode 是否需要解码
|
|
28
37
|
* @param selfLink 是否允许selfLink
|
|
29
38
|
*/
|
|
30
|
-
constructor(str, defaultNs = 0, config =
|
|
39
|
+
constructor(str, defaultNs = 0, config = index_1.default.getConfig(), decode = false, selfLink = false) {
|
|
31
40
|
const { namespaces, nsid } = config;
|
|
32
41
|
let namespace = namespaces[defaultNs], title = (0, string_1.decodeHtml)(str);
|
|
33
42
|
if (decode && title.includes('%')) {
|
|
@@ -43,7 +52,7 @@ class Title {
|
|
|
43
52
|
namespace = '';
|
|
44
53
|
title = title.slice(1).trim();
|
|
45
54
|
}
|
|
46
|
-
const iw = defaultNs ? undefined :
|
|
55
|
+
const iw = defaultNs ? undefined : index_1.default.isInterwiki(title, config);
|
|
47
56
|
if (iw) {
|
|
48
57
|
this.interwiki = iw[1].toLowerCase();
|
|
49
58
|
title = title.slice(iw[0].length);
|
|
@@ -89,12 +98,13 @@ class Title {
|
|
|
89
98
|
* 转换
|
|
90
99
|
* @param conversionTable 单向转换表
|
|
91
100
|
*/
|
|
92
|
-
autoConvert(
|
|
101
|
+
autoConvert() {
|
|
102
|
+
const { conversionTable } = this;
|
|
93
103
|
if (conversionTable.size > 0) {
|
|
94
104
|
const regex = new RegExp([...conversionTable.keys()].sort().reverse().map(string_1.escapeRegExp).join('|'), 'gu');
|
|
95
105
|
this.main = this.main.replace(regex, p => conversionTable.get(p));
|
|
96
106
|
}
|
|
97
107
|
}
|
|
98
108
|
}
|
|
99
|
-
|
|
100
|
-
|
|
109
|
+
exports.Title = Title;
|
|
110
|
+
index_1.default.classes['Title'] = __filename;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.attributesParent = void 0;
|
|
4
|
+
const index_1 = require("../index");
|
|
3
5
|
/**
|
|
4
6
|
* 子节点含有AttributesToken的类
|
|
5
7
|
* @param constructor 基类
|
|
6
8
|
* @param i AttributesToken子节点的位置
|
|
7
9
|
*/
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
8
11
|
const attributesParent = (constructor, i = 0) => {
|
|
9
12
|
/** 子节点含有AttributesToken的类 */
|
|
10
13
|
class AttributesParent extends constructor {
|
|
@@ -86,5 +89,5 @@ const attributesParent = (constructor, i = 0) => {
|
|
|
86
89
|
}
|
|
87
90
|
return AttributesParent;
|
|
88
91
|
};
|
|
89
|
-
|
|
90
|
-
|
|
92
|
+
exports.attributesParent = attributesParent;
|
|
93
|
+
index_1.default.mixins['attributesParent'] = __filename;
|