suneditor 2.46.1 → 3.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +174 -805
  6. package/dist/suneditor.min.css +1 -0
  7. package/dist/suneditor.min.js +1 -2
  8. package/package.json +96 -70
  9. package/src/assets/icons/_default.js +194 -0
  10. package/src/assets/suneditor-content.css +646 -0
  11. package/src/assets/suneditor.css +3378 -0
  12. package/src/core/base/eventHandlers/handler_toolbar.js +114 -0
  13. package/src/core/base/eventHandlers/handler_ww_clipboard.js +31 -0
  14. package/src/core/base/eventHandlers/handler_ww_dragDrop.js +69 -0
  15. package/src/core/base/eventHandlers/handler_ww_key_input.js +975 -0
  16. package/src/core/base/eventHandlers/handler_ww_mouse.js +118 -0
  17. package/src/core/base/eventManager.js +1115 -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 +146 -0
  21. package/src/core/class/component.js +627 -0
  22. package/src/core/class/format.js +3255 -0
  23. package/src/core/class/html.js +1621 -0
  24. package/src/core/class/menu.js +260 -0
  25. package/src/core/class/nodeTransform.js +379 -0
  26. package/src/core/class/notice.js +42 -0
  27. package/src/core/class/offset.js +578 -0
  28. package/src/core/class/selection.js +508 -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 +1593 -0
  33. package/src/core/section/actives.js +107 -0
  34. package/src/core/section/constructor.js +1237 -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 +313 -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 +199 -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 +162 -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 +315 -0
  72. package/src/modules/Figure.js +1160 -0
  73. package/src/modules/FileBrowser.js +271 -0
  74. package/src/modules/FileManager.js +290 -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 +73 -0
  88. package/src/plugins/dropdown/font.js +113 -0
  89. package/src/plugins/dropdown/fontColor.js +73 -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 +172 -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 +510 -0
  104. package/src/plugins/modal/image.js +1062 -0
  105. package/src/plugins/modal/link.js +211 -0
  106. package/src/plugins/modal/math.js +347 -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
