suneditor 2.46.2 → 3.0.0-alpha.2

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 (289) hide show
  1. package/.eslintignore +7 -0
  2. package/.eslintrc.json +64 -0
  3. package/CONTRIBUTING.md +36 -0
  4. package/LICENSE.txt +1 -1
  5. package/README.md +11 -1560
  6. package/package.json +94 -70
  7. package/src/assets/icons/_default.js +194 -0
  8. package/src/assets/suneditor-content.css +642 -0
  9. package/src/assets/suneditor.css +3378 -0
  10. package/src/core/base/eventHandlers/handler_toolbar.js +114 -0
  11. package/src/core/base/eventHandlers/handler_ww_clipboard.js +31 -0
  12. package/src/core/base/eventHandlers/handler_ww_dragDrop.js +69 -0
  13. package/src/core/base/eventHandlers/handler_ww_key_input.js +978 -0
  14. package/src/core/base/eventHandlers/handler_ww_mouse.js +118 -0
  15. package/src/core/base/eventManager.js +1129 -0
  16. package/src/core/base/events.js +320 -0
  17. package/src/core/base/history.js +301 -0
  18. package/src/core/class/char.js +146 -0
  19. package/src/core/class/component.js +624 -0
  20. package/src/core/class/format.js +3255 -0
  21. package/src/core/class/html.js +1621 -0
  22. package/src/core/class/menu.js +260 -0
  23. package/src/core/class/nodeTransform.js +379 -0
  24. package/src/core/class/notice.js +42 -0
  25. package/src/core/class/offset.js +578 -0
  26. package/src/core/class/selection.js +508 -0
  27. package/src/core/class/shortcuts.js +38 -0
  28. package/src/core/class/toolbar.js +440 -0
  29. package/src/core/class/viewer.js +646 -0
  30. package/src/core/editor.js +1588 -0
  31. package/src/core/section/actives.js +107 -0
  32. package/src/core/section/constructor.js +1237 -0
  33. package/src/core/section/context.js +97 -0
  34. package/src/editorInjector/_classes.js +22 -0
  35. package/src/editorInjector/_core.js +28 -0
  36. package/src/editorInjector/index.js +13 -0
  37. package/src/helper/converter.js +313 -0
  38. package/src/helper/domUtils.js +1177 -0
  39. package/src/helper/env.js +250 -0
  40. package/src/helper/index.js +19 -0
  41. package/src/helper/numbers.js +68 -0
  42. package/src/helper/unicode.js +43 -0
  43. package/src/langs/ckb.js +161 -0
  44. package/src/langs/cs.js +161 -0
  45. package/src/langs/da.js +161 -0
  46. package/src/langs/de.js +162 -0
  47. package/src/langs/en.js +199 -0
  48. package/src/langs/es.js +162 -0
  49. package/src/langs/fa.js +159 -0
  50. package/src/langs/fr.js +161 -0
  51. package/src/langs/he.js +162 -0
  52. package/src/{lang → langs}/index.js +0 -2
  53. package/src/langs/it.js +162 -0
  54. package/src/langs/ja.js +162 -0
  55. package/src/langs/ko.js +162 -0
  56. package/src/langs/lv.js +162 -0
  57. package/src/langs/nl.js +162 -0
  58. package/src/langs/pl.js +162 -0
  59. package/src/langs/pt_br.js +162 -0
  60. package/src/langs/ro.js +162 -0
  61. package/src/langs/ru.js +162 -0
  62. package/src/langs/se.js +162 -0
  63. package/src/langs/tr.js +159 -0
  64. package/src/langs/ua.js +162 -0
  65. package/src/langs/ur.js +162 -0
  66. package/src/langs/zh_cn.js +162 -0
  67. package/src/modules/ApiManager.js +168 -0
  68. package/src/modules/ColorPicker.js +302 -0
  69. package/src/modules/Controller.js +315 -0
  70. package/src/modules/Figure.js +1174 -0
  71. package/src/modules/FileBrowser.js +271 -0
  72. package/src/modules/FileManager.js +290 -0
  73. package/src/modules/HueSlider.js +513 -0
  74. package/src/modules/Modal.js +177 -0
  75. package/src/modules/ModalAnchorEditor.js +494 -0
  76. package/src/modules/SelectMenu.js +447 -0
  77. package/src/modules/_DragHandle.js +16 -0
  78. package/src/modules/index.js +14 -0
  79. package/src/plugins/command/blockquote.js +47 -47
  80. package/src/plugins/command/exportPdf.js +168 -0
  81. package/src/plugins/command/fileUpload.js +389 -0
  82. package/src/plugins/command/list_bulleted.js +112 -0
  83. package/src/plugins/command/list_numbered.js +115 -0
  84. package/src/plugins/dropdown/align.js +143 -0
  85. package/src/plugins/dropdown/backgroundColor.js +73 -0
  86. package/src/plugins/dropdown/font.js +113 -0
  87. package/src/plugins/dropdown/fontColor.js +73 -0
  88. package/src/plugins/dropdown/formatBlock.js +141 -0
  89. package/src/plugins/dropdown/hr.js +111 -0
  90. package/src/plugins/dropdown/layout.js +72 -0
  91. package/src/plugins/dropdown/lineHeight.js +114 -0
  92. package/src/plugins/dropdown/list.js +107 -0
  93. package/src/plugins/dropdown/paragraphStyle.js +117 -0
  94. package/src/plugins/dropdown/table.js +2810 -0
  95. package/src/plugins/dropdown/template.js +71 -0
  96. package/src/plugins/dropdown/textStyle.js +137 -0
  97. package/src/plugins/field/mention.js +172 -0
  98. package/src/plugins/fileBrowser/imageGallery.js +76 -59
  99. package/src/plugins/index.js +86 -24
  100. package/src/plugins/input/fontSize.js +357 -0
  101. package/src/plugins/modal/audio.js +492 -0
  102. package/src/plugins/modal/image.js +1062 -0
  103. package/src/plugins/modal/link.js +211 -0
  104. package/src/plugins/modal/math.js +347 -0
  105. package/src/plugins/modal/video.js +870 -0
  106. package/src/suneditor.js +62 -67
  107. package/src/themes/test.css +61 -0
  108. package/typings/CommandPlugin.d.ts +8 -0
  109. package/typings/DialogPlugin.d.ts +20 -0
  110. package/typings/FileBrowserPlugin.d.ts +30 -0
  111. package/typings/Lang.d.ts +124 -0
  112. package/typings/Module.d.ts +15 -0
  113. package/typings/Plugin.d.ts +42 -0
  114. package/typings/SubmenuPlugin.d.ts +8 -0
  115. package/typings/_classes.d.ts +17 -0
  116. package/typings/_colorPicker.d.ts +60 -0
  117. package/typings/_core.d.ts +55 -0
  118. package/typings/align.d.ts +5 -0
  119. package/{src/plugins/dialog → typings}/audio.d.ts +1 -1
  120. package/typings/backgroundColor.d.ts +5 -0
  121. package/{src/plugins/command → typings}/blockquote.d.ts +1 -1
  122. package/typings/char.d.ts +39 -0
  123. package/typings/component.d.ts +38 -0
  124. package/typings/context.d.ts +39 -0
  125. package/typings/converter.d.ts +33 -0
  126. package/typings/dialog.d.ts +28 -0
  127. package/typings/domUtils.d.ts +361 -0
  128. package/typings/editor.d.ts +7 -0
  129. package/typings/editor.ts +542 -0
  130. package/typings/env.d.ts +70 -0
  131. package/typings/eventManager.d.ts +37 -0
  132. package/typings/events.d.ts +262 -0
  133. package/typings/fileBrowser.d.ts +42 -0
  134. package/typings/fileManager.d.ts +67 -0
  135. package/typings/font.d.ts +5 -0
  136. package/typings/fontColor.d.ts +5 -0
  137. package/typings/fontSize.d.ts +5 -0
  138. package/typings/format.d.ts +191 -0
  139. package/typings/formatBlock.d.ts +5 -0
  140. package/typings/history.d.ts +48 -0
  141. package/typings/horizontalRule.d.ts +5 -0
  142. package/{src/plugins/dialog → typings}/image.d.ts +1 -1
  143. package/{src/plugins/fileBrowser → typings}/imageGallery.d.ts +1 -1
  144. package/typings/index.d.ts +21 -0
  145. package/{src/plugins/modules/index.d.ts → typings/index.modules.d.ts} +3 -3
  146. package/typings/index.plugins.d.ts +58 -0
  147. package/typings/lineHeight.d.ts +5 -0
  148. package/{src/plugins/dialog → typings}/link.d.ts +1 -1
  149. package/typings/list.d.ts +5 -0
  150. package/{src/plugins/dialog → typings}/math.d.ts +1 -1
  151. package/typings/mediaContainer.d.ts +25 -0
  152. package/typings/node.d.ts +57 -0
  153. package/typings/notice.d.ts +16 -0
  154. package/typings/numbers.d.ts +29 -0
  155. package/typings/offset.d.ts +24 -0
  156. package/typings/options.d.ts +589 -0
  157. package/typings/paragraphStyle.d.ts +5 -0
  158. package/typings/resizing.d.ts +141 -0
  159. package/typings/selection.d.ts +94 -0
  160. package/typings/shortcuts.d.ts +13 -0
  161. package/typings/suneditor.d.ts +9 -0
  162. package/typings/table.d.ts +5 -0
  163. package/typings/template.d.ts +5 -0
  164. package/typings/textStyle.d.ts +5 -0
  165. package/typings/toolbar.d.ts +32 -0
  166. package/typings/unicode.d.ts +25 -0
  167. package/{src/plugins/dialog → typings}/video.d.ts +1 -1
  168. package/dist/css/suneditor.min.css +0 -1
  169. package/dist/suneditor.min.js +0 -2
  170. package/src/assets/css/suneditor-contents.css +0 -562
  171. package/src/assets/css/suneditor.css +0 -566
  172. package/src/assets/defaultIcons.js +0 -103
  173. package/src/lang/Lang.d.ts +0 -144
  174. package/src/lang/ckb.d.ts +0 -5
  175. package/src/lang/ckb.js +0 -188
  176. package/src/lang/cs.d.ts +0 -5
  177. package/src/lang/cs.js +0 -188
  178. package/src/lang/da.d.ts +0 -5
  179. package/src/lang/da.js +0 -191
  180. package/src/lang/de.d.ts +0 -5
  181. package/src/lang/de.js +0 -188
  182. package/src/lang/en.d.ts +0 -5
  183. package/src/lang/en.js +0 -188
  184. package/src/lang/es.d.ts +0 -5
  185. package/src/lang/es.js +0 -188
  186. package/src/lang/fa.d.ts +0 -5
  187. package/src/lang/fa.js +0 -188
  188. package/src/lang/fr.d.ts +0 -5
  189. package/src/lang/fr.js +0 -188
  190. package/src/lang/he.d.ts +0 -5
  191. package/src/lang/he.js +0 -188
  192. package/src/lang/index.d.ts +0 -23
  193. package/src/lang/it.d.ts +0 -5
  194. package/src/lang/it.js +0 -188
  195. package/src/lang/ja.d.ts +0 -5
  196. package/src/lang/ja.js +0 -188
  197. package/src/lang/ko.d.ts +0 -5
  198. package/src/lang/ko.js +0 -188
  199. package/src/lang/lv.d.ts +0 -5
  200. package/src/lang/lv.js +0 -188
  201. package/src/lang/nl.d.ts +0 -5
  202. package/src/lang/nl.js +0 -188
  203. package/src/lang/pl.d.ts +0 -5
  204. package/src/lang/pl.js +0 -188
  205. package/src/lang/pt_br.d.ts +0 -5
  206. package/src/lang/pt_br.js +0 -189
  207. package/src/lang/ro.d.ts +0 -5
  208. package/src/lang/ro.js +0 -188
  209. package/src/lang/ru.d.ts +0 -5
  210. package/src/lang/ru.js +0 -188
  211. package/src/lang/se.d.ts +0 -5
  212. package/src/lang/se.js +0 -191
  213. package/src/lang/tr.d.ts +0 -5
  214. package/src/lang/tr.js +0 -191
  215. package/src/lang/ua.d.ts +0 -5
  216. package/src/lang/ua.js +0 -188
  217. package/src/lang/ur.d.ts +0 -5
  218. package/src/lang/ur.js +0 -188
  219. package/src/lang/zh_cn.d.ts +0 -5
  220. package/src/lang/zh_cn.js +0 -187
  221. package/src/lib/constructor.js +0 -954
  222. package/src/lib/context.d.ts +0 -42
  223. package/src/lib/context.js +0 -71
  224. package/src/lib/core.d.ts +0 -1135
  225. package/src/lib/core.js +0 -9395
  226. package/src/lib/history.d.ts +0 -48
  227. package/src/lib/history.js +0 -219
  228. package/src/lib/util.d.ts +0 -678
  229. package/src/lib/util.js +0 -2131
  230. package/src/options.d.ts +0 -608
  231. package/src/plugins/CommandPlugin.d.ts +0 -8
  232. package/src/plugins/DialogPlugin.d.ts +0 -20
  233. package/src/plugins/FileBrowserPlugin.d.ts +0 -30
  234. package/src/plugins/Module.d.ts +0 -15
  235. package/src/plugins/Plugin.d.ts +0 -42
  236. package/src/plugins/SubmenuPlugin.d.ts +0 -8
  237. package/src/plugins/dialog/audio.js +0 -559
  238. package/src/plugins/dialog/image.js +0 -1126
  239. package/src/plugins/dialog/link.js +0 -223
  240. package/src/plugins/dialog/math.js +0 -295
  241. package/src/plugins/dialog/mention.js +0 -242
  242. package/src/plugins/dialog/video.js +0 -979
  243. package/src/plugins/index.d.ts +0 -79
  244. package/src/plugins/modules/_anchor.js +0 -461
  245. package/src/plugins/modules/_colorPicker.d.ts +0 -60
  246. package/src/plugins/modules/_colorPicker.js +0 -201
  247. package/src/plugins/modules/_notice.d.ts +0 -21
  248. package/src/plugins/modules/_notice.js +0 -72
  249. package/src/plugins/modules/_selectMenu.js +0 -119
  250. package/src/plugins/modules/component.d.ts +0 -25
  251. package/src/plugins/modules/component.js +0 -81
  252. package/src/plugins/modules/dialog.d.ts +0 -28
  253. package/src/plugins/modules/dialog.js +0 -175
  254. package/src/plugins/modules/fileBrowser.d.ts +0 -42
  255. package/src/plugins/modules/fileBrowser.js +0 -374
  256. package/src/plugins/modules/fileManager.d.ts +0 -67
  257. package/src/plugins/modules/fileManager.js +0 -326
  258. package/src/plugins/modules/index.js +0 -9
  259. package/src/plugins/modules/resizing.d.ts +0 -154
  260. package/src/plugins/modules/resizing.js +0 -903
  261. package/src/plugins/submenu/align.d.ts +0 -5
  262. package/src/plugins/submenu/align.js +0 -160
  263. package/src/plugins/submenu/font.d.ts +0 -5
  264. package/src/plugins/submenu/font.js +0 -123
  265. package/src/plugins/submenu/fontColor.d.ts +0 -5
  266. package/src/plugins/submenu/fontColor.js +0 -101
  267. package/src/plugins/submenu/fontSize.d.ts +0 -5
  268. package/src/plugins/submenu/fontSize.js +0 -112
  269. package/src/plugins/submenu/formatBlock.d.ts +0 -5
  270. package/src/plugins/submenu/formatBlock.js +0 -273
  271. package/src/plugins/submenu/hiliteColor.d.ts +0 -5
  272. package/src/plugins/submenu/hiliteColor.js +0 -102
  273. package/src/plugins/submenu/horizontalRule.d.ts +0 -5
  274. package/src/plugins/submenu/horizontalRule.js +0 -98
  275. package/src/plugins/submenu/lineHeight.d.ts +0 -5
  276. package/src/plugins/submenu/lineHeight.js +0 -104
  277. package/src/plugins/submenu/list.d.ts +0 -5
  278. package/src/plugins/submenu/list.js +0 -456
  279. package/src/plugins/submenu/paragraphStyle.d.ts +0 -5
  280. package/src/plugins/submenu/paragraphStyle.js +0 -135
  281. package/src/plugins/submenu/table.d.ts +0 -5
  282. package/src/plugins/submenu/table.js +0 -1431
  283. package/src/plugins/submenu/template.d.ts +0 -5
  284. package/src/plugins/submenu/template.js +0 -72
  285. package/src/plugins/submenu/textStyle.d.ts +0 -5
  286. package/src/plugins/submenu/textStyle.js +0 -167
  287. package/src/suneditor.d.ts +0 -9
  288. package/src/suneditor_build.js +0 -18
  289. /package/{src/plugins/dialog → typings}/mention.d.ts +0 -0
