@aquera/nile-elements 1.9.5 → 1.9.7

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 (565) hide show
  1. package/README.md +9 -0
  2. package/dist/index-178e1e57.cjs.js +2 -0
  3. package/dist/index-178e1e57.cjs.js.map +1 -0
  4. package/dist/index-1faa963c.esm.js +1 -0
  5. package/dist/index-249de90a.esm.js +1 -0
  6. package/dist/index-353172ed.esm.js +1 -0
  7. package/dist/index-6f3fa4ab.esm.js +1 -0
  8. package/dist/index-89c520e9.cjs.js +5 -0
  9. package/dist/index-89c520e9.cjs.js.map +1 -0
  10. package/dist/index-920675c4.esm.js +1 -0
  11. package/dist/index-b387a9f4.cjs.js +2 -0
  12. package/dist/index-b387a9f4.cjs.js.map +1 -0
  13. package/dist/index-cc1385e0.cjs.js +2 -0
  14. package/dist/index-cc1385e0.cjs.js.map +1 -0
  15. package/dist/index-dedc38a6.esm.js +1 -0
  16. package/dist/index-df196058.cjs.js +2 -0
  17. package/dist/index-df196058.cjs.js.map +1 -0
  18. package/dist/index-f956f56d.cjs.js +7 -0
  19. package/dist/index-f956f56d.cjs.js.map +1 -0
  20. package/dist/index.cjs.js +1 -1
  21. package/dist/index.esm.js +1 -1
  22. package/dist/index.js +3802 -664
  23. package/dist/internal/glyph.cjs.js +2 -0
  24. package/dist/internal/glyph.cjs.js.map +1 -0
  25. package/dist/internal/glyph.esm.js +5 -0
  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-chip/nile-chip.css.cjs.js +1 -1
  31. package/dist/nile-chip/nile-chip.css.cjs.js.map +1 -1
  32. package/dist/nile-chip/nile-chip.css.esm.js +8 -1
  33. package/dist/nile-code-editor/extensionSetup.cjs.js +7 -7
  34. package/dist/nile-code-editor/extensionSetup.cjs.js.map +1 -1
  35. package/dist/nile-code-editor/extensionSetup.esm.js +1 -1
  36. package/dist/nile-code-editor/index.cjs.js +1 -1
  37. package/dist/nile-code-editor/index.esm.js +1 -1
  38. package/dist/nile-code-editor/nile-code-editor.cjs.js +2 -2
  39. package/dist/nile-code-editor/nile-code-editor.cjs.js.map +1 -1
  40. package/dist/nile-code-editor/nile-code-editor.esm.js +4 -4
  41. package/dist/nile-color-picker/index.cjs.js +1 -1
  42. package/dist/nile-color-picker/nile-color-picker.cjs.js +1 -1
  43. package/dist/nile-combobox/index.cjs.js +1 -1
  44. package/dist/nile-combobox/index.esm.js +1 -1
  45. package/dist/nile-combobox/nile-combobox.cjs.js +1 -1
  46. package/dist/nile-combobox/nile-combobox.esm.js +1 -1
  47. package/dist/nile-combobox/portal-manager.cjs.js +1 -1
  48. package/dist/nile-context-menu/index.cjs.js +1 -1
  49. package/dist/nile-context-menu/nile-context-menu.cjs.js +1 -1
  50. package/dist/nile-context-submenu/index.cjs.js +1 -1
  51. package/dist/nile-context-submenu/nile-context-submenu.cjs.js +1 -1
  52. package/dist/nile-detail/index.cjs.js +1 -1
  53. package/dist/nile-detail/index.esm.js +1 -1
  54. package/dist/nile-detail/nile-detail.cjs.js +1 -1
  55. package/dist/nile-detail/nile-detail.esm.js +1 -1
  56. package/dist/nile-dropdown/index.cjs.js +1 -1
  57. package/dist/nile-dropdown/nile-dropdown.cjs.js +1 -1
  58. package/dist/nile-dropdown/portal-manager.cjs.js +1 -1
  59. package/dist/nile-file-upload/index.cjs.js +1 -1
  60. package/dist/nile-file-upload/nile-file-upload.cjs.js +1 -1
  61. package/dist/nile-file-upload/nile-file-upload.template.cjs.js +1 -1
  62. package/dist/nile-floating-panel/index.cjs.js +1 -1
  63. package/dist/nile-floating-panel/nile-floating-panel.cjs.js +1 -1
  64. package/dist/nile-hero/nile-hero.cjs.js +1 -1
  65. package/dist/nile-hero/nile-hero.cjs.js.map +1 -1
  66. package/dist/nile-hero/nile-hero.css.cjs.js +1 -1
  67. package/dist/nile-hero/nile-hero.css.cjs.js.map +1 -1
  68. package/dist/nile-hero/nile-hero.css.esm.js +14 -14
  69. package/dist/nile-hero/nile-hero.esm.js +1 -1
  70. package/dist/nile-hero-header/nile-hero-header.cjs.js +1 -1
  71. package/dist/nile-hero-header/nile-hero-header.cjs.js.map +1 -1
  72. package/dist/nile-hero-header/nile-hero-header.css.cjs.js +1 -1
  73. package/dist/nile-hero-header/nile-hero-header.css.cjs.js.map +1 -1
  74. package/dist/nile-hero-header/nile-hero-header.css.esm.js +11 -11
  75. package/dist/nile-hero-header/nile-hero-header.esm.js +3 -3
  76. package/dist/nile-lite-tooltip/index.cjs.js +1 -1
  77. package/dist/nile-lite-tooltip/nile-lite-tooltip.cjs.js +1 -1
  78. package/dist/nile-markdown-editor/index.cjs.js +1 -1
  79. package/dist/nile-markdown-editor/nile-markdown-editor.cjs.js +1 -1
  80. package/dist/nile-popover/index.cjs.js +1 -1
  81. package/dist/nile-popover/nile-popover.cjs.js +1 -1
  82. package/dist/nile-popover/portal-manager.cjs.js +1 -1
  83. package/dist/nile-popup/index.cjs.js +1 -1
  84. package/dist/nile-popup/nile-popup.cjs.js +1 -1
  85. package/dist/nile-rich-text-editor/index.cjs.js +1 -1
  86. package/dist/nile-rich-text-editor/index.esm.js +1 -1
  87. package/dist/nile-rich-text-editor/nile-rich-text-editor.cjs.js +1 -1
  88. package/dist/nile-rich-text-editor/nile-rich-text-editor.cjs.js.map +1 -1
  89. package/dist/nile-rich-text-editor/nile-rich-text-editor.css.cjs.js +1 -1
  90. package/dist/nile-rich-text-editor/nile-rich-text-editor.css.cjs.js.map +1 -1
  91. package/dist/nile-rich-text-editor/nile-rich-text-editor.css.esm.js +70 -0
  92. package/dist/nile-rich-text-editor/nile-rich-text-editor.esm.js +1 -1
  93. package/dist/nile-rich-text-editor/nile-rte-image.cjs.js +3 -0
  94. package/dist/nile-rich-text-editor/nile-rte-image.cjs.js.map +1 -0
  95. package/dist/nile-rich-text-editor/nile-rte-image.esm.js +96 -0
  96. package/dist/nile-select/index.cjs.js +1 -1
  97. package/dist/nile-select/nile-select.cjs.js +1 -1
  98. package/dist/nile-select/portal-manager.cjs.js +1 -1
  99. package/dist/nile-side-bar-action/index.cjs.js +1 -1
  100. package/dist/nile-side-bar-action/nile-side-bar-action.cjs.js +1 -1
  101. package/dist/nile-side-bar-action/portal-manager.cjs.js +1 -1
  102. package/dist/nile-tooltip/index.cjs.js +1 -1
  103. package/dist/nile-tooltip/nile-tooltip.cjs.js +1 -1
  104. package/dist/nile-virtual-select/index.cjs.js +1 -1
  105. package/dist/nile-virtual-select/nile-virtual-select.cjs.js +1 -1
  106. package/dist/nile-virtual-select/portal-manager.cjs.js +1 -1
  107. package/dist/nile-virtual-select/renderer.cjs.js +1 -1
  108. package/dist/nile-wysiwyg-editor/emoji.cjs.js +2 -0
  109. package/dist/nile-wysiwyg-editor/emoji.cjs.js.map +1 -0
  110. package/dist/nile-wysiwyg-editor/emoji.esm.js +1 -0
  111. package/dist/nile-wysiwyg-editor/engine/commands.cjs.js +2 -0
  112. package/dist/nile-wysiwyg-editor/engine/commands.cjs.js.map +1 -0
  113. package/dist/nile-wysiwyg-editor/engine/commands.esm.js +1 -0
  114. package/dist/nile-wysiwyg-editor/engine/create-state.cjs.js +2 -0
  115. package/dist/nile-wysiwyg-editor/engine/create-state.cjs.js.map +1 -0
  116. package/dist/nile-wysiwyg-editor/engine/create-state.esm.js +1 -0
  117. package/dist/nile-wysiwyg-editor/engine/export.cjs.js +2 -0
  118. package/dist/nile-wysiwyg-editor/engine/export.cjs.js.map +1 -0
  119. package/dist/nile-wysiwyg-editor/engine/export.esm.js +1 -0
  120. package/dist/nile-wysiwyg-editor/engine/index.cjs.js +2 -0
  121. package/dist/nile-wysiwyg-editor/engine/index.cjs.js.map +1 -0
  122. package/dist/nile-wysiwyg-editor/engine/index.esm.js +1 -0
  123. package/dist/nile-wysiwyg-editor/engine/inputrules.cjs.js +2 -0
  124. package/dist/nile-wysiwyg-editor/engine/inputrules.cjs.js.map +1 -0
  125. package/dist/nile-wysiwyg-editor/engine/inputrules.esm.js +1 -0
  126. package/dist/nile-wysiwyg-editor/engine/keymap.cjs.js +2 -0
  127. package/dist/nile-wysiwyg-editor/engine/keymap.cjs.js.map +1 -0
  128. package/dist/nile-wysiwyg-editor/engine/keymap.esm.js +1 -0
  129. package/dist/nile-wysiwyg-editor/engine/markdown-parse.cjs.js +2 -0
  130. package/dist/nile-wysiwyg-editor/engine/markdown-parse.cjs.js.map +1 -0
  131. package/dist/nile-wysiwyg-editor/engine/markdown-parse.esm.js +1 -0
  132. package/dist/nile-wysiwyg-editor/engine/markdown.cjs.js +2 -0
  133. package/dist/nile-wysiwyg-editor/engine/markdown.cjs.js.map +1 -0
  134. package/dist/nile-wysiwyg-editor/engine/markdown.esm.js +1 -0
  135. package/dist/nile-wysiwyg-editor/engine/office-paste.cjs.js +2 -0
  136. package/dist/nile-wysiwyg-editor/engine/office-paste.cjs.js.map +1 -0
  137. package/dist/nile-wysiwyg-editor/engine/office-paste.esm.js +1 -0
  138. package/dist/nile-wysiwyg-editor/engine/plugins/code-highlight.cjs.js +2 -0
  139. package/dist/nile-wysiwyg-editor/engine/plugins/code-highlight.cjs.js.map +1 -0
  140. package/dist/nile-wysiwyg-editor/engine/plugins/code-highlight.esm.js +1 -0
  141. package/dist/nile-wysiwyg-editor/engine/plugins/embed-view.cjs.js +2 -0
  142. package/dist/nile-wysiwyg-editor/engine/plugins/embed-view.cjs.js.map +1 -0
  143. package/dist/nile-wysiwyg-editor/engine/plugins/embed-view.esm.js +1 -0
  144. package/dist/nile-wysiwyg-editor/engine/plugins/embeds.cjs.js +2 -0
  145. package/dist/nile-wysiwyg-editor/engine/plugins/embeds.cjs.js.map +1 -0
  146. package/dist/nile-wysiwyg-editor/engine/plugins/embeds.esm.js +1 -0
  147. package/dist/nile-wysiwyg-editor/engine/plugins/find-replace.cjs.js +2 -0
  148. package/dist/nile-wysiwyg-editor/engine/plugins/find-replace.cjs.js.map +1 -0
  149. package/dist/nile-wysiwyg-editor/engine/plugins/find-replace.esm.js +1 -0
  150. package/dist/nile-wysiwyg-editor/engine/plugins/format-painter.cjs.js +2 -0
  151. package/dist/nile-wysiwyg-editor/engine/plugins/format-painter.cjs.js.map +1 -0
  152. package/dist/nile-wysiwyg-editor/engine/plugins/format-painter.esm.js +1 -0
  153. package/dist/nile-wysiwyg-editor/engine/plugins/image-view.cjs.js +2 -0
  154. package/dist/nile-wysiwyg-editor/engine/plugins/image-view.cjs.js.map +1 -0
  155. package/dist/nile-wysiwyg-editor/engine/plugins/image-view.esm.js +1 -0
  156. package/dist/nile-wysiwyg-editor/engine/plugins/image.cjs.js +2 -0
  157. package/dist/nile-wysiwyg-editor/engine/plugins/image.cjs.js.map +1 -0
  158. package/dist/nile-wysiwyg-editor/engine/plugins/image.esm.js +1 -0
  159. package/dist/nile-wysiwyg-editor/engine/plugins/link.cjs.js +2 -0
  160. package/dist/nile-wysiwyg-editor/engine/plugins/link.cjs.js.map +1 -0
  161. package/dist/nile-wysiwyg-editor/engine/plugins/link.esm.js +1 -0
  162. package/dist/nile-wysiwyg-editor/engine/plugins/math-view.cjs.js +2 -0
  163. package/dist/nile-wysiwyg-editor/engine/plugins/math-view.cjs.js.map +1 -0
  164. package/dist/nile-wysiwyg-editor/engine/plugins/math-view.esm.js +1 -0
  165. package/dist/nile-wysiwyg-editor/engine/plugins/max-length.cjs.js +2 -0
  166. package/dist/nile-wysiwyg-editor/engine/plugins/max-length.cjs.js.map +1 -0
  167. package/dist/nile-wysiwyg-editor/engine/plugins/max-length.esm.js +1 -0
  168. package/dist/nile-wysiwyg-editor/engine/plugins/paste.cjs.js +2 -0
  169. package/dist/nile-wysiwyg-editor/engine/plugins/paste.cjs.js.map +1 -0
  170. package/dist/nile-wysiwyg-editor/engine/plugins/paste.esm.js +1 -0
  171. package/dist/nile-wysiwyg-editor/engine/plugins/placeholder.cjs.js +2 -0
  172. package/dist/nile-wysiwyg-editor/engine/plugins/placeholder.cjs.js.map +1 -0
  173. package/dist/nile-wysiwyg-editor/engine/plugins/placeholder.esm.js +1 -0
  174. package/dist/nile-wysiwyg-editor/engine/plugins/single-line.cjs.js +2 -0
  175. package/dist/nile-wysiwyg-editor/engine/plugins/single-line.cjs.js.map +1 -0
  176. package/dist/nile-wysiwyg-editor/engine/plugins/single-line.esm.js +1 -0
  177. package/dist/nile-wysiwyg-editor/engine/plugins/suggestions.cjs.js +2 -0
  178. package/dist/nile-wysiwyg-editor/engine/plugins/suggestions.cjs.js.map +1 -0
  179. package/dist/nile-wysiwyg-editor/engine/plugins/suggestions.esm.js +1 -0
  180. package/dist/nile-wysiwyg-editor/engine/plugins/tables.cjs.js +2 -0
  181. package/dist/nile-wysiwyg-editor/engine/plugins/tables.cjs.js.map +1 -0
  182. package/dist/nile-wysiwyg-editor/engine/plugins/tables.esm.js +1 -0
  183. package/dist/nile-wysiwyg-editor/engine/plugins/task-list.cjs.js +2 -0
  184. package/dist/nile-wysiwyg-editor/engine/plugins/task-list.cjs.js.map +1 -0
  185. package/dist/nile-wysiwyg-editor/engine/plugins/task-list.esm.js +1 -0
  186. package/dist/nile-wysiwyg-editor/engine/sanitize.cjs.js +2 -0
  187. package/dist/nile-wysiwyg-editor/engine/sanitize.cjs.js.map +1 -0
  188. package/dist/nile-wysiwyg-editor/engine/sanitize.esm.js +1 -0
  189. package/dist/nile-wysiwyg-editor/engine/schema.cjs.js +2 -0
  190. package/dist/nile-wysiwyg-editor/engine/schema.cjs.js.map +1 -0
  191. package/dist/nile-wysiwyg-editor/engine/schema.esm.js +1 -0
  192. package/dist/nile-wysiwyg-editor/engine/selection-state.cjs.js +2 -0
  193. package/dist/nile-wysiwyg-editor/engine/selection-state.cjs.js.map +1 -0
  194. package/dist/nile-wysiwyg-editor/engine/selection-state.esm.js +1 -0
  195. package/dist/nile-wysiwyg-editor/engine/serializer.cjs.js +2 -0
  196. package/dist/nile-wysiwyg-editor/engine/serializer.cjs.js.map +1 -0
  197. package/dist/nile-wysiwyg-editor/engine/serializer.esm.js +1 -0
  198. package/dist/nile-wysiwyg-editor/index.cjs.js +2 -0
  199. package/dist/nile-wysiwyg-editor/index.cjs.js.map +1 -0
  200. package/dist/nile-wysiwyg-editor/index.esm.js +1 -0
  201. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.cjs.js +2 -0
  202. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.cjs.js.map +1 -0
  203. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.css.cjs.js +2 -0
  204. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.css.cjs.js.map +1 -0
  205. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.css.esm.js +780 -0
  206. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.esm.js +97 -0
  207. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.cjs.js +2 -0
  208. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.cjs.js.map +1 -0
  209. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.esm.js +1 -0
  210. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.cjs.js +2 -0
  211. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.cjs.js.map +1 -0
  212. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.css.cjs.js +2 -0
  213. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.css.cjs.js.map +1 -0
  214. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.css.esm.js +244 -0
  215. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.esm.js +137 -0
  216. package/dist/nile-wysiwyg-editor/types.cjs.js +2 -0
  217. package/dist/nile-wysiwyg-editor/types.cjs.js.map +1 -0
  218. package/dist/nile-wysiwyg-editor/types.esm.js +1 -0
  219. package/dist/nile-wysiwyg-editor/ui/bookmark-panel.cjs.js +2 -0
  220. package/dist/nile-wysiwyg-editor/ui/bookmark-panel.cjs.js.map +1 -0
  221. package/dist/nile-wysiwyg-editor/ui/bookmark-panel.esm.js +97 -0
  222. package/dist/nile-wysiwyg-editor/ui/bubble-menu.cjs.js +2 -0
  223. package/dist/nile-wysiwyg-editor/ui/bubble-menu.cjs.js.map +1 -0
  224. package/dist/nile-wysiwyg-editor/ui/bubble-menu.esm.js +67 -0
  225. package/dist/nile-wysiwyg-editor/ui/code-block-menu.cjs.js +2 -0
  226. package/dist/nile-wysiwyg-editor/ui/code-block-menu.cjs.js.map +1 -0
  227. package/dist/nile-wysiwyg-editor/ui/code-block-menu.esm.js +65 -0
  228. package/dist/nile-wysiwyg-editor/ui/embed-menu.cjs.js +2 -0
  229. package/dist/nile-wysiwyg-editor/ui/embed-menu.cjs.js.map +1 -0
  230. package/dist/nile-wysiwyg-editor/ui/embed-menu.esm.js +64 -0
  231. package/dist/nile-wysiwyg-editor/ui/embed-panel.cjs.js +2 -0
  232. package/dist/nile-wysiwyg-editor/ui/embed-panel.cjs.js.map +1 -0
  233. package/dist/nile-wysiwyg-editor/ui/embed-panel.esm.js +68 -0
  234. package/dist/nile-wysiwyg-editor/ui/emoji-picker.cjs.js +2 -0
  235. package/dist/nile-wysiwyg-editor/ui/emoji-picker.cjs.js.map +1 -0
  236. package/dist/nile-wysiwyg-editor/ui/emoji-picker.esm.js +96 -0
  237. package/dist/nile-wysiwyg-editor/ui/find-replace.cjs.js +2 -0
  238. package/dist/nile-wysiwyg-editor/ui/find-replace.cjs.js.map +1 -0
  239. package/dist/nile-wysiwyg-editor/ui/find-replace.esm.js +112 -0
  240. package/dist/nile-wysiwyg-editor/ui/image-menu.cjs.js +2 -0
  241. package/dist/nile-wysiwyg-editor/ui/image-menu.cjs.js.map +1 -0
  242. package/dist/nile-wysiwyg-editor/ui/image-menu.esm.js +64 -0
  243. package/dist/nile-wysiwyg-editor/ui/image-panel.cjs.js +2 -0
  244. package/dist/nile-wysiwyg-editor/ui/image-panel.cjs.js.map +1 -0
  245. package/dist/nile-wysiwyg-editor/ui/image-panel.esm.js +171 -0
  246. package/dist/nile-wysiwyg-editor/ui/insert-menu.cjs.js +2 -0
  247. package/dist/nile-wysiwyg-editor/ui/insert-menu.cjs.js.map +1 -0
  248. package/dist/nile-wysiwyg-editor/ui/insert-menu.esm.js +90 -0
  249. package/dist/nile-wysiwyg-editor/ui/link-editor.cjs.js +2 -0
  250. package/dist/nile-wysiwyg-editor/ui/link-editor.cjs.js.map +1 -0
  251. package/dist/nile-wysiwyg-editor/ui/link-editor.esm.js +114 -0
  252. package/dist/nile-wysiwyg-editor/ui/markdown-panel.cjs.js +2 -0
  253. package/dist/nile-wysiwyg-editor/ui/markdown-panel.cjs.js.map +1 -0
  254. package/dist/nile-wysiwyg-editor/ui/markdown-panel.esm.js +80 -0
  255. package/dist/nile-wysiwyg-editor/ui/math-panel.cjs.js +2 -0
  256. package/dist/nile-wysiwyg-editor/ui/math-panel.cjs.js.map +1 -0
  257. package/dist/nile-wysiwyg-editor/ui/math-panel.esm.js +92 -0
  258. package/dist/nile-wysiwyg-editor/ui/shortcut-help.cjs.js +2 -0
  259. package/dist/nile-wysiwyg-editor/ui/shortcut-help.cjs.js.map +1 -0
  260. package/dist/nile-wysiwyg-editor/ui/shortcut-help.esm.js +147 -0
  261. package/dist/nile-wysiwyg-editor/ui/source-view.cjs.js +2 -0
  262. package/dist/nile-wysiwyg-editor/ui/source-view.cjs.js.map +1 -0
  263. package/dist/nile-wysiwyg-editor/ui/source-view.esm.js +79 -0
  264. package/dist/nile-wysiwyg-editor/ui/special-chars.cjs.js +2 -0
  265. package/dist/nile-wysiwyg-editor/ui/special-chars.cjs.js.map +1 -0
  266. package/dist/nile-wysiwyg-editor/ui/special-chars.esm.js +96 -0
  267. package/dist/nile-wysiwyg-editor/ui/suggest-list.cjs.js +2 -0
  268. package/dist/nile-wysiwyg-editor/ui/suggest-list.cjs.js.map +1 -0
  269. package/dist/nile-wysiwyg-editor/ui/suggest-list.esm.js +67 -0
  270. package/dist/nile-wysiwyg-editor/ui/table-grid-picker.cjs.js +2 -0
  271. package/dist/nile-wysiwyg-editor/ui/table-grid-picker.cjs.js.map +1 -0
  272. package/dist/nile-wysiwyg-editor/ui/table-grid-picker.esm.js +100 -0
  273. package/dist/nile-wysiwyg-editor/ui/table-menu.cjs.js +2 -0
  274. package/dist/nile-wysiwyg-editor/ui/table-menu.cjs.js.map +1 -0
  275. package/dist/nile-wysiwyg-editor/ui/table-menu.esm.js +58 -0
  276. package/dist/src/index.d.ts +24 -0
  277. package/dist/src/index.js +19 -0
  278. package/dist/src/index.js.map +1 -1
  279. package/dist/src/internal/glyph.d.ts +6 -0
  280. package/dist/src/internal/glyph.js +13 -0
  281. package/dist/src/internal/glyph.js.map +1 -0
  282. package/dist/src/nile-chip/nile-chip.css.js +8 -1
  283. package/dist/src/nile-chip/nile-chip.css.js.map +1 -1
  284. package/dist/src/nile-code-editor/nile-code-editor.js +3 -3
  285. package/dist/src/nile-code-editor/nile-code-editor.js.map +1 -1
  286. package/dist/src/nile-hero/nile-hero.css.js +12 -12
  287. package/dist/src/nile-hero/nile-hero.css.js.map +1 -1
  288. package/dist/src/nile-hero/nile-hero.js +1 -1
  289. package/dist/src/nile-hero/nile-hero.js.map +1 -1
  290. package/dist/src/nile-hero-header/nile-hero-header.css.js +9 -9
  291. package/dist/src/nile-hero-header/nile-hero-header.css.js.map +1 -1
  292. package/dist/src/nile-hero-header/nile-hero-header.js +1 -1
  293. package/dist/src/nile-hero-header/nile-hero-header.js.map +1 -1
  294. package/dist/src/nile-rich-text-editor/nile-rich-text-editor.css.js +70 -0
  295. package/dist/src/nile-rich-text-editor/nile-rich-text-editor.css.js.map +1 -1
  296. package/dist/src/nile-rich-text-editor/nile-rich-text-editor.d.ts +3 -0
  297. package/dist/src/nile-rich-text-editor/nile-rich-text-editor.js +81 -3
  298. package/dist/src/nile-rich-text-editor/nile-rich-text-editor.js.map +1 -1
  299. package/dist/src/nile-rich-text-editor/nile-rte-image.d.ts +87 -0
  300. package/dist/src/nile-rich-text-editor/nile-rte-image.js +1073 -0
  301. package/dist/src/nile-rich-text-editor/nile-rte-image.js.map +1 -0
  302. package/dist/src/nile-wysiwyg-editor/emoji.d.ts +5 -0
  303. package/dist/src/nile-wysiwyg-editor/emoji.js +138 -0
  304. package/dist/src/nile-wysiwyg-editor/emoji.js.map +1 -0
  305. package/dist/src/nile-wysiwyg-editor/engine/commands.d.ts +69 -0
  306. package/dist/src/nile-wysiwyg-editor/engine/commands.js +863 -0
  307. package/dist/src/nile-wysiwyg-editor/engine/commands.js.map +1 -0
  308. package/dist/src/nile-wysiwyg-editor/engine/create-state.d.ts +35 -0
  309. package/dist/src/nile-wysiwyg-editor/engine/create-state.js +67 -0
  310. package/dist/src/nile-wysiwyg-editor/engine/create-state.js.map +1 -0
  311. package/dist/src/nile-wysiwyg-editor/engine/export.d.ts +38 -0
  312. package/dist/src/nile-wysiwyg-editor/engine/export.js +208 -0
  313. package/dist/src/nile-wysiwyg-editor/engine/export.js.map +1 -0
  314. package/dist/src/nile-wysiwyg-editor/engine/export.test.d.ts +1 -0
  315. package/dist/src/nile-wysiwyg-editor/engine/export.test.js +96 -0
  316. package/dist/src/nile-wysiwyg-editor/engine/export.test.js.map +1 -0
  317. package/dist/src/nile-wysiwyg-editor/engine/index.d.ts +37 -0
  318. package/dist/src/nile-wysiwyg-editor/engine/index.js +29 -0
  319. package/dist/src/nile-wysiwyg-editor/engine/index.js.map +1 -0
  320. package/dist/src/nile-wysiwyg-editor/engine/inputrules.d.ts +12 -0
  321. package/dist/src/nile-wysiwyg-editor/engine/inputrules.js +144 -0
  322. package/dist/src/nile-wysiwyg-editor/engine/inputrules.js.map +1 -0
  323. package/dist/src/nile-wysiwyg-editor/engine/keymap.d.ts +15 -0
  324. package/dist/src/nile-wysiwyg-editor/engine/keymap.js +94 -0
  325. package/dist/src/nile-wysiwyg-editor/engine/keymap.js.map +1 -0
  326. package/dist/src/nile-wysiwyg-editor/engine/markdown-parse.d.ts +22 -0
  327. package/dist/src/nile-wysiwyg-editor/engine/markdown-parse.js +287 -0
  328. package/dist/src/nile-wysiwyg-editor/engine/markdown-parse.js.map +1 -0
  329. package/dist/src/nile-wysiwyg-editor/engine/markdown-parse.test.d.ts +1 -0
  330. package/dist/src/nile-wysiwyg-editor/engine/markdown-parse.test.js +106 -0
  331. package/dist/src/nile-wysiwyg-editor/engine/markdown-parse.test.js.map +1 -0
  332. package/dist/src/nile-wysiwyg-editor/engine/markdown.d.ts +10 -0
  333. package/dist/src/nile-wysiwyg-editor/engine/markdown.js +162 -0
  334. package/dist/src/nile-wysiwyg-editor/engine/markdown.js.map +1 -0
  335. package/dist/src/nile-wysiwyg-editor/engine/office-paste.d.ts +13 -0
  336. package/dist/src/nile-wysiwyg-editor/engine/office-paste.js +182 -0
  337. package/dist/src/nile-wysiwyg-editor/engine/office-paste.js.map +1 -0
  338. package/dist/src/nile-wysiwyg-editor/engine/plugins/code-highlight.d.ts +10 -0
  339. package/dist/src/nile-wysiwyg-editor/engine/plugins/code-highlight.js +165 -0
  340. package/dist/src/nile-wysiwyg-editor/engine/plugins/code-highlight.js.map +1 -0
  341. package/dist/src/nile-wysiwyg-editor/engine/plugins/embed-view.d.ts +17 -0
  342. package/dist/src/nile-wysiwyg-editor/engine/plugins/embed-view.js +69 -0
  343. package/dist/src/nile-wysiwyg-editor/engine/plugins/embed-view.js.map +1 -0
  344. package/dist/src/nile-wysiwyg-editor/engine/plugins/embeds.d.ts +17 -0
  345. package/dist/src/nile-wysiwyg-editor/engine/plugins/embeds.js +96 -0
  346. package/dist/src/nile-wysiwyg-editor/engine/plugins/embeds.js.map +1 -0
  347. package/dist/src/nile-wysiwyg-editor/engine/plugins/find-replace.d.ts +26 -0
  348. package/dist/src/nile-wysiwyg-editor/engine/plugins/find-replace.js +123 -0
  349. package/dist/src/nile-wysiwyg-editor/engine/plugins/find-replace.js.map +1 -0
  350. package/dist/src/nile-wysiwyg-editor/engine/plugins/format-painter.d.ts +28 -0
  351. package/dist/src/nile-wysiwyg-editor/engine/plugins/format-painter.js +72 -0
  352. package/dist/src/nile-wysiwyg-editor/engine/plugins/format-painter.js.map +1 -0
  353. package/dist/src/nile-wysiwyg-editor/engine/plugins/image-view.d.ts +41 -0
  354. package/dist/src/nile-wysiwyg-editor/engine/plugins/image-view.js +176 -0
  355. package/dist/src/nile-wysiwyg-editor/engine/plugins/image-view.js.map +1 -0
  356. package/dist/src/nile-wysiwyg-editor/engine/plugins/image.d.ts +15 -0
  357. package/dist/src/nile-wysiwyg-editor/engine/plugins/image.js +64 -0
  358. package/dist/src/nile-wysiwyg-editor/engine/plugins/image.js.map +1 -0
  359. package/dist/src/nile-wysiwyg-editor/engine/plugins/link.d.ts +11 -0
  360. package/dist/src/nile-wysiwyg-editor/engine/plugins/link.js +42 -0
  361. package/dist/src/nile-wysiwyg-editor/engine/plugins/link.js.map +1 -0
  362. package/dist/src/nile-wysiwyg-editor/engine/plugins/math-view.d.ts +18 -0
  363. package/dist/src/nile-wysiwyg-editor/engine/plugins/math-view.js +46 -0
  364. package/dist/src/nile-wysiwyg-editor/engine/plugins/math-view.js.map +1 -0
  365. package/dist/src/nile-wysiwyg-editor/engine/plugins/max-length.d.ts +7 -0
  366. package/dist/src/nile-wysiwyg-editor/engine/plugins/max-length.js +26 -0
  367. package/dist/src/nile-wysiwyg-editor/engine/plugins/max-length.js.map +1 -0
  368. package/dist/src/nile-wysiwyg-editor/engine/plugins/paste.d.ts +31 -0
  369. package/dist/src/nile-wysiwyg-editor/engine/plugins/paste.js +55 -0
  370. package/dist/src/nile-wysiwyg-editor/engine/plugins/paste.js.map +1 -0
  371. package/dist/src/nile-wysiwyg-editor/engine/plugins/placeholder.d.ts +7 -0
  372. package/dist/src/nile-wysiwyg-editor/engine/plugins/placeholder.js +25 -0
  373. package/dist/src/nile-wysiwyg-editor/engine/plugins/placeholder.js.map +1 -0
  374. package/dist/src/nile-wysiwyg-editor/engine/plugins/single-line.d.ts +10 -0
  375. package/dist/src/nile-wysiwyg-editor/engine/plugins/single-line.js +48 -0
  376. package/dist/src/nile-wysiwyg-editor/engine/plugins/single-line.js.map +1 -0
  377. package/dist/src/nile-wysiwyg-editor/engine/plugins/suggestions.d.ts +29 -0
  378. package/dist/src/nile-wysiwyg-editor/engine/plugins/suggestions.js +87 -0
  379. package/dist/src/nile-wysiwyg-editor/engine/plugins/suggestions.js.map +1 -0
  380. package/dist/src/nile-wysiwyg-editor/engine/plugins/tables.d.ts +8 -0
  381. package/dist/src/nile-wysiwyg-editor/engine/plugins/tables.js +11 -0
  382. package/dist/src/nile-wysiwyg-editor/engine/plugins/tables.js.map +1 -0
  383. package/dist/src/nile-wysiwyg-editor/engine/plugins/task-list.d.ts +16 -0
  384. package/dist/src/nile-wysiwyg-editor/engine/plugins/task-list.js +49 -0
  385. package/dist/src/nile-wysiwyg-editor/engine/plugins/task-list.js.map +1 -0
  386. package/dist/src/nile-wysiwyg-editor/engine/pm.test.d.ts +1 -0
  387. package/dist/src/nile-wysiwyg-editor/engine/pm.test.js +883 -0
  388. package/dist/src/nile-wysiwyg-editor/engine/pm.test.js.map +1 -0
  389. package/dist/src/nile-wysiwyg-editor/engine/productivity.test.d.ts +1 -0
  390. package/dist/src/nile-wysiwyg-editor/engine/productivity.test.js +129 -0
  391. package/dist/src/nile-wysiwyg-editor/engine/productivity.test.js.map +1 -0
  392. package/dist/src/nile-wysiwyg-editor/engine/sanitize.d.ts +13 -0
  393. package/dist/src/nile-wysiwyg-editor/engine/sanitize.js +155 -0
  394. package/dist/src/nile-wysiwyg-editor/engine/sanitize.js.map +1 -0
  395. package/dist/src/nile-wysiwyg-editor/engine/schema.d.ts +20 -0
  396. package/dist/src/nile-wysiwyg-editor/engine/schema.js +823 -0
  397. package/dist/src/nile-wysiwyg-editor/engine/schema.js.map +1 -0
  398. package/dist/src/nile-wysiwyg-editor/engine/selection-state.d.ts +70 -0
  399. package/dist/src/nile-wysiwyg-editor/engine/selection-state.js +138 -0
  400. package/dist/src/nile-wysiwyg-editor/engine/selection-state.js.map +1 -0
  401. package/dist/src/nile-wysiwyg-editor/engine/serializer.d.ts +18 -0
  402. package/dist/src/nile-wysiwyg-editor/engine/serializer.js +63 -0
  403. package/dist/src/nile-wysiwyg-editor/engine/serializer.js.map +1 -0
  404. package/dist/src/nile-wysiwyg-editor/index.d.ts +3 -0
  405. package/dist/src/nile-wysiwyg-editor/index.js +3 -0
  406. package/dist/src/nile-wysiwyg-editor/index.js.map +1 -0
  407. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.css.d.ts +1 -0
  408. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.css.js +782 -0
  409. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.css.js.map +1 -0
  410. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.d.ts +364 -0
  411. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.js +2038 -0
  412. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.js.map +1 -0
  413. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.test.d.ts +1 -0
  414. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.test.js +636 -0
  415. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.test.js.map +1 -0
  416. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.d.ts +1 -0
  417. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.js +2 -0
  418. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.js.map +1 -0
  419. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.css.d.ts +6 -0
  420. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.css.js +251 -0
  421. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.css.js.map +1 -0
  422. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.d.ts +41 -0
  423. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.js +700 -0
  424. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.js.map +1 -0
  425. package/dist/src/nile-wysiwyg-editor/types.d.ts +49 -0
  426. package/dist/src/nile-wysiwyg-editor/types.js +8 -0
  427. package/dist/src/nile-wysiwyg-editor/types.js.map +1 -0
  428. package/dist/src/nile-wysiwyg-editor/ui/bookmark-panel.d.ts +20 -0
  429. package/dist/src/nile-wysiwyg-editor/ui/bookmark-panel.js +159 -0
  430. package/dist/src/nile-wysiwyg-editor/ui/bookmark-panel.js.map +1 -0
  431. package/dist/src/nile-wysiwyg-editor/ui/bubble-menu.d.ts +21 -0
  432. package/dist/src/nile-wysiwyg-editor/ui/bubble-menu.js +125 -0
  433. package/dist/src/nile-wysiwyg-editor/ui/bubble-menu.js.map +1 -0
  434. package/dist/src/nile-wysiwyg-editor/ui/code-block-menu.d.ts +18 -0
  435. package/dist/src/nile-wysiwyg-editor/ui/code-block-menu.js +107 -0
  436. package/dist/src/nile-wysiwyg-editor/ui/code-block-menu.js.map +1 -0
  437. package/dist/src/nile-wysiwyg-editor/ui/embed-menu.d.ts +19 -0
  438. package/dist/src/nile-wysiwyg-editor/ui/embed-menu.js +123 -0
  439. package/dist/src/nile-wysiwyg-editor/ui/embed-menu.js.map +1 -0
  440. package/dist/src/nile-wysiwyg-editor/ui/embed-panel.d.ts +27 -0
  441. package/dist/src/nile-wysiwyg-editor/ui/embed-panel.js +146 -0
  442. package/dist/src/nile-wysiwyg-editor/ui/embed-panel.js.map +1 -0
  443. package/dist/src/nile-wysiwyg-editor/ui/emoji-picker.d.ts +21 -0
  444. package/dist/src/nile-wysiwyg-editor/ui/emoji-picker.js +154 -0
  445. package/dist/src/nile-wysiwyg-editor/ui/emoji-picker.js.map +1 -0
  446. package/dist/src/nile-wysiwyg-editor/ui/find-replace.d.ts +26 -0
  447. package/dist/src/nile-wysiwyg-editor/ui/find-replace.js +178 -0
  448. package/dist/src/nile-wysiwyg-editor/ui/find-replace.js.map +1 -0
  449. package/dist/src/nile-wysiwyg-editor/ui/image-menu.d.ts +18 -0
  450. package/dist/src/nile-wysiwyg-editor/ui/image-menu.js +129 -0
  451. package/dist/src/nile-wysiwyg-editor/ui/image-menu.js.map +1 -0
  452. package/dist/src/nile-wysiwyg-editor/ui/image-panel.d.ts +56 -0
  453. package/dist/src/nile-wysiwyg-editor/ui/image-panel.js +349 -0
  454. package/dist/src/nile-wysiwyg-editor/ui/image-panel.js.map +1 -0
  455. package/dist/src/nile-wysiwyg-editor/ui/insert-menu.d.ts +25 -0
  456. package/dist/src/nile-wysiwyg-editor/ui/insert-menu.js +142 -0
  457. package/dist/src/nile-wysiwyg-editor/ui/insert-menu.js.map +1 -0
  458. package/dist/src/nile-wysiwyg-editor/ui/link-editor.d.ts +30 -0
  459. package/dist/src/nile-wysiwyg-editor/ui/link-editor.js +189 -0
  460. package/dist/src/nile-wysiwyg-editor/ui/link-editor.js.map +1 -0
  461. package/dist/src/nile-wysiwyg-editor/ui/markdown-panel.d.ts +24 -0
  462. package/dist/src/nile-wysiwyg-editor/ui/markdown-panel.js +144 -0
  463. package/dist/src/nile-wysiwyg-editor/ui/markdown-panel.js.map +1 -0
  464. package/dist/src/nile-wysiwyg-editor/ui/math-panel.d.ts +31 -0
  465. package/dist/src/nile-wysiwyg-editor/ui/math-panel.js +172 -0
  466. package/dist/src/nile-wysiwyg-editor/ui/math-panel.js.map +1 -0
  467. package/dist/src/nile-wysiwyg-editor/ui/shortcut-help.d.ts +30 -0
  468. package/dist/src/nile-wysiwyg-editor/ui/shortcut-help.js +296 -0
  469. package/dist/src/nile-wysiwyg-editor/ui/shortcut-help.js.map +1 -0
  470. package/dist/src/nile-wysiwyg-editor/ui/source-view.d.ts +19 -0
  471. package/dist/src/nile-wysiwyg-editor/ui/source-view.js +120 -0
  472. package/dist/src/nile-wysiwyg-editor/ui/source-view.js.map +1 -0
  473. package/dist/src/nile-wysiwyg-editor/ui/special-chars.d.ts +20 -0
  474. package/dist/src/nile-wysiwyg-editor/ui/special-chars.js +199 -0
  475. package/dist/src/nile-wysiwyg-editor/ui/special-chars.js.map +1 -0
  476. package/dist/src/nile-wysiwyg-editor/ui/suggest-list.d.ts +31 -0
  477. package/dist/src/nile-wysiwyg-editor/ui/suggest-list.js +133 -0
  478. package/dist/src/nile-wysiwyg-editor/ui/suggest-list.js.map +1 -0
  479. package/dist/src/nile-wysiwyg-editor/ui/table-grid-picker.d.ts +23 -0
  480. package/dist/src/nile-wysiwyg-editor/ui/table-grid-picker.js +177 -0
  481. package/dist/src/nile-wysiwyg-editor/ui/table-grid-picker.js.map +1 -0
  482. package/dist/src/nile-wysiwyg-editor/ui/table-menu.d.ts +16 -0
  483. package/dist/src/nile-wysiwyg-editor/ui/table-menu.js +101 -0
  484. package/dist/src/nile-wysiwyg-editor/ui/table-menu.js.map +1 -0
  485. package/dist/src/version.js +1 -1
  486. package/dist/src/version.js.map +1 -1
  487. package/dist/tsconfig.tsbuildinfo +1 -1
  488. package/package.json +18 -2
  489. package/src/index.ts +57 -1
  490. package/src/internal/glyph.ts +13 -0
  491. package/src/nile-chip/nile-chip.css.ts +8 -1
  492. package/src/nile-code-editor/nile-code-editor.ts +3 -3
  493. package/src/nile-hero/nile-hero.css.ts +12 -12
  494. package/src/nile-hero/nile-hero.ts +1 -1
  495. package/src/nile-hero-header/nile-hero-header.css.ts +9 -9
  496. package/src/nile-hero-header/nile-hero-header.ts +1 -1
  497. package/src/nile-rich-text-editor/nile-rich-text-editor.css.ts +70 -0
  498. package/src/nile-rich-text-editor/nile-rich-text-editor.ts +89 -3
  499. package/src/nile-rich-text-editor/nile-rte-image.ts +1132 -0
  500. package/src/nile-wysiwyg-editor/emoji.ts +137 -0
  501. package/src/nile-wysiwyg-editor/engine/commands.ts +1035 -0
  502. package/src/nile-wysiwyg-editor/engine/create-state.ts +117 -0
  503. package/src/nile-wysiwyg-editor/engine/export.test.ts +113 -0
  504. package/src/nile-wysiwyg-editor/engine/export.ts +242 -0
  505. package/src/nile-wysiwyg-editor/engine/index.ts +69 -0
  506. package/src/nile-wysiwyg-editor/engine/inputrules.ts +169 -0
  507. package/src/nile-wysiwyg-editor/engine/keymap.ts +146 -0
  508. package/src/nile-wysiwyg-editor/engine/markdown-parse.test.ts +148 -0
  509. package/src/nile-wysiwyg-editor/engine/markdown-parse.ts +337 -0
  510. package/src/nile-wysiwyg-editor/engine/markdown.ts +165 -0
  511. package/src/nile-wysiwyg-editor/engine/office-paste.ts +199 -0
  512. package/src/nile-wysiwyg-editor/engine/plugins/code-highlight.ts +173 -0
  513. package/src/nile-wysiwyg-editor/engine/plugins/embed-view.ts +85 -0
  514. package/src/nile-wysiwyg-editor/engine/plugins/embeds.ts +99 -0
  515. package/src/nile-wysiwyg-editor/engine/plugins/find-replace.ts +155 -0
  516. package/src/nile-wysiwyg-editor/engine/plugins/format-painter.ts +80 -0
  517. package/src/nile-wysiwyg-editor/engine/plugins/image-view.ts +220 -0
  518. package/src/nile-wysiwyg-editor/engine/plugins/image.ts +80 -0
  519. package/src/nile-wysiwyg-editor/engine/plugins/link.ts +42 -0
  520. package/src/nile-wysiwyg-editor/engine/plugins/math-view.ts +56 -0
  521. package/src/nile-wysiwyg-editor/engine/plugins/max-length.ts +24 -0
  522. package/src/nile-wysiwyg-editor/engine/plugins/paste.ts +74 -0
  523. package/src/nile-wysiwyg-editor/engine/plugins/placeholder.ts +24 -0
  524. package/src/nile-wysiwyg-editor/engine/plugins/single-line.ts +47 -0
  525. package/src/nile-wysiwyg-editor/engine/plugins/suggestions.ts +110 -0
  526. package/src/nile-wysiwyg-editor/engine/plugins/tables.ts +12 -0
  527. package/src/nile-wysiwyg-editor/engine/plugins/task-list.ts +65 -0
  528. package/src/nile-wysiwyg-editor/engine/pm.test.ts +1088 -0
  529. package/src/nile-wysiwyg-editor/engine/productivity.test.ts +163 -0
  530. package/src/nile-wysiwyg-editor/engine/sanitize.ts +156 -0
  531. package/src/nile-wysiwyg-editor/engine/schema.ts +859 -0
  532. package/src/nile-wysiwyg-editor/engine/selection-state.ts +210 -0
  533. package/src/nile-wysiwyg-editor/engine/serializer.ts +78 -0
  534. package/src/nile-wysiwyg-editor/index.ts +3 -0
  535. package/src/nile-wysiwyg-editor/nile-wysiwyg-editor.css.ts +782 -0
  536. package/src/nile-wysiwyg-editor/nile-wysiwyg-editor.test.ts +750 -0
  537. package/src/nile-wysiwyg-editor/nile-wysiwyg-editor.ts +2155 -0
  538. package/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.ts +1 -0
  539. package/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.css.ts +251 -0
  540. package/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.ts +772 -0
  541. package/src/nile-wysiwyg-editor/types.ts +83 -0
  542. package/src/nile-wysiwyg-editor/ui/bookmark-panel.ts +155 -0
  543. package/src/nile-wysiwyg-editor/ui/bubble-menu.ts +135 -0
  544. package/src/nile-wysiwyg-editor/ui/code-block-menu.ts +105 -0
  545. package/src/nile-wysiwyg-editor/ui/embed-menu.ts +133 -0
  546. package/src/nile-wysiwyg-editor/ui/embed-panel.ts +143 -0
  547. package/src/nile-wysiwyg-editor/ui/emoji-picker.ts +152 -0
  548. package/src/nile-wysiwyg-editor/ui/find-replace.ts +174 -0
  549. package/src/nile-wysiwyg-editor/ui/image-menu.ts +140 -0
  550. package/src/nile-wysiwyg-editor/ui/image-panel.ts +337 -0
  551. package/src/nile-wysiwyg-editor/ui/insert-menu.ts +142 -0
  552. package/src/nile-wysiwyg-editor/ui/link-editor.ts +180 -0
  553. package/src/nile-wysiwyg-editor/ui/markdown-panel.ts +143 -0
  554. package/src/nile-wysiwyg-editor/ui/math-panel.ts +169 -0
  555. package/src/nile-wysiwyg-editor/ui/shortcut-help.ts +311 -0
  556. package/src/nile-wysiwyg-editor/ui/source-view.ts +119 -0
  557. package/src/nile-wysiwyg-editor/ui/special-chars.ts +209 -0
  558. package/src/nile-wysiwyg-editor/ui/suggest-list.ts +138 -0
  559. package/src/nile-wysiwyg-editor/ui/table-grid-picker.ts +173 -0
  560. package/src/nile-wysiwyg-editor/ui/table-menu.ts +109 -0
  561. package/vscode-html-custom-data.json +491 -1
  562. package/web-dev-server.config.mjs +6 -2
  563. package/dist/index-5fef1a0d.esm.js +0 -1
  564. package/dist/index-8f38fae3.cjs.js +0 -2
  565. package/dist/index-8f38fae3.cjs.js.map +0 -1