@@ -1,954 +0,0 @@
1
- /*
2
- * wysiwyg web editor
3
- *
4
- * suneditor.js
5
- * Copyright 2017 JiHong Lee.
6
- * MIT license.
7
- */
8
- 'use strict';
9
-
10
- import _icons from '../assets/defaultIcons';
11
- import _defaultLang from '../lang/en';
12
- import util from './util';
13
-
14
- export default {
15
- /**
16
- * @description document create
17
- * @param {Element} element Textarea
18
- * @param {Object} options Options
19
- * @returns {Object}
20
- */
21
- init: function (element, options) {
22
- if (typeof options !== 'object') options = {};
23
-
24
- const doc = document;
25
-
26
- /** --- init options --- */
27
- this._initOptions(element, options);
28
-
29
- // suneditor div
30
- const top_div = doc.createElement('DIV');
31
- top_div.className = 'sun-editor' + (options.rtl ? ' se-rtl' : '');
32
- if (element.id) top_div.id = 'suneditor_' + element.id;
33
-
34
- // relative div
35
- const relative = doc.createElement('DIV');
36
- relative.className = 'se-container';
37
-
38
- // toolbar
39
- const tool_bar = this._createToolBar(doc, options.buttonList, options.plugins, options);
40
- const toolbarShadow = tool_bar.element.cloneNode(false);
41
- toolbarShadow.className += ' se-toolbar-shadow';
42
- tool_bar.element.style.visibility = 'hidden';
43
- if (tool_bar.pluginCallButtons.math) this._checkKatexMath(options.katex);
44
- const arrow = doc.createElement('DIV');
45
- arrow.className = 'se-arrow';
46
-
47
- // sticky toolbar dummy
48
- const sticky_dummy = doc.createElement('DIV');
49
- sticky_dummy.className = 'se-toolbar-sticky-dummy';
50
-
51
- // inner editor div
52
- const editor_div = doc.createElement('DIV');
53
- editor_div.className = 'se-wrapper';
54
-
55
- /** --- init elements and create bottom bar --- */
56
- const initElements = this._initElements(options, top_div, tool_bar.element, arrow);
57
-
58
- const bottomBar = initElements.bottomBar;
59
- const wysiwyg_div = initElements.wysiwygFrame;
60
- const placeholder_span = initElements.placeholder;
61
- let textarea = initElements.codeView;
62
-
63
- // resizing bar
64
- const resizing_bar = bottomBar.resizingBar;
65
- const navigation = bottomBar.navigation;
66
- const char_wrapper = bottomBar.charWrapper;
67
- const char_counter = bottomBar.charCounter;
68
-
69
- // loading box
70
- const loading_box = doc.createElement('DIV');
71
- loading_box.className = 'se-loading-box sun-editor-common';
72
- loading_box.innerHTML = '<div class="se-loading-effect"></div>';
73
-
74
- // enter line
75
- const line_breaker = doc.createElement('DIV');
76
- line_breaker.className = 'se-line-breaker';
77
- line_breaker.innerHTML = '<button class="se-btn">' + options.icons.line_break + '</button>';
78
- const line_breaker_t = doc.createElement('DIV');
79
- line_breaker_t.className += 'se-line-breaker-component';
80
- const line_breaker_b = line_breaker_t.cloneNode(true);
81
- line_breaker_t.innerHTML = line_breaker_b.innerHTML = options.icons.line_break;
82
-
83
- // resize operation background
84
- const resize_back = doc.createElement('DIV');
85
- resize_back.className = 'se-resizing-back';
86
-
87
- /// focus temp
88
- const focusTemp = doc.createElement('INPUT');
89
- focusTemp.tabIndex = -1;
90
- focusTemp.style.cssText = 'position: absolute !important; top: -10000px !important; display: block !important; width: 0 !important; height: 0 !important; margin: 0 !important; padding: 0 !important;';
91
-
92
- // toolbar container
93
- const toolbarContainer = options.toolbarContainer;
94
- if (toolbarContainer) {
95
- toolbarContainer.appendChild(tool_bar.element);
96
- toolbarContainer.appendChild(toolbarShadow);
97
- }
98
-
99
- // resizingbar
100
- const resizingBarContainer = options.resizingBarContainer;
101
- if (resizing_bar && resizingBarContainer) resizingBarContainer.appendChild(resizing_bar);
102
-
103
- /** append html */
104
- editor_div.appendChild(textarea);
105
- if (placeholder_span) editor_div.appendChild(placeholder_span);
106
- if (!toolbarContainer) {
107
- relative.appendChild(tool_bar.element);
108
- relative.appendChild(toolbarShadow);
109
- }
110
- relative.appendChild(sticky_dummy);
111
- relative.appendChild(editor_div);
112
- relative.appendChild(resize_back);
113
- relative.appendChild(loading_box);
114
- relative.appendChild(line_breaker);
115
- relative.appendChild(line_breaker_t);
116
- relative.appendChild(line_breaker_b);
117
- relative.appendChild(focusTemp);
118
- if (resizing_bar && !resizingBarContainer) relative.appendChild(resizing_bar);
119
- top_div.appendChild(relative);
120
-
121
- textarea = this._checkCodeMirror(options, textarea);
122
-
123
- return {
124
- constructed: {
125
- _top: top_div,
126
- _relative: relative,
127
- _toolBar: tool_bar.element,
128
- _toolbarShadow: toolbarShadow,
129
- _menuTray: tool_bar._menuTray,
130
- _editorArea: editor_div,
131
- _wysiwygArea: wysiwyg_div,
132
- _codeArea: textarea,
133
- _placeholder: placeholder_span,
134
- _resizingBar: resizing_bar,
135
- _navigation: navigation,
136
- _charWrapper: char_wrapper,
137
- _charCounter: char_counter,
138
- _loading: loading_box,
139
- _lineBreaker: line_breaker,
140
- _lineBreaker_t: line_breaker_t,
141
- _lineBreaker_b: line_breaker_b,
142
- _resizeBack: resize_back,
143
- _stickyDummy: sticky_dummy,
144
- _arrow: arrow,
145
- _focusTemp: focusTemp
146
- },
147
- options: options,
148
- plugins: tool_bar.plugins,
149
- pluginCallButtons: tool_bar.pluginCallButtons,
150
- _responsiveButtons: tool_bar.responsiveButtons
151
- };
152
- },
153
-
154
- /**
155
- * @description Check the CodeMirror option to apply the CodeMirror and return the CodeMirror element.
156
- * @param {Object} options options
157
- * @param {Element} textarea textarea element
158
- * @private
159
- */
160
- _checkCodeMirror: function (options, textarea) {
161
- if (options.codeMirror) {
162
- const cmOptions = [{
163
- mode: 'htmlmixed',
164
- htmlMode: true,
165
- lineNumbers: true,
166
- lineWrapping: true
167
- }, (options.codeMirror.options || {})].reduce(function (init, option) {
168
- for (let key in option) {
169
- if (util.hasOwn(option, key)) init[key] = option[key];
170
- }
171
- return init;
172
- }, {});
173
-
174
- if (options.height === 'auto') {
175
- cmOptions.viewportMargin = Infinity;
176
- cmOptions.height = 'auto';
177
- }
178
-
179
- const cm = options.codeMirror.src.fromTextArea(textarea, cmOptions);
180
- cm.display.wrapper.style.cssText = textarea.style.cssText;
181
-
182
- options.codeMirrorEditor = cm;
183
- textarea = cm.display.wrapper;
184
- textarea.className += ' se-wrapper-code-mirror';
185
- }
186
-
187
- return textarea;
188
- },
189
-
190
- /**
191
- * @description Check for a katex object.
192
- * @param {Object} katex katex object
193
- * @private
194
- */
195
- _checkKatexMath: function (katex) {
196
- if (!katex) throw Error('[SUNEDITOR.create.fail] To use the math button you need to add a "katex" object to the options.');
197
-
198
- const katexOptions = [{
199
- throwOnError: false,
200
- }, (katex.options || {})].reduce(function (init, option) {
201
- for (let key in option) {
202
- if (util.hasOwn(option, key)) init[key] = option[key];
203
- }
204
- return init;
205
- }, {});
206
-
207
- katex.options = katexOptions;
208
- },
209
-
210
- /**
211
- * @description Add or reset options
212
- * @param {Object} mergeOptions New options property
213
- * @param {Object} context Context object of core
214
- * @param {Object} originOptions Origin options
215
- * @returns {Object} pluginCallButtons
216
- * @private
217
- */
218
- _setOptions: function (mergeOptions, context, originOptions) {
219
- this._initOptions(context.element.originElement, mergeOptions);
220
-
221
- const el = context.element;
222
- const relative = el.relative;
223
- const editorArea = el.editorArea;
224
- const isNewToolbarContainer = mergeOptions.toolbarContainer && mergeOptions.toolbarContainer !== originOptions.toolbarContainer;
225
- const isNewToolbar = mergeOptions.lang !== originOptions.lang || mergeOptions.buttonList !== originOptions.buttonList || mergeOptions.mode !== originOptions.mode || isNewToolbarContainer;
226
-
227
- const tool_bar = this._createToolBar(document, (isNewToolbar ? mergeOptions.buttonList : originOptions.buttonList), mergeOptions.plugins, mergeOptions);
228
- if (tool_bar.pluginCallButtons.math) this._checkKatexMath(mergeOptions.katex);
229
- const arrow = document.createElement('DIV');
230
- arrow.className = 'se-arrow';
231
-
232
- if (isNewToolbar) {
233
- tool_bar.element.style.visibility = 'hidden';
234
- // toolbar container
235
- if (isNewToolbarContainer) {
236
- mergeOptions.toolbarContainer.appendChild(tool_bar.element);
237
- el.toolbar.parentElement.removeChild(el.toolbar);
238
- } else {
239
- el.toolbar.parentElement.replaceChild(tool_bar.element, el.toolbar);
240
- }
241
-
242
- el.toolbar = tool_bar.element;
243
- el._menuTray = tool_bar._menuTray;
244
- el._arrow = arrow;
245
- }
246
-
247
- const initElements = this._initElements(mergeOptions, el.topArea, (isNewToolbar ? tool_bar.element : el.toolbar), arrow);
248
-
249
- const bottomBar = initElements.bottomBar;
250
- const wysiwygFrame = initElements.wysiwygFrame;
251
- const placeholder_span = initElements.placeholder;
252
- let code = initElements.codeView;
253
-
254
- if (el.resizingBar) util.removeItem(el.resizingBar);
255
- if (bottomBar.resizingBar) {
256
- if (mergeOptions.resizingBarContainer && mergeOptions.resizingBarContainer !== originOptions.resizingBarContainer) {
257
- mergeOptions.resizingBarContainer.appendChild(bottomBar.resizingBar);
258
- } else {
259
- relative.appendChild(bottomBar.resizingBar);
260
- }
261
- }
262
-
263
- editorArea.innerHTML = '';
264
- editorArea.appendChild(code);
265
- if (placeholder_span) editorArea.appendChild(placeholder_span);
266
-
267
- code = this._checkCodeMirror(mergeOptions, code);
268
-
269
- el.resizingBar = bottomBar.resizingBar;
270
- el.navigation = bottomBar.navigation;
271
- el.charWrapper = bottomBar.charWrapper;
272
- el.charCounter = bottomBar.charCounter;
273
- el.wysiwygFrame = wysiwygFrame;
274
- el.code = code;
275
- el.placeholder = placeholder_span;
276
-
277
- if (mergeOptions.rtl) util.addClass(el.topArea, 'se-rtl');
278
- else util.removeClass(el.topArea, 'se-rtl');
279
-
280
- return {
281
- callButtons: tool_bar.pluginCallButtons,
282
- plugins: tool_bar.plugins,
283
- toolbar: tool_bar
284
- };
285
- },
286
-
287
- /**
288
- * @description Initialize property of suneditor elements
289
- * @param {Object} options Options
290
- * @param {Element} topDiv Suneditor top div
291
- * @param {Element} toolBar Tool bar
292
- * @param {Element} toolBarArrow Tool bar arrow (balloon editor)
293
- * @returns {Object} Bottom bar elements (resizingBar, navigation, charWrapper, charCounter)
294
- * @private
295
- */
296
- _initElements: function (options, topDiv, toolBar, toolBarArrow) {
297
- /** top div */
298
- topDiv.style.cssText = options._editorStyles.top;
299
-
300
- /** toolbar */
301
- if (/inline/i.test(options.mode)) {
302
- toolBar.className += ' se-toolbar-inline';
303
- toolBar.style.width = options.toolbarWidth;
304
- } else if (/balloon/i.test(options.mode)) {
305
- toolBar.className += ' se-toolbar-balloon';
306
- toolBar.style.width = options.toolbarWidth;
307
- toolBar.appendChild(toolBarArrow);
308
- }
309
-
310
- /** editor */
311
- // wysiwyg div or iframe
312
- const wysiwygDiv = document.createElement(!options.iframe ? 'DIV' : 'IFRAME');
313
- wysiwygDiv.className = 'se-wrapper-inner se-wrapper-wysiwyg';
314
-
315
- if (!options.iframe) {
316
- wysiwygDiv.setAttribute('contenteditable', true);
317
- wysiwygDiv.setAttribute('autocorrect', "off");
318
- wysiwygDiv.setAttribute('scrolling', 'auto');
319
- for (let key in options.iframeAttributes) {
320
- wysiwygDiv.setAttribute(key, options.iframeAttributes[key]);
321
- }
322
- wysiwygDiv.className += ' ' + options._editableClass;
323
- wysiwygDiv.style.cssText = options._editorStyles.frame + options._editorStyles.editor;
324
- wysiwygDiv.className += options.className;
325
- } else {
326
- wysiwygDiv.allowFullscreen = true;
327
- wysiwygDiv.frameBorder = 0;
328
- wysiwygDiv.style.cssText = options._editorStyles.frame;
329
- wysiwygDiv.className += options.className;
330
- }
331
-
332
- // textarea for code view
333
- const textarea = document.createElement('TEXTAREA');
334
- textarea.className = 'se-wrapper-inner se-wrapper-code' + options.className;
335
- textarea.style.cssText = options._editorStyles.frame;
336
- textarea.style.display = 'none';
337
- if (options.height === 'auto') textarea.style.overflow = 'hidden';
338
-
339
- /** resize bar */
340
- let resizingBar = null;
341
- let navigation = null;
342
- let charWrapper = null;
343
- let charCounter = null;
344
- if (options.resizingBar) {
345
- resizingBar = document.createElement('DIV');
346
- resizingBar.className = 'se-resizing-bar sun-editor-common';
347
-
348
- /** navigation */
349
- navigation = document.createElement('DIV');
350
- navigation.className = 'se-navigation sun-editor-common';
351
- resizingBar.appendChild(navigation);
352
-
353
- /** char counter */
354
- if (options.charCounter) {
355
- charWrapper = document.createElement('DIV');
356
- charWrapper.className = 'se-char-counter-wrapper';
357
-
358
- if (options.charCounterLabel) {
359
- const charLabel = document.createElement('SPAN');
360
- charLabel.className = 'se-char-label';
361
- charLabel.textContent = options.charCounterLabel;
362
- charWrapper.appendChild(charLabel);
363
- }
364
-
365
- charCounter = document.createElement('SPAN');
366
- charCounter.className = 'se-char-counter';
367
- charCounter.textContent = '0';
368
- charWrapper.appendChild(charCounter);
369
-
370
- if (options.maxCharCount > 0) {
371
- const char_max = document.createElement('SPAN');
372
- char_max.textContent = ' / ' + options.maxCharCount;
373
- charWrapper.appendChild(char_max);
374
- }
375
-
376
- resizingBar.appendChild(charWrapper);
377
- }
378
- }
379
-
380
- let placeholder = null;
381
- if (options.placeholder) {
382
- placeholder = document.createElement('SPAN');
383
- placeholder.className = 'se-placeholder';
384
- placeholder.innerText = options.placeholder;
385
- }
386
-
387
- return {
388
- bottomBar: {
389
- resizingBar: resizingBar,
390
- navigation: navigation,
391
- charWrapper: charWrapper,
392
- charCounter: charCounter
393
- },
394
- wysiwygFrame: wysiwygDiv,
395
- codeView: textarea,
396
- placeholder: placeholder
397
- };
398
- },
399
-
400
- /**
401
- * @description Initialize options
402
- * @param {Element} element Options object
403
- * @param {Object} options Options object
404
- * @private
405
- */
406
- _initOptions: function (element, options) {
407
- const plugins = {};
408
- if (options.plugins) {
409
- const _plugins = options.plugins;
410
- const pluginsValues = _plugins.length ? _plugins : Object.keys(_plugins).map(function(name) { return _plugins[name]; });
411
- for (let i = 0, len = pluginsValues.length, p; i < len; i++) {
412
- p = pluginsValues[i].default || pluginsValues[i];
413
- plugins[p.name] = p;
414
- }
415
- }
416
- options.plugins = plugins;
417
- /** Values */
418
- options.strictMode = options.strictMode !== false;
419
- options.lang = options.lang || _defaultLang;
420
- options.value = typeof options.value === 'string' ? options.value : null;
421
- options.allowedClassNames = new util._w.RegExp((options.allowedClassNames && typeof options.allowedClassNames === 'string' ? options.allowedClassNames + '|' : '') + '^__se__|se-|katex');
422
- options.historyStackDelayTime = typeof options.historyStackDelayTime === 'number' ? options.historyStackDelayTime : 400;
423
- options.frameAttrbutes = options.frameAttrbutes || {};
424
- // tag style
425
- options.defaultTag = typeof options.defaultTag === 'string' && options.defaultTag.length > 0 ? options.defaultTag : 'p';
426
- const textTags = options.textTags = [{bold: 'STRONG', underline: 'U', italic: 'EM', strike: 'DEL', sub: 'SUB', sup: 'SUP'}, (options.textTags || {})].reduce(function (_default, _new) {
427
- for (let key in _new) {
428
- _default[key] = _new[key];
429
- }
430
- return _default;
431
- }, {});
432
- options._textTagsMap = {
433
- 'strong': textTags.bold.toLowerCase(),
434
- 'b': textTags.bold.toLowerCase(),
435
- 'u': textTags.underline.toLowerCase(),
436
- 'ins': textTags.underline.toLowerCase(),
437
- 'em': textTags.italic.toLowerCase(),
438
- 'i': textTags.italic.toLowerCase(),
439
- 'del': textTags.strike.toLowerCase(),
440
- 'strike': textTags.strike.toLowerCase(),
441
- 's': textTags.strike.toLowerCase(),
442
- 'sub': textTags.sub.toLowerCase(),
443
- 'sup': textTags.sup.toLowerCase()
444
- };
445
- options._defaultCommand = {
446
- bold: options.textTags.bold,
447
- underline: options.textTags.underline,
448
- italic: options.textTags.italic,
449
- strike: options.textTags.strike,
450
- subscript: options.textTags.sub,
451
- superscript: options.textTags.sup
452
- };
453
- /** Whitelist, Blacklist */
454
- options.__allowedScriptTag = options.__allowedScriptTag === true;
455
- const whitelist = 'br|p|div|pre|blockquote|h1|h2|h3|h4|h5|h6|ol|ul|li|hr|figure|figcaption|img|iframe|audio|video|source|table|thead|tbody|tr|th|td|a|b|strong|var|i|em|u|ins|s|span|strike|del|sub|sup|code|svg|path|details|summary';
456
- // tags
457
- options.tagsBlacklist = options.tagsBlacklist || '';
458
- options._defaultTagsWhitelist = (typeof options._defaultTagsWhitelist === 'string' ? options._defaultTagsWhitelist : whitelist) + (options.__allowedScriptTag ? '|script' : '');
459
- options._editorTagsWhitelist = options.addTagsWhitelist === '*' ? '*' : this._setWhitelist(options._defaultTagsWhitelist + (typeof options.addTagsWhitelist === 'string' && options.addTagsWhitelist.length > 0 ? '|' + options.addTagsWhitelist : ''), options.tagsBlacklist);
460
- // paste tags
461
- options.pasteTagsBlacklist = options.tagsBlacklist + (options.tagsBlacklist && options.pasteTagsBlacklist ? ('|' + options.pasteTagsBlacklist) : (options.pasteTagsBlacklist || ''));
462
- options.pasteTagsWhitelist = options.pasteTagsWhitelist === '*' ? '*' : this._setWhitelist(typeof options.pasteTagsWhitelist === 'string' ? options.pasteTagsWhitelist : options._editorTagsWhitelist, options.pasteTagsBlacklist);
463
- // tag attributes
464
- options.attributesWhitelist = (!options.attributesWhitelist || typeof options.attributesWhitelist !== 'object') ? null : options.attributesWhitelist;
465
- options.attributesBlacklist = (!options.attributesBlacklist || typeof options.attributesBlacklist !== 'object') ? null : options.attributesBlacklist;
466
- /** Layout */
467
- options.mode = options.mode || 'classic'; // classic, inline, balloon, balloon-always
468
- options.rtl = !!options.rtl;
469
- options.lineAttrReset = ['id'].concat((options.lineAttrReset && typeof options.lineAttrReset === 'string' ? options.lineAttrReset.toLowerCase().split('|') : []));
470
- options._editableClass = 'sun-editor-editable' + (options.rtl ? ' se-rtl' : '');
471
- options._printClass = typeof options._printClass === 'string' ? options._printClass : null;
472
- options.toolbarWidth = options.toolbarWidth ? (util.isNumber(options.toolbarWidth) ? options.toolbarWidth + 'px' : options.toolbarWidth) : 'auto';
473
- options.toolbarContainer = typeof options.toolbarContainer === 'string' ? document.querySelector(options.toolbarContainer) : options.toolbarContainer;
474
- options.stickyToolbar = (/balloon/i.test(options.mode) || !!options.toolbarContainer) ? -1 : options.stickyToolbar === undefined ? 0 : (/^\d+/.test(options.stickyToolbar) ? util.getNumber(options.stickyToolbar, 0) : -1);
475
- options.hideToolbar = !!options.hideToolbar;
476
- options.fullScreenOffset = options.fullScreenOffset === undefined ? 0 : (/^\d+/.test(options.fullScreenOffset) ? util.getNumber(options.fullScreenOffset, 0) : 0);
477
- options.fullPage = !!options.fullPage;
478
- options.iframe = options.fullPage || !!options.iframe;
479
- options.iframeAttributes = options.iframeAttributes || {};
480
- options.iframeCSSFileName = options.iframe ? typeof options.iframeCSSFileName === 'string' ? [options.iframeCSSFileName] : (options.iframeCSSFileName || ['suneditor']) : null;
481
- options.previewTemplate = typeof options.previewTemplate === 'string' ? options.previewTemplate : null;
482
- options.printTemplate = typeof options.printTemplate === 'string' ? options.printTemplate : null;
483
- /** CodeMirror object */
484
- options.codeMirror = options.codeMirror ? options.codeMirror.src ? options.codeMirror : {src: options.codeMirror} : null;
485
- /** katex object (Math plugin) */
486
- options.katex = options.katex ? options.katex.src ? options.katex : {src: options.katex} : null;
487
- options.mathFontSize = !!options.mathFontSize ? options.mathFontSize : [
488
- {text: '1', value: '1em'},
489
- {text: '1.5', value: '1.5em'},
490
- {text: '2', value: '2em'},
491
- {text: '2.5', value: '2.5em'}
492
- ];
493
- /** Display */
494
- options.position = typeof options.position === 'string' ? options.position : null;
495
- options.display = options.display || (element.style.display === 'none' || !element.style.display ? 'block' : element.style.display);
496
- options.popupDisplay = options.popupDisplay || 'full';
497
- /** Bottom resizing bar */
498
- options.resizingBar = options.resizingBar === undefined ? (/inline|balloon/i.test(options.mode) ? false : true) : options.resizingBar;
499
- options.showPathLabel = !options.resizingBar ? false : typeof options.showPathLabel === 'boolean' ? options.showPathLabel : true;
500
- options.resizeEnable = options.resizeEnable === undefined ? true : !!options.resizeEnable;
501
- options.resizingBarContainer = typeof options.resizingBarContainer === 'string' ? document.querySelector(options.resizingBarContainer) : options.resizingBarContainer;
502
- /** Character count */
503
- options.charCounter = options.maxCharCount > 0 ? true : typeof options.charCounter === 'boolean' ? options.charCounter : false;
504
- options.charCounterType = typeof options.charCounterType === 'string' ? options.charCounterType : 'char';
505
- options.charCounterLabel = typeof options.charCounterLabel === 'string' ? options.charCounterLabel.trim() : null;
506
- options.maxCharCount = util.isNumber(options.maxCharCount) && options.maxCharCount > -1 ? options.maxCharCount * 1 : null;
507
- /** Width size */
508
- options.width = options.width ? (util.isNumber(options.width) ? options.width + 'px' : options.width) : (element.clientWidth ? element.clientWidth + 'px' : '100%');
509
- options.minWidth = (util.isNumber(options.minWidth) ? options.minWidth + 'px' : options.minWidth) || '';
510
- options.maxWidth = (util.isNumber(options.maxWidth) ? options.maxWidth + 'px' : options.maxWidth) || '';
511
- /** Height size */
512
- options.height = options.height ? (util.isNumber(options.height) ? options.height + 'px' : options.height) : (element.clientHeight ? element.clientHeight + 'px' : 'auto');
513
- options.minHeight = (util.isNumber(options.minHeight) ? options.minHeight + 'px' : options.minHeight) || '';
514
- options.maxHeight = (util.isNumber(options.maxHeight) ? options.maxHeight + 'px' : options.maxHeight) || '';
515
- /** Editing area */
516
- options.className = (typeof options.className === 'string' && options.className.length > 0) ? ' ' + options.className : '';
517
- options.defaultStyle = typeof options.defaultStyle === 'string' ? options.defaultStyle : '';
518
- /** Defining menu items */
519
- options.font = !options.font ? ['Arial', 'Comic Sans MS', 'Courier New', 'Impact', 'Georgia', 'tahoma', 'Trebuchet MS', 'Verdana'] : options.font;
520
- options.fontSize = !options.fontSize ? null : options.fontSize;
521
- options.formats = !options.formats ? null : options.formats;
522
- options.colorList = !options.colorList ? null : options.colorList;
523
- options.lineHeights = !options.lineHeights ? null : options.lineHeights;
524
- options.paragraphStyles = !options.paragraphStyles ? null : options.paragraphStyles;
525
- options.textStyles = !options.textStyles ? null : options.textStyles;
526
- options.fontSizeUnit = typeof options.fontSizeUnit === 'string' ? (options.fontSizeUnit.trim().toLowerCase() || 'px') : 'px';
527
- options.alignItems = typeof options.alignItems === 'object' ? options.alignItems : (options.rtl ? ['right', 'center', 'left', 'justify'] : ['left', 'center', 'right', 'justify']);
528
- /** Image */
529
- options.imageResizing = options.imageResizing === undefined ? true : options.imageResizing;
530
- options.imageHeightShow = options.imageHeightShow === undefined ? true : !!options.imageHeightShow;
531
- options.imageAlignShow = options.imageAlignShow === undefined ? true : !!options.imageAlignShow;
532
- options.imageWidth = !options.imageWidth ? 'auto' : util.isNumber(options.imageWidth) ? options.imageWidth + 'px' : options.imageWidth;
533
- options.imageHeight = !options.imageHeight ? 'auto' : util.isNumber(options.imageHeight) ? options.imageHeight + 'px' : options.imageHeight;
534
- options.imageSizeOnlyPercentage = !!options.imageSizeOnlyPercentage;
535
- options._imageSizeUnit = options.imageSizeOnlyPercentage ? '%' : 'px';
536
- options.imageRotation = options.imageRotation !== undefined ? options.imageRotation : !(options.imageSizeOnlyPercentage || !options.imageHeightShow);
537
- options.imageFileInput = options.imageFileInput === undefined ? true : options.imageFileInput;
538
- options.imageUrlInput = (options.imageUrlInput === undefined || !options.imageFileInput) ? true : options.imageUrlInput;
539
- options.imageUploadHeader = options.imageUploadHeader || null;
540
- options.imageUploadUrl = typeof options.imageUploadUrl === 'string' ? options.imageUploadUrl : null;
541
- options.imageUploadSizeLimit = /\d+/.test(options.imageUploadSizeLimit) ? util.getNumber(options.imageUploadSizeLimit, 0) : null;
542
- options.imageMultipleFile = !!options.imageMultipleFile;
543
- options.imageAccept = (typeof options.imageAccept !== 'string' || options.imageAccept.trim() === "*") ? 'image/*' : options.imageAccept.trim() || 'image/*';
544
- /** Image - image gallery */
545
- options.imageGalleryUrl = typeof options.imageGalleryUrl === 'string' ? options.imageGalleryUrl : null;
546
- options.imageGalleryHeader = options.imageGalleryHeader || null;
547
- /** Video */
548
- options.videoResizing = options.videoResizing === undefined ? true : options.videoResizing;
549
- options.videoHeightShow = options.videoHeightShow === undefined ? true : !!options.videoHeightShow;
550
- options.videoAlignShow = options.videoAlignShow === undefined ? true : !!options.videoAlignShow;
551
- options.videoRatioShow = options.videoRatioShow === undefined ? true : !!options.videoRatioShow;
552
- options.videoWidth = !options.videoWidth || !util.getNumber(options.videoWidth, 0) ? '' : util.isNumber(options.videoWidth) ? options.videoWidth + 'px' : options.videoWidth;
553
- options.videoHeight = !options.videoHeight || !util.getNumber(options.videoHeight, 0) ? '' : util.isNumber(options.videoHeight) ? options.videoHeight + 'px' : options.videoHeight;
554
- options.videoSizeOnlyPercentage = !!options.videoSizeOnlyPercentage;
555
- options._videoSizeUnit = options.videoSizeOnlyPercentage ? '%' : 'px';
556
- options.videoRotation = options.videoRotation !== undefined ? options.videoRotation : !(options.videoSizeOnlyPercentage || !options.videoHeightShow);
557
- options.videoRatio = (util.getNumber(options.videoRatio, 4) || 0.5625);
558
- options.videoRatioList = !options.videoRatioList ? null : options.videoRatioList;
559
- options.youtubeQuery = (options.youtubeQuery || '').replace('?', '');
560
- options.videoFileInput = !!options.videoFileInput;
561
- options.videoUrlInput = (options.videoUrlInput === undefined || !options.videoFileInput) ? true : options.videoUrlInput;
562
- options.videoUploadHeader = options.videoUploadHeader || null;
563
- options.videoUploadUrl = typeof options.videoUploadUrl === 'string' ? options.videoUploadUrl : null;
564
- options.videoUploadSizeLimit = /\d+/.test(options.videoUploadSizeLimit) ? util.getNumber(options.videoUploadSizeLimit, 0) : null;
565
- options.videoMultipleFile = !!options.videoMultipleFile;
566
- options.videoTagAttrs = options.videoTagAttrs || null;
567
- options.videoIframeAttrs = options.videoIframeAttrs || null;
568
- options.videoAccept = (typeof options.videoAccept !== 'string' || options.videoAccept.trim() === "*") ? 'video/*' : options.videoAccept.trim() || 'video/*';
569
- /** Audio */
570
- options.audioWidth = !options.audioWidth ? '' : util.isNumber(options.audioWidth) ? options.audioWidth + 'px' : options.audioWidth;
571
- options.audioHeight = !options.audioHeight ? '' : util.isNumber(options.audioHeight) ? options.audioHeight + 'px' : options.audioHeight;
572
- options.audioFileInput = !!options.audioFileInput;
573
- options.audioUrlInput = (options.audioUrlInput === undefined || !options.audioFileInput) ? true : options.audioUrlInput;
574
- options.audioUploadHeader = options.audioUploadHeader || null;
575
- options.audioUploadUrl = typeof options.audioUploadUrl === 'string' ? options.audioUploadUrl : null;
576
- options.audioUploadSizeLimit = /\d+/.test(options.audioUploadSizeLimit) ? util.getNumber(options.audioUploadSizeLimit, 0) : null;
577
- options.audioMultipleFile = !!options.audioMultipleFile;
578
- options.audioTagAttrs = options.audioTagAttrs || null;
579
- options.audioAccept = (typeof options.audioAccept !== 'string' || options.audioAccept.trim() === "*") ? 'audio/*' : options.audioAccept.trim() || 'audio/*';
580
- /** Table */
581
- options.tableCellControllerPosition = typeof options.tableCellControllerPosition === 'string' ? options.tableCellControllerPosition.toLowerCase() : 'cell';
582
- /** Link */
583
- options.linkTargetNewWindow = !!options.linkTargetNewWindow;
584
- options.linkProtocol = typeof options.linkProtocol === 'string' ? options.linkProtocol : null;
585
- options.linkRel = Array.isArray(options.linkRel) ? options.linkRel : [];
586
- options.linkRelDefault = options.linkRelDefault || {};
587
- /** HR */
588
- // options.hrItems = options.hrItems;
589
- /** Key actions */
590
- options.tabDisable = !!options.tabDisable;
591
- options.shortcutsDisable = Array.isArray(options.shortcutsDisable) ? options.shortcutsDisable : [];
592
- options.shortcutsHint = options.shortcutsHint === undefined ? true : !!options.shortcutsHint;
593
- /** Defining save button */
594
- options.callBackSave = !options.callBackSave ? null : options.callBackSave;
595
- /** Templates Array */
596
- options.templates = !options.templates ? null : options.templates;
597
- /** ETC */
598
- options.placeholder = typeof options.placeholder === 'string' ? options.placeholder : null;
599
- options.mediaAutoSelect = options.mediaAutoSelect === undefined ? true : !!options.mediaAutoSelect;
600
- /** Buttons */
601
- options.buttonList = !!options.buttonList ? options.buttonList : [
602
- ['undo', 'redo'],
603
- ['bold', 'underline', 'italic', 'strike', 'subscript', 'superscript'],
604
- ['removeFormat'],
605
- ['outdent', 'indent'],
606
- ['fullScreen', 'showBlocks', 'codeView'],
607
- ['preview', 'print']
608
- ];
609
-
610
- /** RTL - buttons */
611
- if (options.rtl) {
612
- options.buttonList = options.buttonList.reverse();
613
- }
614
-
615
- /** --- Define icons --- */
616
- // custom icons
617
- options.icons = (!options.icons || typeof options.icons !== 'object') ? _icons : [_icons, options.icons].reduce(function (_default, _new) {
618
- for (let key in _new) {
619
- if (util.hasOwn(_new, key)) _default[key] = _new[key];
620
- }
621
- return _default;
622
- }, {});
623
- // rtl icons
624
- options.icons = !options.rtl ? options.icons : [options.icons, options.icons.rtl].reduce(function (_default, _new) {
625
- for (let key in _new) {
626
- if (util.hasOwn(_new, key)) _default[key] = _new[key];
627
- }
628
- return _default;
629
- }, {});
630
-
631
- /** Private options */
632
- options.__listCommonStyle = options.__listCommonStyle || ['fontSize', 'color', 'fontFamily', 'fontWeight', 'fontStyle'];
633
-
634
- /** _init options */
635
- options._editorStyles = util._setDefaultOptionStyle(options, options.defaultStyle);
636
- },
637
-
638
- _setWhitelist: function (whitelist, blacklist) {
639
- if (typeof blacklist !== 'string') return whitelist;
640
- blacklist = blacklist.split('|');
641
- whitelist = whitelist.split('|');
642
- for (let i = 0, len = blacklist.length, index; i < len; i++) {
643
- index = whitelist.indexOf(blacklist[i]);
644
- if (index > -1) whitelist.splice(index, 1);
645
- }
646
- return whitelist.join('|');
647
- },
648
-
649
- /**
650
- * @description Suneditor's Default button list
651
- * @param {Object} options options
652
- * @private
653
- */
654
- _defaultButtons: function (options) {
655
- const icons = options.icons;
656
- const lang = options.lang;
657
- const cmd = util.isOSX_IOS ? '⌘' : 'CTRL';
658
- const addShift = util.isOSX_IOS ? '⇧' : '+SHIFT';
659
- const shortcutsDisable = !options.shortcutsHint ? ['bold', 'strike', 'underline', 'italic', 'undo', 'indent', 'save'] : options.shortcutsDisable;
660
- const indentKey = options.rtl ? ['[',']'] : [']','['];
661
- const indentIcon = options.rtl ? [icons.outdent, icons.indent] : [icons.indent, icons.outdent];
662
-
663
- return {
664
- /** default command */
665
- bold: ['', lang.toolbar.bold + '<span class="se-shortcut">' + (shortcutsDisable.indexOf('bold') > -1 ? '' : cmd + '+<span class="se-shortcut-key">B</span>') + '</span>', 'bold', '', icons.bold],
666
- underline: ['', lang.toolbar.underline + '<span class="se-shortcut">' + (shortcutsDisable.indexOf('underline') > -1 ? '' : cmd + '+<span class="se-shortcut-key">U</span>') + '</span>', 'underline', '', icons.underline],
667
- italic: ['', lang.toolbar.italic + '<span class="se-shortcut">' + (shortcutsDisable.indexOf('italic') > -1 ? '' : cmd + '+<span class="se-shortcut-key">I</span>') + '</span>', 'italic', '', icons.italic],
668
- strike: ['', lang.toolbar.strike + '<span class="se-shortcut">' + (shortcutsDisable.indexOf('strike') > -1 ? '' : cmd + addShift + '+<span class="se-shortcut-key">S</span>') + '</span>', 'strike', '', icons.strike],
669
- subscript: ['', lang.toolbar.subscript, 'SUB', '', icons.subscript],
670
- superscript: ['', lang.toolbar.superscript, 'SUP', '', icons.superscript],
671
- removeFormat: ['', lang.toolbar.removeFormat, 'removeFormat', '', icons.erase],
672
- indent: ['', lang.toolbar.indent + '<span class="se-shortcut">' + (shortcutsDisable.indexOf('indent') > -1 ? '' : cmd + '+<span class="se-shortcut-key">' + indentKey[0] + '</span>') + '</span>', 'indent', '', indentIcon[0]],
673
- outdent: ['', lang.toolbar.outdent + '<span class="se-shortcut">' + (shortcutsDisable.indexOf('indent') > -1 ? '' : cmd + '+<span class="se-shortcut-key">' + indentKey[1] + '</span>') + '</span>', 'outdent', '', indentIcon[1]],
674
- fullScreen: ['se-code-view-enabled se-resizing-enabled', lang.toolbar.fullScreen, 'fullScreen', '', icons.expansion],
675
- showBlocks: ['', lang.toolbar.showBlocks, 'showBlocks', '', icons.show_blocks],
676
- codeView: ['se-code-view-enabled se-resizing-enabled', lang.toolbar.codeView, 'codeView', '', icons.code_view],
677
- undo: ['', lang.toolbar.undo + '<span class="se-shortcut">' + (shortcutsDisable.indexOf('undo') > -1 ? '' : cmd + '+<span class="se-shortcut-key">Z</span>') + '</span>', 'undo', '', icons.undo],
678
- redo: ['', lang.toolbar.redo + '<span class="se-shortcut">' + (shortcutsDisable.indexOf('undo') > -1 ? '' : cmd + '+<span class="se-shortcut-key">Y</span> / ' + cmd + addShift + '+<span class="se-shortcut-key">Z</span>') + '</span>', 'redo', '', icons.redo],
679
- preview: ['se-resizing-enabled', lang.toolbar.preview, 'preview', '', icons.preview],
680
- print: ['se-resizing-enabled', lang.toolbar.print, 'print', '', icons.print],
681
- dir: ['', lang.toolbar[options.rtl ? 'dir_ltr' : 'dir_rtl'], 'dir', '', icons[options.rtl ? 'dir_ltr' : 'dir_rtl']],
682
- dir_ltr: ['', lang.toolbar.dir_ltr, 'dir_ltr', '', icons.dir_ltr],
683
- dir_rtl: ['', lang.toolbar.dir_rtl, 'dir_rtl', '', icons.dir_rtl],
684
- save: ['se-resizing-enabled', lang.toolbar.save + '<span class="se-shortcut">' + (shortcutsDisable.indexOf('save') > -1 ? '' : cmd + '+<span class="se-shortcut-key">S</span>') + '</span>', 'save', '', icons.save],
685
- /** plugins - command */
686
- blockquote: ['', lang.toolbar.tag_blockquote, 'blockquote', 'command', icons.blockquote],
687
- /** plugins - submenu */
688
- font: ['se-btn-select se-btn-tool-font', lang.toolbar.font, 'font', 'submenu', '<span class="txt">' + lang.toolbar.font + '</span>' + icons.arrow_down],
689
- formatBlock: ['se-btn-select se-btn-tool-format', lang.toolbar.formats, 'formatBlock', 'submenu', '<span class="txt">' + lang.toolbar.formats + '</span>' + icons.arrow_down],
690
- fontSize: ['se-btn-select se-btn-tool-size', lang.toolbar.fontSize, 'fontSize', 'submenu', '<span class="txt">' + lang.toolbar.fontSize + '</span>' + icons.arrow_down],
691
- fontColor: ['', lang.toolbar.fontColor, 'fontColor', 'submenu', icons.font_color],
692
- hiliteColor: ['', lang.toolbar.hiliteColor, 'hiliteColor', 'submenu', icons.highlight_color],
693
- align: ['se-btn-align', lang.toolbar.align, 'align', 'submenu', (options.rtl ? icons.align_right : icons.align_left)],
694
- list: ['', lang.toolbar.list, 'list', 'submenu', icons.list_number],
695
- horizontalRule: ['btn_line', lang.toolbar.horizontalRule, 'horizontalRule', 'submenu', icons.horizontal_rule],
696
- table: ['', lang.toolbar.table, 'table', 'submenu', icons.table],
697
- lineHeight: ['', lang.toolbar.lineHeight, 'lineHeight', 'submenu', icons.line_height],
698
- template: ['', lang.toolbar.template, 'template', 'submenu', icons.template],
699
- paragraphStyle: ['', lang.toolbar.paragraphStyle, 'paragraphStyle', 'submenu', icons.paragraph_style],
700
- textStyle: ['', lang.toolbar.textStyle, 'textStyle', 'submenu', icons.text_style],
701
- /** plugins - dialog */
702
- link: ['', lang.toolbar.link, 'link', 'dialog', icons.link],
703
- image: ['', lang.toolbar.image, 'image', 'dialog', icons.image],
704
- video: ['', lang.toolbar.video, 'video', 'dialog', icons.video],
705
- audio: ['', lang.toolbar.audio, 'audio', 'dialog', icons.audio],
706
- math: ['', lang.toolbar.math, 'math', 'dialog', icons.math],
707
- /** plugins - fileBrowser */
708
- imageGallery: ['', lang.toolbar.imageGallery, 'imageGallery', 'fileBrowser', icons.image_gallery]
709
- };
710
- },
711
-
712
- /**
713
- * @description Create a group div containing each module
714
- * @returns {Object}
715
- * @private
716
- */
717
- _createModuleGroup: function () {
718
- const oDiv = util.createElement('DIV');
719
- oDiv.className = 'se-btn-module se-btn-module-border';
720
-
721
- const oUl = util.createElement('UL');
722
- oUl.className = 'se-menu-list';
723
- oDiv.appendChild(oUl);
724
-
725
- return {
726
- 'div': oDiv,
727
- 'ul': oUl
728
- };
729
- },
730
-
731
- /**
732
- * @description Create a button element
733
- * @param {string} buttonClass className in button
734
- * @param {string} title Title in button
735
- * @param {string} dataCommand The data-command property of the button
736
- * @param {string} dataDisplay The data-display property of the button ('dialog', 'submenu', 'command')
737
- * @param {string} innerHTML Html in button
738
- * @param {string} _disabled Button disabled
739
- * @param {Object} _icons Icons
740
- * @returns {Object}
741
- * @private
742
- */
743
- _createButton: function (buttonClass, title, dataCommand, dataDisplay, innerHTML, _disabled, _icons) {
744
- const oLi = util.createElement('LI');
745
- const oButton = util.createElement('BUTTON');
746
- const label = (title || dataCommand);
747
-
748
- oButton.setAttribute('type', 'button');
749
- oButton.setAttribute('class', 'se-btn' + (buttonClass ? ' ' + buttonClass : '') + ' se-tooltip');
750
- oButton.setAttribute('data-command', dataCommand);
751
- oButton.setAttribute('data-display', dataDisplay);
752
- oButton.setAttribute('aria-label', label.replace(/<span .+<\/span>/, ''));
753
- oButton.setAttribute('tabindex', '-1');
754
-
755
- if (!innerHTML) innerHTML = '<span class="se-icon-text">!</span>';
756
- if (/^default\./i.test(innerHTML)) {
757
- innerHTML = _icons[innerHTML.replace(/^default\./i, '')];
758
- }
759
- if (/^text\./i.test(innerHTML)) {
760
- innerHTML = innerHTML.replace(/^text\./i, '');
761
- oButton.className += ' se-btn-more-text';
762
- }
763
-
764
- innerHTML += '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + label + '</span></span>';
765
-
766
- if (_disabled) oButton.setAttribute('disabled', true);
767
-
768
- oButton.innerHTML = innerHTML;
769
- oLi.appendChild(oButton);
770
-
771
- return {
772
- 'li': oLi,
773
- 'button': oButton
774
- };
775
- },
776
-
777
- /**
778
- * @description Create editor HTML
779
- * @param {Array} doc document object
780
- * @param {Array} buttonList option.buttonList
781
- * @param {Object|null} plugins Plugins
782
- * @param {Array} options options
783
- * @returns {Object} { element: (Element) Toolbar element, plugins: (Array|null) Plugins Array, pluginCallButtons: (Object), responsiveButtons: (Array) }
784
- * @private
785
- */
786
- _createToolBar: function (doc, buttonList, plugins, options) {
787
- const separator_vertical = doc.createElement('DIV');
788
- separator_vertical.className = 'se-toolbar-separator-vertical';
789
-
790
- const tool_bar = doc.createElement('DIV');
791
- tool_bar.className = 'se-toolbar sun-editor-common';
792
-
793
- const _buttonTray = doc.createElement('DIV');
794
- _buttonTray.className = 'se-btn-tray';
795
- tool_bar.appendChild(_buttonTray);
796
-
797
- /** create button list */
798
- buttonList = JSON.parse(JSON.stringify(buttonList));
799
- const icons = options.icons;
800
- const defaultButtonList = this._defaultButtons(options);
801
- const pluginCallButtons = {};
802
- const responsiveButtons = [];
803
-
804
- let module = null;
805
- let button = null;
806
- let moduleElement = null;
807
- let buttonElement = null;
808
- let pluginName = '';
809
- let vertical = false;
810
- const moreLayer = util.createElement('DIV');
811
- moreLayer.className = 'se-toolbar-more-layer';
812
-
813
- buttonGroupLoop:
814
- for (let i = 0, more, moreContainer, moreCommand, buttonGroup, align; i < buttonList.length; i++) {
815
- more = false;
816
- align = '';
817
- buttonGroup = buttonList[i];
818
- moduleElement = this._createModuleGroup();
819
-
820
- // button object
821
- if (typeof buttonGroup === 'object') {
822
- // buttons loop
823
- for (let j = 0, moreButton; j < buttonGroup.length; j++) {
824
- button = buttonGroup[j];
825
- moreButton = false;
826
-
827
- if (/^\%\d+/.test(button) && j === 0) {
828
- buttonGroup[0] = button.replace(/[^\d]/g, '');
829
- responsiveButtons.push(buttonGroup);
830
- buttonList.splice(i--, 1);
831
- continue buttonGroupLoop;
832
- }
833
-
834
- if (typeof button === 'object') {
835
- if (typeof button.add === 'function') {
836
- pluginName = button.name;
837
- module = defaultButtonList[pluginName];
838
- plugins[pluginName] = button;
839
- } else {
840
- pluginName = button.name;
841
- module = [button.buttonClass, button.title, button.name, button.dataDisplay, button.innerHTML, button._disabled];
842
- }
843
- } else {
844
- // align
845
- if (/^\-/.test(button)) {
846
- align = button.substr(1);
847
- moduleElement.div.className += ' module-float-' + align;
848
- continue;
849
- }
850
-
851
- // rtl fix
852
- if (/^\#/.test(button)) {
853
- const option = button.substr(1);
854
- if (option === 'fix') moduleElement.ul.className += ' se-menu-dir-fix';
855
- continue;
856
- }
857
-
858
- // more button
859
- if (/^\:/.test(button)) {
860
- moreButton = true;
861
- const matched = button.match(/^\:([^\-]+)\-([^\-]+)\-([^\-]+)/);
862
- moreCommand = '__se__' + matched[1].trim();
863
- const title = matched[2].trim();
864
- const innerHTML = matched[3].trim();
865
- module = ['se-btn-more', title, moreCommand, 'MORE', innerHTML];
866
- }
867
- // buttons
868
- else {
869
- module = defaultButtonList[button];
870
- }
871
-
872
- pluginName = button;
873
- if (!module) {
874
- const custom = plugins[pluginName];
875
- if (!custom) throw Error('[SUNEDITOR.create.toolbar.fail] The button name of a plugin that does not exist. [' + pluginName + ']');
876
- module = [custom.buttonClass, custom.title, custom.name, custom.display, custom.innerHTML, custom._disabled];
877
- }
878
- }
879
-
880
- buttonElement = this._createButton(module[0], module[1], module[2], module[3], module[4], module[5], icons);
881
- (more ? moreContainer : moduleElement.ul).appendChild(buttonElement.li);
882
-
883
- if (plugins[pluginName]) {
884
- pluginCallButtons[pluginName] = buttonElement.button;
885
- }
886
-
887
- // more button
888
- if (moreButton) {
889
- more = true;
890
- moreContainer = util.createElement('DIV');
891
- moreContainer.className = 'se-more-layer ' + moreCommand;
892
- moreContainer.innerHTML = '<div class="se-more-form"><ul class="se-menu-list"' + (align ? ' style="float: ' + align + ';"' : '') + '></ul></div>';
893
- moreLayer.appendChild(moreContainer);
894
- moreContainer = moreContainer.firstElementChild.firstElementChild;
895
- }
896
- }
897
-
898
- if (vertical) {
899
- const sv = separator_vertical.cloneNode(false);
900
- _buttonTray.appendChild(sv);
901
- }
902
-
903
- _buttonTray.appendChild(moduleElement.div);
904
- vertical = true;
905
- }
906
- /** line break */
907
- else if (/^\/$/.test(buttonGroup)) {
908
- const enterDiv = doc.createElement('DIV');
909
- enterDiv.className = 'se-btn-module-enter';
910
- _buttonTray.appendChild(enterDiv);
911
- vertical = false;
912
- }
913
- }
914
-
915
- switch (_buttonTray.children.length) {
916
- case 0:
917
- _buttonTray.style.display = 'none';
918
- break;
919
- case 1:
920
- util.removeClass(_buttonTray.firstElementChild, 'se-btn-module-border');
921
- break;
922
- default:
923
- if (options.rtl) {
924
- const sv = separator_vertical.cloneNode(false);
925
- sv.style.float = _buttonTray.lastElementChild.style.float;
926
- _buttonTray.appendChild(sv);
927
- }
928
- }
929
-
930
- if (responsiveButtons.length > 0) responsiveButtons.unshift(buttonList);
931
- if (moreLayer.children.length > 0) _buttonTray.appendChild(moreLayer);
932
-
933
- // menu tray
934
- const _menuTray = doc.createElement('DIV');
935
- _menuTray.className = 'se-menu-tray';
936
- tool_bar.appendChild(_menuTray);
937
-
938
- // cover
939
- const tool_cover = doc.createElement('DIV');
940
- tool_cover.className = 'se-toolbar-cover';
941
- tool_bar.appendChild(tool_cover);
942
-
943
- if (options.hideToolbar) tool_bar.style.display = 'none';
944
-
945
- return {
946
- 'element': tool_bar,
947
- 'plugins': plugins,
948
- 'pluginCallButtons': pluginCallButtons,
949
- 'responsiveButtons': responsiveButtons,
950
- '_menuTray': _menuTray,
951
- '_buttonTray': _buttonTray
952
- };
953
- }
954
- };