@lionrapid/core 0.2.1 → 0.3.0-beta.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.
Files changed (95) hide show
  1. package/dist/browser/auto-translator.d.ts.map +1 -1
  2. package/dist/browser/auto-translator.js +15 -4
  3. package/dist/browser/auto-translator.js.map +1 -1
  4. package/dist/browser/block-extractor.d.ts.map +1 -1
  5. package/dist/browser/block-extractor.js +6 -0
  6. package/dist/browser/block-extractor.js.map +1 -1
  7. package/dist/browser/editor/editor-api.d.ts +31 -1
  8. package/dist/browser/editor/editor-api.d.ts.map +1 -1
  9. package/dist/browser/editor/editor-api.js +43 -1
  10. package/dist/browser/editor/editor-api.js.map +1 -1
  11. package/dist/browser/editor/editor-init.js +25 -0
  12. package/dist/browser/editor/editor-init.js.map +1 -1
  13. package/dist/browser/editor/editor-styles.d.ts +1 -1
  14. package/dist/browser/editor/editor-styles.d.ts.map +1 -1
  15. package/dist/browser/editor/editor-styles.js +55 -0
  16. package/dist/browser/editor/editor-styles.js.map +1 -1
  17. package/dist/browser/editor/live-preview.d.ts.map +1 -1
  18. package/dist/browser/editor/live-preview.js +20 -3
  19. package/dist/browser/editor/live-preview.js.map +1 -1
  20. package/dist/browser/editor/sidebar.d.ts +20 -1
  21. package/dist/browser/editor/sidebar.d.ts.map +1 -1
  22. package/dist/browser/editor/sidebar.js +147 -9
  23. package/dist/browser/editor/sidebar.js.map +1 -1
  24. package/dist/browser/lionrapid.auto.dev.js +125 -311
  25. package/dist/browser/lionrapid.auto.dev.js.map +3 -3
  26. package/dist/browser/lionrapid.auto.js +125 -311
  27. package/dist/browser/lionrapid.auto.js.map +3 -3
  28. package/dist/browser/lionrapid.auto.min.js +3 -3
  29. package/dist/browser/lionrapid.auto.min.js.map +4 -4
  30. package/dist/browser/lionrapid.editor.js +274 -181
  31. package/dist/browser/lionrapid.editor.js.map +3 -3
  32. package/dist/browser/lionrapid.editor.min.js +58 -3
  33. package/dist/browser/lionrapid.editor.min.js.map +4 -4
  34. package/dist/browser/lionrapid.esm.js +108 -294
  35. package/dist/browser/lionrapid.esm.js.map +3 -3
  36. package/dist/browser/lionrapid.esm.min.js +2 -2
  37. package/dist/browser/lionrapid.esm.min.js.map +4 -4
  38. package/dist/browser/lionrapid.iife.dev.js +108 -294
  39. package/dist/browser/lionrapid.iife.dev.js.map +3 -3
  40. package/dist/browser/lionrapid.iife.js +108 -294
  41. package/dist/browser/lionrapid.iife.js.map +3 -3
  42. package/dist/browser/lionrapid.iife.min.js +2 -2
  43. package/dist/browser/lionrapid.iife.min.js.map +4 -4
  44. package/dist/browser/lionrapid.umd.js +108 -294
  45. package/dist/browser/lionrapid.umd.js.map +3 -3
  46. package/dist/browser/lionrapid.umd.min.js +2 -2
  47. package/dist/browser/lionrapid.umd.min.js.map +4 -4
  48. package/dist/browser/markup-parser.d.ts +9 -5
  49. package/dist/browser/markup-parser.d.ts.map +1 -1
  50. package/dist/browser/markup-parser.js +19 -23
  51. package/dist/browser/markup-parser.js.map +1 -1
  52. package/dist/content/canonical-tag.d.ts +34 -0
  53. package/dist/content/canonical-tag.d.ts.map +1 -0
  54. package/dist/content/canonical-tag.js +57 -0
  55. package/dist/content/canonical-tag.js.map +1 -0
  56. package/dist/content/index.d.ts +1 -4
  57. package/dist/content/index.d.ts.map +1 -1
  58. package/dist/content/index.js +3 -1
  59. package/dist/content/index.js.map +1 -1
  60. package/dist/content/parser/MarkupParser.d.ts +9 -49
  61. package/dist/content/parser/MarkupParser.d.ts.map +1 -1
  62. package/dist/content/parser/MarkupParser.js +37 -157
  63. package/dist/content/parser/MarkupParser.js.map +1 -1
  64. package/dist/content/serializer/HTMLSerializer.d.ts +10 -43
  65. package/dist/content/serializer/HTMLSerializer.d.ts.map +1 -1
  66. package/dist/content/serializer/HTMLSerializer.js +29 -69
  67. package/dist/content/serializer/HTMLSerializer.js.map +1 -1
  68. package/dist/content/types.d.ts +21 -12
  69. package/dist/content/types.d.ts.map +1 -1
  70. package/dist/content/validator/ContentValidator.d.ts +2 -2
  71. package/dist/content/validator/ContentValidator.js +2 -2
  72. package/dist/index.d.ts +2 -3
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +4 -1
  75. package/dist/index.js.map +1 -1
  76. package/dist/lionRapid.d.ts +1 -1
  77. package/dist/lionRapid.js +4 -4
  78. package/dist/lionRapid.js.map +1 -1
  79. package/dist/repositories/network-repository.d.ts +14 -0
  80. package/dist/repositories/network-repository.d.ts.map +1 -1
  81. package/dist/repositories/network-repository.js +26 -4
  82. package/dist/repositories/network-repository.js.map +1 -1
  83. package/package.json +1 -1
  84. package/dist/content/safe-href.d.ts +0 -22
  85. package/dist/content/safe-href.d.ts.map +0 -1
  86. package/dist/content/safe-href.js +0 -48
  87. package/dist/content/safe-href.js.map +0 -1
  88. package/dist/content/style-mapper/DefaultStyleMapper.d.ts +0 -59
  89. package/dist/content/style-mapper/DefaultStyleMapper.d.ts.map +0 -1
  90. package/dist/content/style-mapper/DefaultStyleMapper.js +0 -132
  91. package/dist/content/style-mapper/DefaultStyleMapper.js.map +0 -1
  92. package/dist/content/style-mapper/IStyleMapper.d.ts +0 -50
  93. package/dist/content/style-mapper/IStyleMapper.d.ts.map +0 -1
  94. package/dist/content/style-mapper/IStyleMapper.js +0 -6
  95. package/dist/content/style-mapper/IStyleMapper.js.map +0 -1
