suneditor 2.46.2 → 3.0.0-alpha.10

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 (290) hide show
  1. package/.eslintignore +7 -0
  2. package/.eslintrc.json +64 -0
  3. package/CONTRIBUTING.md +36 -0
  4. package/LICENSE.txt +1 -1
  5. package/README.md +11 -1560
  6. package/dist/suneditor.min.css +1 -0
  7. package/dist/suneditor.min.js +1 -2
  8. package/package.json +97 -70
  9. package/src/assets/icons/_default.js +194 -0
  10. package/src/assets/suneditor-contents.css +643 -0
  11. package/src/assets/suneditor.css +3394 -0
  12. package/src/core/base/eventHandlers/handler_toolbar.js +114 -0
  13. package/src/core/base/eventHandlers/handler_ww_clipboard.js +37 -0
  14. package/src/core/base/eventHandlers/handler_ww_dragDrop.js +74 -0
  15. package/src/core/base/eventHandlers/handler_ww_key_input.js +1002 -0
  16. package/src/core/base/eventHandlers/handler_ww_mouse.js +147 -0
  17. package/src/core/base/eventManager.js +1156 -0
  18. package/src/core/base/events.js +320 -0
  19. package/src/core/base/history.js +301 -0
  20. package/src/core/class/char.js +147 -0
  21. package/src/core/class/component.js +639 -0
  22. package/src/core/class/format.js +3258 -0
  23. package/src/core/class/html.js +1710 -0
  24. package/src/core/class/menu.js +260 -0
  25. package/src/core/class/nodeTransform.js +405 -0
  26. package/src/core/class/notice.js +42 -0
  27. package/src/core/class/offset.js +575 -0
  28. package/src/core/class/selection.js +511 -0
  29. package/src/core/class/shortcuts.js +38 -0
  30. package/src/core/class/toolbar.js +440 -0
  31. package/src/core/class/viewer.js +646 -0
  32. package/src/core/editor.js +1601 -0
  33. package/src/core/section/actives.js +145 -0
  34. package/src/core/section/constructor.js +1252 -0
  35. package/src/core/section/context.js +97 -0
  36. package/src/editorInjector/_classes.js +22 -0
  37. package/src/editorInjector/_core.js +28 -0
  38. package/src/editorInjector/index.js +13 -0
  39. package/src/helper/converter.js +388 -0
  40. package/src/helper/domUtils.js +1177 -0
  41. package/src/helper/env.js +250 -0
  42. package/src/helper/index.js +19 -0
  43. package/src/helper/numbers.js +68 -0
  44. package/src/helper/unicode.js +43 -0
  45. package/src/langs/ckb.js +161 -0
  46. package/src/langs/cs.js +161 -0
  47. package/src/langs/da.js +161 -0
  48. package/src/langs/de.js +162 -0
  49. package/src/langs/en.js +210 -0
  50. package/src/langs/es.js +162 -0
  51. package/src/langs/fa.js +159 -0
  52. package/src/langs/fr.js +161 -0
  53. package/src/langs/he.js +162 -0
  54. package/src/{lang → langs}/index.js +0 -2
  55. package/src/langs/it.js +162 -0
  56. package/src/langs/ja.js +162 -0
  57. package/src/langs/ko.js +210 -0
  58. package/src/langs/lv.js +162 -0
  59. package/src/langs/nl.js +162 -0
  60. package/src/langs/pl.js +162 -0
  61. package/src/langs/pt_br.js +162 -0
  62. package/src/langs/ro.js +162 -0
  63. package/src/langs/ru.js +162 -0
  64. package/src/langs/se.js +162 -0
  65. package/src/langs/tr.js +159 -0
  66. package/src/langs/ua.js +162 -0
  67. package/src/langs/ur.js +162 -0
  68. package/src/langs/zh_cn.js +162 -0
  69. package/src/modules/ApiManager.js +168 -0
  70. package/src/modules/ColorPicker.js +302 -0
  71. package/src/modules/Controller.js +323 -0
  72. package/src/modules/Figure.js +1176 -0
  73. package/src/modules/FileBrowser.js +271 -0
  74. package/src/modules/FileManager.js +307 -0
  75. package/src/modules/HueSlider.js +513 -0
  76. package/src/modules/Modal.js +177 -0
  77. package/src/modules/ModalAnchorEditor.js +494 -0
  78. package/src/modules/SelectMenu.js +447 -0
  79. package/src/modules/_DragHandle.js +16 -0
  80. package/src/modules/index.js +14 -0
  81. package/src/plugins/command/blockquote.js +47 -47
  82. package/src/plugins/command/exportPdf.js +168 -0
  83. package/src/plugins/command/fileUpload.js +389 -0
  84. package/src/plugins/command/list_bulleted.js +112 -0
  85. package/src/plugins/command/list_numbered.js +115 -0
  86. package/src/plugins/dropdown/align.js +143 -0
  87. package/src/plugins/dropdown/backgroundColor.js +90 -0
  88. package/src/plugins/dropdown/font.js +113 -0
  89. package/src/plugins/dropdown/fontColor.js +90 -0
  90. package/src/plugins/dropdown/formatBlock.js +141 -0
  91. package/src/plugins/dropdown/hr.js +111 -0
  92. package/src/plugins/dropdown/layout.js +72 -0
  93. package/src/plugins/dropdown/lineHeight.js +114 -0
  94. package/src/plugins/dropdown/list.js +107 -0
  95. package/src/plugins/dropdown/paragraphStyle.js +117 -0
  96. package/src/plugins/dropdown/table.js +2810 -0
  97. package/src/plugins/dropdown/template.js +71 -0
  98. package/src/plugins/dropdown/textStyle.js +137 -0
  99. package/src/plugins/field/mention.js +181 -0
  100. package/src/plugins/fileBrowser/imageGallery.js +76 -59
  101. package/src/plugins/index.js +86 -24
  102. package/src/plugins/input/fontSize.js +357 -0
  103. package/src/plugins/modal/audio.js +492 -0
  104. package/src/plugins/modal/image.js +1064 -0
  105. package/src/plugins/modal/link.js +211 -0
  106. package/src/plugins/modal/math.js +363 -0
  107. package/src/plugins/modal/video.js +870 -0
  108. package/src/suneditor.js +62 -67
  109. package/src/themes/test.css +61 -0
  110. package/typings/CommandPlugin.d.ts +8 -0
  111. package/typings/DialogPlugin.d.ts +20 -0
  112. package/typings/FileBrowserPlugin.d.ts +30 -0
  113. package/typings/Lang.d.ts +124 -0
  114. package/typings/Module.d.ts +15 -0
  115. package/typings/Plugin.d.ts +42 -0
  116. package/typings/SubmenuPlugin.d.ts +8 -0
  117. package/typings/_classes.d.ts +17 -0
  118. package/typings/_colorPicker.d.ts +60 -0
  119. package/typings/_core.d.ts +55 -0
  120. package/typings/align.d.ts +5 -0
  121. package/{src/plugins/dialog → typings}/audio.d.ts +1 -1
  122. package/typings/backgroundColor.d.ts +5 -0
  123. package/{src/plugins/command → typings}/blockquote.d.ts +1 -1
  124. package/typings/char.d.ts +39 -0
  125. package/typings/component.d.ts +38 -0
  126. package/typings/context.d.ts +39 -0
  127. package/typings/converter.d.ts +33 -0
  128. package/typings/dialog.d.ts +28 -0
  129. package/typings/domUtils.d.ts +361 -0
  130. package/typings/editor.d.ts +7 -0
  131. package/typings/editor.ts +542 -0
  132. package/typings/env.d.ts +70 -0
  133. package/typings/eventManager.d.ts +37 -0
  134. package/typings/events.d.ts +262 -0
  135. package/typings/fileBrowser.d.ts +42 -0
  136. package/typings/fileManager.d.ts +67 -0
  137. package/typings/font.d.ts +5 -0
  138. package/typings/fontColor.d.ts +5 -0
  139. package/typings/fontSize.d.ts +5 -0
  140. package/typings/format.d.ts +191 -0
  141. package/typings/formatBlock.d.ts +5 -0
  142. package/typings/history.d.ts +48 -0
  143. package/typings/horizontalRule.d.ts +5 -0
  144. package/{src/plugins/dialog → typings}/image.d.ts +1 -1
  145. package/{src/plugins/fileBrowser → typings}/imageGallery.d.ts +1 -1
  146. package/typings/index.d.ts +21 -0
  147. package/{src/plugins/modules/index.d.ts → typings/index.modules.d.ts} +3 -3
  148. package/typings/index.plugins.d.ts +58 -0
  149. package/typings/lineHeight.d.ts +5 -0
  150. package/{src/plugins/dialog → typings}/link.d.ts +1 -1
  151. package/typings/list.d.ts +5 -0
  152. package/{src/plugins/dialog → typings}/math.d.ts +1 -1
  153. package/typings/mediaContainer.d.ts +25 -0
  154. package/typings/node.d.ts +57 -0
  155. package/typings/notice.d.ts +16 -0
  156. package/typings/numbers.d.ts +29 -0
  157. package/typings/offset.d.ts +24 -0
  158. package/typings/options.d.ts +589 -0
  159. package/typings/paragraphStyle.d.ts +5 -0
  160. package/typings/resizing.d.ts +141 -0
  161. package/typings/selection.d.ts +94 -0
  162. package/typings/shortcuts.d.ts +13 -0
  163. package/typings/suneditor.d.ts +9 -0
  164. package/typings/table.d.ts +5 -0
  165. package/typings/template.d.ts +5 -0
  166. package/typings/textStyle.d.ts +5 -0
  167. package/typings/toolbar.d.ts +32 -0
  168. package/typings/unicode.d.ts +25 -0
  169. package/{src/plugins/dialog → typings}/video.d.ts +1 -1
  170. package/dist/css/suneditor.min.css +0 -1
  171. package/src/assets/css/suneditor-contents.css +0 -562
  172. package/src/assets/css/suneditor.css +0 -566
  173. package/src/assets/defaultIcons.js +0 -103
  174. package/src/lang/Lang.d.ts +0 -144
  175. package/src/lang/ckb.d.ts +0 -5
  176. package/src/lang/ckb.js +0 -188
  177. package/src/lang/cs.d.ts +0 -5
  178. package/src/lang/cs.js +0 -188
  179. package/src/lang/da.d.ts +0 -5
  180. package/src/lang/da.js +0 -191
  181. package/src/lang/de.d.ts +0 -5
  182. package/src/lang/de.js +0 -188
  183. package/src/lang/en.d.ts +0 -5
  184. package/src/lang/en.js +0 -188
  185. package/src/lang/es.d.ts +0 -5
  186. package/src/lang/es.js +0 -188
  187. package/src/lang/fa.d.ts +0 -5
  188. package/src/lang/fa.js +0 -188
  189. package/src/lang/fr.d.ts +0 -5
  190. package/src/lang/fr.js +0 -188
  191. package/src/lang/he.d.ts +0 -5
  192. package/src/lang/he.js +0 -188
  193. package/src/lang/index.d.ts +0 -23
  194. package/src/lang/it.d.ts +0 -5
  195. package/src/lang/it.js +0 -188
  196. package/src/lang/ja.d.ts +0 -5
  197. package/src/lang/ja.js +0 -188
  198. package/src/lang/ko.d.ts +0 -5
  199. package/src/lang/ko.js +0 -188
  200. package/src/lang/lv.d.ts +0 -5
  201. package/src/lang/lv.js +0 -188
  202. package/src/lang/nl.d.ts +0 -5
  203. package/src/lang/nl.js +0 -188
  204. package/src/lang/pl.d.ts +0 -5
  205. package/src/lang/pl.js +0 -188
  206. package/src/lang/pt_br.d.ts +0 -5
  207. package/src/lang/pt_br.js +0 -189
  208. package/src/lang/ro.d.ts +0 -5
  209. package/src/lang/ro.js +0 -188
  210. package/src/lang/ru.d.ts +0 -5
  211. package/src/lang/ru.js +0 -188
  212. package/src/lang/se.d.ts +0 -5
  213. package/src/lang/se.js +0 -191
  214. package/src/lang/tr.d.ts +0 -5
  215. package/src/lang/tr.js +0 -191
  216. package/src/lang/ua.d.ts +0 -5
  217. package/src/lang/ua.js +0 -188
  218. package/src/lang/ur.d.ts +0 -5
  219. package/src/lang/ur.js +0 -188
  220. package/src/lang/zh_cn.d.ts +0 -5
  221. package/src/lang/zh_cn.js +0 -187
  222. package/src/lib/constructor.js +0 -954
  223. package/src/lib/context.d.ts +0 -42
  224. package/src/lib/context.js +0 -71
  225. package/src/lib/core.d.ts +0 -1135
  226. package/src/lib/core.js +0 -9395
  227. package/src/lib/history.d.ts +0 -48
  228. package/src/lib/history.js +0 -219
  229. package/src/lib/util.d.ts +0 -678
  230. package/src/lib/util.js +0 -2131
  231. package/src/options.d.ts +0 -608
  232. package/src/plugins/CommandPlugin.d.ts +0 -8
  233. package/src/plugins/DialogPlugin.d.ts +0 -20
  234. package/src/plugins/FileBrowserPlugin.d.ts +0 -30
  235. package/src/plugins/Module.d.ts +0 -15
  236. package/src/plugins/Plugin.d.ts +0 -42
  237. package/src/plugins/SubmenuPlugin.d.ts +0 -8
  238. package/src/plugins/dialog/audio.js +0 -559
  239. package/src/plugins/dialog/image.js +0 -1126
  240. package/src/plugins/dialog/link.js +0 -223
  241. package/src/plugins/dialog/math.js +0 -295
  242. package/src/plugins/dialog/mention.js +0 -242
  243. package/src/plugins/dialog/video.js +0 -979
  244. package/src/plugins/index.d.ts +0 -79
  245. package/src/plugins/modules/_anchor.js +0 -461
  246. package/src/plugins/modules/_colorPicker.d.ts +0 -60
  247. package/src/plugins/modules/_colorPicker.js +0 -201
  248. package/src/plugins/modules/_notice.d.ts +0 -21
  249. package/src/plugins/modules/_notice.js +0 -72
  250. package/src/plugins/modules/_selectMenu.js +0 -119
  251. package/src/plugins/modules/component.d.ts +0 -25
  252. package/src/plugins/modules/component.js +0 -81
  253. package/src/plugins/modules/dialog.d.ts +0 -28
  254. package/src/plugins/modules/dialog.js +0 -175
  255. package/src/plugins/modules/fileBrowser.d.ts +0 -42
  256. package/src/plugins/modules/fileBrowser.js +0 -374
  257. package/src/plugins/modules/fileManager.d.ts +0 -67
  258. package/src/plugins/modules/fileManager.js +0 -326
  259. package/src/plugins/modules/index.js +0 -9
  260. package/src/plugins/modules/resizing.d.ts +0 -154
  261. package/src/plugins/modules/resizing.js +0 -903
  262. package/src/plugins/submenu/align.d.ts +0 -5
  263. package/src/plugins/submenu/align.js +0 -160
  264. package/src/plugins/submenu/font.d.ts +0 -5
  265. package/src/plugins/submenu/font.js +0 -123
  266. package/src/plugins/submenu/fontColor.d.ts +0 -5
  267. package/src/plugins/submenu/fontColor.js +0 -101
  268. package/src/plugins/submenu/fontSize.d.ts +0 -5
  269. package/src/plugins/submenu/fontSize.js +0 -112
  270. package/src/plugins/submenu/formatBlock.d.ts +0 -5
  271. package/src/plugins/submenu/formatBlock.js +0 -273
  272. package/src/plugins/submenu/hiliteColor.d.ts +0 -5
  273. package/src/plugins/submenu/hiliteColor.js +0 -102
  274. package/src/plugins/submenu/horizontalRule.d.ts +0 -5
  275. package/src/plugins/submenu/horizontalRule.js +0 -98
  276. package/src/plugins/submenu/lineHeight.d.ts +0 -5
  277. package/src/plugins/submenu/lineHeight.js +0 -104
  278. package/src/plugins/submenu/list.d.ts +0 -5
  279. package/src/plugins/submenu/list.js +0 -456
  280. package/src/plugins/submenu/paragraphStyle.d.ts +0 -5
  281. package/src/plugins/submenu/paragraphStyle.js +0 -135
  282. package/src/plugins/submenu/table.d.ts +0 -5
  283. package/src/plugins/submenu/table.js +0 -1431
  284. package/src/plugins/submenu/template.d.ts +0 -5
  285. package/src/plugins/submenu/template.js +0 -72
  286. package/src/plugins/submenu/textStyle.d.ts +0 -5
  287. package/src/plugins/submenu/textStyle.js +0 -167
  288. package/src/suneditor.d.ts +0 -9
  289. package/src/suneditor_build.js +0 -18
  290. /package/{src/plugins/dialog → typings}/mention.d.ts +0 -0
