wikiparser-node 1.9.2 → 1.9.3

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 (110) hide show
  1. package/dist/base.d.ts +9 -3
  2. package/dist/index.js +0 -1
  3. package/dist/lib/element.d.ts +1 -0
  4. package/dist/lib/element.js +23 -249
  5. package/dist/lib/node.d.ts +3 -1
  6. package/dist/lib/range.js +12 -12
  7. package/dist/lib/text.d.ts +2 -1
  8. package/dist/lib/text.js +8 -2
  9. package/dist/mixin/hidden.js +5 -0
  10. package/dist/mixin/syntax.js +2 -1
  11. package/dist/parser/selector.js +223 -20
  12. package/dist/parser/table.js +3 -3
  13. package/dist/src/arg.d.ts +1 -2
  14. package/dist/src/arg.js +3 -2
  15. package/dist/src/atom.d.ts +5 -3
  16. package/dist/src/atom.js +28 -2
  17. package/dist/src/attribute.d.ts +1 -2
  18. package/dist/src/attribute.js +5 -2
  19. package/dist/src/attributes.d.ts +1 -2
  20. package/dist/src/attributes.js +7 -2
  21. package/dist/src/converter.d.ts +1 -2
  22. package/dist/src/converter.js +5 -2
  23. package/dist/src/converterFlags.d.ts +1 -2
  24. package/dist/src/converterFlags.js +5 -2
  25. package/dist/src/converterRule.d.ts +1 -3
  26. package/dist/src/converterRule.js +5 -3
  27. package/dist/src/extLink.d.ts +1 -2
  28. package/dist/src/extLink.js +5 -2
  29. package/dist/src/gallery.d.ts +1 -2
  30. package/dist/src/gallery.js +7 -4
  31. package/dist/src/heading.d.ts +1 -2
  32. package/dist/src/heading.js +3 -2
  33. package/dist/src/hidden.d.ts +1 -2
  34. package/dist/src/hidden.js +3 -2
  35. package/dist/src/html.d.ts +1 -2
  36. package/dist/src/html.js +3 -2
  37. package/dist/src/imageParameter.d.ts +1 -2
  38. package/dist/src/imageParameter.js +3 -2
  39. package/dist/src/imagemap.d.ts +1 -2
  40. package/dist/src/imagemap.js +3 -2
  41. package/dist/src/imagemapLink.d.ts +1 -1
  42. package/dist/src/imagemapLink.js +5 -1
  43. package/dist/src/index.d.ts +2 -1
  44. package/dist/src/index.js +26 -1
  45. package/dist/src/link/base.d.ts +1 -2
  46. package/dist/src/link/base.js +5 -3
  47. package/dist/src/link/category.d.ts +1 -1
  48. package/dist/src/link/category.js +5 -1
  49. package/dist/src/link/file.d.ts +1 -1
  50. package/dist/src/link/file.js +3 -1
  51. package/dist/src/link/galleryImage.d.ts +1 -2
  52. package/dist/src/link/galleryImage.js +7 -33
  53. package/dist/src/link/index.d.ts +1 -2
  54. package/dist/src/link/index.js +5 -2
  55. package/dist/src/link/redirectTarget.d.ts +1 -2
  56. package/dist/src/link/redirectTarget.js +5 -2
  57. package/dist/src/magicLink.d.ts +2 -2
  58. package/dist/src/magicLink.js +8 -5
  59. package/dist/src/nested.d.ts +1 -2
  60. package/dist/src/nested.js +3 -2
  61. package/dist/src/nowiki/base.d.ts +1 -2
  62. package/dist/src/nowiki/base.js +1 -3
  63. package/dist/src/nowiki/comment.d.ts +1 -2
  64. package/dist/src/nowiki/comment.js +3 -2
  65. package/dist/src/nowiki/dd.d.ts +1 -1
  66. package/dist/src/nowiki/dd.js +3 -1
  67. package/dist/src/nowiki/doubleUnderscore.d.ts +1 -2
  68. package/dist/src/nowiki/doubleUnderscore.js +3 -2
  69. package/dist/src/nowiki/hr.d.ts +1 -1
  70. package/dist/src/nowiki/hr.js +3 -1
  71. package/dist/src/nowiki/index.d.ts +1 -1
  72. package/dist/src/nowiki/index.js +3 -1
  73. package/dist/src/nowiki/list.d.ts +1 -1
  74. package/dist/src/nowiki/list.js +3 -1
  75. package/dist/src/nowiki/listBase.d.ts +1 -1
  76. package/dist/src/nowiki/noinclude.d.ts +1 -5
  77. package/dist/src/nowiki/noinclude.js +3 -5
  78. package/dist/src/nowiki/quote.d.ts +1 -4
  79. package/dist/src/nowiki/quote.js +3 -4
  80. package/dist/src/onlyinclude.d.ts +1 -2
  81. package/dist/src/onlyinclude.js +3 -2
  82. package/dist/src/paramTag/index.d.ts +1 -2
  83. package/dist/src/paramTag/index.js +3 -2
  84. package/dist/src/parameter.d.ts +1 -7
  85. package/dist/src/parameter.js +3 -7
  86. package/dist/src/pre.d.ts +1 -2
  87. package/dist/src/pre.js +3 -2
  88. package/dist/src/redirect.d.ts +1 -2
  89. package/dist/src/redirect.js +3 -2
  90. package/dist/src/syntax.d.ts +4 -4
  91. package/dist/src/syntax.js +6 -3
  92. package/dist/src/table/base.d.ts +1 -2
  93. package/dist/src/table/base.js +0 -1
  94. package/dist/src/table/index.d.ts +1 -10
  95. package/dist/src/table/index.js +3 -10
  96. package/dist/src/table/td.d.ts +1 -7
  97. package/dist/src/table/td.js +3 -7
  98. package/dist/src/table/tr.d.ts +1 -1
  99. package/dist/src/table/tr.js +3 -1
  100. package/dist/src/table/trBase.d.ts +1 -1
  101. package/dist/src/tagPair/ext.d.ts +1 -2
  102. package/dist/src/tagPair/ext.js +7 -4
  103. package/dist/src/tagPair/include.d.ts +1 -3
  104. package/dist/src/tagPair/include.js +5 -3
  105. package/dist/src/tagPair/index.d.ts +1 -1
  106. package/dist/src/transclude.d.ts +1 -2
  107. package/dist/src/transclude.js +8 -5
  108. package/dist/util/constants.js +2 -2
  109. package/dist/util/debug.js +0 -2
  110. package/package.json +1 -1
