@heartlandone/vega 2.75.0 → 2.75.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 (178) hide show
  1. package/dist/cjs/{app-globals-bf183914.js → app-globals-35614ce8.js} +4 -4
  2. package/dist/cjs/{design-token-cbc01283.js → design-token-bb39e07e.js} +1 -1
  3. package/dist/cjs/{dto-renderer-manager-2fc24151.js → dto-renderer-manager-03e1a038.js} +197 -22
  4. package/dist/cjs/{element-appender-slimmer-318d29c7.js → element-appender-slimmer-daa8b9f5.js} +2 -2
  5. package/dist/cjs/{function-extension-ca9aa115.js → function-extension-cfbbc57e.js} +1 -1
  6. package/dist/cjs/{image-annotation-action-e4a35325.js → image-annotation-action-3fa501b7.js} +1 -1
  7. package/dist/cjs/index.cjs.js +6 -6
  8. package/dist/cjs/{language-extension-38e4905e.js → language-extension-8c4a56ff.js} +2 -2
  9. package/dist/cjs/loader.cjs.js +4 -4
  10. package/dist/cjs/{public-rules-661823fa.js → public-rules-dc2a8d62.js} +2 -2
  11. package/dist/cjs/{responsive-format-facade-f71d399c.js → responsive-format-facade-d5dba942.js} +2 -2
  12. package/dist/cjs/{rich-text-editor-required-rule-d5feeffd.js → rich-text-editor-required-rule-ba312af9.js} +1 -1
  13. package/dist/cjs/{style-formatter-566df206.js → style-formatter-49693da7.js} +1 -1
  14. package/dist/cjs/vega-accordion.cjs.entry.js +4 -4
  15. package/dist/cjs/vega-app-header-button.cjs.entry.js +4 -4
  16. package/dist/cjs/vega-box.cjs.entry.js +5 -5
  17. package/dist/cjs/vega-button-circle.cjs.entry.js +4 -4
  18. package/dist/cjs/vega-button.cjs.entry.js +3 -3
  19. package/dist/cjs/vega-card.cjs.entry.js +4 -4
  20. package/dist/cjs/vega-carousel.cjs.entry.js +3 -3
  21. package/dist/cjs/vega-chip.cjs.entry.js +4 -4
  22. package/dist/cjs/vega-date-picker_2.cjs.entry.js +4 -4
  23. package/dist/cjs/vega-dialog_2.cjs.entry.js +4 -4
  24. package/dist/cjs/vega-divider.cjs.entry.js +4 -4
  25. package/dist/cjs/vega-dropdown_5.cjs.entry.js +4 -4
  26. package/dist/cjs/vega-env-manager-23b8b23c.js +2 -2
  27. package/dist/cjs/vega-flag-icon.cjs.entry.js +4 -4
  28. package/dist/cjs/vega-flex.cjs.entry.js +5 -5
  29. package/dist/cjs/vega-font.cjs.entry.js +4 -4
  30. package/dist/cjs/vega-grid.cjs.entry.js +4 -4
  31. package/dist/cjs/vega-icon.cjs.entry.js +4 -4
  32. package/dist/cjs/vega-image-uploader.cjs.entry.js +3 -3
  33. package/dist/cjs/vega-input-phone-number.cjs.entry.js +2 -2
  34. package/dist/cjs/vega-input-select.cjs.entry.js +3 -3
  35. package/dist/cjs/vega-left-nav_5.cjs.entry.js +4 -4
  36. package/dist/cjs/vega-loader-wrapper_2.cjs.entry.js +3 -3
  37. package/dist/cjs/vega-pagination.cjs.entry.js +3 -3
  38. package/dist/cjs/vega-popover_2.cjs.entry.js +5 -5
  39. package/dist/cjs/vega-progress-tracker_2.cjs.entry.js +3 -3
  40. package/dist/cjs/vega-rich-text-content.cjs.entry.js +2 -2
  41. package/dist/cjs/vega-rich-text-editor_4.cjs.entry.js +60 -10
  42. package/dist/cjs/vega-selection-chip_2.cjs.entry.js +3 -3
  43. package/dist/cjs/vega-sidenav_3.cjs.entry.js +3 -3
  44. package/dist/cjs/vega-signature-capture.cjs.entry.js +4 -4
  45. package/dist/cjs/vega-table_11.cjs.entry.js +3 -3
  46. package/dist/cjs/vega-time-picker_2.cjs.entry.js +4 -4
  47. package/dist/cjs/vega-tooltip_2.cjs.entry.js +4 -4
  48. package/dist/cjs/vega.cjs.js +4 -4
  49. package/dist/collection/components/vega-rich-text-editor/dto/blocks/html-block.js +16 -0
  50. package/dist/collection/components/vega-rich-text-editor/dto/content-state.js +3 -22
  51. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/html-cleaner/html-content-cleaner-processor.interface.js +1 -0
  52. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/html-cleaner/html-content-cleaner.js +59 -0
  53. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/html-cleaner/index.js +4 -0
  54. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/html-cleaner/processors/remove-whitespace-after-opening-tag-processor.js +21 -0
  55. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/html-cleaner/processors/remove-whitespace-before-closing-tag-processor.js +21 -0
  56. package/dist/collection/components/vega-rich-text-editor/slimmers/controllers/html-cleaner/processors/remove-whitespace-between-tags-processor.js +77 -0
  57. package/dist/collection/components/vega-rich-text-editor/test/dto/blocks/html-block.test.js +39 -0
  58. package/dist/collection/components/vega-rich-text-editor/test/dto/content-state.test.js +166 -1
  59. package/dist/collection/components/vega-rich-text-editor/test/html-cleaner/html-content-cleaner.test.js +186 -0
  60. package/dist/collection/components/vega-rich-text-editor/test/html-cleaner/remove-whitespace-after-opening-tag-processor.test.js +22 -0
  61. package/dist/collection/components/vega-rich-text-editor/test/html-cleaner/remove-whitespace-before-closing-tag-processor.test.js +22 -0
  62. package/dist/collection/components/vega-rich-text-editor/test/html-cleaner/remove-whitespace-between-tags-processor.test.js +26 -0
  63. package/dist/collection/helpers/code-format/code-formatter.js +57 -7
  64. package/dist/collection/helpers/code-format/test/code-formatter.test.js +48 -0
  65. package/dist/esm/{app-globals-f3414aca.js → app-globals-2ac60ff5.js} +4 -4
  66. package/dist/esm/{design-token-9b299589.js → design-token-007efbaa.js} +1 -1
  67. package/dist/esm/{dto-renderer-manager-f07cf2d9.js → dto-renderer-manager-ee1a5864.js} +197 -22
  68. package/dist/esm/{element-appender-slimmer-7cb08343.js → element-appender-slimmer-35e26b5a.js} +2 -2
  69. package/dist/esm/{function-extension-63028f20.js → function-extension-e8c0e43e.js} +1 -1
  70. package/dist/esm/{image-annotation-action-53529cd9.js → image-annotation-action-285d432e.js} +1 -1
  71. package/dist/esm/index.js +6 -6
  72. package/dist/esm/{language-extension-c4ff21dd.js → language-extension-29bf8acd.js} +2 -2
  73. package/dist/esm/loader.js +4 -4
  74. package/dist/esm/{public-rules-6ebdfcf5.js → public-rules-724873f5.js} +2 -2
  75. package/dist/esm/{responsive-format-facade-05e53016.js → responsive-format-facade-28ee2dbd.js} +2 -2
  76. package/dist/esm/{rich-text-editor-required-rule-f63a37d1.js → rich-text-editor-required-rule-873e2e67.js} +1 -1
  77. package/dist/esm/{style-formatter-5f5bd714.js → style-formatter-314b37f3.js} +1 -1
  78. package/dist/esm/vega-accordion.entry.js +4 -4
  79. package/dist/esm/vega-app-header-button.entry.js +4 -4
  80. package/dist/esm/vega-box.entry.js +5 -5
  81. package/dist/esm/vega-button-circle.entry.js +4 -4
  82. package/dist/esm/vega-button.entry.js +3 -3
  83. package/dist/esm/vega-card.entry.js +4 -4
  84. package/dist/esm/vega-carousel.entry.js +3 -3
  85. package/dist/esm/vega-chip.entry.js +4 -4
  86. package/dist/esm/vega-date-picker_2.entry.js +4 -4
  87. package/dist/esm/vega-dialog_2.entry.js +4 -4
  88. package/dist/esm/vega-divider.entry.js +4 -4
  89. package/dist/esm/vega-dropdown_5.entry.js +4 -4
  90. package/dist/esm/vega-env-manager-8f8dc473.js +2 -2
  91. package/dist/esm/vega-flag-icon.entry.js +4 -4
  92. package/dist/esm/vega-flex.entry.js +5 -5
  93. package/dist/esm/vega-font.entry.js +4 -4
  94. package/dist/esm/vega-grid.entry.js +4 -4
  95. package/dist/esm/vega-icon.entry.js +4 -4
  96. package/dist/esm/vega-image-uploader.entry.js +3 -3
  97. package/dist/esm/vega-input-phone-number.entry.js +2 -2
  98. package/dist/esm/vega-input-select.entry.js +3 -3
  99. package/dist/esm/vega-left-nav_5.entry.js +4 -4
  100. package/dist/esm/vega-loader-wrapper_2.entry.js +3 -3
  101. package/dist/esm/vega-pagination.entry.js +3 -3
  102. package/dist/esm/vega-popover_2.entry.js +5 -5
  103. package/dist/esm/vega-progress-tracker_2.entry.js +3 -3
  104. package/dist/esm/vega-rich-text-content.entry.js +2 -2
  105. package/dist/esm/vega-rich-text-editor_4.entry.js +60 -10
  106. package/dist/esm/vega-selection-chip_2.entry.js +3 -3
  107. package/dist/esm/vega-sidenav_3.entry.js +3 -3
  108. package/dist/esm/vega-signature-capture.entry.js +4 -4
  109. package/dist/esm/vega-table_11.entry.js +3 -3
  110. package/dist/esm/vega-time-picker_2.entry.js +4 -4
  111. package/dist/esm/vega-tooltip_2.entry.js +4 -4
  112. package/dist/esm/vega.js +4 -4
  113. package/dist/sri/vega-sri-manifest.json +162 -162
  114. package/dist/types/components/vega-rich-text-editor/dto/blocks/html-block.d.ts +10 -0
  115. package/dist/types/components/vega-rich-text-editor/slimmers/controllers/html-cleaner/html-content-cleaner-processor.interface.d.ts +13 -0
  116. package/dist/types/components/vega-rich-text-editor/slimmers/controllers/html-cleaner/html-content-cleaner.d.ts +35 -0
  117. package/dist/types/components/vega-rich-text-editor/slimmers/controllers/html-cleaner/index.d.ts +4 -0
  118. package/dist/types/components/vega-rich-text-editor/slimmers/controllers/html-cleaner/processors/remove-whitespace-after-opening-tag-processor.d.ts +19 -0
  119. package/dist/types/components/vega-rich-text-editor/slimmers/controllers/html-cleaner/processors/remove-whitespace-before-closing-tag-processor.d.ts +19 -0
  120. package/dist/types/components/vega-rich-text-editor/slimmers/controllers/html-cleaner/processors/remove-whitespace-between-tags-processor.d.ts +59 -0
  121. package/dist/types/components/vega-rich-text-editor/test/html-cleaner/html-content-cleaner.test.d.ts +1 -0
  122. package/dist/types/components/vega-rich-text-editor/test/html-cleaner/remove-whitespace-after-opening-tag-processor.test.d.ts +1 -0
  123. package/dist/types/components/vega-rich-text-editor/test/html-cleaner/remove-whitespace-before-closing-tag-processor.test.d.ts +1 -0
  124. package/dist/types/components/vega-rich-text-editor/test/html-cleaner/remove-whitespace-between-tags-processor.test.d.ts +1 -0
  125. package/dist/types/helpers/code-format/code-formatter.d.ts +14 -0
  126. package/dist/vega/index.esm.js +1 -1
  127. package/dist/vega/{p-aa10eeb3.entry.js → p-012753b5.entry.js} +1 -1
  128. package/dist/vega/{p-fdc270b8.entry.js → p-024331ce.entry.js} +1 -1
  129. package/dist/vega/{p-ce1a2982.js → p-0575d22e.js} +1 -1
  130. package/dist/vega/{p-a86010f7.entry.js → p-08a90cc6.entry.js} +1 -1
  131. package/dist/vega/p-0ede1fea.entry.js +1 -0
  132. package/dist/vega/p-3353b3d7.js +1 -0
  133. package/dist/vega/p-365b1b35.entry.js +1 -0
  134. package/dist/vega/{p-a5bd3c15.entry.js → p-3ae9ee3d.entry.js} +1 -1
  135. package/dist/vega/{p-35bf5789.entry.js → p-3af92370.entry.js} +1 -1
  136. package/dist/vega/{p-ac4563d7.js → p-430be941.js} +1 -1
  137. package/dist/vega/{p-d6ed3d76.entry.js → p-45296fd4.entry.js} +1 -1
  138. package/dist/vega/{p-6f239144.entry.js → p-491618a6.entry.js} +1 -1
  139. package/dist/vega/{p-3cfd8616.entry.js → p-4aa893ef.entry.js} +1 -1
  140. package/dist/vega/{p-ef001c70.entry.js → p-4c47e8bb.entry.js} +1 -1
  141. package/dist/vega/{p-20ad42be.js → p-4da75f2b.js} +1 -1
  142. package/dist/vega/{p-e1610196.entry.js → p-5110ba73.entry.js} +1 -1
  143. package/dist/vega/{p-07d3df01.entry.js → p-556f9a21.entry.js} +1 -1
  144. package/dist/vega/{p-a65941d0.entry.js → p-55b54ba0.entry.js} +1 -1
  145. package/dist/vega/{p-50ab977c.entry.js → p-5efc6fe1.entry.js} +1 -1
  146. package/dist/vega/p-5f377954.js +1 -1
  147. package/dist/vega/{p-5df9a856.entry.js → p-64cd1931.entry.js} +1 -1
  148. package/dist/vega/{p-22c5d83b.js → p-68df4288.js} +1 -1
  149. package/dist/vega/{p-c8f1b9d5.js → p-691ba1ae.js} +1 -1
  150. package/dist/vega/{p-fba14ad2.entry.js → p-6fa8e231.entry.js} +1 -1
  151. package/dist/vega/{p-91ec2e30.js → p-749f96a4.js} +1 -1
  152. package/dist/vega/{p-67f18b9e.entry.js → p-7aaece55.entry.js} +1 -1
  153. package/dist/vega/{p-75651f32.entry.js → p-7ec6a104.entry.js} +1 -1
  154. package/dist/vega/{p-60274fb1.js → p-89d685a8.js} +1 -1
  155. package/dist/vega/{p-ffbff9b5.entry.js → p-8d701832.entry.js} +1 -1
  156. package/dist/vega/{p-e87b0b4a.entry.js → p-8ed0faa2.entry.js} +1 -1
  157. package/dist/vega/{p-87238c4c.entry.js → p-99aa554b.entry.js} +1 -1
  158. package/dist/vega/{p-ab2f35af.entry.js → p-9a2446f1.entry.js} +1 -1
  159. package/dist/vega/{p-3bbc0c7d.entry.js → p-a475d525.entry.js} +1 -1
  160. package/dist/vega/{p-a20854d6.entry.js → p-ac5e9955.entry.js} +1 -1
  161. package/dist/vega/p-b1f869fb.js +1 -0
  162. package/dist/vega/{p-f383c856.js → p-c2488ed6.js} +1 -1
  163. package/dist/vega/{p-747d6afc.entry.js → p-cf5b80f9.entry.js} +1 -1
  164. package/dist/vega/{p-8a887843.entry.js → p-db60a38e.entry.js} +1 -1
  165. package/dist/vega/{p-06aaced4.js → p-e93545fd.js} +1 -1
  166. package/dist/vega/{p-fbd64f9c.entry.js → p-ec192283.entry.js} +1 -1
  167. package/dist/vega/p-f2a3a1ec.entry.js +1 -0
  168. package/dist/vega/{p-08f18b22.entry.js → p-f2cdd212.entry.js} +1 -1
  169. package/dist/vega/{p-34246870.entry.js → p-f4c05b4a.entry.js} +1 -1
  170. package/dist/vega/{p-5a27084e.entry.js → p-f8641214.entry.js} +1 -1
  171. package/dist/vega/{p-60da99c6.entry.js → p-f89443aa.entry.js} +1 -1
  172. package/dist/vega/vega.esm.js +1 -1
  173. package/package.json +1 -1
  174. package/dist/vega/p-22b2841f.entry.js +0 -1
  175. package/dist/vega/p-53a694d1.entry.js +0 -1
  176. package/dist/vega/p-56e97df8.js +0 -1
  177. package/dist/vega/p-7ae55fd5.js +0 -1
  178. package/dist/vega/p-991008a8.entry.js +0 -1