@@ -0,0 +1,97 @@
1
+ import { get as getNumber } from '../../helper/numbers';
2
+
3
+ /**
4
+ * @description Elements and variables you should have
5
+ * @param {Element} editorTargets Target textarea
6
+ * @param {Element} top Editor top area
7
+ * @param {Element} wwFrame Editor wysiwyg frame
8
+ * @param {Element} codeWrapper Editor code view wrapper
9
+ * @param {Element} codeFrame Editor code view frame
10
+ * @param {Element|null} statusbar Editor statusbar
11
+ * @param {any} key root key
12
+ * @returns {Map}
13
+ */
14
+ export const CreateFrameContext = function (editorTarget, top, wwFrame, codeWrapper, codeFrame, statusbar, key) {
15
+ const m = new Map([
16
+ ['key', key],
17
+ ['options', editorTarget.options],
18
+ ['originElement', editorTarget.target],
19
+ ['topArea', top],
20
+ ['container', top.querySelector('.se-container')],
21
+ ['wrapper', top.querySelector('.se-wrapper')],
22
+ ['wysiwygFrame', wwFrame],
23
+ ['wysiwyg', wwFrame], // options.iframe ? wwFrame.contentDocument.body : wwFrame
24
+ ['codeWrapper', codeWrapper],
25
+ ['code', codeFrame],
26
+ ['codeNumbers', codeWrapper?.querySelector('.se-code-view-line')],
27
+ ['lineBreaker_t', top.querySelector('.se-line-breaker-component-t')],
28
+ ['lineBreaker_b', top.querySelector('.se-line-breaker-component-b')],
29
+ ['_stickyDummy', top.querySelector('.se-toolbar-sticky-dummy')],
30
+ ['_toolbarShadow', top.querySelector('.se-toolbar-shadow')],
31
+ ['_minHeight', getNumber(wwFrame.style.minHeight || '65', 0)],
32
+ ['isCodeView', false],
33
+ ['isFullScreen', false],
34
+ ['isReadOnly', false],
35
+ ['isDisabled', false],
36
+ ['isChanged', -1],
37
+ ['historyIndex', -1],
38
+ ['savedIndex', -1]
39
+ ]);
40
+
41
+ if (statusbar) UpdateStatusbarContext(statusbar, m);
42
+
43
+ const placeholder = top.querySelector('.se-placeholder');
44
+ if (placeholder) m.set('placeholder', placeholder);
45
+
46
+ return m;
47
+ };
48
+
49
+ /**
50
+ * @description Update statusbar context
51
+ * @param {Element} statusbar Statusbar element
52
+ * @param {FrameContext} mapper FrameContext map
53
+ */
54
+ export const UpdateStatusbarContext = function (statusbar, mapper) {
55
+ statusbar ? mapper.set('statusbar', statusbar) : mapper.delete('statusbar');
56
+ const navigation = statusbar ? statusbar.querySelector('.se-navigation') : null;
57
+ const charWrapper = statusbar ? statusbar.querySelector('.se-char-counter-wrapper') : null;
58
+ const charCounter = statusbar ? statusbar.querySelector('.se-char-counter-wrapper .se-char-counter') : null;
59
+ navigation ? mapper.set('navigation', navigation) : mapper.delete('navigation');
60
+ charWrapper ? mapper.set('charWrapper', charWrapper) : mapper.delete('charWrapper');
61
+ charCounter ? mapper.set('charCounter', charCounter) : mapper.delete('charCounter');
62
+ };
63
+
64
+ /**
65
+ * @description Common elements and variables you should have
66
+ * @param {Element} toolbar Toolbar frame
67
+ * @param {Element|null} toolbarContainer Toolbar container
68
+ * @param {Element} menuTray menu tray
69
+ * @param {Element|null} subbar sub toolbar
70
+ * @returns {Map}
71
+ */
72
+ export const CreateContext = function (toolbar, toolbarContainer, menuTray, subbar, statusbarContainer) {
73
+ const m = new Map([
74
+ ['menuTray', menuTray],
75
+ ['toolbar.main', toolbar],
76
+ ['toolbar.buttonTray', toolbar.querySelector('.se-btn-tray')],
77
+ ['toolbar._arrow', toolbar.querySelector('.se-arrow')]
78
+ ]);
79
+
80
+ if (subbar) {
81
+ m.set('toolbar.sub.main', subbar);
82
+ m.set('toolbar.sub.buttonTray', subbar.querySelector('.se-btn-tray'));
83
+ m.set('toolbar.sub._arrow', subbar.querySelector('.se-arrow'));
84
+ m.set('toolbar.sub._wrapper', subbar.parentElement.parentElement);
85
+ }
86
+
87
+ if (toolbarContainer) {
88
+ m.set('toolbar._wrapper', toolbarContainer.querySelector('.sun-editor'));
89
+ m.set('_stickyDummy', toolbarContainer.querySelector('.se-toolbar-sticky-dummy'));
90
+ }
91
+
92
+ if (statusbarContainer) {
93
+ m.set('statusbar._wrapper', statusbarContainer.querySelector('.sun-editor'));
94
+ }
95
+
96
+ return m;
97
+ };
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @description Add all inner classes to the editor;
3
+ * @param {any} editor Editor object
4
+ * @private
5
+ */
6
+ function ClassInjector(editor) {
7
+ this.char = editor.char;
8
+ this.component = editor.component;
9
+ this.format = editor.format;
10
+ this.html = editor.html;
11
+ this.menu = editor.menu;
12
+ this.nodeTransform = editor.nodeTransform;
13
+ this.notice = editor.notice;
14
+ this.offset = editor.offset;
15
+ this.selection = editor.selection;
16
+ this.shortcuts = editor.shortcuts;
17
+ this.toolbar = editor.toolbar;
18
+ this.viewer = editor.viewer;
19
+ if (editor.subToolbar) this.subToolbar = editor.subToolbar;
20
+ }
21
+
22
+ export default ClassInjector;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @description Add default properties to the editor core;
3
+ * @param {any} editor Editor's core
4
+ * @private
5
+ */
6
+ function CoreInjector(editor) {
7
+ // editor root
8
+ this.editor = editor;
9
+ // base
10
+ this.eventManager = editor.eventManager;
11
+ this.history = editor.history;
12
+ this.events = editor.events;
13
+ this.triggerEvent = editor.triggerEvent;
14
+ this.carrierWrapper = editor.carrierWrapper;
15
+ // environment variables
16
+ this.plugins = editor.plugins;
17
+ this.status = editor.status;
18
+ this.context = editor.context;
19
+ this.options = editor.options;
20
+ this.icons = editor.icons;
21
+ this.lang = editor.lang;
22
+ // window, document, shadowRoot
23
+ this._w = editor._w;
24
+ this._d = editor._d;
25
+ this._shadowRoot = editor._shadowRoot;
26
+ }
27
+
28
+ export default CoreInjector;
@@ -0,0 +1,13 @@
1
+ import CoreInjector from './_core';
2
+ import ClassInjector from './_classes';
3
+
4
+ /**
5
+ * @description Initializes and adds inner classes and default properties of the editor.
6
+ * @param {any} editor Editor object
7
+ */
8
+ function EditorInjector(editor) {
9
+ CoreInjector.call(this, editor);
10
+ ClassInjector.call(this, editor);
11
+ }
12
+
13
+ export default EditorInjector;
@@ -0,0 +1,388 @@
1
+ import { _d, _w } from './env';
2
+
3
+ const URLPattern = /https?:\/\/[^\s]+/g;
4
+ const FONT_VALUES_MAP = {
5
+ 'xx-small': 1,
6
+ 'x-small': 2,
7
+ small: 3,
8
+ medium: 4,
9
+ large: 5,
10
+ 'x-large': 6,
11
+ 'xx-large': 7,
12
+ 'xxx-large': 8
13
+ };
14
+
15
+ /**
16
+ * @description Convert HTML string to HTML Entity
17
+ * @param {string} content
18
+ * @returns {string} Content string
19
+ * @private
20
+ */
21
+ export function htmlToEntity(content) {
22
+ const ec = {
23
+ '&': '&',
24
+ '\u00A0': ' ',
25
+ "'": ''',
26
+ '"': '"',
27
+ '<': '&lt;',
28
+ '>': '&gt;'
29
+ };
30
+ return content.replace(/&|\u00A0|'|"|<|>/g, (m) => {
31
+ return typeof ec[m] === 'string' ? ec[m] : m;
32
+ });
33
+ }
34
+
35
+ /**
36
+ * @description Convert HTML Entity to HTML string
37
+ * @param {string} content Content string
38
+ * @returns {string}
39
+ */
40
+ export function entityToHTML(content) {
41
+ const ec = {
42
+ '&amp;': '&',
43
+ '&nbsp;': '\u00A0',
44
+ '&apos;': "'",
45
+ '&quot;': '"',
46
+ '&lt;': '<',
47
+ '&gt;': '>'
48
+ };
49
+ return content.replace(/&amp;|&nbsp;|&apos;|&quot;|\$lt;|\$gt;/g, (m) => {
50
+ return typeof ec[m] === 'string' ? ec[m] : m;
51
+ });
52
+ }
53
+
54
+ /**
55
+ * @description Debounce function
56
+ * @param {Function} func function
57
+ * @param {number} wait delay ms
58
+ * @returns
59
+ */
60
+ export function debounce(func, wait) {
61
+ let timeout;
62
+
63
+ return function executedFunction(...args) {
64
+ const later = () => {
65
+ _w.clearTimeout(timeout);
66
+ func(...args);
67
+ };
68
+
69
+ _w.clearTimeout(timeout);
70
+ timeout = setTimeout(later, wait);
71
+ };
72
+ }
73
+
74
+ /**
75
+ *
76
+ * @param {"em"|"rem"|"%"|"pt"|"px"} to Size units to be converted
77
+ * @param {string} size siSize to convert with units (ex: "15rem")
78
+ * @returns {string}
79
+ */
80
+ export function fontSize(to, size) {
81
+ const value = size.match(/(\d+(?:\.\d+)?)(.+)/);
82
+ const sizeNum = value ? value[1] * 1 : FONT_VALUES_MAP[size];
83
+ const from = value ? value[2] : 'rem';
84
+ let pxSize = sizeNum;
85
+
86
+ if (/em/.test(from)) {
87
+ pxSize = Math.round(sizeNum / 0.0625);
88
+ } else if (from === 'pt') {
89
+ pxSize = Math.round(sizeNum * 1.333);
90
+ } else if (from === '%') {
91
+ pxSize = sizeNum / 100;
92
+ }
93
+
94
+ switch (to) {
95
+ case 'em':
96
+ case 'rem':
97
+ return (pxSize * 0.0625).toFixed(2) + to;
98
+ case '%':
99
+ return (pxSize * 0.0625).toFixed(2) * 100 + to;
100
+ case 'pt':
101
+ return Math.floor(pxSize / 1.333) + to;
102
+ default:
103
+ // px
104
+ return pxSize + to;
105
+ }
106
+ }
107
+
108
+ /**
109
+ * @description Convert the node list to an array. If not, returns an empty array.
110
+ * @param {NodeList|null} nodeList
111
+ * @returns Array
112
+ */
113
+ export function nodeListToArray(nodeList) {
114
+ if (!nodeList) return [];
115
+ return Array.prototype.slice.call(nodeList);
116
+ }
117
+
118
+ /**
119
+ * @description Returns a new object with keys and values swapped.
120
+ * @param {Object} obj object
121
+ * @returns {Object}
122
+ */
123
+ export function swapKeyValue(obj) {
124
+ const swappedObj = {};
125
+
126
+ for (const key in obj) {
127
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
128
+ swappedObj[obj[key]] = key;
129
+ }
130
+ }
131
+
132
+ return swappedObj;
133
+ }
134
+
135
+ /**
136
+ * @description Create whitelist RegExp object.
137
+ * Return RegExp format: new RegExp("<\\/?\\b(?!" + list + ")\\b[^>^<]*+>", "gi")
138
+ * @param {string} list Tags list ("br|p|div|pre...")
139
+ * @returns {RegExp}
140
+ */
141
+ export function createElementWhitelist(list) {
142
+ return new RegExp(`<\\/?\\b(?!\\b${(list || '').replace(/\|/g, '\\b|\\b')}\\b)[^>]*>`, 'gi');
143
+ }
144
+
145
+ /**
146
+ * @description Create blacklist RegExp object.
147
+ * Return RegExp format: new RegExp("<\\/?\\b(?:" + list + ")\\b[^>^<]*+>", "gi")
148
+ * @param {string} list Tags list ("br|p|div|pre...")
149
+ * @returns {RegExp}
150
+ */
151
+ export function createElementBlacklist(list) {
152
+ return new RegExp(`<\\/?\\b(?:\\b${(list || '^').replace(/\|/g, '\\b|\\b')}\\b)[^>]*>`, 'gi');
153
+ }
154
+
155
+ /**
156
+ * @description Function to check hex format color
157
+ * @param {string} str Color value
158
+ */
159
+ export function isHexColor(str) {
160
+ return /^#[0-9a-f]{3}(?:[0-9a-f]{3})?$/i.test(str);
161
+ }
162
+
163
+ /**
164
+ * @description Function to convert hex format to a rgb color
165
+ * @param {string} rgb RGB color format
166
+ * @returns {string}
167
+ */
168
+ export function rgb2hex(rgba) {
169
+ if (isHexColor(rgba) || !rgba) return rgba;
170
+
171
+ const rgbaMatch = rgba.match(/^rgba?[\s+]?\(([\d]+)[\s+]?,[\s+]?([\d]+)[\s+]?,[\s+]?([\d]+)[\s+]?/i);
172
+
173
+ if (rgbaMatch && rgbaMatch.length >= 4) {
174
+ const r = ('0' + parseInt(rgbaMatch[1], 10).toString(16)).slice(-2);
175
+ const g = ('0' + parseInt(rgbaMatch[2], 10).toString(16)).slice(-2);
176
+ const b = ('0' + parseInt(rgbaMatch[3], 10).toString(16)).slice(-2);
177
+
178
+ let a = '';
179
+ if (rgba.includes('rgba')) {
180
+ const alphaMatch = rgba.match(/[\s+]?([\d]+\.?[\d]*)[\s+]?/i);
181
+ if (alphaMatch) {
182
+ a = ('0' + Math.round(parseFloat(alphaMatch[1]) * 255).toString(16)).slice(-2);
183
+ }
184
+ }
185
+
186
+ return `#${r}${g}${b}${a}`;
187
+ } else {
188
+ return '';
189
+ }
190
+ }
191
+
192
+ /**
193
+ * @description Computes the width as a percentage of the parent's width, and returns this value rounded to two decimal places.
194
+ * @param {Element} target
195
+ * @param {Element|null} parentTarget
196
+ * @returns {number}
197
+ */
198
+ export function getWidthInPercentage(target, parentTarget) {
199
+ const parent = parentTarget || target.parentElement;
200
+ const parentStyle = _w.getComputedStyle(parent);
201
+ const parentPaddingLeft = _w.parseFloat(parentStyle.paddingLeft);
202
+ const parentPaddingRight = _w.parseFloat(parentStyle.paddingRight);
203
+ const scrollbarWidth = parent.offsetWidth - parent.clientWidth;
204
+ const parentWidth = parent.offsetWidth - parentPaddingLeft - parentPaddingRight - scrollbarWidth;
205
+ const widthInPercentage = (target.offsetWidth / parentWidth) * 100;
206
+ return widthInPercentage;
207
+ }
208
+
209
+ /**
210
+ * @description Convert url pattern text node to anchor node
211
+ * @param {Node} node Text node
212
+ */
213
+ export function textToAnchor(node) {
214
+ if (node.nodeType === 3 && URLPattern.test(node.textContent) && !/^A$/i.test(node.parentNode?.nodeName)) {
215
+ const textContent = node.textContent;
216
+ const fragment = _d.createDocumentFragment();
217
+ let lastIndex = 0;
218
+ textContent.replace(URLPattern, (match, offset) => {
219
+ if (offset > 0) {
220
+ fragment.appendChild(_d.createTextNode(textContent.slice(0, offset)));
221
+ }
222
+ const anchor = _d.createElement('a');
223
+ anchor.href = match;
224
+ anchor.target = '_blank';
225
+ anchor.textContent = match;
226
+ fragment.appendChild(anchor);
227
+ lastIndex = offset + match.length;
228
+ if (lastIndex < textContent.length) {
229
+ fragment.appendChild(_d.createTextNode(textContent.slice(lastIndex)));
230
+ }
231
+ });
232
+ node.parentNode.replaceChild(fragment, node);
233
+ }
234
+ }
235
+
236
+ /**
237
+ * Converts styles within a <span> tag to corresponding HTML tags (e.g., <strong>, <em>, <u>, <s>).
238
+ * Maintains the original <span> tag and wraps its content with the new tags.
239
+ * @param {Object} styleToTag An object mapping style properties to HTML tags. ex) {bold: { regex: /font-weight\s*:\s*bold/i, tag: 'strong' },}
240
+ * @param {Node} node Node
241
+ */
242
+ export function spanToStyleNode(styleToTag, node) {
243
+ if (node.nodeType === 1 && /^SPAN$/i.test(node.nodeName) && node.hasAttribute('style')) {
244
+ const style = node.getAttribute('style');
245
+ const tags = [];
246
+ Object.keys(styleToTag).forEach((key) => {
247
+ if (styleToTag[key].regex.test(style)) {
248
+ const tag = _d.createElement(styleToTag[key].tag);
249
+ tags.push(tag);
250
+ }
251
+ });
252
+
253
+ if (tags.length > 0) {
254
+ const temp = _d.createElement('span');
255
+ let currentNode = node.firstChild;
256
+
257
+ tags.forEach((tag, index) => {
258
+ if (index === 0) {
259
+ temp.appendChild(tag);
260
+ } else {
261
+ tags[index - 1].appendChild(tag);
262
+ }
263
+ });
264
+
265
+ const parent = tags[tags.length - 1];
266
+ while (currentNode) {
267
+ const nextNode = currentNode.nextSibling;
268
+ parent.appendChild(currentNode);
269
+ currentNode = nextNode;
270
+ }
271
+
272
+ while (node.firstChild) {
273
+ node.removeChild(node.firstChild);
274
+ }
275
+
276
+ node.appendChild(temp);
277
+ }
278
+ }
279
+ }
280
+
281
+ /**
282
+ * @description Converts options-related styles and returns them for each frame.
283
+ * @param {Object.<string, any>} fo frameOptions
284
+ * @param {string} cssText Style string
285
+ * @returns {{top: string, frame: string, editor: string}}
286
+ * @private
287
+ */
288
+ export function _setDefaultOptionStyle(fo, cssText) {
289
+ let optionStyle = '';
290
+ if (fo.get('height')) optionStyle += 'height:' + fo.get('height') + ';';
291
+ if (fo.get('minHeight')) optionStyle += 'min-height:' + fo.get('minHeight') + ';';
292
+ if (fo.get('maxHeight')) optionStyle += 'max-height:' + fo.get('maxHeight') + ';';
293
+ if (fo.get('width')) optionStyle += 'width:' + fo.get('width') + ';';
294
+ if (fo.get('minWidth')) optionStyle += 'min-width:' + fo.get('minWidth') + ';';
295
+ if (fo.get('maxWidth')) optionStyle += 'max-width:' + fo.get('maxWidth') + ';';
296
+
297
+ let top = '',
298
+ frame = '',
299
+ editor = '';
300
+ cssText = optionStyle + cssText;
301
+ const styleArr = cssText.split(';');
302
+ for (let i = 0, len = styleArr.length, s; i < len; i++) {
303
+ s = styleArr[i].trim();
304
+ if (!s) continue;
305
+ if (/^(min-|max-)?width\s*:/.test(s) || /^(z-index|position|display)\s*:/.test(s)) {
306
+ top += s + ';';
307
+ continue;
308
+ }
309
+ if (/^(min-|max-)?height\s*:/.test(s)) {
310
+ if (/^height/.test(s) && s.split(':')[1].trim() === 'auto') {
311
+ fo.set('height', 'auto');
312
+ }
313
+ frame += s + ';';
314
+ continue;
315
+ }
316
+ editor += s + ';';
317
+ }
318
+
319
+ return {
320
+ top: top,
321
+ frame: frame,
322
+ editor: editor
323
+ };
324
+ }
325
+
326
+ /**
327
+ * @description Set default style tag of the iframe
328
+ * @param {Object.<string, any>} options Options
329
+ * @returns {string} "<link rel="stylesheet" href=".." />.."
330
+ */
331
+ export function _setIframeStyleLinks(linkNames) {
332
+ let tagString = '';
333
+
334
+ if (linkNames) {
335
+ for (let f = 0, len = linkNames.length, path; f < len; f++) {
336
+ path = [];
337
+
338
+ if (/(^https?:\/\/)|(^data:text\/css,)/.test(linkNames[f])) {
339
+ path.push(linkNames[f]);
340
+ } else {
341
+ const CSSFileName = new RegExp(`(^|.*[\\/])${linkNames[f]}(\\..+)?.css((\\??.+?)|\\b)$`, 'i');
342
+ for (let c = _d.getElementsByTagName('link'), i = 0, cLen = c.length, styleTag; i < cLen; i++) {
343
+ styleTag = c[i].href.match(CSSFileName);
344
+ if (styleTag) path.push(styleTag[0]);
345
+ }
346
+ }
347
+
348
+ if (!path || path.length === 0)
349
+ throw '[SUNEDITOR.constructor.iframe.fail] The suneditor CSS files installation path could not be automatically detected. Please set the option property "iframe_cssFileName" before creating editor instances.';
350
+
351
+ for (let i = 0, pLen = path.length; i < pLen; i++) {
352
+ tagString += '<link href="' + path[i] + '" rel="stylesheet">';
353
+ }
354
+ }
355
+ }
356
+
357
+ return tagString;
358
+ }
359
+
360
+ /**
361
+ * @description When iframe height options is "auto" return "<style>" tag that required.
362
+ * @param {string} frameHeight height
363
+ * @returns {string} "<style>...</style>"
364
+ */
365
+ export function _setAutoHeightStyle(frameHeight) {
366
+ return frameHeight === 'auto' ? '<style>\n/** Iframe height auto */\nbody{height: min-content; overflow: hidden;}\n</style>' : '';
367
+ }
368
+
369
+ const converter = {
370
+ htmlToEntity,
371
+ entityToHTML,
372
+ debounce,
373
+ fontSize,
374
+ nodeListToArray,
375
+ swapKeyValue,
376
+ createElementWhitelist,
377
+ createElementBlacklist,
378
+ isHexColor,
379
+ rgb2hex,
380
+ getWidthInPercentage,
381
+ textToAnchor,
382
+ spanToStyleNode,
383
+ _setDefaultOptionStyle,
384
+ _setIframeStyleLinks,
385
+ _setAutoHeightStyle
386
+ };
387
+
388
+ export default converter;