@@ -0,0 +1,2810 @@
1
+ import EditorInjector from '../../editorInjector';
2
+ import { domUtils, numbers, converter, env } from '../../helper';
3
+ import { Controller, SelectMenu, ColorPicker, Figure, _DragHandle } from '../../modules';
4
+
5
+ const { _w, ON_OVER_COMPONENT } = env;
6
+
7
+ const ROW_SELECT_MARGIN = 5;
8
+ const CELL_SELECT_MARGIN = 2;
9
+ const CELL_DECIMAL_END = 0;
10
+
11
+ const RESIZE_CELL_CLASS = '.se-table-resize-line';
12
+ const RESIZE_CELL_PREV_CLASS = '.se-table-resize-line-prev';
13
+ const RESIZE_ROW_CLASS = '.se-table-resize-row';
14
+ const RESIZE_ROW_PREV_CLASS = '.se-table-resize-row-prev';
15
+
16
+ const BORDER_LIST = ['none', 'solid', 'dotted', 'dashed', 'double', 'groove', 'ridge', 'inset', 'outset'];
17
+ const BORDER_FORMATS = {
18
+ all: 'border_all',
19
+ inside: 'border_inside',
20
+ horizon: 'border_horizontal',
21
+ vertical: 'border_vertical',
22
+ outside: 'border_outside',
23
+ left: 'border_left',
24
+ top: 'border_top',
25
+ right: 'border_right',
26
+ bottom: 'border_bottom',
27
+ none: 'border_none'
28
+ };
29
+ const BORDER_FORMAT_INSIDE = ['all', 'inside', 'horizon', 'vertical'];
30
+ const BORDER_NS = {
31
+ l: 'borderLeft',
32
+ t: 'borderTop',
33
+ r: 'borderRight',
34
+ b: 'borderBottom'
35
+ };
36
+ const DEFAULT_BORDER_UNIT = 'px';
37
+ const DEFAULT_COLOR_LIST = [
38
+ // row-1
39
+ '#b0dbb0',
40
+ '#efef7e',
41
+ '#f2acac',
42
+ '#dcb0f6',
43
+ '#99bdff',
44
+ // row-2
45
+ '#5dbd5d',
46
+ '#e7c301',
47
+ '#f64444',
48
+ '#e57ff4',
49
+ '#4387f1',
50
+ // row-3
51
+ '#27836a',
52
+ '#f69915',
53
+ '#ba0808',
54
+ '#a90bed',
55
+ '#134299',
56
+ // row-4
57
+ '#e4e4e4',
58
+ '#B3B3B3',
59
+ '#808080',
60
+ '#4D4D4D',
61
+ '#000000'
62
+ ];
63
+
64
+ const Table = function (editor, pluginOptions) {
65
+ // plugin bisic properties
66
+ EditorInjector.call(this, editor);
67
+ this.title = this.lang.table;
68
+ this.icon = 'table';
69
+
70
+ // pluginOptions options
71
+ this.figureScrollList = ['se-scroll-figure-xy', 'se-scroll-figure-x', 'se-scroll-figure-y'];
72
+ this.figureScroll = typeof pluginOptions.scrollType === 'string' ? pluginOptions.scrollType.toLowerCase() : 'x';
73
+ this.captionPosition = pluginOptions.captionPosition !== 'bottom' ? 'top' : 'bottom';
74
+ this.cellControllerTop = (pluginOptions.cellControllerPosition !== 'cell' ? 'table' : 'cell') === 'table';
75
+
76
+ // create HTML
77
+ const menu = CreateHTML(editor);
78
+ const commandArea = menu.querySelector('.se-controller-table-picker');
79
+ const controller_table = CreateHTML_controller_table(editor);
80
+ const controller_cell = CreateHTML_controller_cell(editor, this.cellControllerTop);
81
+ const controller_props = CreateHTML_controller_properties(editor);
82
+
83
+ editor.applyFrameRoots((e) => {
84
+ e.get('wrapper').appendChild(domUtils.createElement('DIV', { class: RESIZE_CELL_CLASS.replace(/^\./, '') }));
85
+ e.get('wrapper').appendChild(domUtils.createElement('DIV', { class: RESIZE_CELL_PREV_CLASS.replace(/^\./, '') }));
86
+ e.get('wrapper').appendChild(domUtils.createElement('DIV', { class: RESIZE_ROW_CLASS.replace(/^\./, '') }));
87
+ e.get('wrapper').appendChild(domUtils.createElement('DIV', { class: RESIZE_ROW_PREV_CLASS.replace(/^\./, '') }));
88
+ });
89
+
90
+ // members - Controller
91
+ this.controller_table = new Controller(this, controller_table, { position: 'top' });
92
+ this.controller_cell = new Controller(this, controller_cell, { position: this.cellControllerTop ? 'top' : 'bottom' });
93
+ // props
94
+ const propsTargetForms = [this.controller_table.form, this.controller_cell.form];
95
+ this.controller_props = new Controller(this, controller_props, { position: 'bottom', parents: propsTargetForms, isInsideForm: true });
96
+ this.controller_props_title = controller_props.querySelector('.se-controller-title');
97
+ // color picker
98
+ const colorForm = domUtils.createElement('DIV', { class: 'se-controller se-list-layer' }, null);
99
+ this.colorPicker = new ColorPicker(this, '', {
100
+ colorList: pluginOptions.colorList || DEFAULT_COLOR_LIST,
101
+ splitNum: 5,
102
+ disableRemove: true,
103
+ hueSliderOptions: { controllerOptions: { parents: [colorForm], isOutsideForm: true } }
104
+ });
105
+
106
+ colorForm.appendChild(this.colorPicker.target);
107
+ this.controller_colorPicker = new Controller(this, colorForm, {
108
+ position: 'bottom',
109
+ parents: [this.controller_props.form].concat(propsTargetForms),
110
+ isInsideForm: true,
111
+ isWWTarget: false,
112
+ initMethod: () => {
113
+ this.colorPicker.hueSlider.close();
114
+ domUtils.removeClass(this.controller_colorPicker.currentTarget, 'on');
115
+ }
116
+ });
117
+
118
+ this.figure = new Figure(this, null, {});
119
+
120
+ this.sliderType = '';
121
+
122
+ // members - SelectMenu - split
123
+ const splitMenu = CreateSplitMenu(this.lang);
124
+ this.splitButton = controller_cell.querySelector('[data-command="onsplit"]');
125
+ this.selectMenu_split = new SelectMenu(this, { checkList: false, position: 'bottom-center' });
126
+ this.selectMenu_split.on(this.splitButton, OnSplitCells.bind(this));
127
+ this.selectMenu_split.create(splitMenu.items, splitMenu.menus);
128
+
129
+ // members - SelectMenu - column
130
+ const columnMenu = CreateColumnMenu(this.lang, this.icons);
131
+ const columnButton = controller_cell.querySelector('[data-command="oncolumn"]');
132
+ this.selectMenu_column = new SelectMenu(this, { checkList: false, position: 'bottom-center' });
133
+ this.selectMenu_column.on(columnButton, OnColumnEdit.bind(this));
134
+ this.selectMenu_column.create(columnMenu.items, columnMenu.menus);
135
+
136
+ // members - SelectMenu - row
137
+ const rownMenu = CreateRowMenu(this.lang, this.icons);
138
+ const rowButton = controller_cell.querySelector('[data-command="onrow"]');
139
+ this.selectMenu_row = new SelectMenu(this, { checkList: false, position: 'bottom-center' });
140
+ this.selectMenu_row.on(rowButton, OnRowEdit.bind(this));
141
+ this.selectMenu_row.create(rownMenu.items, rownMenu.menus);
142
+
143
+ // members - SelectMenu - properties - border style
144
+ const borderMenu = CreateBorderMenu();
145
+ const borderButton = controller_props.querySelector('[data-command="props_onborder_style"]');
146
+ this.selectMenu_props_border = new SelectMenu(this, { checkList: false, position: 'bottom-center' });
147
+ this.selectMenu_props_border.on(borderButton, OnPropsBorderEdit.bind(this));
148
+ this.selectMenu_props_border.create(borderMenu.items, borderMenu.menus);
149
+
150
+ // members - SelectMenu - properties - border format
151
+ const borderFormatMenu = CreateBorderFormatMenu(this.lang, this.icons, []);
152
+ const borderFormatButton = controller_props.querySelector('[data-command="props_onborder_format"]');
153
+ this.selectMenu_props_border_format = new SelectMenu(this, { checkList: false, position: 'bottom-left', dir: 'ltr', splitNum: 5 });
154
+ this.selectMenu_props_border_format.on(borderFormatButton, OnPropsBorderFormatEdit.bind(this, 'all'));
155
+ this.selectMenu_props_border_format.create(borderFormatMenu.items, borderFormatMenu.menus);
156
+
157
+ const borderFormatMenu_oneCell = CreateBorderFormatMenu(this.lang, this.icons, BORDER_FORMAT_INSIDE);
158
+ this.selectMenu_props_border_format_oneCell = new SelectMenu(this, { checkList: false, position: 'bottom-left', dir: 'ltr', splitNum: 6 });
159
+ this.selectMenu_props_border_format_oneCell.on(borderFormatButton, OnPropsBorderFormatEdit.bind(this, 'outside'));
160
+ this.selectMenu_props_border_format_oneCell.create(borderFormatMenu_oneCell.items, borderFormatMenu_oneCell.menus);
161
+
162
+ // memberts - elements..
163
+ this.maxText = this.lang.maxSize;
164
+ this.minText = this.lang.minSize;
165
+ this.propTargets = {
166
+ cell_alignment: controller_props.querySelector('.se-table-props-align > .__se__a_h'),
167
+ cell_alignment_vertical: controller_props.querySelector('.se-table-props-align > .__se__a_v'),
168
+ border_format: borderFormatButton,
169
+ border_style: controller_props.querySelector('[data-command="props_onborder_style"] .se-txt'),
170
+ border_color: controller_props.querySelector('.__se_border_color'),
171
+ border_width: controller_props.querySelector('.__se__border_size'),
172
+ back_color: controller_props.querySelector('.__se_back_color'),
173
+ font_color: controller_props.querySelector('.__se_font_color'),
174
+ palette_border_button: controller_props.querySelector('[data-command="props_onpalette"][data-value="border"]'),
175
+ font_bold: controller_props.querySelector('[data-command="props_font_style"][data-value="bold"]'),
176
+ font_underline: controller_props.querySelector('[data-command="props_font_style"][data-value="underline"]'),
177
+ font_italic: controller_props.querySelector('[data-command="props_font_style"][data-value="italic"]'),
178
+ font_strike: controller_props.querySelector('[data-command="props_font_style"][data-value="strike"]')
179
+ };
180
+ this._propsCache = [];
181
+ this._currentFontStyles = [];
182
+ this._propsAlignCache = '';
183
+ this._propsVerticalAlignCache = '';
184
+ this._typeCache = '';
185
+ this.tableHighlight = menu.querySelector('.se-table-size-highlighted');
186
+ this.tableUnHighlight = menu.querySelector('.se-table-size-unhighlighted');
187
+ this.tableDisplay = menu.querySelector('.se-table-size-display');
188
+ this.resizeButton = controller_table.querySelector('._se_table_resize');
189
+ this.resizeText = controller_table.querySelector('._se_table_resize > span > span');
190
+ this.columnFixedButton = controller_table.querySelector('._se_table_fixed_column');
191
+ this.headerButton = controller_table.querySelector('._se_table_header');
192
+ this.captionButton = controller_table.querySelector('._se_table_caption');
193
+ this.mergeButton = controller_cell.querySelector('[data-command="merge"]');
194
+
195
+ // members - private
196
+ this._resizing = false;
197
+ this._resizeLine = null;
198
+ this._resizeLinePrev = null;
199
+ this._figure = null;
200
+ this._element = null;
201
+ this._tdElement = null;
202
+ this._trElement = null;
203
+ this._trElements = null;
204
+ this._tableXY = [];
205
+ this._maxWidth = true;
206
+ this._fixedColumn = false;
207
+ this._physical_cellCnt = 0;
208
+ this._logical_cellCnt = 0;
209
+ this._rowCnt = 0;
210
+ this._rowIndex = 0;
211
+ this._physical_cellIndex = 0;
212
+ this._logical_cellIndex = 0;
213
+ this._current_colSpan = 0;
214
+ this._current_rowSpan = 0;
215
+
216
+ // member - multi selecte
217
+ this._selectedCells = null;
218
+ this._shift = false;
219
+ this._fixedCell = null;
220
+ this._fixedCellName = null;
221
+ this._selectedCell = null;
222
+ this._selectedTable = null;
223
+ this._ref = null;
224
+
225
+ // member - global events
226
+ this._bindMultiOn = OnCellMultiSelect.bind(this);
227
+ this._bindMultiOff = OffCellMultiSelect.bind(this);
228
+ this._bindShiftOff = OffCellShift.bind(this);
229
+ this._bindTouchOff = OffCellTouch.bind(this);
230
+ this.__globalEvents = {
231
+ on: null,
232
+ off: null,
233
+ shiftOff: null,
234
+ touchOff: null,
235
+ resize: null,
236
+ resizeStop: null,
237
+ resizeKeyDown: null
238
+ };
239
+
240
+ // init
241
+ this.menu.initDropdownTarget(Table, menu);
242
+ this.eventManager.addEvent(commandArea, 'mousemove', OnMouseMoveTablePicker.bind(this));
243
+ this.eventManager.addEvent(commandArea, 'click', OnClickTablePicker.bind(this));
244
+ };
245
+
246
+ Table.key = 'table';
247
+ Table.type = 'dropdown-free';
248
+ Table.className = '';
249
+ Table.component = function (node) {
250
+ return domUtils.isTable(node) ? node : null;
251
+ };
252
+ Table.options = { isInputComponent: true };
253
+ Table.prototype = {
254
+ /**
255
+ * @override core
256
+ */
257
+ action() {
258
+ const oTable = domUtils.createElement('TABLE');
259
+ const x = this._tableXY[0];
260
+ const y = this._tableXY[1];
261
+
262
+ const body = `<tbody>${`<tr>${CreateCells('td', x, false)}</tr>`.repeat(y)}</tbody>`;
263
+ const colGroup = `<colgroup>${`<col style="width: ${numbers.get(100 / x, CELL_DECIMAL_END)}%;">`.repeat(x)}</colgroup>`;
264
+ oTable.innerHTML = colGroup + body;
265
+
266
+ const figure = domUtils.createElement('FIGURE', { class: 'se-flex-component se-input-component' });
267
+ figure.appendChild(oTable);
268
+
269
+ if (this.component.insert(figure, false, false)) {
270
+ this._resetTablePicker();
271
+ const target = oTable.querySelector('td div');
272
+ this.selection.setRange(target, 0, target, 0);
273
+ }
274
+ },
275
+
276
+ /**
277
+ * @override core
278
+ */
279
+ retainFormat() {
280
+ return {
281
+ query: 'table',
282
+ method: (element) => {
283
+ const ColgroupEl = element.querySelector('colgroup');
284
+ let FigureEl = domUtils.isFigure(element.parentNode) ? element.parentNode : null;
285
+ if (ColgroupEl && FigureEl) return;
286
+
287
+ // create colgroup
288
+ if (!ColgroupEl) {
289
+ const maxCount = GetMaxColumns(element);
290
+ const colGroup = domUtils.createElement('colgroup', null, `<col style="width: ${numbers.get(100 / maxCount, CELL_DECIMAL_END)}%;">`.repeat(maxCount));
291
+ element.insertBefore(colGroup, element.firstElementChild);
292
+ }
293
+
294
+ // figure
295
+ if (!FigureEl) {
296
+ FigureEl = domUtils.createElement('FIGURE', { class: 'se-flex-component se-input-component' });
297
+ element.parentNode.insertBefore(FigureEl, element);
298
+ FigureEl.appendChild(element);
299
+ } else {
300
+ domUtils.addClass(FigureEl, 'se-flex-component|se-input-component');
301
+ }
302
+
303
+ // scroll
304
+ if (!this.figureScroll) {
305
+ domUtils.removeClass(FigureEl, this.figureScrollList.join('|'));
306
+ } else {
307
+ const scrollTypeClass = `se-scroll-figure-${this.figureScroll}`;
308
+ domUtils.addClass(FigureEl, scrollTypeClass);
309
+ domUtils.removeClass(FigureEl, this.figureScrollList.filter((v) => v !== scrollTypeClass).join('|'));
310
+ }
311
+ }
312
+ };
313
+ },
314
+
315
+ /**
316
+ * @override core
317
+ * @param {"rtl"|"ltr"} dir Direction
318
+ */
319
+ setDir(dir) {
320
+ this.tableHighlight.style.left = dir === 'rtl' ? 10 * 18 - 13 + 'px' : '';
321
+ this._resetTablePicker();
322
+ this._resetPropsAlign(dir === 'rtl');
323
+ },
324
+
325
+ onMouseMove({ event }) {
326
+ if (this._resizing) return;
327
+ const target = domUtils.getParentElement(event.target, IsResizeEls);
328
+ if (!target || this._fixedCell) {
329
+ this.__hideResizeLine();
330
+ return;
331
+ }
332
+
333
+ const cellEdge = CheckCellEdge(event, target);
334
+ if (cellEdge.is) {
335
+ if (this._element) this._element.style.cursor = '';
336
+ this.__removeGlobalEvents();
337
+ if (this._resizeLine?.style.display === 'block') this._resizeLine.style.display = 'none';
338
+ this._resizeLine = this.editor.frameContext.get('wrapper').querySelector(RESIZE_CELL_CLASS);
339
+ this._setResizeLinePosition(domUtils.getParentElement(target, domUtils.isTable), target, this._resizeLine, cellEdge.isLeft);
340
+ this._resizeLine.style.display = 'block';
341
+ return;
342
+ }
343
+
344
+ const rowEdge = CheckRowEdge(event, target);
345
+ if (rowEdge.is) {
346
+ this.__removeGlobalEvents();
347
+ this._element = domUtils.getParentElement(target, domUtils.isTable);
348
+ this._element.style.cursor = 'ns-resize';
349
+ if (this._resizeLine?.style.display === 'block') this._resizeLine.style.display = 'none';
350
+ this._resizeLine = this.editor.frameContext.get('wrapper').querySelector(RESIZE_ROW_CLASS);
351
+ this._setResizeRowPosition(domUtils.getParentElement(target, domUtils.isTable), target, this._resizeLine);
352
+ this._resizeLine.style.display = 'block';
353
+ return;
354
+ }
355
+
356
+ if (this._element) this._element.style.cursor = '';
357
+ this.__hideResizeLine();
358
+ },
359
+
360
+ onScroll() {
361
+ if (this._resizeLine?.style.display !== 'block') return;
362
+ // delete resize line position
363
+ if (this._element) this._element.style.cursor = '';
364
+ this._resizeLine.style.display = 'none';
365
+ },
366
+
367
+ /**
368
+ * @override core
369
+ * @param {any} event Event object
370
+ */
371
+ onMouseDown({ event }) {
372
+ this._ref = null;
373
+ const target = domUtils.getParentElement(event.target, IsResizeEls);
374
+ if (!target) return;
375
+
376
+ const cellEdge = CheckCellEdge(event, target);
377
+ if (cellEdge.is) {
378
+ try {
379
+ this._deleteStyleSelectedCells();
380
+ this.setCellInfo(target, true);
381
+ const colIndex = this._logical_cellIndex - (cellEdge.isLeft ? 1 : 0);
382
+
383
+ // ready
384
+ this.editor.enableBackWrapper('ew-resize');
385
+ if (!this._resizeLine) this._resizeLine = this.editor.frameContext.get('wrapper').querySelector(RESIZE_CELL_CLASS);
386
+ this._resizeLinePrev = this.editor.frameContext.get('wrapper').querySelector(RESIZE_CELL_PREV_CLASS);
387
+
388
+ // select figure
389
+ if (colIndex < 0 || colIndex === this._logical_cellCnt - 1) {
390
+ this._startFigureResizing(cellEdge.startX, colIndex < 0);
391
+ return;
392
+ }
393
+
394
+ const col = this._element.querySelector('colgroup').querySelectorAll('col')[colIndex < 0 ? 0 : colIndex];
395
+ this._startCellResizing(col, cellEdge.startX, numbers.get(_w.getComputedStyle(col).width, CELL_DECIMAL_END), cellEdge.isLeft);
396
+ } catch (err) {
397
+ console.warn('[SUNEDITOR.plugins.table.error]', err);
398
+ this.__removeGlobalEvents();
399
+ }
400
+
401
+ return;
402
+ }
403
+
404
+ const rowEdge = CheckRowEdge(event, target);
405
+ if (rowEdge.is) {
406
+ try {
407
+ let row = domUtils.getParentElement(target, domUtils.isTableRow);
408
+ let rowSpan = target.rowSpan;
409
+ if (rowSpan > 1) {
410
+ while (domUtils.isTableRow(row) && rowSpan > 1) {
411
+ row = row.nextElementSibling;
412
+ --rowSpan;
413
+ }
414
+ }
415
+
416
+ this._deleteStyleSelectedCells();
417
+ this.setRowInfo(row);
418
+
419
+ // ready
420
+ this.editor.enableBackWrapper('ns-resize');
421
+ if (!this._resizeLine) this._resizeLine = this.editor.frameContext.get('wrapper').querySelector(RESIZE_ROW_CLASS);
422
+ this._resizeLinePrev = this.editor.frameContext.get('wrapper').querySelector(RESIZE_ROW_PREV_CLASS);
423
+
424
+ this._startRowResizing(row, rowEdge.startY, numbers.get(_w.getComputedStyle(row).height, CELL_DECIMAL_END));
425
+ } catch (err) {
426
+ console.warn('[SUNEDITOR.plugins.table.error]', err);
427
+ this.__removeGlobalEvents();
428
+ }
429
+
430
+ return;
431
+ }
432
+
433
+ if (!(target !== this._fixedCell && !this._shift)) return;
434
+
435
+ this._deleteStyleSelectedCells();
436
+ if (/^TR$/i.test(target.nodeName)) return;
437
+
438
+ this.selectCells(target, false);
439
+ },
440
+
441
+ /**
442
+ * @override core
443
+ */
444
+ onMouseUp() {
445
+ this._shift = false;
446
+ },
447
+
448
+ /**
449
+ * @override core
450
+ */
451
+ onMouseLeave() {
452
+ this.__hideResizeLine();
453
+ },
454
+
455
+ /**
456
+ * @override core
457
+ * @param {any} event Event object
458
+ * @param {any} range range object
459
+ * @param {Element} line Current line element
460
+ */
461
+ onKeyDown({ event, range, line }) {
462
+ this._ref = null;
463
+ if (this.editor.selectMenuOn || this._resizing) return;
464
+
465
+ const keyCode = event.keyCode;
466
+ // table tabkey
467
+ if (keyCode === 9) {
468
+ const tableCell = domUtils.getParentElement(line, domUtils.isTableCell);
469
+ if (tableCell && range.collapsed && domUtils.isEdgePoint(range.startContainer, range.startOffset)) {
470
+ this._closeController();
471
+
472
+ const shift = event.shiftKey;
473
+ const table = domUtils.getParentElement(tableCell, 'table');
474
+ const cells = domUtils.getListChildren(table, domUtils.isTableCell);
475
+ const idx = shift ? domUtils.prevIndex(cells, tableCell) : domUtils.nextIndex(cells, tableCell);
476
+
477
+ if (idx === cells.length && !shift) {
478
+ if (!domUtils.getParentElement(tableCell, 'thead')) {
479
+ const rows = table.rows;
480
+ const newRow = this.insertBodyRow(table, rows.length, rows[rows.length - 1].cells.length);
481
+ const firstTd = newRow.querySelector('td div');
482
+ this.selection.setRange(firstTd, 0, firstTd, 0);
483
+ }
484
+
485
+ event.preventDefault();
486
+ event.stopPropagation();
487
+
488
+ return false;
489
+ }
490
+
491
+ if (idx === -1 && shift) return;
492
+
493
+ let moveCell = cells[idx];
494
+ if (!moveCell) return;
495
+
496
+ moveCell = moveCell.firstElementChild || moveCell;
497
+ this.selection.setRange(moveCell, 0, moveCell, 0);
498
+
499
+ event.preventDefault();
500
+ event.stopPropagation();
501
+
502
+ return false;
503
+ }
504
+ }
505
+
506
+ let cell = null;
507
+ if (!event.shiftKey || keyCode !== 16) {
508
+ cell = domUtils.getParentElement(line, domUtils.isTableCell);
509
+ if (!domUtils.hasClass(cell, 'se-selected-cell-focus')) return;
510
+
511
+ this._deleteStyleSelectedCells();
512
+ this._toggleEditor(true);
513
+ this.__removeGlobalEvents();
514
+ this._closeController();
515
+
516
+ return;
517
+ }
518
+
519
+ if (this._shift || this._ref) return;
520
+
521
+ cell = cell || domUtils.getParentElement(line, domUtils.isTableCell);
522
+ if (cell) {
523
+ this._fixedCell = cell;
524
+ this._closeController();
525
+ this.selectCells(cell, event.shiftKey);
526
+ return false;
527
+ }
528
+ },
529
+
530
+ /**
531
+ * @override core
532
+ * @param {any} event Event object
533
+ * @param {any} range range object
534
+ * @param {Element} line Current line element
535
+ */
536
+ onKeyUp({ line }) {
537
+ if (this._shift && domUtils.getParentElement(line, domUtils.isTableCell) === this._fixedCell) {
538
+ this._deleteStyleSelectedCells();
539
+ this._toggleEditor(true);
540
+ this.__removeGlobalEvents();
541
+ }
542
+ this._shift = false;
543
+ },
544
+
545
+ /**
546
+ * @override ColorPicker
547
+ */
548
+ colorPickerAction(color) {
549
+ const target = this.propTargets[`${this.sliderType}_color`];
550
+ target.style.borderColor = target.value = color;
551
+ this.controller_colorPicker.close();
552
+ },
553
+
554
+ /**
555
+ * @override controller
556
+ * @param {Element} target Target button element
557
+ * @returns
558
+ */
559
+ controllerAction(target) {
560
+ const command = target.getAttribute('data-command');
561
+ if (!command) return;
562
+
563
+ const { back_color, font_color, border_color } = this.propTargets;
564
+ const value = target.getAttribute('data-value');
565
+
566
+ switch (command) {
567
+ case 'header':
568
+ this.toggleHeader();
569
+ this._historyPush();
570
+ break;
571
+ case 'caption':
572
+ this.toggleCaption();
573
+ this._historyPush();
574
+ break;
575
+ case 'onsplit':
576
+ this.selectMenu_split.open();
577
+ break;
578
+ case 'oncolumn':
579
+ this.selectMenu_column.open();
580
+ break;
581
+ case 'onrow':
582
+ this.selectMenu_row.menus[0].style.display = this.selectMenu_row.menus[1].style.display = /^TH$/i.test(this._tdElement?.nodeName) ? 'none' : '';
583
+ this.selectMenu_row.open();
584
+ break;
585
+ case 'openTableProperties':
586
+ if (this.controller_props.currentTarget === target && this.controller_props.form?.style.display === 'block') {
587
+ this.controller_props.close();
588
+ } else {
589
+ this.controller_props_title.textContent = this.lang.tableProperties;
590
+ this._setCtrlProps('table');
591
+ this.controller_props.open(target, this.controller_table.form, { isWWTarget: false, initMethod: null, addOffset: null });
592
+ }
593
+ break;
594
+ case 'openCellProperties':
595
+ if (this.controller_props.currentTarget === target && this.controller_props.form?.style.display === 'block') {
596
+ this.controller_props.close();
597
+ } else {
598
+ this.controller_props_title.textContent = this.lang.cellProperties;
599
+ this._setCtrlProps('cell');
600
+ this.controller_props.open(target, this.controller_cell.form, { isWWTarget: false, initMethod: null, addOffset: null });
601
+ }
602
+ break;
603
+ case 'props_onborder_format':
604
+ if (this._propsCache.length === 1) {
605
+ this.selectMenu_props_border_format_oneCell.open();
606
+ } else {
607
+ this.selectMenu_props_border_format.open();
608
+ }
609
+ break;
610
+ case 'props_onborder_style':
611
+ this.selectMenu_props_border.open();
612
+ break;
613
+ case 'props_onpalette':
614
+ this._onColorPalette(target, value, value === 'border' ? border_color : value === 'back' ? back_color : font_color);
615
+ break;
616
+ case 'props_font_style':
617
+ domUtils.toggleClass(this.propTargets[`font_${value}`], 'on');
618
+ break;
619
+ case 'props_submit':
620
+ this._submitProps(target);
621
+ break;
622
+ case 'revert': {
623
+ const propsCache = this._propsCache;
624
+ for (let i = 0, len = propsCache.length; i < len; i++) {
625
+ propsCache[i][0].style.cssText = propsCache[i][1];
626
+ }
627
+ // alignment
628
+ this._setAlignProps(this.propTargets.cell_alignment, this._propsAlignCache, true);
629
+ this._setAlignProps(this.propTargets.cell_alignment_vertical, this._propsVerticalAlignCache, true);
630
+ if (domUtils.isTable(propsCache[0][0]) && this._figure) {
631
+ this._figure.style.float = this._propsAlignCache;
632
+ }
633
+ break;
634
+ }
635
+ case 'close_props':
636
+ this.controller_props.close();
637
+ break;
638
+ case 'props_align':
639
+ this._setAlignProps(this.propTargets.cell_alignment, target.getAttribute('data-value'), false);
640
+ break;
641
+ case 'props_align_vertical':
642
+ this._setAlignProps(this.propTargets.cell_alignment_vertical, target.getAttribute('data-value'), false);
643
+ break;
644
+ case 'merge':
645
+ this.mergeCells();
646
+ break;
647
+ case 'resize':
648
+ this._maxWidth = !this._maxWidth;
649
+ this.setTableStyle('width', false);
650
+ this._historyPush();
651
+ this.component.select(this._element, Table.key, true);
652
+ break;
653
+ case 'layout':
654
+ this._fixedColumn = !this._fixedColumn;
655
+ this.setTableStyle('column', false);
656
+ this._historyPush();
657
+ this.component.select(this._element, Table.key, true);
658
+ break;
659
+ case 'remove': {
660
+ const emptyDiv = this._figure?.parentNode;
661
+ domUtils.removeItem(this._figure);
662
+ this._closeController();
663
+
664
+ if (emptyDiv !== this.editor.frameContext.get('wysiwyg'))
665
+ this.nodeTransform.removeAllParents(
666
+ emptyDiv,
667
+ function (current) {
668
+ return current.childNodes.length === 0;
669
+ },
670
+ null
671
+ );
672
+ this.editor.focus();
673
+ this.history.push(false);
674
+ }
675
+ }
676
+
677
+ if (!/(^props_|^revert|Properties$)/.test(command)) {
678
+ this.controller_props.close();
679
+ this.controller_colorPicker.close();
680
+ }
681
+
682
+ if (!/^(remove|props_|on|open|merge)/.test(command)) {
683
+ this.setCellControllerPosition(this._tdElement, this._shift);
684
+ }
685
+ },
686
+
687
+ /**
688
+ * @override controller
689
+ */
690
+ close() {
691
+ this.__removeGlobalEvents();
692
+ this._deleteStyleSelectedCells();
693
+ this._toggleEditor(true);
694
+
695
+ this._figure = null;
696
+ this._element = null;
697
+ // this._tdElement = null;
698
+ this._trElement = null;
699
+ this._trElements = null;
700
+ this._tableXY = [];
701
+ this._maxWidth = false;
702
+ this._fixedColumn = false;
703
+ this._physical_cellCnt = 0;
704
+ this._logical_cellCnt = 0;
705
+ this._rowCnt = 0;
706
+ this._rowIndex = 0;
707
+ this._physical_cellIndex = 0;
708
+ this._logical_cellIndex = 0;
709
+ this._current_colSpan = 0;
710
+ this._current_rowSpan = 0;
711
+
712
+ this._shift = false;
713
+ this._selectedCells = null;
714
+ this._selectedTable = null;
715
+ this._ref = null;
716
+
717
+ this._fixedCell = null;
718
+ this._selectedCell = null;
719
+ this._fixedCellName = null;
720
+
721
+ const { border_format, border_color, border_style, border_width, back_color, font_color, cell_alignment, cell_alignment_vertical, font_bold, font_underline, font_italic, font_strike } = this.propTargets;
722
+ domUtils.removeClass([border_format, border_color, border_style, border_width, back_color, font_color, cell_alignment, cell_alignment_vertical, font_bold, font_underline, font_italic, font_strike], 'on');
723
+ },
724
+
725
+ selectCells(tdElement, shift) {
726
+ if (!this._shift && !this._ref) this.__removeGlobalEvents();
727
+
728
+ this._shift = shift;
729
+ this._fixedCell = tdElement;
730
+ this._fixedCellName = tdElement.nodeName;
731
+ this._selectedTable = domUtils.getParentElement(tdElement, 'TABLE');
732
+
733
+ this._deleteStyleSelectedCells();
734
+ domUtils.addClass(tdElement, 'se-selected-cell-focus');
735
+
736
+ if (!shift) {
737
+ this.__globalEvents.on = this.eventManager.addGlobalEvent('mousemove', this._bindMultiOn, false);
738
+ } else {
739
+ this.__globalEvents.shiftOff = this.eventManager.addGlobalEvent('keyup', this._bindShiftOff, false);
740
+ this.__globalEvents.on = this.eventManager.addGlobalEvent('mousedown', this._bindMultiOn, false);
741
+ }
742
+
743
+ this.__globalEvents.off = this.eventManager.addGlobalEvent('mouseup', this._bindMultiOff, false);
744
+ this.__globalEvents.touchOff = this.eventManager.addGlobalEvent('touchmove', this._bindTouchOff, false);
745
+ },
746
+
747
+ seTableInfo(element) {
748
+ const table = (this._element = this._selectedTable || domUtils.getParentElement(element, 'TABLE'));
749
+ this._figure = domUtils.getParentElement(table, domUtils.isFigure) || table;
750
+ return table;
751
+ },
752
+
753
+ setCellInfo(tdElement, reset) {
754
+ const table = this.seTableInfo(tdElement);
755
+ this._trElement = tdElement.parentNode;
756
+
757
+ // hedaer
758
+ if (table.querySelector('thead')) domUtils.addClass(this.headerButton, 'active');
759
+ else domUtils.removeClass(this.headerButton, 'active');
760
+
761
+ // caption
762
+ if (table.querySelector('caption')) domUtils.addClass(this.captionButton, 'active');
763
+ else domUtils.removeClass(this.captionButton, 'active');
764
+
765
+ if (reset || this._physical_cellCnt === 0) {
766
+ if (this._tdElement !== tdElement) {
767
+ this._tdElement = tdElement;
768
+ this._trElement = tdElement.parentNode;
769
+ }
770
+
771
+ if (!this._selectedCells || this._selectedCells.length === 0) this._selectedCells = [tdElement];
772
+
773
+ const rows = (this._trElements = table.rows);
774
+ const cellIndex = tdElement.cellIndex;
775
+
776
+ let cellCnt = 0;
777
+ for (let i = 0, cells = rows[0].cells, len = rows[0].cells.length; i < len; i++) {
778
+ cellCnt += cells[i].colSpan;
779
+ }
780
+
781
+ // row cnt, row index
782
+ const rowIndex = (this._rowIndex = this._trElement.rowIndex);
783
+ this._rowCnt = rows.length;
784
+
785
+ // cell cnt, physical cell index
786
+ this._physical_cellCnt = this._trElement.cells.length;
787
+ this._logical_cellCnt = cellCnt;
788
+ this._physical_cellIndex = cellIndex;
789
+
790
+ // span
791
+ this._current_colSpan = this._tdElement.colSpan - 1;
792
+ this._current_rowSpan = this._trElement.cells[cellIndex].rowSpan - 1;
793
+
794
+ // find logcal cell index
795
+ let rowSpanArr = [];
796
+ let spanIndex = [];
797
+ for (let i = 0, cells, colSpan; i <= rowIndex; i++) {
798
+ cells = rows[i].cells;
799
+ colSpan = 0;
800
+ for (let c = 0, cLen = cells.length, cell, cs, rs, logcalIndex; c < cLen; c++) {
801
+ cell = cells[c];
802
+ cs = cell.colSpan - 1;
803
+ rs = cell.rowSpan - 1;
804
+ logcalIndex = c + colSpan;
805
+
806
+ if (spanIndex.length > 0) {
807
+ for (let r = 0, arr; r < spanIndex.length; r++) {
808
+ arr = spanIndex[r];
809
+ if (arr.row > i) continue;
810
+ if (logcalIndex >= arr.index) {
811
+ colSpan += arr.cs;
812
+ logcalIndex += arr.cs;
813
+ arr.rs -= 1;
814
+ arr.row = i + 1;
815
+ if (arr.rs < 1) {
816
+ spanIndex.splice(r, 1);
817
+ r--;
818
+ }
819
+ } else if (c === cLen - 1) {
820
+ arr.rs -= 1;
821
+ arr.row = i + 1;
822
+ if (arr.rs < 1) {
823
+ spanIndex.splice(r, 1);
824
+ r--;
825
+ }
826
+ }
827
+ }
828
+ }
829
+
830
+ // logcal cell index
831
+ if (i === rowIndex && c === cellIndex) {
832
+ this._logical_cellIndex = logcalIndex;
833
+ break;
834
+ }
835
+
836
+ if (rs > 0) {
837
+ rowSpanArr.push({
838
+ index: logcalIndex,
839
+ cs: cs + 1,
840
+ rs: rs,
841
+ row: -1
842
+ });
843
+ }
844
+
845
+ colSpan += cs;
846
+ }
847
+
848
+ spanIndex = spanIndex.concat(rowSpanArr).sort(function (a, b) {
849
+ return a.index - b.index;
850
+ });
851
+ rowSpanArr = [];
852
+ }
853
+
854
+ rowSpanArr = null;
855
+ spanIndex = null;
856
+ }
857
+ },
858
+
859
+ setRowInfo(trElement) {
860
+ const table = this.seTableInfo(trElement);
861
+ const rows = (this._trElements = table.rows);
862
+ this._rowCnt = rows.length;
863
+ this._rowIndex = trElement.rowIndex;
864
+ },
865
+
866
+ editTable(type, option) {
867
+ const table = this._element;
868
+ const isRow = type === 'row';
869
+
870
+ if (isRow) {
871
+ const tableAttr = this._trElement.parentNode;
872
+ if (/^THEAD$/i.test(tableAttr.nodeName)) {
873
+ if (option === 'up') {
874
+ return;
875
+ } else if (!tableAttr.nextElementSibling || !/^TBODY$/i.test(tableAttr.nextElementSibling.nodeName)) {
876
+ if (!option) {
877
+ domUtils.removeItem(this._figure);
878
+ this._closeController();
879
+ } else {
880
+ table.innerHTML += '<tbody><tr>' + CreateCells('td', this._logical_cellCnt, false) + '</tr></tbody>';
881
+ }
882
+ return;
883
+ }
884
+ }
885
+ }
886
+
887
+ // multi
888
+ if (this._ref) {
889
+ const positionCell = this._tdElement;
890
+ const selectedCells = this._selectedCells;
891
+ // multi - row
892
+ if (isRow) {
893
+ // remove row
894
+ if (!option) {
895
+ let row = selectedCells[0].parentNode;
896
+ const removeCells = [selectedCells[0]];
897
+
898
+ for (let i = 1, len = selectedCells.length, cell; i < len; i++) {
899
+ cell = selectedCells[i];
900
+ if (row !== cell.parentNode) {
901
+ removeCells.push(cell);
902
+ row = cell.parentNode;
903
+ }
904
+ }
905
+
906
+ for (let i = 0, len = removeCells.length; i < len; i++) {
907
+ this.setCellInfo(removeCells[i], true);
908
+ this.editRow(option);
909
+ }
910
+ } else {
911
+ // edit row
912
+ this.setCellInfo(option === 'up' ? selectedCells[0] : selectedCells[selectedCells.length - 1], true);
913
+ this.editRow(option, positionCell);
914
+ }
915
+ } else {
916
+ // multi - cell
917
+ const firstRow = selectedCells[0].parentNode;
918
+ // remove cell
919
+ if (!option) {
920
+ const removeCells = [selectedCells[0]];
921
+
922
+ for (let i = 1, len = selectedCells.length, cell; i < len; i++) {
923
+ cell = selectedCells[i];
924
+ if (firstRow === cell.parentNode) {
925
+ removeCells.push(cell);
926
+ } else {
927
+ break;
928
+ }
929
+ }
930
+
931
+ for (let i = 0, len = removeCells.length; i < len; i++) {
932
+ this.setCellInfo(removeCells[i], true);
933
+ this.editCell(option);
934
+ }
935
+ } else {
936
+ // edit cell
937
+ let rightCell = null;
938
+
939
+ for (let i = 0, len = selectedCells.length - 1; i < len; i++) {
940
+ if (firstRow !== selectedCells[i + 1].parentNode) {
941
+ rightCell = selectedCells[i];
942
+ break;
943
+ }
944
+ }
945
+
946
+ this.setCellInfo(option === 'left' ? selectedCells[0] : rightCell || selectedCells[0], true);
947
+ this.editCell(option, positionCell);
948
+ }
949
+ }
950
+
951
+ if (!option) this.close();
952
+ } // one
953
+ else {
954
+ this[isRow ? 'editRow' : 'editCell'](option);
955
+ }
956
+
957
+ // after remove
958
+ if (!option) {
959
+ const children = table.children;
960
+ for (let i = 0; i < children.length; i++) {
961
+ if (children[i].children.length === 0) {
962
+ domUtils.removeItem(children[i]);
963
+ i--;
964
+ }
965
+ }
966
+
967
+ if (table.children.length === 0) domUtils.removeItem(table);
968
+ }
969
+ },
970
+
971
+ editRow(option, positionResetElement) {
972
+ const remove = !option;
973
+ const up = option === 'up';
974
+ const originRowIndex = this._rowIndex;
975
+ const rowIndex = remove || up ? originRowIndex : originRowIndex + this._current_rowSpan + 1;
976
+ const sign = remove ? -1 : 1;
977
+
978
+ const rows = this._trElements;
979
+ let cellCnt = this._logical_cellCnt;
980
+
981
+ for (let i = 0, len = originRowIndex + (remove ? -1 : 0), cell; i <= len; i++) {
982
+ cell = rows[i].cells;
983
+ if (cell.length === 0) return;
984
+
985
+ for (let c = 0, cLen = cell.length, rs, cs; c < cLen; c++) {
986
+ rs = cell[c].rowSpan;
987
+ cs = cell[c].colSpan;
988
+ if (rs < 2 && cs < 2) continue;
989
+
990
+ if (rs + i > rowIndex && rowIndex > i) {
991
+ cell[c].rowSpan = rs + sign;
992
+ cellCnt -= cs;
993
+ }
994
+ }
995
+ }
996
+
997
+ if (remove) {
998
+ const next = rows[originRowIndex + 1];
999
+ if (next) {
1000
+ const spanCells = [];
1001
+ let cells = rows[originRowIndex].cells;
1002
+ let colSpan = 0;
1003
+
1004
+ for (let i = 0, len = cells.length, cell, logcalIndex; i < len; i++) {
1005
+ cell = cells[i];
1006
+ logcalIndex = i + colSpan;
1007
+ colSpan += cell.colSpan - 1;
1008
+
1009
+ if (cell.rowSpan > 1) {
1010
+ cell.rowSpan -= 1;
1011
+ spanCells.push({ cell: cell.cloneNode(false), index: logcalIndex });
1012
+ }
1013
+ }
1014
+
1015
+ if (spanCells.length > 0) {
1016
+ let spanCell = spanCells.shift();
1017
+ cells = next.cells;
1018
+ colSpan = 0;
1019
+
1020
+ for (let i = 0, len = cells.length, cell, logcalIndex; i < len; i++) {
1021
+ cell = cells[i];
1022
+ logcalIndex = i + colSpan;
1023
+ colSpan += cell.colSpan - 1;
1024
+
1025
+ if (logcalIndex >= spanCell.index) {
1026
+ i--;
1027
+ colSpan--;
1028
+ colSpan += spanCell.cell.colSpan - 1;
1029
+ next.insertBefore(spanCell.cell, cell);
1030
+ spanCell = spanCells.shift();
1031
+ if (!spanCell) break;
1032
+ }
1033
+ }
1034
+
1035
+ if (spanCell) {
1036
+ next.appendChild(spanCell.cell);
1037
+ for (let i = 0, len = spanCells.length; i < len; i++) {
1038
+ next.appendChild(spanCells[i].cell);
1039
+ }
1040
+ }
1041
+ }
1042
+ }
1043
+
1044
+ this._element.deleteRow(rowIndex);
1045
+ } else {
1046
+ this.insertBodyRow(this._element, rowIndex, cellCnt);
1047
+ }
1048
+
1049
+ if (!remove) {
1050
+ this.setCellControllerPosition(positionResetElement || this._tdElement, true);
1051
+ } else {
1052
+ this._closeController();
1053
+ }
1054
+ },
1055
+
1056
+ editCell(option, positionResetElement) {
1057
+ const remove = !option;
1058
+ const left = option === 'left';
1059
+ const colSpan = this._current_colSpan;
1060
+ const cellIndex = remove || left ? this._logical_cellIndex : this._logical_cellIndex + colSpan + 1;
1061
+
1062
+ const rows = this._trElements;
1063
+ let rowSpanArr = [];
1064
+ let spanIndex = [];
1065
+ let passCell = 0;
1066
+ let insertIndex;
1067
+ const removeCell = [];
1068
+ const removeSpanArr = [];
1069
+
1070
+ for (let i = 0, len = this._rowCnt, row, cells, newCell, applySpan, cellColSpan; i < len; i++) {
1071
+ row = rows[i];
1072
+ insertIndex = cellIndex;
1073
+ applySpan = false;
1074
+ cells = row.cells;
1075
+ cellColSpan = 0;
1076
+
1077
+ for (let c = 0, cell, cLen = cells.length, rs, cs, removeIndex; c < cLen; c++) {
1078
+ cell = cells[c];
1079
+ if (!cell) break;
1080
+
1081
+ rs = cell.rowSpan - 1;
1082
+ cs = cell.colSpan - 1;
1083
+
1084
+ if (!remove) {
1085
+ if (c >= insertIndex) break;
1086
+ if (cs > 0) {
1087
+ if (passCell < 1 && cs + c >= insertIndex) {
1088
+ cell.colSpan += 1;
1089
+ insertIndex = null;
1090
+ passCell = rs + 1;
1091
+ break;
1092
+ }
1093
+
1094
+ insertIndex -= cs;
1095
+ }
1096
+
1097
+ if (!applySpan) {
1098
+ for (let r = 0, arr; r < spanIndex.length; r++) {
1099
+ arr = spanIndex[r];
1100
+ insertIndex -= arr.cs;
1101
+ arr.rs -= 1;
1102
+ if (arr.rs < 1) {
1103
+ spanIndex.splice(r, 1);
1104
+ r--;
1105
+ }
1106
+ }
1107
+ applySpan = true;
1108
+ }
1109
+ } else {
1110
+ removeIndex = c + cellColSpan;
1111
+
1112
+ if (spanIndex.length > 0) {
1113
+ const lastCell = !cells[c + 1];
1114
+ for (let r = 0, arr; r < spanIndex.length; r++) {
1115
+ arr = spanIndex[r];
1116
+ if (arr.row > i) continue;
1117
+
1118
+ if (removeIndex >= arr.index) {
1119
+ cellColSpan += arr.cs;
1120
+ removeIndex = c + cellColSpan;
1121
+ arr.rs -= 1;
1122
+ arr.row = i + 1;
1123
+ if (arr.rs < 1) {
1124
+ spanIndex.splice(r, 1);
1125
+ r--;
1126
+ }
1127
+ } else if (lastCell) {
1128
+ arr.rs -= 1;
1129
+ arr.row = i + 1;
1130
+ if (arr.rs < 1) {
1131
+ spanIndex.splice(r, 1);
1132
+ r--;
1133
+ }
1134
+ }
1135
+ }
1136
+ }
1137
+
1138
+ if (rs > 0) {
1139
+ rowSpanArr.push({
1140
+ rs: rs,
1141
+ cs: cs + 1,
1142
+ index: removeIndex,
1143
+ row: -1
1144
+ });
1145
+ }
1146
+
1147
+ if (removeIndex >= insertIndex && removeIndex + cs <= insertIndex + colSpan) {
1148
+ removeCell.push(cell);
1149
+ } else if (removeIndex <= insertIndex + colSpan && removeIndex + cs >= insertIndex) {
1150
+ cell.colSpan -= numbers.getOverlapRangeAtIndex(cellIndex, cellIndex + colSpan, removeIndex, removeIndex + cs);
1151
+ } else if (rs > 0 && (removeIndex < insertIndex || removeIndex + cs > insertIndex + colSpan)) {
1152
+ removeSpanArr.push({
1153
+ cell: cell,
1154
+ i: i,
1155
+ rs: i + rs
1156
+ });
1157
+ }
1158
+
1159
+ cellColSpan += cs;
1160
+ }
1161
+ }
1162
+
1163
+ spanIndex = spanIndex.concat(rowSpanArr).sort(function (a, b) {
1164
+ return a.index - b.index;
1165
+ });
1166
+ rowSpanArr = [];
1167
+
1168
+ if (!remove) {
1169
+ if (passCell > 0) {
1170
+ passCell -= 1;
1171
+ continue;
1172
+ }
1173
+
1174
+ if (insertIndex !== null && cells.length > 0) {
1175
+ newCell = CreateCells(cells[0].nodeName, 0, true);
1176
+ newCell = row.insertBefore(newCell, cells[insertIndex]);
1177
+ }
1178
+ }
1179
+ }
1180
+
1181
+ const colgroup = this._element.querySelector('colgroup');
1182
+ if (colgroup) {
1183
+ const cols = colgroup.querySelectorAll('col');
1184
+ if (remove) {
1185
+ domUtils.removeItem(cols[insertIndex]);
1186
+ } else {
1187
+ let totalW = 0;
1188
+ for (let i = 0, len = cols.length, w; i < len; i++) {
1189
+ w = numbers.get(cols[i].style.width);
1190
+ w -= Math.round((w * len * 0.1) / 2, CELL_DECIMAL_END);
1191
+ totalW += w;
1192
+ cols[i].style.width = `${w}%`;
1193
+ }
1194
+ const newCol = domUtils.createElement('col', { style: `width:${100 - totalW}%` });
1195
+ colgroup.insertBefore(newCol, cols[insertIndex]);
1196
+ }
1197
+ }
1198
+
1199
+ if (remove) {
1200
+ let removeFirst, removeEnd;
1201
+ for (let r = 0, rLen = removeCell.length, row; r < rLen; r++) {
1202
+ row = removeCell[r].parentNode;
1203
+ domUtils.removeItem(removeCell[r]);
1204
+ if (row.cells.length === 0) {
1205
+ if (!removeFirst) removeFirst = domUtils.getArrayIndex(rows, row);
1206
+ removeEnd = domUtils.getArrayIndex(rows, row);
1207
+ domUtils.removeItem(row);
1208
+ }
1209
+ }
1210
+
1211
+ for (let c = 0, cLen = removeSpanArr.length, rowSpanCell; c < cLen; c++) {
1212
+ rowSpanCell = removeSpanArr[c];
1213
+ rowSpanCell.cell.rowSpan = numbers.getOverlapRangeAtIndex(removeFirst, removeEnd, rowSpanCell.i, rowSpanCell.rs);
1214
+ }
1215
+
1216
+ this._closeController();
1217
+ } else {
1218
+ this.setCellControllerPosition(positionResetElement || this._tdElement, true);
1219
+ }
1220
+ },
1221
+
1222
+ insertBodyRow(table, rowIndex, cellCnt) {
1223
+ const newRow = table.insertRow(rowIndex);
1224
+ newRow.innerHTML = CreateCells('td', cellCnt, false);
1225
+ return newRow;
1226
+ },
1227
+
1228
+ mergeCells() {
1229
+ const ref = this._ref;
1230
+ const selectedCells = this._selectedCells;
1231
+ const mergeCell = selectedCells[0];
1232
+
1233
+ let emptyRowFirst = null;
1234
+ let emptyRowLast = null;
1235
+ const cs = ref.ce - ref.cs + 1;
1236
+ let rs = ref.re - ref.rs + 1;
1237
+ let mergeHTML = '';
1238
+ let row = null;
1239
+
1240
+ for (let i = 1, len = selectedCells.length, cell, ch; i < len; i++) {
1241
+ cell = selectedCells[i];
1242
+ if (row !== cell.parentNode) row = cell.parentNode;
1243
+
1244
+ ch = cell.children;
1245
+ for (let c = 0, cLen = ch.length; c < cLen; c++) {
1246
+ if (this.format.isLine(ch[c]) && domUtils.isZeroWith(ch[c].textContent)) {
1247
+ domUtils.removeItem(ch[c]);
1248
+ }
1249
+ }
1250
+
1251
+ mergeHTML += cell.innerHTML;
1252
+ domUtils.removeItem(cell);
1253
+
1254
+ if (row.cells.length === 0) {
1255
+ if (!emptyRowFirst) emptyRowFirst = row;
1256
+ else emptyRowLast = row;
1257
+ rs -= 1;
1258
+ }
1259
+ }
1260
+
1261
+ if (emptyRowFirst) {
1262
+ const rows = this._trElements;
1263
+ const rowIndexFirst = domUtils.getArrayIndex(rows, emptyRowFirst);
1264
+ const rowIndexLast = domUtils.getArrayIndex(rows, emptyRowLast || emptyRowFirst);
1265
+ const removeRows = [];
1266
+
1267
+ for (let i = 0, cells; i <= rowIndexLast; i++) {
1268
+ cells = rows[i].cells;
1269
+ if (cells.length === 0) {
1270
+ removeRows.push(rows[i]);
1271
+ continue;
1272
+ }
1273
+
1274
+ for (let c = 0, cLen = cells.length, cell, rs2; c < cLen; c++) {
1275
+ cell = cells[c];
1276
+ rs2 = cell.rowSpan - 1;
1277
+ if (rs2 > 0 && i + rs2 >= rowIndexFirst) {
1278
+ cell.rowSpan -= numbers.getOverlapRangeAtIndex(rowIndexFirst, rowIndexLast, i, i + rs2);
1279
+ }
1280
+ }
1281
+ }
1282
+
1283
+ for (let i = 0, len = removeRows.length; i < len; i++) {
1284
+ domUtils.removeItem(removeRows[i]);
1285
+ }
1286
+ }
1287
+
1288
+ mergeCell.innerHTML += mergeHTML;
1289
+ mergeCell.colSpan = cs;
1290
+ mergeCell.rowSpan = rs;
1291
+
1292
+ this.setMergeSplitButton(true, false);
1293
+ this.setController(mergeCell);
1294
+
1295
+ this.editor.focusEdge(mergeCell);
1296
+ this._historyPush();
1297
+ },
1298
+
1299
+ toggleHeader() {
1300
+ const btn = this.headerButton;
1301
+ const active = domUtils.hasClass(btn, 'active');
1302
+ const table = this._element;
1303
+
1304
+ if (!active) {
1305
+ const header = domUtils.createElement('THEAD');
1306
+ header.innerHTML = '<tr>' + CreateCells('th', this._logical_cellCnt, false) + '</tr>';
1307
+ table.insertBefore(header, table.firstElementChild);
1308
+ } else {
1309
+ domUtils.removeItem(table.querySelector('thead'));
1310
+ }
1311
+
1312
+ domUtils.toggleClass(btn, 'active');
1313
+
1314
+ if (/TH/i.test(this._tdElement.nodeName)) {
1315
+ this._closeController();
1316
+ } else {
1317
+ this.setCellControllerPosition(this._tdElement, false);
1318
+ }
1319
+ },
1320
+
1321
+ toggleCaption() {
1322
+ const btn = this.captionButton;
1323
+ const active = domUtils.hasClass(btn, 'active');
1324
+ const table = this._element;
1325
+
1326
+ if (!active) {
1327
+ const caption = domUtils.createElement('CAPTION', { class: `se-table-caption-${this.captionPosition}` });
1328
+ caption.innerHTML = '<div><br></div>';
1329
+ table.insertBefore(caption, table.firstElementChild);
1330
+ } else {
1331
+ domUtils.removeItem(table.querySelector('caption'));
1332
+ }
1333
+
1334
+ domUtils.toggleClass(btn, 'active');
1335
+ this.setCellControllerPosition(this._tdElement, false);
1336
+ },
1337
+
1338
+ setTableStyle(styles, ondisplay) {
1339
+ if (styles.includes('width')) {
1340
+ const targets = this._figure;
1341
+ if (!targets) return;
1342
+
1343
+ let sizeIcon, text;
1344
+ if (!this._maxWidth) {
1345
+ sizeIcon = this.icons.expansion;
1346
+ text = this.maxText;
1347
+ if (!ondisplay) targets.style.width = 'min-content';
1348
+ } else {
1349
+ sizeIcon = this.icons.reduction;
1350
+ text = this.minText;
1351
+ if (!ondisplay) targets.style.width = '100%';
1352
+ }
1353
+
1354
+ domUtils.changeElement(this.resizeButton.firstElementChild, sizeIcon);
1355
+ domUtils.changeTxt(this.resizeText, text);
1356
+ }
1357
+
1358
+ if (styles.includes('column')) {
1359
+ if (!this._fixedColumn) {
1360
+ domUtils.removeClass(this._element, 'se-table-layout-fixed');
1361
+ domUtils.addClass(this._element, 'se-table-layout-auto');
1362
+ domUtils.removeClass(this.columnFixedButton, 'active');
1363
+ } else {
1364
+ domUtils.removeClass(this._element, 'se-table-layout-auto');
1365
+ domUtils.addClass(this._element, 'se-table-layout-fixed');
1366
+ domUtils.addClass(this.columnFixedButton, 'active');
1367
+ }
1368
+ }
1369
+ },
1370
+
1371
+ setMergeSplitButton(fixedCell, selectedCell) {
1372
+ if (!selectedCell || !selectedCell || fixedCell === selectedCell) {
1373
+ this.splitButton.style.display = 'block';
1374
+ this.mergeButton.style.display = 'none';
1375
+ } else {
1376
+ this.splitButton.style.display = 'none';
1377
+ this.mergeButton.style.display = 'block';
1378
+ }
1379
+ },
1380
+
1381
+ /**
1382
+ * @override fileManager
1383
+ * @param {Element} target Target element
1384
+ */
1385
+ select(target) {
1386
+ this._figureOpen(target);
1387
+
1388
+ const targetWidth = this._figure?.style.width || '100%';
1389
+ this._maxWidth = targetWidth === '100%';
1390
+ this._fixedColumn = domUtils.hasClass(target, 'se-table-layout-fixed') || target.style.tableLayout === 'fixed';
1391
+ this.setTableStyle(this._maxWidth ? 'width|column' : 'width', true);
1392
+
1393
+ if (_DragHandle.get('__overInfo') === ON_OVER_COMPONENT) return;
1394
+
1395
+ if (!this._tdElement) return;
1396
+ this.setCellInfo(this._tdElement, true);
1397
+
1398
+ // controller open
1399
+ const figureEl = domUtils.getParentElement(target, domUtils.isFigure);
1400
+ this.controller_table.open(figureEl, null, { isWWTarget: false, initMethod: null, addOffset: null });
1401
+
1402
+ const addOffset = !this.cellControllerTop ? null : this.controller_table.form.style.display === 'block' ? { left: this.controller_table.form.offsetWidth + 2 } : null;
1403
+ this.controller_cell.open(this._tdElement, this.cellControllerTop ? figureEl : null, { isWWTarget: false, initMethod: null, addOffset: addOffset });
1404
+ },
1405
+
1406
+ setController(tdElement) {
1407
+ if (!this.selection.get().isCollapsed && !this._selectedCell) {
1408
+ this._deleteStyleSelectedCells();
1409
+ return;
1410
+ }
1411
+
1412
+ this._tdElement = tdElement;
1413
+ domUtils.addClass(tdElement, 'se-selected-cell-focus');
1414
+ const tableElement = this._element || this._selectedTable || domUtils.getParentElement(tdElement, 'TABLE');
1415
+ this.component.select(tableElement, Table.key, true);
1416
+ },
1417
+
1418
+ setCellControllerPosition(tdElement, reset) {
1419
+ this.setCellInfo(tdElement, reset);
1420
+ this.controller_cell.resetPosition(this.cellControllerTop ? domUtils.getParentElement(tdElement, domUtils.isTable) : tdElement);
1421
+ },
1422
+
1423
+ _historyPush() {
1424
+ this._deleteStyleSelectedCells();
1425
+ this.history.push(false);
1426
+ this._recallStyleSelectedCells();
1427
+ },
1428
+
1429
+ _figureOpen(target) {
1430
+ this.figure.open(target, { nonResizing: true, nonSizeInfo: true, nonBorder: true, figureTarget: true, __fileManagerInfo: false });
1431
+ },
1432
+
1433
+ _startCellResizing(col, startX, startWidth, isLeftEdge) {
1434
+ this._setResizeLinePosition(this._figure, this._tdElement, this._resizeLinePrev, isLeftEdge);
1435
+ this._resizeLinePrev.style.display = 'block';
1436
+ const prevValue = col.style.width;
1437
+ const nextCol = col.nextElementSibling;
1438
+ const nextColPrevValue = nextCol.style.width;
1439
+ const realWidth = domUtils.hasClass(this._element, 'se-table-layout-fixed') ? nextColPrevValue : converter.getWidthInPercentage(col);
1440
+
1441
+ if (_DragHandle.get('__dragHandler')) _DragHandle.get('__dragHandler').style.display = 'none';
1442
+ this._addResizeGlobalEvents(
1443
+ this._cellResize.bind(
1444
+ this,
1445
+ col,
1446
+ nextCol,
1447
+ this._figure,
1448
+ this._tdElement,
1449
+ this._resizeLine,
1450
+ isLeftEdge,
1451
+ startX,
1452
+ startWidth,
1453
+ numbers.get(prevValue, CELL_DECIMAL_END),
1454
+ numbers.get(realWidth, CELL_DECIMAL_END),
1455
+ this._element.offsetWidth
1456
+ ),
1457
+ () => {
1458
+ this.__removeGlobalEvents();
1459
+ this.history.push(true);
1460
+ // figure reopen
1461
+ this.component.select(this._element, Table.key, true);
1462
+ },
1463
+ (e) => {
1464
+ this._stopResize(col, prevValue, 'width', e);
1465
+ this._stopResize(nextCol, nextColPrevValue, 'width', e);
1466
+ }
1467
+ );
1468
+ },
1469
+
1470
+ _cellResize(col, nextCol, figure, tdEl, resizeLine, isLeftEdge, startX, startWidth, prevWidthPercent, nextColWidthPercent, tableWidth, e) {
1471
+ const deltaX = e.clientX - startX;
1472
+ const newWidthPx = startWidth + deltaX;
1473
+ const newWidthPercent = (newWidthPx / tableWidth) * 100;
1474
+
1475
+ if (newWidthPercent > 0) {
1476
+ col.style.width = `${newWidthPercent}%`;
1477
+ const delta = prevWidthPercent - newWidthPercent;
1478
+ nextCol.style.width = `${nextColWidthPercent + delta}%`;
1479
+ this._setResizeLinePosition(figure, tdEl, resizeLine, isLeftEdge);
1480
+ }
1481
+ },
1482
+
1483
+ _startRowResizing(row, startY, startHeight) {
1484
+ this._setResizeRowPosition(this._figure, row, this._resizeLinePrev);
1485
+ this._resizeLinePrev.style.display = 'block';
1486
+ const prevValue = row.style.height;
1487
+
1488
+ this._addResizeGlobalEvents(
1489
+ this._rowResize.bind(this, row, this._figure, this._resizeLine, startY, startHeight),
1490
+ () => {
1491
+ this.__removeGlobalEvents(this);
1492
+ this.history.push(true);
1493
+ },
1494
+ this._stopResize.bind(this, row, prevValue, 'height')
1495
+ );
1496
+ },
1497
+
1498
+ _rowResize(row, figure, resizeLine, startY, startHeight, e) {
1499
+ const deltaY = e.clientY - startY;
1500
+ const newHeightPx = startHeight + deltaY;
1501
+ row.style.height = `${newHeightPx}px`;
1502
+ this._setResizeRowPosition(figure, row, resizeLine);
1503
+ },
1504
+
1505
+ _startFigureResizing(startX, isLeftEdge) {
1506
+ const figure = this._figure;
1507
+ this._setResizeLinePosition(figure, figure, this._resizeLinePrev, isLeftEdge);
1508
+ this._resizeLinePrev.style.display = 'block';
1509
+ const realWidth = converter.getWidthInPercentage(figure);
1510
+
1511
+ if (_DragHandle.get('__dragHandler')) _DragHandle.get('__dragHandler').style.display = 'none';
1512
+ this._addResizeGlobalEvents(
1513
+ this._figureResize.bind(this, figure, this._resizeLine, isLeftEdge, startX, figure.offsetWidth, numbers.get(realWidth, CELL_DECIMAL_END)),
1514
+ () => {
1515
+ this.__removeGlobalEvents();
1516
+ // figure reopen
1517
+ this.component.select(this._element, Table.key, true);
1518
+ },
1519
+ this._stopResize.bind(this, figure, figure.style.width, 'width')
1520
+ );
1521
+ },
1522
+
1523
+ _figureResize(figure, resizeLine, isLeftEdge, startX, startWidth, constNum, e) {
1524
+ const deltaX = isLeftEdge ? startX - e.clientX : e.clientX - startX;
1525
+ const newWidthPx = startWidth + deltaX;
1526
+ const newWidthPercent = (newWidthPx / startWidth) * constNum;
1527
+
1528
+ if (newWidthPercent > 0) {
1529
+ figure.style.width = `${newWidthPercent}%`;
1530
+ this._setResizeLinePosition(figure, figure, resizeLine, isLeftEdge);
1531
+ }
1532
+ },
1533
+
1534
+ _setResizeLinePosition(figure, target, resizeLine, isLeftEdge) {
1535
+ const tdOffset = this.offset.get(target);
1536
+ const tableOffset = this.offset.get(figure);
1537
+ resizeLine.style.left = `${tdOffset.left + (isLeftEdge ? 0 : target.offsetWidth)}px`;
1538
+ resizeLine.style.top = `${tableOffset.top}px`;
1539
+ resizeLine.style.height = `${figure.offsetHeight}px`;
1540
+ },
1541
+
1542
+ _setResizeRowPosition(figure, target, resizeLine) {
1543
+ const rowOffset = this.offset.get(target);
1544
+ const tableOffset = this.offset.get(figure);
1545
+ resizeLine.style.top = `${rowOffset.top + target.offsetHeight}px`;
1546
+ resizeLine.style.left = `${tableOffset.left}px`;
1547
+ resizeLine.style.width = `${figure.offsetWidth}px`;
1548
+ },
1549
+
1550
+ _stopResize(target, prevValue, styleProp, e) {
1551
+ if (e.keyCode !== 27) return;
1552
+ this.__removeGlobalEvents();
1553
+ target.style[styleProp] = prevValue;
1554
+ // figure reopen
1555
+ if (styleProp === 'width') {
1556
+ this.component.select(this._element, Table.key, true);
1557
+ }
1558
+ },
1559
+
1560
+ _deleteStyleSelectedCells() {
1561
+ domUtils.removeClass([this._fixedCell, this._selectedCell], 'se-selected-cell-focus');
1562
+ if (this._selectedTable) {
1563
+ const selectedCells = this._selectedTable.querySelectorAll('.se-selected-table-cell');
1564
+ for (let i = 0, len = selectedCells.length; i < len; i++) {
1565
+ domUtils.removeClass(selectedCells[i], 'se-selected-table-cell');
1566
+ }
1567
+ }
1568
+ },
1569
+
1570
+ _recallStyleSelectedCells() {
1571
+ if (this._selectedCells) {
1572
+ const selectedCells = this._selectedCells;
1573
+ for (let i = 0, len = selectedCells.length; i < len; i++) {
1574
+ domUtils.addClass(selectedCells[i], 'se-selected-table-cell');
1575
+ }
1576
+ }
1577
+ },
1578
+
1579
+ _addResizeGlobalEvents(resizeFn, stopFn, keyDownFn) {
1580
+ this.__globalEvents.resize = this.eventManager.addGlobalEvent('mousemove', resizeFn, false);
1581
+ this.__globalEvents.resizeStop = this.eventManager.addGlobalEvent('mouseup', stopFn, false);
1582
+ this.__globalEvents.resizeKeyDown = this.eventManager.addGlobalEvent('keydown', keyDownFn, false);
1583
+ this._resizing = true;
1584
+ },
1585
+
1586
+ _toggleEditor(enabled) {
1587
+ const wysiwyg = this.editor.frameContext.get('wysiwyg');
1588
+ wysiwyg.setAttribute('contenteditable', enabled);
1589
+ if (enabled) domUtils.removeClass(wysiwyg, 'se-disabled');
1590
+ else domUtils.addClass(wysiwyg, 'se-disabled');
1591
+ },
1592
+
1593
+ _setCtrlProps(type) {
1594
+ this._typeCache = type;
1595
+ const isTable = type === 'table';
1596
+ const targets = isTable ? [this._element] : this._selectedCells;
1597
+ if (!targets || targets.length === 0) return;
1598
+
1599
+ const { border_format, border_color, border_style, border_width, back_color, font_color, cell_alignment, cell_alignment_vertical, font_bold, font_underline, font_italic, font_strike } = this.propTargets;
1600
+ const { border, backgroundColor, color, textAlign, verticalAlign, fontWeight, textDecoration, fontStyle } = _w.getComputedStyle(targets[0]);
1601
+ const cellBorder = this._getBorderStyle(border);
1602
+
1603
+ cell_alignment.querySelector('[data-value="justify"]').style.display = isTable ? 'none' : '';
1604
+ if (isTable) cell_alignment_vertical.style.display = 'none';
1605
+ else cell_alignment_vertical.style.display = '';
1606
+
1607
+ let b_color = converter.rgb2hex(cellBorder.c),
1608
+ b_style = cellBorder.s,
1609
+ b_width = cellBorder.w,
1610
+ backColor = converter.rgb2hex(backgroundColor),
1611
+ fontColor = converter.rgb2hex(color),
1612
+ bold = /.+/.test(fontWeight),
1613
+ underline = /underline/i.test(textDecoration),
1614
+ strike = /line-through/i.test(textDecoration),
1615
+ italic = /italic/i.test(fontStyle),
1616
+ align = isTable ? this._figure?.style.float : textAlign,
1617
+ align_v = verticalAlign;
1618
+ this._propsCache = [];
1619
+
1620
+ for (let i = 0, t, isBreak; (t = targets[i]); i++) {
1621
+ // eslint-disable-next-line no-shadow
1622
+ const { cssText, border, backgroundColor, color, textAlign, verticalAlign, fontWeight, textDecoration, fontStyle } = t.style;
1623
+ this._propsCache.push([t, cssText]);
1624
+ if (isBreak) continue;
1625
+
1626
+ const { c, s, w } = this._getBorderStyle(border);
1627
+
1628
+ if (b_color && cellBorder.c !== c) b_color = '';
1629
+ if (b_style && cellBorder.s !== s) b_style = '';
1630
+ if (b_width && cellBorder.w !== w) b_width = '';
1631
+ if (backColor !== converter.rgb2hex(backgroundColor)) backColor = '';
1632
+ if (fontColor !== converter.rgb2hex(color)) fontColor = '';
1633
+ if (align !== (isTable ? this._figure?.style.float : textAlign)) align = '';
1634
+ if (align_v && align_v !== verticalAlign) align_v = '';
1635
+ if (bold && bold !== /.+/.test(fontWeight)) bold = '';
1636
+ if (underline && underline !== /underline/i.test(textDecoration)) underline = false;
1637
+ if (strike && strike !== /line-through/i.test(textDecoration)) strike = false;
1638
+ if (italic && italic !== /italic/i.test(fontStyle)) italic = false;
1639
+ if (!b_color || !b_style || !b_width || !backColor || !fontColor) {
1640
+ isBreak = true;
1641
+ }
1642
+ }
1643
+
1644
+ // border - format
1645
+ border_format.firstElementChild.innerHTML = this.icons[BORDER_FORMATS[targets.length === 1 ? 'outside' : 'all']];
1646
+ border_format.setAttribute('se-border-format', 'all');
1647
+ domUtils.removeClass(border_format, 'active');
1648
+
1649
+ // border - styles
1650
+ b_style = b_style || BORDER_LIST[0];
1651
+ border_style.textContent = b_style;
1652
+ border_color.style.borderColor = border_color.value = b_color;
1653
+ border_width.value = b_width;
1654
+ this._disableBorderProps(b_style === BORDER_LIST[0]);
1655
+
1656
+ // back, font color
1657
+ back_color.value = back_color.style.borderColor = backColor;
1658
+ font_color.value = font_color.style.borderColor = fontColor;
1659
+
1660
+ // font style
1661
+ if (bold) domUtils.addClass(font_bold, 'on');
1662
+ if (underline) domUtils.addClass(font_underline, 'on');
1663
+ if (strike) domUtils.addClass(font_strike, 'on');
1664
+ if (italic) domUtils.addClass(font_italic, 'on');
1665
+
1666
+ // align
1667
+ this._setAlignProps(cell_alignment, (this._propsAlignCache = align), true);
1668
+ this._setAlignProps(cell_alignment_vertical, (this._propsVerticalAlignCache = align_v), true);
1669
+ },
1670
+
1671
+ _setAlignProps(el, align, reset) {
1672
+ domUtils.removeClass(el.querySelectorAll('button'), 'on');
1673
+
1674
+ if (!reset && el.getAttribute('se-cell-align') === align) {
1675
+ el.setAttribute('se-cell-align', '');
1676
+ return;
1677
+ }
1678
+
1679
+ domUtils.addClass(el.querySelector(`[data-value="${align}"]`), 'on');
1680
+ el.setAttribute('se-cell-align', align);
1681
+ },
1682
+
1683
+ _disableBorderProps(disabled) {
1684
+ const { border_color, border_width, palette_border_button } = this.propTargets;
1685
+ if (disabled) {
1686
+ border_color.setAttribute('disabled', true);
1687
+ border_width.setAttribute('disabled', true);
1688
+ palette_border_button.setAttribute('disabled', true);
1689
+ border_width.setAttribute('disabled', true);
1690
+ } else {
1691
+ border_color.removeAttribute('disabled');
1692
+ border_width.removeAttribute('disabled');
1693
+ palette_border_button.removeAttribute('disabled');
1694
+ border_width.removeAttribute('disabled');
1695
+ }
1696
+ },
1697
+
1698
+ _getBorderStyle(borderStyle) {
1699
+ const parts = borderStyle.split(/\s(?![^()]*\))/);
1700
+ let w = '',
1701
+ s = '',
1702
+ c = '';
1703
+
1704
+ if (parts.length === 3) {
1705
+ w = parts[0];
1706
+ s = parts[1];
1707
+ c = parts[2];
1708
+ } else if (parts.length === 2) {
1709
+ if (/\d/.test(parts[0])) {
1710
+ w = parts[0];
1711
+ s = parts[1];
1712
+ } else {
1713
+ s = parts[0];
1714
+ c = parts[1];
1715
+ }
1716
+ } else if (parts.length === 1) {
1717
+ if (/\d/.test(parts[0])) {
1718
+ w = parts[0];
1719
+ } else {
1720
+ s = parts[0];
1721
+ }
1722
+ }
1723
+
1724
+ return { w, s, c: converter.rgb2hex(c) };
1725
+ },
1726
+
1727
+ _submitProps(target) {
1728
+ try {
1729
+ target.setAttribute('disabled', true);
1730
+
1731
+ const isTable = this.controller_table.form.contains(this.controller_props.currentTarget);
1732
+ const targets = isTable ? [this._element] : this._selectedCells;
1733
+ const tr = targets[0];
1734
+ const trStyles = _w.getComputedStyle(tr);
1735
+ const { border_format, border_color, border_style, border_width, back_color, font_color, cell_alignment, cell_alignment_vertical } = this.propTargets;
1736
+
1737
+ const borderFormat = border_format.getAttribute('se-border-format') || '';
1738
+ const hasFormat = borderFormat !== 'all';
1739
+ const borderStyle = (border_style.textContent === 'none' ? '' : border_style.textContent) || '';
1740
+ const isNoneFormat = borderFormat === 'none' || !borderStyle;
1741
+
1742
+ const cellAlignment = cell_alignment.getAttribute('se-cell-align') || '';
1743
+ const cellAlignmentVertical = cell_alignment_vertical.getAttribute('se-cell-align') || '';
1744
+ const borderColor = isNoneFormat ? '' : border_color.value.trim() || trStyles.borderColor;
1745
+ let borderWidth = isNoneFormat ? '' : border_width.value.trim() || trStyles.borderWidth;
1746
+ borderWidth = borderWidth + (numbers.is(borderWidth) ? DEFAULT_BORDER_UNIT : '');
1747
+ const backColor = back_color.value.trim();
1748
+ const fontColor = font_color.value.trim();
1749
+ const hasBorder = hasFormat && !isNoneFormat && borderWidth;
1750
+ const borderCss = `${borderWidth} ${borderStyle} ${borderColor}`;
1751
+ const cells = {
1752
+ left: [],
1753
+ top: [],
1754
+ right: [],
1755
+ bottom: [],
1756
+ middle: []
1757
+ };
1758
+
1759
+ if (!isTable) {
1760
+ // --- target cells roof
1761
+ let { rs, re, cs, ce } = this._ref || {
1762
+ rs: tr.parentElement.rowIndex || 0,
1763
+ re: tr.parentElement.rowIndex || 0,
1764
+ cs: tr.cellIndex || 0,
1765
+ ce: tr.cellIndex || 0
1766
+ };
1767
+ const mergeInfo = new Array(re - rs + 1).fill(0).map(() => new Array(ce - cs + 1).fill(0));
1768
+ const cellStartIndex = cs;
1769
+ re -= rs;
1770
+ rs -= rs;
1771
+ ce -= cs;
1772
+ cs -= cs;
1773
+ let prevRow = tr.parentNode;
1774
+ for (let i = 0, cellCnt = 0, len = targets.length, e, es, rowIndex = 0, cellIndex, colspan, rowspan; i < len; i++, cellCnt++) {
1775
+ e = targets[i];
1776
+ colspan = e.colSpan;
1777
+ rowspan = e.rowSpan;
1778
+ cellIndex = e.cellIndex - cellStartIndex;
1779
+
1780
+ if (prevRow !== e.parentNode) {
1781
+ rowIndex++;
1782
+ cellCnt = 0;
1783
+ prevRow = e.parentNode;
1784
+ }
1785
+
1786
+ let c = 0;
1787
+ while (c <= cellIndex) {
1788
+ cellIndex += mergeInfo[rowIndex][c] || 0;
1789
+ c++;
1790
+ }
1791
+
1792
+ try {
1793
+ if (rowspan > 1) {
1794
+ const rowspanNum = rowspan - 1;
1795
+ for (let r = rowIndex; r <= rowIndex + rowspanNum; r++) {
1796
+ mergeInfo[r][cellIndex] += colspan - (rowIndex === r ? 1 : 0);
1797
+ }
1798
+ } else if (colspan > 1) {
1799
+ mergeInfo[rowIndex][cellIndex] += colspan - 1;
1800
+ }
1801
+ } catch (err) {
1802
+ // ignore error
1803
+ }
1804
+
1805
+ const isBottom = rowIndex + rowspan - 1 === re;
1806
+ if (rowIndex === rs) cells.top.push(e);
1807
+ if (rowIndex === re || isBottom) cells.bottom.push(e);
1808
+ if (cellIndex === cs) cells.left.push(e);
1809
+ if (cellIndex === ce || cellIndex + colspan - 1 === ce) cells.right.push(e);
1810
+ if (!isBottom && rowIndex !== rs && rowIndex !== re && cellIndex !== cs && cellIndex !== ce) cells.middle.push(e);
1811
+
1812
+ // --- set styles
1813
+ es = e.style;
1814
+ // alignment
1815
+ es.textAlign = cellAlignment;
1816
+ es.verticalAlign = cellAlignmentVertical;
1817
+ // back
1818
+ es.backgroundColor = backColor;
1819
+ // font
1820
+ es.color = fontColor;
1821
+ // font style
1822
+ this._setFontStyle(es);
1823
+ // border
1824
+ if (hasBorder) continue;
1825
+ // border - all || none
1826
+ if (isNoneFormat) {
1827
+ es.border = es.borderLeft = es.borderTop = es.borderRight = es.borderBottom = '';
1828
+ } else {
1829
+ es.border = borderCss;
1830
+ }
1831
+ }
1832
+
1833
+ if (cells.middle.length === 0) {
1834
+ cells.middle = targets;
1835
+ }
1836
+ } else {
1837
+ // -- table styles
1838
+ const es = tr.style;
1839
+ // alignment
1840
+ if (this._figure) {
1841
+ this._figure.style.float = cellAlignment;
1842
+ this._figure.style.verticalAlign = cellAlignmentVertical;
1843
+ }
1844
+ // back
1845
+ es.backgroundColor = backColor;
1846
+ // font
1847
+ es.color = fontColor;
1848
+ // font style
1849
+ this._setFontStyle(es);
1850
+ // border
1851
+ if (!hasBorder) {
1852
+ // border - all || none
1853
+ if (isNoneFormat) {
1854
+ es.border = es.borderLeft = es.borderTop = es.borderRight = es.borderBottom = '';
1855
+ } else {
1856
+ es.border = borderCss;
1857
+ }
1858
+ }
1859
+
1860
+ cells.left = cells.top = cells.right = cells.bottom = targets;
1861
+ }
1862
+
1863
+ cells.all = targets;
1864
+
1865
+ // border format
1866
+ if (hasBorder) {
1867
+ this._setBorderStyles(cells, borderFormat, borderCss);
1868
+ }
1869
+
1870
+ this._historyPush();
1871
+
1872
+ // set cells style
1873
+ this.controller_props.close();
1874
+ if (this._tdElement) {
1875
+ this._recallStyleSelectedCells();
1876
+ this.setCellInfo(this._tdElement, true);
1877
+ domUtils.addClass(this._tdElement, 'se-selected-cell-focus');
1878
+ }
1879
+ } catch (err) {
1880
+ console.warn('[SUNEDITOR.plugins.table.setProps.error]', err);
1881
+ } finally {
1882
+ target.removeAttribute('disabled');
1883
+ }
1884
+ },
1885
+
1886
+ _setFontStyle(styles) {
1887
+ const { font_bold, font_italic, font_strike, font_underline } = this.propTargets;
1888
+ styles.fontWeight = domUtils.hasClass(font_bold, 'on') ? 'bold' : '';
1889
+ styles.fontStyle = domUtils.hasClass(font_italic, 'on') ? 'italic' : '';
1890
+ styles.textDecoration = ((domUtils.hasClass(font_strike, 'on') ? 'line-through ' : '') + (domUtils.hasClass(font_underline, 'on') ? 'underline' : '')).trim();
1891
+ },
1892
+
1893
+ /**
1894
+ * @private
1895
+ * @description Set border format
1896
+ * @param {Element[]} cells Target elements
1897
+ * @param {"all"|"inside"|"horizon"|"vertical"|"outside"|"left"|"top"|"right"|"bottom"} borderKey Border style
1898
+ * @param {number} s Border style
1899
+ * @param {boolean} isTable table selected
1900
+ */
1901
+ _setBorderStyles(cells, borderKey, s) {
1902
+ const { left, top, right, bottom, all } = cells;
1903
+ switch (borderKey) {
1904
+ case 'inside':
1905
+ if (cells.length === 1) return;
1906
+ domUtils.setStyle(
1907
+ all.filter((c) => !bottom.includes(c)),
1908
+ BORDER_NS.b,
1909
+ s
1910
+ );
1911
+ domUtils.setStyle(
1912
+ all.filter((c) => !right.includes(c)),
1913
+ BORDER_NS.r,
1914
+ s
1915
+ );
1916
+ break;
1917
+ case 'horizon':
1918
+ if (cells.length === 1) return;
1919
+ domUtils.setStyle(
1920
+ all.filter((c) => !bottom.includes(c)),
1921
+ BORDER_NS.b,
1922
+ s
1923
+ );
1924
+ break;
1925
+ case 'vertical':
1926
+ if (cells.length === 1) return;
1927
+ domUtils.setStyle(
1928
+ all.filter((c) => !right.includes(c)),
1929
+ BORDER_NS.r,
1930
+ s
1931
+ );
1932
+ break;
1933
+ case 'outside':
1934
+ domUtils.setStyle(left, BORDER_NS.l, s);
1935
+ domUtils.setStyle(top, BORDER_NS.t, s);
1936
+ domUtils.setStyle(right, BORDER_NS.r, s);
1937
+ domUtils.setStyle(bottom, BORDER_NS.b, s);
1938
+ break;
1939
+ case 'left':
1940
+ domUtils.setStyle(left, BORDER_NS.l, s);
1941
+ break;
1942
+ case 'top':
1943
+ domUtils.setStyle(top, BORDER_NS.t, s);
1944
+ break;
1945
+ case 'right':
1946
+ domUtils.setStyle(right, BORDER_NS.r, s);
1947
+ break;
1948
+ case 'bottom':
1949
+ domUtils.setStyle(bottom, BORDER_NS.b, s);
1950
+ break;
1951
+ }
1952
+ },
1953
+
1954
+ _setMultiCells(startCell, endCell) {
1955
+ const rows = this._selectedTable.rows;
1956
+ this._deleteStyleSelectedCells();
1957
+
1958
+ if (startCell === endCell) {
1959
+ if (!this._shift) return;
1960
+ } else {
1961
+ domUtils.addClass(startCell, 'se-selected-table-cell');
1962
+ }
1963
+
1964
+ let findSelectedCell = true;
1965
+ let spanIndex = [];
1966
+ let rowSpanArr = [];
1967
+ const ref = (this._ref = { _i: 0, cs: null, ce: null, rs: null, re: null });
1968
+
1969
+ for (let i = 0, len = rows.length, cells, colSpan; i < len; i++) {
1970
+ cells = rows[i].cells;
1971
+ colSpan = 0;
1972
+
1973
+ for (let c = 0, cLen = cells.length, cell, logcalIndex, cs, rs; c < cLen; c++) {
1974
+ cell = cells[c];
1975
+ cs = cell.colSpan - 1;
1976
+ rs = cell.rowSpan - 1;
1977
+ logcalIndex = c + colSpan;
1978
+
1979
+ if (spanIndex.length > 0) {
1980
+ for (let r = 0, arr; r < spanIndex.length; r++) {
1981
+ arr = spanIndex[r];
1982
+ if (arr.row > i) continue;
1983
+ if (logcalIndex >= arr.index) {
1984
+ colSpan += arr.cs;
1985
+ logcalIndex += arr.cs;
1986
+ arr.rs -= 1;
1987
+ arr.row = i + 1;
1988
+ if (arr.rs < 1) {
1989
+ spanIndex.splice(r, 1);
1990
+ r--;
1991
+ }
1992
+ } else if (c === cLen - 1) {
1993
+ arr.rs -= 1;
1994
+ arr.row = i + 1;
1995
+ if (arr.rs < 1) {
1996
+ spanIndex.splice(r, 1);
1997
+ r--;
1998
+ }
1999
+ }
2000
+ }
2001
+ }
2002
+
2003
+ if (findSelectedCell) {
2004
+ if (cell === startCell || cell === endCell) {
2005
+ ref.cs = ref.cs !== null && ref.cs < logcalIndex ? ref.cs : logcalIndex;
2006
+ ref.ce = ref.ce !== null && ref.ce > logcalIndex + cs ? ref.ce : logcalIndex + cs;
2007
+ ref.rs = ref.rs !== null && ref.rs < i ? ref.rs : i;
2008
+ ref.re = ref.re !== null && ref.re > i + rs ? ref.re : i + rs;
2009
+ ref._i += 1;
2010
+ }
2011
+
2012
+ if (ref._i === 2) {
2013
+ findSelectedCell = false;
2014
+ spanIndex = [];
2015
+ rowSpanArr = [];
2016
+ i = -1;
2017
+ break;
2018
+ }
2019
+ } else if (numbers.getOverlapRangeAtIndex(ref.cs, ref.ce, logcalIndex, logcalIndex + cs) && numbers.getOverlapRangeAtIndex(ref.rs, ref.re, i, i + rs)) {
2020
+ const newCs = ref.cs < logcalIndex ? ref.cs : logcalIndex;
2021
+ const newCe = ref.ce > logcalIndex + cs ? ref.ce : logcalIndex + cs;
2022
+ const newRs = ref.rs < i ? ref.rs : i;
2023
+ const newRe = ref.re > i + rs ? ref.re : i + rs;
2024
+
2025
+ if (ref.cs !== newCs || ref.ce !== newCe || ref.rs !== newRs || ref.re !== newRe) {
2026
+ ref.cs = newCs;
2027
+ ref.ce = newCe;
2028
+ ref.rs = newRs;
2029
+ ref.re = newRe;
2030
+ i = -1;
2031
+
2032
+ spanIndex = [];
2033
+ rowSpanArr = [];
2034
+ break;
2035
+ }
2036
+
2037
+ domUtils.addClass(cell, 'se-selected-table-cell');
2038
+ }
2039
+
2040
+ if (rs > 0) {
2041
+ rowSpanArr.push({
2042
+ index: logcalIndex,
2043
+ cs: cs + 1,
2044
+ rs: rs,
2045
+ row: -1
2046
+ });
2047
+ }
2048
+
2049
+ colSpan += cell.colSpan - 1;
2050
+ }
2051
+
2052
+ spanIndex = spanIndex.concat(rowSpanArr).sort((a, b) => {
2053
+ return a.index - b.index;
2054
+ });
2055
+ rowSpanArr = [];
2056
+ }
2057
+ },
2058
+
2059
+ _resetTablePicker() {
2060
+ if (!this.tableHighlight) return;
2061
+
2062
+ const highlight = this.tableHighlight.style;
2063
+ const unHighlight = this.tableUnHighlight.style;
2064
+
2065
+ highlight.width = '1em';
2066
+ highlight.height = '1em';
2067
+ unHighlight.width = '10em';
2068
+ unHighlight.height = '10em';
2069
+
2070
+ domUtils.changeTxt(this.tableDisplay, '1 x 1');
2071
+ this.menu.dropdownOff();
2072
+ },
2073
+
2074
+ _resetPropsAlign() {
2075
+ const { cell_alignment } = this.propTargets;
2076
+ const left = cell_alignment.querySelector('[data-value="left"]');
2077
+ const right = cell_alignment.querySelector('[data-value="right"]');
2078
+ const l_parent = left.parentElement;
2079
+ const r_parent = right.parentElement;
2080
+ l_parent.appendChild(right);
2081
+ r_parent.appendChild(left);
2082
+ },
2083
+
2084
+ _onColorPalette(button, type, color) {
2085
+ if (this.controller_colorPicker.isOpen && type === this.sliderType) {
2086
+ this.controller_colorPicker.close();
2087
+ } else {
2088
+ this.sliderType = type;
2089
+ domUtils.addClass(button, 'on');
2090
+ this.colorPicker.init(color?.value || '', button);
2091
+ this.controller_colorPicker.open(button, null, { isWWTarget: false, initMethod: null, addOffset: null });
2092
+ }
2093
+ },
2094
+
2095
+ _closeController() {
2096
+ this.component.deselect();
2097
+ this.controller_table.close();
2098
+ this.controller_cell.close();
2099
+ },
2100
+
2101
+ __hideResizeLine() {
2102
+ if (this._resizeLine) {
2103
+ this._resizeLine.style.display = 'none';
2104
+ this._resizeLine = null;
2105
+ }
2106
+ },
2107
+
2108
+ __removeGlobalEvents() {
2109
+ this._resizing = false;
2110
+ this.editor.disableBackWrapper();
2111
+ this.__hideResizeLine();
2112
+ if (this._resizeLinePrev) {
2113
+ this._resizeLinePrev.style.display = 'none';
2114
+ this._resizeLinePrev = null;
2115
+ }
2116
+ const globalEvents = this.__globalEvents;
2117
+ for (const k in globalEvents) {
2118
+ if (globalEvents[k]) globalEvents[k] = this.eventManager.removeGlobalEvent(globalEvents[k]);
2119
+ }
2120
+ },
2121
+
2122
+ constructor: Table
2123
+ };
2124
+
2125
+ function IsResizeEls(node) {
2126
+ return /^(TD|TH|TR)$/i.test(node?.nodeName);
2127
+ }
2128
+
2129
+ function CheckCellEdge(event, tableCell) {
2130
+ const startX = event.clientX;
2131
+ const startWidth = numbers.get(_w.getComputedStyle(tableCell).width, CELL_DECIMAL_END);
2132
+ const rect = tableCell.getBoundingClientRect();
2133
+ const offsetX = Math.round(startX - rect.left);
2134
+ const isLeft = offsetX <= CELL_SELECT_MARGIN;
2135
+ const is = isLeft || startWidth - offsetX <= CELL_SELECT_MARGIN;
2136
+
2137
+ return {
2138
+ is,
2139
+ isLeft,
2140
+ startX
2141
+ };
2142
+ }
2143
+
2144
+ function CheckRowEdge(event, tableCell) {
2145
+ const startY = event.clientY;
2146
+ const startHeight = numbers.get(_w.getComputedStyle(tableCell).height, CELL_DECIMAL_END);
2147
+ const rect = tableCell.getBoundingClientRect();
2148
+ const is = Math.ceil(startHeight + rect.top - startY) <= ROW_SELECT_MARGIN;
2149
+
2150
+ return {
2151
+ is,
2152
+ startY
2153
+ };
2154
+ }
2155
+
2156
+ function OnSplitCells(direction) {
2157
+ const vertical = direction === 'vertical';
2158
+ const currentCell = this._tdElement;
2159
+ const rows = this._trElements;
2160
+ const currentRow = this._trElement;
2161
+ const index = this._logical_cellIndex;
2162
+ const rowIndex = this._rowIndex;
2163
+ const newCell = CreateCells(currentCell.nodeName, 0, true);
2164
+
2165
+ // vertical
2166
+ if (vertical) {
2167
+ const currentColSpan = currentCell.colSpan;
2168
+ newCell.rowSpan = currentCell.rowSpan;
2169
+
2170
+ // colspan > 1
2171
+ if (currentColSpan > 1) {
2172
+ newCell.colSpan = Math.floor(currentColSpan / 2);
2173
+ currentCell.colSpan = currentColSpan - newCell.colSpan;
2174
+ currentRow.insertBefore(newCell, currentCell.nextElementSibling);
2175
+ } else {
2176
+ // colspan - 1
2177
+ let rowSpanArr = [];
2178
+ let spanIndex = [];
2179
+
2180
+ for (let i = 0, len = this._rowCnt, cells, colSpan; i < len; i++) {
2181
+ cells = rows[i].cells;
2182
+ colSpan = 0;
2183
+ for (let c = 0, cLen = cells.length, cell, cs, rs, logcalIndex; c < cLen; c++) {
2184
+ cell = cells[c];
2185
+ cs = cell.colSpan - 1;
2186
+ rs = cell.rowSpan - 1;
2187
+ logcalIndex = c + colSpan;
2188
+
2189
+ if (spanIndex.length > 0) {
2190
+ for (let r = 0, arr; r < spanIndex.length; r++) {
2191
+ arr = spanIndex[r];
2192
+ if (arr.row > i) continue;
2193
+ if (logcalIndex >= arr.index) {
2194
+ colSpan += arr.cs;
2195
+ logcalIndex += arr.cs;
2196
+ arr.rs -= 1;
2197
+ arr.row = i + 1;
2198
+ if (arr.rs < 1) {
2199
+ spanIndex.splice(r, 1);
2200
+ r--;
2201
+ }
2202
+ } else if (c === cLen - 1) {
2203
+ arr.rs -= 1;
2204
+ arr.row = i + 1;
2205
+ if (arr.rs < 1) {
2206
+ spanIndex.splice(r, 1);
2207
+ r--;
2208
+ }
2209
+ }
2210
+ }
2211
+ }
2212
+
2213
+ if (logcalIndex <= index && rs > 0) {
2214
+ rowSpanArr.push({
2215
+ index: logcalIndex,
2216
+ cs: cs + 1,
2217
+ rs: rs,
2218
+ row: -1
2219
+ });
2220
+ }
2221
+
2222
+ if (cell !== currentCell && logcalIndex <= index && logcalIndex + cs >= index + currentColSpan - 1) {
2223
+ cell.colSpan += 1;
2224
+ break;
2225
+ }
2226
+
2227
+ if (logcalIndex > index) break;
2228
+
2229
+ colSpan += cs;
2230
+ }
2231
+
2232
+ spanIndex = spanIndex.concat(rowSpanArr).sort(function (a, b) {
2233
+ return a.index - b.index;
2234
+ });
2235
+ rowSpanArr = [];
2236
+ }
2237
+
2238
+ currentRow.insertBefore(newCell, currentCell.nextElementSibling);
2239
+ }
2240
+ } else {
2241
+ // horizontal
2242
+ const currentRowSpan = currentCell.rowSpan;
2243
+ newCell.colSpan = currentCell.colSpan;
2244
+
2245
+ // rowspan > 1
2246
+ if (currentRowSpan > 1) {
2247
+ newCell.rowSpan = Math.floor(currentRowSpan / 2);
2248
+ const newRowSpan = currentRowSpan - newCell.rowSpan;
2249
+
2250
+ const rowSpanArr = [];
2251
+ const nextRowIndex = domUtils.getArrayIndex(rows, currentRow) + newRowSpan;
2252
+
2253
+ for (let i = 0, cells, colSpan; i < nextRowIndex; i++) {
2254
+ cells = rows[i].cells;
2255
+ colSpan = 0;
2256
+ for (let c = 0, cLen = cells.length, cell, cs, logcalIndex; c < cLen; c++) {
2257
+ logcalIndex = c + colSpan;
2258
+ if (logcalIndex >= index) break;
2259
+
2260
+ cell = cells[c];
2261
+ cs = cell.rowSpan - 1;
2262
+ if (cs > 0 && cs + i >= nextRowIndex && logcalIndex < index) {
2263
+ rowSpanArr.push({
2264
+ index: logcalIndex,
2265
+ cs: cell.colSpan
2266
+ });
2267
+ }
2268
+ colSpan += cell.colSpan - 1;
2269
+ }
2270
+ }
2271
+
2272
+ const nextRow = rows[nextRowIndex];
2273
+ const nextCells = nextRow.cells;
2274
+ let rs = rowSpanArr.shift();
2275
+
2276
+ for (let c = 0, cLen = nextCells.length, colSpan = 0, cell, cs, logcalIndex, insertIndex; c < cLen; c++) {
2277
+ logcalIndex = c + colSpan;
2278
+ cell = nextCells[c];
2279
+ cs = cell.colSpan - 1;
2280
+ insertIndex = logcalIndex + cs + 1;
2281
+
2282
+ if (rs && insertIndex >= rs.index) {
2283
+ colSpan += rs.cs;
2284
+ insertIndex += rs.cs;
2285
+ rs = rowSpanArr.shift();
2286
+ }
2287
+
2288
+ if (insertIndex >= index || c === cLen - 1) {
2289
+ nextRow.insertBefore(newCell, cell.nextElementSibling);
2290
+ break;
2291
+ }
2292
+
2293
+ colSpan += cs;
2294
+ }
2295
+
2296
+ currentCell.rowSpan = newRowSpan;
2297
+ } else {
2298
+ // rowspan - 1
2299
+ newCell.rowSpan = currentCell.rowSpan;
2300
+ const newRow = domUtils.createElement('TR');
2301
+ newRow.appendChild(newCell);
2302
+
2303
+ for (let i = 0, cells; i < rowIndex; i++) {
2304
+ cells = rows[i].cells;
2305
+ if (cells.length === 0) return;
2306
+
2307
+ for (let c = 0, cLen = cells.length; c < cLen; c++) {
2308
+ if (i + cells[c].rowSpan - 1 >= rowIndex) {
2309
+ cells[c].rowSpan += 1;
2310
+ }
2311
+ }
2312
+ }
2313
+
2314
+ const physicalIndex = this._physical_cellIndex;
2315
+ const cells = currentRow.cells;
2316
+
2317
+ for (let c = 0, cLen = cells.length; c < cLen; c++) {
2318
+ if (c === physicalIndex) continue;
2319
+ cells[c].rowSpan += 1;
2320
+ }
2321
+
2322
+ currentRow.parentNode.insertBefore(newRow, currentRow.nextElementSibling);
2323
+ }
2324
+ }
2325
+
2326
+ this.selectMenu_split.close();
2327
+ this.editor.focusEdge(currentCell);
2328
+
2329
+ this._deleteStyleSelectedCells();
2330
+ this.history.push(false);
2331
+
2332
+ this.setController(currentCell);
2333
+ this._selectedCell = this._fixedCell = currentCell;
2334
+ }
2335
+
2336
+ function OnColumnEdit(command) {
2337
+ switch (command) {
2338
+ case 'insert-left':
2339
+ this.editTable('cell', 'left');
2340
+ break;
2341
+ case 'insert-right':
2342
+ this.editTable('cell', 'right');
2343
+ break;
2344
+ case 'delete':
2345
+ this.editTable('cell', null);
2346
+ }
2347
+
2348
+ this._historyPush();
2349
+ }
2350
+
2351
+ function OnRowEdit(command) {
2352
+ switch (command) {
2353
+ case 'insert-above':
2354
+ this.editTable('row', 'up');
2355
+ break;
2356
+ case 'insert-below':
2357
+ this.editTable('row', 'down');
2358
+ break;
2359
+ case 'delete':
2360
+ this.editTable('row', null);
2361
+ }
2362
+
2363
+ this._historyPush();
2364
+ }
2365
+
2366
+ function OnMouseMoveTablePicker(e) {
2367
+ e.stopPropagation();
2368
+
2369
+ let x = Math.ceil(e.offsetX / 18);
2370
+ let y = Math.ceil(e.offsetY / 18);
2371
+ x = x < 1 ? 1 : x;
2372
+ y = y < 1 ? 1 : y;
2373
+
2374
+ if (this.options.get('_rtl')) {
2375
+ this.tableHighlight.style.left = x * 18 - 13 + 'px';
2376
+ x = 11 - x;
2377
+ }
2378
+
2379
+ this.tableHighlight.style.width = x + 'em';
2380
+ this.tableHighlight.style.height = y + 'em';
2381
+
2382
+ const x_u = x < 5 ? 5 : x > 8 ? 10 : x + 2;
2383
+ const y_u = y < 5 ? 5 : y > 8 ? 10 : y + 2;
2384
+ this.tableUnHighlight.style.width = x_u + 'em';
2385
+ this.tableUnHighlight.style.height = y_u + 'em';
2386
+
2387
+ domUtils.changeTxt(this.tableDisplay, x + ' x ' + y);
2388
+ this._tableXY = [x, y];
2389
+ }
2390
+
2391
+ function OnClickTablePicker() {
2392
+ this.action();
2393
+ }
2394
+
2395
+ function CreateCells(nodeName, cnt, returnElement) {
2396
+ nodeName = nodeName.toLowerCase();
2397
+
2398
+ if (!returnElement) {
2399
+ return `<${nodeName}><div><br></div></${nodeName}>`.repeat(cnt);
2400
+ } else {
2401
+ return domUtils.createElement(nodeName, null, '<div><br></div>');
2402
+ }
2403
+ }
2404
+
2405
+ function OnCellMultiSelect(e) {
2406
+ this.editor._antiBlur = true;
2407
+ const target = domUtils.getParentElement(e.target, domUtils.isTableCell);
2408
+
2409
+ if (this._shift) {
2410
+ if (target === this._fixedCell) {
2411
+ this._shift = false;
2412
+ this._deleteStyleSelectedCells();
2413
+ this._toggleEditor(true);
2414
+ this.__removeGlobalEvents();
2415
+ return;
2416
+ } else {
2417
+ this._toggleEditor(false);
2418
+ }
2419
+ } else if (!this._ref) {
2420
+ if (target === this._fixedCell) return;
2421
+ else this._toggleEditor(false);
2422
+ }
2423
+
2424
+ if (!target || target === this._selectedCell || this._fixedCellName !== target.nodeName || this._selectedTable !== domUtils.getParentElement(target, 'TABLE')) {
2425
+ return;
2426
+ }
2427
+
2428
+ this._selectedCell = target;
2429
+ this._setMultiCells(this._fixedCell, target);
2430
+ }
2431
+
2432
+ function OffCellMultiSelect(e) {
2433
+ e.stopPropagation();
2434
+
2435
+ if (!this._shift) {
2436
+ this.__removeGlobalEvents();
2437
+ this._toggleEditor(true);
2438
+ } else if (this.__globalEvents.touchOff) {
2439
+ this.__globalEvents.touchOff = this.eventManager.removeGlobalEvent(this.__globalEvents.touchOff);
2440
+ }
2441
+
2442
+ if (!this._fixedCell || !this._selectedTable) return;
2443
+
2444
+ this.setMergeSplitButton(this._fixedCell, this._selectedCell);
2445
+ this._selectedCells = Array.from(this._selectedTable.querySelectorAll('.se-selected-table-cell'));
2446
+
2447
+ const focusCell = this._selectedCells?.length > 0 ? this._selectedCell : this._fixedCell;
2448
+ this.setController(focusCell);
2449
+ }
2450
+
2451
+ function OffCellShift() {
2452
+ if (!this._ref) this._closeController();
2453
+ }
2454
+
2455
+ function OffCellTouch() {
2456
+ this.close();
2457
+ }
2458
+
2459
+ function GetMaxColumns(table) {
2460
+ let maxColumns = 0;
2461
+
2462
+ for (const row of table.rows) {
2463
+ let columnCount = 0;
2464
+ for (const cell of row.cells) {
2465
+ columnCount += cell.colSpan;
2466
+ }
2467
+ maxColumns = Math.max(maxColumns, columnCount);
2468
+ }
2469
+
2470
+ return maxColumns;
2471
+ }
2472
+
2473
+ function OnPropsBorderEdit(command) {
2474
+ this.propTargets.border_style.textContent = command;
2475
+ this._disableBorderProps(command === BORDER_LIST[0]);
2476
+ this.selectMenu_props_border.close();
2477
+ }
2478
+
2479
+ function OnPropsBorderFormatEdit(defaultCommand, command) {
2480
+ const { border_format } = this.propTargets;
2481
+
2482
+ border_format.setAttribute('se-border-format', command);
2483
+ border_format.firstElementChild.innerHTML = this.icons[BORDER_FORMATS[command]];
2484
+ if (command !== defaultCommand) domUtils.addClass(border_format, 'active');
2485
+ else domUtils.removeClass(border_format, 'active');
2486
+
2487
+ this.selectMenu_props_border_format.close();
2488
+ this.selectMenu_props_border_format_oneCell.close();
2489
+ }
2490
+
2491
+ // init element
2492
+ function CreateSplitMenu(lang) {
2493
+ const menus = domUtils.createElement(
2494
+ 'DIV',
2495
+ null,
2496
+ /*html*/ `
2497
+ <div title="${lang.verticalSplit}" aria-label="${lang.verticalSplit}">
2498
+ ${lang.verticalSplit}
2499
+ </div>
2500
+ <div title="${lang.horizontalSplit}" aria-label="${lang.horizontalSplit}">
2501
+ ${lang.horizontalSplit}
2502
+ </div>`
2503
+ );
2504
+
2505
+ return { items: ['vertical', 'horizontal'], menus: menus.querySelectorAll('div') };
2506
+ }
2507
+
2508
+ function CreateColumnMenu(lang, icons) {
2509
+ const menus = domUtils.createElement(
2510
+ 'DIV',
2511
+ null,
2512
+ /*html*/ `
2513
+ <div title="${lang.insertColumnBefore}" aria-label="${lang.insertColumnBefore}">
2514
+ <span class="se-list-icon">${icons.insert_column_left}</span><span class="se-txt">${lang.insertColumnBefore}</span>
2515
+ </div>
2516
+ <div title="${lang.insertColumnAfter}" aria-label="${lang.insertColumnAfter}">
2517
+ <span class="se-list-icon">${icons.insert_column_right}</span><span class="se-txt">${lang.insertColumnAfter}</span>
2518
+ </div>
2519
+ <div title="${lang.deleteColumn}" aria-label="${lang.deleteColumn}">
2520
+ <span class="se-list-icon">${icons.delete_column}</span><span class="se-txt">${lang.deleteColumn}</span>
2521
+ </div>`
2522
+ );
2523
+
2524
+ return { items: ['insert-left', 'insert-right', 'delete'], menus: menus.querySelectorAll('div') };
2525
+ }
2526
+
2527
+ function CreateRowMenu(lang, icons) {
2528
+ const menus = domUtils.createElement(
2529
+ 'DIV',
2530
+ null,
2531
+ /*html*/ `
2532
+ <div title="${lang.insertRowAbove}" aria-label="${lang.insertRowAbove}">
2533
+ <span class="se-list-icon">${icons.insert_row_above}</span><span class="se-txt">${lang.insertRowAbove}</span>
2534
+ </div>
2535
+ <div title="${lang.insertRowBelow}" aria-label="${lang.insertRowBelow}">
2536
+ <span class="se-list-icon">${icons.insert_row_below}</span><span class="se-txt">${lang.insertRowBelow}</span>
2537
+ </div>
2538
+ <div title="${lang.deleteRow}" aria-label="${lang.deleteRow}">
2539
+ <span class="se-list-icon">${icons.delete_row}</span><span class="se-txt">${lang.deleteRow}</span>
2540
+ </div>`
2541
+ );
2542
+
2543
+ return { items: ['insert-above', 'insert-below', 'delete'], menus: menus.querySelectorAll('div') };
2544
+ }
2545
+
2546
+ function CreateBorderMenu() {
2547
+ let html = '';
2548
+
2549
+ for (let i = 0, len = BORDER_LIST.length, s; i < len; i++) {
2550
+ s = BORDER_LIST[i];
2551
+ html += /*html*/ `
2552
+ <div title="${s}" aria-label="${s}" style="padding: 0 12px;">
2553
+ <span class="se-txt">${s}</span>
2554
+ </div>`;
2555
+ }
2556
+
2557
+ const menus = domUtils.createElement('DIV', null, html);
2558
+ return { items: BORDER_LIST, menus: menus.querySelectorAll('div') };
2559
+ }
2560
+
2561
+ function CreateBorderFormatMenu(langs, icons, indideFormats) {
2562
+ const items = [];
2563
+ let html = '';
2564
+
2565
+ for (const k in BORDER_FORMATS) {
2566
+ if (indideFormats.includes(k)) continue;
2567
+ const s = BORDER_FORMATS[k];
2568
+ items.push(k);
2569
+ html += /*html*/ `
2570
+ <button type="button" class="se-btn se-tooltip">
2571
+ ${icons[s]}
2572
+ <span class="se-tooltip-inner">
2573
+ <span class="se-tooltip-text">${langs[s]}</span>
2574
+ </span>
2575
+ </button>`;
2576
+ }
2577
+
2578
+ const menus = domUtils.createElement('DIV', null, html);
2579
+ return { items, menus: menus.querySelectorAll('button') };
2580
+ }
2581
+
2582
+ function CreateHTML() {
2583
+ const html = /*html*/ `
2584
+ <div class="se-table-size">
2585
+ <div class="se-table-size-picker se-controller-table-picker"></div>
2586
+ <div class="se-table-size-highlighted"></div>
2587
+ <div class="se-table-size-unhighlighted"></div>
2588
+ </div>
2589
+ <div class="se-table-size-display">1 x 1</div>`;
2590
+
2591
+ return domUtils.createElement('DIV', { class: 'se-dropdown se-selector-table' }, html);
2592
+ }
2593
+
2594
+ function CreateHTML_controller_table({ lang, icons }) {
2595
+ const html = /*html*/ `
2596
+ <div class="se-arrow se-arrow-down se-visible-hidden"></div>
2597
+ <div class="se-btn-group">
2598
+ <button type="button" data-command="openTableProperties" class="se-btn se-tooltip">
2599
+ ${icons.table_properties}
2600
+ <span class="se-tooltip-inner">
2601
+ <span class="se-tooltip-text">${lang.tableProperties}</span>
2602
+ </span>
2603
+ </button>
2604
+ <button type="button" data-command="layout" class="se-btn se-tooltip _se_table_fixed_column">
2605
+ ${icons.fixed_column_width}
2606
+ <span class="se-tooltip-inner">
2607
+ <span class="se-tooltip-text">${lang.fixedColumnWidth}</span>
2608
+ </span>
2609
+ </button>
2610
+ <button type="button" data-command="header" class="se-btn se-tooltip _se_table_header">
2611
+ ${icons.table_header}
2612
+ <span class="se-tooltip-inner">
2613
+ <span class="se-tooltip-text">${lang.tableHeader}</span>
2614
+ </span>
2615
+ </button>
2616
+ <button type="button" data-command="caption" class="se-btn se-tooltip _se_table_caption">
2617
+ ${icons.caption}
2618
+ <span class="se-tooltip-inner">
2619
+ <span class="se-tooltip-text">${lang.caption}</span>
2620
+ </span>
2621
+ </button>
2622
+ <button type="button" data-command="resize" class="se-btn se-tooltip _se_table_resize">
2623
+ ${icons.reduction}
2624
+ <span class="se-tooltip-inner">
2625
+ <span class="se-tooltip-text">${lang.minSize}</span>
2626
+ </span>
2627
+ </button>
2628
+ <button type="button" data-command="remove" class="se-btn se-tooltip">
2629
+ ${icons.delete}
2630
+ <span class="se-tooltip-inner">
2631
+ <span class="se-tooltip-text">${lang.remove}</span>
2632
+ </span>
2633
+ </button>
2634
+ </div>`;
2635
+
2636
+ return domUtils.createElement('DIV', { class: 'se-controller se-controller-table' }, html);
2637
+ }
2638
+
2639
+ function CreateHTML_controller_cell({ lang, icons }, cellControllerTop) {
2640
+ const html = /*html*/ `
2641
+ <div class="se-arrow se-arrow-${cellControllerTop ? 'down se-visible-hidden' : 'up'}"></div>
2642
+ <div class="se-btn-group">
2643
+ <button type="button" data-command="openCellProperties" class="se-btn se-tooltip">
2644
+ ${icons.cell_properties}
2645
+ <span class="se-tooltip-inner">
2646
+ <span class="se-tooltip-text">${lang.cellProperties}</span>
2647
+ </span>
2648
+ </button>
2649
+ <button type="button" data-command="oncolumn" class="se-btn se-tooltip">
2650
+ ${icons.table_column}
2651
+ <span class="se-tooltip-inner">
2652
+ <span class="se-tooltip-text">${lang.column}</span>
2653
+ </span>
2654
+ </button>
2655
+ <button type="button" data-command="onrow" class="se-btn se-tooltip">
2656
+ ${icons.table_row}
2657
+ <span class="se-tooltip-inner">
2658
+ <span class="se-tooltip-text">${lang.row}</span>
2659
+ </span>
2660
+ </button>
2661
+ <button type="button" data-command="merge" class="se-btn se-tooltip" style="display: none;">
2662
+ ${icons.merge_cell}
2663
+ <span class="se-tooltip-inner">
2664
+ <span class="se-tooltip-text">${lang.mergeCells}</span>
2665
+ </span>
2666
+ </button>
2667
+ <button type="button" data-command="onsplit" class="se-btn se-tooltip">
2668
+ ${icons.split_cell}
2669
+ <span class="se-tooltip-inner">
2670
+ <span class="se-tooltip-text">${lang.splitCells}</span>
2671
+ </span>
2672
+ </button>
2673
+ </div>`;
2674
+
2675
+ return domUtils.createElement('DIV', { class: 'se-controller se-controller-table-cell' }, html);
2676
+ }
2677
+
2678
+ function CreateHTML_controller_properties({ lang, icons, options }) {
2679
+ const alignItems = options.get('_rtl') ? ['right', 'center', 'left', 'justify'] : ['left', 'center', 'right', 'justify'];
2680
+ let alignHtml = '';
2681
+ for (let i = 0, item, text; i < alignItems.length; i++) {
2682
+ item = alignItems[i];
2683
+ text = lang['align' + item.charAt(0).toUpperCase() + item.slice(1)];
2684
+ alignHtml += /*html*/ `
2685
+ <li>
2686
+ <button type="button" class="se-btn se-btn-list se-tooltip" data-command="props_align" data-value="${item}" title="${text}" aria-label="${text}">
2687
+ ${icons['align_' + item]}
2688
+ <span class="se-tooltip-inner">
2689
+ <span class="se-tooltip-text">${text}</span>
2690
+ </span>
2691
+ </button>
2692
+ </li>`;
2693
+ }
2694
+
2695
+ // vertical align html
2696
+ const verticalAligns = ['top', 'middle', 'bottom'];
2697
+ let verticalAlignHtml = '';
2698
+ for (let i = 0, item, text; i < verticalAligns.length; i++) {
2699
+ item = verticalAligns[i];
2700
+ text = lang['align' + item.charAt(0).toUpperCase() + item.slice(1)];
2701
+ verticalAlignHtml += /*html*/ `
2702
+ <li>
2703
+ <button type="button" class="se-btn se-btn-list se-tooltip" data-command="props_align_vertical" data-value="${item}" title="${text}" aria-label="${text}">
2704
+ ${icons['align_' + item]}
2705
+ <span class="se-tooltip-inner">
2706
+ <span class="se-tooltip-text">${text}</span>
2707
+ </span>
2708
+ </button>
2709
+ </li>`;
2710
+ }
2711
+
2712
+ const html = /*html*/ `
2713
+ <div class="se-controller-content">
2714
+ <div class="se-controller-header">
2715
+ <button type="button" data-command="close_props" class="se-btn se-close-btn close" title="${lang.close}" aria-label="${lang.close}">${icons.cancel}</button>
2716
+ <span class="se-controller-title">${lang.tableProperties}</span>
2717
+ </div>
2718
+ <div class="se-controller-body">
2719
+
2720
+ <label>${lang.border}</label>
2721
+ <div class="se-form-group se-form-w0">
2722
+ <button type="button" data-command="props_onborder_format" class="se-btn se-tooltip">
2723
+ ${icons[BORDER_FORMATS.all]}
2724
+ <span class="se-tooltip-inner">
2725
+ <span class="se-tooltip-text">${lang.border}</span>
2726
+ </span>
2727
+ </button>
2728
+ <button type="button" data-command="props_onborder_style" class="se-btn se-btn-select se-tooltip se-border-style">
2729
+ <span class="se-txt"></span>
2730
+ ${icons.arrow_down}
2731
+ <span class="se-tooltip-inner">
2732
+ <span class="se-tooltip-text">${lang.border}</span>
2733
+ </span>
2734
+ </button>
2735
+ <input type="text" class="se-color-input __se_border_color" placeholder="${lang.color}" />
2736
+ <button type="button" data-command="props_onpalette" data-value="border" class="se-btn se-tooltip">
2737
+ ${icons.color_palette}
2738
+ <span class="se-tooltip-inner">
2739
+ <span class="se-tooltip-text">${lang.colorPicker}</span>
2740
+ </span>
2741
+ </button>
2742
+ <input type="text" class="se-input-control __se__border_size" placeholder="${lang.width}" />
2743
+ </div>
2744
+
2745
+ <label>${lang.color}</label>
2746
+ <div class="se-form-group se-form-w0">
2747
+ <button type="button" data-command="props_onpalette" data-value="font" class="se-btn se-tooltip">
2748
+ ${icons.font_color}
2749
+ <span class="se-tooltip-inner">
2750
+ <span class="se-tooltip-text">${lang.fontColor}</span>
2751
+ </span>
2752
+ </button>
2753
+ <input type="text" class="se-color-input __se_font_color" placeholder="${lang.fontColor}" />
2754
+ <button type="button" data-command="props_onpalette" data-value="back" class="se-btn se-tooltip">
2755
+ ${icons.background_color}
2756
+ <span class="se-tooltip-inner">
2757
+ <span class="se-tooltip-text">${lang.backgroundColor}</span>
2758
+ </span>
2759
+ </button>
2760
+ <input type="text" class="se-color-input __se_back_color" placeholder="${lang.backgroundColor}" />
2761
+ </div>
2762
+
2763
+ <label>${lang.font}</label>
2764
+ <div class="se-form-group se-form-w0">
2765
+ <button type="button" data-command="props_font_style" data-value="bold" class="se-btn se-tooltip">
2766
+ ${icons.bold}
2767
+ <span class="se-tooltip-inner">
2768
+ <span class="se-tooltip-text">${lang.bold}</span>
2769
+ </span>
2770
+ </button>
2771
+ <button type="button" data-command="props_font_style" data-value="underline" class="se-btn se-tooltip">
2772
+ ${icons.underline}
2773
+ <span class="se-tooltip-inner">
2774
+ <span class="se-tooltip-text">${lang.underline}</span>
2775
+ </span>
2776
+ </button>
2777
+ <button type="button" data-command="props_font_style" data-value="italic" class="se-btn se-tooltip">
2778
+ ${icons.italic}
2779
+ <span class="se-tooltip-inner">
2780
+ <span class="se-tooltip-text">${lang.italic}</span>
2781
+ </span>
2782
+ </button>
2783
+ <button type="button" data-command="props_font_style" data-value="strike" class="se-btn se-tooltip">
2784
+ ${icons.strike}
2785
+ <span class="se-tooltip-inner">
2786
+ <span class="se-tooltip-text">${lang.strike}</span>
2787
+ </span>
2788
+ </button>
2789
+ </div>
2790
+
2791
+ <div class="se-table-props-align">
2792
+ <label>${lang.align}</label>
2793
+ <div class="se-form-group se-form-w0 se-list-inner __se__a_h">
2794
+ <ul class="se-form-group se-form-w0">${alignHtml}</ul>
2795
+ </div>
2796
+ <div class="se-form-group se-form-w0 se-list-inner __se__a_v">
2797
+ <ul class="se-form-group se-form-w0">${verticalAlignHtml}</ul>
2798
+ </div>
2799
+ </div>
2800
+ </div>
2801
+ <div class="se-form-group se-form-w0 se-form-flex-btn">
2802
+ <button type="button" class="se-btn se-btn-success" data-command="props_submit" title="${lang.submitButton}" aria-label="${lang.submitButton}">${icons.checked}</button>
2803
+ <button type="button" class="se-btn se-btn-danger" data-command="revert" title="${lang.revert}" aria-label="${lang.revert}">${icons.revert}</button>
2804
+ </div>
2805
+ </div>`;
2806
+
2807
+ return domUtils.createElement('DIV', { class: 'se-controller se-table-props' }, html);
2808
+ }
2809
+
2810
+ export default Table;