@@ -7,8 +7,8 @@ const globalSlimmerRegistry = require('./global-slimmer-registry-b3bce7e0.js');
7
7
  const componentUsageRuntimeMetrics = require('./component-usage-runtime-metrics-d10ace87.js');
8
8
  const component = require('./component-1e352960.js');
9
9
  const darkModeStyleController = require('./dark-mode-style-controller-c21172aa.js');
10
- const imageAnnotationAction = require('./image-annotation-action-e4a35325.js');
11
- const dtoRendererManager = require('./dto-renderer-manager-2fc24151.js');
10
+ const imageAnnotationAction = require('./image-annotation-action-3fa501b7.js');
11
+ const dtoRendererManager = require('./dto-renderer-manager-03e1a038.js');
12
12
  const codeBlock = require('./code-block-c1d2e6a8.js');
13
13
  const baseRenderer = require('./base-renderer-0a3b62b7.js');
14
14
  const accessibility = require('./accessibility-bfa227f6.js');
@@ -10,11 +10,11 @@ const accessibility = require('./accessibility-bfa227f6.js');
10
10
  const changeManager = require('./change-manager-a297e4d2.js');
11
11
  const domNodeSubjectObserverFactory = require('./dom-node-subject-observer-factory-b5e71bf6.js');
12
12
  const vegaInternalEventId = require('./vega-internal-event-id-f2465f1b.js');
