@aquera/nile-elements 2.0.15 → 2.0.17

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 (376) hide show
  1. package/README.md +6 -0
  2. package/demo/nxtgen-classes.css +5 -5
  3. package/demo/nxtgen-dark.css +16 -16
  4. package/demo/nxtgen-properties.css +2 -2
  5. package/demo/nxtgen-utilities.css +5 -5
  6. package/demo/nxtgen.css +5 -5
  7. package/demo/utilities.css +2 -2
  8. package/demo/variables.css +2 -2
  9. package/dist/{index-f6944844.cjs.js → index-0c0c869d.cjs.js} +2 -2
  10. package/dist/{index-f6944844.cjs.js.map → index-0c0c869d.cjs.js.map} +1 -1
  11. package/dist/{index-403841c7.cjs.js → index-129ef6fb.cjs.js} +3 -3
  12. package/dist/{index-403841c7.cjs.js.map → index-129ef6fb.cjs.js.map} +1 -1
  13. package/dist/{index-1faa963c.esm.js → index-36f2a6b5.esm.js} +1 -1
  14. package/dist/index-4df50481.esm.js +1 -0
  15. package/dist/index-5d34cff1.esm.js +1 -0
  16. package/dist/index-7ae95edd.cjs.js +2 -0
  17. package/dist/{index-3ca67627.cjs.js.map → index-7ae95edd.cjs.js.map} +1 -1
  18. package/dist/index-7ca72b78.esm.js +1 -0
  19. package/dist/index-bbe23ad8.cjs.js +2 -0
  20. package/dist/index-bbe23ad8.cjs.js.map +1 -0
  21. package/dist/index-ccc6a799.cjs.js +5 -0
  22. package/dist/index-ccc6a799.cjs.js.map +1 -0
  23. package/dist/index.cjs.js +1 -1
  24. package/dist/index.esm.js +1 -1
  25. package/dist/index.js +124 -72
  26. package/dist/nile-auto-complete/index.cjs.js +1 -1
  27. package/dist/nile-auto-complete/nile-auto-complete.cjs.js +1 -1
  28. package/dist/nile-auto-complete/portal-manager.cjs.js +1 -1
  29. package/dist/nile-auto-complete/portal-utils.cjs.js +1 -1
  30. package/dist/nile-code-editor/extensionSetup.cjs.js +2 -2
  31. package/dist/nile-code-editor/index.cjs.js +1 -1
  32. package/dist/nile-code-editor/nile-code-editor.cjs.js +1 -1
  33. package/dist/nile-code-editor/theme.cjs.js +1 -1
  34. package/dist/nile-color-picker/index.cjs.js +1 -1
  35. package/dist/nile-color-picker/nile-color-picker.cjs.js +1 -1
  36. package/dist/nile-combobox/index.cjs.js +1 -1
  37. package/dist/nile-combobox/nile-combobox.cjs.js +1 -1
  38. package/dist/nile-combobox/portal-manager.cjs.js +1 -1
  39. package/dist/nile-context-menu/index.cjs.js +1 -1
  40. package/dist/nile-context-menu/nile-context-menu.cjs.js +1 -1
  41. package/dist/nile-context-submenu/index.cjs.js +1 -1
  42. package/dist/nile-context-submenu/nile-context-submenu.cjs.js +1 -1
  43. package/dist/nile-detail/index.cjs.js +1 -1
  44. package/dist/nile-detail/nile-detail.cjs.js +1 -1
  45. package/dist/nile-dropdown/index.cjs.js +1 -1
  46. package/dist/nile-dropdown/nile-dropdown.cjs.js +1 -1
  47. package/dist/nile-dropdown/portal-manager.cjs.js +1 -1
  48. package/dist/nile-file-upload/index.cjs.js +1 -1
  49. package/dist/nile-file-upload/nile-file-upload.cjs.js +1 -1
  50. package/dist/nile-file-upload/nile-file-upload.template.cjs.js +1 -1
  51. package/dist/nile-floating-panel/index.cjs.js +1 -1
  52. package/dist/nile-floating-panel/nile-floating-panel.cjs.js +1 -1
  53. package/dist/nile-lite-tooltip/index.cjs.js +1 -1
  54. package/dist/nile-lite-tooltip/nile-lite-tooltip.cjs.js +1 -1
  55. package/dist/nile-lite-tooltip/nile-lite-tooltip.css.cjs.js +1 -1
  56. package/dist/nile-lite-tooltip/nile-lite-tooltip.css.cjs.js.map +1 -1
  57. package/dist/nile-lite-tooltip/nile-lite-tooltip.css.esm.js +1 -1
  58. package/dist/nile-markdown-editor/index.cjs.js +1 -1
  59. package/dist/nile-markdown-editor/nile-markdown-editor.cjs.js +1 -1
  60. package/dist/nile-popover/index.cjs.js +1 -1
  61. package/dist/nile-popover/nile-popover.cjs.js +1 -1
  62. package/dist/nile-popover/portal-manager.cjs.js +1 -1
  63. package/dist/nile-popup/index.cjs.js +1 -1
  64. package/dist/nile-popup/nile-popup.cjs.js +1 -1
  65. package/dist/nile-segmented-progress-bar/index.cjs.js +1 -1
  66. package/dist/nile-segmented-progress-bar/nile-segmented-progress-bar.cjs.js +1 -1
  67. package/dist/nile-select/index.cjs.js +1 -1
  68. package/dist/nile-select/nile-select.cjs.js +1 -1
  69. package/dist/nile-select/portal-manager.cjs.js +1 -1
  70. package/dist/nile-side-bar-action/index.cjs.js +1 -1
  71. package/dist/nile-side-bar-action/nile-side-bar-action.cjs.js +1 -1
  72. package/dist/nile-side-bar-action/portal-manager.cjs.js +1 -1
  73. package/dist/nile-tooltip/index.cjs.js +1 -1
  74. package/dist/nile-tooltip/nile-tooltip.cjs.js +1 -1
  75. package/dist/nile-tooltip/nile-tooltip.css.cjs.js +1 -1
  76. package/dist/nile-tooltip/nile-tooltip.css.cjs.js.map +1 -1
  77. package/dist/nile-tooltip/nile-tooltip.css.esm.js +1 -1
  78. package/dist/nile-virtual-select/index.cjs.js +1 -1
  79. package/dist/nile-virtual-select/nile-virtual-select.cjs.js +1 -1
  80. package/dist/nile-virtual-select/portal-manager.cjs.js +1 -1
  81. package/dist/nile-virtual-select/renderer.cjs.js +1 -1
  82. package/dist/nile-wysiwyg-editor/engine/commands.cjs.js +1 -1
  83. package/dist/nile-wysiwyg-editor/engine/commands.cjs.js.map +1 -1
  84. package/dist/nile-wysiwyg-editor/engine/commands.esm.js +1 -1
  85. package/dist/nile-wysiwyg-editor/engine/create-state.cjs.js +1 -1
  86. package/dist/nile-wysiwyg-editor/engine/create-state.cjs.js.map +1 -1
  87. package/dist/nile-wysiwyg-editor/engine/create-state.esm.js +1 -1
  88. package/dist/nile-wysiwyg-editor/engine/email-css.cjs.js +2 -0
  89. package/dist/nile-wysiwyg-editor/engine/email-css.cjs.js.map +1 -0
  90. package/dist/nile-wysiwyg-editor/engine/email-css.esm.js +1 -0
  91. package/dist/nile-wysiwyg-editor/engine/email-render.cjs.js +2 -0
  92. package/dist/nile-wysiwyg-editor/engine/email-render.cjs.js.map +1 -0
  93. package/dist/nile-wysiwyg-editor/engine/email-render.esm.js +1 -0
  94. package/dist/nile-wysiwyg-editor/engine/html-detect.cjs.js +2 -0
  95. package/dist/nile-wysiwyg-editor/engine/html-detect.cjs.js.map +1 -0
  96. package/dist/nile-wysiwyg-editor/engine/html-detect.esm.js +1 -0
  97. package/dist/nile-wysiwyg-editor/engine/index.cjs.js +1 -1
  98. package/dist/nile-wysiwyg-editor/engine/index.esm.js +1 -1
  99. package/dist/nile-wysiwyg-editor/engine/inputrules.cjs.js +1 -1
  100. package/dist/nile-wysiwyg-editor/engine/inputrules.cjs.js.map +1 -1
  101. package/dist/nile-wysiwyg-editor/engine/inputrules.esm.js +1 -1
  102. package/dist/nile-wysiwyg-editor/engine/keymap.cjs.js +1 -1
  103. package/dist/nile-wysiwyg-editor/engine/keymap.cjs.js.map +1 -1
  104. package/dist/nile-wysiwyg-editor/engine/keymap.esm.js +1 -1
  105. package/dist/nile-wysiwyg-editor/engine/plugins/code-highlight.cjs.js +1 -1
  106. package/dist/nile-wysiwyg-editor/engine/plugins/code-highlight.cjs.js.map +1 -1
  107. package/dist/nile-wysiwyg-editor/engine/plugins/code-highlight.esm.js +1 -1
  108. package/dist/nile-wysiwyg-editor/engine/plugins/embed-view.cjs.js +1 -1
  109. package/dist/nile-wysiwyg-editor/engine/plugins/embed-view.cjs.js.map +1 -1
  110. package/dist/nile-wysiwyg-editor/engine/plugins/embed-view.esm.js +1 -1
  111. package/dist/nile-wysiwyg-editor/engine/plugins/embeds.cjs.js +1 -1
  112. package/dist/nile-wysiwyg-editor/engine/plugins/embeds.cjs.js.map +1 -1
  113. package/dist/nile-wysiwyg-editor/engine/plugins/embeds.esm.js +1 -1
  114. package/dist/nile-wysiwyg-editor/engine/plugins/find-replace.cjs.js +1 -1
  115. package/dist/nile-wysiwyg-editor/engine/plugins/find-replace.cjs.js.map +1 -1
  116. package/dist/nile-wysiwyg-editor/engine/plugins/find-replace.esm.js +1 -1
  117. package/dist/nile-wysiwyg-editor/engine/plugins/format-painter.cjs.js +1 -1
  118. package/dist/nile-wysiwyg-editor/engine/plugins/format-painter.cjs.js.map +1 -1
  119. package/dist/nile-wysiwyg-editor/engine/plugins/format-painter.esm.js +1 -1
  120. package/dist/nile-wysiwyg-editor/engine/plugins/image-view.cjs.js +1 -1
  121. package/dist/nile-wysiwyg-editor/engine/plugins/image-view.cjs.js.map +1 -1
  122. package/dist/nile-wysiwyg-editor/engine/plugins/image-view.esm.js +1 -1
  123. package/dist/nile-wysiwyg-editor/engine/plugins/image.cjs.js +1 -1
  124. package/dist/nile-wysiwyg-editor/engine/plugins/image.cjs.js.map +1 -1
  125. package/dist/nile-wysiwyg-editor/engine/plugins/image.esm.js +1 -1
  126. package/dist/nile-wysiwyg-editor/engine/plugins/link.cjs.js +1 -1
  127. package/dist/nile-wysiwyg-editor/engine/plugins/link.cjs.js.map +1 -1
  128. package/dist/nile-wysiwyg-editor/engine/plugins/link.esm.js +1 -1
  129. package/dist/nile-wysiwyg-editor/engine/plugins/max-length.cjs.js +1 -1
  130. package/dist/nile-wysiwyg-editor/engine/plugins/max-length.cjs.js.map +1 -1
  131. package/dist/nile-wysiwyg-editor/engine/plugins/max-length.esm.js +1 -1
  132. package/dist/nile-wysiwyg-editor/engine/plugins/paste.cjs.js +1 -1
  133. package/dist/nile-wysiwyg-editor/engine/plugins/paste.cjs.js.map +1 -1
  134. package/dist/nile-wysiwyg-editor/engine/plugins/paste.esm.js +1 -1
  135. package/dist/nile-wysiwyg-editor/engine/plugins/placeholder.cjs.js +1 -1
  136. package/dist/nile-wysiwyg-editor/engine/plugins/placeholder.cjs.js.map +1 -1
  137. package/dist/nile-wysiwyg-editor/engine/plugins/placeholder.esm.js +1 -1
  138. package/dist/nile-wysiwyg-editor/engine/plugins/single-line.cjs.js +1 -1
  139. package/dist/nile-wysiwyg-editor/engine/plugins/single-line.cjs.js.map +1 -1
  140. package/dist/nile-wysiwyg-editor/engine/plugins/single-line.esm.js +1 -1
  141. package/dist/nile-wysiwyg-editor/engine/plugins/suggestions.cjs.js +1 -1
  142. package/dist/nile-wysiwyg-editor/engine/plugins/suggestions.cjs.js.map +1 -1
  143. package/dist/nile-wysiwyg-editor/engine/plugins/suggestions.esm.js +1 -1
  144. package/dist/nile-wysiwyg-editor/engine/plugins/tables.cjs.js +1 -1
  145. package/dist/nile-wysiwyg-editor/engine/plugins/tables.cjs.js.map +1 -1
  146. package/dist/nile-wysiwyg-editor/engine/plugins/tables.esm.js +1 -1
  147. package/dist/nile-wysiwyg-editor/engine/sanitize.cjs.js +2 -1
  148. package/dist/nile-wysiwyg-editor/engine/sanitize.cjs.js.map +1 -1
  149. package/dist/nile-wysiwyg-editor/engine/sanitize.esm.js +1 -1
  150. package/dist/nile-wysiwyg-editor/engine/schema.cjs.js +1 -1
  151. package/dist/nile-wysiwyg-editor/engine/schema.cjs.js.map +1 -1
  152. package/dist/nile-wysiwyg-editor/engine/schema.esm.js +1 -1
  153. package/dist/nile-wysiwyg-editor/engine/selection-state.cjs.js +1 -1
  154. package/dist/nile-wysiwyg-editor/engine/selection-state.cjs.js.map +1 -1
  155. package/dist/nile-wysiwyg-editor/engine/selection-state.esm.js +1 -1
  156. package/dist/nile-wysiwyg-editor/engine/serializer.cjs.js +1 -1
  157. package/dist/nile-wysiwyg-editor/engine/serializer.cjs.js.map +1 -1
  158. package/dist/nile-wysiwyg-editor/engine/serializer.esm.js +1 -1
  159. package/dist/nile-wysiwyg-editor/index.cjs.js +1 -1
  160. package/dist/nile-wysiwyg-editor/index.esm.js +1 -1
  161. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.cjs.js +1 -1
  162. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.cjs.js.map +1 -1
  163. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.css.cjs.js +1 -1
  164. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.css.cjs.js.map +1 -1
  165. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.css.esm.js +45 -4
  166. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.esm.js +2 -2
  167. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.cjs.js +1 -1
  168. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.cjs.js +1 -1
  169. package/dist/nile-wysiwyg-editor/ui/bookmark-panel.cjs.js +1 -1
  170. package/dist/nile-wysiwyg-editor/ui/bookmark-panel.cjs.js.map +1 -1
  171. package/dist/nile-wysiwyg-editor/ui/bookmark-panel.esm.js +2 -2
  172. package/dist/nile-wysiwyg-editor/ui/bubble-menu.cjs.js +1 -1
  173. package/dist/nile-wysiwyg-editor/ui/bubble-menu.cjs.js.map +1 -1
  174. package/dist/nile-wysiwyg-editor/ui/bubble-menu.esm.js +5 -5
  175. package/dist/nile-wysiwyg-editor/ui/code-block-menu.cjs.js +1 -1
  176. package/dist/nile-wysiwyg-editor/ui/code-block-menu.cjs.js.map +1 -1
  177. package/dist/nile-wysiwyg-editor/ui/code-block-menu.esm.js +1 -1
  178. package/dist/nile-wysiwyg-editor/ui/embed-menu.cjs.js +1 -1
  179. package/dist/nile-wysiwyg-editor/ui/embed-menu.cjs.js.map +1 -1
  180. package/dist/nile-wysiwyg-editor/ui/embed-menu.esm.js +1 -1
  181. package/dist/nile-wysiwyg-editor/ui/embed-panel.cjs.js +1 -1
  182. package/dist/nile-wysiwyg-editor/ui/embed-panel.cjs.js.map +1 -1
  183. package/dist/nile-wysiwyg-editor/ui/embed-panel.esm.js +2 -2
  184. package/dist/nile-wysiwyg-editor/ui/emoji-picker.cjs.js +1 -1
  185. package/dist/nile-wysiwyg-editor/ui/emoji-picker.cjs.js.map +1 -1
  186. package/dist/nile-wysiwyg-editor/ui/emoji-picker.esm.js +1 -1
  187. package/dist/nile-wysiwyg-editor/ui/find-replace.cjs.js +1 -1
  188. package/dist/nile-wysiwyg-editor/ui/find-replace.cjs.js.map +1 -1
  189. package/dist/nile-wysiwyg-editor/ui/find-replace.esm.js +3 -3
  190. package/dist/nile-wysiwyg-editor/ui/image-menu.cjs.js +1 -1
  191. package/dist/nile-wysiwyg-editor/ui/image-menu.cjs.js.map +1 -1
  192. package/dist/nile-wysiwyg-editor/ui/image-menu.esm.js +3 -3
  193. package/dist/nile-wysiwyg-editor/ui/image-panel.cjs.js +1 -1
  194. package/dist/nile-wysiwyg-editor/ui/image-panel.cjs.js.map +1 -1
  195. package/dist/nile-wysiwyg-editor/ui/image-panel.esm.js +1 -1
  196. package/dist/nile-wysiwyg-editor/ui/insert-menu.cjs.js +1 -1
  197. package/dist/nile-wysiwyg-editor/ui/insert-menu.cjs.js.map +1 -1
  198. package/dist/nile-wysiwyg-editor/ui/insert-menu.esm.js +1 -1
  199. package/dist/nile-wysiwyg-editor/ui/link-editor.cjs.js +1 -1
  200. package/dist/nile-wysiwyg-editor/ui/link-editor.cjs.js.map +1 -1
  201. package/dist/nile-wysiwyg-editor/ui/link-editor.esm.js +9 -9
  202. package/dist/nile-wysiwyg-editor/ui/markdown-panel.cjs.js +1 -1
  203. package/dist/nile-wysiwyg-editor/ui/markdown-panel.cjs.js.map +1 -1
  204. package/dist/nile-wysiwyg-editor/ui/markdown-panel.esm.js +1 -1
  205. package/dist/nile-wysiwyg-editor/ui/math-panel.cjs.js +1 -1
  206. package/dist/nile-wysiwyg-editor/ui/math-panel.cjs.js.map +1 -1
  207. package/dist/nile-wysiwyg-editor/ui/math-panel.esm.js +1 -1
  208. package/dist/nile-wysiwyg-editor/ui/shortcut-help.cjs.js +1 -1
  209. package/dist/nile-wysiwyg-editor/ui/shortcut-help.cjs.js.map +1 -1
  210. package/dist/nile-wysiwyg-editor/ui/shortcut-help.esm.js +1 -1
  211. package/dist/nile-wysiwyg-editor/ui/source-view.cjs.js +1 -1
  212. package/dist/nile-wysiwyg-editor/ui/source-view.cjs.js.map +1 -1
  213. package/dist/nile-wysiwyg-editor/ui/source-view.esm.js +4 -4
  214. package/dist/nile-wysiwyg-editor/ui/special-chars.cjs.js +1 -1
  215. package/dist/nile-wysiwyg-editor/ui/special-chars.cjs.js.map +1 -1
  216. package/dist/nile-wysiwyg-editor/ui/special-chars.esm.js +1 -1
  217. package/dist/nile-wysiwyg-editor/ui/suggest-list.cjs.js +1 -1
  218. package/dist/nile-wysiwyg-editor/ui/suggest-list.cjs.js.map +1 -1
  219. package/dist/nile-wysiwyg-editor/ui/suggest-list.esm.js +23 -12
  220. package/dist/nile-wysiwyg-editor/ui/table-grid-picker.cjs.js +1 -1
  221. package/dist/nile-wysiwyg-editor/ui/table-grid-picker.cjs.js.map +1 -1
  222. package/dist/nile-wysiwyg-editor/ui/table-grid-picker.esm.js +7 -7
  223. package/dist/nile-wysiwyg-editor/ui/table-menu.cjs.js +1 -1
  224. package/dist/nile-wysiwyg-editor/ui/table-menu.cjs.js.map +1 -1
  225. package/dist/nile-wysiwyg-editor/ui/table-menu.esm.js +1 -1
  226. package/dist/src/nile-lite-tooltip/nile-lite-tooltip.css.js +1 -1
  227. package/dist/src/nile-lite-tooltip/nile-lite-tooltip.css.js.map +1 -1
  228. package/dist/src/nile-tooltip/nile-tooltip.css.js +1 -1
  229. package/dist/src/nile-tooltip/nile-tooltip.css.js.map +1 -1
  230. package/dist/src/nile-wysiwyg-editor/engine/create-state.d.ts +5 -0
  231. package/dist/src/nile-wysiwyg-editor/engine/create-state.js +2 -0
  232. package/dist/src/nile-wysiwyg-editor/engine/create-state.js.map +1 -1
  233. package/dist/src/nile-wysiwyg-editor/engine/email-css.d.ts +14 -0
  234. package/dist/src/nile-wysiwyg-editor/engine/email-css.js +140 -0
  235. package/dist/src/nile-wysiwyg-editor/engine/email-css.js.map +1 -0
  236. package/dist/src/nile-wysiwyg-editor/engine/email-fidelity.test.d.ts +1 -0
  237. package/dist/src/nile-wysiwyg-editor/engine/email-fidelity.test.js +1045 -0
  238. package/dist/src/nile-wysiwyg-editor/engine/email-fidelity.test.js.map +1 -0
  239. package/dist/src/nile-wysiwyg-editor/engine/email-render.d.ts +11 -0
  240. package/dist/src/nile-wysiwyg-editor/engine/email-render.js +93 -0
  241. package/dist/src/nile-wysiwyg-editor/engine/email-render.js.map +1 -0
  242. package/dist/src/nile-wysiwyg-editor/engine/html-detect.d.ts +2 -0
  243. package/dist/src/nile-wysiwyg-editor/engine/html-detect.js +24 -0
  244. package/dist/src/nile-wysiwyg-editor/engine/html-detect.js.map +1 -0
  245. package/dist/src/nile-wysiwyg-editor/engine/index.d.ts +4 -1
  246. package/dist/src/nile-wysiwyg-editor/engine/index.js +3 -1
  247. package/dist/src/nile-wysiwyg-editor/engine/index.js.map +1 -1
  248. package/dist/src/nile-wysiwyg-editor/engine/inputrules.d.ts +0 -5
  249. package/dist/src/nile-wysiwyg-editor/engine/inputrules.js +19 -0
  250. package/dist/src/nile-wysiwyg-editor/engine/inputrules.js.map +1 -1
  251. package/dist/src/nile-wysiwyg-editor/engine/plugins/image-view.js +3 -2
  252. package/dist/src/nile-wysiwyg-editor/engine/plugins/image-view.js.map +1 -1
  253. package/dist/src/nile-wysiwyg-editor/engine/plugins/link.d.ts +4 -0
  254. package/dist/src/nile-wysiwyg-editor/engine/plugins/link.js +56 -1
  255. package/dist/src/nile-wysiwyg-editor/engine/plugins/link.js.map +1 -1
  256. package/dist/src/nile-wysiwyg-editor/engine/plugins/paste.d.ts +5 -0
  257. package/dist/src/nile-wysiwyg-editor/engine/plugins/paste.js +27 -6
  258. package/dist/src/nile-wysiwyg-editor/engine/plugins/paste.js.map +1 -1
  259. package/dist/src/nile-wysiwyg-editor/engine/plugins/tables.js +30 -7
  260. package/dist/src/nile-wysiwyg-editor/engine/plugins/tables.js.map +1 -1
  261. package/dist/src/nile-wysiwyg-editor/engine/pm.test.js +46 -0
  262. package/dist/src/nile-wysiwyg-editor/engine/pm.test.js.map +1 -1
  263. package/dist/src/nile-wysiwyg-editor/engine/sanitize.d.ts +9 -1
  264. package/dist/src/nile-wysiwyg-editor/engine/sanitize.js +730 -7
  265. package/dist/src/nile-wysiwyg-editor/engine/sanitize.js.map +1 -1
  266. package/dist/src/nile-wysiwyg-editor/engine/schema.d.ts +3 -0
  267. package/dist/src/nile-wysiwyg-editor/engine/schema.js +215 -34
  268. package/dist/src/nile-wysiwyg-editor/engine/schema.js.map +1 -1
  269. package/dist/src/nile-wysiwyg-editor/engine/selection-state.js +3 -1
  270. package/dist/src/nile-wysiwyg-editor/engine/selection-state.js.map +1 -1
  271. package/dist/src/nile-wysiwyg-editor/engine/serializer.d.ts +12 -4
  272. package/dist/src/nile-wysiwyg-editor/engine/serializer.js +18 -8
  273. package/dist/src/nile-wysiwyg-editor/engine/serializer.js.map +1 -1
  274. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor-email-fidelity.test.d.ts +1 -0
  275. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor-email-fidelity.test.js +287 -0
  276. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor-email-fidelity.test.js.map +1 -0
  277. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.css.js +45 -4
  278. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.css.js.map +1 -1
  279. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.d.ts +23 -0
  280. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.js +113 -15
  281. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.js.map +1 -1
  282. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.test.js +213 -0
  283. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.test.js.map +1 -1
  284. package/dist/src/nile-wysiwyg-editor/ui/bookmark-panel.js +2 -2
  285. package/dist/src/nile-wysiwyg-editor/ui/bookmark-panel.js.map +1 -1
  286. package/dist/src/nile-wysiwyg-editor/ui/bubble-menu.js +1 -1
  287. package/dist/src/nile-wysiwyg-editor/ui/bubble-menu.js.map +1 -1
  288. package/dist/src/nile-wysiwyg-editor/ui/embed-menu.js +1 -1
  289. package/dist/src/nile-wysiwyg-editor/ui/embed-menu.js.map +1 -1
  290. package/dist/src/nile-wysiwyg-editor/ui/embed-panel.js +1 -1
  291. package/dist/src/nile-wysiwyg-editor/ui/embed-panel.js.map +1 -1
  292. package/dist/src/nile-wysiwyg-editor/ui/emoji-picker.js +1 -1
  293. package/dist/src/nile-wysiwyg-editor/ui/emoji-picker.js.map +1 -1
  294. package/dist/src/nile-wysiwyg-editor/ui/find-replace.js +1 -1
  295. package/dist/src/nile-wysiwyg-editor/ui/find-replace.js.map +1 -1
  296. package/dist/src/nile-wysiwyg-editor/ui/image-menu.js +1 -1
  297. package/dist/src/nile-wysiwyg-editor/ui/image-menu.js.map +1 -1
  298. package/dist/src/nile-wysiwyg-editor/ui/image-panel.js +1 -1
  299. package/dist/src/nile-wysiwyg-editor/ui/image-panel.js.map +1 -1
  300. package/dist/src/nile-wysiwyg-editor/ui/insert-menu.js +1 -1
  301. package/dist/src/nile-wysiwyg-editor/ui/insert-menu.js.map +1 -1
  302. package/dist/src/nile-wysiwyg-editor/ui/link-editor.js +2 -2
  303. package/dist/src/nile-wysiwyg-editor/ui/link-editor.js.map +1 -1
  304. package/dist/src/nile-wysiwyg-editor/ui/markdown-panel.js +1 -1
  305. package/dist/src/nile-wysiwyg-editor/ui/markdown-panel.js.map +1 -1
  306. package/dist/src/nile-wysiwyg-editor/ui/math-panel.js +1 -1
  307. package/dist/src/nile-wysiwyg-editor/ui/math-panel.js.map +1 -1
  308. package/dist/src/nile-wysiwyg-editor/ui/shortcut-help.js +1 -1
  309. package/dist/src/nile-wysiwyg-editor/ui/shortcut-help.js.map +1 -1
  310. package/dist/src/nile-wysiwyg-editor/ui/source-view.js +2 -2
  311. package/dist/src/nile-wysiwyg-editor/ui/source-view.js.map +1 -1
  312. package/dist/src/nile-wysiwyg-editor/ui/special-chars.js +1 -1
  313. package/dist/src/nile-wysiwyg-editor/ui/special-chars.js.map +1 -1
  314. package/dist/src/nile-wysiwyg-editor/ui/suggest-list.js +14 -3
  315. package/dist/src/nile-wysiwyg-editor/ui/suggest-list.js.map +1 -1
  316. package/dist/src/nile-wysiwyg-editor/ui/table-grid-picker.js +2 -2
  317. package/dist/src/nile-wysiwyg-editor/ui/table-grid-picker.js.map +1 -1
  318. package/dist/src/nile-wysiwyg-editor/ui/table-menu.js +1 -1
  319. package/dist/src/nile-wysiwyg-editor/ui/table-menu.js.map +1 -1
  320. package/dist/src/version.js +1 -1
  321. package/dist/src/version.js.map +1 -1
  322. package/dist/tsconfig.tsbuildinfo +1 -1
  323. package/dist/version.cjs.js +1 -1
  324. package/dist/version.cjs.js.map +1 -1
  325. package/dist/version.esm.js +1 -1
  326. package/package.json +1 -1
  327. package/src/nile-lite-tooltip/nile-lite-tooltip.css.ts +1 -1
  328. package/src/nile-tooltip/nile-tooltip.css.ts +1 -1
  329. package/src/nile-wysiwyg-editor/engine/create-state.ts +7 -0
  330. package/src/nile-wysiwyg-editor/engine/email-css.ts +136 -0
  331. package/src/nile-wysiwyg-editor/engine/email-fidelity.test.ts +1347 -0
  332. package/src/nile-wysiwyg-editor/engine/email-render.ts +99 -0
  333. package/src/nile-wysiwyg-editor/engine/html-detect.ts +26 -0
  334. package/src/nile-wysiwyg-editor/engine/index.ts +10 -1
  335. package/src/nile-wysiwyg-editor/engine/inputrules.ts +18 -1
  336. package/src/nile-wysiwyg-editor/engine/plugins/image-view.ts +3 -2
  337. package/src/nile-wysiwyg-editor/engine/plugins/link.ts +58 -2
  338. package/src/nile-wysiwyg-editor/engine/plugins/paste.ts +31 -8
  339. package/src/nile-wysiwyg-editor/engine/plugins/tables.ts +29 -7
  340. package/src/nile-wysiwyg-editor/engine/pm.test.ts +73 -0
  341. package/src/nile-wysiwyg-editor/engine/sanitize.ts +729 -7
  342. package/src/nile-wysiwyg-editor/engine/schema.ts +206 -33
  343. package/src/nile-wysiwyg-editor/engine/selection-state.ts +3 -1
  344. package/src/nile-wysiwyg-editor/engine/serializer.ts +30 -8
  345. package/src/nile-wysiwyg-editor/nile-wysiwyg-editor-email-fidelity.test.ts +357 -0
  346. package/src/nile-wysiwyg-editor/nile-wysiwyg-editor.css.ts +45 -4
  347. package/src/nile-wysiwyg-editor/nile-wysiwyg-editor.test.ts +258 -0
  348. package/src/nile-wysiwyg-editor/nile-wysiwyg-editor.ts +119 -12
  349. package/src/nile-wysiwyg-editor/ui/bookmark-panel.ts +2 -2
  350. package/src/nile-wysiwyg-editor/ui/bubble-menu.ts +1 -1
  351. package/src/nile-wysiwyg-editor/ui/embed-menu.ts +1 -1
  352. package/src/nile-wysiwyg-editor/ui/embed-panel.ts +1 -1
  353. package/src/nile-wysiwyg-editor/ui/emoji-picker.ts +1 -1
  354. package/src/nile-wysiwyg-editor/ui/find-replace.ts +1 -1
  355. package/src/nile-wysiwyg-editor/ui/image-menu.ts +1 -1
  356. package/src/nile-wysiwyg-editor/ui/image-panel.ts +1 -1
  357. package/src/nile-wysiwyg-editor/ui/insert-menu.ts +1 -1
  358. package/src/nile-wysiwyg-editor/ui/link-editor.ts +2 -2
  359. package/src/nile-wysiwyg-editor/ui/markdown-panel.ts +1 -1
  360. package/src/nile-wysiwyg-editor/ui/math-panel.ts +1 -1
  361. package/src/nile-wysiwyg-editor/ui/shortcut-help.ts +1 -1
  362. package/src/nile-wysiwyg-editor/ui/source-view.ts +2 -2
  363. package/src/nile-wysiwyg-editor/ui/special-chars.ts +1 -1
  364. package/src/nile-wysiwyg-editor/ui/suggest-list.ts +14 -3
  365. package/src/nile-wysiwyg-editor/ui/table-grid-picker.ts +2 -2
  366. package/src/nile-wysiwyg-editor/ui/table-menu.ts +1 -1
  367. package/vscode-html-custom-data.json +15 -1
  368. package/web-test-runner.config.mjs +4 -0
  369. package/dist/index-3ca67627.cjs.js +0 -2
  370. package/dist/index-6f3fa4ab.esm.js +0 -1
  371. package/dist/index-7b1c9857.esm.js +0 -1
  372. package/dist/index-89c520e9.cjs.js +0 -5
  373. package/dist/index-89c520e9.cjs.js.map +0 -1
  374. package/dist/index-ba47645d.esm.js +0 -1
  375. package/dist/index-c3210a9c.cjs.js +0 -2
  376. package/dist/index-c3210a9c.cjs.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-fidelity.test.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/engine/email-fidelity.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { defaultSchema, htmlToDoc, docToHtml, sanitizeHtml } from './index';\nimport { looksLikeHtml } from './html-detect';\n\n/**\n * A compact \"bulletproof\" email: outer 100% table → 600px container with a\n * background/border → coloured header cell → body cell with padding + font +\n * an h1/p carrying margins and inline strong/em/underline spans → a callout\n * cell with a left border → a bgcolor button cell wrapping an <a> → a footer\n * cell with a top border → and a display:none preheader div that must drop.\n */\nconst EMAIL_FIXTURE = `\n<div style=\"display:none; max-height:0; overflow:hidden; mso-hide:all; font-size:1px; line-height:1px; color:#eef1f4;\">\n Hidden preheader text that should never survive.\n</div>\n<table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"background-color:#eef1f4;\">\n <tr>\n <td align=\"center\" style=\"padding:32px 12px;\">\n <table role=\"presentation\" width=\"600\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"width:100%; max-width:600px; background-color:#ffffff; border:1px solid #d9dee4;\">\n <tr>\n <td style=\"padding:28px 40px; background-color:#1f3a5f;\">\n <p style=\"margin:0; font-family:Georgia, 'Times New Roman', serif; font-size:24px; line-height:30px; color:#ffffff; font-weight:bold;\">Company Name</p>\n </td>\n </tr>\n <tr>\n <td style=\"padding:36px 40px 12px 40px; font-family:Arial, Helvetica, sans-serif; font-size:16px; line-height:26px; color:#2b2f36;\">\n <h1 style=\"margin:0 0 20px 0; font-family:Georgia, serif; font-size:26px; line-height:34px; font-weight:normal; color:#1f3a5f;\">Your monthly update</h1>\n <p style=\"margin:0 0 18px 0;\">This is <strong style=\"font-weight:bold;\">bold</strong>, <em style=\"font-style:italic;\">italic</em>, and <span style=\"text-decoration:underline;\">underlined</span>.</p>\n <table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"margin:8px 0 24px 0;\">\n <tr>\n <td style=\"padding:18px 20px; background-color:#f4f7fa; border-left:4px solid #1f3a5f; font-family:Arial, Helvetica, sans-serif; font-size:15px; line-height:24px; color:#2b2f36;\">\n <strong style=\"font-weight:bold;\">Action needed:</strong> please review your details.\n </td>\n </tr>\n </table>\n <table role=\"presentation\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"margin:0 0 28px 0;\">\n <tr>\n <td align=\"center\" bgcolor=\"#1f3a5f\" style=\"background-color:#1f3a5f; border-radius:4px;\">\n <a href=\"https://example.com\" target=\"_blank\" style=\"color:#ffffff; text-decoration:none;\">Confirm my details</a>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n <tr>\n <td style=\"padding:20px 40px 28px 40px; border-top:1px solid #e3e7ec; font-family:Arial, Helvetica, sans-serif; font-size:12px; line-height:18px; color:#6b7380;\">\n <p style=\"margin:0 0 6px 0;\">Company Name, 123 Street Address.</p>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n</table>`;\n\n/** Parse an HTML string and return the first element matching a selector. */\nfunction parse(html: string, selector: string): HTMLElement | null {\n const doc = new DOMParser().parseFromString(html, 'text/html');\n return doc.querySelector<HTMLElement>(selector);\n}\n\n/** All elements matching a selector from a parsed HTML string. */\nfunction parseAll(html: string, selector: string): HTMLElement[] {\n const doc = new DOMParser().parseFromString(html, 'text/html');\n return Array.from(doc.querySelectorAll<HTMLElement>(selector));\n}\n\nconst ON = { emailFidelity: true } as const;\n\ndescribe('email-fidelity: sanitizeHtml layout styles', () => {\n it('1. keeps td padding when the flag is on', () => {\n const out = sanitizeHtml('<table><tr><td style=\"padding:18px 20px\">x</td></tr></table>', ON);\n const td = parse(out, 'td')!;\n expect(td.style.padding).to.not.equal('');\n });\n\n it('2. keeps table width and max-width', () => {\n const out = sanitizeHtml(\n '<table style=\"width:100%; max-width:600px\">x</table>',\n ON\n );\n const table = parse(out, 'table')!;\n expect(table.style.width).to.equal('100%');\n expect(table.style.maxWidth).to.equal('600px');\n });\n\n it('3. keeps a td border-left shorthand', () => {\n const out = sanitizeHtml(\n '<table><tr><td style=\"border-left:4px solid #1f3a5f\">x</td></tr></table>',\n ON\n );\n const td = parse(out, 'td')!;\n expect(td.style.borderLeftStyle).to.equal('solid');\n expect(td.style.borderLeftWidth).to.equal('4px');\n });\n\n it('4. keeps paragraph/heading margins', () => {\n const out = sanitizeHtml(\n '<h1 style=\"margin:0 0 20px 0\">h</h1><p style=\"margin:0 0 18px 0\">p</p>',\n ON\n );\n expect(parse(out, 'h1')!.style.margin).to.not.equal('');\n expect(parse(out, 'p')!.style.margin).to.not.equal('');\n });\n\n it('5. keeps table border and background-color', () => {\n const out = sanitizeHtml(\n '<table style=\"background-color:#ffffff; border:1px solid #d9dee4\">x</table>',\n ON\n );\n const table = parse(out, 'table')!;\n expect(table.style.backgroundColor).to.match(/rgb\\(255, 255, 255\\)|#ffffff/);\n expect(table.style.borderStyle).to.equal('solid');\n });\n\n it('6. converts legacy bgcolor/width/valign to styles and removes the raw attrs', () => {\n const out = sanitizeHtml(\n '<table width=\"600\"><tr><td bgcolor=\"#1f3a5f\" valign=\"top\" width=\"200\">x</td></tr></table>',\n ON\n );\n const table = parse(out, 'table')!;\n const td = parse(out, 'td')!;\n expect(table.hasAttribute('width')).to.equal(false);\n expect(td.hasAttribute('bgcolor')).to.equal(false);\n expect(td.hasAttribute('valign')).to.equal(false);\n expect(td.hasAttribute('width')).to.equal(false);\n expect(table.style.width).to.not.equal('');\n expect(td.style.backgroundColor).to.match(/rgb\\(31, 58, 95\\)|#1f3a5f/);\n expect(td.style.verticalAlign).to.equal('top');\n expect(td.style.width).to.not.equal('');\n });\n\n it('7. drops display:none elements with their content', () => {\n const out = sanitizeHtml(\n '<div style=\"display:none\">preheader secret</div><p>kept</p>',\n ON\n );\n expect(out).to.not.include('preheader secret');\n expect(out).to.include('kept');\n });\n\n it('8. drops mso-hide:all elements with their content', () => {\n const out = sanitizeHtml(\n '<div style=\"mso-hide:all; font-size:1px\">hidden msg</div><p>kept</p>',\n ON\n );\n expect(out).to.not.include('hidden msg');\n expect(out).to.include('kept');\n });\n});\n\ndescribe('email-fidelity: fixture round-trip (flag on)', () => {\n it('9. layout styles survive sanitize', () => {\n const out = sanitizeHtml(EMAIL_FIXTURE, ON);\n // 600px container width + max-width.\n const container = parseAll(out, 'table').find(t => t.style.maxWidth === '600px');\n expect(container, '600px container').to.exist;\n // Callout left border.\n const callout = parseAll(out, 'td').find(t => t.style.borderLeftStyle === 'solid');\n expect(callout, 'callout border-left').to.exist;\n // Footer top border.\n const footer = parseAll(out, 'td').find(t => t.style.borderTopStyle === 'solid');\n expect(footer, 'footer border-top').to.exist;\n // Some cell keeps padding.\n expect(parseAll(out, 'td').some(t => t.style.padding !== '' || t.style.paddingTop !== '')).to.equal(\n true\n );\n });\n\n it('10. layout styles survive a full htmlToDoc→docToHtml round-trip', () => {\n const doc = htmlToDoc(defaultSchema, EMAIL_FIXTURE, true, ON);\n const out = docToHtml(doc);\n expect(parseAll(out, 'table').some(t => t.style.maxWidth === '600px'), '600px width').to.equal(\n true\n );\n expect(parseAll(out, 'td').some(t => t.style.borderLeftStyle === 'solid'), 'callout').to.equal(\n true\n );\n expect(parseAll(out, 'td').some(t => t.style.borderTopStyle === 'solid'), 'footer').to.equal(\n true\n );\n expect(parseAll(out, 'td').some(t => t.style.paddingTop !== '' || t.style.padding !== ''), 'padding')\n .to.equal(true);\n // Paragraph margins preserved.\n expect(parseAll(out, 'p').some(p => p.style.marginBottom !== '' || p.style.margin !== ''), 'p margin')\n .to.equal(true);\n });\n\n it('11. no text-run span inherits a table/cell background-color or font-family', () => {\n const doc = htmlToDoc(defaultSchema, EMAIL_FIXTURE, true, ON);\n const out = docToHtml(doc);\n for (const span of parseAll(out, 'span')) {\n expect(span.style.backgroundColor, `span bg: ${span.outerHTML}`).to.equal('');\n // Arial is only ever set on cells in the fixture; Georgia is set on the\n // header <p>/<h1> themselves and is allowed to mark their own text.\n expect(span.style.fontFamily, `span font: ${span.outerHTML}`).to.not.include('Arial');\n }\n });\n\n it('11b. a paragraph/heading keeps its own colour and font', () => {\n const out = docToHtml(htmlToDoc(defaultSchema, EMAIL_FIXTURE, true, ON));\n const header = parseAll(out, 'p').find(p => p.textContent === 'Company Name');\n expect(header?.innerHTML).to.include('Georgia');\n expect(header?.innerHTML).to.include('24px');\n expect(header?.innerHTML).to.match(/color: (?:rgb\\(255, 255, 255\\)|#ffffff)/);\n expect(parseAll(out, 'h1')[0].innerHTML).to.include('Georgia');\n });\n\n it('11c. a container table centred by its holding cell keeps auto side margins', () => {\n const out = docToHtml(\n htmlToDoc(\n defaultSchema,\n '<table role=\"presentation\"><tr><td align=\"center\"><table role=\"presentation\" style=\"max-width:600px\"><tr><td>x</td></tr></table></td></tr></table>',\n true,\n ON\n )\n );\n const inner = parseAll(out, 'table')[1];\n expect(inner.style.marginLeft).to.equal('auto');\n expect(inner.style.marginRight).to.equal('auto');\n expect(inner.style.maxWidth).to.equal('600px');\n });\n\n it('12. serialized output is substantially smaller than flag-off output', () => {\n const on = docToHtml(htmlToDoc(defaultSchema, EMAIL_FIXTURE, true, ON));\n const off = docToHtml(htmlToDoc(defaultSchema, EMAIL_FIXTURE));\n expect(on.length).to.be.lessThan(off.length * 0.6);\n });\n\n it('13. the display:none preheader text is absent from the document', () => {\n const doc = htmlToDoc(defaultSchema, EMAIL_FIXTURE, true, ON);\n expect(doc.textContent).to.not.include('Hidden preheader');\n expect(docToHtml(doc)).to.not.include('Hidden preheader');\n });\n\n it('14. serialize → parse → serialize is a fixpoint', () => {\n const once = docToHtml(htmlToDoc(defaultSchema, EMAIL_FIXTURE, true, ON));\n const twice = docToHtml(htmlToDoc(defaultSchema, once, true, ON));\n expect(twice).to.equal(once);\n });\n});\n\ndescribe('email-fidelity: CSS value validation (flag on)', () => {\n const stripped: [string, string][] = [\n ['padding:url(x)', 'td'],\n ['width:calc(100% - 2px)', 'td'],\n ['margin:expression(alert(1))', 'p'],\n ['border-left:1px solid url(javascript:alert(1))', 'td'],\n ['padding:var(--x)', 'td'],\n ['width:10px\\\\9', 'td'],\n ];\n\n for (const [decl, tag] of stripped) {\n const prop = decl.split(':')[0];\n it(`15. strips hostile declaration: ${decl}`, () => {\n const html =\n tag === 'p'\n ? `<p style=\"${decl}\">x</p>`\n : `<table><tr><td style=\"${decl}\">x</td></tr></table>`;\n const out = sanitizeHtml(html, ON);\n const el = parse(out, tag)!;\n expect(el.style.getPropertyValue(prop), `${prop} must be empty`).to.equal('');\n expect(out).to.not.match(/url\\(|calc\\(|expression\\(|var\\(/);\n });\n }\n\n const allowed: [string, string, string, string][] = [\n ['padding:12px 24px', 'td', 'padding', 'paddingTop'],\n ['width:100%', 'td', 'width', 'width'],\n ['margin:0 0 18pt 0', 'p', 'margin', 'marginBottom'],\n ['border-left:4px solid #1f3a5f', 'td', 'border-left-style', 'borderLeftStyle'],\n ];\n\n for (const [decl, tag, , jsProp] of allowed) {\n it(`16. keeps valid declaration: ${decl}`, () => {\n const html =\n tag === 'p'\n ? `<p style=\"${decl}\">x</p>`\n : `<table><tr><td style=\"${decl}\">x</td></tr></table>`;\n const out = sanitizeHtml(html, ON);\n const el = parse(out, tag)!;\n expect((el.style as unknown as Record<string, string>)[jsProp]).to.not.equal('');\n });\n }\n});\n\ndescribe('email-fidelity: back-compat (flag off)', () => {\n it('17. no options, {}, and {emailFidelity:false} are identical', () => {\n const a = sanitizeHtml(EMAIL_FIXTURE);\n const b = sanitizeHtml(EMAIL_FIXTURE, {});\n const c = sanitizeHtml(EMAIL_FIXTURE, { emailFidelity: false });\n expect(b).to.equal(a);\n expect(c).to.equal(a);\n });\n\n it('18. flag-off output strips cell padding (unchanged 2.0.16 behaviour)', () => {\n const out = sanitizeHtml(EMAIL_FIXTURE);\n expect(out).to.not.include('padding');\n });\n});\n\ndescribe('email-fidelity: looksLikeHtml', () => {\n const truthy = [\n '<!doctype html><html><body><p>x</p></body></html>',\n ' <html><head></head><body>x</body></html>',\n '<table role=\"presentation\"><tr><td>x</td></tr></table>',\n '<div><p>nested block</p></div>',\n '<p>a paragraph</p>',\n '<h1>heading</h1>',\n '<ul><li>item</li></ul>',\n '<blockquote>quote</blockquote>',\n '<section><p>x</p></section>',\n '<!-- lead comment --><div>after comment</div>',\n ];\n for (const text of truthy) {\n it(`19. true for: ${text.slice(0, 32)}`, () => {\n expect(looksLikeHtml(text)).to.equal(true);\n });\n }\n\n const falsy = [\n 'Just some plain prose with no markup at all.',\n 'A markdown line with a stray <br> in it',\n 'inline **markdown** with a <b>bold</b> word only',\n 'a < b > c is a math comparison, not html',\n '',\n ' ',\n ];\n for (const text of falsy) {\n it(`20. false for: ${text.slice(0, 32)}`, () => {\n expect(looksLikeHtml(text)).to.equal(false);\n });\n }\n});\n\n// ---------------------------------------------------------------------------\n// allowedStyles — custom allowlist extension\n// (spec: \"Custom allowlist extension\"; plan nile-qa sections A–E, G)\n// ---------------------------------------------------------------------------\nimport {\n normalizeEmailAllowedStyles,\n parseAllowedStylesAttr,\n isExtensionPropValid,\n isExtensionValueValid,\n sanitizeExtraStyleForWrite,\n} from './email-css';\nimport { jsonToDoc } from './serializer';\n\n/** email-fidelity-on options carrying a normalized app allowlist. */\nconst WITH = (styles: Record<string, string[]>) =>\n ({ emailFidelity: true, allowedStyles: normalizeEmailAllowedStyles(styles) }) as const;\n\n/** The `data-extra-style` string on the first matching element, or ''. */\nfunction extra(html: string, selector: string): string {\n return parse(html, selector)?.getAttribute('data-extra-style') ?? '';\n}\n\ndescribe('allowedStyles: happy path (section A)', () => {\n it('A1. keeps an extension prop on a td via data-extra-style, not live style', () => {\n const out = sanitizeHtml(\n '<table><tr><td style=\"letter-spacing:0.5px\">x</td></tr></table>',\n WITH({ td: ['letter-spacing'] })\n );\n expect(extra(out, 'td')).to.include('letter-spacing: 0.5px');\n expect(parse(out, 'td')!.style.letterSpacing).to.equal('');\n });\n\n it('A2. keeps an extension prop on a <p>', () => {\n const out = sanitizeHtml(\n '<p style=\"letter-spacing:0.5px\">x</p>',\n WITH({ p: ['letter-spacing'] })\n );\n expect(extra(out, 'p')).to.include('letter-spacing: 0.5px');\n expect(parse(out, 'p')!.style.letterSpacing).to.equal('');\n });\n\n it('A3. keeps an extension prop on an <h2>', () => {\n const out = sanitizeHtml(\n '<h2 style=\"letter-spacing:0.5px\">x</h2>',\n WITH({ h2: ['letter-spacing'] })\n );\n expect(extra(out, 'h2')).to.include('letter-spacing: 0.5px');\n expect(parse(out, 'h2')!.style.letterSpacing).to.equal('');\n });\n\n it('A4. round-trips the prop onto live p/td style via htmlToDoc→docToHtml', () => {\n const out = docToHtml(\n htmlToDoc(\n defaultSchema,\n '<p style=\"letter-spacing:0.5px\">x</p><table><tr><td style=\"letter-spacing:0.5px\">y</td></tr></table>',\n true,\n WITH({ p: ['letter-spacing'], td: ['letter-spacing'] })\n )\n );\n expect(parse(out, 'p')!.style.letterSpacing).to.equal('0.5px');\n expect(parse(out, 'td')!.style.letterSpacing).to.equal('0.5px');\n for (const span of parseAll(out, 'span')) {\n expect(span.style.letterSpacing, span.outerHTML).to.equal('');\n }\n });\n\n it('A5. round-trip is a fixpoint with a config set', () => {\n const cfg = WITH({ p: ['letter-spacing'], td: ['letter-spacing'] });\n const src = '<p style=\"letter-spacing:0.5px\">x</p>';\n const once = docToHtml(htmlToDoc(defaultSchema, src, true, cfg));\n const twice = docToHtml(htmlToDoc(defaultSchema, once, true, cfg));\n expect(twice).to.equal(once);\n });\n\n it('A6. multiple props and tags survive (non-built-in names only)', () => {\n const out = sanitizeHtml(\n '<table style=\"border-spacing:2px\"><tr><td style=\"letter-spacing:0.5px; text-indent:4px\">x</td></tr></table>',\n WITH({ td: ['letter-spacing', 'text-indent'], table: ['border-spacing'] })\n );\n expect(extra(out, 'td')).to.include('letter-spacing: 0.5px');\n expect(extra(out, 'td')).to.include('text-indent: 4px');\n expect(extra(out, 'table')).to.include('border-spacing: 2px');\n });\n});\n\ndescribe('allowedStyles: feature-off byte-identical (section B)', () => {\n const FIX = '<table><tr><td style=\"letter-spacing:0.5px\">x</td></tr></table>';\n\n it('B1. flag off: a config changes nothing vs no config', () => {\n const noCfg = sanitizeHtml(FIX);\n const withCfg = sanitizeHtml(FIX, {\n allowedStyles: normalizeEmailAllowedStyles({ td: ['letter-spacing'] }),\n } as { allowedStyles: ReturnType<typeof normalizeEmailAllowedStyles> });\n expect(withCfg).to.equal(noCfg);\n });\n\n it('B2. flag on + empty config === flag on + no allowedStyles', () => {\n const emptyCfg = sanitizeHtml(EMAIL_FIXTURE, WITH({}));\n const noCfg = sanitizeHtml(EMAIL_FIXTURE, ON);\n expect(emptyCfg).to.equal(noCfg);\n });\n});\n\ndescribe('allowedStyles: security matrix (section C)', () => {\n // Each: a config + a declaration that must NOT survive as an extension.\n // expected = no data-extra-style carrying the prop name.\n const cases: [string, Record<string, string[]>, string, string][] = [\n // [label, config, declaration, propName that must be absent from data-extra-style]\n ['denylist position', { td: ['position'] }, 'position:fixed', 'position'],\n ['denylist display', { td: ['display'] }, 'display:none', 'display'],\n ['denylist float', { td: ['float'] }, 'float:left', 'float'],\n ['denylist overflow', { td: ['overflow'] }, 'overflow:hidden', 'overflow'],\n ['denylist z-index', { td: ['z-index'] }, 'z-index:5', 'z-index'],\n ['denylist background', { td: ['background'] }, 'background:red', 'background'],\n ['builtin color', { td: ['color'] }, 'color:red', 'color'],\n ['builtin padding', { td: ['padding'] }, 'padding:4px', 'padding'],\n ['builtin width', { td: ['width'] }, 'width:10px', 'width'],\n ['value url', { td: ['letter-spacing'] }, 'letter-spacing:url(x)', 'letter-spacing'],\n ['value expression', { td: ['letter-spacing'] }, 'letter-spacing:expression(alert(1))', 'letter-spacing'],\n ['value var', { td: ['letter-spacing'] }, 'letter-spacing:var(--x)', 'letter-spacing'],\n ['value calc', { td: ['letter-spacing'] }, 'letter-spacing:calc(1px)', 'letter-spacing'],\n ['value attr', { td: ['letter-spacing'] }, 'letter-spacing:attr(data-x)', 'letter-spacing'],\n ['value env', { td: ['letter-spacing'] }, 'letter-spacing:env(x)', 'letter-spacing'],\n ['value image-set', { td: ['letter-spacing'] }, 'letter-spacing:image-set(a)', 'letter-spacing'],\n ['value important', { td: ['letter-spacing'] }, 'letter-spacing:1px !important', 'letter-spacing'],\n ['name custom prop', { td: ['--x'] }, '--x:1px', '--x'],\n ['name vendor prefix', { td: ['-webkit-transform'] }, '-webkit-transform:none', 'webkit-transform'],\n ];\n\n for (const [label, cfg, decl, prop] of cases) {\n it(`C. drops ${label}`, () => {\n const out = sanitizeHtml(\n `<table><tr><td style=\"${decl}\">x</td></tr></table>`,\n WITH(cfg)\n );\n expect(extra(out, 'td')).to.not.include(prop);\n });\n }\n\n it('C-inject. a ;-injected denylisted decl never reaches data-extra-style', () => {\n const out = sanitizeHtml(\n '<table><tr><td style=\"letter-spacing:1px; position:fixed\">x</td></tr></table>',\n WITH({ td: ['letter-spacing'] })\n );\n expect(extra(out, 'td')).to.include('letter-spacing: 1px');\n expect(extra(out, 'td')).to.not.include('position');\n expect(parse(out, 'td')!.style.position).to.equal('');\n });\n\n it('C-obfus. uppercase / escaped obfuscated names are dropped', () => {\n const upper = sanitizeHtml(\n '<table><tr><td style=\"letter-spacing:1px\">x</td></tr></table>',\n WITH({ td: ['LETTER-SPACING'] })\n );\n expect(extra(upper, 'td')).to.not.include('letter-spacing');\n });\n\n it('C-nonascii. a non-ASCII value is dropped', () => {\n const out = sanitizeHtml(\n '<table><tr><td style=\"letter-spacing:é\">x</td></tr></table>',\n WITH({ td: ['letter-spacing'] })\n );\n expect(extra(out, 'td')).to.not.include('letter-spacing');\n });\n\n it('C-length. an over-length (>128) value is dropped', () => {\n const big = `${'1'.repeat(140)}px`;\n const out = sanitizeHtml(\n `<table><tr><td style=\"letter-spacing:${big}\">x</td></tr></table>`,\n WITH({ td: ['letter-spacing'] })\n );\n expect(extra(out, 'td')).to.not.include('letter-spacing');\n });\n\n it('C-tag. unknown / text-level tags are dropped from the allowlist', () => {\n const out = sanitizeHtml(\n '<div style=\"letter-spacing:1px\"><span style=\"letter-spacing:1px\">x</span></div>',\n WITH({ script: ['letter-spacing'], span: ['letter-spacing'], div: ['letter-spacing'] })\n );\n expect(extra(out, 'div')).to.not.include('letter-spacing');\n expect(extra(out, 'span')).to.not.include('letter-spacing');\n });\n\n it('C-mso. mso-line-height-rule is kept', () => {\n const out = sanitizeHtml(\n '<table><tr><td style=\"mso-line-height-rule:exactly\">x</td></tr></table>',\n WITH({ td: ['mso-line-height-rule'] })\n );\n expect(extra(out, 'td')).to.include('mso-line-height-rule: exactly');\n });\n\n it('C-msohide. an mso-hide:all element is still dropped whole regardless of config', () => {\n const out = sanitizeHtml(\n '<div style=\"mso-hide:all; mso-line-height-rule:exactly\">secret</div><p>kept</p>',\n WITH({ p: ['letter-spacing'] })\n );\n expect(out).to.not.include('secret');\n expect(out).to.include('kept');\n });\n});\n\ndescribe('allowedStyles: JSON trust boundary (section D)', () => {\n it('D1. a paragraph extraStyle keeps a safe decl but strips a denylisted one', () => {\n const doc = jsonToDoc(defaultSchema, {\n type: 'doc',\n content: [\n {\n type: 'paragraph',\n attrs: { extraStyle: 'letter-spacing: 1px; position: fixed' },\n content: [{ type: 'text', text: 'x' }],\n },\n ],\n });\n const out = docToHtml(doc);\n expect(out).to.include('letter-spacing');\n expect(out).to.not.include('position');\n });\n\n it('D2. a table cell extraStyle keeps a safe decl but strips a denylisted one', () => {\n const doc = jsonToDoc(defaultSchema, {\n type: 'doc',\n content: [\n {\n type: 'table',\n content: [\n {\n type: 'table_row',\n content: [\n {\n type: 'table_cell',\n attrs: { extraStyle: 'letter-spacing: 1px; position: fixed' },\n content: [{ type: 'paragraph', content: [{ type: 'text', text: 'x' }] }],\n },\n ],\n },\n ],\n },\n ],\n });\n const out = docToHtml(doc);\n expect(parse(out, 'td')!.style.letterSpacing).to.equal('1px');\n expect(parse(out, 'td')!.style.position).to.equal('');\n });\n});\n\ndescribe('allowedStyles: cell padding per-side fix (section E)', () => {\n it('E1. a td with only padding-top survives a round-trip', () => {\n const out = docToHtml(\n htmlToDoc(defaultSchema, '<table><tr><td style=\"padding-top:12px\">x</td></tr></table>', true, ON)\n );\n expect(parse(out, 'td')!.style.paddingTop).to.equal('12px');\n });\n\n it('E2. a padding:36px 40px shorthand round-trips per side', () => {\n const out = docToHtml(\n htmlToDoc(defaultSchema, '<table><tr><td style=\"padding:36px 40px\">x</td></tr></table>', true, ON)\n );\n const td = parse(out, 'td')!;\n expect(td.style.paddingTop).to.equal('36px');\n expect(td.style.paddingRight).to.equal('40px');\n expect(td.style.paddingBottom).to.equal('36px');\n expect(td.style.paddingLeft).to.equal('40px');\n });\n\n it('E3. a cell border:1px solid #ccc keeps all four sides', () => {\n const out = docToHtml(\n htmlToDoc(defaultSchema, '<table><tr><td style=\"border:1px solid #ccc\">x</td></tr></table>', true, ON)\n );\n const td = parse(out, 'td')!;\n expect(td.style.borderTopStyle).to.equal('solid');\n expect(td.style.borderRightStyle).to.equal('solid');\n expect(td.style.borderBottomStyle).to.equal('solid');\n expect(td.style.borderLeftStyle).to.equal('solid');\n });\n\n it('E4. a uniform table border still round-trips', () => {\n const out = docToHtml(\n htmlToDoc(defaultSchema, '<table style=\"border:1px solid #d9dee4\">x</table>', true, ON)\n );\n expect(parse(out, 'table')!.style.borderStyle).to.equal('solid');\n });\n});\n\ndescribe('allowedStyles: email-css unit helpers', () => {\n it('U1. isExtensionPropValid accepts new props, rejects built-in/denylist/grammar', () => {\n expect(isExtensionPropValid('letter-spacing')).to.equal(true);\n expect(isExtensionPropValid('mso-line-height-rule')).to.equal(true);\n expect(isExtensionPropValid('color')).to.equal(false); // built-in\n expect(isExtensionPropValid('padding-top')).to.equal(false); // built-in\n expect(isExtensionPropValid('position')).to.equal(false); // denylist\n expect(isExtensionPropValid('--x')).to.equal(false); // grammar\n expect(isExtensionPropValid('-webkit-transform')).to.equal(false); // grammar\n expect(isExtensionPropValid('LETTER-SPACING')).to.equal(false); // grammar\n });\n\n it('U2. isExtensionValueValid accepts plain values, rejects hostile ones', () => {\n expect(isExtensionValueValid('0.5px')).to.equal(true);\n expect(isExtensionValueValid('rgb(1, 2, 3)')).to.equal(true);\n expect(isExtensionValueValid('url(x)')).to.equal(false);\n expect(isExtensionValueValid('calc(1px)')).to.equal(false);\n expect(isExtensionValueValid('var(--x)')).to.equal(false);\n expect(isExtensionValueValid('1px !important')).to.equal(false);\n expect(isExtensionValueValid('a/b')).to.equal(false);\n expect(isExtensionValueValid('é')).to.equal(false);\n expect(isExtensionValueValid(`${'1'.repeat(140)}px`)).to.equal(false);\n });\n\n it('U3. parseAllowedStylesAttr parses the attribute string form', () => {\n expect(parseAllowedStylesAttr('td: letter-spacing, text-indent; p: letter-spacing')).to.deep.equal({\n td: ['letter-spacing', 'text-indent'],\n p: ['letter-spacing'],\n });\n });\n\n it('U4. normalizeEmailAllowedStyles warns once per bad entry and never throws', () => {\n const warn = console.warn;\n let count = 0;\n console.warn = () => {\n count += 1;\n };\n try {\n const norm = normalizeEmailAllowedStyles({ td: ['letter-spacing', 'position'], foo: ['x'] });\n expect(norm.get('td')?.has('letter-spacing')).to.equal(true);\n expect(norm.get('td')?.has('position')).to.not.equal(true);\n } finally {\n console.warn = warn;\n }\n expect(count).to.be.greaterThan(0);\n // tolerate junk input without throwing\n expect(() => normalizeEmailAllowedStyles({} as Record<string, string[]>)).to.not.throw();\n });\n\n it('U5. sanitizeExtraStyleForWrite keeps safe decls and drops unsafe ones', () => {\n const safe = sanitizeExtraStyleForWrite('letter-spacing: 1px; position: fixed');\n expect(safe).to.include('letter-spacing: 1px');\n expect(safe).to.not.include('position');\n });\n});\n\n// ---------------------------------------------------------------------------\n// Fixes 2–4 from the ZenLeaf email test (plan: fixes-1-4-plan.md)\n// ---------------------------------------------------------------------------\n\n/** docToHtml(htmlToDoc(...)) with email-fidelity on. */\nfunction roundTripOn(html: string): string {\n return docToHtml(htmlToDoc(defaultSchema, html, true, ON));\n}\n/** docToHtml(htmlToDoc(...)) with the flag off (2.0.16 behaviour). */\nfunction roundTripOff(html: string): string {\n return docToHtml(htmlToDoc(defaultSchema, html));\n}\n\ndescribe('fix 2: cell text-align (email-fidelity only)', () => {\n it('F2.1. keeps text-align:center on a td', () => {\n const out = roundTripOn(\n '<table><tr><td style=\"text-align:center\"><p>x</p></td></tr></table>'\n );\n expect(parse(out, 'td')!.style.textAlign).to.equal('center');\n });\n\n it('F2.2. converts a legacy align=\"center\" on a td to text-align', () => {\n const out = roundTripOn(\n '<table><tr><td align=\"center\"><p>x</p></td></tr></table>'\n );\n expect(parse(out, 'td')!.style.textAlign).to.equal('center');\n });\n\n it('F2.3. keeps text-align:right and text-align:justify', () => {\n const right = roundTripOn('<table><tr><td style=\"text-align:right\"><p>x</p></td></tr></table>');\n expect(parse(right, 'td')!.style.textAlign).to.equal('right');\n const just = roundTripOn('<table><tr><td style=\"text-align:justify\"><p>x</p></td></tr></table>');\n expect(parse(just, 'td')!.style.textAlign).to.equal('justify');\n });\n\n it('F2.4. drops an invalid text-align value (url/expression)', () => {\n const url = roundTripOn('<table><tr><td style=\"text-align:url(x)\"><p>x</p></td></tr></table>');\n expect(parse(url, 'td')!.style.textAlign).to.equal('');\n expect(url).to.not.include('url(');\n const expr = roundTripOn(\n '<table><tr><td style=\"text-align:expression(alert(1))\"><p>x</p></td></tr></table>'\n );\n expect(parse(expr, 'td')!.style.textAlign).to.equal('');\n expect(expr).to.not.include('expression(');\n });\n\n it('F2.5. flag off: a td text-align is dropped (unchanged behaviour)', () => {\n const out = roundTripOff('<table><tr><td style=\"text-align:center\"><p>x</p></td></tr></table>');\n expect(parse(out, 'td')!.style.textAlign).to.equal('');\n });\n\n it('F2.6. table centring via align=\"center\" on the holder cell still works', () => {\n const out = roundTripOn(\n '<table role=\"presentation\"><tr><td align=\"center\"><table role=\"presentation\" style=\"max-width:600px\"><tr><td>x</td></tr></table></td></tr></table>'\n );\n const inner = parseAll(out, 'table')[1];\n expect(inner.style.marginLeft).to.equal('auto');\n expect(inner.style.marginRight).to.equal('auto');\n });\n\n it('F2.6b. align=\"center\" on a cell holding a table centres the table as a block, not the nested body text', () => {\n const out = roundTripOn(\n '<table role=\"presentation\"><tr><td align=\"center\"><table role=\"presentation\" style=\"max-width:600px\"><tr><td><p>body text</p></td></tr></table></td></tr></table>'\n );\n // The holder cell's own text IS centred (the browser does centre it)...\n const holder = parseAll(out, 'td')[0];\n expect(holder.style.textAlign).to.equal('center');\n // ...the nested table is still centred as a block...\n expect(parseAll(out, 'table')[1].style.marginLeft).to.equal('auto');\n // ...but the nested table's own cell is pinned to left, so its body text is\n // NOT centred (legacy align does not inherit into a nested table).\n expect(parseAll(out, 'td')[1].style.textAlign).to.equal('left');\n });\n\n it('F2.7. serialize → parse → serialize is a fixpoint', () => {\n const src = '<table><tr><td style=\"text-align:center\"><p>x</p></td></tr></table>';\n const once = roundTripOn(src);\n expect(roundTripOn(once)).to.equal(once);\n });\n});\n\ndescribe('fix 2c: container-level centring propagation (email-fidelity only)', () => {\n // Case 1: td align=\"center\" holding BOTH a nested table and its own text.\n const CASE1 =\n '<table role=\"presentation\" width=\"100%\"><tr><td align=\"center\">' +\n '<table role=\"presentation\"><tr><td><img src=\"x.png\" width=\"20\"></td></tr></table>' +\n '<p>Powered by Aquera</p></td></tr></table>';\n\n it('C1.1. the holder cell centres its own text', () => {\n const holder = parseAll(roundTripOn(CASE1), 'td')[0];\n expect(holder.style.textAlign).to.equal('center');\n });\n\n it('C1.2. the nested table\\'s own cell is NOT centred (pinned left)', () => {\n const nested = parseAll(roundTripOn(CASE1), 'table')[1];\n const nestedCell = nested.querySelector('td')!;\n expect(nestedCell.style.textAlign).to.equal('left');\n });\n\n it('C1.3. a nested cell with its own alignment is left untouched', () => {\n const out = roundTripOn(\n '<table><tr><td align=\"center\">' +\n '<table><tr><td style=\"text-align:right\"><p>r</p></td></tr></table>' +\n '<p>t</p></td></tr></table>'\n );\n expect(parseAll(out, 'td')[1].style.textAlign).to.equal('right');\n });\n\n // Case 2: <center>.\n it('C2.1. <center> centres a block paragraph it wraps', () => {\n const out = roundTripOn('<center><p>Powered by Aquera</p></center>');\n expect(parse(out, 'p')!.style.textAlign).to.equal('center');\n });\n\n it('C2.2. <center> wraps loose inline text in a centred paragraph', () => {\n const out = roundTripOn('<center>Powered by Aquera</center>');\n expect(parse(out, 'p')!.style.textAlign).to.equal('center');\n expect(parse(out, 'p')!.textContent).to.contain('Powered by Aquera');\n });\n\n it('C2.3. <center> centres a nested table as a block', () => {\n const out = roundTripOn(\n '<center><table role=\"presentation\"><tr><td><p>x</p></td></tr></table></center>'\n );\n expect(parse(out, 'table')!.style.marginLeft).to.equal('auto');\n });\n\n // Case 3: div[style text-align].\n it('C3.1. div style text-align:center centres a loose text child', () => {\n const out = roundTripOn('<div style=\"text-align:center\">Powered by Aquera</div>');\n expect(parse(out, 'p')!.style.textAlign).to.equal('center');\n });\n\n it('C3.2. CSS text-align on a div does NOT centre a nested table as a block', () => {\n const out = roundTripOn(\n '<div style=\"text-align:center\"><table role=\"presentation\"><tr><td><p>x</p></td></tr></table></div>'\n );\n expect(parse(out, 'table')!.style.marginLeft).to.not.equal('auto');\n });\n\n // Case 4: div[align].\n it('C4.1. div align=\"center\" centres a loose text child', () => {\n const out = roundTripOn('<div align=\"center\">Powered by Aquera</div>');\n expect(parse(out, 'p')!.style.textAlign).to.equal('center');\n });\n\n it('C4.2. div align=\"center\" centres a nested table as a block', () => {\n const out = roundTripOn(\n '<div align=\"center\"><table role=\"presentation\"><tr><td><p>x</p></td></tr></table></div>'\n );\n expect(parse(out, 'table')!.style.marginLeft).to.equal('auto');\n });\n\n // Case 5: CSS text-align on a table.\n it('C5.1. table style text-align:center centres its direct cells', () => {\n const out = roundTripOn(\n '<table role=\"presentation\" width=\"100%\" style=\"text-align:center\"><tr><td><p>Powered by Aquera</p></td></tr></table>'\n );\n expect(parse(out, 'td')!.style.textAlign).to.equal('center');\n });\n\n it('C5.2. a cell with its own alignment overrides the table text-align', () => {\n const out = roundTripOn(\n '<table style=\"text-align:center\"><tr><td style=\"text-align:left\"><p>x</p></td></tr></table>'\n );\n expect(parse(out, 'td')!.style.textAlign).to.equal('left');\n });\n\n // Case 6: tr[align].\n it('C6.1. tr align=\"center\" centres its direct cells', () => {\n const out = roundTripOn(\n '<table role=\"presentation\" width=\"100%\"><tr align=\"center\"><td><p>Powered by Aquera</p></td></tr></table>'\n );\n expect(parse(out, 'td')!.style.textAlign).to.equal('center');\n });\n\n it('C7.1. flag off: none of the container-level centring survives', () => {\n expect(parse(roundTripOff('<center><p>x</p></center>'), 'p')!.style.textAlign).to.equal('');\n expect(\n parse(roundTripOff('<div align=\"center\">x</div>'), 'p')?.style.textAlign ?? ''\n ).to.equal('');\n expect(\n parse(\n roundTripOff(\n '<table style=\"text-align:center\"><tr><td><p>x</p></td></tr></table>'\n ),\n 'td'\n )!.style.textAlign\n ).to.equal('');\n });\n\n it('C7.2. each case is a serialize → parse → serialize fixpoint', () => {\n for (const src of [\n CASE1,\n '<center><p>x</p></center>',\n '<div style=\"text-align:center\">x</div>',\n '<div align=\"center\">x</div>',\n '<table style=\"text-align:center\"><tr><td><p>x</p></td></tr></table>',\n '<table role=\"presentation\" width=\"100%\"><tr align=\"center\"><td><p>x</p></td></tr></table>',\n ]) {\n const once = roundTripOn(src);\n expect(roundTripOn(once), src).to.equal(once);\n }\n });\n});\n\ndescribe('fix 3: table-level font/colour (email-fidelity only)', () => {\n const TABLE =\n '<table style=\"font-family:Verdana, Geneva, sans-serif; font-size:16px; color:hsl(273, 100%, 5%); line-height:1.5\"><tr><td><p>hello</p></td></tr></table>';\n\n it('F3.1. keeps font-family/font-size/color/line-height on the table', () => {\n const table = parse(roundTripOn(TABLE), 'table')!;\n expect(table.style.fontFamily).to.include('Verdana');\n expect(table.style.fontSize).to.equal('16px');\n expect(table.style.color).to.not.equal('');\n expect(table.style.lineHeight).to.not.equal('');\n });\n\n it('F3.2. accepts an hsl() colour', () => {\n const table = parse(roundTripOn(TABLE), 'table')!;\n // Browsers normalize hsl() to rgb().\n expect(table.style.color).to.match(/rgb\\(|hsl\\(/);\n });\n\n it('F3.3. rejects a colour that smuggles a var()', () => {\n const out = roundTripOn(\n '<table style=\"color:hsl(var(--x))\"><tr><td><p>x</p></td></tr></table>'\n );\n expect(parse(out, 'table')!.style.color).to.equal('');\n expect(out).to.not.include('var(');\n });\n\n it('F3.4. no per-run span carries the table font-family or colour', () => {\n const out = roundTripOn(TABLE);\n for (const span of parseAll(out, 'span')) {\n expect(span.style.fontFamily, span.outerHTML).to.not.include('Verdana');\n }\n });\n\n it('F3.5. flag off: table font-family/colour are dropped (unchanged behaviour)', () => {\n const table = parse(roundTripOff(TABLE), 'table')!;\n expect(table.style.fontFamily).to.equal('');\n expect(table.style.color).to.equal('');\n });\n\n it('F3.6. serialize → parse → serialize is a fixpoint', () => {\n const once = roundTripOn(TABLE);\n expect(roundTripOn(once)).to.equal(once);\n });\n});\n\ndescribe('fix 4a: colgroup column widths (email-fidelity only)', () => {\n const THREE_COL =\n '<table><colgroup><col style=\"width:33.33%\"><col style=\"width:33.34%\"><col style=\"width:33.33%\"></colgroup>' +\n '<tr><td><p>a</p></td><td><p>b</p></td><td><p>c</p></td></tr></table>';\n\n it('F4a.1. copies each col width onto the matching cell', () => {\n const tds = parseAll(roundTripOn(THREE_COL), 'td');\n expect(tds[0].style.width).to.equal('33.33%');\n expect(tds[1].style.width).to.equal('33.34%');\n expect(tds[2].style.width).to.equal('33.33%');\n });\n\n it('F4a.2. a cell with its own width keeps it', () => {\n const out = roundTripOn(\n '<table><colgroup><col style=\"width:33.33%\"><col style=\"width:33.34%\"><col style=\"width:33.33%\"></colgroup>' +\n '<tr><td style=\"width:120px\"><p>a</p></td><td><p>b</p></td><td><p>c</p></td></tr></table>'\n );\n const tds = parseAll(out, 'td');\n expect(tds[0].style.width).to.equal('120px');\n expect(tds[1].style.width).to.equal('33.34%');\n });\n\n it('F4a.3. a row containing a colspan>1 cell is skipped', () => {\n const out = roundTripOn(\n '<table><colgroup><col style=\"width:33.33%\"><col style=\"width:33.34%\"><col style=\"width:33.33%\"></colgroup>' +\n '<tr><td colspan=\"2\"><p>a</p></td><td><p>c</p></td></tr></table>'\n );\n for (const td of parseAll(out, 'td')) {\n expect(td.style.width).to.equal('');\n }\n });\n\n it('F4a.4. an outer colgroup does not touch a nested table\\'s cells', () => {\n const out = roundTripOn(\n '<table><colgroup><col style=\"width:33.33%\"><col style=\"width:33.34%\"><col style=\"width:33.33%\"></colgroup>' +\n '<tr><td><table><tr><td><p>nested</p></td></tr></table></td><td><p>b</p></td><td><p>c</p></td></tr></table>'\n );\n const nested = parseAll(out, 'table')[1];\n const nestedCell = nested.querySelector('td')!;\n expect(nestedCell.style.width).to.equal('');\n });\n\n it('F4a.5. flag off: colgroup widths are not propagated', () => {\n const tds = parseAll(roundTripOff(THREE_COL), 'td');\n expect(tds[0].style.width).to.equal('');\n });\n\n it('F4a.6. serialize → parse → serialize is a fixpoint', () => {\n const once = roundTripOn(THREE_COL);\n expect(roundTripOn(once)).to.equal(once);\n });\n});\n\ndescribe('fix 4b: margin shorthand centring (email-fidelity only)', () => {\n it('F4b.1. margin:0px auto centres the table', () => {\n const out = roundTripOn('<table style=\"margin:0px auto; max-width:600px\"><tr><td><p>x</p></td></tr></table>');\n const table = parse(out, 'table')!;\n expect(table.style.marginLeft).to.equal('auto');\n expect(table.style.marginRight).to.equal('auto');\n });\n\n it('F4b.2. margin:0 10px does not centre the table', () => {\n const out = roundTripOn('<table style=\"margin:0 10px\"><tr><td><p>x</p></td></tr></table>');\n const table = parse(out, 'table')!;\n expect(table.style.marginLeft).to.not.equal('auto');\n expect(table.style.marginRight).to.not.equal('auto');\n });\n\n it('F4b.3. flag off: margin:0px auto does not centre', () => {\n const out = roundTripOff('<table style=\"margin:0px auto; max-width:600px\"><tr><td><p>x</p></td></tr></table>');\n expect(parse(out, 'table')!.style.marginLeft).to.not.equal('auto');\n });\n\n it('F4b.4. serialize → parse → serialize is a fixpoint', () => {\n const src = '<table style=\"margin:0px auto; max-width:600px\"><tr><td><p>x</p></td></tr></table>';\n const once = roundTripOn(src);\n expect(roundTripOn(once)).to.equal(once);\n });\n});\n\ndescribe('ZenLeaf integration (email-fidelity on)', () => {\n // A trimmed but representative copy of the CKEditor \"ZenLeaf\" email: an outer\n // presentation table carrying Verdana/colour/line-height and margin:0px auto,\n // a 100%-width hero image, centred heading/offer cells, and a 3-column\n // colgroup table whose cells must inherit the column widths.\n const ZENLEAF = `\n<table style=\"font-family:Verdana, Geneva, Tahoma, sans-serif;font-size:16px;color:hsl(273, 100%, 5%);line-height:1.5;margin:0px auto;background-color:#ffffff;max-width:690px;\" role=\"presentation\">\n <tbody>\n <tr><td style=\"overflow-wrap:break-word;\">\n <img style=\"display:inline;height:auto;vertical-align:middle;width:100%;\" src=\"https://ckeditor.com/assets/images/ckdemo/email-editing/zenleaf-tea-flower.png\" alt=\"hero\" width=\"1232\" height=\"742\">\n </td></tr>\n <tr><td style=\"text-align:center;\">\n <h2 style=\"font-size:36px;color:#333333;margin:0;\"><strong>The Magic of Green Tea</strong></h2>\n </td></tr>\n <tr><td style=\"text-align:center;\">\n <p style=\"margin:0;color:#333333;\">Get 20% off our premium green tea collection!</p>\n </td></tr>\n <tr><td style=\"background-color:#FFF475;\">\n <table role=\"presentation\" style=\"table-layout:fixed;border-spacing:0px;\">\n <colgroup><col style=\"width:33.33%;\"><col style=\"width:33.34%;\"><col style=\"width:33.33%;\"></colgroup>\n <tbody><tr>\n <td style=\"padding:12px;text-align:center;\"><p>Boosts energy</p></td>\n <td style=\"padding:12px;text-align:center;\"><p>Antioxidants</p></td>\n <td style=\"padding:12px;text-align:center;\"><p>Immune support</p></td>\n </tr></tbody>\n </table>\n </td></tr>\n </tbody>\n</table>`;\n\n it('Z1. the first image keeps width: 100%', () => {\n const out = roundTripOn(ZENLEAF);\n expect(parseAll(out, 'img')[0].style.width).to.equal('100%');\n });\n\n it('Z2. at least one cell is text-align: center', () => {\n const out = roundTripOn(ZENLEAF);\n const centred = parseAll(out, 'td').filter(t => t.style.textAlign === 'center');\n expect(centred.length).to.be.greaterThan(0);\n });\n\n it('Z3. the outer table is centred and keeps a Verdana font-family', () => {\n const out = roundTripOn(ZENLEAF);\n const outer = parseAll(out, 'table')[0];\n expect(outer.style.marginLeft).to.equal('auto');\n expect(outer.style.marginRight).to.equal('auto');\n expect(outer.style.fontFamily).to.include('Verdana');\n });\n\n it('Z4. the 3-column table cells carry 33.33%/33.34% widths', () => {\n const out = roundTripOn(ZENLEAF);\n const widths = parseAll(out, 'td').map(t => t.style.width);\n expect(widths).to.include('33.33%');\n expect(widths).to.include('33.34%');\n });\n\n it('Z5. the fidelity-on output is still smaller than the flag-off output', () => {\n const on = roundTripOn(ZENLEAF);\n const off = roundTripOff(ZENLEAF);\n expect(on.length).to.be.lessThan(off.length);\n });\n\n it('Z6. serialize → parse → serialize is a fixpoint', () => {\n const once = roundTripOn(ZENLEAF);\n expect(roundTripOn(once)).to.equal(once);\n });\n});\n\n// ---------------------------------------------------------------------------\n// Button links → one-cell table buttons (email-fidelity only)\n// (plan: button-links-plan.md — option A, 2026-10-13)\n//\n// Email builders make a \"button\" from ONE styled <a> (display:inline-block +\n// background-color/padding/border-radius/width). The editor stores links as a\n// mark on text, so the box styling is dropped and background-color becomes a\n// thin highlight strip. The email-fidelity pre-pass converts such a link, when\n// it is the only content of its block, into:\n// <table role=\"presentation\"><tbody><tr><td style=\"CELL\"><a …>text</a></td></tr></tbody></table>\n// with the box styles on the cell and the text styles kept on the link.\n// ---------------------------------------------------------------------------\n\n/** The ZenLeaf \"Get discount\" button: one display:inline-block styled link in a centred td. */\nconst BTN_GET_DISCOUNT = `\n<table role=\"presentation\"><tbody><tr>\n <td style=\"text-align:center;\">\n <a href=\"#\" style=\"display:inline-block; width:260px; border-radius:8px; margin:0px auto; padding:12px; font-size:24px; font-weight:700; text-align:center; color:rgb(255,255,255); text-decoration:none; background-color:rgb(64,107,30);\">Get discount</a>\n </td>\n</tr></tbody></table>`;\n\n/** The ZenLeaf \"Shop now\" button (darker background, same shape). */\nconst BTN_SHOP_NOW = `\n<table role=\"presentation\"><tbody><tr>\n <td style=\"text-align:center;\">\n <a href=\"#\" style=\"display:inline-block; width:200px; border-radius:6px; margin:0px auto; padding:14px 28px; font-size:20px; font-weight:700; text-align:center; color:rgb(255,255,255); text-decoration:none; background-color:rgb(20,21,23);\">Shop now</a>\n </td>\n</tr></tbody></table>`;\n\n/** Find the <td> that was produced for a button link: the innermost td holding the link. */\nfunction buttonCell(html: string): HTMLElement {\n const link = parse(html, 'a')!;\n return link.closest('td') as HTMLElement;\n}\n\ndescribe('button links: ZenLeaf \"Get discount\" (email-fidelity on)', () => {\n it('BL1. produces a role=presentation table around the link', () => {\n const out = roundTripOn(BTN_GET_DISCOUNT);\n const link = parse(out, 'a')!;\n const table = link.closest('table');\n expect(table, 'link sits inside a table').to.exist;\n expect(table!.getAttribute('role')).to.equal('presentation');\n });\n\n it('BL2. the button cell carries the link background-color', () => {\n const out = roundTripOn(BTN_GET_DISCOUNT);\n expect(buttonCell(out).style.backgroundColor).to.equal('rgb(64, 107, 30)');\n });\n\n it('BL3. the button cell carries the padding (any per-side equivalent of 12px)', () => {\n const out = roundTripOn(BTN_GET_DISCOUNT);\n const td = buttonCell(out);\n const uniform = td.style.padding === '12px';\n const perSide =\n td.style.paddingTop === '12px' &&\n td.style.paddingRight === '12px' &&\n td.style.paddingBottom === '12px' &&\n td.style.paddingLeft === '12px';\n expect(uniform || perSide, `padding was \"${td.style.cssText}\"`).to.equal(true);\n });\n\n it('BL4. the button cell carries border-radius and width', () => {\n const td = buttonCell(roundTripOn(BTN_GET_DISCOUNT));\n expect(td.style.borderRadius).to.equal('8px');\n expect(td.style.width).to.equal('260px');\n });\n\n it('BL5. the button cell is text-align: center', () => {\n expect(buttonCell(roundTripOn(BTN_GET_DISCOUNT)).style.textAlign).to.equal('center');\n });\n\n it('BL6. the table is centred (auto side margins) from the link margin:0 auto', () => {\n const out = roundTripOn(BTN_GET_DISCOUNT);\n const table = parse(out, 'a')!.closest('table')!;\n const centredByMargin =\n table.style.marginLeft === 'auto' && table.style.marginRight === 'auto';\n const centredByAttr = table.getAttribute('align') === 'center';\n expect(centredByMargin || centredByAttr, `table was \"${table.outerHTML}\"`).to.equal(true);\n });\n\n it('BL7. the link keeps its href and text', () => {\n const out = roundTripOn(BTN_GET_DISCOUNT);\n const link = parse(out, 'a')!;\n expect(link.getAttribute('href')).to.equal('#');\n expect(link.textContent).to.equal('Get discount');\n });\n\n it('BL8. no span wraps the link text with a background-color highlight', () => {\n const out = roundTripOn(BTN_GET_DISCOUNT);\n for (const span of parseAll(out, 'span')) {\n expect(span.style.backgroundColor, span.outerHTML).to.equal('');\n }\n });\n\n it('BL9. the link keeps white colour, 24px, bold as text styling', () => {\n const out = roundTripOn(BTN_GET_DISCOUNT);\n const link = parse(out, 'a')!;\n // white / 24px / bold may land on the link itself or a mark span inside it.\n expect(link.innerHTML, 'white').to.match(/rgb\\(255, 255, 255\\)|#ffffff|#fff\\b/i);\n expect(link.innerHTML, '24px').to.include('24px');\n expect(link.innerHTML, 'bold').to.match(/font-weight:\\s*(?:700|bold)|<strong/i);\n });\n\n it('BL10. the box styles are removed from the link itself', () => {\n const link = parse(roundTripOn(BTN_GET_DISCOUNT), 'a')!;\n expect(link.style.display, 'display').to.equal('');\n expect(link.style.backgroundColor, 'background').to.equal('');\n expect(link.style.padding, 'padding').to.equal('');\n expect(link.style.paddingTop, 'padding-top').to.equal('');\n expect(link.style.width, 'width').to.equal('');\n expect(link.style.borderRadius, 'border-radius').to.equal('');\n });\n});\n\ndescribe('button links: ZenLeaf \"Shop now\" (email-fidelity on)', () => {\n it('BL11. the button cell carries the darker background-color', () => {\n expect(buttonCell(roundTripOn(BTN_SHOP_NOW)).style.backgroundColor).to.equal('rgb(20, 21, 23)');\n });\n\n it('BL12. the button cell carries border-radius and width', () => {\n const td = buttonCell(roundTripOn(BTN_SHOP_NOW));\n expect(td.style.borderRadius).to.equal('6px');\n expect(td.style.width).to.equal('200px');\n });\n\n it('BL13. the button cell keeps the 14px/28px padding per side', () => {\n const td = buttonCell(roundTripOn(BTN_SHOP_NOW));\n const uniform = td.style.padding === '14px 28px';\n const perSide =\n td.style.paddingTop === '14px' &&\n td.style.paddingRight === '28px' &&\n td.style.paddingBottom === '14px' &&\n td.style.paddingLeft === '28px';\n expect(uniform || perSide, `padding was \"${td.style.cssText}\"`).to.equal(true);\n });\n\n it('BL14. no span highlights the link text', () => {\n for (const span of parseAll(roundTripOn(BTN_SHOP_NOW), 'span')) {\n expect(span.style.backgroundColor, span.outerHTML).to.equal('');\n }\n });\n});\n\ndescribe('button links: not-a-button cases (email-fidelity on)', () => {\n it('BL15. a plain coloured link in a paragraph is left inline (no table)', () => {\n const out = roundTripOn('<p><a href=\"x\" style=\"color:red\">link</a></p>');\n expect(parse(out, 'p a'), 'link stays in the paragraph').to.exist;\n expect(parse(out, 'p table'), 'no table inside the paragraph').to.not.exist;\n });\n\n it('BL16. display:inline-block with no bg/padding is not converted', () => {\n const out = roundTripOn(\n '<p><a href=\"x\" style=\"display:inline-block\">link</a></p>'\n );\n expect(parse(out, 'p table'), 'no table').to.not.exist;\n });\n\n it('BL17. a button-styled link sharing a paragraph with other text stays inline', () => {\n const out = roundTripOn(\n '<p>before <a href=\"#\" style=\"display:inline-block; padding:12px; background-color:rgb(64,107,30);\">btn</a> after</p>'\n );\n expect(parse(out, 'p table'), 'no table; link is not the only content').to.not.exist;\n expect(parse(out, 'p')!.textContent).to.include('before');\n expect(parse(out, 'p')!.textContent).to.include('after');\n });\n});\n\ndescribe('button links: block replacement (email-fidelity on)', () => {\n it('BL18. a <p> whose only content is a button link is replaced by the table', () => {\n const out = roundTripOn(\n '<p><a href=\"#\" style=\"display:inline-block; width:260px; padding:12px; background-color:rgb(64,107,30);\">Get discount</a></p>'\n );\n const link = parse(out, 'a')!;\n const table = link.closest('table');\n expect(table, 'link now inside a table').to.exist;\n // The original <p> is replaced by the table (the cell's own paragraph is just\n // ProseMirror's block+ cell content model).\n expect(table!.closest('p'), 'table not nested in the old paragraph').to.not.exist;\n expect(out.trim().startsWith('<table'), 'document starts with the button table').to.equal(true);\n expect(buttonCell(out).style.backgroundColor).to.equal('rgb(64, 107, 30)');\n });\n\n it('BL19. an existing bgcolor button cell gets a nested padded button cell', () => {\n // First-email idiom: a navy cell wrapping an inline-block padded link.\n const out = roundTripOn(\n '<table role=\"presentation\"><tbody><tr><td bgcolor=\"#1f3a5f\" style=\"background-color:#1f3a5f\"><a href=\"#\" style=\"display:inline-block; padding:13px 28px; color:#ffffff; text-decoration:none;\">Confirm</a></td></tr></tbody></table>'\n );\n const link = parse(out, 'a')!;\n const inner = link.closest('td')!;\n // The link's immediate cell now carries the padding...\n const uniform = inner.style.padding === '13px 28px';\n const perSide =\n inner.style.paddingTop === '13px' &&\n inner.style.paddingRight === '28px' &&\n inner.style.paddingBottom === '13px' &&\n inner.style.paddingLeft === '28px';\n expect(uniform || perSide, `inner padding was \"${inner.style.cssText}\"`).to.equal(true);\n // ...and the outer navy cell background survives somewhere above it.\n const navy = parseAll(out, 'td').some(\n t => t.style.backgroundColor === 'rgb(31, 58, 95)'\n );\n expect(navy, 'navy background retained').to.equal(true);\n });\n});\n\ndescribe('button links: flag off (unchanged 2.0.16 behaviour)', () => {\n it('BL20. flag off: the button link is NOT turned into a table', () => {\n const out = roundTripOff(BTN_GET_DISCOUNT);\n // The only table is the original wrapper; the link is not wrapped in a new one.\n const link = parse(out, 'a')!;\n const cell = link.closest('td')!;\n expect(cell.querySelector('table'), 'no nested button table').to.not.exist;\n });\n\n it('BL21. flag off: no cell carries the button background-color', () => {\n const out = roundTripOff(BTN_GET_DISCOUNT);\n const anyBg = parseAll(out, 'td').some(\n t => t.style.backgroundColor === 'rgb(64, 107, 30)'\n );\n expect(anyBg).to.equal(false);\n });\n});\n\ndescribe('button links: security (email-fidelity on)', () => {\n it('BL22. a hostile padding:url(x) never reaches the button cell', () => {\n const out = roundTripOn(\n '<p><a href=\"#\" style=\"display:inline-block; padding:url(x); background-color:rgb(64,107,30);\">btn</a></p>'\n );\n expect(out).to.not.include('url(');\n const bg = parseAll(out, 'td').some(t => t.style.backgroundColor === 'rgb(64, 107, 30)');\n if (bg) {\n const td = buttonCell(out);\n expect(td.style.padding, 'padding must be empty').to.equal('');\n }\n });\n\n it('BL23. a background-color:expression(...) is dropped', () => {\n const out = roundTripOn(\n '<p><a href=\"#\" style=\"display:inline-block; padding:12px; background-color:expression(alert(1));\">btn</a></p>'\n );\n expect(out).to.not.include('expression(');\n });\n\n it('BL24. a javascript: href on a button link is stripped', () => {\n const out = roundTripOn(\n '<p><a href=\"javascript:alert(1)\" style=\"display:inline-block; padding:12px; background-color:rgb(64,107,30);\">btn</a></p>'\n );\n const link = parse(out, 'a');\n if (link) {\n expect((link.getAttribute('href') ?? '').toLowerCase()).to.not.include('javascript:');\n }\n expect(out.toLowerCase()).to.not.include('javascript:');\n });\n});\n\ndescribe('button links: fixpoint (email-fidelity on)', () => {\n it('BL25. \"Get discount\" is a serialize → parse → serialize fixpoint', () => {\n const once = roundTripOn(BTN_GET_DISCOUNT);\n expect(roundTripOn(once)).to.equal(once);\n });\n\n it('BL26. the reloaded button is not re-detected (link no longer has box styles)', () => {\n const once = roundTripOn(BTN_GET_DISCOUNT);\n // After one pass the link has no display/padding, so a second pass must not\n // add another nested table layer.\n const tablesOnce = parseAll(once, 'table').length;\n const tablesTwice = parseAll(roundTripOn(once), 'table').length;\n expect(tablesTwice).to.equal(tablesOnce);\n });\n\n it('BL27. \"Shop now\" is a serialize → parse → serialize fixpoint', () => {\n const once = roundTripOn(BTN_SHOP_NOW);\n expect(roundTripOn(once)).to.equal(once);\n });\n});\n"]}
@@ -0,0 +1,11 @@
1
+ import { Node as PMNode } from 'prosemirror-model';
2
+ /** email-fidelity: writes the editor's data-table rendering into the saved HTML; layout tables keep their authored output. */
3
+ /** Theme-resolved colours the editor draws data tables with; null = not drawn. */
4
+ export interface EmailRenderDefaults {
5
+ borderColor: string | null;
6
+ headerBackground: string | null;
7
+ }
8
+ /** Returns a copy of `doc` with the editor's data-table rendering filled into node attrs. */
9
+ export declare function applyEmailRenderDefaults(doc: PMNode, defaults: EmailRenderDefaults): PMNode;
10
+ /** Collapsed borders and no cell spacing on every table, fixed columns on data tables. */
11
+ export declare function finishEmailTables(container: HTMLElement): void;
@@ -0,0 +1,93 @@
1
+ import { Fragment } from 'prosemirror-model';
2
+ /** Kept in sync by hand with `.ProseMirror td, .ProseMirror th { padding: 6px 8px }`. */
3
+ const CELL_PADDING = {
4
+ paddingTop: '6px',
5
+ paddingRight: '8px',
6
+ paddingBottom: '6px',
7
+ paddingLeft: '8px',
8
+ };
9
+ const CELL_BORDERS = ['borderTop', 'borderRight', 'borderBottom', 'borderLeft'];
10
+ /** `.ProseMirror td > *` zeroes block margins inside cells. */
11
+ const CELL_CHILD_MARGIN = 'margin-top: 0px; margin-bottom: 0px';
12
+ /** Returns a copy of `doc` with the editor's data-table rendering filled into node attrs. */
13
+ export function applyEmailRenderDefaults(doc, defaults) {
14
+ return fill(doc, null, defaults);
15
+ }
16
+ function fill(node, context, defaults) {
17
+ if (node.isLeaf)
18
+ return node;
19
+ const name = node.type.name;
20
+ let attrs = node.attrs;
21
+ let childContext = null;
22
+ if (name === 'table') {
23
+ if (!attrs.layout) {
24
+ childContext = 'data-table';
25
+ if (!attrs.width)
26
+ attrs = { ...attrs, width: '100%' };
27
+ }
28
+ }
29
+ else if (name === 'table_row') {
30
+ childContext = context;
31
+ }
32
+ else if ((name === 'table_cell' || name === 'table_header') && context === 'data-table') {
33
+ attrs = cellDefaults(attrs, name === 'table_header', defaults);
34
+ childContext = 'data-cell';
35
+ }
36
+ else if (context === 'data-cell' && 'margin' in attrs && !attrs.margin) {
37
+ attrs = { ...attrs, margin: CELL_CHILD_MARGIN };
38
+ }
39
+ const children = [];
40
+ node.forEach(child => children.push(fill(child, childContext, defaults)));
41
+ return node.type.create(attrs, Fragment.fromArray(children), node.marks);
42
+ }
43
+ function cellDefaults(attrs, header, defaults) {
44
+ const next = { ...attrs };
45
+ for (const [key, value] of Object.entries(CELL_PADDING))
46
+ if (!next[key])
47
+ next[key] = value;
48
+ if (!next.valign)
49
+ next.valign = 'top';
50
+ if (defaults.borderColor) {
51
+ const border = `1px solid ${defaults.borderColor}`;
52
+ for (const key of CELL_BORDERS)
53
+ if (!next[key])
54
+ next[key] = border;
55
+ }
56
+ // A resized column keeps its width in data-colwidth, which mail clients ignore.
57
+ const colwidth = next.colwidth;
58
+ if (!next.width && Array.isArray(colwidth) && colwidth.length && colwidth.every(w => w > 0)) {
59
+ next.width = `${colwidth.reduce((sum, w) => sum + w, 0)}px`;
60
+ }
61
+ if (header) {
62
+ if (!next.background && defaults.headerBackground)
63
+ next.background = defaults.headerBackground;
64
+ if (!next.textAlign)
65
+ next.textAlign = 'left';
66
+ const textStyle = next.textStyle ?? '';
67
+ if (!/font-weight/i.test(textStyle)) {
68
+ next.textStyle = textStyle ? `${textStyle}; font-weight: 600` : 'font-weight: 600';
69
+ }
70
+ }
71
+ return next;
72
+ }
73
+ /** Collapsed borders and no cell spacing on every table, fixed columns on data tables. */
74
+ export function finishEmailTables(container) {
75
+ for (const table of Array.from(container.querySelectorAll('table'))) {
76
+ if (!table.hasAttribute('cellpadding'))
77
+ table.setAttribute('cellpadding', '0');
78
+ if (!table.hasAttribute('cellspacing'))
79
+ table.setAttribute('cellspacing', '0');
80
+ const style = table.getAttribute('style') ?? '';
81
+ const add = [];
82
+ if (!/(^|;)\s*border-collapse\s*:/i.test(style))
83
+ add.push('border-collapse: collapse');
84
+ const layout = table.getAttribute('role') === 'presentation';
85
+ if (!layout && !/(^|;)\s*table-layout\s*:/i.test(style))
86
+ add.push('table-layout: fixed');
87
+ if (add.length) {
88
+ const base = style.trim().replace(/;\s*$/, '');
89
+ table.setAttribute('style', base ? `${base}; ${add.join('; ')}` : add.join('; '));
90
+ }
91
+ }
92
+ }
93
+ //# sourceMappingURL=email-render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-render.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/engine/email-render.ts"],"names":[],"mappings":"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","sourcesContent":["import { Fragment, Node as PMNode } from 'prosemirror-model';\n\n/** email-fidelity: writes the editor's data-table rendering into the saved HTML; layout tables keep their authored output. */\n\n/** Theme-resolved colours the editor draws data tables with; null = not drawn. */\nexport interface EmailRenderDefaults {\n borderColor: string | null;\n headerBackground: string | null;\n}\n\n/** Kept in sync by hand with `.ProseMirror td, .ProseMirror th { padding: 6px 8px }`. */\nconst CELL_PADDING: Record<string, string> = {\n paddingTop: '6px',\n paddingRight: '8px',\n paddingBottom: '6px',\n paddingLeft: '8px',\n};\n\nconst CELL_BORDERS = ['borderTop', 'borderRight', 'borderBottom', 'borderLeft'];\n\n/** `.ProseMirror td > *` zeroes block margins inside cells. */\nconst CELL_CHILD_MARGIN = 'margin-top: 0px; margin-bottom: 0px';\n\ntype Context = 'data-table' | 'data-cell' | null;\n\n/** Returns a copy of `doc` with the editor's data-table rendering filled into node attrs. */\nexport function applyEmailRenderDefaults(doc: PMNode, defaults: EmailRenderDefaults): PMNode {\n return fill(doc, null, defaults);\n}\n\nfunction fill(node: PMNode, context: Context, defaults: EmailRenderDefaults): PMNode {\n if (node.isLeaf) return node;\n const name = node.type.name;\n let attrs = node.attrs;\n let childContext: Context = null;\n\n if (name === 'table') {\n if (!attrs.layout) {\n childContext = 'data-table';\n if (!attrs.width) attrs = { ...attrs, width: '100%' };\n }\n } else if (name === 'table_row') {\n childContext = context;\n } else if ((name === 'table_cell' || name === 'table_header') && context === 'data-table') {\n attrs = cellDefaults(attrs, name === 'table_header', defaults);\n childContext = 'data-cell';\n } else if (context === 'data-cell' && 'margin' in attrs && !attrs.margin) {\n attrs = { ...attrs, margin: CELL_CHILD_MARGIN };\n }\n\n const children: PMNode[] = [];\n node.forEach(child => children.push(fill(child, childContext, defaults)));\n return node.type.create(attrs, Fragment.fromArray(children), node.marks);\n}\n\nfunction cellDefaults(\n attrs: Record<string, any>,\n header: boolean,\n defaults: EmailRenderDefaults\n): Record<string, any> {\n const next = { ...attrs };\n for (const [key, value] of Object.entries(CELL_PADDING)) if (!next[key]) next[key] = value;\n if (!next.valign) next.valign = 'top';\n if (defaults.borderColor) {\n const border = `1px solid ${defaults.borderColor}`;\n for (const key of CELL_BORDERS) if (!next[key]) next[key] = border;\n }\n // A resized column keeps its width in data-colwidth, which mail clients ignore.\n const colwidth = next.colwidth as number[] | null;\n if (!next.width && Array.isArray(colwidth) && colwidth.length && colwidth.every(w => w > 0)) {\n next.width = `${colwidth.reduce((sum, w) => sum + w, 0)}px`;\n }\n if (header) {\n if (!next.background && defaults.headerBackground) next.background = defaults.headerBackground;\n if (!next.textAlign) next.textAlign = 'left';\n const textStyle = (next.textStyle as string | null) ?? '';\n if (!/font-weight/i.test(textStyle)) {\n next.textStyle = textStyle ? `${textStyle}; font-weight: 600` : 'font-weight: 600';\n }\n }\n return next;\n}\n\n/** Collapsed borders and no cell spacing on every table, fixed columns on data tables. */\nexport function finishEmailTables(container: HTMLElement): void {\n for (const table of Array.from(container.querySelectorAll('table'))) {\n if (!table.hasAttribute('cellpadding')) table.setAttribute('cellpadding', '0');\n if (!table.hasAttribute('cellspacing')) table.setAttribute('cellspacing', '0');\n const style = table.getAttribute('style') ?? '';\n const add: string[] = [];\n if (!/(^|;)\\s*border-collapse\\s*:/i.test(style)) add.push('border-collapse: collapse');\n const layout = table.getAttribute('role') === 'presentation';\n if (!layout && !/(^|;)\\s*table-layout\\s*:/i.test(style)) add.push('table-layout: fixed');\n if (add.length) {\n const base = style.trim().replace(/;\\s*$/, '');\n table.setAttribute('style', base ? `${base}; ${add.join('; ')}` : add.join('; '));\n }\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ /** Conservative check: does a text/plain paste look like HTML rather than prose or Markdown? */
2
+ export declare function looksLikeHtml(text: string): boolean;
@@ -0,0 +1,24 @@
1
+ /** Conservative check: does a text/plain paste look like HTML rather than prose or Markdown? */
2
+ /** Block-level tags whose balanced open+close pair marks real HTML structure. */
3
+ const BLOCK_TAGS = 'table|div|p|h1|h2|h3|h4|h5|h6|ul|ol|blockquote|section|body';
4
+ const BALANCED_BLOCK = new RegExp(`<(${BLOCK_TAGS})(?:\\s[^>]*)?>[\\s\\S]*?</\\1\\s*>`, 'i');
5
+ export function looksLikeHtml(text) {
6
+ if (!text)
7
+ return false;
8
+ // Skip leading whitespace and HTML comments so a doctype/`<html>` preamble
9
+ // behind a comment still counts.
10
+ let head = text.replace(/^\s+/, '');
11
+ while (head.startsWith('<!--')) {
12
+ const end = head.indexOf('-->');
13
+ if (end === -1)
14
+ break;
15
+ head = head.slice(end + 3).replace(/^\s+/, '');
16
+ }
17
+ const lower = head.toLowerCase();
18
+ if (lower.startsWith('<!doctype html') || lower.startsWith('<html'))
19
+ return true;
20
+ // A balanced block-level element anywhere is enough; the backreference keeps
21
+ // the open and close tag names matched.
22
+ return BALANCED_BLOCK.test(text);
23
+ }
24
+ //# sourceMappingURL=html-detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-detect.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/engine/html-detect.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAEhG,iFAAiF;AACjF,MAAM,UAAU,GAAG,6DAA6D,CAAC;AAEjF,MAAM,cAAc,GAAG,IAAI,MAAM,CAC/B,KAAK,UAAU,qCAAqC,EACpD,GAAG,CACJ,CAAC;AAEF,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACxB,2EAA2E;IAC3E,iCAAiC;IACjC,IAAI,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACpC,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,MAAM;QACtB,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,IAAI,KAAK,CAAC,UAAU,CAAC,gBAAgB,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACjF,6EAA6E;IAC7E,wCAAwC;IACxC,OAAO,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACnC,CAAC","sourcesContent":["/** Conservative check: does a text/plain paste look like HTML rather than prose or Markdown? */\n\n/** Block-level tags whose balanced open+close pair marks real HTML structure. */\nconst BLOCK_TAGS = 'table|div|p|h1|h2|h3|h4|h5|h6|ul|ol|blockquote|section|body';\n\nconst BALANCED_BLOCK = new RegExp(\n `<(${BLOCK_TAGS})(?:\\\\s[^>]*)?>[\\\\s\\\\S]*?</\\\\1\\\\s*>`,\n 'i'\n);\n\nexport function looksLikeHtml(text: string): boolean {\n if (!text) return false;\n // Skip leading whitespace and HTML comments so a doctype/`<html>` preamble\n // behind a comment still counts.\n let head = text.replace(/^\\s+/, '');\n while (head.startsWith('<!--')) {\n const end = head.indexOf('-->');\n if (end === -1) break;\n head = head.slice(end + 3).replace(/^\\s+/, '');\n }\n const lower = head.toLowerCase();\n if (lower.startsWith('<!doctype html') || lower.startsWith('<html')) return true;\n // A balanced block-level element anywhere is enough; the backreference keeps\n // the open and close tag names matched.\n return BALANCED_BLOCK.test(text);\n}\n"]}
@@ -1,6 +1,9 @@
1
1
  export { createSchema, defaultSchema } from './schema';
2
2
  export type { Alignment } from './schema';
3
- export { sanitizeHtml, isSafeUrl } from './sanitize';
3
+ export { sanitizeHtml, isSafeUrl, relocateEmailContainers } from './sanitize';
4
+ export { normalizeEmailAllowedStyles, parseAllowedStylesAttr, isExtensionPropValid, isExtensionValueValid, sanitizeExtraStyleForWrite, } from './email-css';
5
+ export type { NormalizedAllowedStyles } from './email-css';
6
+ export { looksLikeHtml } from './html-detect';
4
7
  export { htmlToDoc, htmlToSlice, docToHtml, docToText, docToJson, jsonToDoc, isDocEmpty, } from './serializer';
5
8
  export { getCommand, getMarkRange } from './commands';
6
9
  export type { CommandName, CommandAttrs } from './commands';
@@ -1,5 +1,7 @@
1
1
  export { createSchema, defaultSchema } from './schema';
2
- export { sanitizeHtml, isSafeUrl } from './sanitize';
2
+ export { sanitizeHtml, isSafeUrl, relocateEmailContainers } from './sanitize';
3
+ export { normalizeEmailAllowedStyles, parseAllowedStylesAttr, isExtensionPropValid, isExtensionValueValid, sanitizeExtraStyleForWrite, } from './email-css';
4
+ export { looksLikeHtml } from './html-detect';
3
5
  export { htmlToDoc, htmlToSlice, docToHtml, docToText, docToJson, jsonToDoc, isDocEmpty, } from './serializer';
4
6
  export { getCommand, getMarkRange } from './commands';
5
7
  export { docToMarkdown } from './markdown';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/engine/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEvD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EACL,SAAS,EACT,WAAW,EACX,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,UAAU,GACX,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACrF,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGnF,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EACL,cAAc,EACd,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,WAAW,EACX,eAAe,EACf,YAAY,GACb,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC","sourcesContent":["export { createSchema, defaultSchema } from './schema';\nexport type { Alignment } from './schema';\nexport { sanitizeHtml, isSafeUrl } from './sanitize';\nexport {\n htmlToDoc,\n htmlToSlice,\n docToHtml,\n docToText,\n docToJson,\n jsonToDoc,\n isDocEmpty,\n} from './serializer';\nexport { getCommand, getMarkRange } from './commands';\nexport type { CommandName, CommandAttrs } from './commands';\nexport { docToMarkdown } from './markdown';\nexport { markdownToHtml, looksLikeMarkdown } from './markdown-parse';\nexport { isOfficeHtml, isExcelHtml, cleanOfficeHtml } from './office-paste';\nexport {\n toInlineStyledHtml,\n buildWordDocument,\n buildPrintDocument,\n} from './export';\nexport type { PrintOptions } from './export';\nexport { selectedImageInfo } from './commands';\nexport { ImageView, FigureView } from './plugins/image-view';\nexport { EmbedView } from './plugins/embed-view';\nexport { StyleBlockView } from './plugins/style-block-view';\nexport { MathView } from './plugins/math-view';\nexport type { MathRenderer } from './plugins/math-view';\nexport { INDENT_STEP_PX, MAX_INDENT, BULLET_STYLES, ORDERED_STYLES } from './schema';\nexport { computeToolbarState } from './selection-state';\nexport type { ToolbarState } from './selection-state';\nexport {\n createEditorState,\n mentionSuggestKey,\n slashSuggestKey,\n emojiSuggestKey,\n} from './create-state';\nexport { maxLengthPlugin } from './plugins/max-length';\nexport { TaskItemView } from './plugins/task-list';\nexport { codeHighlightPlugin, CODE_LANGUAGES } from './plugins/code-highlight';\nexport { toEmbedUrl, isAllowedEmbedSrc, embedPastePlugin } from './plugins/embeds';\nexport type { EmbedTarget } from './plugins/embeds';\nexport type { CreateStateOptions } from './create-state';\nexport { countWords } from './serializer';\nexport type { SuggestionMatch, SuggestionOptions } from './plugins/suggestions';\nexport {\n findReplaceKey,\n getFindState,\n searchTr,\n findStepTr,\n clearFindTr,\n replaceActiveTr,\n replaceAllTr,\n} from './plugins/find-replace';\nexport type { FindState, FindMatch } from './plugins/find-replace';\nexport { placeholderPlugin } from './plugins/placeholder';\nexport {\n formatPainterPlugin,\n formatPainterKey,\n isFormatPainterArmed,\n armFormatPainter,\n disarmFormatPainter,\n applyFormatPainter,\n} from './plugins/format-painter';\nexport { linkPlugin } from './plugins/link';\nexport { singleLinePlugin, flattenToSingleParagraph } from './plugins/single-line';\nexport { tablePlugins } from './plugins/tables';\nexport { imagePlugin, imageUploadKey, findUploadPos } from './plugins/image';\nexport { pastePlugin, plainTextSlice, stripSliceFormatting } from './plugins/paste';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/engine/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEvD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAC9E,OAAO,EACL,2BAA2B,EAC3B,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EACL,SAAS,EACT,WAAW,EACX,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,UAAU,GACX,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACrF,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGnF,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EACL,cAAc,EACd,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,WAAW,EACX,eAAe,EACf,YAAY,GACb,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC","sourcesContent":["export { createSchema, defaultSchema } from './schema';\nexport type { Alignment } from './schema';\nexport { sanitizeHtml, isSafeUrl, relocateEmailContainers } from './sanitize';\nexport {\n normalizeEmailAllowedStyles,\n parseAllowedStylesAttr,\n isExtensionPropValid,\n isExtensionValueValid,\n sanitizeExtraStyleForWrite,\n} from './email-css';\nexport type { NormalizedAllowedStyles } from './email-css';\nexport { looksLikeHtml } from './html-detect';\nexport {\n htmlToDoc,\n htmlToSlice,\n docToHtml,\n docToText,\n docToJson,\n jsonToDoc,\n isDocEmpty,\n} from './serializer';\nexport { getCommand, getMarkRange } from './commands';\nexport type { CommandName, CommandAttrs } from './commands';\nexport { docToMarkdown } from './markdown';\nexport { markdownToHtml, looksLikeMarkdown } from './markdown-parse';\nexport { isOfficeHtml, isExcelHtml, cleanOfficeHtml } from './office-paste';\nexport {\n toInlineStyledHtml,\n buildWordDocument,\n buildPrintDocument,\n} from './export';\nexport type { PrintOptions } from './export';\nexport { selectedImageInfo } from './commands';\nexport { ImageView, FigureView } from './plugins/image-view';\nexport { EmbedView } from './plugins/embed-view';\nexport { StyleBlockView } from './plugins/style-block-view';\nexport { MathView } from './plugins/math-view';\nexport type { MathRenderer } from './plugins/math-view';\nexport { INDENT_STEP_PX, MAX_INDENT, BULLET_STYLES, ORDERED_STYLES } from './schema';\nexport { computeToolbarState } from './selection-state';\nexport type { ToolbarState } from './selection-state';\nexport {\n createEditorState,\n mentionSuggestKey,\n slashSuggestKey,\n emojiSuggestKey,\n} from './create-state';\nexport { maxLengthPlugin } from './plugins/max-length';\nexport { TaskItemView } from './plugins/task-list';\nexport { codeHighlightPlugin, CODE_LANGUAGES } from './plugins/code-highlight';\nexport { toEmbedUrl, isAllowedEmbedSrc, embedPastePlugin } from './plugins/embeds';\nexport type { EmbedTarget } from './plugins/embeds';\nexport type { CreateStateOptions } from './create-state';\nexport { countWords } from './serializer';\nexport type { SuggestionMatch, SuggestionOptions } from './plugins/suggestions';\nexport {\n findReplaceKey,\n getFindState,\n searchTr,\n findStepTr,\n clearFindTr,\n replaceActiveTr,\n replaceAllTr,\n} from './plugins/find-replace';\nexport type { FindState, FindMatch } from './plugins/find-replace';\nexport { placeholderPlugin } from './plugins/placeholder';\nexport {\n formatPainterPlugin,\n formatPainterKey,\n isFormatPainterArmed,\n armFormatPainter,\n disarmFormatPainter,\n applyFormatPainter,\n} from './plugins/format-painter';\nexport { linkPlugin } from './plugins/link';\nexport { singleLinePlugin, flattenToSingleParagraph } from './plugins/single-line';\nexport { tablePlugins } from './plugins/tables';\nexport { imagePlugin, imageUploadKey, findUploadPos } from './plugins/image';\nexport { pastePlugin, plainTextSlice, stripSliceFormatting } from './plugins/paste';\n"]}
@@ -4,9 +4,4 @@ export interface InputRulesOptions {
4
4
  /** Include the autocorrect/typography rules. Defaults to true. */
5
5
  textTransform?: boolean;
6
6
  }
7
- /**
8
- * Markdown-style typing shortcuts: block rules plus inline mark rules
9
- * (**bold**, *italic*, `code`, ~~strike~~), and (unless disabled) the
10
- * typography autocorrect rules.
11
- */
12
7
  export declare function buildInputRules(schema: Schema, options?: InputRulesOptions): Plugin;
@@ -1,4 +1,5 @@
1
1
  import { inputRules, wrappingInputRule, textblockTypeInputRule, InputRule, } from 'prosemirror-inputrules';
2
+ import { TextSelection } from 'prosemirror-state';
2
3
  function escapeRegex(text) {
3
4
  return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
4
5
  }
@@ -111,6 +112,22 @@ function linkifyRule(schema) {
111
112
  * (**bold**, *italic*, `code`, ~~strike~~), and (unless disabled) the
112
113
  * typography autocorrect rules.
113
114
  */
115
+ /** "---", "***" or "___" alone in a top-level paragraph → horizontal rule. */
116
+ function horizontalRuleRule(schema) {
117
+ return new InputRule(/^(?:---|\*\*\*|___)$/, (state, _match, start) => {
118
+ const $start = state.doc.resolve(start);
119
+ const { paragraph, horizontal_rule: hr } = schema.nodes;
120
+ // The rule's two earlier characters must be the whole paragraph.
121
+ if ($start.parent.type !== paragraph || $start.parent.content.size !== 2)
122
+ return null;
123
+ const index = $start.index(-1);
124
+ if (!$start.node(-1).canReplaceWith(index, index + 1, hr))
125
+ return null;
126
+ const before = $start.before();
127
+ const tr = state.tr.replaceWith(before, $start.after(), [hr.create(), paragraph.create()]);
128
+ return tr.setSelection(TextSelection.create(tr.doc, before + 2)).scrollIntoView();
129
+ });
130
+ }
114
131
  export function buildInputRules(schema, options = {}) {
115
132
  const transforms = options.textTransform === false ? [] : textTransformRules();
116
133
  return inputRules({
@@ -126,6 +143,8 @@ export function buildInputRules(schema, options = {}) {
126
143
  wrappingInputRule(/^(\d+)\.\s$/, schema.nodes.ordered_list, match => ({ order: +match[1] }), (match, node) => node.childCount + node.attrs.order === +match[1]),
127
144
  // "```" → code block
128
145
  textblockTypeInputRule(/^```$/, schema.nodes.code_block),
146
+ // "---" / "***" / "___" → horizontal rule
147
+ horizontalRuleRule(schema),
129
148
  // "[] " or "[ ] " → checklist
130
149
  wrappingInputRule(/^\s*\[[ ]?\]\s$/, schema.nodes.task_list),
131
150
  // Inline marks. Bold before italic so '**' is never read as italic;