package/dist/base.d.ts CHANGED
@@ -53,8 +53,14 @@ export interface AstNode {
53
53
  /** 以HTML格式打印 */
54
54
  print(): string;
55
55
  }
56
- /** 类似HTMLElement */
57
- interface AstElement extends AstNode {
56
+ /** 所有节点的基类 */
57
+ interface Token extends AstNode {
58
+ readonly name?: string;
59
+ /**
60
+ * 符合选择器的所有后代节点
61
+ * @param selector 选择器
62
+ */
63
+ querySelectorAll<T = Token>(selector: string): T[];
58
64
  /** 保存为JSON */
59
65
  json(): AST;
60
66
  }
@@ -68,6 +74,6 @@ export interface Parser {
68
74
  * @param include 是否嵌入
69
75
  * @param maxStage 最大解析层级
70
76
  */
71
- parse(wikitext: string, include?: boolean, maxStage?: number, config?: Config): AstElement;
77
+ parse(wikitext: string, include?: boolean, maxStage?: number, config?: Config): Token;
72
78
  }
73
79
  export {};
package/dist/index.js CHANGED
@@ -159,7 +159,6 @@ const Parser = {
159
159
  ...Object.entries(constants_1.classes),
160
160
  ...Object.entries(constants_1.mixins),
161
161
  ...Object.entries(constants_1.parsers),
162
- ...Object.entries(constants_1.constants),
163
162
  ];
164
163
  for (const [, filePath] of entries) {
165
164
  try {
@@ -8,6 +8,7 @@ export declare abstract class AstElement extends AstNode {
8
8
  readonly data: undefined;
9
9
  /** 子节点总数 */
10
10
  get length(): number;
11
+ set length(n: number);
11
12
  /** 全部非文本子节点 */
12
13
  get children(): Token[];
13
14
  /** 首位非文本子节点 */
@@ -6,34 +6,21 @@ const path = require("path");
6
6
  const string_1 = require("../util/string");
7
7
  const debug_1 = require("../util/debug");
8
8
  const constants_1 = require("../util/constants");
9
- const ranges_1 = require("./ranges");
10
- const title_1 = require("./title");
11
9
  const node_1 = require("./node");
12
- /* NOT FOR BROWSER */
13
10
  /**
14
- * optionally convert to lower cases
15
- * @param val 属性值
16
- * @param i 是否对大小写不敏感
11
+ * 将选择器转化为类型谓词
12
+ * @param selector 选择器
17
13
  */
18
- const toCase = (val, i) => i ? val.toLowerCase() : val;
19
- /**
20
- * 检查某个下标是否符合表达式
21
- * @param str 表达式
22
- * @param i 待检查的下标
23
- */
24
- const nth = (str, i) => new ranges_1.Ranges(str).applyTo(i + 1).includes(i);
25
- /**
26
- * 检测:lang()伪选择器
27
- * @param node 节点
28
- * @param node.attributes 节点属性
29
- * @param regex 语言正则
30
- */
31
- const matchesLang = ({ attributes }, regex) => {
32
- const lang = attributes?.['lang'];
33
- return lang === undefined ? undefined : typeof lang === 'string' && regex.test(lang);
14
+ const getCondition = (selector) => {
15
+ /* NOT FOR BROWSER */
16
+ if (/[^a-z\-,\s]/u.test(selector)) {
17
+ const { checkToken } = require('../parser/selector');
18
+ return checkToken(selector);
19
+ }
20
+ /* NOT FOR BROWSER END */
21
+ const types = new Set(selector.split(',').map(str => str.trim()));
22
+ return (({ type }) => types.has(type));
34
23
  };
35
- const primitives = new Set(['string', 'number', 'boolean', 'undefined']);
36
- /* NOT FOR BROWSER END */
37
24
  /** 类似HTMLElement */
38
25
  class AstElement extends node_1.AstNode {
39
26
  /** 子节点总数 */
@@ -41,6 +28,13 @@ class AstElement extends node_1.AstNode {
41
28
  return this.childNodes.length;
42
29
  }
43
30
  /* NOT FOR BROWSER */
31
+ set length(n) {
32
+ if (n >= 0 && n < this.length) {
33
+ for (let i = this.length - 1; i >= n; i--) {
34
+ this.removeAt(i);
35
+ }
36
+ }
37
+ }
44
38
  /** 全部非文本子节点 */
45
39
  get children() {
46
40
  return this.childNodes.filter((child) => child.type !== 'text');
@@ -153,27 +147,12 @@ class AstElement extends node_1.AstNode {
153
147
  (0, debug_1.setChildNodes)(this, i, 0, [node]);
154
148
  return node;
155
149
  }
156
- /**
157
- * 将选择器转化为类型谓词
158
- * @param selector 选择器
159
- */
160
- #getCondition(selector) {
161
- /* NOT FOR BROWSER */
162
- if (/[^a-z\-,\s]/u.test(selector)) {
163
- const { parseSelector } = require('../parser/selector');
164
- const stack = parseSelector(selector);
165
- return (token => stack.some(copy => token.#matchesArray(copy)));
166
- }
167
- /* NOT FOR BROWSER END */
168
- const types = new Set(selector.split(',').map(str => str.trim()));
169
- return (({ type }) => types.has(type));
170
- }
171
150
  /**
172
151
  * 最近的祖先节点
173
152
  * @param selector 选择器
174
153
  */
175
154
  closest(selector) {
176
- const condition = this.#getCondition(selector);
155
+ const condition = getCondition(selector);
177
156
  let { parentNode } = this;
178
157
  while (parentNode) {
179
158
  if (condition(parentNode)) {
@@ -207,7 +186,7 @@ class AstElement extends node_1.AstNode {
207
186
  * @param selector 选择器
208
187
  */
209
188
  querySelector(selector) {
210
- const condition = this.#getCondition(selector);
189
+ const condition = getCondition(selector);
211
190
  return this.#getElementBy(condition);
212
191
  }
213
192
  /**
@@ -232,7 +211,7 @@ class AstElement extends node_1.AstNode {
232
211
  * @param selector 选择器
233
212
  */
234
213
  querySelectorAll(selector) {
235
- const condition = this.#getCondition(selector);
214
+ const condition = getCondition(selector);
236
215
  return this.#getElementsBy(condition);
237
216
  }
238
217
  /**
@@ -302,6 +281,7 @@ class AstElement extends node_1.AstNode {
302
281
  json(file, start = this.getAbsoluteIndex()) {
303
282
  const json = {
304
283
  ...this,
284
+ type: this.type,
305
285
  range: [start, start + this.toString().length],
306
286
  childNodes: [],
307
287
  };
@@ -320,218 +300,12 @@ class AstElement extends node_1.AstNode {
320
300
  return json;
321
301
  }
322
302
  /* NOT FOR BROWSER */
323
- /** 是否受保护。保护条件来自Token,这里仅提前用于:required和:optional伪选择器。 */
324
- #isProtected() {
325
- const { parentNode } = this;
326
- if (!parentNode) {
327
- return undefined;
328
- }
329
- const { childNodes, fixed } = parentNode;
330
- return fixed
331
- || parentNode.getAttribute('protectedChildren').applyTo(childNodes)
332
- .includes(childNodes.indexOf(this));
333
- }
334
- /**
335
- * 获取属性
336
- * @param key 属性键
337
- */
338
- #getAttr(key) {
339
- if (typeof this.getAttr === 'function') {
340
- const attr = this.getAttr(key);
341
- if (attr !== undefined) {
342
- return attr;
343
- }
344
- }
345
- const val = this.getAttribute(key);
346
- return val instanceof RegExp ? val.source : val;
347
- }
348
- /**
349
- * 检查是否符合属性选择器
350
- * @param key 属性键
351
- * @param equal 比较符
352
- * @param val 属性值
353
- * @param i 是否对大小写不敏感
354
- * @throws `RangeError` 复杂属性不能用于选择器
355
- */
356
- #matchesAttr(key, equal, val = '', i) {
357
- const isAttr = typeof this.hasAttr === 'function' && typeof this.getAttr === 'function';
358
- if (!(key in this) && (!isAttr || !this.hasAttr(key))) {
359
- return equal === '!=';
360
- }
361
- const v = toCase(val, i), thisVal = this.#getAttr(key);
362
- if (!equal) {
363
- return thisVal !== undefined && thisVal !== false;
364
- }
365
- if (equal === '~=') {
366
- const thisVals = typeof thisVal === 'string' ? thisVal.split(/\s/u) : thisVal;
367
- return Boolean(thisVals?.[Symbol.iterator])
368
- && [...thisVals].some(w => typeof w === 'string' && toCase(w, i) === v);
369
- }
370
- else if (!primitives.has(typeof thisVal) && !(thisVal instanceof title_1.Title)) {
371
- throw new RangeError(`The complex attribute ${key} cannot be used in a selector!`);
372
- }
373
- const stringVal = toCase(String(thisVal), i);
374
- switch (equal) {
375
- case '|=':
376
- return stringVal === v || stringVal.startsWith(`${v}-`);
377
- case '^=':
378
- return stringVal.startsWith(v);
379
- case '$=':
380
- return stringVal.endsWith(v);
381
- case '*=':
382
- return stringVal.includes(v);
383
- case '!=':
384
- return stringVal !== v;
385
- default: // `=`
386
- return stringVal === v;
387
- }
388
- }
389
- /**
390
- * 检查是否符合解析后的选择器,不含节点关系
391
- * @param step 解析后的选择器
392
- * @throws `SyntaxError` 错误的正则伪选择器
393
- * @throws `SyntaxError` 未定义的伪选择器
394
- */
395
- #matches(step) {
396
- const { parentNode, type, name, childNodes, link } = this, children = parentNode?.children, childrenOfType = children?.filter(({ type: t }) => t === type), siblingsCount = children?.length ?? 1, siblingsCountOfType = childrenOfType?.length ?? 1, index = (children?.indexOf(this) ?? 0) + 1, indexOfType = (childrenOfType?.indexOf(this) ?? 0) + 1, lastIndex = siblingsCount - index + 1, lastIndexOfType = siblingsCountOfType - indexOfType + 1;
397
- return step.every(selector => {
398
- if (typeof selector === 'string') {
399
- switch (selector) { // 情形1:简单伪选择器、type和name
400
- case '*':
401
- return true;
402
- case ':root':
403
- return !parentNode;
404
- case ':first-child':
405
- return index === 1;
406
- case ':first-of-type':
407
- return indexOfType === 1;
408
- case ':last-child':
409
- return lastIndex === 1;
410
- case ':last-of-type':
411
- return lastIndexOfType === 1;
412
- case ':only-child':
413
- return siblingsCount === 1;
414
- case ':only-of-type':
415
- return siblingsCountOfType === 1;
416
- case ':empty':
417
- return !childNodes.some(({ type: t, data }) => t !== 'text' || data);
418
- case ':parent':
419
- return childNodes.some(({ type: t, data }) => t !== 'text' || data);
420
- case ':header':
421
- return type === 'heading';
422
- case ':hidden':
423
- return this.text() === '';
424
- case ':visible':
425
- return this.text() !== '';
426
- case ':only-whitespace':
427
- return this.text().trim() === '';
428
- case ':any-link':
429
- return type === 'link'
430
- || type === 'free-ext-link'
431
- || type === 'magic-link'
432
- || type === 'ext-link'
433
- || (type === 'file' || type === 'gallery-image') && link;
434
- case ':local-link':
435
- return (type === 'link' || type === 'file' || type === 'gallery-image')
436
- && link instanceof title_1.Title
437
- && link.title === '';
438
- case ':invalid':
439
- return type === 'table-inter' || type === 'image-parameter' && name === 'invalid';
440
- case ':required':
441
- return this.#isProtected() === true;
442
- case ':optional':
443
- return this.#isProtected() === false;
444
- default: {
445
- const [t, n] = selector.split('#');
446
- return (!t || t === type) && (!n || n === name);
447
- }
448
- }
449
- }
450
- else if (selector.length === 4) { // 情形2:属性选择器
451
- return this.#matchesAttr(...selector);
452
- }
453
- const [s, pseudo] = selector; // 情形3:复杂伪选择器
454
- switch (pseudo) {
455
- case 'is':
456
- return this.matches(s);
457
- case 'not':
458
- return !this.matches(s);
459
- case 'nth-child':
460
- return nth(s, index);
461
- case 'nth-of-type':
462
- return nth(s, indexOfType);
463
- case 'nth-last-child':
464
- return nth(s, lastIndex);
465
- case 'nth-last-of-type':
466
- return nth(s, lastIndexOfType);
467
- case 'contains':
468
- return this.text().includes(s);
469
- case 'has':
470
- return Boolean(this.querySelector(s));
471
- case 'lang': {
472
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
473
- /^zh(?:-|$)/iu;
474
- const regex = new RegExp(`^${s}(?:-|$)`, 'iu');
475
- for (let node = this; node; node = node.parentNode) {
476
- const result = matchesLang(node, regex);
477
- if (result !== undefined) {
478
- return result;
479
- }
480
- }
481
- return false;
482
- }
483
- case 'regex': {
484
- const mt = /^([^,]+),\s*\/(.+)\/([a-z]*)$/u.exec(s);
485
- if (!mt) {
486
- throw new SyntaxError(`Wrong usage of the regex pseudo-selector. Use ":regex('attr, /re/i')" format.`);
487
- }
488
- try {
489
- return new RegExp(mt[2], mt[3]).test(String(this.#getAttr(mt[1].trim())));
490
- }
491
- catch {
492
- throw new SyntaxError(`Invalid regular expression: /${mt[2]}/${mt[3]}`);
493
- }
494
- }
495
- default:
496
- throw new SyntaxError(`Undefined pseudo-selector: ${pseudo}`);
497
- }
498
- });
499
- }
500
- /**
501
- * 检查是否符合解析后的选择器
502
- * @param copy 解析后的选择器
503
- */
504
- #matchesArray(copy) {
505
- const condition = [...copy], step = condition.pop();
506
- if (this.#matches(step)) {
507
- const { parentNode, previousElementSibling } = this;
508
- switch (condition[condition.length - 1]?.relation) {
509
- case undefined:
510
- return true;
511
- case '>':
512
- return Boolean(parentNode && parentNode.#matchesArray(condition));
513
- case '+':
514
- return Boolean(previousElementSibling && previousElementSibling.#matchesArray(condition));
515
- case '~': {
516
- if (!parentNode) {
517
- return false;
518
- }
519
- const { children } = parentNode;
520
- return children.slice(0, children.indexOf(this))
521
- .some(child => child.#matchesArray(condition));
522
- }
523
- default: // ' '
524
- return this.getAncestors().some(ancestor => ancestor.#matchesArray(condition));
525
- }
526
- }
527
- return false;
528
- }
529
303
  /**
530
304
  * 检查是否符合选择器
531
305
  * @param selector 选择器
532
306
  */
533
307
  matches(selector) {
534
- return selector === undefined || this.#getCondition(selector)(this);
308
+ return selector === undefined || getCondition(selector)(this);
535
309
  }
536
310
  /**
537
311
  * 类型选择器
@@ -16,9 +16,11 @@ export interface CaretPosition {
16
16
  /** 类似Node */
17
17
  export declare abstract class AstNode implements AstNodeBase {
18
18
  #private;
19
- type: TokenTypes | 'text';
20
19
  data?: string | undefined;
21
20
  readonly childNodes: readonly AstNodes[];
21
+ /** 节点类型 */
22
+ abstract get type(): TokenTypes | 'text';
23
+ abstract set type(value: TokenTypes | 'text');
22
24
  text(): string;
23
25
  lint(): LintError[];
24
26
  print(): string;
package/dist/lib/range.js CHANGED
@@ -20,6 +20,14 @@ const getParent = (node) => {
20
20
  }
21
21
  throw new RangeError('The reference node has no parent node!');
22
22
  };
23
+ /**
24
+ * 未初始化时抛出错误
25
+ * @param start 是否未初始化起点
26
+ * @throws `Error` 未初始化
27
+ */
28
+ const notInit = (start) => {
29
+ throw new Error(`Please set the ${start ? 'start' : 'end'} position first!`);
30
+ };
23
31
  /** 模拟Range对象 */
24
32
  class AstRange {
25
33
  #startContainer;
@@ -28,11 +36,11 @@ class AstRange {
28
36
  #endOffset;
29
37
  /** 起点容器 */
30
38
  get startContainer() {
31
- return this.#startContainer ?? this.#notInit(true);
39
+ return this.#startContainer ?? notInit(true);
32
40
  }
33
41
  /** 起点位置 */
34
42
  get startOffset() {
35
- return this.#startOffset ?? this.#notInit(true);
43
+ return this.#startOffset ?? notInit(true);
36
44
  }
37
45
  /** 起点绝对位置 */
38
46
  get startIndex() {
@@ -44,11 +52,11 @@ class AstRange {
44
52
  }
45
53
  /** 终点容器 */
46
54
  get endContainer() {
47
- return this.#endContainer ?? this.#notInit(false);
55
+ return this.#endContainer ?? notInit(false);
48
56
  }
49
57
  /** 终点位置 */
50
58
  get endOffset() {
51
- return this.#endOffset ?? this.#notInit(false);
59
+ return this.#endOffset ?? notInit(false);
52
60
  }
53
61
  /** 终点绝对位置 */
54
62
  get endIndex() {
@@ -67,14 +75,6 @@ class AstRange {
67
75
  const { startContainer, endContainer } = this;
68
76
  return startContainer.contains(endContainer) ? startContainer : startContainer.parentNode;
69
77
  }
70
- /**
71
- * 未初始化时抛出错误
72
- * @param start 是否未初始化起点
73
- * @throws `Error` 未初始化
74
- */
75
- #notInit(start) {
76
- throw new Error(`Please set the ${start ? 'start' : 'end'} position first!`);
77
- }
78
78
  /**
79
79
  * 检查起点和终点的设置是否有效
80
80
  * @throws `RangeError` 起点和终点不是兄弟节点
@@ -3,11 +3,12 @@ import type { LintError } from '../base';
3
3
  /** 文本节点 */
4
4
  export declare class AstText extends AstNode {
5
5
  #private;
6
- readonly type = "text";
7
6
  readonly name: undefined;
8
7
  readonly data: string;
8
+ get type(): 'text';
9
9
  /** 文本长度 */
10
10
  get length(): number;
11
+ set length(n: number);
11
12
  /** @param text 包含文本 */
12
13
  constructor(text: string);
13
14
  /** 可见部分 */
package/dist/lib/text.js CHANGED
@@ -76,20 +76,26 @@ const source = String.raw `<\s*(?:/\s*)?([a-z]\w*)|\{+|\}+|\[{2,}|\[(?![^[]*?\])
76
76
  ];
77
77
  /** 文本节点 */
78
78
  class AstText extends node_1.AstNode {
79
- type = 'text';
80
79
  data = '';
80
+ get type() {
81
+ return 'text';
82
+ }
81
83
  /* NOT FOR BROWSER */
82
84
  /** 文本长度 */
83
85
  get length() {
84
86
  return this.data.length;
85
87
  }
88
+ set length(n) {
89
+ if (n >= 0 && n < this.length) {
90
+ this.replaceData(this.data.slice(0, n));
91
+ }
92
+ }
86
93
  /* NOT FOR BROWSER END */
87
94
  /** @param text 包含文本 */
88
95
  constructor(text) {
89
96
  super();
90
97
  Object.defineProperties(this, {
91
98
  childNodes: { enumerable: false, configurable: false },
92
- type: { enumerable: false, writable: false },
93
99
  data: {
94
100
  value: text,
95
101
  /* NOT FOR BROWSER */
@@ -21,6 +21,11 @@ const hiddenToken = (linter) => (constructor, _) => {
21
21
  // @ts-expect-error private argument
22
22
  return linter ? [] : super.lint(start);
23
23
  }
24
+ /* NOT FOR BROWSER */
25
+ /** @private */
26
+ dispatchEvent() {
27
+ //
28
+ }
24
29
  }
25
30
  (0, debug_1.mixin)(AnyHiddenToken, constructor);
26
31
  return AnyHiddenToken;
@@ -23,8 +23,9 @@ const syntax = (pattern) => (constructor, _) => {
23
23
  }
24
24
  /** @private */
25
25
  afterBuild() {
26
+ super.afterBuild();
26
27
  const /** @implements */ syntaxListener = (e, data) => {
27
- if (!debug_1.Shadow.running && !this.pattern.test(this.text())) {
28
+ if (!debug_1.Shadow.running && !this.pattern.test((0, string_1.text)(this.childNodes))) {
28
29
  (0, debug_1.undo)(e, data);
29
30
  this.constructorError('cannot modify the syntax pattern');
30
31
  }