13
- const dtoRendererManager = require('./dto-renderer-manager-2fc24151.js');
13
+ const dtoRendererManager = require('./dto-renderer-manager-03e1a038.js');
14
14
  const typeGuard = require('./type-guard-a0f026d8.js');
15
15
  const internalIconManager = require('./internal-icon-manager-32f9ed63.js');
16
16
  const codeBlock = require('./code-block-c1d2e6a8.js');
17
- const imageAnnotationAction = require('./image-annotation-action-e4a35325.js');
17
+ const imageAnnotationAction = require('./image-annotation-action-3fa501b7.js');
18
18
  const createPublicApiRuntimeMetricsSlimmer = require('./create-public-api-runtime-metrics-slimmer-e2e274e1.js');
19
19
  const index$1 = require('./index-95fca64f.js');
20
20
  const formFieldControllerSlimmer = require('./form-field-controller-slimmer-aef2fb1e.js');
@@ -25,7 +25,7 @@ const staticSubjectTitle = require('./static-subject-title-5829a298.js');
25
25
  const observer = require('./observer-f49483e8.js');
26
26
  const timer = require('./timer-5f33058b.js');
27
27
  const darkModeStateControllerSlimmer = require('./dark-mode-state-controller-slimmer-8a87ec08.js');
28
- const richTextEditorRequiredRule = require('./rich-text-editor-required-rule-d5feeffd.js');
28
+ const richTextEditorRequiredRule = require('./rich-text-editor-required-rule-ba312af9.js');
29
29
  const childNodesEventPreventSlimmer = require('./child-nodes-event-prevent-slimmer-aca87dac.js');