@@ -1,13 +1,17 @@
1
1
  /**
2
- * DOM-based Markup Parser
2
+ * DOM-based Markup Parser (raw-only)
3
3
  *
4
- * Converts a block element's childNodes into ContentUnit.
5
- * Uses the browser's DOM rather than regex (unlike edge/PHP which parse raw HTML strings).
6
- * Mirrors WordPress TS MarkupParser.
4
+ * Converts a block element's childNodes into ContentUnit by walking the
5
+ * DOM. Every inline element becomes an indexed tag whose style is the
6
+ * verbatim opening tag in canonical form (see content/canonical-tag.ts).
7
+ *
8
+ * Mirrors the regex-based parser in `content/parser/MarkupParser.ts` and
9
+ * the edge proxy parser, producing byte-identical text + styles for the
10
+ * same source so translation keys match across boundaries.
7
11
  */
8
12
  import type { ContentUnit } from '../content/types.js';
9
13
  /**
10
- * Parse a block element into ContentUnit using DOM walking
14
+ * Parse a block element into ContentUnit using DOM walking.
11
15
  */
12
16
  export declare function parseBlockElement(element: Element): ContentUnit;
13
17
  //# sourceMappingURL=markup-parser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"markup-parser.d.ts","sourceRoot":"","sources":["../../src/browser/markup-parser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAKvD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,CAqD/D"}