@@ -0,0 +1,1132 @@
1
+ import { LitElement, html } from 'lit';
2
+ import { customElement, property, state } from 'lit/decorators.js';
3
+
4
+ @customElement('nile-rte-image')
5
+ export class NileRteImage extends LitElement {
6
+ protected createRenderRoot() {
7
+ return this;
8
+ }
9
+
10
+ @property({ attribute: false }) editorEl!: HTMLElement;
11
+ @property({ type: Boolean, reflect: true, attribute: true }) disabled = false;
12
+ @property({ type: String, reflect: true, attribute: true }) label = 'Image';
13
+ @property({ type: String, reflect: true, attribute: true }) placeholder = 'Paste image link here';
14
+ @property({ type: String, reflect: true, attribute: true }) altPlaceholder = 'Describe the image';
15
+ @property({ type: String, reflect: true, attribute: true }) captionPlaceholder = 'Add a caption (optional)';
16
+ @property({ type: Number, reflect: true, attribute: 'maxfilesize' }) maxFileSize = 2 * 1024 * 1024;
17
+ @property({ type: Boolean, reflect: true, attribute: 'uploadfromcomputer' }) uploadFromComputer = false;
18
+
19
+ @state() private srcValue = '';
20
+ @state() private altValue = '';
21
+ @state() private captionValue = '';
22
+ @state() private hasActiveImage = false;
23
+ @state() private uploadedFileName = '';
24
+ @state() private errorMessage = '';
25
+ @state() private popoverStyle = '';
26
+
27
+ private selectionRange: Range | null = null;
28
+ private activeFigure: HTMLElement | null = null;
29
+
30
+ private ignoreBlur = false;
31
+ private isApplying = false;
32
+
33
+ private selectedFigure: HTMLElement | null = null;
34
+ private resizeOverlay: HTMLElement | null = null;
35
+ private dragStartX = 0;
36
+ private dragStartWidth = 0;
37
+ private dragDir = '';
38
+ private isDragging = false;
39
+ private trackingRaf = 0;
40
+
41
+ connectedCallback() {
42
+ super.connectedCallback();
43
+
44
+ this.injectCss(`
45
+ nile-popover.rte-image-popover::part(popover) {
46
+ min-width: 340px;
47
+ max-width: 420px;
48
+ background: white;
49
+ border: 1px solid var(--nile-colors-neutral-400, var(--ng-componentcolors-utility-gray-400));
50
+ border-radius: 8px;
51
+ padding: 0;
52
+ gap: 0;
53
+ overflow: hidden;
54
+ height: auto;
55
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
56
+ }
57
+
58
+ .image-popup-wrap {
59
+ display: flex;
60
+ flex-direction: column;
61
+ gap: 12px;
62
+ padding: 12px;
63
+ }
64
+
65
+ .image-popup-wrap nile-input {
66
+ width: 100%;
67
+ }
68
+
69
+ .image-popup-wrap .image-upload-row {
70
+ display: flex;
71
+ align-items: center;
72
+ justify-content: center;
73
+ gap: 8px;
74
+ width: 100%;
75
+ }
76
+
77
+ .image-popup-wrap .image-upload-row nile-button {
78
+ flex-shrink: 0;
79
+ }
80
+
81
+ .image-popup-wrap .image-upload-filename {
82
+ font-size: 12px;
83
+ color: var(--nile-colors-neutral-600, var(--ng-colors-text-secondary));
84
+ overflow: hidden;
85
+ text-overflow: ellipsis;
86
+ white-space: nowrap;
87
+ min-width: 0;
88
+ }
89
+
90
+ .image-popup-wrap .image-error {
91
+ font-size: 12px;
92
+ color: var(--nile-colors-error-600, var(--ng-colors-text-error-primary-600));
93
+ }
94
+
95
+ .image-popup-wrap .image-divider-row {
96
+ display: flex;
97
+ align-items: center;
98
+ gap: 8px;
99
+ color: var(--nile-colors-neutral-500, var(--ng-colors-text-secondary));
100
+ font-size: 12px;
101
+ }
102
+
103
+ .image-popup-wrap .image-divider-row::before,
104
+ .image-popup-wrap .image-divider-row::after {
105
+ content: '';
106
+ flex: 1;
107
+ height: 1px;
108
+ background: var(--nile-colors-neutral-400, var(--ng-colors-border-neutral));
109
+ }
110
+
111
+ .image-popup-wrap .image-actions-row {
112
+ display: flex;
113
+ justify-content: flex-end;
114
+ gap: 8px;
115
+ width: 100%;
116
+ }
117
+
118
+ nile-button.rte-image-button::part(base) {
119
+ border: none;
120
+ height: 32px;
121
+ width: 32px;
122
+ }
123
+
124
+ nile-rte-image input[type='file'] {
125
+ display: none;
126
+ }
127
+
128
+ .rte-image-resize-overlay {
129
+ position: fixed;
130
+ z-index: 999;
131
+ pointer-events: none;
132
+ border: 2px solid var(--nile-colors-primary-500, var(--ng-componentcolors-utility-blue-500));
133
+ border-radius: var(--nile-radius-radius-lg, var(--ng-radius-md));
134
+ box-sizing: border-box;
135
+ }
136
+
137
+ .rte-image-resize-overlay .rte-resize-handle {
138
+ position: absolute;
139
+ width: 12px;
140
+ height: 12px;
141
+ background: var(--nile-colors-white-base, #fff);
142
+ border: 2px solid var(--nile-colors-primary-500, var(--ng-componentcolors-utility-blue-500));
143
+ border-radius: 50%;
144
+ pointer-events: auto;
145
+ box-sizing: border-box;
146
+ }
147
+
148
+ .rte-image-resize-overlay .rte-resize-handle[data-dir='nw'] { top: -7px; left: -7px; cursor: nwse-resize; }
149
+ .rte-image-resize-overlay .rte-resize-handle[data-dir='ne'] { top: -7px; right: -7px; cursor: nesw-resize; }
150
+ .rte-image-resize-overlay .rte-resize-handle[data-dir='sw'] { bottom: -7px; left: -7px; cursor: nesw-resize; }
151
+ .rte-image-resize-overlay .rte-resize-handle[data-dir='se'] { bottom: -7px; right: -7px; cursor: nwse-resize; }
152
+
153
+ .rte-image-resize-overlay .rte-image-align-bar {
154
+ position: absolute;
155
+ top: -44px;
156
+ left: 50%;
157
+ transform: translateX(-50%);
158
+ display: flex;
159
+ gap: 2px;
160
+ padding: 4px;
161
+ background: var(--nile-colors-white-base, #fff);
162
+ border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-neutral));
163
+ border-radius: 8px;
164
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
165
+ pointer-events: auto;
166
+ }
167
+
168
+ .rte-image-resize-overlay .rte-image-align-bar button {
169
+ display: flex;
170
+ align-items: center;
171
+ justify-content: center;
172
+ width: 28px;
173
+ height: 28px;
174
+ border: none;
175
+ background: transparent;
176
+ border-radius: 6px;
177
+ cursor: pointer;
178
+ padding: 0;
179
+ }
180
+
181
+ .rte-image-resize-overlay .rte-image-align-bar button:hover {
182
+ background: var(--nile-colors-neutral-200, var(--ng-componentcolors-utility-gray-200));
183
+ }
184
+
185
+ .rte-image-resize-overlay .rte-image-align-bar button[data-active] {
186
+ background: var(--nile-colors-primary-400, var(--ng-componentcolors-utility-blue-400));
187
+ }
188
+
189
+ .rte-image-resize-overlay .rte-image-align-bar button nile-icon {
190
+ pointer-events: none;
191
+ }
192
+
193
+ .rte-image-resize-overlay .rte-resize-size-label {
194
+ position: absolute;
195
+ bottom: -26px;
196
+ right: 0;
197
+ background: var(--nile-colors-dark-900, #101828);
198
+ color: #fff;
199
+ font-size: 11px;
200
+ line-height: 1;
201
+ padding: 4px 6px;
202
+ border-radius: 4px;
203
+ white-space: nowrap;
204
+ pointer-events: none;
205
+ }
206
+ `);
207
+ }
208
+
209
+ private injectCss(cssText: string) {
210
+ if (this.querySelector('style[data-rte-image-style]')) return;
211
+ const style = document.createElement('style');
212
+ style.setAttribute('data-rte-image-style', 'true');
213
+ style.textContent = cssText;
214
+ this.insertBefore(style, this.firstChild);
215
+ }
216
+
217
+ protected updated(changed: Map<string, any>) {
218
+ if (changed.has('editorEl')) {
219
+ const prev = changed.get('editorEl') as HTMLElement | undefined;
220
+ prev?.removeEventListener('click', this.onEditorImageClick);
221
+ prev?.removeEventListener('dblclick', this.onEditorImageDblClick);
222
+ prev?.removeEventListener('input', this.onEditorInput);
223
+ prev?.removeEventListener('paste', this.onEditorImagePaste);
224
+ this.editorEl?.addEventListener('click', this.onEditorImageClick);
225
+ this.editorEl?.addEventListener('dblclick', this.onEditorImageDblClick);
226
+ this.editorEl?.addEventListener('input', this.onEditorInput);
227
+ this.editorEl?.addEventListener('paste', this.onEditorImagePaste);
228
+ }
229
+ if (changed.has('disabled') && this.disabled) {
230
+ this.deselectImage();
231
+ }
232
+ }
233
+
234
+ disconnectedCallback(): void {
235
+ this.editorEl?.removeEventListener('click', this.onEditorImageClick);
236
+ this.editorEl?.removeEventListener('dblclick', this.onEditorImageDblClick);
237
+ this.editorEl?.removeEventListener('input', this.onEditorInput);
238
+ this.editorEl?.removeEventListener('paste', this.onEditorImagePaste);
239
+ window.removeEventListener('scroll', this.onScroll, true);
240
+ this.deselectImage();
241
+ super.disconnectedCallback();
242
+ }
243
+
244
+ private onEditorInput = () => {
245
+ // content edits can remove or reflow the figure
246
+ if (this.selectedFigure && !this.selectedFigure.isConnected) {
247
+ this.deselectImage();
248
+ } else {
249
+ this.updateOverlayPosition();
250
+ }
251
+ };
252
+
253
+ private onEditorImagePaste = (e: ClipboardEvent) => {
254
+ if (this.disabled) return;
255
+
256
+ const items = Array.from(e.clipboardData?.items ?? []);
257
+ const imageFiles = items
258
+ .filter(i => i.kind === 'file' && i.type.startsWith('image/'))
259
+ .map(i => i.getAsFile())
260
+ .filter((f): f is File => !!f);
261
+ if (!imageFiles.length) return;
262
+
263
+ e.preventDefault();
264
+ e.stopPropagation();
265
+
266
+ for (const file of imageFiles) {
267
+ if (this.maxFileSize > 0 && file.size > this.maxFileSize) {
268
+ console.warn(
269
+ `nile-rte-image: pasted image "${file.name}" skipped — exceeds the ${this.maxFileSize} byte limit`
270
+ );
271
+ continue;
272
+ }
273
+ const reader = new FileReader();
274
+ reader.onload = () => {
275
+ this.insertPastedImage(
276
+ String(reader.result || ''),
277
+ file.name.replace(/\.[^.]+$/, '')
278
+ );
279
+ };
280
+ reader.readAsDataURL(file);
281
+ }
282
+ };
283
+
284
+ private insertPastedImage(src: string, alt: string) {
285
+ if (!src.startsWith('data:image/')) return;
286
+
287
+ let range: Range;
288
+ const sel = document.getSelection();
289
+ if (
290
+ sel &&
291
+ sel.rangeCount > 0 &&
292
+ this.editorEl.contains(sel.getRangeAt(0).commonAncestorContainer)
293
+ ) {
294
+ range = sel.getRangeAt(0).cloneRange();
295
+ } else {
296
+ range = document.createRange();
297
+ range.selectNodeContents(this.editorEl);
298
+ range.collapse(false);
299
+ }
300
+
301
+ const figure = this.buildFigure(src, alt);
302
+ this.insertFigureAt(range, figure);
303
+ this.emit(src);
304
+ }
305
+
306
+ private isSafeSrc(src: string): boolean {
307
+ return /^(https?:\/\/|data:image\/|blob:|\/)/i.test(src);
308
+ }
309
+
310
+ private normalizeSrc(src: string): string {
311
+ if (this.isSafeSrc(src)) return src;
312
+ if (/^[a-z][a-z0-9+.-]*:/i.test(src)) return '';
313
+ return `https://${src}`;
314
+ }
315
+
316
+ private getSelectionRect(): DOMRect | null {
317
+ if (!this.selectionRange) return null;
318
+
319
+ let rect = this.selectionRange.getBoundingClientRect();
320
+ if (rect.width === 0 && rect.height === 0) {
321
+ const span = document.createElement('span');
322
+ span.textContent = '\u200b';
323
+ const tempRange = this.selectionRange.cloneRange();
324
+ tempRange.insertNode(span);
325
+ rect = span.getBoundingClientRect();
326
+ span.remove();
327
+ }
328
+ return rect;
329
+ }
330
+
331
+ private positionPopover(anchorRect?: DOMRect | null) {
332
+ const rect = anchorRect ?? this.getSelectionRect();
333
+ if (!rect) return;
334
+
335
+ const half = 170;
336
+ const centerX = Math.min(
337
+ Math.max(rect.left + rect.width / 2, half + 8),
338
+ window.innerWidth - half - 8
339
+ );
340
+
341
+ this.popoverStyle = `
342
+ position: fixed;
343
+ top: ${rect.bottom + 8}px;
344
+ left: ${centerX}px;
345
+ transform: translateX(-50%);
346
+ z-index: 1000;
347
+ `;
348
+ }
349
+
350
+ private onScroll = () => {
351
+ this.closePopover();
352
+ };
353
+
354
+ private openPopover() {
355
+ requestAnimationFrame(() => {
356
+ const pop = this.querySelector('nile-popover') as any;
357
+ pop && (pop.isShow = true);
358
+ window.addEventListener('scroll', this.onScroll, true);
359
+ });
360
+ }
361
+
362
+ private closePopover() {
363
+ const pop = this.querySelector('nile-popover') as any;
364
+ pop && (pop.isShow = false);
365
+
366
+ window.removeEventListener('scroll', this.onScroll, true);
367
+
368
+ this.srcValue = '';
369
+ this.altValue = '';
370
+ this.captionValue = '';
371
+ this.uploadedFileName = '';
372
+ this.errorMessage = '';
373
+ this.selectionRange = null;
374
+ this.activeFigure = null;
375
+ this.hasActiveImage = false;
376
+ this.popoverStyle = '';
377
+ }
378
+
379
+ private onEditorImageClick = (e: MouseEvent) => {
380
+ if (this.disabled) return;
381
+ const target = e.target as HTMLElement;
382
+ const figure = target.closest?.('figure.rte-image') as HTMLElement | null;
383
+ if (!figure || !this.editorEl.contains(figure)) {
384
+ this.deselectImage();
385
+ return;
386
+ }
387
+
388
+ e.preventDefault();
389
+ this.selectImage(figure);
390
+ };
391
+
392
+ private onEditorImageDblClick = (e: MouseEvent) => {
393
+ if (this.disabled) return;
394
+ const target = e.target as HTMLElement;
395
+ const figure = target.closest?.('figure.rte-image') as HTMLElement | null;
396
+ if (!figure || !this.editorEl.contains(figure)) return;
397
+
398
+ e.preventDefault();
399
+ this.openEditFor(figure);
400
+ };
401
+
402
+ private openEditFor(figure: HTMLElement, anchorRect?: DOMRect | null) {
403
+ const range = document.createRange();
404
+ range.selectNode(figure);
405
+ this.selectionRange = range;
406
+
407
+ this.activeFigure = figure;
408
+ this.hasActiveImage = true;
409
+
410
+ const img = figure.querySelector('img');
411
+ const figcaption = figure.querySelector('figcaption');
412
+ this.srcValue = img?.getAttribute('src') || '';
413
+ this.altValue = img?.getAttribute('alt') || '';
414
+ this.captionValue = figcaption?.textContent || '';
415
+ this.uploadedFileName = '';
416
+ this.errorMessage = '';
417
+
418
+ this.positionPopover(anchorRect ?? figure.getBoundingClientRect());
419
+ this.openPopover();
420
+ }
421
+
422
+ private getToolbarButtonRect(): DOMRect | null {
423
+ const btn = this.querySelector('nile-button.rte-image-button');
424
+ return btn ? btn.getBoundingClientRect() : null;
425
+ }
426
+
427
+ // ---------- resize ----------
428
+
429
+ private selectImage(figure: HTMLElement) {
430
+ if (this.selectedFigure === figure) {
431
+ this.updateOverlayPosition();
432
+ return;
433
+ }
434
+ this.deselectImage();
435
+ this.selectedFigure = figure;
436
+
437
+ const img = figure.querySelector('img');
438
+ if (img && !img.complete) {
439
+ img.addEventListener('load', this.onSelectedImageLoad, { once: true });
440
+ }
441
+
442
+ this.buildOverlay();
443
+ this.syncAlignBar();
444
+ this.updateOverlayPosition();
445
+ this.startOverlayTracking();
446
+
447
+ document.addEventListener('mousedown', this.onDocMousedown, true);
448
+ document.addEventListener('keydown', this.onDocKeydown, true);
449
+ }
450
+
451
+ private deselectImage() {
452
+ if (!this.selectedFigure && !this.resizeOverlay) return;
453
+ this.selectedFigure = null;
454
+ this.resizeOverlay?.remove();
455
+ this.resizeOverlay = null;
456
+ this.isDragging = false;
457
+ this.stopOverlayTracking();
458
+
459
+ document.removeEventListener('mousedown', this.onDocMousedown, true);
460
+ document.removeEventListener('keydown', this.onDocKeydown, true);
461
+ document.removeEventListener('mousemove', this.onDragMove);
462
+ document.removeEventListener('mouseup', this.onDragEnd);
463
+ }
464
+
465
+ private onDocKeydown = (e: KeyboardEvent) => {
466
+ if (!this.selectedFigure) return;
467
+
468
+ if (e.key === 'Escape') {
469
+ this.deselectImage();
470
+ return;
471
+ }
472
+ if (e.key !== 'Backspace' && e.key !== 'Delete') return;
473
+
474
+ // don't hijack deletions typed into inputs (e.g. the edit popover)
475
+ const target = e.target as HTMLElement;
476
+ if (target?.closest?.('input, textarea, nile-input, nile-popover')) return;
477
+
478
+ e.preventDefault();
479
+ e.stopPropagation();
480
+
481
+ const figure = this.selectedFigure;
482
+ this.deselectImage();
483
+ const parent = figure.parentNode;
484
+ figure.remove();
485
+ if (parent instanceof HTMLElement && !parent.hasChildNodes()) {
486
+ parent.innerHTML = '<br>';
487
+ }
488
+ this.emit('');
489
+ };
490
+
491
+ private onSelectedImageLoad = () => {
492
+ this.updateOverlayPosition();
493
+ };
494
+
495
+ // re-sync the overlay to the image every frame while selected — this keeps
496
+ // it glued to the image through scrolling (any container), layout shifts,
497
+ // and image loads without needing to enumerate those events
498
+ private startOverlayTracking() {
499
+ this.stopOverlayTracking();
500
+ const tick = () => {
501
+ if (!this.selectedFigure || !this.resizeOverlay) return;
502
+ if (!this.selectedFigure.isConnected) {
503
+ this.deselectImage();
504
+ return;
505
+ }
506
+ this.updateOverlayPosition();
507
+ this.trackingRaf = requestAnimationFrame(tick);
508
+ };
509
+ this.trackingRaf = requestAnimationFrame(tick);
510
+ }
511
+
512
+ private stopOverlayTracking() {
513
+ if (this.trackingRaf !== 0) {
514
+ cancelAnimationFrame(this.trackingRaf);
515
+ this.trackingRaf = 0;
516
+ }
517
+ }
518
+
519
+ private onDocMousedown = (e: MouseEvent) => {
520
+ const target = e.target as HTMLElement;
521
+ if (this.resizeOverlay?.contains(target)) return;
522
+ if (this.selectedFigure?.contains(target)) return;
523
+ // clicks on our own UI (toolbar image button, popover) must not clear the
524
+ // selection, otherwise pressing the toolbar button while an image is
525
+ // selected would drop into insert mode instead of edit mode
526
+ if (this.contains(target)) return;
527
+ this.deselectImage();
528
+ };
529
+
530
+ private buildOverlay() {
531
+ const overlay = document.createElement('div');
532
+ overlay.className = 'rte-image-resize-overlay';
533
+
534
+ for (const dir of ['nw', 'ne', 'sw', 'se']) {
535
+ const handle = document.createElement('div');
536
+ handle.className = 'rte-resize-handle';
537
+ handle.dataset.dir = dir;
538
+ handle.addEventListener('mousedown', this.onHandleMousedown);
539
+ overlay.appendChild(handle);
540
+ }
541
+
542
+ const label = document.createElement('span');
543
+ label.className = 'rte-resize-size-label';
544
+ overlay.appendChild(label);
545
+
546
+ const alignBar = document.createElement('div');
547
+ alignBar.className = 'rte-image-align-bar';
548
+ const alignments: Array<{ dir: string; icon: string; title: string }> = [
549
+ { dir: 'left', icon: 'format_align_left', title: 'Align left' },
550
+ { dir: 'center', icon: 'format_align_middle', title: 'Align center' },
551
+ { dir: 'right', icon: 'format_align_right', title: 'Align right' },
552
+ { dir: 'justify', icon: 'format_align_justify', title: 'Full width' },
553
+ ];
554
+ for (const { dir, icon, title } of alignments) {
555
+ const btn = document.createElement('button');
556
+ btn.type = 'button';
557
+ btn.dataset.dir = dir;
558
+ btn.title = title;
559
+ btn.setAttribute('aria-label', title);
560
+ btn.innerHTML = `<nile-icon name="${icon}" size="18"></nile-icon>`;
561
+ btn.addEventListener('mousedown', e => e.preventDefault());
562
+ btn.addEventListener('click', this.onAlignClick);
563
+ alignBar.appendChild(btn);
564
+ }
565
+ overlay.appendChild(alignBar);
566
+
567
+ // append to <body>: a transformed/filtered ancestor (drawer, modal,
568
+ // animated panel) would otherwise become the containing block for
569
+ // position:fixed and the overlay would render far from the image
570
+ document.body.appendChild(overlay);
571
+ this.resizeOverlay = overlay;
572
+ }
573
+
574
+ private updateOverlayPosition() {
575
+ if (!this.resizeOverlay || !this.selectedFigure) return;
576
+ const img = this.selectedFigure.querySelector('img');
577
+ if (!img) {
578
+ this.deselectImage();
579
+ return;
580
+ }
581
+ const rect = img.getBoundingClientRect();
582
+ this.resizeOverlay.style.top = `${rect.top}px`;
583
+ this.resizeOverlay.style.left = `${rect.left}px`;
584
+ this.resizeOverlay.style.width = `${rect.width}px`;
585
+ this.resizeOverlay.style.height = `${rect.height}px`;
586
+
587
+ // keep the align bar reachable: above the image by default, flipped to
588
+ // just inside the top edge when the image touches the viewport top
589
+ const bar = this.resizeOverlay.querySelector(
590
+ '.rte-image-align-bar'
591
+ ) as HTMLElement | null;
592
+ if (bar) {
593
+ if (rect.top < 56) {
594
+ bar.style.top = '8px';
595
+ } else {
596
+ bar.style.top = '-44px';
597
+ }
598
+ }
599
+
600
+ const label = this.resizeOverlay.querySelector(
601
+ '.rte-resize-size-label'
602
+ ) as HTMLElement | null;
603
+ if (label) {
604
+ label.textContent = `${Math.round(rect.width)} × ${Math.round(rect.height)}`;
605
+ label.style.display = this.isDragging ? '' : 'none';
606
+ }
607
+ }
608
+
609
+ private onAlignClick = (e: Event) => {
610
+ if (!this.selectedFigure) return;
611
+ const dir = (e.currentTarget as HTMLElement).dataset.dir || 'left';
612
+
613
+ if (dir === 'left') {
614
+ this.selectedFigure.removeAttribute('data-align');
615
+ } else {
616
+ this.selectedFigure.setAttribute('data-align', dir);
617
+ }
618
+ this.syncAlignBar();
619
+ this.updateOverlayPosition();
620
+
621
+ const img = this.selectedFigure.querySelector('img');
622
+ this.emit(img?.getAttribute('src') || '');
623
+ };
624
+
625
+ private syncAlignBar() {
626
+ if (!this.resizeOverlay || !this.selectedFigure) return;
627
+ const current = this.selectedFigure.getAttribute('data-align') || 'left';
628
+ this.resizeOverlay
629
+ .querySelectorAll<HTMLElement>('.rte-image-align-bar button')
630
+ .forEach(btn => {
631
+ btn.toggleAttribute('data-active', btn.dataset.dir === current);
632
+ });
633
+ }
634
+
635
+ private onHandleMousedown = (e: MouseEvent) => {
636
+ if (this.disabled || !this.selectedFigure) return;
637
+ e.preventDefault();
638
+ e.stopPropagation();
639
+
640
+ const img = this.selectedFigure.querySelector('img');
641
+ if (!img) return;
642
+
643
+ // a full-width image can't be hand-resized — dragging implies a custom
644
+ // width, so drop back to default alignment first
645
+ if (this.selectedFigure.getAttribute('data-align') === 'justify') {
646
+ this.selectedFigure.removeAttribute('data-align');
647
+ this.syncAlignBar();
648
+ }
649
+
650
+ this.isDragging = true;
651
+ this.dragDir = (e.currentTarget as HTMLElement).dataset.dir || 'se';
652
+ this.dragStartX = e.clientX;
653
+ this.dragStartWidth = img.getBoundingClientRect().width;
654
+
655
+ document.addEventListener('mousemove', this.onDragMove);
656
+ document.addEventListener('mouseup', this.onDragEnd);
657
+ };
658
+
659
+ private onDragMove = (e: MouseEvent) => {
660
+ if (!this.isDragging || !this.selectedFigure) return;
661
+ const img = this.selectedFigure.querySelector('img');
662
+ if (!img) return;
663
+
664
+ const dx = e.clientX - this.dragStartX;
665
+ const growsRight = this.dragDir === 'ne' || this.dragDir === 'se';
666
+ let width = this.dragStartWidth + (growsRight ? dx : -dx);
667
+
668
+ const maxWidth = this.getEditorContentWidth();
669
+ width = Math.max(48, Math.min(width, maxWidth));
670
+
671
+ img.setAttribute('width', String(Math.round(width)));
672
+ this.updateOverlayPosition();
673
+ };
674
+
675
+ private onDragEnd = () => {
676
+ if (!this.isDragging) return;
677
+ this.isDragging = false;
678
+ document.removeEventListener('mousemove', this.onDragMove);
679
+ document.removeEventListener('mouseup', this.onDragEnd);
680
+ this.updateOverlayPosition();
681
+
682
+ const img = this.selectedFigure?.querySelector('img');
683
+ this.dispatchEvent(
684
+ new CustomEvent('nile-image-changed', {
685
+ detail: {
686
+ src: img?.getAttribute('src') || '',
687
+ alt: img?.getAttribute('alt') || '',
688
+ caption:
689
+ this.selectedFigure?.querySelector('figcaption')?.textContent || '',
690
+ width: img ? Number(img.getAttribute('width')) || null : null,
691
+ },
692
+ bubbles: true,
693
+ composed: true,
694
+ })
695
+ );
696
+ };
697
+
698
+ private getEditorContentWidth(): number {
699
+ const style = getComputedStyle(this.editorEl);
700
+ return (
701
+ this.editorEl.clientWidth -
702
+ parseFloat(style.paddingLeft || '0') -
703
+ parseFloat(style.paddingRight || '0') || Infinity
704
+ );
705
+ }
706
+
707
+ private onOpen = () => {
708
+ if (this.disabled) return;
709
+
710
+ if (this.selectedFigure) {
711
+ this.openEditFor(this.selectedFigure, this.getToolbarButtonRect());
712
+ return;
713
+ }
714
+
715
+ const sel = document.getSelection();
716
+ if (
717
+ sel &&
718
+ sel.rangeCount > 0 &&
719
+ this.editorEl.contains(sel.getRangeAt(0).commonAncestorContainer)
720
+ ) {
721
+ this.selectionRange = sel.getRangeAt(0).cloneRange();
722
+ } else {
723
+ const range = document.createRange();
724
+ range.selectNodeContents(this.editorEl);
725
+ range.collapse(false);
726
+ this.selectionRange = range;
727
+ }
728
+
729
+ this.activeFigure = null;
730
+ this.hasActiveImage = false;
731
+ this.srcValue = '';
732
+ this.altValue = '';
733
+ this.captionValue = '';
734
+ this.uploadedFileName = '';
735
+ this.errorMessage = '';
736
+ this.positionPopover(this.getToolbarButtonRect());
737
+ this.openPopover();
738
+
739
+ requestAnimationFrame(() => {
740
+ const input = this.querySelector('nile-input');
741
+ (input as any)?.focus();
742
+ });
743
+ };
744
+
745
+ private onInputKeydown = (e: KeyboardEvent) => {
746
+ if (e.key !== 'Escape' && e.key !== 'Enter') return;
747
+ e.preventDefault();
748
+ e.stopPropagation();
749
+ if (e.key === 'Escape') {
750
+ this.closePopover();
751
+ return;
752
+ }
753
+ this.isApplying = true;
754
+ try {
755
+ this.applyImage();
756
+ } finally {
757
+ this.isApplying = false;
758
+ }
759
+ };
760
+
761
+ private onInputBlur = () => {
762
+ if (this.ignoreBlur || this.isApplying) return;
763
+ requestAnimationFrame(() => {
764
+ if (this.ignoreBlur || this.isApplying) return;
765
+ const pop = this.querySelector('nile-popover');
766
+ if (pop?.matches(':focus-within')) return;
767
+ this.closePopover();
768
+ });
769
+ };
770
+
771
+ private onSrcInput = (e: CustomEvent) => {
772
+ this.srcValue = e.detail.value;
773
+ this.uploadedFileName = '';
774
+ this.errorMessage = '';
775
+ };
776
+
777
+ private onAltInput = (e: CustomEvent) => {
778
+ this.altValue = e.detail.value;
779
+ };
780
+
781
+ private onCaptionInput = (e: CustomEvent) => {
782
+ this.captionValue = e.detail.value;
783
+ };
784
+
785
+ private onPopoverMousedown = () => {
786
+ this.ignoreBlur = true;
787
+ };
788
+
789
+ private onPopoverMouseup = () => {
790
+ this.ignoreBlur = false;
791
+ };
792
+
793
+ private onToolbarButtonMousedown = (e: Event) => {
794
+ e.preventDefault();
795
+ };
796
+
797
+ private onUploadClick = () => {
798
+ // keep the popover open while the OS file dialog steals focus
799
+ this.ignoreBlur = true;
800
+ const fileInput = this.querySelector(
801
+ 'input[type="file"]'
802
+ ) as HTMLInputElement | null;
803
+ fileInput?.click();
804
+ window.addEventListener(
805
+ 'focus',
806
+ () => {
807
+ setTimeout(() => {
808
+ this.ignoreBlur = false;
809
+ }, 200);
810
+ },
811
+ { once: true }
812
+ );
813
+ };
814
+
815
+ private onFileChange = (e: Event) => {
816
+ const input = e.target as HTMLInputElement;
817
+ const file = input.files?.[0];
818
+ input.value = '';
819
+ if (!file) return;
820
+
821
+ if (!file.type.startsWith('image/')) {
822
+ this.errorMessage = 'Only image files are supported';
823
+ return;
824
+ }
825
+ if (this.maxFileSize > 0 && file.size > this.maxFileSize) {
826
+ const mb = (this.maxFileSize / (1024 * 1024)).toFixed(1);
827
+ this.errorMessage = `File is too large. Maximum size is ${mb} MB`;
828
+ return;
829
+ }
830
+
831
+ const reader = new FileReader();
832
+ reader.onload = () => {
833
+ this.srcValue = String(reader.result || '');
834
+ this.uploadedFileName = file.name;
835
+ this.errorMessage = '';
836
+ if (!this.altValue) {
837
+ this.altValue = file.name.replace(/\.[^.]+$/, '');
838
+ }
839
+ };
840
+ reader.onerror = () => {
841
+ this.errorMessage = 'Could not read the selected file';
842
+ };
843
+ reader.readAsDataURL(file);
844
+ };
845
+
846
+ private onApplyClick = () => {
847
+ this.isApplying = true;
848
+ this.applyImage();
849
+ this.isApplying = false;
850
+ this.ignoreBlur = false;
851
+ };
852
+
853
+ private onRemoveClick = () => {
854
+ this.isApplying = true;
855
+ this.removeImage();
856
+ this.isApplying = false;
857
+ this.ignoreBlur = false;
858
+ };
859
+
860
+ private buildFigure(src: string, alt = '', caption = ''): HTMLElement {
861
+ const figure = document.createElement('figure');
862
+ figure.className = 'rte-image';
863
+ figure.setAttribute('contenteditable', 'false');
864
+
865
+ const img = document.createElement('img');
866
+ img.src = src;
867
+ if (alt.trim()) img.alt = alt.trim();
868
+ figure.appendChild(img);
869
+
870
+ if (caption.trim()) {
871
+ const figcaption = document.createElement('figcaption');
872
+ figcaption.textContent = caption.trim();
873
+ figure.appendChild(figcaption);
874
+ }
875
+ return figure;
876
+ }
877
+
878
+ private insertFigureAt(insertRange: Range, figure: HTMLElement) {
879
+ const sel = document.getSelection();
880
+ if (!sel) return;
881
+
882
+ // a <figure> is not valid inside <p>/<h*>, so place it after the
883
+ // block that holds the caret instead of splitting it at the range
884
+ let block: HTMLElement | null = null;
885
+ let n: Node | null = insertRange.startContainer;
886
+ while (n && n !== this.editorEl) {
887
+ if (
888
+ n instanceof HTMLElement &&
889
+ /^(P|H[1-6]|UL|OL|BLOCKQUOTE|PRE|TABLE|FIGURE|DIV)$/.test(n.tagName)
890
+ ) {
891
+ block = n;
892
+ break;
893
+ }
894
+ n = n.parentNode;
895
+ }
896
+ // an empty paragraph (the default '<p><br></p>' of a fresh editor) would
897
+ // otherwise remain above the image as a blank gap — take its place instead
898
+ const isEmptyBlock =
899
+ block &&
900
+ /^(P|H[1-6])$/.test(block.tagName) &&
901
+ (block.textContent ?? '').replace(/\u200B/g, '').trim() === '' &&
902
+ !block.querySelector('img');
903
+
904
+ if (block?.parentNode) {
905
+ if (isEmptyBlock) {
906
+ block.parentNode.insertBefore(figure, block);
907
+ block.remove();
908
+ } else {
909
+ block.parentNode.insertBefore(figure, block.nextSibling);
910
+ }
911
+ } else {
912
+ this.editorEl.appendChild(figure);
913
+ }
914
+
915
+ // keep a paragraph after the image so typing can continue below it
916
+ let after = figure.nextElementSibling;
917
+ if (!after) {
918
+ const p = document.createElement('p');
919
+ p.innerHTML = '<br>';
920
+ figure.parentNode?.insertBefore(p, figure.nextSibling);
921
+ after = p;
922
+ }
923
+
924
+ const range = document.createRange();
925
+ range.setStart(after, 0);
926
+ range.collapse(true);
927
+ sel.removeAllRanges();
928
+ sel.addRange(range);
929
+ }
930
+
931
+ private applyImage() {
932
+ const raw = this.srcValue.trim();
933
+ if (!raw) {
934
+ if (this.uploadFromComputer) {
935
+ this.errorMessage = 'Enter an image link or upload a file';
936
+ }
937
+ return;
938
+ }
939
+
940
+ const src = this.normalizeSrc(raw);
941
+ if (!src) {
942
+ this.errorMessage = 'Enter a valid image link';
943
+ return;
944
+ }
945
+
946
+ if (this.activeFigure) {
947
+ const img = this.activeFigure.querySelector('img');
948
+ if (img) {
949
+ img.src = src;
950
+ if (this.altValue.trim()) {
951
+ img.alt = this.altValue.trim();
952
+ } else {
953
+ img.removeAttribute('alt');
954
+ }
955
+ }
956
+
957
+ let figcaption = this.activeFigure.querySelector('figcaption');
958
+ if (this.captionValue.trim()) {
959
+ if (!figcaption) {
960
+ figcaption = document.createElement('figcaption');
961
+ this.activeFigure.appendChild(figcaption);
962
+ }
963
+ figcaption.textContent = this.captionValue.trim();
964
+ } else {
965
+ figcaption?.remove();
966
+ }
967
+
968
+ this.emit(src);
969
+ this.closePopover();
970
+ requestAnimationFrame(() => this.updateOverlayPosition());
971
+ return;
972
+ }
973
+
974
+ if (!(this.selectionRange instanceof Range)) return;
975
+
976
+ this.editorEl.focus();
977
+
978
+ const sel = document.getSelection();
979
+ if (!sel) return;
980
+ sel.removeAllRanges();
981
+ sel.addRange(this.selectionRange);
982
+
983
+ const figure = this.buildFigure(src, this.altValue, this.captionValue);
984
+ this.insertFigureAt(this.selectionRange, figure);
985
+
986
+ this.emit(src);
987
+ this.closePopover();
988
+ }
989
+
990
+ private removeImage() {
991
+ if (!this.activeFigure) return;
992
+ this.deselectImage();
993
+ const parent = this.activeFigure.parentNode;
994
+ this.activeFigure.remove();
995
+ if (parent instanceof HTMLElement && !parent.hasChildNodes()) {
996
+ parent.innerHTML = '<br>';
997
+ }
998
+ this.emit('');
999
+ this.closePopover();
1000
+ }
1001
+
1002
+ private emit(src: string) {
1003
+ this.dispatchEvent(
1004
+ new CustomEvent('nile-image-changed', {
1005
+ detail: {
1006
+ src,
1007
+ alt: this.altValue.trim(),
1008
+ caption: this.captionValue.trim(),
1009
+ },
1010
+ bubbles: true,
1011
+ composed: true,
1012
+ })
1013
+ );
1014
+ }
1015
+
1016
+ render() {
1017
+ const iconColor = this.disabled
1018
+ ? 'var(--nile-colors-neutral-500, var(--ng-colors-fg-disabled-subtle))'
1019
+ : 'var(--nile-colors-dark-900, var(--ng-colors-text-primary-900))';
1020
+
1021
+ return html`
1022
+ <nile-lite-tooltip content=${this.label}>
1023
+ <nile-button
1024
+ variant="tertiary"
1025
+ size="small"
1026
+ ?disabled=${this.disabled}
1027
+ @mousedown=${this.onToolbarButtonMousedown}
1028
+ @click=${this.onOpen}
1029
+ class="rte-image-button"
1030
+ >
1031
+ <nile-glyph name="image" color=${iconColor}></nile-glyph>
1032
+ </nile-button>
1033
+ </nile-lite-tooltip>
1034
+
1035
+ <nile-popover
1036
+ class="rte-image-popover"
1037
+ .arrow=${false}
1038
+ style=${this.popoverStyle}
1039
+ @mousedown=${this.onPopoverMousedown}
1040
+ @mouseup=${this.onPopoverMouseup}
1041
+ >
1042
+ <div class="image-popup-wrap">
1043
+ <nile-input
1044
+ label="Image URL"
1045
+ placeholder=${this.placeholder}
1046
+ .value=${this.srcValue}
1047
+ @nile-input=${this.onSrcInput}
1048
+ @keydown=${this.onInputKeydown}
1049
+ @nile-blur=${this.onInputBlur}
1050
+ ></nile-input>
1051
+
1052
+ ${this.uploadFromComputer
1053
+ ? html`
1054
+ <div class="image-divider-row" part="divider">or</div>
1055
+
1056
+ <div class="image-upload-row" part="upload-row">
1057
+ <nile-button
1058
+ part="upload-button"
1059
+ size="small"
1060
+ variant="secondary"
1061
+ @click=${this.onUploadClick}
1062
+ >
1063
+ <nile-glyph name="upload" slot="prefix"></nile-glyph>
1064
+ Upload from computer
1065
+ </nile-button>
1066
+ ${this.uploadedFileName
1067
+ ? html`<span class="image-upload-filename" part="upload-filename"
1068
+ >${this.uploadedFileName}</span
1069
+ >`
1070
+ : null}
1071
+ </div>
1072
+ <input
1073
+ part="upload-input"
1074
+ type="file"
1075
+ accept="image/*"
1076
+ @change=${this.onFileChange}
1077
+ />
1078
+ `
1079
+ : null}
1080
+
1081
+ ${this.errorMessage
1082
+ ? html`<span class="image-error" part="error">${this.errorMessage}</span>`
1083
+ : null}
1084
+
1085
+ <nile-input
1086
+ label="Alt text"
1087
+ placeholder=${this.altPlaceholder}
1088
+ .value=${this.altValue}
1089
+ @nile-input=${this.onAltInput}
1090
+ @keydown=${this.onInputKeydown}
1091
+ @nile-blur=${this.onInputBlur}
1092
+ part="alt-input"
1093
+ ></nile-input>
1094
+
1095
+ <nile-input
1096
+ label="Caption"
1097
+ placeholder=${this.captionPlaceholder}
1098
+ .value=${this.captionValue}
1099
+ @nile-input=${this.onCaptionInput}
1100
+ @keydown=${this.onInputKeydown}
1101
+ @nile-blur=${this.onInputBlur}
1102
+ part="caption-input"
1103
+ ></nile-input>
1104
+
1105
+ <div class="image-actions-row" part="actions-row">
1106
+ ${this.hasActiveImage
1107
+ ? html`
1108
+ <nile-button
1109
+ part="remove-button"
1110
+ size="small"
1111
+ variant="secondary"
1112
+ @click=${this.onRemoveClick}
1113
+ >
1114
+ Remove
1115
+ </nile-button>
1116
+ `
1117
+ : null}
1118
+ <nile-button part="apply-button" size="small" variant="primary" @click=${this.onApplyClick}>
1119
+ ${this.hasActiveImage ? 'Update' : 'Insert'}
1120
+ </nile-button>
1121
+ </div>
1122
+ </div>
1123
+ </nile-popover>
1124
+ `;
1125
+ }
1126
+ }
1127
+
1128
+ declare global {
1129
+ interface HTMLElementTagNameMap {
1130
+ 'nile-rte-image': NileRteImage;
1131
+ }
1132
+ }