wikiparser-node 0.5.0 → 0.6.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.
Files changed (63) hide show
  1. package/config/default.json +129 -66
  2. package/config/zhwiki.json +4 -4
  3. package/index.js +74 -65
  4. package/lib/element.js +125 -152
  5. package/lib/node.js +251 -223
  6. package/lib/ranges.js +2 -2
  7. package/lib/text.js +64 -64
  8. package/lib/title.js +8 -7
  9. package/mixin/hidden.js +2 -0
  10. package/mixin/sol.js +1 -2
  11. package/package.json +4 -3
  12. package/parser/brackets.js +8 -2
  13. package/parser/externalLinks.js +1 -1
  14. package/parser/hrAndDoubleUnderscore.js +4 -4
  15. package/parser/links.js +7 -7
  16. package/parser/table.js +12 -10
  17. package/src/arg.js +53 -48
  18. package/src/atom/index.js +7 -5
  19. package/src/attribute.js +91 -80
  20. package/src/charinsert.js +91 -0
  21. package/src/converter.js +22 -11
  22. package/src/converterFlags.js +72 -62
  23. package/src/converterRule.js +49 -49
  24. package/src/extLink.js +30 -28
  25. package/src/gallery.js +56 -32
  26. package/src/hasNowiki/index.js +42 -0
  27. package/src/hasNowiki/pre.js +40 -0
  28. package/src/heading.js +15 -11
  29. package/src/html.js +38 -38
  30. package/src/imageParameter.js +64 -48
  31. package/src/imagemap.js +205 -0
  32. package/src/imagemapLink.js +43 -0
  33. package/src/index.js +222 -124
  34. package/src/link/category.js +4 -8
  35. package/src/link/file.js +95 -59
  36. package/src/link/galleryImage.js +74 -10
  37. package/src/link/index.js +61 -39
  38. package/src/magicLink.js +21 -22
  39. package/src/nested/choose.js +24 -0
  40. package/src/nested/combobox.js +23 -0
  41. package/src/nested/index.js +88 -0
  42. package/src/nested/references.js +23 -0
  43. package/src/nowiki/comment.js +17 -17
  44. package/src/nowiki/dd.js +2 -2
  45. package/src/nowiki/doubleUnderscore.js +14 -14
  46. package/src/nowiki/index.js +12 -0
  47. package/src/onlyinclude.js +10 -8
  48. package/src/paramTag/index.js +83 -0
  49. package/src/paramTag/inputbox.js +42 -0
  50. package/src/parameter.js +32 -18
  51. package/src/syntax.js +9 -1
  52. package/src/table/index.js +33 -32
  53. package/src/table/td.js +51 -57
  54. package/src/table/tr.js +6 -6
  55. package/src/tagPair/ext.js +58 -40
  56. package/src/tagPair/include.js +1 -1
  57. package/src/tagPair/index.js +21 -20
  58. package/src/transclude.js +158 -143
  59. package/tool/index.js +720 -439
  60. package/util/base.js +17 -0
  61. package/util/debug.js +1 -1
  62. package/util/diff.js +1 -1
  63. package/util/string.js +20 -20
package/lib/node.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const {typeError, externalUse} = require('../util/debug'),
3
+ const {typeError} = require('../util/debug'),
4
4
  {text} = require('../util/string'),
5
5
  assert = require('assert/strict'),
6
6
  EventEmitter = require('events'),