30
30
  const translationSlimmer = require('./translation-slimmer-f0ebe710.js');
31
31
  const darkModeStyleController = require('./dark-mode-style-controller-c21172aa.js');
@@ -67,6 +67,7 @@ class CodeFormatter {
67
67
  constructor() {
68
68
  /**
69
69
  * Formats a given HTML source string by applying indentation and cleaning up styles.
70
+ * Content inside preserve tags (pre) is preserved as-is without formatting.
70
71
  *
71
72
  * @param {string} source - The HTML source string to format.
72
73
  * @param {CodeFormatOptions} options - Formatting options.
@@ -81,9 +82,25 @@ class CodeFormatter {
81
82
  const tokens = source.split(tagRegex).filter((t) => t.length > 0);
82
83
  let indentLevel = 0;
83
84
  let output = '';
85
+ let preserveDepth = 0;
84
86
  for (let i = 0; i < tokens.length; i++) {
85
87
  let token = tokens[i];
86
- // Decrease indentation for closing tags
88
+ const tagName = CodeFormatter.getTagName(token);
89
+ // Track if we're entering or exiting preserve tags
90
+ if (CodeFormatter.PRESERVE_CONTENT_TAGS.has(tagName)) {
91
+ if (token.startsWith('</')) {
92
+ preserveDepth = Math.max(0, preserveDepth - 1);
93
+ }
94
+ else if (token.startsWith('<')) {
95
+ preserveDepth++;
96
+ }
97
+ }
98
+ // If inside preserve tag, output as-is without formatting
99
+ if (preserveDepth > 0) {
100
+ output += token;
101
+ continue;
102
+ }
103
+ // Decrease indentation for closing tags (after exiting preserve tags)
87
104
  if (token.startsWith('</')) {
88
105
  indentLevel = Math.max(0, indentLevel - 1);
89
106
  }
@@ -93,15 +110,20 @@ class CodeFormatter {
93
110
  token = token.replace(/style\s*=\s*"([^"]*)"/g, (_, styleContent) => {
94
111
  return `style="${this.formatStyle(styleContent)}"`;
95
112
  });
96
- const tagName = CodeFormatter.getTagName(token);
97
113
  const isInline = CodeFormatter.INLINE_TAGS.has(tagName);
98
- // Inline tag grouping: e.g., <strong>Text</strong> stays on one line
99
- if (isInline && i + 2 < tokens.length && tokens[i + 2] === `</${tagName}>`) {
100
- // Group consecutive inline tags
114
+ // Inline tag grouping: e.g., <strong>Text</strong> or <span></span> stays on one line
115
+ // Check for empty tags: <tag></tag> (closing tag immediately follows opening tag)
116
+ if (isInline && i + 1 < tokens.length && tokens[i + 1] === `</${tagName}>`) {
117
+ // Empty inline tag: <span></span>
118
+ output += `${indent}${token}${tokens[i + 1]}\n`;
119
+ i += 1;
120
+ }
121
+ else if (isInline && i + 2 < tokens.length && tokens[i + 2] === `</${tagName}>`) {
122
+ // Group consecutive inline tags with content
101
123
  let inlineGroup = `${token}${tokens[i + 1]}${tokens[i + 2]}`;
102
124
  i += 2;
103
125
  // Keep merging consecutive inline tag pairs
104
- while (i + 2 < tokens.length &&
126
+ while (i + 3 < tokens.length &&
105
127
  tokens[i + 1].startsWith('<') &&
106
128
  CodeFormatter.INLINE_TAGS.has(CodeFormatter.getTagName(tokens[i + 1])) &&
107
129
  tokens[i + 3] === `</${CodeFormatter.getTagName(tokens[i + 1])}>`) {
@@ -115,7 +137,7 @@ class CodeFormatter {
115
137
  // Increase indentation for non-void opening tags
116
138
  if (!token.startsWith('</') &&
117
139
  !token.endsWith('/>') &&
118
- !/^<br|^<img|^<meta|^<input|^<hr/i.test(token)) {
140
+ !CodeFormatter.VOID_TAGS.has(tagName)) {
119
141
  indentLevel++;
120
142
  }
121
143
  }
@@ -156,6 +178,10 @@ class CodeFormatter {
156
178
  .join('; ');
157
179
  }
158
180
  }
181
+ /**
182
+ * Inline/phrasing elements that should be kept on a single line with their content.
183
+ * These tags are formatted as: <tag>content</tag> on one line.
184
+ */
159
185
  CodeFormatter.INLINE_TAGS = new Set([
160
186
  'span',
161
187
  'strong',
@@ -175,6 +201,30 @@ CodeFormatter.INLINE_TAGS = new Set([
175
201
  'del',
176
202
  'ins',
177
203
  ]);
204
+ /**
205
+ * Void/self-closing elements that don't have closing tags.
206
+ * Used to avoid increasing indentation for these elements.
207
+ */
208
+ CodeFormatter.VOID_TAGS = new Set([
209
+ 'area',
210
+ 'base',
211
+ 'br',
212
+ 'col',
213
+ 'embed',
214
+ 'hr',
215
+ 'img',
216
+ 'input',
217
+ 'link',
218
+ 'meta',
219
+ 'param',
220
+ 'source',
221
+ 'track',
222
+ 'wbr',
223
+ ]);
224
+ /**
225
+ * Tags whose content should be preserved as-is without formatting.
226
+ */
227
+ CodeFormatter.PRESERVE_CONTENT_TAGS = new Set(['pre']);
178
228
  const CodeFormatter$1 = new CodeFormatter();
179
229
 
180
230
  var __decorate$C = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
@@ -6,7 +6,7 @@ const index = require('./index-58ea899e.js');
6
6
  const component = require('./component-1e352960.js');
7
7
  const globalSlimmerRegistry = require('./global-slimmer-registry-b3bce7e0.js');
8
8
  const componentUsageRuntimeMetrics = require('./component-usage-runtime-metrics-d10ace87.js');
9
- const responsiveFormatFacade = require('./responsive-format-facade-f71d399c.js');
9
+ const responsiveFormatFacade = require('./responsive-format-facade-d5dba942.js');
10
10
  const accessibility = require('./accessibility-bfa227f6.js');
11
11
  const subStateObserverSlimmer = require('./sub-state-observer-slimmer-5d0b8ac3.js');
12
12
  const observer = require('./observer-f49483e8.js');
@@ -34,13 +34,13 @@ require('./dynamic-slimmer-f31fdfd7.js');
34
34
  require('./number-4816603d.js');
35
35
  require('./pixel-98f2a10c.js');
36
36
  require('./vega-env-manager-23b8b23c.js');
37
- require('./function-extension-ca9aa115.js');
37
+ require('./function-extension-cfbbc57e.js');
38
38
  require('./dark-mode-style-controller-c21172aa.js');
39
39
  require('./_commonjsHelpers-537d719a.js');
40
40
  require('./vega-nonce-manager-df69d3ed.js');
41
41
  require('./try-get-document-c0ebd39a.js');
42
42
  require('./internal-vega-event-manager-6befeb34.js');
43
- require('./dto-renderer-manager-2fc24151.js');
43
+ require('./dto-renderer-manager-03e1a038.js');
44
44
  require('./code-block-c1d2e6a8.js');
45
45
  require('./string-39438062.js');
46
46
  require('./object-e2e28e3d.js');
@@ -8,13 +8,13 @@ const component = require('./component-1e352960.js');
8
8
  const createPublicApiRuntimeMetricsSlimmer = require('./create-public-api-runtime-metrics-slimmer-e2e274e1.js');
9
9
  const globalSlimmerRegistry = require('./global-slimmer-registry-b3bce7e0.js');
10
10
  const componentUsageRuntimeMetrics = require('./component-usage-runtime-metrics-d10ace87.js');
11
- const functionExtension = require('./function-extension-ca9aa115.js');
11
+ const functionExtension = require('./function-extension-cfbbc57e.js');
12
12
  const pageResizeObserverSlimmer = require('./page-resize-observer-slimmer-11937d6f.js');
13
13
  const accessibility = require('./accessibility-bfa227f6.js');
14
14
  const internalIconManager = require('./internal-icon-manager-32f9ed63.js');
15
15
  const subStateNotifySlimmer = require('./sub-state-notify-slimmer-468e19aa.js');
16
16
  const effect = require('./effect-98e88068.js');
17
- const responsiveFormatFacade = require('./responsive-format-facade-f71d399c.js');
17
+ const responsiveFormatFacade = require('./responsive-format-facade-d5dba942.js');
18
18
  const domNodeSubjectObserverFactory = require('./dom-node-subject-observer-factory-b5e71bf6.js');
19
19
  const vegaInternalEventId = require('./vega-internal-event-id-f2465f1b.js');
20
20
  const eventEmitSlimmer = require('./event-emit-slimmer-2dacabbd.js');
@@ -30,7 +30,7 @@ require('./dark-mode-style-controller-c21172aa.js');
30
30
  require('./_commonjsHelpers-537d719a.js');
31
31
  require('./vega-nonce-manager-df69d3ed.js');
32
32
  require('./try-get-document-c0ebd39a.js');
33
- require('./dto-renderer-manager-2fc24151.js');
33
+ require('./dto-renderer-manager-03e1a038.js');
34
34
  require('./code-block-c1d2e6a8.js');
35
35
  require('./string-39438062.js');
36
36
  require('./type-guard-a0f026d8.js');
@@ -8,7 +8,7 @@ const componentUsageRuntimeMetrics = require('./component-usage-runtime-metrics-
8
8
  const internalIconManager = require('./internal-icon-manager-32f9ed63.js');
9
9
  const component = require('./component-1e352960.js');
10
10
  const domNodeSubjectObserverFactory = require('./dom-node-subject-observer-factory-b5e71bf6.js');
11
- const designToken = require('./design-token-cbc01283.js');
11
+ const designToken = require('./design-token-bb39e07e.js');
12
12
  const staticSubjectTitle = require('./static-subject-title-5829a298.js');
13
13
  const changeManager = require('./change-manager-a297e4d2.js');
14
14
  const object = require('./object-e2e28e3d.js');
@@ -26,18 +26,18 @@ require('./breakpoints-ebde4837.js');
26
26
  require('./ui-32e69595.js');
27
27
  require('./typography-4560e7f1.js');
28
28
  require('./translation-5f9f9c0c.js');
29
- require('./responsive-format-facade-f71d399c.js');
29
+ require('./responsive-format-facade-d5dba942.js');
30
30
  require('./number-4816603d.js');
31
31
  require('./pixel-98f2a10c.js');
32
32
  require('./array-249289f2.js');
33
33
  require('./vega-env-manager-23b8b23c.js');
34
- require('./function-extension-ca9aa115.js');
34
+ require('./function-extension-cfbbc57e.js');
35
35
  require('./dark-mode-style-controller-c21172aa.js');
36
36
  require('./_commonjsHelpers-537d719a.js');
37
37
  require('./vega-nonce-manager-df69d3ed.js');
38
38
  require('./try-get-document-c0ebd39a.js');
39
39
  require('./internal-vega-event-manager-6befeb34.js');
40
- require('./dto-renderer-manager-2fc24151.js');
40
+ require('./dto-renderer-manager-03e1a038.js');
41
41
  require('./code-block-c1d2e6a8.js');
42
42
  require('./vega-internal-event-id-f2465f1b.js');
43
43
  require('./string-39438062.js');
@@ -14,7 +14,7 @@ const ui = require('./ui-9e181079.js');
14
14
  const domNodeSubjectObserverFactory = require('./dom-node-subject-observer-factory-b5e71bf6.js');
15
15
  const remoteInvocationRegistry = require('./remote-invocation-registry-fc22fdd0.js');
16
16
  const vegaInternalEventId = require('./vega-internal-event-id-f2465f1b.js');
17
- const responsiveFormatFacade = require('./responsive-format-facade-f71d399c.js');
17
+ const responsiveFormatFacade = require('./responsive-format-facade-d5dba942.js');
18
18
  const typeGuard = require('./type-guard-a0f026d8.js');
19
19
  const component = require('./component-1e352960.js');
20
20
  const createPublicApiRuntimeMetricsSlimmer = require('./create-public-api-runtime-metrics-slimmer-e2e274e1.js');
@@ -29,12 +29,12 @@ const translationSlimmer = require('./translation-slimmer-f0ebe710.js');
29
29
  const subStateObserverSlimmer = require('./sub-state-observer-slimmer-5d0b8ac3.js');
30
30
  const featureFlagController = require('./feature-flag-controller-ce2162c8.js');
31
31
  const breakpoints = require('./breakpoints-ebde4837.js');
32
- const functionExtension = require('./function-extension-ca9aa115.js');
32
+ const functionExtension = require('./function-extension-cfbbc57e.js');
33
33
  require('./vega-env-manager-23b8b23c.js');
34
34
  const internalIconManager = require('./internal-icon-manager-32f9ed63.js');
35
35
  require('./wait-for-vega-handler-5469ff80.js');
36
36
  require('./translation-5f9f9c0c.js');
37
- require('./dto-renderer-manager-2fc24151.js');
37
+ require('./dto-renderer-manager-03e1a038.js');
38
38
  require('./vega-nonce-manager-df69d3ed.js');
39
39
  require('./code-block-c1d2e6a8.js');
40
40
  const accessibility = require('./accessibility-bfa227f6.js');
@@ -16,7 +16,7 @@ const typeGuard = require('./type-guard-a0f026d8.js');
16
16
  const array = require('./array-249289f2.js');
17
17
  const staticSubjectTitle = require('./static-subject-title-5829a298.js');
18
18
  const changeManager = require('./change-manager-a297e4d2.js');
19
- const elementAppenderSlimmer = require('./element-appender-slimmer-318d29c7.js');
19
+ const elementAppenderSlimmer = require('./element-appender-slimmer-daa8b9f5.js');
20
20
  const clickOutsideOnlyToDismissStrategy = require('./click-outside-only-to-dismiss-strategy-407f6d1e.js');
21
21
  const keyboardManagerSlimmer = require('./keyboard-manager-slimmer-0d45f944.js');
22
22
  const internalFormFieldValidationRule_abstract = require('./internal-form-field-validation-rule.abstract-07cdff46.js');
@@ -38,17 +38,17 @@ require('./mutation-observer-filters-38cebc6d.js');
38
38
  require('./sub-state-observer-slimmer-5d0b8ac3.js');
39
39
  require('./typography-4560e7f1.js');
40
40
  require('./number-4816603d.js');
41
- require('./function-extension-ca9aa115.js');
41
+ require('./function-extension-cfbbc57e.js');
42
42
  require('./dark-mode-style-controller-c21172aa.js');
43
43
  require('./_commonjsHelpers-537d719a.js');
44
44
  require('./vega-nonce-manager-df69d3ed.js');
45
45
  require('./internal-vega-event-manager-6befeb34.js');
46
- require('./dto-renderer-manager-2fc24151.js');
46
+ require('./dto-renderer-manager-03e1a038.js');
47
47
  require('./code-block-c1d2e6a8.js');
48
48
  require('./object-e2e28e3d.js');
49
49
  require('./internal-icon-manager-32f9ed63.js');
50
50
  require('./base-renderer-0a3b62b7.js');
51
- require('./responsive-format-facade-f71d399c.js');
51
+ require('./responsive-format-facade-d5dba942.js');
52
52
  require('./pixel-98f2a10c.js');
53
53
  require('./vega-env-manager-23b8b23c.js');
54
54
  require('./feature-flag-controller-ce2162c8.js');
@@ -7,7 +7,7 @@ const component = require('./component-1e352960.js');
7
7
  const injectKeyboardManager = require('./inject-keyboard-manager-d21b4387.js');
8
8
  const globalSlimmerRegistry = require('./global-slimmer-registry-b3bce7e0.js');
9
9
  const componentUsageRuntimeMetrics = require('./component-usage-runtime-metrics-d10ace87.js');
10
- const elementAppenderSlimmer = require('./element-appender-slimmer-318d29c7.js');
10
+ const elementAppenderSlimmer = require('./element-appender-slimmer-daa8b9f5.js');
11
11
  const deprecatedPropertySlimmer = require('./deprecated-property-slimmer-1eb8f031.js');
12
12
  require('./keyboard-manager-3dea6b28.js');
13
13
  require('./ui-9e181079.js');
@@ -20,7 +20,7 @@ require('./change-manager-a297e4d2.js');
20
20
  require('./static-subject-title-5829a298.js');
21
21
  require('./create-public-api-runtime-metrics-slimmer-e2e274e1.js');
22
22
  require('./dynamic-slimmer-f31fdfd7.js');
23
- require('./function-extension-ca9aa115.js');
23
+ require('./function-extension-cfbbc57e.js');
24
24
  require('./page-resize-observer-slimmer-11937d6f.js');
25
25
  require('./try-get-document-c0ebd39a.js');
26
26
  require('./dark-mode-style-controller-c21172aa.js');
@@ -30,14 +30,14 @@ require('./vega-nonce-manager-df69d3ed.js');
30
30
  require('./internal-vega-event-manager-6befeb34.js');
31
31
  require('./dom-node-subject-observer-factory-b5e71bf6.js');
32
32
  require('./number-4816603d.js');
33
- require('./dto-renderer-manager-2fc24151.js');
33
+ require('./dto-renderer-manager-03e1a038.js');
34
34
  require('./code-block-c1d2e6a8.js');
35
35
  require('./vega-internal-event-id-f2465f1b.js');
36
36
  require('./string-39438062.js');
37
37
  require('./object-e2e28e3d.js');
38
38
  require('./internal-icon-manager-32f9ed63.js');
39
39
  require('./base-renderer-0a3b62b7.js');
40
- require('./responsive-format-facade-f71d399c.js');
40
+ require('./responsive-format-facade-d5dba942.js');
41
41
  require('./pixel-98f2a10c.js');
42
42
  require('./array-249289f2.js');
43
43
  require('./vega-env-manager-23b8b23c.js');
@@ -1,12 +1,12 @@
1
1
  'use strict';
2
2
 
3
3
  const index = require('./index-58ea899e.js');
4
- const appGlobals = require('./app-globals-bf183914.js');
4
+ const appGlobals = require('./app-globals-35614ce8.js');
5
5
  require('./feature-flag-controller-ce2162c8.js');
6
6
  require('./global-slimmer-registry-b3bce7e0.js');
7
7
  require('./index-4d7bce1a.js');
8
8
  require('./_commonjsHelpers-537d719a.js');
9
- require('./function-extension-ca9aa115.js');
9
+ require('./function-extension-cfbbc57e.js');
10
10
  require('./create-public-api-runtime-metrics-slimmer-e2e274e1.js');
11
11
  require('./dynamic-slimmer-f31fdfd7.js');
12
12
  require('./ui-9e181079.js');
@@ -22,7 +22,7 @@ require('./vega-nonce-manager-df69d3ed.js');
22
22
  require('./internal-vega-event-manager-6befeb34.js');
23
23
  require('./dom-node-subject-observer-factory-b5e71bf6.js');
24
24
  require('./number-4816603d.js');
25
- require('./dto-renderer-manager-2fc24151.js');
25
+ require('./dto-renderer-manager-03e1a038.js');
26
26
  require('./code-block-c1d2e6a8.js');
27
27
  require('./vega-internal-event-id-f2465f1b.js');
28
28
  require('./string-39438062.js');
@@ -37,7 +37,7 @@ require('./wait-for-vega-handler-5469ff80.js');
37
37
  require('./valid-credit-card-number-rule-c854bed9.js');
38
38
  require('./internal-form-field-validation-rule.abstract-07cdff46.js');
39
39
  require('./index-95fca64f.js');
40
- require('./language-extension-38e4905e.js');
40
+ require('./language-extension-8c4a56ff.js');
41
41
 
42
42
  /*
43
43
  Stencil Client Patch Browser v2.17.4 | MIT Licensed | https://stenciljs.com
@@ -53,6 +53,12 @@ export class RTEHtmlBlock extends RTEBlock {
53
53
  toHtml() {
54
54
  const BlockTag = this.htmlTag;
55
55
  const attrStr = super.generateAttributeString();
56
+ // Handle void/self-closing tags (hr, input, col, etc.)
57
+ // Uses HTML5 syntax without self-closing slash for consistency with img and br tags
58
+ if (RTEHtmlBlock.VOID_TAGS.has(this.htmlTag)) {
59
+ return `<${BlockTag}${attrStr}>`;
60
+ }
61
+ // Handle normal tags with children
56
62
  return [
57
63
  `<${BlockTag}${attrStr}>`,
58
64
  this.children.map((block) => block.toHtml()).join(''),
@@ -66,3 +72,13 @@ export class RTEHtmlBlock extends RTEBlock {
66
72
  return Object.assign(Object.assign({}, super.toJSON()), { id: this.id, type: this.type, htmlTag: this.htmlTag, children: this.children.map((child) => child.toJSON()) });
67
73
  }
68
74
  }
75
+ /**
76
+ * Void/self-closing tags that don't have closing tags and don't contain children.
77
+ * These tags should be rendered as <tag> or <tag/> instead of <tag></tag>.
78
+ *
79
+ * Based on canHandleTags from html-block-strategy.ts, the following are void tags:
80
+ * - HR: horizontal rule
81
+ * - INPUT: form input
82
+ * - COL: table column
83
+ */
84
+ RTEHtmlBlock.VOID_TAGS = new Set(['hr', 'input', 'col']);
@@ -21,6 +21,7 @@ import { VegaInternalRichTextEditorFlushChanges } from '../../../helpers/event-m
21
21
  import './setup';
22
22
  import { StylePreservator } from '../../../helpers/csp/styles-preservator';
23
23
  import { LogUtility } from '../../../utils/log';
24
+ import { HTMLContentCleaner } from '../slimmers/controllers/html-cleaner';
24
25
  /**
25
26
  * Class representing the content state of the rich text editor.
26
27
  */
@@ -83,28 +84,8 @@ export class VegaRTEContent {
83
84
  * @returns {VegaRTEContent} The converted content state.
84
85
  */
85
86
  static fromHtml(html, options = { autoMatchFormat: true, skipCustomAnnotations: false }) {
86
- /**
87
- * remove redundant spaces between tags, for example:
88
- * case1:
89
- * '<p>\n\t <span>test</span>\n\t </p>' will be formatted into '<p><span>test</span></p>'
90
- * '<p>
91
- * test
92
- * </p>' will be formatted into '<p>test</p>'
93
- *
94
- * case2:
95
- * <h1>
96
- * _test&*....
97
- * </h1> will be formatted into <h1>_test&*....</h1>
98
- *
99
- * The blank space between individual tags should be preserved:
100
- * <span> </span>
101
- */
102
- const formattedHtml = html
103
- .replace(/>\s+<\/?/g, (match) => {
104
- return match.endsWith('</') ? match : '><';
105
- })
106
- .replace(/(>)[\n\t]+(?=[a-zA-Z0-9_\W])/g, '$1')
107
- .replace(/([a-zA-Z0-9_\W])[\n\t]+(?=<)/g, '$1');
87
+ const cleaner = new HTMLContentCleaner();
88
+ const formattedHtml = cleaner.clean(html);
108
89
  const context = StylePreservator.preserve(formattedHtml);
109
90
  const safeHtml = context.getProcessedHtml();
110
91
  const body = new DOMParser().parseFromString(safeHtml, 'text/html').body;
@@ -0,0 +1,59 @@
1
+ import { RemoveWhitespaceBetweenTagsProcessor } from './processors/remove-whitespace-between-tags-processor';
2
+ import { RemoveWhitespaceAfterOpeningTagProcessor } from './processors/remove-whitespace-after-opening-tag-processor';
3
+ import { RemoveWhitespaceBeforeClosingTagProcessor } from './processors/remove-whitespace-before-closing-tag-processor';
4
+ /**
5
+ * Main HTML content cleaner that orchestrates multiple cleaning processors.
6
+ *
7
+ * This class implements a chain of responsibility pattern where each processor
8
+ * handles a specific aspect of HTML cleaning. The processors are applied in sequence
9
+ * and the entire chain is repeated until no more changes occur.
10
+ *
11
+ * Processors (in order):
12
+ * 1. RemoveWhitespaceBetweenTagsProcessor - Removes whitespace between non-matching tags
13
+ * 2. RemoveWhitespaceAfterOpeningTagProcessor - Removes \n and \t after opening tags
14
+ * 3. RemoveWhitespaceBeforeClosingTagProcessor - Removes \n and \t before closing tags
15
+ */
16
+ export class HTMLContentCleaner {
17
+ constructor() {
18
+ this.processors = [
19
+ new RemoveWhitespaceBetweenTagsProcessor(),
20
+ new RemoveWhitespaceAfterOpeningTagProcessor(),
21
+ new RemoveWhitespaceBeforeClosingTagProcessor(),
22
+ ];
23
+ }
24
+ /**
25
+ * Cleans HTML by applying all processors in the chain repeatedly until no changes occur.
26
+ *
27
+ * The cleaning process:
28
+ * 1. Applies each processor in sequence
29
+ * 2. Compares the result with the input
30
+ * 3. If changes were made, repeats the process
31
+ * 4. Returns the final cleaned HTML
32
+ *
33
+ * Examples of transformations:
34
+ * - `<p>\n\t <span>test</span>\n\t </p>` → `<p><span>test</span></p>`
35
+ * - `<p>\n\tHello</p>` → `<p>Hello</p>`
36
+ * - `<p>Hello\n\t</p>` → `<p>Hello</p>`
37
+ * - `<span> </span>` → `<span> </span>` (preserved - matching tags)
38
+ * - `<p>Hello World</p>` → `<p>Hello World</p>` (preserved - regular spaces)
39
+ *
40
+ * @param {string} html - The HTML string to clean.
41
+ * @returns {string} The cleaned HTML string.
42
+ */
43
+ clean(html) {
44
+ if (!html || html.trim().length === 0) {
45
+ return html;
46
+ }
47
+ let result = html;
48
+ let previousResult;
49
+ // Keep processing until no more changes occur
50
+ do {
51
+ previousResult = result;
52
+ // Apply each processor in the chain
53
+ for (const processor of this.processors) {
54
+ result = processor.process(result);
55
+ }
56
+ } while (result !== previousResult);
57
+ return result;
58
+ }
59
+ }
@@ -0,0 +1,4 @@
1
+ export { HTMLContentCleaner } from './html-content-cleaner';
2
+ export { RemoveWhitespaceBetweenTagsProcessor } from './processors/remove-whitespace-between-tags-processor';
3
+ export { RemoveWhitespaceAfterOpeningTagProcessor } from './processors/remove-whitespace-after-opening-tag-processor';
4
+ export { RemoveWhitespaceBeforeClosingTagProcessor } from './processors/remove-whitespace-before-closing-tag-processor';
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Removes `\n` and `\t` characters after opening tags (before text content).
3
+ *
4
+ * Transforms patterns like `>[\n\t]+(text)` to `>(text)`.
5
+ *
6
+ * Examples:
7
+ * - `<p>\n\tHello` → `<p>Hello`
8
+ * - `<div>\n\n\tWorld` → `<div>World`
9
+ */
10
+ export class RemoveWhitespaceAfterOpeningTagProcessor {
11
+ /**
12
+ * Process the HTML string to remove `\n` and `\t` after opening tags.
13
+ *
14
+ * @param {string} html - The HTML string to process.
15
+ * @returns {string} The processed HTML string.
16
+ */
17
+ process(html) {
18
+ // Pattern: `>[\n\t]+(text)` → `>(text)`
19
+ return html.replace(/(>)[\n\t]+(?=.)/g, '$1');
20
+ }
21
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Removes `\n` and `\t` characters before closing tags (after text content).
3
+ *
4
+ * Transforms patterns like `(text)[\n\t]+<` to `(text)<`.
5
+ *
6
+ * Examples:
7
+ * - `World\n\t</p>` → `World</p>`
8
+ * - `Hello\n</div>` → `Hello</div>`
9
+ */
10
+ export class RemoveWhitespaceBeforeClosingTagProcessor {
11
+ /**
12
+ * Process the HTML string to remove `\n` and `\t` before closing tags.
13
+ *
14
+ * @param {string} html - The HTML string to process.
15
+ * @returns {string} The processed HTML string.
16
+ */
17
+ process(html) {
18
+ // Pattern: `(text)[\n\t]+<` → `(text)<`
19
+ return html.replace(/(.?)[\n\t]+(?=<)/g, '$1');
20
+ }
21
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Removes whitespace between tags, except preserves ALL whitespace between matching opening/closing tag pairs.
3
+ *
4
+ * This processor scans for patterns of `<tag>(whitespace)<tag>` and:
5
+ * - If the first tag is an opening tag and the second tag is its matching closing tag (e.g., `<span> </span>`),
6
+ * preserves ALL the whitespace between them (including spaces, tabs, newlines)
7
+ * - Otherwise, removes all the whitespace between the tags
8
+ *
9
+ * Examples:
10
+ * - `</p>\n\t<div>` → `</p><div>` (different tags: closing p, opening div - whitespace removed)
11
+ * - `<div>\n\t<span>` → `<div><span>` (different tags: opening div, opening span - whitespace removed)
12
+ * - `<span> </span>` → `<span> </span>` (matching tags: opening span, closing span - space preserved)
13
+ * - `<span> </span>` → `<span> </span>` (matching tags - multiple spaces preserved)
14
+ * - `<span>\n\t</span>` → `<span>\n\t</span>` (matching tags - \n\t preserved)
15
+ * - `<code> </code>` → `<code> </code>` (matching tags - space preserved)
16
+ * - `</div> <p>` → `</div><p>` (different tags: closing div, opening p - whitespace removed)
17
+ */
18
+ export class RemoveWhitespaceBetweenTagsProcessor {
19
+ /**
20
+ * Process the HTML string to remove whitespace between non-matching tags.
21
+ *
22
+ * @param {string} html - The HTML string to process.
23
+ * @returns {string} The processed HTML string.
24
+ */
25
+ process(html) {
26
+ return html.replace(/(<[^>]+>)(\s+)(<[^>]+>)/g, (_match, tag1, whitespace, tag2) => {
27
+ const openingTagName = this.extractOpeningTagName(tag1);
28
+ const closingTagName = this.extractClosingTagName(tag2);
29
+ // Preserve all whitespace if tags match (e.g., <span> </span>)
30
+ if (openingTagName && closingTagName && openingTagName === closingTagName) {
31
+ return `${tag1}${whitespace}${tag2}`;
32
+ }
33
+ // Remove whitespace for non-matching tags
34
+ return `${tag1}${tag2}`;
35
+ });
36
+ }
37
+ /**
38
+ * Extracts the tag name from an opening HTML tag.
39
+ *
40
+ * Supports standard HTML tags (div, span, h1, etc.) and custom elements with hyphens (my-component).
41
+ *
42
+ * Examples:
43
+ * - `<span>` → `span`
44
+ * - `<div class="test">` → `div`
45
+ * - `<my-component id="123">` → `my-component`
46
+ * - `</span>` → `null` (not an opening tag)
47
+ *
48
+ * @param {string} tag - The tag string to extract from (e.g., '<span>', '<div class="test">').
49
+ * @returns {string | null} The tag name or null if not an opening tag.
50
+ * @private
51
+ */
52
+ extractOpeningTagName(tag) {
53
+ // Pattern: <(tag name) where tag name starts with letter, followed by letters/numbers/hyphens
54
+ const match = tag.match(/<(\w[\w-]*)/);
55
+ return match ? match[1] : null;
56
+ }
57
+ /**
58
+ * Extracts the tag name from a closing HTML tag.
59
+ *
60
+ * Supports standard HTML tags (div, span, h1, etc.) and custom elements with hyphens (my-component).
61
+ *
62
+ * Examples:
63
+ * - `</span>` → `span`
64
+ * - `</div>` → `div`
65
+ * - `</my-component>` → `my-component`
66
+ * - `<span>` → `null` (not a closing tag)
67
+ *
68
+ * @param {string} tag - The tag string to extract from (e.g., '</span>', '</div>').
69
+ * @returns {string | null} The tag name or null if not a closing tag.
70
+ * @private
71
+ */
72
+ extractClosingTagName(tag) {
73
+ // Pattern: </(tag name) where tag name starts with letter, followed by letters/numbers/hyphens
74
+ const match = tag.match(/<\/(\w[\w-]*)/);
75
+ return match ? match[1] : null;
76
+ }
77
+ }