1
+ {"version":3,"file":"markup-parser.d.ts","sourceRoot":"","sources":["../../src/browser/markup-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGvD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,CA4C/D"}
@@ -1,14 +1,17 @@
1
1
  /**
2
- * DOM-based Markup Parser
2
+ * DOM-based Markup Parser (raw-only)
3
3
  *
4
- * Converts a block element's childNodes into ContentUnit.
5
- * Uses the browser's DOM rather than regex (unlike edge/PHP which parse raw HTML strings).
6
- * Mirrors WordPress TS MarkupParser.
4
+ * Converts a block element's childNodes into ContentUnit by walking the
5
+ * DOM. Every inline element becomes an indexed tag whose style is the
6
+ * verbatim opening tag in canonical form (see content/canonical-tag.ts).
7
+ *
8
+ * Mirrors the regex-based parser in `content/parser/MarkupParser.ts` and
9
+ * the edge proxy parser, producing byte-identical text + styles for the
10
+ * same source so translation keys match across boundaries.
7
11
  */
8
- import { DefaultStyleMapper } from '../content/style-mapper/DefaultStyleMapper.js';
9
- const styleMapper = new DefaultStyleMapper();
12
+ import { serializeOpeningTag, VOID_TAGS } from '../content/canonical-tag.js';
10
13
  /**
11
- * Parse a block element into ContentUnit using DOM walking
14
+ * Parse a block element into ContentUnit using DOM walking.
12
15
  */
13
16
  export function parseBlockElement(element) {
14
17
  const styles = {};
@@ -22,30 +25,23 @@ export function parseBlockElement(element) {
22
25
  }
23
26
  const el = node;
24
27
  const tag = el.tagName.toLowerCase();
25
- // Collect attributes
28
+ // Collect attributes preserving source insertion order.
26
29
  const attrs = {};
27
30
  for (let i = 0; i < el.attributes.length; i++) {
28
31
  const attr = el.attributes[i];
29
32
  attrs[attr.name.toLowerCase()] = attr.value;
30
33
  }
31
- const styleList = styleMapper.mapElementToStyles(tag, attrs);
32
- if (styleList.length > 0) {
33
- // Known styled element — assign indexed tag
34
- tagIndex++;
35
- const idx = tagIndex;
36
- styles[String(idx)] = styleList;
37
- let inner = '';
38
- for (let i = 0; i < node.childNodes.length; i++) {
39
- inner += walk(node.childNodes[i]);
40
- }
41
- return `<${idx}>${inner}</${idx}>`;
34
+ tagIndex++;
35
+ const idx = tagIndex;
36
+ styles[String(idx)] = [`raw:${serializeOpeningTag(tag, attrs)}`];
37
+ if (VOID_TAGS.has(tag)) {
38
+ return `<${idx}/>`;
42
39
  }
43
- // Unknown element — strip tag, recurse children
44
- let result = '';
40
+ let inner = '';
45
41
  for (let i = 0; i < node.childNodes.length; i++) {
46
- result += walk(node.childNodes[i]);
42
+ inner += walk(node.childNodes[i]);
47
43
  }
48
- return result;
44
+ return `<${idx}>${inner}</${idx}>`;
49
45
  }
50
46
  let text = '';
51
47
  for (let i = 0; i < element.childNodes.length; i++) {
@@ -1 +1 @@
1
- {"version":3,"file":"markup-parser.js","sourceRoot":"","sources":["../../src/browser/markup-parser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,+CAA+C,CAAC;AAEnF,MAAM,WAAW,GAAG,IAAI,kBAAkB,EAAE,CAAC;AAE7C;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAgB;IAChD,MAAM,MAAM,GAA6B,EAAE,CAAC;IAC5C,IAAI,QAAQ,GAAG,CAAC,CAAC;IAEjB,SAAS,IAAI,CAAC,IAAU;QACtB,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;QAC9B,CAAC;QAED,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;YACxC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,EAAE,GAAG,IAAe,CAAC;QAC3B,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAErC,qBAAqB;QACrB,MAAM,KAAK,GAA2B,EAAE,CAAC;QACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9C,MAAM,IAAI,GAAG,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAC9B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;QAC9C,CAAC;QAED,MAAM,SAAS,GAAG,WAAW,CAAC,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAE7D,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,4CAA4C;YAC5C,QAAQ,EAAE,CAAC;YACX,MAAM,GAAG,GAAG,QAAQ,CAAC;YACrB,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC;YAEhC,IAAI,KAAK,GAAG,EAAE,CAAC;YACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAChD,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;YACpC,CAAC;YAED,OAAO,IAAI,GAAG,IAAI,KAAK,KAAK,GAAG,GAAG,CAAC;QACrC,CAAC;QAED,gDAAgD;QAChD,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAChD,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACnD,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"markup-parser.js","sourceRoot":"","sources":["../../src/browser/markup-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7E;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAgB;IAChD,MAAM,MAAM,GAA6B,EAAE,CAAC;IAC5C,IAAI,QAAQ,GAAG,CAAC,CAAC;IAEjB,SAAS,IAAI,CAAC,IAAU;QACtB,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;QAC9B,CAAC;QAED,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;YACxC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,EAAE,GAAG,IAAe,CAAC;QAC3B,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAErC,wDAAwD;QACxD,MAAM,KAAK,GAA2B,EAAE,CAAC;QACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9C,MAAM,IAAI,GAAG,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAC9B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;QAC9C,CAAC;QAED,QAAQ,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,QAAQ,CAAC;QACrB,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;QAEjE,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,IAAI,GAAG,IAAI,CAAC;QACrB,CAAC;QAED,IAAI,KAAK,GAAG,EAAE,CAAC;QACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAChD,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,IAAI,GAAG,IAAI,KAAK,KAAK,GAAG,GAAG,CAAC;IACrC,CAAC;IAED,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACnD,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Canonical opening-tag format for ContentUnit `raw:` styles.
3
+ *
4
+ * All four parsers (edge, core HTML walker, core DOM walker, PHP) must
5
+ * produce byte-identical output for the same source element. Rules:
6
+ * - tag name lowercased
7
+ * - attribute names lowercased
8
+ * - attribute values always wrapped in double-quotes
9
+ * - attribute insertion order preserved from source
10
+ * - boolean attrs emitted as `attr=""`
11
+ * - void elements use the same form (no self-closing slash, no close tag emitted)
12
+ *
13
+ * Attribute values are stored byte-for-byte as captured from the source
14
+ * (the source's own entity encoding is preserved — already valid HTML).
15
+ * The serializer only re-escapes `"` → `&quot;` so the chosen double-quote
16
+ * delimiter stays well-formed when the source used single quotes.
17
+ */
18
+ export declare const VOID_TAGS: Set<string>;
19
+ /**
20
+ * Build the canonical opening tag string. Used by parsers to produce
21
+ * the `raw:<...>` style content.
22
+ */
23
+ export declare function serializeOpeningTag(tagName: string, attrs: Record<string, string>): string;
24
+ /**
25
+ * Extract the tag name from a canonical opening tag string.
26
+ * `<span class="x">` → `span`. Returns lowercase.
27
+ */
28
+ export declare function extractTagName(rawOpenTag: string): string;
29
+ /**
30
+ * Return the raw opening tag (the portion after `raw:`) from a style array,
31
+ * or null if no `raw:` style is present.
32
+ */
33
+ export declare function readRawStyle(styles: string[]): string | null;
34
+ //# sourceMappingURL=canonical-tag.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical-tag.d.ts","sourceRoot":"","sources":["../../src/content/canonical-tag.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,eAAO,MAAM,SAAS,aAGpB,CAAC;AAMH;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B,MAAM,CAQR;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAGzD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAK5D"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Canonical opening-tag format for ContentUnit `raw:` styles.
3
+ *
4
+ * All four parsers (edge, core HTML walker, core DOM walker, PHP) must
5
+ * produce byte-identical output for the same source element. Rules:
6
+ * - tag name lowercased
7
+ * - attribute names lowercased
8
+ * - attribute values always wrapped in double-quotes
9
+ * - attribute insertion order preserved from source
10
+ * - boolean attrs emitted as `attr=""`
11
+ * - void elements use the same form (no self-closing slash, no close tag emitted)
12
+ *
13
+ * Attribute values are stored byte-for-byte as captured from the source
14
+ * (the source's own entity encoding is preserved — already valid HTML).
15
+ * The serializer only re-escapes `"` → `&quot;` so the chosen double-quote
16
+ * delimiter stays well-formed when the source used single quotes.
17
+ */
18
+ export const VOID_TAGS = new Set([
19
+ 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',
20
+ 'link', 'meta', 'param', 'source', 'track', 'wbr',
21
+ ]);
22
+ function escapeAttrValue(value) {
23
+ return value.replace(/"/g, '&quot;');
24
+ }
25
+ /**
26
+ * Build the canonical opening tag string. Used by parsers to produce
27
+ * the `raw:<...>` style content.
28
+ */
29
+ export function serializeOpeningTag(tagName, attrs) {
30
+ const tag = tagName.toLowerCase();
31
+ let result = `<${tag}`;
32
+ for (const [name, value] of Object.entries(attrs)) {
33
+ result += ` ${name.toLowerCase()}="${escapeAttrValue(value)}"`;
34
+ }
35
+ result += '>';
36
+ return result;
37
+ }
38
+ /**
39
+ * Extract the tag name from a canonical opening tag string.
40
+ * `<span class="x">` → `span`. Returns lowercase.
41
+ */
42
+ export function extractTagName(rawOpenTag) {
43
+ const end = rawOpenTag.search(/[\s>]/);
44
+ return rawOpenTag.slice(1, end === -1 ? rawOpenTag.length : end).toLowerCase();
45
+ }
46
+ /**
47
+ * Return the raw opening tag (the portion after `raw:`) from a style array,
48
+ * or null if no `raw:` style is present.
49
+ */
50
+ export function readRawStyle(styles) {
51
+ for (const s of styles) {
52
+ if (s.startsWith('raw:'))
53
+ return s.slice(4);
54
+ }
55
+ return null;
56
+ }
57
+ //# sourceMappingURL=canonical-tag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical-tag.js","sourceRoot":"","sources":["../../src/content/canonical-tag.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC;IAC/B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO;IAC1D,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK;CAClD,CAAC,CAAC;AAEH,SAAS,eAAe,CAAC,KAAa;IACpC,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AACvC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAAe,EACf,KAA6B;IAE7B,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAClC,IAAI,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;IACvB,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC;IACjE,CAAC;IACD,MAAM,IAAI,GAAG,CAAC;IACd,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,UAAkB;IAC/C,MAAM,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACvC,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;AACjF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,MAAgB;IAC3C,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -9,12 +9,9 @@
9
9
  export type { ContentUnit } from './types.js';
10
10
  export type { IParser } from './parser/IParser.js';
11
11
  export { MarkupParser } from './parser/MarkupParser.js';
12
- export type { MarkupParserOptions } from './parser/MarkupParser.js';
13
12
  export type { ISerializer } from './serializer/ISerializer.js';
14
13
  export { HTMLSerializer } from './serializer/HTMLSerializer.js';
15
- export type { HTMLSerializerOptions } from './serializer/HTMLSerializer.js';
16
14
  export type { IValidator, ValidationResult, ValidationError, ValidationWarning, ValidationErrorCode, ValidationWarningCode, } from './validator/IValidator.js';
17
15
  export { ContentValidator } from './validator/ContentValidator.js';
18
- export type { IStyleMapper, ElementMapping } from './style-mapper/IStyleMapper.js';
19
- export { DefaultStyleMapper } from './style-mapper/DefaultStyleMapper.js';
16
+ export { VOID_TAGS, serializeOpeningTag, extractTagName, readRawStyle, } from './canonical-tag.js';
20
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/content/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,YAAY,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,YAAY,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAGpE,YAAY,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,YAAY,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAG5E,YAAY,EACV,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAGnE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/content/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,YAAY,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGxD,YAAY,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAGhE,YAAY,EACV,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAInE,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,cAAc,EACd,YAAY,GACb,MAAM,oBAAoB,CAAC"}
@@ -9,5 +9,7 @@
9
9
  export { MarkupParser } from './parser/MarkupParser.js';
10
10
  export { HTMLSerializer } from './serializer/HTMLSerializer.js';
11
11
  export { ContentValidator } from './validator/ContentValidator.js';
12
- export { DefaultStyleMapper } from './style-mapper/DefaultStyleMapper.js';
12
+ // Canonical raw-tag helpers — used by all parsers/serializers (core, edge,
13
+ // react, php) so they produce byte-identical output for the same source.
14
+ export { VOID_TAGS, serializeOpeningTag, extractTagName, readRawStyle, } from './canonical-tag.js';
13
15
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/content/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAKxD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAYhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAInE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/content/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAIxD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAWhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEnE,2EAA2E;AAC3E,yEAAyE;AACzE,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,cAAc,EACd,YAAY,GACb,MAAM,oBAAoB,CAAC"}
@@ -1,67 +1,27 @@
1
1
  /**
2
- * Markup parser for converting HTML strings to ContentUnit
2
+ * Markup parser — converts HTML strings to ContentUnit (raw-only).
3
+ *
4
+ * Every inline element becomes an indexed tag whose style is the verbatim
5
+ * opening tag in canonical form (see canonical-tag.ts). No element-to-
6
+ * semantic-style mapping — wrappers round-trip exactly.
7
+ *
3
8
  * @module content/parser/MarkupParser
4
9
  */
5
10
  import type { IParser } from './IParser.js';
6
11
  import type { ContentUnit } from '../types.js';
7
- import type { IStyleMapper } from '../style-mapper/IStyleMapper.js';
8
- /**
9
- * Configuration options for MarkupParser
10
- */
11
- export interface MarkupParserOptions {
12
- /**
13
- * Custom style mapper for element ↔ style conversion
14
- * Defaults to DefaultStyleMapper
15
- */
16
- styleMapper?: IStyleMapper;
17
- }
18
12
  /**
19
- * Parser that converts HTML markup strings to ContentUnit format
20
- *
21
- * Transforms inline HTML elements into indexed tags with style mapping:
22
- * - `<b>bold</b>` → text: `<1>bold</1>`, styles: `{"1": ["bold"]}`
23
- * - `<a href="/url">link</a>` → styles: `{"1": ["hyperlink:/url"]}`
13
+ * Parser that converts HTML markup strings to ContentUnit (raw-only).
24
14
  *
25
15
  * @example
26
16
  * ```typescript
27
17
  * const parser = new MarkupParser();
28
- *
29
- * const unit = parser.parse('Read our <b>Terms</b>.');
30
- * // → { text: "Read our <1>Terms</1>.", styles: {"1": ["bold"]} }
31
- *
32
- * const nested = parser.parse('<b>bold <i>and italic</i></b>');
33
- * // → { text: "<1>bold <2>and italic</2></1>", styles: {"1": ["bold"], "2": ["italic"]} }
18
+ * parser.parse('Read our <b>Terms</b>.');
19
+ * // → { text: 'Read our <1>Terms</1>.', styles: { '1': ['raw:<b>'] } }
34
20
  * ```
35
21
  */
36
22
  export declare class MarkupParser implements IParser<string> {
37
- private readonly styleMapper;
38
- constructor(options?: MarkupParserOptions);
39
- /**
40
- * Parse HTML string into ContentUnit
41
- *
42
- * Handles two input formats:
43
- * 1. HTML tags: `<b>text</b>` → converts to indexed `<1>text</1>` with styles
44
- * 2. Already indexed: `<1>text</1>` → passes through as-is (from server)
45
- *
46
- * @param input - HTML string with inline elements or already indexed
47
- * @returns ContentUnit with indexed tags and styles
48
- */
49
23
  parse(input: string): ContentUnit;
50
- /**
51
- * Match an HTML tag at the given position
52
- */
53
24
  private matchTag;
54
- /**
55
- * Parse HTML attributes string into key-value pairs
56
- */
57
25
  private parseAttributes;
58
- /**
59
- * Find matching opening tag in the stack
60
- */
61
- private findMatchingOpenTag;
62
- /**
63
- * Find the closing tag index for a given opening tag
64
- */
65
- private findClosingTagIndex;
66
26
  }
67
27
  //# sourceMappingURL=MarkupParser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MarkupParser.d.ts","sourceRoot":"","sources":["../../../src/content/parser/MarkupParser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAGpE;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,WAAW,CAAC,EAAE,YAAY,CAAC;CAC5B;AAaD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,YAAa,YAAW,OAAO,CAAC,MAAM,CAAC;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAe;gBAE/B,OAAO,GAAE,mBAAwB;IAI7C;;;;;;;;;OASG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW;IAuIjC;;OAEG;IACH,OAAO,CAAC,QAAQ;IA0ChB;;OAEG;IACH,OAAO,CAAC,eAAe;IAiBvB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAa3B;;OAEG;IACH,OAAO,CAAC,mBAAmB;CA6B5B"}
1
+ {"version":3,"file":"MarkupParser.d.ts","sourceRoot":"","sources":["../../../src/content/parser/MarkupParser.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAY/C;;;;;;;;;GASG;AACH,qBAAa,YAAa,YAAW,OAAO,CAAC,MAAM,CAAC;IAClD,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW;IA6DjC,OAAO,CAAC,QAAQ;IA2BhB,OAAO,CAAC,eAAe;CAYxB"}
@@ -1,162 +1,85 @@
1
1
  /**
2
- * Markup parser for converting HTML strings to ContentUnit
2
+ * Markup parser — converts HTML strings to ContentUnit (raw-only).
3
+ *
4
+ * Every inline element becomes an indexed tag whose style is the verbatim
5
+ * opening tag in canonical form (see canonical-tag.ts). No element-to-
6
+ * semantic-style mapping — wrappers round-trip exactly.
7
+ *
3
8
  * @module content/parser/MarkupParser
4
9
  */
5
- import { DefaultStyleMapper } from '../style-mapper/DefaultStyleMapper.js';
10
+ import { serializeOpeningTag, VOID_TAGS } from '../canonical-tag.js';
6
11
  /**
7
- * Parser that converts HTML markup strings to ContentUnit format
8
- *
9
- * Transforms inline HTML elements into indexed tags with style mapping:
10
- * - `<b>bold</b>` → text: `<1>bold</1>`, styles: `{"1": ["bold"]}`
11
- * - `<a href="/url">link</a>` → styles: `{"1": ["hyperlink:/url"]}`
12
+ * Parser that converts HTML markup strings to ContentUnit (raw-only).
12
13
  *
13
14
  * @example
14
15
  * ```typescript
15
16
  * const parser = new MarkupParser();
16
- *
17
- * const unit = parser.parse('Read our <b>Terms</b>.');
18
- * // → { text: "Read our <1>Terms</1>.", styles: {"1": ["bold"]} }
19
- *
20
- * const nested = parser.parse('<b>bold <i>and italic</i></b>');
21
- * // → { text: "<1>bold <2>and italic</2></1>", styles: {"1": ["bold"], "2": ["italic"]} }
17
+ * parser.parse('Read our <b>Terms</b>.');
18
+ * // → { text: 'Read our <1>Terms</1>.', styles: { '1': ['raw:<b>'] } }
22
19
  * ```
23
20
  */
24
21
  export class MarkupParser {
25
- styleMapper;
26
- constructor(options = {}) {
27
- this.styleMapper = options.styleMapper ?? new DefaultStyleMapper();
28
- }
29
- /**
30
- * Parse HTML string into ContentUnit
31
- *
32
- * Handles two input formats:
33
- * 1. HTML tags: `<b>text</b>` → converts to indexed `<1>text</1>` with styles
34
- * 2. Already indexed: `<1>text</1>` → passes through as-is (from server)
35
- *
36
- * @param input - HTML string with inline elements or already indexed
37
- * @returns ContentUnit with indexed tags and styles
38
- */
39
22
  parse(input) {
40
- // Check if input already uses indexed tags (from server)
41
- // Pattern: <1>, </1>, <2>, </2>, etc.
42
- const hasIndexedTags = /<\/?[0-9]+>/.test(input);
43
- if (hasIndexedTags) {
44
- // Input already has indexed tags - pass through without style mapping
45
- // The styles will come from component children in Trans, not from server
46
- return {
47
- text: input,
48
- styles: {}, // Empty - styles determined by children
49
- };
23
+ // Already indexed tags from server pass through unchanged.
24
+ if (/<\/?[0-9]+>/.test(input)) {
25
+ return { text: input, styles: {} };
50
26
  }
51
27
  const styles = {};
52
28
  let tagIndex = 0;
53
- // Stack to track open tags and their indices
54
29
  const tagStack = [];
55
- // Result text being built
56
30
  let result = '';
57
31
  let pos = 0;
58
32
  while (pos < input.length) {
59
- // Look for opening tag
60
- const tagMatch = this.matchTag(input, pos);
61
- if (!tagMatch) {
62
- // No more tags, append rest of string
33
+ const tag = this.matchTag(input, pos);
34
+ if (!tag) {
63
35
  result += input.slice(pos);
64
36
  break;
65
37
  }
66
- // Append text before tag
67
- result += input.slice(pos, tagMatch.startIndex);
68
- if (tagMatch.isClosing) {
69
- // Closing tag - find matching opening tag
70
- const matchingOpen = this.findMatchingOpenTag(tagStack, tagMatch.tag.toLowerCase());
71
- if (matchingOpen !== null) {
72
- result += `</${matchingOpen}>`;
73
- // Remove from stack
74
- const stackIndex = tagStack.findIndex((t) => t.index === matchingOpen);
75
- if (stackIndex !== -1) {
76
- tagStack.splice(stackIndex, 1);
38
+ result += input.slice(pos, tag.startIndex);
39
+ if (tag.isClosing) {
40
+ let matchIdx = null;
41
+ for (let i = tagStack.length - 1; i >= 0; i--) {
42
+ if (tagStack[i].tag === tag.tag.toLowerCase()) {
43
+ matchIdx = tagStack[i].index;
44
+ tagStack.splice(i, 1);
45
+ break;
77
46
  }
78
47
  }
79
- else {
80
- // Unmatched closing tag - keep as-is (will be validated later)
81
- result += input.slice(tagMatch.startIndex, tagMatch.endIndex);
48
+ if (matchIdx !== null) {
49
+ result += `</${matchIdx}>`;
82
50
  }
51
+ // Stray close — drop.
83
52
  }
84
- else if (tagMatch.isSelfClosing) {
85
- // Self-closing tag - assign index but no content
53
+ else {
54
+ const tagName = tag.tag.toLowerCase();
55
+ const isVoid = VOID_TAGS.has(tagName);
56
+ const isSelfClosing = tag.isSelfClosing || isVoid;
86
57
  tagIndex++;
87
- const styleList = this.styleMapper.mapElementToStyles(tagMatch.tag, tagMatch.attrs);
88
- if (styleList.length > 0) {
89
- styles[String(tagIndex)] = styleList;
58
+ styles[String(tagIndex)] = [`raw:${serializeOpeningTag(tagName, tag.attrs)}`];
59
+ if (isSelfClosing) {
90
60
  result += `<${tagIndex}/>`;
91
61
  }
92
- // If no styles mapped, skip the tag entirely
93
- }
94
- else {
95
- // Opening tag
96
- const styleList = this.styleMapper.mapElementToStyles(tagMatch.tag, tagMatch.attrs);
97
- if (styleList.length > 0) {
98
- tagIndex++;
99
- styles[String(tagIndex)] = styleList;
100
- result += `<${tagIndex}>`;
101
- tagStack.push({ tag: tagMatch.tag.toLowerCase(), index: tagIndex });
102
- }
103
62
  else {
104
- // Unknown element - don't index it, just process content
105
- // We need to find the closing tag and process content
106
- const closingIndex = this.findClosingTagIndex(input, tagMatch.endIndex, tagMatch.tag);
107
- if (closingIndex !== -1) {
108
- // Recursively parse content
109
- const innerContent = input.slice(tagMatch.endIndex, closingIndex);
110
- const innerUnit = this.parse(innerContent);
111
- // Merge inner styles (adjusting indices based on current tagIndex)
112
- const baseIndex = tagIndex;
113
- for (const [key, value] of Object.entries(innerUnit.styles)) {
114
- const adjustedKey = String(baseIndex + parseInt(key, 10));
115
- styles[adjustedKey] = value;
116
- }
117
- // Adjust result and indices
118
- result += innerUnit.text.replace(/<(\/?)\d+>/g, (match, slash) => {
119
- const num = parseInt(match.replace(/[</>]/g, ''), 10);
120
- return `<${slash}${baseIndex + num}>`;
121
- });
122
- // Move position past closing tag
123
- const closingMatch = this.matchTag(input, closingIndex);
124
- pos = closingMatch ? closingMatch.endIndex : closingIndex;
125
- // Adjust tagIndex to account for inner tags
126
- const maxInnerIndex = Object.keys(innerUnit.styles).length > 0
127
- ? Math.max(...Object.keys(innerUnit.styles).map(Number))
128
- : 0;
129
- tagIndex = baseIndex + maxInnerIndex;
130
- continue;
131
- }
63
+ result += `<${tagIndex}>`;
64
+ tagStack.push({ tag: tagName, index: tagIndex });
132
65
  }
133
66
  }
134
- pos = tagMatch.endIndex;
67
+ pos = tag.endIndex;
135
68
  }
136
- // Handle unclosed tags (add closing tags in reverse order)
137
69
  while (tagStack.length > 0) {
138
70
  const unclosed = tagStack.pop();
139
71
  result += `</${unclosed.index}>`;
140
72
  }
141
- return {
142
- text: result,
143
- styles,
144
- };
73
+ return { text: result, styles };
145
74
  }
146
- /**
147
- * Match an HTML tag at the given position
148
- */
149
75
  matchTag(input, startPos) {
150
- // Find next '<' from startPos
151
76
  const tagStart = input.indexOf('<', startPos);
152
77
  if (tagStart === -1)
153
78
  return null;
154
- // Match tag pattern: <tagname attrs> or </tagname> or <tagname/>
155
79
  const tagPattern = /^<(\/?)([a-zA-Z][a-zA-Z0-9]*)((?:\s+[a-zA-Z][a-zA-Z0-9-]*(?:=(?:"[^"]*"|'[^']*'|[^\s>]*))?)*)\s*(\/?)>/;
156
80
  const remaining = input.slice(tagStart);
157
81
  const match = remaining.match(tagPattern);
158
82
  if (!match) {
159
- // Not a valid tag, skip this '<' and try again
160
83
  if (tagStart + 1 < input.length) {
161
84
  return this.matchTag(input, tagStart + 1);
162
85
  }
@@ -172,60 +95,17 @@ export class MarkupParser {
172
95
  endIndex: tagStart + fullMatch.length,
173
96
  };
174
97
  }
175
- /**
176
- * Parse HTML attributes string into key-value pairs
177
- */
178
98
  parseAttributes(attrsString) {
179
99
  const attrs = {};
180
100
  if (!attrsString.trim())
181
101
  return attrs;
182
- // Match attribute patterns: name="value" or name='value' or name=value or name
183
102
  const attrPattern = /([a-zA-Z][a-zA-Z0-9-]*)(?:=(?:"([^"]*)"|'([^']*)'|([^\s>]*)))?/g;
184
103
  let match;
185
104
  while ((match = attrPattern.exec(attrsString)) !== null) {
186
105
  const [, name, doubleQuoted, singleQuoted, unquoted] = match;
187
- const value = doubleQuoted ?? singleQuoted ?? unquoted ?? '';
188
- attrs[name.toLowerCase()] = value;
106
+ attrs[name.toLowerCase()] = doubleQuoted ?? singleQuoted ?? unquoted ?? '';
189
107
  }
190
108
  return attrs;
191
109
  }
192
- /**
193
- * Find matching opening tag in the stack
194
- */
195
- findMatchingOpenTag(stack, tagName) {
196
- // Search from end of stack (most recent)
197
- for (let i = stack.length - 1; i >= 0; i--) {
198
- if (stack[i].tag === tagName) {
199
- return stack[i].index;
200
- }
201
- }
202
- return null;
203
- }
204
- /**
205
- * Find the closing tag index for a given opening tag
206
- */
207
- findClosingTagIndex(input, startPos, tagName) {
208
- const lowerTag = tagName.toLowerCase();
209
- let depth = 1;
210
- let pos = startPos;
211
- while (pos < input.length && depth > 0) {
212
- const tagMatch = this.matchTag(input, pos);
213
- if (!tagMatch)
214
- break;
215
- if (tagMatch.tag.toLowerCase() === lowerTag) {
216
- if (tagMatch.isClosing) {
217
- depth--;
218
- if (depth === 0) {
219
- return tagMatch.startIndex;
220
- }
221
- }
222
- else if (!tagMatch.isSelfClosing) {
223
- depth++;
224
- }
225
- }
226
- pos = tagMatch.endIndex;
227
- }
228
- return -1;
229
- }
230
110
  }
231
111
  //# sourceMappingURL=MarkupParser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MarkupParser.js","sourceRoot":"","sources":["../../../src/content/parser/MarkupParser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MarkupParser.js","sourceRoot":"","sources":["../../../src/content/parser/MarkupParser.ts"],"names":[],"mappings":"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"}