@@ -21,11 +21,11 @@ class AstNode {
21
21
  * @throws `RangeError` 指定位置不存在子节点
22
22
  */
23
23
  #verifyChild = (i, addition = 0) => {
24
- if (typeof i !== 'number') {
24
+ if (!Number.isInteger(i)) {
25
25
  this.typeError('verifyChild', 'Number');
26
26
  }
27
27
  const {childNodes: {length}} = this;
28
- if (i < -length || i >= length + addition || !Number.isInteger(i)) {
28
+ if (i < -length || i >= length + addition) {
29
29
  throw new RangeError(`不存在第 ${i} 个子节点!`);
30
30
  }
31
31
  };
@@ -45,17 +45,6 @@ class AstNode {
45
45
  return this.#parentNode;
46
46
  }
47
47
 
48
- /** 是否具有根节点 */
49
- get isConnected() {
50
- return this.getRootNode().type === 'root';
51
- }
52
-
53
- /** 不是自身的根节点 */
54
- get ownerDocument() {
55
- const root = this.getRootNode();
56
- return root.type === 'root' && root !== this ? root : undefined;
57
- }
58
-
59
48
  /**
60
49
  * 后一个兄弟节点
61
50
  * @complexity `n`
@@ -96,6 +85,17 @@ class AstNode {
96
85
  return childNodes?.slice(0, i)?.findLast(({type}) => type !== 'text');
97
86
  }
98
87
 
88
+ /** 是否具有根节点 */
89
+ get isConnected() {
90
+ return this.getRootNode().type === 'root';
91
+ }
92
+
93
+ /** 不是自身的根节点 */
94
+ get ownerDocument() {
95
+ const root = this.getRootNode();
96
+ return root.type === 'root' && root !== this ? root : undefined;
97
+ }
98
+
99
99
  /**
100
100
  * 后方是否还有其他节点(不含后代)
101
101
  * @returns {boolean}
@@ -113,9 +113,14 @@ class AstNode {
113
113
  return nextSibling === undefined && parentNode?.eof;
114
114
  }
115
115
 
116
+ constructor() {
117
+ Object.defineProperty(this, 'childNodes', {writable: false});
118
+ Object.freeze(this.childNodes);
119
+ }
120
+
116
121
  /**
117
122
  * 标记仅用于代码调试的方法
118
- * @param {string} method 方法名称
123
+ * @param {string} method
119
124
  * @throws `Error`
120
125
  */
121
126
  debugOnly(method = 'debugOnly') {
@@ -124,7 +129,7 @@ class AstNode {
124
129
 
125
130
  /**
126
131
  * 抛出`TypeError`
127
- * @param {string} method 方法名称
132
+ * @param {string} method
128
133
  * @param {...string} types 可接受的参数类型
129
134
  */
130
135
  typeError(method, ...types) {
@@ -146,17 +151,12 @@ class AstNode {
146
151
  }
147
152
  for (const key of keys) {
148
153
  Object.defineProperty(this, key, {
149
- writable: false, enumerable: Boolean(this[key]), configurable: !permanent,
154
+ writable: false, enumerable: !permanent && Boolean(this[key]), configurable: !permanent,
150
155
  });
151
156
  }
152
157
  return this;
153
158
  }
154
159
 
155
- constructor() {
156
- Object.defineProperty(this, 'childNodes', {writable: false});
157
- Object.freeze(this.childNodes);
158
- }
159
-
160
160
  /**
161
161
  * 是否是全同节点
162
162
  * @param {this} node 待比较的节点
@@ -174,32 +174,6 @@ class AstNode {
174
174
  return true;
175
175
  }
176
176
 
177
- /**
178
- * 是否具有某属性
179
- * @param {PropertyKey} key 属性键
180
- */
181
- hasAttribute(key) {
182
- const type = typeof key;
183
- return type === 'string' || type === 'number' || type === 'symbol'
184
- ? key in this
185
- : this.typeError('hasAttribute', 'String', 'Number', 'Symbol');
186
- }
187
-
188
- /**
189
- * 获取属性值。除非用于私有属性,否则总是返回字符串。
190
- * @template {string} T
191
- * @param {T} key 属性键
192
- * @returns {TokenAttribute<T>}
193
- */
194
- getAttribute(key) {
195
- if (key === 'optional') {
196
- return [...this.#optional];
197
- } else if (key === 'verifyChild') {
198
- return this.#verifyChild;
199
- }
200
- return this.hasAttribute(key) ? String(this[key]) : undefined;
201
- }
202
-
203
177
  /** 获取所有属性键 */
204
178
  getAttributeNames() {
205
179
  const names = Object.getOwnPropertyNames(this);
@@ -211,38 +185,6 @@ class AstNode {
211
185
  return this.getAttributeNames().length > 0;
212
186
  }
213
187
 
214
- /**
215
- * 设置属性
216
- * @template {string} T
217
- * @param {T} key 属性键
218
- * @param {TokenAttribute<T>} value 属性值
219
- * @throws `RangeError` 禁止手动指定的属性
220
- */
221
- setAttribute(key, value) {
222
- if (key === 'parentNode') {
223
- if (externalUse('setAttribute')) {
224
- throw new RangeError(`禁止手动指定 ${key} 属性!`);
225
- }
226
- this.#parentNode = value;
227
- } else if (this.hasAttribute(key)) {
228
- const descriptor = Object.getOwnPropertyDescriptor(this, key);
229
- if (!descriptor || !descriptor.writable && externalUse('setAttribute')) {
230
- throw new RangeError(`禁止手动指定 ${key} 属性!`);
231
- } else if (this.#optional.includes(key)) {
232
- descriptor.enumerable = Boolean(value);
233
- }
234
- const oldValue = this[key],
235
- frozen = oldValue !== null && typeof oldValue === 'object' && Object.isFrozen(oldValue);
236
- Object.defineProperty(this, key, {...descriptor, value});
237
- if (frozen && value !== null && typeof value === 'object') {
238
- Object.freeze(value);
239
- }
240
- } else {
241
- this[key] = value;
242
- }
243
- return this;
244
- }
245
-
246
188
  /**
247
189
  * 移除某属性
248
190
  * @param {PropertyKey} key 属性键
@@ -274,116 +216,55 @@ class AstNode {
274
216
  }
275
217
 
276
218
  /**
277
- * 可见部分
278
- * @param {string} separator 子节点间的连接符
279
- * @returns {string}
280
- * @complexity `n`
281
- */
282
- text(separator = '') {
283
- return text(this.childNodes, separator);
284
- }
285
-
286
- /** 是否具有子节点 */
287
- hasChildNodes() {
288
- return this.childNodes.length > 0;
289
- }
290
-
291
- /**
292
- * 是自身或后代节点
293
- * @param {this} node 待检测节点
294
- * @returns {boolean}
295
- * @complexity `n`
219
+ * 是否具有某属性
220
+ * @param {PropertyKey} key 属性键
296
221
  */
297
- contains(node) {
298
- return node instanceof AstNode
299
- ? node === this || this.childNodes.some(child => child.contains(node))
300
- : this.typeError('contains', 'AstNode');
222
+ hasAttribute(key) {
223
+ const type = typeof key;
224
+ return type === 'string' || type === 'number' || type === 'symbol'
225
+ ? key in this
226
+ : this.typeError('hasAttribute', 'String', 'Number', 'Symbol');
301
227
  }
302
228
 
303
229
  /**
304
- * 添加事件监听
305
- * @param {string|string[]} types 事件类型
306
- * @param {AstListener} listener 监听函数
307
- * @param {{once: boolean}} options 选项
230
+ * 获取属性值。除非用于私有属性,否则总是返回字符串。
231
+ * @template {string} T
232
+ * @param {T} key 属性键
233
+ * @returns {TokenAttribute<T>}
308
234
  */
309
- addEventListener(types, listener, options) {
310
- if (Array.isArray(types)) {
311
- for (const type of types) {
312
- this.addEventListener(type, listener, options);
313
- }
314
- } else if (typeof types !== 'string' || typeof listener !== 'function') {
315
- this.typeError('addEventListener', 'String', 'Function');
316
- } else {
317
- this.#events[options?.once ? 'once' : 'on'](types, listener);
235
+ getAttribute(key) {
236
+ if (key === 'optional') {
237
+ return [...this.#optional];
238
+ } else if (key === 'verifyChild') {
239
+ return this.#verifyChild;
318
240
  }
241
+ return this.hasAttribute(key) ? String(this[key]) : undefined;
319
242
  }
320
243
 
321
244
  /**
322
- * 移除事件监听
323
- * @param {string|string[]} types 事件类型
324
- * @param {AstListener} listener 监听函数
245
+ * 设置属性
246
+ * @template {string} T
247
+ * @param {T} key 属性键
248
+ * @param {TokenAttribute<T>} value 属性值
325
249
  */
326
- removeEventListener(types, listener) {
327
- if (Array.isArray(types)) {
328
- for (const type of types) {
329
- this.removeEventListener(type, listener);
250
+ setAttribute(key, value) {
251
+ if (key === 'parentNode') {
252
+ this.#parentNode = value;
253
+ } else if (Object.hasOwn(this, key)) {
254
+ const descriptor = Object.getOwnPropertyDescriptor(this, key);
255
+ if (this.#optional.includes(key)) {
256
+ descriptor.enumerable = Boolean(value);
330
257
  }
331
- } else if (typeof types !== 'string' || typeof listener !== 'function') {
332
- this.typeError('removeEventListener', 'String', 'Function');
333
- } else {
334
- this.#events.off(types, listener);
335
- }
336
- }
337
-
338
- /**
339
- * 移除事件的所有监听
340
- * @param {string|string[]} types 事件类型
341
- */
342
- removeAllEventListeners(types) {
343
- if (Array.isArray(types)) {
344
- for (const type of types) {
345
- this.removeAllEventListeners(type);
258
+ const oldValue = this[key],
259
+ frozen = oldValue !== null && typeof oldValue === 'object' && Object.isFrozen(oldValue);
260
+ Object.defineProperty(this, key, {...descriptor, value});
261
+ if (frozen && value !== null && typeof value === 'object') {
262
+ Object.freeze(value);
346
263
  }
347
- } else if (types !== undefined && typeof types !== 'string') {
348
- this.typeError('removeAllEventListeners', 'String');
349
264
  } else {
350
- this.#events.removeAllListeners(types);
351
- }
352
- }
353
-
354
- /**
355
- * 列举事件监听
356
- * @param {string} type 事件类型
357
- * @returns {AstListener[]}
358
- */
359
- listEventListeners(type) {
360
- return typeof type === 'string' ? this.#events.listeners(type) : this.typeError('listEventListeners', 'String');
361
- }
362
-
363
- /**
364
- * 触发事件
365
- * @param {AstEvent} e 事件对象
366
- * @param {any} data 事件数据
367
- */
368
- dispatchEvent(e, data) {
369
- if (!(e instanceof Event)) {
370
- this.typeError('dispatchEvent', 'Event');
371
- } else if (!e.target) { // 初始化
372
- Object.defineProperty(e, 'target', {value: this, enumerable: true});
373
-
374
- /** 终止冒泡 */
375
- e.stopPropagation = function() {
376
- Object.defineProperty(this, 'bubbles', {value: false});
377
- };
378
- }
379
- Object.defineProperties(e, { // 每次bubble更新
380
- prevTarget: {value: e.currentTarget, enumerable: true, configurable: true},
381
- currentTarget: {value: this, enumerable: true, configurable: true},
382
- });
383
- this.#events.emit(e.type, e, data);
384
- if (e.bubbles && this.parentNode) {
385
- this.parentNode.dispatchEvent(e, data);
265
+ this[key] = value;
386
266
  }
267
+ return this;
387
268
  }
388
269
 
389
270
  /**
@@ -396,34 +277,8 @@ class AstNode {
396
277
  [node] = childNodes.splice(i, 1),
397
278
  e = new Event('remove', {bubbles: true});
398
279
  node.setAttribute('parentNode');
399
- this.setAttribute('childNodes', childNodes).dispatchEvent(e, {position: i, removed: node});
400
- return node;
401
- }
402
-
403
- /**
404
- * 获取子节点的位置
405
- * @param {this} node 子节点
406
- * @complexity `n`
407
- * @throws `RangeError` 找不到子节点
408
- */
409
- #getChildIndex(node) {
410
- const {childNodes} = this,
411
- i = childNodes.indexOf(node);
412
- if (i === -1) {
413
- Parser.error('找不到子节点!', node);
414
- throw new RangeError('找不到子节点!');
415
- }
416
- return i;
417
- }
418
-
419
- /**
420
- * 移除子节点
421
- * @template {this} T
422
- * @param {T} node 子节点
423
- * @complexity `n`
424
- */
425
- removeChild(node) {
426
- this.removeAt(this.#getChildIndex(node));
280
+ this.setAttribute('childNodes', childNodes);
281
+ this.dispatchEvent(e, {position: i, removed: node});
427
282
  return node;
428
283
  }
429
284
 
@@ -453,8 +308,35 @@ class AstNode {
453
308
  childNodes.splice(j, 1);
454
309
  }
455
310
  childNodes.splice(i, 0, node);
456
- this.setAttribute('childNodes', childNodes)
457
- .dispatchEvent(e, {position: i < 0 ? i + this.childNodes.length - 1 : i, inserted: node});
311
+ this.setAttribute('childNodes', childNodes);
312
+ this.dispatchEvent(e, {position: i < 0 ? i + this.childNodes.length - 1 : i, inserted: node});
313
+ return node;
314
+ }
315
+
316
+ /**
317
+ * 获取子节点的位置
318
+ * @param {this} node 子节点
319
+ * @complexity `n`
320
+ * @throws `RangeError` 找不到子节点
321
+ */
322
+ #getChildIndex(node) {
323
+ const {childNodes} = this,
324
+ i = childNodes.indexOf(node);
325
+ if (i === -1) {
326
+ Parser.error('找不到子节点!', node);
327
+ throw new RangeError('找不到子节点!');
328
+ }
329
+ return i;
330
+ }
331
+
332
+ /**
333
+ * 移除子节点
334
+ * @template {this} T
335
+ * @param {T} node 子节点
336
+ * @complexity `n`
337
+ */
338
+ removeChild(node) {
339
+ this.removeAt(this.#getChildIndex(node));
458
340
  return node;
459
341
  }
460
342
 
@@ -476,7 +358,7 @@ class AstNode {
476
358
  * @complexity `n`
477
359
  */
478
360
  insertBefore(child, reference) {
479
- return reference === undefined ? this.appendChild(child) : this.insertAt(child, this.#getChildIndex(reference));
361
+ return reference === undefined ? this.insertAt(child) : this.insertAt(child, this.#getChildIndex(reference));
480
362
  }
481
363
 
482
364
  /**
@@ -552,6 +434,156 @@ class AstNode {
552
434
  this.remove();
553
435
  }
554
436
 
437
+ /**
438
+ * 可见部分
439
+ * @param {string} separator 子节点间的连接符
440
+ * @returns {string}
441
+ * @complexity `n`
442
+ */
443
+ text(separator = '') {
444
+ return text(this.childNodes, separator);
445
+ }
446
+
447
+ /** 是否具有子节点 */
448
+ hasChildNodes() {
449
+ return this.childNodes.length > 0;
450
+ }
451
+
452
+ /**
453
+ * 是自身或后代节点
454
+ * @param {this} node 待检测节点
455
+ * @returns {boolean}
456
+ * @complexity `n`
457
+ */
458
+ contains(node) {
459
+ return node instanceof AstNode
460
+ ? node === this || this.childNodes.some(child => child.contains(node))
461
+ : this.typeError('contains', 'AstNode');
462
+ }
463
+
464
+ /**
465
+ * 添加事件监听
466
+ * @param {string|string[]} types 事件类型
467
+ * @param {AstListener} listener 监听函数
468
+ * @param {{once: boolean}} options 选项
469
+ */
470
+ addEventListener(types, listener, options) {
471
+ if (Array.isArray(types)) {
472
+ for (const type of types) {
473
+ this.addEventListener(type, listener, options);
474
+ }
475
+ } else if (typeof types === 'string' && typeof listener === 'function') {
476
+ this.#events[options?.once ? 'once' : 'on'](types, listener);
477
+ } else {
478
+ this.typeError('addEventListener', 'String', 'Function');
479
+ }
480
+ }
481
+
482
+ /**
483
+ * 移除事件监听
484
+ * @param {string|string[]} types 事件类型
485
+ * @param {AstListener} listener 监听函数
486
+ */
487
+ removeEventListener(types, listener) {
488
+ if (Array.isArray(types)) {
489
+ for (const type of types) {
490
+ this.removeEventListener(type, listener);
491
+ }
492
+ } else if (typeof types === 'string' && typeof listener === 'function') {
493
+ this.#events.off(types, listener);
494
+ } else {
495
+ this.typeError('removeEventListener', 'String', 'Function');
496
+ }
497
+ }
498
+
499
+ /**
500
+ * 移除事件的所有监听
501
+ * @param {string|string[]} types 事件类型
502
+ */
503
+ removeAllEventListeners(types) {
504
+ if (Array.isArray(types)) {
505
+ for (const type of types) {
506
+ this.removeAllEventListeners(type);
507
+ }
508
+ } else if (types === undefined || typeof types === 'string') {
509
+ this.#events.removeAllListeners(types);
510
+ } else {
511
+ this.typeError('removeAllEventListeners', 'String');
512
+ }
513
+ }
514
+
515
+ /**
516
+ * 列举事件监听
517
+ * @param {string} type 事件类型
518
+ * @returns {AstListener[]}
519
+ */
520
+ listEventListeners(type) {
521
+ return typeof type === 'string' ? this.#events.listeners(type) : this.typeError('listEventListeners', 'String');
522
+ }
523
+
524
+ /**
525
+ * 触发事件
526
+ * @param {AstEvent} e 事件对象
527
+ * @param {*} data 事件数据
528
+ */
529
+ dispatchEvent(e, data) {
530
+ if (!(e instanceof Event)) {
531
+ this.typeError('dispatchEvent', 'Event');
532
+ } else if (!e.target) { // 初始化
533
+ Object.defineProperty(e, 'target', {value: this, enumerable: true});
534
+
535
+ /** 终止冒泡 */
536
+ e.stopPropagation = function() {
537
+ Object.defineProperty(this, 'bubbles', {value: false});
538
+ };
539
+ }
540
+ Object.defineProperties(e, { // 每次bubble更新
541
+ prevTarget: {value: e.currentTarget, enumerable: true, configurable: true},
542
+ currentTarget: {value: this, enumerable: true, configurable: true},
543
+ });
544
+ this.#events.emit(e.type, e, data);
545
+ if (e.bubbles && this.parentNode) {
546
+ this.parentNode.dispatchEvent(e, data);
547
+ }
548
+ }
549
+
550
+ /** 获取所有祖先节点 */
551
+ getAncestors() {
552
+ const /** @type {this[]} */ ancestors = [];
553
+ let {parentNode} = this;
554
+ while (parentNode) {
555
+ ancestors.push(parentNode);
556
+ ({parentNode} = parentNode);
557
+ }
558
+ return ancestors;
559
+ }
560
+
561
+ /**
562
+ * 比较和另一个节点的相对位置
563
+ * @param {this} other 待比较的节点
564
+ * @complexity `n`
565
+ * @throws `Error` 不在同一个语法树
566
+ */
567
+ compareDocumentPosition(other) {
568
+ if (!(other instanceof AstNode)) {
569
+ this.typeError('compareDocumentPosition', 'AstNode');
570
+ } else if (this === other) {
571
+ return 0;
572
+ } else if (this.contains(other)) {
573
+ return -1;
574
+ } else if (other.contains(this)) {
575
+ return 1;
576
+ } else if (this.getRootNode() !== other.getRootNode()) {
577
+ throw new Error('不在同一个语法树!');
578
+ }
579
+ const aAncestors = [...this.getAncestors().reverse(), this],
580
+ bAncestors = [...other.getAncestors().reverse(), other],
581
+ depth = aAncestors.findIndex((ancestor, i) => bAncestors[i] !== ancestor),
582
+ commonAncestor = aAncestors[depth - 1],
583
+ {childNodes} = commonAncestor;
584
+ return childNodes.indexOf(aAncestors[depth]) - childNodes.indexOf(bAncestors[depth]);
585
+ }
586
+
555
587
  /**
556
588
  * 合并相邻的文本子节点
557
589
  * @complexity `n`
@@ -588,11 +620,11 @@ class AstNode {
588
620
  * @complexity `n`
589
621
  */
590
622
  posFromIndex(index) {
591
- if (typeof index !== 'number') {
623
+ if (!Number.isInteger(index)) {
592
624
  this.typeError('posFromIndex', 'Number');
593
625
  }
594
626
  const str = String(this);
595
- if (index >= -str.length && index <= str.length && Number.isInteger(index)) {
627
+ if (index >= -str.length && index <= str.length) {
596
628
  const lines = str.slice(0, index).split('\n');
597
629
  return {top: lines.length - 1, left: lines.at(-1).length};
598
630
  }
@@ -606,12 +638,11 @@ class AstNode {
606
638
  * @complexity `n`
607
639
  */
608
640
  indexFromPos(top, left) {
609
- if (typeof top !== 'number' || typeof left !== 'number') {
641
+ if (!Number.isInteger(top) || !Number.isInteger(left)) {
610
642
  this.typeError('indexFromPos', 'Number');
611
643
  }
612
644
  const lines = String(this).split('\n');
613
- return top >= 0 && left >= 0 && Number.isInteger(top) && Number.isInteger(left)
614
- && lines.length >= top + 1 && lines[top].length >= left
645
+ return top >= 0 && left >= 0 && lines.length >= top + 1 && lines[top].length >= left
615
646
  ? lines.slice(0, top).reduce((acc, curLine) => acc + curLine.length + 1, 0) + left
616
647
  : undefined;
617
648
  }
@@ -641,9 +672,6 @@ class AstNode {
641
672
  * @complexity `n`
642
673
  */
643
674
  getRelativeIndex(j) {
644
- if (j !== undefined && typeof j !== 'number') {
645
- this.typeError('getRelativeIndex', 'Number');
646
- }
647
675
  let /** @type {this[]} */ childNodes;
648
676
 
649
677
  /**
@@ -714,6 +742,14 @@ class AstNode {
714
742
  return this.#getDimension().width;
715
743
  }
716
744
 
745
+ /**
746
+ * 位置、大小和padding
747
+ * @complexity `n`
748
+ */
749
+ get style() {
750
+ return {...this.#getPosition(), ...this.#getDimension(), padding: this.getPadding()};
751
+ }
752
+
717
753
  /**
718
754
  * 相对于父容器的行号
719
755
  * @complexity `n`
@@ -729,14 +765,6 @@ class AstNode {
729
765
  get offsetLeft() {
730
766
  return this.#getPosition().left;
731
767
  }
732
-
733
- /**
734
- * 位置、大小和padding
735
- * @complexity `n`
736
- */
737
- get style() {
738
- return {...this.#getPosition(), ...this.#getDimension(), padding: this.getPadding()};
739
- }
740
768
  }
741
769
 
742
770
  Parser.classes.AstNode = __filename;
package/lib/ranges.js CHANGED
@@ -62,7 +62,7 @@ class Range {
62
62
 
63
63
  /**
64
64
  * 将Range转换为针对特定数组的下标集
65
- * @param {number|any[]} arr 参考数组
65
+ * @param {number|*[]} arr 参考数组
66
66
  * @complexity `n`
67
67
  */
68
68
  applyTo(arr) {
@@ -99,7 +99,7 @@ class Ranges extends Array {
99
99
 
100
100
  /**
101
101
  * 将Ranges转换为针对特定Array的下标集
102
- * @param {number|any[]} arr 参考数组
102
+ * @param {number|*[]} arr 参考数组
103
103
  * @complexity `n`
104
104
  */
105
105
  applyTo(arr) {