suneditor 2.46.2 → 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 -69
  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
@@ -0,0 +1,494 @@
1
+ import EditorInjector from '../editorInjector';
2
+ import SelectMenu from './SelectMenu';
3
+ import FileManager from './FileManager';
4
+ import { domUtils, numbers, env, unicode } from '../helper';
5
+ import { CreateTooltipInner } from '../core/section/constructor';
6
+ const { NO_EVENT } = env;
7
+
8
+ /**
9
+ * @param {*} inst
10
+ * @param {Element} modalForm
11
+ * @param {object} params
12
+ * @param {boolean} params.textToDisplay - Create Text to display input.
13
+ * @param {string} params.title - Modal title
14
+ * @param {boolean} params.openNewWindow - Default checked value of the "Open in new window" checkbox.
15
+ * @param {boolean} params.relList - The "rel" attribute list of anchor tag.
16
+ * @param {object} params.defaultRel - Default "rel" attributes of anchor tag.
17
+ * @param {boolean} params.noAutoPrefix - If true, disables the automatic prefixing of the host URL to the value of the link.
18
+ Example:
19
+ {
20
+ default: 'nofollow', // Default rel
21
+ check_new_window: 'noreferrer noopener', // When "open new window" is checked
22
+ check_bookmark: 'bookmark' // When "bookmark" is checked
23
+ }
24
+ * @param {boolean} params.noAutoPrefix - If true, disables the automatic prefixing of the host URL to the value of the link.
25
+ */
26
+ const ModalAnchorEditor = function (inst, modalForm, params) {
27
+ // plugin bisic properties
28
+ EditorInjector.call(this, inst.editor);
29
+
30
+ // params
31
+ this.openNewWindow = !!params.openNewWindow;
32
+ this.relList = Array.isArray(params.relList) ? params.relList : [];
33
+ this.defaultRel = params.defaultRel || {};
34
+ this.noAutoPrefix = !!params.noAutoPrefix;
35
+ // file upload
36
+ if (params.enableFileUpload) {
37
+ this.uploadUrl = typeof params.uploadUrl === 'string' ? params.uploadUrl : null;
38
+ this.uploadHeaders = params.uploadHeaders || null;
39
+ this.uploadSizeLimit = /\d+/.test(params.uploadSizeLimit) ? numbers.get(params.uploadSizeLimit, 0) : null;
40
+ this.uploadSingleSizeLimit = /\d+/.test(params.uploadSingleSizeLimit) ? numbers.get(params.uploadSingleSizeLimit, 0) : null;
41
+ this.input = domUtils.createElement('input', { type: 'file', accept: params.acceptedFormats || '*' });
42
+ this.eventManager.addEvent(this.input, 'change', OnChangeFile.bind(this));
43
+ // file manager
44
+ this.fileManager = new FileManager(this, {
45
+ query: 'a[download]:not([data-se-file-download])',
46
+ loadHandler: this.events.onFileLoad,
47
+ eventHandler: this.events.onFileAction
48
+ });
49
+ }
50
+
51
+ // create HTML
52
+ const forms = CreatetModalForm(inst.editor, params, this.relList);
53
+
54
+ // members
55
+ this.kink = inst.constructor.key || inst.constructor.name;
56
+ this.inst = inst;
57
+ this.modalForm = modalForm;
58
+ this.host = (this._w.location.origin + this._w.location.pathname).replace(/\/$/, '');
59
+ this.urlInput = forms.querySelector('.se-input-url');
60
+ this.displayInput = forms.querySelector('._se_display_text');
61
+ this.titleInput = forms.querySelector('._se_title');
62
+ this.newWindowCheck = forms.querySelector('._se_anchor_check');
63
+ this.downloadCheck = forms.querySelector('._se_anchor_download');
64
+ this.download = forms.querySelector('._se_anchor_download_icon');
65
+ this.preview = forms.querySelector('.se-link-preview');
66
+ this.bookmark = forms.querySelector('._se_anchor_bookmark_icon');
67
+ this.bookmarkButton = forms.querySelector('._se_bookmark_button');
68
+ this.currentRel = [];
69
+ this.currentTarget = null;
70
+ this.linkValue = '';
71
+ this._change = false;
72
+ this._isRel = this.relList.length > 0;
73
+ // members - rel
74
+ if (this._isRel) {
75
+ this.relButton = forms.querySelector('.se-anchor-rel-btn');
76
+ this.relPreview = forms.querySelector('.se-anchor-rel-preview');
77
+ const relList = this.relList;
78
+ const defaultRel = (this.defaultRel.default || '').split(' ');
79
+ const list = [];
80
+ for (let i = 0, len = relList.length, rel; i < len; i++) {
81
+ rel = relList[i];
82
+ list.push(
83
+ domUtils.createElement(
84
+ 'BUTTON',
85
+ {
86
+ type: 'button',
87
+ class: 'se-btn-list' + (defaultRel.includes(rel) ? ' se-checked' : ''),
88
+ 'data-command': rel,
89
+ title: rel,
90
+ 'aria-label': rel
91
+ },
92
+ rel + '<span class="se-svg">' + this.icons.checked + '</span>'
93
+ )
94
+ );
95
+ }
96
+ this.selectMenu_rel = new SelectMenu(this, { checkList: true, position: 'right-middle', dir: 'ltr' });
97
+ this.selectMenu_rel.on(this.relButton, SetRelItem.bind(this));
98
+ this.selectMenu_rel.create(list);
99
+ this.eventManager.addEvent(this.relButton, 'click', OnClick_relbutton.bind(this));
100
+ }
101
+
102
+ // init
103
+ modalForm.querySelector('.se-anchor-editor').appendChild(forms);
104
+ this.selectMenu_bookmark = new SelectMenu(this, { checkList: false, position: 'bottom-left', dir: 'ltr' });
105
+ this.selectMenu_bookmark.on(this.urlInput, SetHeaderBookmark.bind(this));
106
+ this.eventManager.addEvent(this.newWindowCheck, 'change', OnChange_newWindowCheck.bind(this));
107
+ this.eventManager.addEvent(this.downloadCheck, 'change', OnChange_downloadCheck.bind(this));
108
+ this.eventManager.addEvent(this.displayInput, 'input', OnChange_displayInput.bind(this));
109
+ this.eventManager.addEvent(this.urlInput, 'input', OnChange_urlInput.bind(this));
110
+ this.eventManager.addEvent(this.urlInput, 'focus', OnFocus_urlInput.bind(this));
111
+ this.eventManager.addEvent(this.bookmarkButton, 'click', OnClick_bookmarkButton.bind(this));
112
+ this.eventManager.addEvent(forms.querySelector('._se_upload_button'), 'click', () => this.input.click());
113
+ };
114
+
115
+ ModalAnchorEditor.prototype = {
116
+ set(element) {
117
+ this.currentTarget = element;
118
+ },
119
+
120
+ on(isUpdate) {
121
+ if (!isUpdate) {
122
+ this.init();
123
+ this.displayInput.value = this.selection.get().toString().trim();
124
+ this.newWindowCheck.checked = this.openNewWindow;
125
+ this.titleInput.value = '';
126
+ } else if (this.currentTarget) {
127
+ const href = this.currentTarget.getAttribute('href');
128
+ this.linkValue = this.preview.textContent = this.urlInput.value = this._selfPathBookmark(href) ? href.substr(href.lastIndexOf('#')) : href;
129
+ this.displayInput.value = this.currentTarget.textContent;
130
+ this.titleInput.value = this.currentTarget.title;
131
+ this.newWindowCheck.checked = /_blank/i.test(this.currentTarget.target) ? true : false;
132
+ this.downloadCheck.checked = this.currentTarget.download;
133
+ }
134
+
135
+ this._setRel(isUpdate && this.currentTarget ? this.currentTarget.rel : this.defaultRel.default || '');
136
+ this._setLinkPreview(this.linkValue);
137
+ },
138
+
139
+ create(notText) {
140
+ if (this.linkValue.length === 0) return null;
141
+
142
+ const url = this.linkValue;
143
+ const displayText = this.displayInput.value.length === 0 ? url : this.displayInput.value;
144
+
145
+ const oA = this.currentTarget || domUtils.createElement('A');
146
+ this._updateAnchor(oA, url, displayText, this.titleInput.value, notText);
147
+ this.linkValue = this.preview.textContent = this.urlInput.value = this.displayInput.value = '';
148
+
149
+ return oA;
150
+ },
151
+
152
+ init() {
153
+ this.currentTarget = null;
154
+ this.linkValue = this.preview.textContent = this.urlInput.value = '';
155
+ this.displayInput.value = '';
156
+ this.newWindowCheck.checked = false;
157
+ this.downloadCheck.checked = false;
158
+ this._change = false;
159
+ this._setRel(this.defaultRel.default || '');
160
+ },
161
+
162
+ _updateAnchor(anchor, url, displayText, title, notText) {
163
+ // download
164
+ if (!this._selfPathBookmark(url) && this.downloadCheck.checked) {
165
+ anchor.setAttribute('download', displayText || url);
166
+ } else {
167
+ anchor.removeAttribute('download');
168
+ }
169
+
170
+ // new window
171
+ if (this.newWindowCheck.checked) anchor.target = '_blank';
172
+ else anchor.removeAttribute('target');
173
+
174
+ // rel
175
+ const rel = this.currentRel.join(' ');
176
+ if (!rel) anchor.removeAttribute('rel');
177
+ else anchor.rel = rel;
178
+
179
+ // set url
180
+ anchor.href = url;
181
+ if (title) anchor.title = title;
182
+ else anchor.removeAttribute('title');
183
+
184
+ if (notText) {
185
+ if (anchor.children.length === 0) anchor.textContent = '';
186
+ } else {
187
+ anchor.textContent = displayText;
188
+ }
189
+ },
190
+
191
+ _selfPathBookmark(path) {
192
+ const href = this._w.location.href.replace(/\/$/, '');
193
+ return path.indexOf('#') === 0 || (path.indexOf(href) === 0 && path.indexOf('#') === (!href.includes('#') ? href.length : href.substr(0, href.indexOf('#')).length));
194
+ },
195
+
196
+ _setRel(relAttr) {
197
+ if (!this._isRel) return;
198
+
199
+ const rels = (this.currentRel = !relAttr ? [] : relAttr.split(' '));
200
+ const checkedRel = this.selectMenu_rel.form.querySelectorAll('button');
201
+ for (let i = 0, len = checkedRel.length, cmd; i < len; i++) {
202
+ cmd = checkedRel[i].getAttribute('data-command');
203
+ if (rels.includes(cmd)) {
204
+ domUtils.addClass(checkedRel[i], 'se-checked');
205
+ } else {
206
+ domUtils.removeClass(checkedRel[i], 'se-checked');
207
+ }
208
+ }
209
+
210
+ this.relPreview.title = this.relPreview.textContent = rels.join(' ');
211
+ if (rels.length > 0) {
212
+ domUtils.addClass(this.relButton, 'on');
213
+ } else {
214
+ domUtils.removeClass(this.relButton, 'on');
215
+ }
216
+ },
217
+
218
+ _createHeaderList(urlValue) {
219
+ const headers = domUtils.getListChildren(this.editor.frameContext.get('wysiwyg'), (current) => /h[1-6]/i.test(current.nodeName));
220
+ if (headers.length === 0) return;
221
+
222
+ const valueRegExp = new RegExp(`^${urlValue.replace(/^#/, '')}`, 'i');
223
+ const list = [];
224
+ const menus = [];
225
+ for (let i = 0, len = headers.length, v; i < len; i++) {
226
+ v = headers[i];
227
+ if (!valueRegExp.test(v.textContent)) continue;
228
+ list.push(v);
229
+ menus.push('<div style="' + v.style.cssText + '">' + v.textContent + '</div>');
230
+ }
231
+
232
+ if (list.length === 0) {
233
+ this.selectMenu_bookmark.close();
234
+ } else {
235
+ this.selectMenu_bookmark.create(list, menus);
236
+ this.selectMenu_bookmark.open(this.options.get('_rtl') ? 'bottom-right' : '');
237
+ }
238
+ },
239
+
240
+ _setLinkPreview(value) {
241
+ const preview = this.preview;
242
+ const protocol = this.options.get('defaultUrlProtocol');
243
+ const noPrefix = this.noAutoPrefix;
244
+ const reservedProtocol = /^(mailto:|tel:|sms:|https*:\/\/|#)/.test(value) || value.indexOf(protocol) === 0;
245
+ const sameProtocol = !protocol ? false : RegExp('^' + unicode.escapeStringRegexp(value.substr(0, protocol.length))).test(protocol);
246
+
247
+ value =
248
+ this.linkValue =
249
+ preview.textContent =
250
+ !value ? '' : noPrefix ? value : protocol && !reservedProtocol && !sameProtocol ? protocol + value : reservedProtocol ? value : /^www\./.test(value) ? 'http://' + value : this.host + (/^\//.test(value) ? '' : '/') + value;
251
+
252
+ if (this._selfPathBookmark(value)) {
253
+ this.bookmark.style.display = 'block';
254
+ domUtils.addClass(this.bookmarkButton, 'active');
255
+ } else {
256
+ this.bookmark.style.display = 'none';
257
+ domUtils.removeClass(this.bookmarkButton, 'active');
258
+ }
259
+
260
+ if (!this._selfPathBookmark(value) && this.downloadCheck.checked) {
261
+ this.download.style.display = 'block';
262
+ } else {
263
+ this.download.style.display = 'none';
264
+ }
265
+ },
266
+
267
+ _relMerge(relAttr) {
268
+ const current = this.currentRel;
269
+ if (!relAttr) return current.join(' ');
270
+
271
+ if (/^only:/.test(relAttr)) {
272
+ relAttr = relAttr.replace(/^only:/, '').trim();
273
+ this.currentRel = relAttr.split(' ');
274
+ return relAttr;
275
+ }
276
+
277
+ const rels = relAttr.split(' ');
278
+ for (let i = 0, len = rels.length; i < len; i++) {
279
+ if (!current.includes(rels[i])) current.push(rels[i]);
280
+ }
281
+
282
+ return current.join(' ');
283
+ },
284
+
285
+ _relDelete(relAttr) {
286
+ if (!relAttr) return this.currentRel.join(' ');
287
+ if (/^only:/.test(relAttr)) relAttr = relAttr.replace(/^only:/, '').trim();
288
+
289
+ const rels = this.currentRel.join(' ').replace(RegExp(relAttr + '\\s*'), '');
290
+ this.currentRel = rels.split(' ');
291
+ return rels;
292
+ },
293
+
294
+ _register(response) {
295
+ const file = response.result[0];
296
+ this.linkValue = this.preview.textContent = this.urlInput.value = file.url;
297
+ this.displayInput.value = file.name;
298
+ this.downloadCheck.checked = true;
299
+ this.download.style.display = 'block';
300
+ },
301
+
302
+ async _error(response) {
303
+ const message = await this.triggerEvent('onFileUploadError', { error: response });
304
+ if (message === false) return;
305
+ const err = message === NO_EVENT ? response.errorMessage : message || response.errorMessage;
306
+ this.notice.open(err);
307
+ console.error('[SUNEDITOR.plugin.fileUpload.error]', err);
308
+ },
309
+
310
+ _uploadCallBack(xmlHttp) {
311
+ const response = JSON.parse(xmlHttp.responseText);
312
+ if (response.errorMessage) {
313
+ this._error(response);
314
+ } else {
315
+ this._register(response);
316
+ }
317
+ },
318
+
319
+ constructor: ModalAnchorEditor
320
+ };
321
+
322
+ async function OnChangeFile(e) {
323
+ const files = e.target.files;
324
+ if (!files[0]) return;
325
+
326
+ const fileInfo = {
327
+ url: this.uploadUrl,
328
+ uploadHeaders: this.uploadHeaders,
329
+ files
330
+ };
331
+
332
+ const handler = async function (infos, newInfos) {
333
+ infos = newInfos || infos;
334
+ const xmlHttp = await this.fileManager.asyncUpload(infos.url, infos.uploadHeaders, infos.files);
335
+ this._uploadCallBack(xmlHttp);
336
+ }.bind(this, fileInfo);
337
+
338
+ const result = await this.triggerEvent('onFileUploadBefore', {
339
+ ...fileInfo,
340
+ handler
341
+ });
342
+
343
+ if (result === undefined) return true;
344
+ if (result === false) return false;
345
+ if (result !== null && typeof result === 'object') handler(result);
346
+
347
+ if (result === true || result === NO_EVENT) handler(null);
348
+ }
349
+
350
+ function OnClick_relbutton() {
351
+ this.selectMenu_rel.open(this.options.get('_rtl') ? 'left-middle' : '');
352
+ }
353
+
354
+ function SetHeaderBookmark(item) {
355
+ const id = item.id || 'h_' + Math.random().toString().replace(/.+\./, '');
356
+ item.id = id;
357
+ this.urlInput.value = '#' + id;
358
+
359
+ this._setLinkPreview(this.urlInput.value);
360
+ this.selectMenu_bookmark.close();
361
+ this.urlInput.focus();
362
+ }
363
+
364
+ function SetRelItem(item) {
365
+ const cmd = item.getAttribute('data-command');
366
+ if (!cmd) return;
367
+
368
+ const current = this.currentRel;
369
+ const index = current.indexOf(cmd);
370
+ if (index === -1) current.push(cmd);
371
+ else current.splice(index, 1);
372
+
373
+ this.relPreview.title = this.relPreview.textContent = current.join(', ');
374
+ }
375
+
376
+ function OnChange_displayInput(e) {
377
+ this._change = !!e.target.value.trim();
378
+ }
379
+
380
+ function OnChange_urlInput(e) {
381
+ const value = e.target.value.trim();
382
+ this._setLinkPreview(value);
383
+ if (this._selfPathBookmark(value)) this._createHeaderList(value);
384
+ else this.selectMenu_bookmark.close();
385
+ }
386
+
387
+ function OnFocus_urlInput() {
388
+ const value = this.urlInput.value;
389
+ if (this._selfPathBookmark(value)) this._createHeaderList(value);
390
+ }
391
+
392
+ function OnClick_bookmarkButton() {
393
+ let url = this.urlInput.value;
394
+ if (this._selfPathBookmark(url)) {
395
+ url = url.substr(1);
396
+ this.bookmark.style.display = 'none';
397
+ domUtils.removeClass(this.bookmarkButton, 'active');
398
+ } else {
399
+ url = '#' + url;
400
+ this.bookmark.style.display = 'block';
401
+ domUtils.addClass(this.bookmarkButton, 'active');
402
+ this.downloadCheck.checked = false;
403
+ this.download.style.display = 'none';
404
+ this._createHeaderList(url);
405
+ }
406
+
407
+ this.urlInput.value = url;
408
+ this._setLinkPreview(url);
409
+ this.urlInput.focus();
410
+ }
411
+
412
+ function OnChange_newWindowCheck(e) {
413
+ if (typeof this.defaultRel.check_new_window !== 'string') return;
414
+ if (e.target.checked) {
415
+ this._setRel(this._relMerge(this.defaultRel.check_new_window));
416
+ } else {
417
+ this._setRel(this._relDelete(this.defaultRel.check_new_window));
418
+ }
419
+ }
420
+
421
+ function OnChange_downloadCheck(e) {
422
+ if (e.target.checked) {
423
+ this.download.style.display = 'block';
424
+ this.bookmark.style.display = 'none';
425
+ domUtils.removeClass(this.bookmarkButton, 'active');
426
+ this.linkValue = this.preview.textContent = this.urlInput.value = this.urlInput.value.replace(/^#+/, '');
427
+ if (typeof this.defaultRel.check_bookmark === 'string') {
428
+ this._setRel(this._relMerge(this.defaultRel.check_bookmark));
429
+ }
430
+ } else {
431
+ this.download.style.display = 'none';
432
+ if (typeof this.defaultRel.check_bookmark === 'string') {
433
+ this._setRel(this._relDelete(this.defaultRel.check_bookmark));
434
+ }
435
+ }
436
+ }
437
+
438
+ function CreatetModalForm(editor, params, relList) {
439
+ const lang = editor.lang;
440
+ const icons = editor.icons;
441
+ const textDisplayShow = params.textToDisplay ? '' : 'style="display: none;"';
442
+ const titleShow = params.title ? '' : 'style="display: none;"';
443
+
444
+ let html = /*html*/ `
445
+ <div class="se-modal-body">
446
+ <div class="se-modal-form">
447
+ <label>${lang.link_modal_url}</label>
448
+ <div class="se-modal-form-files">
449
+ <input data-focus class="se-input-form se-input-url" type="text" placeholder="${editor.options.get('protocol') || ''}" />
450
+ ${
451
+ params.enableFileUpload
452
+ ? `<button type="button" class="se-btn se-tooltip se-modal-files-edge-button _se_upload_button" aria-label="${lang.fileUpload}">
453
+ ${icons.file_upload}
454
+ ${CreateTooltipInner(lang.fileUpload)}
455
+ </button>`
456
+ : ''
457
+ }
458
+ <button type="button" class="se-btn se-tooltip se-modal-files-edge-button _se_bookmark_button" aria-label="${lang.link_modal_bookmark}">
459
+ ${icons.bookmark}
460
+ ${CreateTooltipInner(lang.link_modal_bookmark)}
461
+ </button>
462
+ </div>
463
+ <div class="se-anchor-preview-form">
464
+ <span class="se-svg se-anchor-preview-icon _se_anchor_bookmark_icon">${icons.bookmark}</span>
465
+ <span class="se-svg se-anchor-preview-icon _se_anchor_download_icon">${icons.download}</span>
466
+ <pre class="se-link-preview"></pre>
467
+ </div>
468
+ <label ${textDisplayShow}>${lang.link_modal_text}</label>
469
+ <input class="se-input-form _se_display_text" type="text" ${textDisplayShow} />
470
+ <label ${titleShow}>${lang.title}</label>
471
+ <input class="se-input-form _se_title" type="text" ${titleShow} />
472
+ </div>
473
+ <div class="se-modal-form-footer">
474
+ <label><input type="checkbox" class="se-modal-btn-check _se_anchor_check" />&nbsp;${lang.link_modal_newWindowCheck}</label>
475
+ <label><input type="checkbox" class="se-modal-btn-check _se_anchor_download" />&nbsp;${lang.link_modal_downloadLinkCheck}</label>`;
476
+
477
+ if (relList.length > 0) {
478
+ html += /*html*/ `
479
+ <div class="se-anchor-rel">
480
+ <button type="button" class="se-btn se-tooltip se-anchor-rel-btn" title="${lang.link_modal_relAttribute}" aria-label="${lang.link_modal_relAttribute}">
481
+ ${icons.link_rel}
482
+ ${CreateTooltipInner(lang.link_modal_relAttribute)}
483
+ </button>
484
+ <div class="se-anchor-rel-wrapper"><pre class="se-link-preview se-anchor-rel-preview"></pre></div>
485
+ </div>
486
+ </div>`;
487
+ }
488
+
489
+ html += '</div></div>';
490
+
491
+ return domUtils.createElement('DIV', null, html);
492
+ }
493
+
494
+ export default ModalAnchorEditor;