suneditor 3.0.0-alpha.2 → 3.0.0-alpha.20
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.
- package/.eslintrc.json +4 -3
- package/CONTRIBUTING.md +4 -2
- package/README.md +19 -11
- package/README_V3_TEMP.md +705 -0
- package/dist/suneditor.min.css +1 -0
- package/dist/suneditor.min.js +1 -0
- package/example.md +587 -0
- package/package.json +15 -9
- package/src/assets/icons/_default.js +166 -131
- package/src/assets/{suneditor-content.css → suneditor-contents.css} +182 -45
- package/src/assets/suneditor.css +1195 -556
- package/src/assets/variables.css +138 -0
- package/src/core/base/eventHandlers/handler_toolbar.js +35 -14
- package/src/core/base/eventHandlers/handler_ww_clipboard.js +29 -4
- package/src/core/base/eventHandlers/handler_ww_dragDrop.js +59 -15
- package/src/core/base/eventHandlers/handler_ww_key_input.js +426 -212
- package/src/core/base/eventHandlers/handler_ww_mouse.js +108 -32
- package/src/core/base/eventManager.js +540 -209
- package/src/core/base/events.js +616 -320
- package/src/core/base/history.js +93 -39
- package/src/core/class/char.js +29 -13
- package/src/core/class/component.js +332 -145
- package/src/core/class/format.js +671 -509
- package/src/core/class/html.js +504 -290
- package/src/core/class/menu.js +114 -47
- package/src/core/class/nodeTransform.js +111 -66
- package/src/core/class/offset.js +409 -105
- package/src/core/class/selection.js +220 -108
- package/src/core/class/shortcuts.js +68 -8
- package/src/core/class/toolbar.js +106 -116
- package/src/core/class/ui.js +330 -0
- package/src/core/class/viewer.js +178 -74
- package/src/core/editor.js +489 -384
- package/src/core/section/actives.js +118 -22
- package/src/core/section/constructor.js +504 -170
- package/src/core/section/context.js +28 -23
- package/src/core/section/documentType.js +561 -0
- package/src/editorInjector/_classes.js +19 -5
- package/src/editorInjector/_core.js +71 -7
- package/src/editorInjector/index.js +63 -1
- package/src/helper/converter.js +137 -19
- package/src/helper/dom/domCheck.js +294 -0
- package/src/helper/dom/domQuery.js +609 -0
- package/src/helper/dom/domUtils.js +533 -0
- package/src/helper/dom/index.js +12 -0
- package/src/helper/env.js +42 -19
- package/src/helper/index.js +7 -4
- package/src/helper/keyCodeMap.js +183 -0
- package/src/helper/numbers.js +8 -8
- package/src/helper/unicode.js +5 -5
- package/src/langs/ckb.js +69 -3
- package/src/langs/cs.js +67 -1
- package/src/langs/da.js +68 -2
- package/src/langs/de.js +68 -3
- package/src/langs/en.js +29 -1
- package/src/langs/es.js +68 -3
- package/src/langs/fa.js +70 -2
- package/src/langs/fr.js +68 -2
- package/src/langs/he.js +68 -3
- package/src/langs/hu.js +226 -0
- package/src/langs/index.js +3 -2
- package/src/langs/it.js +65 -0
- package/src/langs/ja.js +68 -3
- package/src/langs/ko.js +66 -1
- package/src/langs/lv.js +68 -3
- package/src/langs/nl.js +68 -3
- package/src/langs/pl.js +68 -3
- package/src/langs/pt_br.js +65 -0
- package/src/langs/ro.js +69 -4
- package/src/langs/ru.js +68 -3
- package/src/langs/se.js +68 -3
- package/src/langs/tr.js +68 -0
- package/src/langs/ua.js +68 -3
- package/src/langs/ur.js +71 -6
- package/src/langs/zh_cn.js +69 -4
- package/src/modules/ApiManager.js +77 -54
- package/src/modules/Browser.js +667 -0
- package/src/modules/ColorPicker.js +162 -102
- package/src/modules/Controller.js +233 -136
- package/src/modules/Figure.js +913 -489
- package/src/modules/FileManager.js +141 -72
- package/src/modules/HueSlider.js +113 -61
- package/src/modules/Modal.js +292 -113
- package/src/modules/ModalAnchorEditor.js +380 -230
- package/src/modules/SelectMenu.js +270 -168
- package/src/modules/_DragHandle.js +2 -1
- package/src/modules/index.js +3 -3
- package/src/plugins/browser/audioGallery.js +83 -0
- package/src/plugins/browser/fileBrowser.js +103 -0
- package/src/plugins/browser/fileGallery.js +83 -0
- package/src/plugins/browser/imageGallery.js +81 -0
- package/src/plugins/browser/videoGallery.js +103 -0
- package/src/plugins/command/blockquote.js +40 -27
- package/src/plugins/command/exportPDF.js +134 -0
- package/src/plugins/command/fileUpload.js +226 -158
- package/src/plugins/command/list_bulleted.js +93 -47
- package/src/plugins/command/list_numbered.js +93 -47
- package/src/plugins/dropdown/align.js +66 -54
- package/src/plugins/dropdown/backgroundColor.js +76 -45
- package/src/plugins/dropdown/font.js +71 -47
- package/src/plugins/dropdown/fontColor.js +78 -46
- package/src/plugins/dropdown/formatBlock.js +74 -33
- package/src/plugins/dropdown/hr.js +102 -51
- package/src/plugins/dropdown/layout.js +37 -26
- package/src/plugins/dropdown/lineHeight.js +54 -38
- package/src/plugins/dropdown/list.js +60 -45
- package/src/plugins/dropdown/paragraphStyle.js +51 -30
- package/src/plugins/dropdown/table.js +1269 -777
- package/src/plugins/dropdown/template.js +38 -26
- package/src/plugins/dropdown/textStyle.js +43 -31
- package/src/plugins/field/mention.js +144 -82
- package/src/plugins/index.js +32 -6
- package/src/plugins/input/fontSize.js +161 -108
- package/src/plugins/input/pageNavigator.js +70 -0
- package/src/plugins/modal/audio.js +341 -169
- package/src/plugins/modal/drawing.js +530 -0
- package/src/plugins/modal/embed.js +886 -0
- package/src/plugins/modal/image.js +673 -358
- package/src/plugins/modal/link.js +100 -71
- package/src/plugins/modal/math.js +384 -168
- package/src/plugins/modal/video.js +693 -336
- package/src/plugins/popup/anchor.js +222 -0
- package/src/suneditor.js +54 -12
- package/src/themes/dark.css +85 -0
- package/src/typedef.js +86 -0
- package/types/assets/icons/_default.d.ts +152 -0
- package/types/core/base/eventHandlers/handler_toolbar.d.ts +41 -0
- package/types/core/base/eventHandlers/handler_ww_clipboard.d.ts +40 -0
- package/types/core/base/eventHandlers/handler_ww_dragDrop.d.ts +35 -0
- package/types/core/base/eventHandlers/handler_ww_key_input.d.ts +45 -0
- package/types/core/base/eventHandlers/handler_ww_mouse.d.ts +39 -0
- package/types/core/base/eventManager.d.ts +377 -0
- package/types/core/base/events.d.ts +297 -0
- package/types/core/base/history.d.ts +81 -0
- package/types/core/class/char.d.ts +60 -0
- package/types/core/class/component.d.ts +259 -0
- package/types/core/class/format.d.ts +615 -0
- package/types/core/class/html.d.ts +377 -0
- package/types/core/class/menu.d.ts +118 -0
- package/types/core/class/nodeTransform.d.ts +93 -0
- package/types/core/class/offset.d.ts +512 -0
- package/types/core/class/selection.d.ts +188 -0
- package/types/core/class/shortcuts.d.ts +142 -0
- package/types/core/class/toolbar.d.ts +189 -0
- package/types/core/class/ui.d.ts +144 -0
- package/types/core/class/viewer.d.ts +140 -0
- package/types/core/editor.d.ts +606 -0
- package/types/core/section/actives.d.ts +46 -0
- package/types/core/section/constructor.d.ts +748 -0
- package/types/core/section/context.d.ts +45 -0
- package/types/core/section/documentType.d.ts +178 -0
- package/types/editorInjector/_classes.d.ts +41 -0
- package/types/editorInjector/_core.d.ts +92 -0
- package/types/editorInjector/index.d.ts +71 -0
- package/types/helper/converter.d.ts +150 -0
- package/types/helper/dom/domCheck.d.ts +182 -0
- package/types/helper/dom/domQuery.d.ts +214 -0
- package/types/helper/dom/domUtils.d.ts +211 -0
- package/types/helper/dom/index.d.ts +9 -0
- package/types/helper/env.d.ts +149 -0
- package/types/helper/index.d.ts +163 -0
- package/types/helper/keyCodeMap.d.ts +110 -0
- package/types/helper/numbers.d.ts +43 -0
- package/types/helper/unicode.d.ts +28 -0
- package/types/index.d.ts +0 -0
- package/{typings/Lang.d.ts → types/langs/_Lang.d.ts} +170 -103
- package/types/langs/ckb.d.ts +384 -0
- package/types/langs/cs.d.ts +384 -0
- package/types/langs/da.d.ts +384 -0
- package/types/langs/de.d.ts +384 -0
- package/types/langs/en.d.ts +384 -0
- package/types/langs/es.d.ts +384 -0
- package/types/langs/fa.d.ts +384 -0
- package/types/langs/fr.d.ts +384 -0
- package/types/langs/he.d.ts +384 -0
- package/types/langs/hu.d.ts +384 -0
- package/types/langs/index.d.ts +48 -0
- package/types/langs/it.d.ts +384 -0
- package/types/langs/ja.d.ts +384 -0
- package/types/langs/ko.d.ts +384 -0
- package/types/langs/lv.d.ts +384 -0
- package/types/langs/nl.d.ts +384 -0
- package/types/langs/pl.d.ts +384 -0
- package/types/langs/pt_br.d.ts +384 -0
- package/types/langs/ro.d.ts +384 -0
- package/types/langs/ru.d.ts +384 -0
- package/types/langs/se.d.ts +384 -0
- package/types/langs/tr.d.ts +384 -0
- package/types/langs/ua.d.ts +384 -0
- package/types/langs/ur.d.ts +384 -0
- package/types/langs/zh_cn.d.ts +384 -0
- package/types/modules/ApiManager.d.ts +125 -0
- package/types/modules/Browser.d.ts +326 -0
- package/types/modules/ColorPicker.d.ts +131 -0
- package/types/modules/Controller.d.ts +231 -0
- package/types/modules/Figure.d.ts +504 -0
- package/types/modules/FileManager.d.ts +202 -0
- package/types/modules/HueSlider.d.ts +136 -0
- package/types/modules/Modal.d.ts +117 -0
- package/types/modules/ModalAnchorEditor.d.ts +236 -0
- package/types/modules/SelectMenu.d.ts +194 -0
- package/types/modules/_DragHandle.d.ts +7 -0
- package/types/modules/index.d.ts +26 -0
- package/types/plugins/browser/audioGallery.d.ts +55 -0
- package/types/plugins/browser/fileBrowser.d.ts +64 -0
- package/types/plugins/browser/fileGallery.d.ts +55 -0
- package/types/plugins/browser/imageGallery.d.ts +51 -0
- package/types/plugins/browser/videoGallery.d.ts +57 -0
- package/types/plugins/command/blockquote.d.ts +28 -0
- package/types/plugins/command/exportPDF.d.ts +46 -0
- package/types/plugins/command/fileUpload.d.ts +156 -0
- package/types/plugins/command/list_bulleted.d.ts +56 -0
- package/types/plugins/command/list_numbered.d.ts +56 -0
- package/types/plugins/dropdown/align.d.ts +60 -0
- package/types/plugins/dropdown/backgroundColor.d.ts +63 -0
- package/types/plugins/dropdown/font.d.ts +54 -0
- package/types/plugins/dropdown/fontColor.d.ts +63 -0
- package/types/plugins/dropdown/formatBlock.d.ts +58 -0
- package/types/plugins/dropdown/hr.d.ts +81 -0
- package/types/plugins/dropdown/layout.d.ts +40 -0
- package/types/plugins/dropdown/lineHeight.d.ts +50 -0
- package/types/plugins/dropdown/list.d.ts +39 -0
- package/types/plugins/dropdown/paragraphStyle.d.ts +54 -0
- package/types/plugins/dropdown/table.d.ts +579 -0
- package/types/plugins/dropdown/template.d.ts +40 -0
- package/types/plugins/dropdown/textStyle.d.ts +41 -0
- package/types/plugins/field/mention.d.ts +102 -0
- package/types/plugins/index.d.ts +107 -0
- package/types/plugins/input/fontSize.d.ts +170 -0
- package/types/plugins/input/pageNavigator.d.ts +28 -0
- package/types/plugins/modal/audio.d.ts +269 -0
- package/types/plugins/modal/drawing.d.ts +246 -0
- package/types/plugins/modal/embed.d.ts +387 -0
- package/types/plugins/modal/image.d.ts +451 -0
- package/types/plugins/modal/link.d.ts +128 -0
- package/types/plugins/modal/math.d.ts +193 -0
- package/types/plugins/modal/video.d.ts +485 -0
- package/types/plugins/popup/anchor.d.ts +56 -0
- package/types/suneditor.d.ts +51 -0
- package/types/typedef-global.d.ts +144 -0
- package/src/core/class/notice.js +0 -42
- package/src/helper/domUtils.js +0 -1177
- package/src/modules/FileBrowser.js +0 -271
- package/src/plugins/command/exportPdf.js +0 -168
- package/src/plugins/fileBrowser/imageGallery.js +0 -81
- package/src/themes/test.css +0 -61
- package/typings/CommandPlugin.d.ts +0 -8
- package/typings/DialogPlugin.d.ts +0 -20
- package/typings/FileBrowserPlugin.d.ts +0 -30
- package/typings/Module.d.ts +0 -15
- package/typings/Plugin.d.ts +0 -42
- package/typings/SubmenuPlugin.d.ts +0 -8
- package/typings/_classes.d.ts +0 -17
- package/typings/_colorPicker.d.ts +0 -60
- package/typings/_core.d.ts +0 -55
- package/typings/align.d.ts +0 -5
- package/typings/audio.d.ts +0 -5
- package/typings/backgroundColor.d.ts +0 -5
- package/typings/blockquote.d.ts +0 -5
- package/typings/char.d.ts +0 -39
- package/typings/component.d.ts +0 -38
- package/typings/context.d.ts +0 -39
- package/typings/converter.d.ts +0 -33
- package/typings/dialog.d.ts +0 -28
- package/typings/domUtils.d.ts +0 -361
- package/typings/editor.d.ts +0 -7
- package/typings/editor.ts +0 -542
- package/typings/env.d.ts +0 -70
- package/typings/eventManager.d.ts +0 -37
- package/typings/events.d.ts +0 -262
- package/typings/fileBrowser.d.ts +0 -42
- package/typings/fileManager.d.ts +0 -67
- package/typings/font.d.ts +0 -5
- package/typings/fontColor.d.ts +0 -5
- package/typings/fontSize.d.ts +0 -5
- package/typings/format.d.ts +0 -191
- package/typings/formatBlock.d.ts +0 -5
- package/typings/history.d.ts +0 -48
- package/typings/horizontalRule.d.ts +0 -5
- package/typings/image.d.ts +0 -5
- package/typings/imageGallery.d.ts +0 -5
- package/typings/index.d.ts +0 -21
- package/typings/index.modules.d.ts +0 -11
- package/typings/index.plugins.d.ts +0 -58
- package/typings/lineHeight.d.ts +0 -5
- package/typings/link.d.ts +0 -5
- package/typings/list.d.ts +0 -5
- package/typings/math.d.ts +0 -5
- package/typings/mediaContainer.d.ts +0 -25
- package/typings/mention.d.ts +0 -5
- package/typings/node.d.ts +0 -57
- package/typings/notice.d.ts +0 -16
- package/typings/numbers.d.ts +0 -29
- package/typings/offset.d.ts +0 -24
- package/typings/options.d.ts +0 -589
- package/typings/paragraphStyle.d.ts +0 -5
- package/typings/resizing.d.ts +0 -141
- package/typings/selection.d.ts +0 -94
- package/typings/shortcuts.d.ts +0 -13
- package/typings/suneditor.d.ts +0 -9
- package/typings/table.d.ts +0 -5
- package/typings/template.d.ts +0 -5
- package/typings/textStyle.d.ts +0 -5
- package/typings/toolbar.d.ts +0 -32
- package/typings/unicode.d.ts +0 -25
- package/typings/video.d.ts +0 -5
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import EditorInjector from '../../editorInjector';
|
|
2
|
-
import {
|
|
2
|
+
import { dom, numbers, converter, env, keyCodeMap } from '../../helper';
|
|
3
3
|
import { Controller, SelectMenu, ColorPicker, Figure, _DragHandle } from '../../modules';
|
|
4
4
|
|
|
5
5
|
const { _w, ON_OVER_COMPONENT } = env;
|
|
@@ -61,270 +61,365 @@ const DEFAULT_COLOR_LIST = [
|
|
|
61
61
|
'#000000'
|
|
62
62
|
];
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
-
};
|
|
64
|
+
/**
|
|
65
|
+
* @class
|
|
66
|
+
* @description Table Plugin
|
|
67
|
+
*/
|
|
68
|
+
class Table extends EditorInjector {
|
|
69
|
+
static key = 'table';
|
|
70
|
+
static type = 'dropdown-free';
|
|
71
|
+
static className = '';
|
|
72
|
+
static options = { isInputComponent: true };
|
|
73
|
+
/**
|
|
74
|
+
* @this {Table}
|
|
75
|
+
* @param {HTMLElement} node - The node to check.
|
|
76
|
+
* @returns {HTMLElement|null} Returns a node if the node is a valid component.
|
|
77
|
+
*/
|
|
78
|
+
static component(node) {
|
|
79
|
+
return dom.check.isTable(node) ? node : null;
|
|
80
|
+
}
|
|
239
81
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
}
|
|
82
|
+
/**
|
|
83
|
+
* @constructor
|
|
84
|
+
* @param {__se__EditorCore} editor - The root editor instance
|
|
85
|
+
* @param {Object} pluginOptions
|
|
86
|
+
* @param {"x"|"y"|"xy"} [pluginOptions.scrollType='x'] - Scroll type ('x', 'y', 'xy')
|
|
87
|
+
* @param {"top"|"bottom"} [pluginOptions.captionPosition='bottom'] - Caption position ('top', 'bottom')
|
|
88
|
+
* @param {"cell"|"table"} [pluginOptions.cellControllerPosition='cell'] - Cell controller position ('cell', 'table')
|
|
89
|
+
* @param {Array} [pluginOptions.colorList] - Color list, used in cell color picker
|
|
90
|
+
*/
|
|
91
|
+
constructor(editor, pluginOptions) {
|
|
92
|
+
// plugin bisic properties
|
|
93
|
+
super(editor);
|
|
94
|
+
this.title = this.lang.table;
|
|
95
|
+
this.icon = 'table';
|
|
96
|
+
|
|
97
|
+
// pluginOptions options
|
|
98
|
+
this.figureScrollList = ['se-scroll-figure-xy', 'se-scroll-figure-x', 'se-scroll-figure-y'];
|
|
99
|
+
this.figureScroll = typeof pluginOptions.scrollType === 'string' ? pluginOptions.scrollType.toLowerCase() : 'x';
|
|
100
|
+
this.captionPosition = pluginOptions.captionPosition !== 'bottom' ? 'top' : 'bottom';
|
|
101
|
+
this.cellControllerTop = (pluginOptions.cellControllerPosition !== 'cell' ? 'table' : 'cell') === 'table';
|
|
102
|
+
|
|
103
|
+
// create HTML
|
|
104
|
+
const menu = CreateHTML();
|
|
105
|
+
const commandArea = menu.querySelector('.se-controller-table-picker');
|
|
106
|
+
const controller_table = CreateHTML_controller_table(editor);
|
|
107
|
+
const controller_cell = CreateHTML_controller_cell(editor, this.cellControllerTop);
|
|
108
|
+
const controller_props = CreateHTML_controller_properties(editor);
|
|
109
|
+
|
|
110
|
+
editor.applyFrameRoots((e) => {
|
|
111
|
+
e.get('wrapper').appendChild(dom.utils.createElement('DIV', { class: RESIZE_CELL_CLASS.replace(/^\./, '') }));
|
|
112
|
+
e.get('wrapper').appendChild(dom.utils.createElement('DIV', { class: RESIZE_CELL_PREV_CLASS.replace(/^\./, '') }));
|
|
113
|
+
e.get('wrapper').appendChild(dom.utils.createElement('DIV', { class: RESIZE_ROW_CLASS.replace(/^\./, '') }));
|
|
114
|
+
e.get('wrapper').appendChild(dom.utils.createElement('DIV', { class: RESIZE_ROW_PREV_CLASS.replace(/^\./, '') }));
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// members - Controller
|
|
118
|
+
this.controller_table = new Controller(this, controller_table, { position: 'top' });
|
|
119
|
+
this.controller_cell = new Controller(this, controller_cell.html, { position: this.cellControllerTop ? 'top' : 'bottom' });
|
|
120
|
+
// props
|
|
121
|
+
const propsTargetForms = [this.controller_table.form, this.controller_cell.form];
|
|
122
|
+
this.controller_props = new Controller(this, controller_props.html, { position: 'bottom', parents: propsTargetForms, isInsideForm: true });
|
|
123
|
+
this.controller_props_title = controller_props.controller_props_title;
|
|
124
|
+
// color picker
|
|
125
|
+
const colorForm = dom.utils.createElement('DIV', { class: 'se-controller se-list-layer' }, null);
|
|
126
|
+
this.colorPicker = new ColorPicker(this, '', {
|
|
127
|
+
colorList: pluginOptions.colorList || DEFAULT_COLOR_LIST,
|
|
128
|
+
splitNum: 5,
|
|
129
|
+
disableRemove: true,
|
|
130
|
+
hueSliderOptions: { controllerOptions: { parents: [colorForm], isOutsideForm: true } }
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
colorForm.appendChild(this.colorPicker.target);
|
|
134
|
+
this.controller_colorPicker = new Controller(this, colorForm, {
|
|
135
|
+
position: 'bottom',
|
|
136
|
+
parents: [this.controller_props.form].concat(propsTargetForms),
|
|
137
|
+
isInsideForm: true,
|
|
138
|
+
isWWTarget: false,
|
|
139
|
+
initMethod: () => {
|
|
140
|
+
this.colorPicker.hueSlider.close();
|
|
141
|
+
dom.utils.removeClass(this.controller_colorPicker.currentTarget, 'on');
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
this.figure = new Figure(this, null, {});
|
|
146
|
+
|
|
147
|
+
this.sliderType = '';
|
|
148
|
+
|
|
149
|
+
// members - SelectMenu - split
|
|
150
|
+
const splitMenu = CreateSplitMenu(this.lang);
|
|
151
|
+
this.splitButton = controller_cell.splitButton;
|
|
152
|
+
this.selectMenu_split = new SelectMenu(this, { checkList: false, position: 'bottom-center' });
|
|
153
|
+
this.selectMenu_split.on(this.splitButton, this.#OnSplitCells.bind(this));
|
|
154
|
+
this.selectMenu_split.create(splitMenu.items, splitMenu.menus);
|
|
155
|
+
|
|
156
|
+
// members - SelectMenu - column
|
|
157
|
+
const columnMenu = CreateColumnMenu(this.lang, this.icons);
|
|
158
|
+
const columnButton = controller_cell.columnButton;
|
|
159
|
+
this.selectMenu_column = new SelectMenu(this, { checkList: false, position: 'bottom-center' });
|
|
160
|
+
this.selectMenu_column.on(columnButton, this.#OnColumnEdit.bind(this));
|
|
161
|
+
this.selectMenu_column.create(columnMenu.items, columnMenu.menus);
|
|
162
|
+
|
|
163
|
+
// members - SelectMenu - row
|
|
164
|
+
const rownMenu = CreateRowMenu(this.lang, this.icons);
|
|
165
|
+
const rowButton = controller_cell.rowButton;
|
|
166
|
+
this.selectMenu_row = new SelectMenu(this, { checkList: false, position: 'bottom-center' });
|
|
167
|
+
this.selectMenu_row.on(rowButton, this.#OnRowEdit.bind(this));
|
|
168
|
+
this.selectMenu_row.create(rownMenu.items, rownMenu.menus);
|
|
169
|
+
|
|
170
|
+
// members - SelectMenu - properties - border style
|
|
171
|
+
const borderMenu = CreateBorderMenu();
|
|
172
|
+
const borderButton = controller_props.borderButton;
|
|
173
|
+
this.selectMenu_props_border = new SelectMenu(this, { checkList: false, position: 'bottom-center' });
|
|
174
|
+
this.selectMenu_props_border.on(borderButton, OnPropsBorderEdit.bind(this));
|
|
175
|
+
this.selectMenu_props_border.create(borderMenu.items, borderMenu.menus);
|
|
176
|
+
|
|
177
|
+
// members - SelectMenu - properties - border format
|
|
178
|
+
const borderFormatMenu = CreateBorderFormatMenu(this.lang, this.icons, []);
|
|
179
|
+
const borderFormatButton = controller_props.borderFormatButton;
|
|
180
|
+
this.selectMenu_props_border_format = new SelectMenu(this, { checkList: false, position: 'bottom-left', dir: 'ltr', splitNum: 5 });
|
|
181
|
+
this.selectMenu_props_border_format.on(borderFormatButton, OnPropsBorderFormatEdit.bind(this, 'all'));
|
|
182
|
+
this.selectMenu_props_border_format.create(borderFormatMenu.items, borderFormatMenu.menus);
|
|
183
|
+
|
|
184
|
+
const borderFormatMenu_oneCell = CreateBorderFormatMenu(this.lang, this.icons, BORDER_FORMAT_INSIDE);
|
|
185
|
+
this.selectMenu_props_border_format_oneCell = new SelectMenu(this, { checkList: false, position: 'bottom-left', dir: 'ltr', splitNum: 6 });
|
|
186
|
+
this.selectMenu_props_border_format_oneCell.on(borderFormatButton, OnPropsBorderFormatEdit.bind(this, 'outside'));
|
|
187
|
+
this.selectMenu_props_border_format_oneCell.create(borderFormatMenu_oneCell.items, borderFormatMenu_oneCell.menus);
|
|
188
|
+
|
|
189
|
+
// memberts - elements..
|
|
190
|
+
this.maxText = this.lang.maxSize;
|
|
191
|
+
this.minText = this.lang.minSize;
|
|
192
|
+
this.propTargets = {
|
|
193
|
+
cell_alignment: controller_props.cell_alignment,
|
|
194
|
+
cell_alignment_vertical: controller_props.cell_alignment_vertical,
|
|
195
|
+
cell_alignment_table_text: controller_props.cell_alignment_table_text,
|
|
196
|
+
border_format: borderFormatButton,
|
|
197
|
+
border_style: controller_props.border_style,
|
|
198
|
+
border_color: controller_props.border_color,
|
|
199
|
+
border_width: controller_props.border_width,
|
|
200
|
+
back_color: controller_props.back_color,
|
|
201
|
+
font_color: controller_props.font_color,
|
|
202
|
+
palette_border_button: controller_props.palette_border_button,
|
|
203
|
+
font_bold: controller_props.font_bold,
|
|
204
|
+
font_underline: controller_props.font_underline,
|
|
205
|
+
font_italic: controller_props.font_italic,
|
|
206
|
+
font_strike: controller_props.font_strike
|
|
207
|
+
};
|
|
208
|
+
this._propsCache = [];
|
|
209
|
+
this._currentFontStyles = [];
|
|
210
|
+
this._propsAlignCache = '';
|
|
211
|
+
this._propsVerticalAlignCache = '';
|
|
212
|
+
this._typeCache = '';
|
|
213
|
+
|
|
214
|
+
/** @type {HTMLElement} */
|
|
215
|
+
this.tableHighlight = menu.querySelector('.se-table-size-highlighted');
|
|
216
|
+
/** @type {HTMLElement} */
|
|
217
|
+
this.tableUnHighlight = menu.querySelector('.se-table-size-unhighlighted');
|
|
218
|
+
/** @type {HTMLElement} */
|
|
219
|
+
this.tableDisplay = menu.querySelector('.se-table-size-display');
|
|
220
|
+
/** @type {HTMLButtonElement} */
|
|
221
|
+
this.resizeButton = controller_table.querySelector('._se_table_resize');
|
|
222
|
+
/** @type {HTMLSpanElement} */
|
|
223
|
+
this.resizeText = controller_table.querySelector('._se_table_resize > span > span');
|
|
224
|
+
/** @type {HTMLButtonElement} */
|
|
225
|
+
this.columnFixedButton = controller_table.querySelector('._se_table_fixed_column');
|
|
226
|
+
/** @type {HTMLButtonElement} */
|
|
227
|
+
this.headerButton = controller_table.querySelector('._se_table_header');
|
|
228
|
+
/** @type {HTMLButtonElement} */
|
|
229
|
+
this.captionButton = controller_table.querySelector('._se_table_caption');
|
|
230
|
+
/** @type {HTMLButtonElement} */
|
|
231
|
+
this.mergeButton = controller_cell.mergeButton;
|
|
232
|
+
|
|
233
|
+
// members - private
|
|
234
|
+
this._resizing = false;
|
|
235
|
+
this._resizeLine = null;
|
|
236
|
+
this._resizeLinePrev = null;
|
|
237
|
+
|
|
238
|
+
/** @type {HTMLElement} */
|
|
239
|
+
this._figure = null;
|
|
240
|
+
/** @type {HTMLTableElement} */
|
|
241
|
+
this._element = null;
|
|
242
|
+
/** @type {HTMLTableCellElement} */
|
|
243
|
+
this._tdElement = null;
|
|
244
|
+
/** @type {HTMLTableRowElement} */
|
|
245
|
+
this._trElement = null;
|
|
246
|
+
/** @type {HTMLTableRowElement[]|HTMLCollectionOf<HTMLTableRowElement>} */
|
|
247
|
+
this._trElements = null;
|
|
248
|
+
|
|
249
|
+
this._tableXY = [];
|
|
250
|
+
this._maxWidth = true;
|
|
251
|
+
this._fixedColumn = false;
|
|
252
|
+
this._physical_cellCnt = 0;
|
|
253
|
+
this._logical_cellCnt = 0;
|
|
254
|
+
this._rowCnt = 0;
|
|
255
|
+
this._rowIndex = 0;
|
|
256
|
+
this._physical_cellIndex = 0;
|
|
257
|
+
this._logical_cellIndex = 0;
|
|
258
|
+
this._current_colSpan = 0;
|
|
259
|
+
this._current_rowSpan = 0;
|
|
260
|
+
|
|
261
|
+
// member - multi selecte
|
|
262
|
+
/** @type {HTMLTableElement} */
|
|
263
|
+
this._selectedTable = null;
|
|
264
|
+
/** @type {HTMLTableCellElement} */
|
|
265
|
+
this._fixedCell = null;
|
|
266
|
+
/** @type {HTMLTableCellElement} */
|
|
267
|
+
this._selectedCell = null;
|
|
268
|
+
/** @type {HTMLTableCellElement[]} */
|
|
269
|
+
this._selectedCells = null;
|
|
270
|
+
|
|
271
|
+
this._shift = false;
|
|
272
|
+
this.__s = false;
|
|
273
|
+
this._fixedCellName = null;
|
|
274
|
+
this._ref = null;
|
|
275
|
+
|
|
276
|
+
// member - global events
|
|
277
|
+
this._bindMultiOn = this.#OnCellMultiSelect.bind(this);
|
|
278
|
+
this._bindMultiOff = this.#OffCellMultiSelect.bind(this);
|
|
279
|
+
this._bindShiftOff = this.#OffCellShift.bind(this);
|
|
280
|
+
this._bindTouchOff = this.#OffCellTouch.bind(this);
|
|
281
|
+
this.__globalEvents = {
|
|
282
|
+
on: null,
|
|
283
|
+
off: null,
|
|
284
|
+
shiftOff: null,
|
|
285
|
+
touchOff: null,
|
|
286
|
+
resize: null,
|
|
287
|
+
resizeStop: null,
|
|
288
|
+
resizeKeyDown: null
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
// init
|
|
292
|
+
this.menu.initDropdownTarget(Table, menu);
|
|
293
|
+
this.eventManager.addEvent(commandArea, 'mousemove', this.#OnMouseMoveTablePicker.bind(this));
|
|
294
|
+
this.eventManager.addEvent(commandArea, 'click', this.#OnClickTablePicker.bind(this));
|
|
295
|
+
}
|
|
245
296
|
|
|
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
297
|
/**
|
|
255
|
-
* @
|
|
298
|
+
* @editorMethod Editor.core
|
|
299
|
+
* @description Executes the main execution method of the plugin.
|
|
300
|
+
* - Called when an item in the "dropdown" menu is clicked.
|
|
256
301
|
*/
|
|
257
302
|
action() {
|
|
258
|
-
const oTable =
|
|
303
|
+
const oTable = dom.utils.createElement('TABLE');
|
|
259
304
|
const x = this._tableXY[0];
|
|
260
305
|
const y = this._tableXY[1];
|
|
261
306
|
|
|
262
|
-
const body = `<tbody>${`<tr>${
|
|
307
|
+
const body = `<tbody>${`<tr>${CreateCellsString('td', x)}</tr>`.repeat(y)}</tbody>`;
|
|
263
308
|
const colGroup = `<colgroup>${`<col style="width: ${numbers.get(100 / x, CELL_DECIMAL_END)}%;">`.repeat(x)}</colgroup>`;
|
|
264
309
|
oTable.innerHTML = colGroup + body;
|
|
265
310
|
|
|
266
|
-
|
|
311
|
+
// scroll
|
|
312
|
+
let scrollTypeClass = '';
|
|
313
|
+
if (this.figureScroll) {
|
|
314
|
+
scrollTypeClass = ` se-scroll-figure-${this.figureScroll}`;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const figure = dom.utils.createElement('FIGURE', { class: 'se-flex-component se-input-component' + scrollTypeClass });
|
|
267
318
|
figure.appendChild(oTable);
|
|
268
319
|
|
|
269
|
-
if (this.component.insert(figure, false, false)) {
|
|
320
|
+
if (this.component.insert(figure, { skipCharCount: false, skipSelection: false, skipHistory: false })) {
|
|
270
321
|
this._resetTablePicker();
|
|
271
322
|
const target = oTable.querySelector('td div');
|
|
272
323
|
this.selection.setRange(target, 0, target, 0);
|
|
273
324
|
}
|
|
274
|
-
}
|
|
325
|
+
}
|
|
275
326
|
|
|
276
327
|
/**
|
|
277
|
-
* @
|
|
328
|
+
* @editorMethod Modules.Component
|
|
329
|
+
* @description Executes the method that is called when a component of a plugin is selected.
|
|
330
|
+
* @param {HTMLElement} target Target component element
|
|
331
|
+
*/
|
|
332
|
+
select(target) {
|
|
333
|
+
this._figureOpen(target);
|
|
334
|
+
if (!this._figure) this.setTableInfo(target);
|
|
335
|
+
|
|
336
|
+
const targetWidth = this._figure?.style.width || '100%';
|
|
337
|
+
this._maxWidth = targetWidth === '100%';
|
|
338
|
+
this._fixedColumn = dom.utils.hasClass(target, 'se-table-layout-fixed') || target.style.tableLayout === 'fixed';
|
|
339
|
+
this._setTableStyle(this._maxWidth ? 'width|column' : 'width', true);
|
|
340
|
+
|
|
341
|
+
if (_DragHandle.get('__overInfo') === ON_OVER_COMPONENT) return;
|
|
342
|
+
|
|
343
|
+
if (!this._tdElement) return;
|
|
344
|
+
this.setCellInfo(this._tdElement, true);
|
|
345
|
+
|
|
346
|
+
// controller open
|
|
347
|
+
const btnDisabled = this._selectedCells.length > 1;
|
|
348
|
+
const figureEl = dom.query.getParentElement(target, dom.check.isFigure);
|
|
349
|
+
this.controller_table.open(figureEl, null, { isWWTarget: false, initMethod: null, addOffset: null, disabled: btnDisabled });
|
|
350
|
+
|
|
351
|
+
const addOffset = !this.cellControllerTop ? null : this.controller_table.form.style.display === 'block' ? { left: this.controller_table.form.offsetWidth + 2 } : null;
|
|
352
|
+
this.controller_cell.open(this._tdElement, this.cellControllerTop ? figureEl : null, { isWWTarget: false, initMethod: null, addOffset: addOffset, disabled: btnDisabled });
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* @editorMethod Editor.core
|
|
357
|
+
* @description This method is used to validate and preserve the format of the component within the editor.
|
|
358
|
+
* - It ensures that the structure and attributes of the element are maintained and secure.
|
|
359
|
+
* - The method checks if the element is already wrapped in a valid container and updates its attributes if necessary.
|
|
360
|
+
* - If the element isn't properly contained, a new container is created to retain the format.
|
|
361
|
+
* @returns {{query: string, method: (element: HTMLTableElement) => void}} The format retention object containing the query and method to process the element.
|
|
362
|
+
* - query: The selector query to identify the relevant elements (in this case, 'audio').
|
|
363
|
+
* - method:The function to execute on the element to validate and preserve its format.
|
|
364
|
+
* - The function takes the element as an argument, checks if it is contained correctly, and applies necessary adjustments.
|
|
278
365
|
*/
|
|
279
366
|
retainFormat() {
|
|
280
367
|
return {
|
|
281
368
|
query: 'table',
|
|
282
369
|
method: (element) => {
|
|
283
370
|
const ColgroupEl = element.querySelector('colgroup');
|
|
284
|
-
let FigureEl =
|
|
371
|
+
let FigureEl = dom.check.isFigure(element.parentNode) ? element.parentNode : null;
|
|
285
372
|
if (ColgroupEl && FigureEl) return;
|
|
286
373
|
|
|
287
374
|
// create colgroup
|
|
288
375
|
if (!ColgroupEl) {
|
|
289
376
|
const maxCount = GetMaxColumns(element);
|
|
290
|
-
const colGroup =
|
|
377
|
+
const colGroup = dom.utils.createElement('colgroup', null, `<col style="width: ${numbers.get(100 / maxCount, CELL_DECIMAL_END)}%;">`.repeat(maxCount));
|
|
291
378
|
element.insertBefore(colGroup, element.firstElementChild);
|
|
292
379
|
}
|
|
293
380
|
|
|
294
381
|
// figure
|
|
295
382
|
if (!FigureEl) {
|
|
296
|
-
FigureEl =
|
|
383
|
+
FigureEl = dom.utils.createElement('FIGURE', { class: 'se-flex-component se-input-component' });
|
|
297
384
|
element.parentNode.insertBefore(FigureEl, element);
|
|
298
385
|
FigureEl.appendChild(element);
|
|
299
386
|
} else {
|
|
300
|
-
|
|
387
|
+
dom.utils.addClass(FigureEl, 'se-flex-component|se-input-component');
|
|
301
388
|
}
|
|
302
389
|
|
|
303
390
|
// scroll
|
|
304
391
|
if (!this.figureScroll) {
|
|
305
|
-
|
|
392
|
+
dom.utils.removeClass(FigureEl, this.figureScrollList.join('|'));
|
|
306
393
|
} else {
|
|
307
394
|
const scrollTypeClass = `se-scroll-figure-${this.figureScroll}`;
|
|
308
|
-
|
|
309
|
-
|
|
395
|
+
dom.utils.addClass(FigureEl, scrollTypeClass);
|
|
396
|
+
dom.utils.removeClass(FigureEl, this.figureScrollList.filter((v) => v !== scrollTypeClass).join('|'));
|
|
310
397
|
}
|
|
311
398
|
}
|
|
312
399
|
};
|
|
313
|
-
}
|
|
400
|
+
}
|
|
314
401
|
|
|
315
402
|
/**
|
|
316
|
-
* @
|
|
317
|
-
* @
|
|
403
|
+
* @editorMethod Editor.core
|
|
404
|
+
* @description Executes the method called when the rtl, ltr mode changes. ("editor.setDir")
|
|
405
|
+
* @param {string} dir Direction ("rtl" or "ltr")
|
|
318
406
|
*/
|
|
319
407
|
setDir(dir) {
|
|
320
408
|
this.tableHighlight.style.left = dir === 'rtl' ? 10 * 18 - 13 + 'px' : '';
|
|
321
409
|
this._resetTablePicker();
|
|
322
|
-
this._resetPropsAlign(
|
|
323
|
-
}
|
|
410
|
+
this._resetPropsAlign();
|
|
411
|
+
}
|
|
324
412
|
|
|
413
|
+
/**
|
|
414
|
+
* @editorMethod Editor.EventManager
|
|
415
|
+
* @description Executes the event function of "mousemove".
|
|
416
|
+
* @param {__se__PluginMouseEventInfo} params
|
|
417
|
+
*/
|
|
325
418
|
onMouseMove({ event }) {
|
|
326
419
|
if (this._resizing) return;
|
|
327
|
-
|
|
420
|
+
|
|
421
|
+
const eventTarget = dom.query.getEventTarget(event);
|
|
422
|
+
const target = dom.query.getParentElement(eventTarget, IsResizeEls);
|
|
328
423
|
if (!target || this._fixedCell) {
|
|
329
424
|
this.__hideResizeLine();
|
|
330
425
|
return;
|
|
@@ -336,7 +431,7 @@ Table.prototype = {
|
|
|
336
431
|
this.__removeGlobalEvents();
|
|
337
432
|
if (this._resizeLine?.style.display === 'block') this._resizeLine.style.display = 'none';
|
|
338
433
|
this._resizeLine = this.editor.frameContext.get('wrapper').querySelector(RESIZE_CELL_CLASS);
|
|
339
|
-
this._setResizeLinePosition(
|
|
434
|
+
this._setResizeLinePosition(dom.query.getParentElement(target, dom.check.isTable), target, this._resizeLine, cellEdge.isLeft);
|
|
340
435
|
this._resizeLine.style.display = 'block';
|
|
341
436
|
return;
|
|
342
437
|
}
|
|
@@ -344,33 +439,39 @@ Table.prototype = {
|
|
|
344
439
|
const rowEdge = CheckRowEdge(event, target);
|
|
345
440
|
if (rowEdge.is) {
|
|
346
441
|
this.__removeGlobalEvents();
|
|
347
|
-
this._element =
|
|
442
|
+
this._element = dom.query.getParentElement(target, dom.check.isTable);
|
|
348
443
|
this._element.style.cursor = 'ns-resize';
|
|
349
444
|
if (this._resizeLine?.style.display === 'block') this._resizeLine.style.display = 'none';
|
|
350
445
|
this._resizeLine = this.editor.frameContext.get('wrapper').querySelector(RESIZE_ROW_CLASS);
|
|
351
|
-
this._setResizeRowPosition(
|
|
446
|
+
this._setResizeRowPosition(dom.query.getParentElement(target, dom.check.isTable), target, this._resizeLine);
|
|
352
447
|
this._resizeLine.style.display = 'block';
|
|
353
448
|
return;
|
|
354
449
|
}
|
|
355
450
|
|
|
356
451
|
if (this._element) this._element.style.cursor = '';
|
|
357
452
|
this.__hideResizeLine();
|
|
358
|
-
}
|
|
453
|
+
}
|
|
359
454
|
|
|
455
|
+
/**
|
|
456
|
+
* @editorMethod Editor.EventManager
|
|
457
|
+
* @description Executes the event function of "scroll".
|
|
458
|
+
*/
|
|
360
459
|
onScroll() {
|
|
361
460
|
if (this._resizeLine?.style.display !== 'block') return;
|
|
362
461
|
// delete resize line position
|
|
363
462
|
if (this._element) this._element.style.cursor = '';
|
|
364
463
|
this._resizeLine.style.display = 'none';
|
|
365
|
-
}
|
|
464
|
+
}
|
|
366
465
|
|
|
367
466
|
/**
|
|
368
|
-
* @
|
|
369
|
-
* @
|
|
467
|
+
* @editorMethod Editor.EventManager
|
|
468
|
+
* @description Executes the event function of "mousedown".
|
|
469
|
+
* @param {__se__PluginMouseEventInfo} params
|
|
370
470
|
*/
|
|
371
471
|
onMouseDown({ event }) {
|
|
372
472
|
this._ref = null;
|
|
373
|
-
const
|
|
473
|
+
const eventTarget = dom.query.getEventTarget(event);
|
|
474
|
+
const target = /** @type {HTMLTableCellElement} */ (dom.query.getParentElement(eventTarget, IsResizeEls));
|
|
374
475
|
if (!target) return;
|
|
375
476
|
|
|
376
477
|
const cellEdge = CheckCellEdge(event, target);
|
|
@@ -381,7 +482,7 @@ Table.prototype = {
|
|
|
381
482
|
const colIndex = this._logical_cellIndex - (cellEdge.isLeft ? 1 : 0);
|
|
382
483
|
|
|
383
484
|
// ready
|
|
384
|
-
this.
|
|
485
|
+
this.ui.enableBackWrapper('ew-resize');
|
|
385
486
|
if (!this._resizeLine) this._resizeLine = this.editor.frameContext.get('wrapper').querySelector(RESIZE_CELL_CLASS);
|
|
386
487
|
this._resizeLinePrev = this.editor.frameContext.get('wrapper').querySelector(RESIZE_CELL_PREV_CLASS);
|
|
387
488
|
|
|
@@ -404,11 +505,12 @@ Table.prototype = {
|
|
|
404
505
|
const rowEdge = CheckRowEdge(event, target);
|
|
405
506
|
if (rowEdge.is) {
|
|
406
507
|
try {
|
|
407
|
-
|
|
508
|
+
/** @type {HTMLTableRowElement} */
|
|
509
|
+
let row = dom.query.getParentElement(target, dom.check.isTableRow);
|
|
408
510
|
let rowSpan = target.rowSpan;
|
|
409
511
|
if (rowSpan > 1) {
|
|
410
|
-
while (
|
|
411
|
-
row = row.nextElementSibling;
|
|
512
|
+
while (dom.check.isTableRow(row) && rowSpan > 1) {
|
|
513
|
+
row = /** @type {HTMLTableRowElement} */ (row.nextElementSibling);
|
|
412
514
|
--rowSpan;
|
|
413
515
|
}
|
|
414
516
|
}
|
|
@@ -417,7 +519,7 @@ Table.prototype = {
|
|
|
417
519
|
this.setRowInfo(row);
|
|
418
520
|
|
|
419
521
|
// ready
|
|
420
|
-
this.
|
|
522
|
+
this.ui.enableBackWrapper('ns-resize');
|
|
421
523
|
if (!this._resizeLine) this._resizeLine = this.editor.frameContext.get('wrapper').querySelector(RESIZE_ROW_CLASS);
|
|
422
524
|
this._resizeLinePrev = this.editor.frameContext.get('wrapper').querySelector(RESIZE_ROW_PREV_CLASS);
|
|
423
525
|
|
|
@@ -430,52 +532,56 @@ Table.prototype = {
|
|
|
430
532
|
return;
|
|
431
533
|
}
|
|
432
534
|
|
|
433
|
-
if (
|
|
535
|
+
if (this._shift && target !== this._fixedCell) return;
|
|
434
536
|
|
|
435
537
|
this._deleteStyleSelectedCells();
|
|
436
538
|
if (/^TR$/i.test(target.nodeName)) return;
|
|
437
539
|
|
|
438
540
|
this.selectCells(target, false);
|
|
439
|
-
}
|
|
541
|
+
}
|
|
440
542
|
|
|
441
543
|
/**
|
|
442
|
-
* @
|
|
544
|
+
* @editorMethod Editor.EventManager
|
|
545
|
+
* @description Executes the event function of "mouseup".
|
|
443
546
|
*/
|
|
444
547
|
onMouseUp() {
|
|
445
548
|
this._shift = false;
|
|
446
|
-
}
|
|
549
|
+
}
|
|
447
550
|
|
|
448
551
|
/**
|
|
449
|
-
* @
|
|
552
|
+
* @editorMethod Editor.EventManager
|
|
553
|
+
* @description Executes the event function of "mouseleave".
|
|
450
554
|
*/
|
|
451
555
|
onMouseLeave() {
|
|
452
556
|
this.__hideResizeLine();
|
|
453
|
-
}
|
|
557
|
+
}
|
|
454
558
|
|
|
455
559
|
/**
|
|
456
|
-
* @
|
|
457
|
-
* @
|
|
458
|
-
* @param {
|
|
459
|
-
* @param {Element} line Current line element
|
|
560
|
+
* @editorMethod Editor.EventManager
|
|
561
|
+
* @description Executes the event function of "keydown".
|
|
562
|
+
* @param {__se__PluginKeyEventInfo} params
|
|
460
563
|
*/
|
|
461
564
|
onKeyDown({ event, range, line }) {
|
|
462
565
|
this._ref = null;
|
|
463
|
-
if (this.editor.selectMenuOn || this._resizing) return;
|
|
566
|
+
if (this.editor.selectMenuOn || this._resizing || this.__s) return;
|
|
464
567
|
|
|
465
|
-
const keyCode = event.
|
|
568
|
+
const keyCode = event.code;
|
|
569
|
+
this.__s = event.shiftKey;
|
|
466
570
|
// table tabkey
|
|
467
|
-
if (keyCode
|
|
468
|
-
const tableCell =
|
|
469
|
-
if (tableCell && range.collapsed &&
|
|
571
|
+
if (keyCodeMap.isTab(keyCode)) {
|
|
572
|
+
const tableCell = dom.query.getParentElement(line, dom.check.isTableCell);
|
|
573
|
+
if (tableCell && range.collapsed && dom.check.isEdgePoint(range.startContainer, range.startOffset)) {
|
|
470
574
|
this._closeController();
|
|
471
575
|
|
|
472
576
|
const shift = event.shiftKey;
|
|
473
|
-
|
|
474
|
-
const
|
|
475
|
-
|
|
577
|
+
/** @type {HTMLTableElement} */
|
|
578
|
+
const table = dom.query.getParentElement(tableCell, 'table');
|
|
579
|
+
/** @type {HTMLTableCellElement[]} */
|
|
580
|
+
const cells = dom.query.getListChildren(table, dom.check.isTableCell);
|
|
581
|
+
const idx = shift ? dom.utils.prevIndex(cells, tableCell) : dom.utils.nextIndex(cells, tableCell);
|
|
476
582
|
|
|
477
583
|
if (idx === cells.length && !shift) {
|
|
478
|
-
if (!
|
|
584
|
+
if (!dom.query.getParentElement(tableCell, 'thead')) {
|
|
479
585
|
const rows = table.rows;
|
|
480
586
|
const newRow = this.insertBodyRow(table, rows.length, rows[rows.length - 1].cells.length);
|
|
481
587
|
const firstTd = newRow.querySelector('td div');
|
|
@@ -490,11 +596,11 @@ Table.prototype = {
|
|
|
490
596
|
|
|
491
597
|
if (idx === -1 && shift) return;
|
|
492
598
|
|
|
493
|
-
|
|
599
|
+
const moveCell = cells[idx];
|
|
494
600
|
if (!moveCell) return;
|
|
495
601
|
|
|
496
|
-
|
|
497
|
-
this.selection.setRange(
|
|
602
|
+
const rangeCell = moveCell.firstElementChild || moveCell;
|
|
603
|
+
this.selection.setRange(rangeCell, 0, rangeCell, 0);
|
|
498
604
|
|
|
499
605
|
event.preventDefault();
|
|
500
606
|
event.stopPropagation();
|
|
@@ -504,9 +610,9 @@ Table.prototype = {
|
|
|
504
610
|
}
|
|
505
611
|
|
|
506
612
|
let cell = null;
|
|
507
|
-
if (!event
|
|
508
|
-
cell =
|
|
509
|
-
if (!
|
|
613
|
+
if (!keyCodeMap.isShift(event)) {
|
|
614
|
+
cell = dom.query.getParentElement(line, dom.check.isTableCell);
|
|
615
|
+
if (!dom.utils.hasClass(cell, 'se-selected-cell-focus')) return;
|
|
510
616
|
|
|
511
617
|
this._deleteStyleSelectedCells();
|
|
512
618
|
this._toggleEditor(true);
|
|
@@ -518,43 +624,46 @@ Table.prototype = {
|
|
|
518
624
|
|
|
519
625
|
if (this._shift || this._ref) return;
|
|
520
626
|
|
|
521
|
-
cell = cell ||
|
|
627
|
+
cell = /** @type {HTMLTableCellElement} */ (cell || dom.query.getParentElement(line, dom.check.isTableCell));
|
|
522
628
|
if (cell) {
|
|
629
|
+
this.__s = false;
|
|
523
630
|
this._fixedCell = cell;
|
|
524
631
|
this._closeController();
|
|
525
632
|
this.selectCells(cell, event.shiftKey);
|
|
526
633
|
return false;
|
|
527
634
|
}
|
|
528
|
-
}
|
|
635
|
+
}
|
|
529
636
|
|
|
530
637
|
/**
|
|
531
|
-
* @
|
|
532
|
-
* @
|
|
533
|
-
* @param {
|
|
534
|
-
* @param {Element} line Current line element
|
|
638
|
+
* @editorMethod Editor.EventManager
|
|
639
|
+
* @description Executes the event function of "keyup".
|
|
640
|
+
* @param {__se__PluginKeyEventInfo} params
|
|
535
641
|
*/
|
|
536
642
|
onKeyUp({ line }) {
|
|
537
|
-
|
|
643
|
+
this.__s = false;
|
|
644
|
+
if (this._shift && dom.query.getParentElement(line, dom.check.isTableCell) === this._fixedCell) {
|
|
538
645
|
this._deleteStyleSelectedCells();
|
|
539
646
|
this._toggleEditor(true);
|
|
540
647
|
this.__removeGlobalEvents();
|
|
541
648
|
}
|
|
542
649
|
this._shift = false;
|
|
543
|
-
}
|
|
650
|
+
}
|
|
544
651
|
|
|
545
652
|
/**
|
|
546
|
-
* @
|
|
653
|
+
* @editorMethod Modules.ColorPicker
|
|
654
|
+
* @description Executes the method called when a button of "ColorPicker" module is clicked.
|
|
655
|
+
* @param {string} color - Color code (hex)
|
|
547
656
|
*/
|
|
548
657
|
colorPickerAction(color) {
|
|
549
658
|
const target = this.propTargets[`${this.sliderType}_color`];
|
|
550
659
|
target.style.borderColor = target.value = color;
|
|
551
660
|
this.controller_colorPicker.close();
|
|
552
|
-
}
|
|
661
|
+
}
|
|
553
662
|
|
|
554
663
|
/**
|
|
555
|
-
* @
|
|
556
|
-
* @
|
|
557
|
-
* @
|
|
664
|
+
* @editorMethod Modules.Controller
|
|
665
|
+
* @description Executes the method that is called when a button is clicked in the "controller".
|
|
666
|
+
* @param {HTMLButtonElement} target Target button element
|
|
558
667
|
*/
|
|
559
668
|
controllerAction(target) {
|
|
560
669
|
const command = target.getAttribute('data-command');
|
|
@@ -614,7 +723,7 @@ Table.prototype = {
|
|
|
614
723
|
this._onColorPalette(target, value, value === 'border' ? border_color : value === 'back' ? back_color : font_color);
|
|
615
724
|
break;
|
|
616
725
|
case 'props_font_style':
|
|
617
|
-
|
|
726
|
+
dom.utils.toggleClass(this.propTargets[`font_${value}`], 'on');
|
|
618
727
|
break;
|
|
619
728
|
case 'props_submit':
|
|
620
729
|
this._submitProps(target);
|
|
@@ -627,7 +736,7 @@ Table.prototype = {
|
|
|
627
736
|
// alignment
|
|
628
737
|
this._setAlignProps(this.propTargets.cell_alignment, this._propsAlignCache, true);
|
|
629
738
|
this._setAlignProps(this.propTargets.cell_alignment_vertical, this._propsVerticalAlignCache, true);
|
|
630
|
-
if (
|
|
739
|
+
if (dom.check.isTable(propsCache[0][0]) && this._figure) {
|
|
631
740
|
this._figure.style.float = this._propsAlignCache;
|
|
632
741
|
}
|
|
633
742
|
break;
|
|
@@ -646,19 +755,19 @@ Table.prototype = {
|
|
|
646
755
|
break;
|
|
647
756
|
case 'resize':
|
|
648
757
|
this._maxWidth = !this._maxWidth;
|
|
649
|
-
this.
|
|
758
|
+
this._setTableStyle('width', false);
|
|
650
759
|
this._historyPush();
|
|
651
760
|
this.component.select(this._element, Table.key, true);
|
|
652
761
|
break;
|
|
653
762
|
case 'layout':
|
|
654
763
|
this._fixedColumn = !this._fixedColumn;
|
|
655
|
-
this.
|
|
764
|
+
this._setTableStyle('column', false);
|
|
656
765
|
this._historyPush();
|
|
657
766
|
this.component.select(this._element, Table.key, true);
|
|
658
767
|
break;
|
|
659
768
|
case 'remove': {
|
|
660
769
|
const emptyDiv = this._figure?.parentNode;
|
|
661
|
-
|
|
770
|
+
dom.utils.removeItem(this._figure);
|
|
662
771
|
this._closeController();
|
|
663
772
|
|
|
664
773
|
if (emptyDiv !== this.editor.frameContext.get('wysiwyg'))
|
|
@@ -680,12 +789,13 @@ Table.prototype = {
|
|
|
680
789
|
}
|
|
681
790
|
|
|
682
791
|
if (!/^(remove|props_|on|open|merge)/.test(command)) {
|
|
683
|
-
this.
|
|
792
|
+
this._setCellControllerPosition(this._tdElement, this._shift);
|
|
684
793
|
}
|
|
685
|
-
}
|
|
794
|
+
}
|
|
686
795
|
|
|
687
796
|
/**
|
|
688
|
-
* @
|
|
797
|
+
* @editorMethod Modules.Controller
|
|
798
|
+
* @description Executes the method called when the "controller" is closed.
|
|
689
799
|
*/
|
|
690
800
|
close() {
|
|
691
801
|
this.__removeGlobalEvents();
|
|
@@ -719,19 +829,26 @@ Table.prototype = {
|
|
|
719
829
|
this._fixedCellName = null;
|
|
720
830
|
|
|
721
831
|
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
|
-
|
|
723
|
-
}
|
|
832
|
+
dom.utils.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');
|
|
833
|
+
}
|
|
724
834
|
|
|
835
|
+
/**
|
|
836
|
+
* @description Selects cells in a table, handling single and multi-cell selection, and managing shift key behavior for extended selection.
|
|
837
|
+
* @param {HTMLTableCellElement} tdElement The target table cell (`<td>`) element that is being selected.
|
|
838
|
+
* @param {boolean} shift A flag indicating whether the shift key is held down for multi-cell selection.
|
|
839
|
+
* If `true`, the selection will extend to include adjacent cells, otherwise it selects only the provided cell.
|
|
840
|
+
*/
|
|
725
841
|
selectCells(tdElement, shift) {
|
|
842
|
+
this.__s = shift;
|
|
726
843
|
if (!this._shift && !this._ref) this.__removeGlobalEvents();
|
|
727
844
|
|
|
728
845
|
this._shift = shift;
|
|
729
846
|
this._fixedCell = tdElement;
|
|
730
847
|
this._fixedCellName = tdElement.nodeName;
|
|
731
|
-
this._selectedTable =
|
|
848
|
+
this._selectedTable = dom.query.getParentElement(tdElement, 'TABLE');
|
|
732
849
|
|
|
733
850
|
this._deleteStyleSelectedCells();
|
|
734
|
-
|
|
851
|
+
dom.utils.addClass(tdElement, 'se-selected-cell-focus');
|
|
735
852
|
|
|
736
853
|
if (!shift) {
|
|
737
854
|
this.__globalEvents.on = this.eventManager.addGlobalEvent('mousemove', this._bindMultiOn, false);
|
|
@@ -742,30 +859,41 @@ Table.prototype = {
|
|
|
742
859
|
|
|
743
860
|
this.__globalEvents.off = this.eventManager.addGlobalEvent('mouseup', this._bindMultiOff, false);
|
|
744
861
|
this.__globalEvents.touchOff = this.eventManager.addGlobalEvent('touchmove', this._bindTouchOff, false);
|
|
745
|
-
}
|
|
862
|
+
}
|
|
746
863
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
864
|
+
/**
|
|
865
|
+
* @description Sets the table and figure elements based on the provided cell element, and stores references to them for later use.
|
|
866
|
+
* @param {Node} element The target table cell (`<td>`) element from which the table info will be extracted.
|
|
867
|
+
* @returns {HTMLTableElement} The `<table>` element that is the parent of the provided `element`.
|
|
868
|
+
*/
|
|
869
|
+
setTableInfo(element) {
|
|
870
|
+
const table = (this._element = this._selectedTable || dom.query.getParentElement(element, 'TABLE'));
|
|
871
|
+
this._figure = dom.query.getParentElement(table, dom.check.isFigure) || table;
|
|
872
|
+
return /** @type {HTMLTableElement} */ (table);
|
|
873
|
+
}
|
|
752
874
|
|
|
875
|
+
/**
|
|
876
|
+
* @description Sets various table-related information based on the provided table cell element (`<td>`). This includes updating cell, row, and table attributes, handling spanning cells, and adjusting the UI for elements like headers and captions.
|
|
877
|
+
* @param {HTMLTableCellElement} tdElement The target table cell (`<td>`) element from which table information will be extracted.
|
|
878
|
+
* @param {boolean} reset A flag indicating whether to reset the cell information. If `true`, the cell information will be reset and recalculated.
|
|
879
|
+
*/
|
|
753
880
|
setCellInfo(tdElement, reset) {
|
|
754
|
-
const table = this.
|
|
755
|
-
|
|
881
|
+
const table = this.setTableInfo(tdElement);
|
|
882
|
+
if (!table) return;
|
|
883
|
+
this._trElement = /** @type {HTMLTableRowElement} */ (tdElement.parentNode);
|
|
756
884
|
|
|
757
885
|
// hedaer
|
|
758
|
-
if (table.querySelector('thead'))
|
|
759
|
-
else
|
|
886
|
+
if (table.querySelector('thead')) dom.utils.addClass(this.headerButton, 'active');
|
|
887
|
+
else dom.utils.removeClass(this.headerButton, 'active');
|
|
760
888
|
|
|
761
889
|
// caption
|
|
762
|
-
if (table.querySelector('caption'))
|
|
763
|
-
else
|
|
890
|
+
if (table.querySelector('caption')) dom.utils.addClass(this.captionButton, 'active');
|
|
891
|
+
else dom.utils.removeClass(this.captionButton, 'active');
|
|
764
892
|
|
|
765
893
|
if (reset || this._physical_cellCnt === 0) {
|
|
766
894
|
if (this._tdElement !== tdElement) {
|
|
767
895
|
this._tdElement = tdElement;
|
|
768
|
-
this._trElement = tdElement.parentNode;
|
|
896
|
+
this._trElement = /** @type {HTMLTableRowElement} */ (tdElement.parentNode);
|
|
769
897
|
}
|
|
770
898
|
|
|
771
899
|
if (!this._selectedCells || this._selectedCells.length === 0) this._selectedCells = [tdElement];
|
|
@@ -854,30 +982,39 @@ Table.prototype = {
|
|
|
854
982
|
rowSpanArr = null;
|
|
855
983
|
spanIndex = null;
|
|
856
984
|
}
|
|
857
|
-
}
|
|
985
|
+
}
|
|
858
986
|
|
|
987
|
+
/**
|
|
988
|
+
* @description Sets row-related information based on the provided table row element (`<tr>`). This includes updating the row count and the index of the selected row.
|
|
989
|
+
* @param {HTMLTableRowElement} trElement The target table row (`<tr>`) element from which row information will be extracted.
|
|
990
|
+
*/
|
|
859
991
|
setRowInfo(trElement) {
|
|
860
|
-
const table = this.
|
|
992
|
+
const table = this.setTableInfo(trElement);
|
|
861
993
|
const rows = (this._trElements = table.rows);
|
|
862
994
|
this._rowCnt = rows.length;
|
|
863
995
|
this._rowIndex = trElement.rowIndex;
|
|
864
|
-
}
|
|
996
|
+
}
|
|
865
997
|
|
|
998
|
+
/**
|
|
999
|
+
* @description Edits the table by adding, removing, or modifying rows and cells, based on the provided options. Supports both single and multi-cell/row editing.
|
|
1000
|
+
* @param {"row"|"cell"} type The type of element to edit ('row' or 'cell').
|
|
1001
|
+
* @param {?"up"|"down"|"left"|"right"} option The action to perform: 'up', 'down', 'left', 'right', or `null` for removing.
|
|
1002
|
+
*/
|
|
866
1003
|
editTable(type, option) {
|
|
867
1004
|
const table = this._element;
|
|
868
1005
|
const isRow = type === 'row';
|
|
869
1006
|
|
|
870
1007
|
if (isRow) {
|
|
871
|
-
const tableAttr = this._trElement.
|
|
1008
|
+
const tableAttr = this._trElement.parentElement;
|
|
872
1009
|
if (/^THEAD$/i.test(tableAttr.nodeName)) {
|
|
873
1010
|
if (option === 'up') {
|
|
874
1011
|
return;
|
|
875
1012
|
} else if (!tableAttr.nextElementSibling || !/^TBODY$/i.test(tableAttr.nextElementSibling.nodeName)) {
|
|
876
1013
|
if (!option) {
|
|
877
|
-
|
|
1014
|
+
dom.utils.removeItem(this._figure);
|
|
878
1015
|
this._closeController();
|
|
879
1016
|
} else {
|
|
880
|
-
table.innerHTML += '<tbody><tr>' +
|
|
1017
|
+
table.innerHTML += '<tbody><tr>' + CreateCellsString('td', this._logical_cellCnt) + '</tr></tbody>';
|
|
881
1018
|
}
|
|
882
1019
|
return;
|
|
883
1020
|
}
|
|
@@ -959,16 +1096,26 @@ Table.prototype = {
|
|
|
959
1096
|
const children = table.children;
|
|
960
1097
|
for (let i = 0; i < children.length; i++) {
|
|
961
1098
|
if (children[i].children.length === 0) {
|
|
962
|
-
|
|
1099
|
+
dom.utils.removeItem(children[i]);
|
|
963
1100
|
i--;
|
|
964
1101
|
}
|
|
965
1102
|
}
|
|
966
1103
|
|
|
967
|
-
if (table.children.length === 0)
|
|
1104
|
+
if (table.children.length === 0) dom.utils.removeItem(table);
|
|
968
1105
|
}
|
|
969
|
-
}
|
|
1106
|
+
}
|
|
970
1107
|
|
|
1108
|
+
/**
|
|
1109
|
+
* @description Edits a table row, either adding, removing, the row
|
|
1110
|
+
* @param {?string} option The action to perform on the row ("up"|"down"|null)
|
|
1111
|
+
* - null: to remove the row
|
|
1112
|
+
* - 'up': to insert the row up
|
|
1113
|
+
* - 'down': to insert the row down, or null to remove.
|
|
1114
|
+
* @param {?HTMLTableCellElement=} [positionResetElement] The element to reset the position of (optional). This can be the cell that triggered the row edit.
|
|
1115
|
+
*/
|
|
971
1116
|
editRow(option, positionResetElement) {
|
|
1117
|
+
this._deleteStyleSelectedCells();
|
|
1118
|
+
|
|
972
1119
|
const remove = !option;
|
|
973
1120
|
const up = option === 'up';
|
|
974
1121
|
const originRowIndex = this._rowIndex;
|
|
@@ -1008,7 +1155,7 @@ Table.prototype = {
|
|
|
1008
1155
|
|
|
1009
1156
|
if (cell.rowSpan > 1) {
|
|
1010
1157
|
cell.rowSpan -= 1;
|
|
1011
|
-
spanCells.push({ cell: cell.cloneNode(false), index: logcalIndex });
|
|
1158
|
+
spanCells.push({ cell: /** @type {HTMLTableCellElement} */ (cell.cloneNode(false)), index: logcalIndex });
|
|
1012
1159
|
}
|
|
1013
1160
|
}
|
|
1014
1161
|
|
|
@@ -1047,12 +1194,20 @@ Table.prototype = {
|
|
|
1047
1194
|
}
|
|
1048
1195
|
|
|
1049
1196
|
if (!remove) {
|
|
1050
|
-
this.
|
|
1197
|
+
this._setCellControllerPosition(positionResetElement || this._tdElement, true);
|
|
1051
1198
|
} else {
|
|
1052
1199
|
this._closeController();
|
|
1053
1200
|
}
|
|
1054
|
-
}
|
|
1201
|
+
}
|
|
1055
1202
|
|
|
1203
|
+
/**
|
|
1204
|
+
* @description Edits a table cell(column), either adding, removing, or modifying the cell based on the provided option.
|
|
1205
|
+
* @param {?string} option The action to perform on the cell ("left"|"right"|null)
|
|
1206
|
+
* - null: to remove the cell
|
|
1207
|
+
* - left: to insert a new cell to the left
|
|
1208
|
+
* - right: to insert a new cell to the right
|
|
1209
|
+
* @param {?HTMLTableCellElement=} [positionResetElement] The element to reset the position of (optional). This can be the cell that triggered the column edit.
|
|
1210
|
+
*/
|
|
1056
1211
|
editCell(option, positionResetElement) {
|
|
1057
1212
|
const remove = !option;
|
|
1058
1213
|
const left = option === 'left';
|
|
@@ -1172,7 +1327,7 @@ Table.prototype = {
|
|
|
1172
1327
|
}
|
|
1173
1328
|
|
|
1174
1329
|
if (insertIndex !== null && cells.length > 0) {
|
|
1175
|
-
newCell =
|
|
1330
|
+
newCell = CreateCellsHTML(cells[0].nodeName);
|
|
1176
1331
|
newCell = row.insertBefore(newCell, cells[insertIndex]);
|
|
1177
1332
|
}
|
|
1178
1333
|
}
|
|
@@ -1182,16 +1337,16 @@ Table.prototype = {
|
|
|
1182
1337
|
if (colgroup) {
|
|
1183
1338
|
const cols = colgroup.querySelectorAll('col');
|
|
1184
1339
|
if (remove) {
|
|
1185
|
-
|
|
1340
|
+
dom.utils.removeItem(cols[insertIndex]);
|
|
1186
1341
|
} else {
|
|
1187
1342
|
let totalW = 0;
|
|
1188
1343
|
for (let i = 0, len = cols.length, w; i < len; i++) {
|
|
1189
1344
|
w = numbers.get(cols[i].style.width);
|
|
1190
|
-
w -= Math.round((w * len * 0.1) / 2
|
|
1345
|
+
w -= Math.round((w * len * 0.1) / 2);
|
|
1191
1346
|
totalW += w;
|
|
1192
1347
|
cols[i].style.width = `${w}%`;
|
|
1193
1348
|
}
|
|
1194
|
-
const newCol =
|
|
1349
|
+
const newCol = dom.utils.createElement('col', { style: `width:${100 - totalW}%` });
|
|
1195
1350
|
colgroup.insertBefore(newCol, cols[insertIndex]);
|
|
1196
1351
|
}
|
|
1197
1352
|
}
|
|
@@ -1199,12 +1354,12 @@ Table.prototype = {
|
|
|
1199
1354
|
if (remove) {
|
|
1200
1355
|
let removeFirst, removeEnd;
|
|
1201
1356
|
for (let r = 0, rLen = removeCell.length, row; r < rLen; r++) {
|
|
1202
|
-
row = removeCell[r].parentNode;
|
|
1203
|
-
|
|
1357
|
+
row = /** @type {HTMLTableRowElement} */ (removeCell[r].parentNode);
|
|
1358
|
+
dom.utils.removeItem(removeCell[r]);
|
|
1204
1359
|
if (row.cells.length === 0) {
|
|
1205
|
-
if (!removeFirst) removeFirst =
|
|
1206
|
-
removeEnd =
|
|
1207
|
-
|
|
1360
|
+
if (!removeFirst) removeFirst = dom.utils.getArrayIndex(rows, row);
|
|
1361
|
+
removeEnd = dom.utils.getArrayIndex(rows, row);
|
|
1362
|
+
dom.utils.removeItem(row);
|
|
1208
1363
|
}
|
|
1209
1364
|
}
|
|
1210
1365
|
|
|
@@ -1215,16 +1370,27 @@ Table.prototype = {
|
|
|
1215
1370
|
|
|
1216
1371
|
this._closeController();
|
|
1217
1372
|
} else {
|
|
1218
|
-
this.
|
|
1373
|
+
this._setCellControllerPosition(positionResetElement || this._tdElement, true);
|
|
1219
1374
|
}
|
|
1220
|
-
}
|
|
1375
|
+
}
|
|
1221
1376
|
|
|
1377
|
+
/**
|
|
1378
|
+
* @description Inserts a new row into the table at the specified index to it.
|
|
1379
|
+
* @param {HTMLTableElement} table The table element to insert the row into.
|
|
1380
|
+
* @param {number} rowIndex The index at which to insert the new row.
|
|
1381
|
+
* @param {number} cellCnt The number of cells to create in the new row.
|
|
1382
|
+
* @returns {HTMLTableRowElement} The newly inserted row element.
|
|
1383
|
+
*/
|
|
1222
1384
|
insertBodyRow(table, rowIndex, cellCnt) {
|
|
1223
1385
|
const newRow = table.insertRow(rowIndex);
|
|
1224
|
-
newRow.innerHTML =
|
|
1386
|
+
newRow.innerHTML = CreateCellsString('td', cellCnt);
|
|
1225
1387
|
return newRow;
|
|
1226
|
-
}
|
|
1388
|
+
}
|
|
1227
1389
|
|
|
1390
|
+
/**
|
|
1391
|
+
* @description Merges the selected table cells into one cell by combining their contents and adjusting their row and column spans.
|
|
1392
|
+
* - This method removes the selected cells, consolidates their contents, and applies the appropriate row and column spans to the merged cell.
|
|
1393
|
+
*/
|
|
1228
1394
|
mergeCells() {
|
|
1229
1395
|
const ref = this._ref;
|
|
1230
1396
|
const selectedCells = this._selectedCells;
|
|
@@ -1239,17 +1405,17 @@ Table.prototype = {
|
|
|
1239
1405
|
|
|
1240
1406
|
for (let i = 1, len = selectedCells.length, cell, ch; i < len; i++) {
|
|
1241
1407
|
cell = selectedCells[i];
|
|
1242
|
-
if (row !== cell.parentNode) row = cell.parentNode;
|
|
1408
|
+
if (row !== cell.parentNode) row = /** @type {HTMLTableRowElement} */ (cell.parentNode);
|
|
1243
1409
|
|
|
1244
1410
|
ch = cell.children;
|
|
1245
1411
|
for (let c = 0, cLen = ch.length; c < cLen; c++) {
|
|
1246
|
-
if (this.format.isLine(ch[c]) &&
|
|
1247
|
-
|
|
1412
|
+
if (this.format.isLine(ch[c]) && dom.check.isZeroWidth(ch[c].textContent)) {
|
|
1413
|
+
dom.utils.removeItem(ch[c]);
|
|
1248
1414
|
}
|
|
1249
1415
|
}
|
|
1250
1416
|
|
|
1251
1417
|
mergeHTML += cell.innerHTML;
|
|
1252
|
-
|
|
1418
|
+
dom.utils.removeItem(cell);
|
|
1253
1419
|
|
|
1254
1420
|
if (row.cells.length === 0) {
|
|
1255
1421
|
if (!emptyRowFirst) emptyRowFirst = row;
|
|
@@ -1260,8 +1426,8 @@ Table.prototype = {
|
|
|
1260
1426
|
|
|
1261
1427
|
if (emptyRowFirst) {
|
|
1262
1428
|
const rows = this._trElements;
|
|
1263
|
-
const rowIndexFirst =
|
|
1264
|
-
const rowIndexLast =
|
|
1429
|
+
const rowIndexFirst = dom.utils.getArrayIndex(rows, emptyRowFirst);
|
|
1430
|
+
const rowIndexLast = dom.utils.getArrayIndex(rows, emptyRowLast || emptyRowFirst);
|
|
1265
1431
|
const removeRows = [];
|
|
1266
1432
|
|
|
1267
1433
|
for (let i = 0, cells; i <= rowIndexLast; i++) {
|
|
@@ -1281,7 +1447,7 @@ Table.prototype = {
|
|
|
1281
1447
|
}
|
|
1282
1448
|
|
|
1283
1449
|
for (let i = 0, len = removeRows.length; i < len; i++) {
|
|
1284
|
-
|
|
1450
|
+
dom.utils.removeItem(removeRows[i]);
|
|
1285
1451
|
}
|
|
1286
1452
|
}
|
|
1287
1453
|
|
|
@@ -1289,53 +1455,65 @@ Table.prototype = {
|
|
|
1289
1455
|
mergeCell.colSpan = cs;
|
|
1290
1456
|
mergeCell.rowSpan = rs;
|
|
1291
1457
|
|
|
1292
|
-
this.
|
|
1293
|
-
this.
|
|
1458
|
+
this._setMergeSplitButton(true, false);
|
|
1459
|
+
this._setController(mergeCell);
|
|
1294
1460
|
|
|
1295
1461
|
this.editor.focusEdge(mergeCell);
|
|
1296
1462
|
this._historyPush();
|
|
1297
|
-
}
|
|
1463
|
+
}
|
|
1298
1464
|
|
|
1465
|
+
/**
|
|
1466
|
+
* @description Toggles the visibility of the table header (`<thead>`). If the header is present, it is removed; if absent, it is added.
|
|
1467
|
+
*/
|
|
1299
1468
|
toggleHeader() {
|
|
1300
1469
|
const btn = this.headerButton;
|
|
1301
|
-
const active =
|
|
1470
|
+
const active = dom.utils.hasClass(btn, 'active');
|
|
1302
1471
|
const table = this._element;
|
|
1303
1472
|
|
|
1304
1473
|
if (!active) {
|
|
1305
|
-
const header =
|
|
1306
|
-
header.innerHTML = '<tr>' +
|
|
1474
|
+
const header = dom.utils.createElement('THEAD');
|
|
1475
|
+
header.innerHTML = '<tr>' + CreateCellsString('th', this._logical_cellCnt) + '</tr>';
|
|
1307
1476
|
table.insertBefore(header, table.firstElementChild);
|
|
1308
1477
|
} else {
|
|
1309
|
-
|
|
1478
|
+
dom.utils.removeItem(table.querySelector('thead'));
|
|
1310
1479
|
}
|
|
1311
1480
|
|
|
1312
|
-
|
|
1481
|
+
dom.utils.toggleClass(btn, 'active');
|
|
1313
1482
|
|
|
1314
1483
|
if (/TH/i.test(this._tdElement.nodeName)) {
|
|
1315
1484
|
this._closeController();
|
|
1316
1485
|
} else {
|
|
1317
|
-
this.
|
|
1486
|
+
this._setCellControllerPosition(this._tdElement, false);
|
|
1318
1487
|
}
|
|
1319
|
-
}
|
|
1488
|
+
}
|
|
1320
1489
|
|
|
1490
|
+
/**
|
|
1491
|
+
* @description Toggles the visibility of the table caption (`<caption>`). If the caption is present, it is removed; if absent, it is added.
|
|
1492
|
+
*/
|
|
1321
1493
|
toggleCaption() {
|
|
1322
1494
|
const btn = this.captionButton;
|
|
1323
|
-
const active =
|
|
1495
|
+
const active = dom.utils.hasClass(btn, 'active');
|
|
1324
1496
|
const table = this._element;
|
|
1325
1497
|
|
|
1326
1498
|
if (!active) {
|
|
1327
|
-
const caption =
|
|
1499
|
+
const caption = dom.utils.createElement('CAPTION', { class: `se-table-caption-${this.captionPosition}` });
|
|
1328
1500
|
caption.innerHTML = '<div><br></div>';
|
|
1329
1501
|
table.insertBefore(caption, table.firstElementChild);
|
|
1330
1502
|
} else {
|
|
1331
|
-
|
|
1503
|
+
dom.utils.removeItem(table.querySelector('caption'));
|
|
1332
1504
|
}
|
|
1333
1505
|
|
|
1334
|
-
|
|
1335
|
-
this.
|
|
1336
|
-
}
|
|
1506
|
+
dom.utils.toggleClass(btn, 'active');
|
|
1507
|
+
this._setCellControllerPosition(this._tdElement, false);
|
|
1508
|
+
}
|
|
1337
1509
|
|
|
1338
|
-
|
|
1510
|
+
/**
|
|
1511
|
+
* @private
|
|
1512
|
+
* @description Updates table styles.
|
|
1513
|
+
* @param {string} styles - Styles to update.
|
|
1514
|
+
* @param {boolean} ondisplay - Whether to update display.
|
|
1515
|
+
*/
|
|
1516
|
+
_setTableStyle(styles, ondisplay) {
|
|
1339
1517
|
if (styles.includes('width')) {
|
|
1340
1518
|
const targets = this._figure;
|
|
1341
1519
|
if (!targets) return;
|
|
@@ -1351,24 +1529,30 @@ Table.prototype = {
|
|
|
1351
1529
|
if (!ondisplay) targets.style.width = '100%';
|
|
1352
1530
|
}
|
|
1353
1531
|
|
|
1354
|
-
|
|
1355
|
-
|
|
1532
|
+
dom.utils.changeElement(this.resizeButton.firstElementChild, sizeIcon);
|
|
1533
|
+
dom.utils.changeTxt(this.resizeText, text);
|
|
1356
1534
|
}
|
|
1357
1535
|
|
|
1358
1536
|
if (styles.includes('column')) {
|
|
1359
1537
|
if (!this._fixedColumn) {
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1538
|
+
dom.utils.removeClass(this._element, 'se-table-layout-fixed');
|
|
1539
|
+
dom.utils.addClass(this._element, 'se-table-layout-auto');
|
|
1540
|
+
dom.utils.removeClass(this.columnFixedButton, 'active');
|
|
1363
1541
|
} else {
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1542
|
+
dom.utils.removeClass(this._element, 'se-table-layout-auto');
|
|
1543
|
+
dom.utils.addClass(this._element, 'se-table-layout-fixed');
|
|
1544
|
+
dom.utils.addClass(this.columnFixedButton, 'active');
|
|
1367
1545
|
}
|
|
1368
1546
|
}
|
|
1369
|
-
}
|
|
1547
|
+
}
|
|
1370
1548
|
|
|
1371
|
-
|
|
1549
|
+
/**
|
|
1550
|
+
* @private
|
|
1551
|
+
* @description Sets the merge/split button visibility.
|
|
1552
|
+
* @param {boolean} fixedCell - Whether a single cell is selected.
|
|
1553
|
+
* @param {boolean} selectedCell - Whether multiple cells are selected.
|
|
1554
|
+
*/
|
|
1555
|
+
_setMergeSplitButton(fixedCell, selectedCell) {
|
|
1372
1556
|
if (!selectedCell || !selectedCell || fixedCell === selectedCell) {
|
|
1373
1557
|
this.splitButton.style.display = 'block';
|
|
1374
1558
|
this.mergeButton.style.display = 'none';
|
|
@@ -1376,67 +1560,70 @@ Table.prototype = {
|
|
|
1376
1560
|
this.splitButton.style.display = 'none';
|
|
1377
1561
|
this.mergeButton.style.display = 'block';
|
|
1378
1562
|
}
|
|
1379
|
-
}
|
|
1563
|
+
}
|
|
1380
1564
|
|
|
1381
1565
|
/**
|
|
1382
|
-
* @
|
|
1383
|
-
* @
|
|
1566
|
+
* @private
|
|
1567
|
+
* @description Sets the controller position for a cell.
|
|
1568
|
+
* @param {HTMLTableCellElement} tdElement - The target table cell.
|
|
1384
1569
|
*/
|
|
1385
|
-
|
|
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) {
|
|
1570
|
+
_setController(tdElement) {
|
|
1407
1571
|
if (!this.selection.get().isCollapsed && !this._selectedCell) {
|
|
1408
1572
|
this._deleteStyleSelectedCells();
|
|
1409
1573
|
return;
|
|
1410
1574
|
}
|
|
1411
1575
|
|
|
1412
1576
|
this._tdElement = tdElement;
|
|
1413
|
-
|
|
1414
|
-
const tableElement = this._element || this._selectedTable ||
|
|
1577
|
+
dom.utils.addClass(tdElement, 'se-selected-cell-focus');
|
|
1578
|
+
const tableElement = this._element || this._selectedTable || dom.query.getParentElement(tdElement, 'TABLE');
|
|
1415
1579
|
this.component.select(tableElement, Table.key, true);
|
|
1416
|
-
}
|
|
1580
|
+
}
|
|
1417
1581
|
|
|
1418
|
-
|
|
1582
|
+
/**
|
|
1583
|
+
* @private
|
|
1584
|
+
* @description Sets the position of the cell controller.
|
|
1585
|
+
* @param {HTMLTableCellElement} tdElement - The target table cell.
|
|
1586
|
+
* @param {boolean} reset - Whether to reset the controller position.
|
|
1587
|
+
*/
|
|
1588
|
+
_setCellControllerPosition(tdElement, reset) {
|
|
1419
1589
|
this.setCellInfo(tdElement, reset);
|
|
1420
|
-
this.controller_cell.resetPosition(this.cellControllerTop ?
|
|
1421
|
-
}
|
|
1590
|
+
this.controller_cell.resetPosition(this.cellControllerTop ? dom.query.getParentElement(tdElement, dom.check.isTable) : tdElement);
|
|
1591
|
+
}
|
|
1422
1592
|
|
|
1593
|
+
/**
|
|
1594
|
+
* @private
|
|
1595
|
+
* @description Adds a new entry to the history stack.
|
|
1596
|
+
*/
|
|
1423
1597
|
_historyPush() {
|
|
1424
1598
|
this._deleteStyleSelectedCells();
|
|
1425
1599
|
this.history.push(false);
|
|
1426
1600
|
this._recallStyleSelectedCells();
|
|
1427
|
-
}
|
|
1601
|
+
}
|
|
1428
1602
|
|
|
1603
|
+
/**
|
|
1604
|
+
* @private
|
|
1605
|
+
* @description Opens the figure.
|
|
1606
|
+
* @param {Node} target - The target figure element.
|
|
1607
|
+
*/
|
|
1429
1608
|
_figureOpen(target) {
|
|
1430
1609
|
this.figure.open(target, { nonResizing: true, nonSizeInfo: true, nonBorder: true, figureTarget: true, __fileManagerInfo: false });
|
|
1431
|
-
}
|
|
1610
|
+
}
|
|
1432
1611
|
|
|
1612
|
+
/**
|
|
1613
|
+
* @private
|
|
1614
|
+
* @description Starts resizing a table cell.
|
|
1615
|
+
* @param {HTMLElement} col The column element.
|
|
1616
|
+
* @param {number} startX The starting X position.
|
|
1617
|
+
* @param {number} startWidth The initial width of the column.
|
|
1618
|
+
* @param {boolean} isLeftEdge Whether the resizing is on the left edge.
|
|
1619
|
+
*/
|
|
1433
1620
|
_startCellResizing(col, startX, startWidth, isLeftEdge) {
|
|
1434
1621
|
this._setResizeLinePosition(this._figure, this._tdElement, this._resizeLinePrev, isLeftEdge);
|
|
1435
1622
|
this._resizeLinePrev.style.display = 'block';
|
|
1436
1623
|
const prevValue = col.style.width;
|
|
1437
|
-
const nextCol = col.nextElementSibling;
|
|
1624
|
+
const nextCol = /** @type {HTMLElement} */ (col.nextElementSibling);
|
|
1438
1625
|
const nextColPrevValue = nextCol.style.width;
|
|
1439
|
-
const realWidth =
|
|
1626
|
+
const realWidth = dom.utils.hasClass(this._element, 'se-table-layout-fixed') ? nextColPrevValue : converter.getWidthInPercentage(col);
|
|
1440
1627
|
|
|
1441
1628
|
if (_DragHandle.get('__dragHandler')) _DragHandle.get('__dragHandler').style.display = 'none';
|
|
1442
1629
|
this._addResizeGlobalEvents(
|
|
@@ -1465,8 +1652,24 @@ Table.prototype = {
|
|
|
1465
1652
|
this._stopResize(nextCol, nextColPrevValue, 'width', e);
|
|
1466
1653
|
}
|
|
1467
1654
|
);
|
|
1468
|
-
}
|
|
1655
|
+
}
|
|
1469
1656
|
|
|
1657
|
+
/**
|
|
1658
|
+
* @private
|
|
1659
|
+
* @description Resizes a table cell.
|
|
1660
|
+
* @param {HTMLElement} col The column element.
|
|
1661
|
+
* @param {HTMLElement} nextCol The next column element.
|
|
1662
|
+
* @param {HTMLElement} figure The table figure element.
|
|
1663
|
+
* @param {HTMLElement} tdEl The table cell element.
|
|
1664
|
+
* @param {HTMLElement} resizeLine The resize line element.
|
|
1665
|
+
* @param {boolean} isLeftEdge Whether the resizing is on the left edge.
|
|
1666
|
+
* @param {number} startX The starting X position.
|
|
1667
|
+
* @param {number} startWidth The initial width of the column.
|
|
1668
|
+
* @param {number} prevWidthPercent The previous width percentage.
|
|
1669
|
+
* @param {number} nextColWidthPercent The next column's width percentage.
|
|
1670
|
+
* @param {number} tableWidth The total width of the table.
|
|
1671
|
+
* @param {MouseEvent} e The mouse event.
|
|
1672
|
+
*/
|
|
1470
1673
|
_cellResize(col, nextCol, figure, tdEl, resizeLine, isLeftEdge, startX, startWidth, prevWidthPercent, nextColWidthPercent, tableWidth, e) {
|
|
1471
1674
|
const deltaX = e.clientX - startX;
|
|
1472
1675
|
const newWidthPx = startWidth + deltaX;
|
|
@@ -1478,8 +1681,15 @@ Table.prototype = {
|
|
|
1478
1681
|
nextCol.style.width = `${nextColWidthPercent + delta}%`;
|
|
1479
1682
|
this._setResizeLinePosition(figure, tdEl, resizeLine, isLeftEdge);
|
|
1480
1683
|
}
|
|
1481
|
-
}
|
|
1684
|
+
}
|
|
1482
1685
|
|
|
1686
|
+
/**
|
|
1687
|
+
* @private
|
|
1688
|
+
* @description Starts resizing a table row.
|
|
1689
|
+
* @param {HTMLElement} row The table row element.
|
|
1690
|
+
* @param {number} startY The starting Y position.
|
|
1691
|
+
* @param {number} startHeight The initial height of the row.
|
|
1692
|
+
*/
|
|
1483
1693
|
_startRowResizing(row, startY, startHeight) {
|
|
1484
1694
|
this._setResizeRowPosition(this._figure, row, this._resizeLinePrev);
|
|
1485
1695
|
this._resizeLinePrev.style.display = 'block';
|
|
@@ -1488,20 +1698,36 @@ Table.prototype = {
|
|
|
1488
1698
|
this._addResizeGlobalEvents(
|
|
1489
1699
|
this._rowResize.bind(this, row, this._figure, this._resizeLine, startY, startHeight),
|
|
1490
1700
|
() => {
|
|
1491
|
-
this.__removeGlobalEvents(
|
|
1701
|
+
this.__removeGlobalEvents();
|
|
1492
1702
|
this.history.push(true);
|
|
1493
1703
|
},
|
|
1494
1704
|
this._stopResize.bind(this, row, prevValue, 'height')
|
|
1495
1705
|
);
|
|
1496
|
-
}
|
|
1706
|
+
}
|
|
1497
1707
|
|
|
1708
|
+
/**
|
|
1709
|
+
* @private
|
|
1710
|
+
* @description Resizes a table row.
|
|
1711
|
+
* @param {HTMLElement} row The table row element.
|
|
1712
|
+
* @param {HTMLElement} figure The table figure element.
|
|
1713
|
+
* @param {HTMLElement} resizeLine The resize line element.
|
|
1714
|
+
* @param {number} startY The starting Y position.
|
|
1715
|
+
* @param {number} startHeight The initial height of the row.
|
|
1716
|
+
* @param {MouseEvent} e The mouse event.
|
|
1717
|
+
*/
|
|
1498
1718
|
_rowResize(row, figure, resizeLine, startY, startHeight, e) {
|
|
1499
1719
|
const deltaY = e.clientY - startY;
|
|
1500
1720
|
const newHeightPx = startHeight + deltaY;
|
|
1501
1721
|
row.style.height = `${newHeightPx}px`;
|
|
1502
1722
|
this._setResizeRowPosition(figure, row, resizeLine);
|
|
1503
|
-
}
|
|
1723
|
+
}
|
|
1504
1724
|
|
|
1725
|
+
/**
|
|
1726
|
+
* @private
|
|
1727
|
+
* @description Starts resizing the table figure.
|
|
1728
|
+
* @param {number} startX The starting X position.
|
|
1729
|
+
* @param {boolean} isLeftEdge Whether the resizing is on the left edge.
|
|
1730
|
+
*/
|
|
1505
1731
|
_startFigureResizing(startX, isLeftEdge) {
|
|
1506
1732
|
const figure = this._figure;
|
|
1507
1733
|
this._setResizeLinePosition(figure, figure, this._resizeLinePrev, isLeftEdge);
|
|
@@ -1518,8 +1744,19 @@ Table.prototype = {
|
|
|
1518
1744
|
},
|
|
1519
1745
|
this._stopResize.bind(this, figure, figure.style.width, 'width')
|
|
1520
1746
|
);
|
|
1521
|
-
}
|
|
1747
|
+
}
|
|
1522
1748
|
|
|
1749
|
+
/**
|
|
1750
|
+
* @private
|
|
1751
|
+
* @description Resizes the table figure.
|
|
1752
|
+
* @param {HTMLElement} figure The table figure element.
|
|
1753
|
+
* @param {HTMLElement} resizeLine The resize line element.
|
|
1754
|
+
* @param {boolean} isLeftEdge Whether the resizing is on the left edge.
|
|
1755
|
+
* @param {number} startX The starting X position.
|
|
1756
|
+
* @param {number} startWidth The initial width of the figure.
|
|
1757
|
+
* @param {number} constNum A constant number used for width calculation.
|
|
1758
|
+
* @param {MouseEvent} e The mouse event.
|
|
1759
|
+
*/
|
|
1523
1760
|
_figureResize(figure, resizeLine, isLeftEdge, startX, startWidth, constNum, e) {
|
|
1524
1761
|
const deltaX = isLeftEdge ? startX - e.clientX : e.clientX - startX;
|
|
1525
1762
|
const newWidthPx = startWidth + deltaX;
|
|
@@ -1529,78 +1766,126 @@ Table.prototype = {
|
|
|
1529
1766
|
figure.style.width = `${newWidthPercent}%`;
|
|
1530
1767
|
this._setResizeLinePosition(figure, figure, resizeLine, isLeftEdge);
|
|
1531
1768
|
}
|
|
1532
|
-
}
|
|
1769
|
+
}
|
|
1533
1770
|
|
|
1771
|
+
/**
|
|
1772
|
+
* @private
|
|
1773
|
+
* @description Sets the resize line position.
|
|
1774
|
+
* @param {HTMLElement} figure The table figure element.
|
|
1775
|
+
* @param {HTMLElement} target The target element.
|
|
1776
|
+
* @param {HTMLElement} resizeLine The resize line element.
|
|
1777
|
+
* @param {boolean} isLeftEdge Whether the resizing is on the left edge.
|
|
1778
|
+
*/
|
|
1534
1779
|
_setResizeLinePosition(figure, target, resizeLine, isLeftEdge) {
|
|
1535
|
-
const tdOffset = this.offset.
|
|
1536
|
-
const tableOffset = this.offset.
|
|
1780
|
+
const tdOffset = this.offset.getLocal(target);
|
|
1781
|
+
const tableOffset = this.offset.getLocal(figure);
|
|
1537
1782
|
resizeLine.style.left = `${tdOffset.left + (isLeftEdge ? 0 : target.offsetWidth)}px`;
|
|
1538
1783
|
resizeLine.style.top = `${tableOffset.top}px`;
|
|
1539
1784
|
resizeLine.style.height = `${figure.offsetHeight}px`;
|
|
1540
|
-
}
|
|
1785
|
+
}
|
|
1541
1786
|
|
|
1787
|
+
/**
|
|
1788
|
+
* @private
|
|
1789
|
+
* @description Sets the resize row position.
|
|
1790
|
+
* @param {HTMLElement} figure The table figure element.
|
|
1791
|
+
* @param {HTMLElement} target The target row element.
|
|
1792
|
+
* @param {HTMLElement} resizeLine The resize line element.
|
|
1793
|
+
*/
|
|
1542
1794
|
_setResizeRowPosition(figure, target, resizeLine) {
|
|
1543
|
-
const rowOffset = this.offset.
|
|
1544
|
-
const tableOffset = this.offset.
|
|
1795
|
+
const rowOffset = this.offset.getLocal(target);
|
|
1796
|
+
const tableOffset = this.offset.getLocal(figure);
|
|
1545
1797
|
resizeLine.style.top = `${rowOffset.top + target.offsetHeight}px`;
|
|
1546
1798
|
resizeLine.style.left = `${tableOffset.left}px`;
|
|
1547
1799
|
resizeLine.style.width = `${figure.offsetWidth}px`;
|
|
1548
|
-
}
|
|
1800
|
+
}
|
|
1549
1801
|
|
|
1802
|
+
/**
|
|
1803
|
+
* @private
|
|
1804
|
+
* @description Stops resizing the table.
|
|
1805
|
+
* @param {HTMLElement} target The target element.
|
|
1806
|
+
* @param {string} prevValue The previous style value.
|
|
1807
|
+
* @param {string} styleProp The CSS property being changed.
|
|
1808
|
+
* @param {KeyboardEvent} e The keyboard event.
|
|
1809
|
+
*/
|
|
1550
1810
|
_stopResize(target, prevValue, styleProp, e) {
|
|
1551
|
-
if (e.
|
|
1811
|
+
if (!keyCodeMap.isEsc(e.code)) return;
|
|
1552
1812
|
this.__removeGlobalEvents();
|
|
1553
1813
|
target.style[styleProp] = prevValue;
|
|
1554
1814
|
// figure reopen
|
|
1555
1815
|
if (styleProp === 'width') {
|
|
1556
1816
|
this.component.select(this._element, Table.key, true);
|
|
1557
1817
|
}
|
|
1558
|
-
}
|
|
1818
|
+
}
|
|
1559
1819
|
|
|
1820
|
+
/**
|
|
1821
|
+
* @private
|
|
1822
|
+
* @description Deletes styles from selected table cells.
|
|
1823
|
+
*/
|
|
1560
1824
|
_deleteStyleSelectedCells() {
|
|
1561
|
-
|
|
1825
|
+
dom.utils.removeClass([this._fixedCell, this._selectedCell], 'se-selected-cell-focus');
|
|
1562
1826
|
if (this._selectedTable) {
|
|
1563
1827
|
const selectedCells = this._selectedTable.querySelectorAll('.se-selected-table-cell');
|
|
1564
1828
|
for (let i = 0, len = selectedCells.length; i < len; i++) {
|
|
1565
|
-
|
|
1829
|
+
dom.utils.removeClass(selectedCells[i], 'se-selected-table-cell');
|
|
1566
1830
|
}
|
|
1567
1831
|
}
|
|
1568
|
-
}
|
|
1832
|
+
}
|
|
1569
1833
|
|
|
1834
|
+
/**
|
|
1835
|
+
* @private
|
|
1836
|
+
* @description Restores styles for selected table cells.
|
|
1837
|
+
*/
|
|
1570
1838
|
_recallStyleSelectedCells() {
|
|
1571
1839
|
if (this._selectedCells) {
|
|
1572
1840
|
const selectedCells = this._selectedCells;
|
|
1573
1841
|
for (let i = 0, len = selectedCells.length; i < len; i++) {
|
|
1574
|
-
|
|
1842
|
+
dom.utils.addClass(selectedCells[i], 'se-selected-table-cell');
|
|
1575
1843
|
}
|
|
1576
1844
|
}
|
|
1577
|
-
}
|
|
1845
|
+
}
|
|
1578
1846
|
|
|
1847
|
+
/**
|
|
1848
|
+
* @private
|
|
1849
|
+
* @description Adds global event listeners for resizing.
|
|
1850
|
+
* @param {(...args: *) => void} resizeFn The function handling the resize event.
|
|
1851
|
+
* @param {(...args: *) => void} stopFn The function handling the stop event.
|
|
1852
|
+
* @param {(...args: *) => void} keyDownFn The function handling the keydown event.
|
|
1853
|
+
*/
|
|
1579
1854
|
_addResizeGlobalEvents(resizeFn, stopFn, keyDownFn) {
|
|
1580
1855
|
this.__globalEvents.resize = this.eventManager.addGlobalEvent('mousemove', resizeFn, false);
|
|
1581
1856
|
this.__globalEvents.resizeStop = this.eventManager.addGlobalEvent('mouseup', stopFn, false);
|
|
1582
1857
|
this.__globalEvents.resizeKeyDown = this.eventManager.addGlobalEvent('keydown', keyDownFn, false);
|
|
1583
1858
|
this._resizing = true;
|
|
1584
|
-
}
|
|
1859
|
+
}
|
|
1585
1860
|
|
|
1861
|
+
/**
|
|
1862
|
+
* @private
|
|
1863
|
+
* @description Enables or disables editor mode.
|
|
1864
|
+
* @param {boolean} enabled Whether to enable or disable the editor.
|
|
1865
|
+
*/
|
|
1586
1866
|
_toggleEditor(enabled) {
|
|
1587
1867
|
const wysiwyg = this.editor.frameContext.get('wysiwyg');
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
},
|
|
1868
|
+
if (enabled) dom.utils.removeClass(wysiwyg, 'se-disabled');
|
|
1869
|
+
else dom.utils.addClass(wysiwyg, 'se-disabled');
|
|
1870
|
+
}
|
|
1592
1871
|
|
|
1872
|
+
/**
|
|
1873
|
+
* @private
|
|
1874
|
+
* @description Updates control properties.
|
|
1875
|
+
* @param {string} type The type of control property.
|
|
1876
|
+
*/
|
|
1593
1877
|
_setCtrlProps(type) {
|
|
1594
1878
|
this._typeCache = type;
|
|
1595
1879
|
const isTable = type === 'table';
|
|
1596
1880
|
const targets = isTable ? [this._element] : this._selectedCells;
|
|
1597
1881
|
if (!targets || targets.length === 0) return;
|
|
1598
1882
|
|
|
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;
|
|
1883
|
+
const { border_format, border_color, border_style, border_width, back_color, font_color, cell_alignment, cell_alignment_vertical, cell_alignment_table_text, font_bold, font_underline, font_italic, font_strike } = this.propTargets;
|
|
1600
1884
|
const { border, backgroundColor, color, textAlign, verticalAlign, fontWeight, textDecoration, fontStyle } = _w.getComputedStyle(targets[0]);
|
|
1601
1885
|
const cellBorder = this._getBorderStyle(border);
|
|
1602
1886
|
|
|
1603
|
-
cell_alignment.querySelector('[data-value="justify"]').style.display = isTable ? 'none' : '';
|
|
1887
|
+
/** @type {HTMLElement} */ (cell_alignment.querySelector('[data-value="justify"]')).style.display = isTable ? 'none' : '';
|
|
1888
|
+
cell_alignment_table_text.style.display = isTable ? '' : 'none';
|
|
1604
1889
|
if (isTable) cell_alignment_vertical.style.display = 'none';
|
|
1605
1890
|
else cell_alignment_vertical.style.display = '';
|
|
1606
1891
|
|
|
@@ -1632,7 +1917,7 @@ Table.prototype = {
|
|
|
1632
1917
|
if (fontColor !== converter.rgb2hex(color)) fontColor = '';
|
|
1633
1918
|
if (align !== (isTable ? this._figure?.style.float : textAlign)) align = '';
|
|
1634
1919
|
if (align_v && align_v !== verticalAlign) align_v = '';
|
|
1635
|
-
if (bold && bold !== /.+/.test(fontWeight)) bold =
|
|
1920
|
+
if (bold && bold !== /.+/.test(fontWeight)) bold = false;
|
|
1636
1921
|
if (underline && underline !== /underline/i.test(textDecoration)) underline = false;
|
|
1637
1922
|
if (strike && strike !== /line-through/i.test(textDecoration)) strike = false;
|
|
1638
1923
|
if (italic && italic !== /italic/i.test(fontStyle)) italic = false;
|
|
@@ -1644,7 +1929,7 @@ Table.prototype = {
|
|
|
1644
1929
|
// border - format
|
|
1645
1930
|
border_format.firstElementChild.innerHTML = this.icons[BORDER_FORMATS[targets.length === 1 ? 'outside' : 'all']];
|
|
1646
1931
|
border_format.setAttribute('se-border-format', 'all');
|
|
1647
|
-
|
|
1932
|
+
dom.utils.removeClass(border_format, 'active');
|
|
1648
1933
|
|
|
1649
1934
|
// border - styles
|
|
1650
1935
|
b_style = b_style || BORDER_LIST[0];
|
|
@@ -1658,43 +1943,64 @@ Table.prototype = {
|
|
|
1658
1943
|
font_color.value = font_color.style.borderColor = fontColor;
|
|
1659
1944
|
|
|
1660
1945
|
// font style
|
|
1661
|
-
if (bold)
|
|
1662
|
-
if (underline)
|
|
1663
|
-
if (strike)
|
|
1664
|
-
if (italic)
|
|
1946
|
+
if (bold) dom.utils.addClass(font_bold, 'on');
|
|
1947
|
+
if (underline) dom.utils.addClass(font_underline, 'on');
|
|
1948
|
+
if (strike) dom.utils.addClass(font_strike, 'on');
|
|
1949
|
+
if (italic) dom.utils.addClass(font_italic, 'on');
|
|
1665
1950
|
|
|
1666
1951
|
// align
|
|
1667
1952
|
this._setAlignProps(cell_alignment, (this._propsAlignCache = align), true);
|
|
1668
1953
|
this._setAlignProps(cell_alignment_vertical, (this._propsVerticalAlignCache = align_v), true);
|
|
1669
|
-
}
|
|
1954
|
+
}
|
|
1670
1955
|
|
|
1956
|
+
/**
|
|
1957
|
+
* @private
|
|
1958
|
+
* @description Sets text alignment properties.
|
|
1959
|
+
* @param {Element} el The element to apply alignment to.
|
|
1960
|
+
* @param {string} align The alignment value.
|
|
1961
|
+
* @param {boolean} reset Whether to reset the alignment.
|
|
1962
|
+
*/
|
|
1671
1963
|
_setAlignProps(el, align, reset) {
|
|
1672
|
-
|
|
1964
|
+
dom.utils.removeClass(el.querySelectorAll('button'), 'on');
|
|
1673
1965
|
|
|
1674
1966
|
if (!reset && el.getAttribute('se-cell-align') === align) {
|
|
1675
1967
|
el.setAttribute('se-cell-align', '');
|
|
1676
1968
|
return;
|
|
1677
1969
|
}
|
|
1678
1970
|
|
|
1679
|
-
|
|
1971
|
+
dom.utils.addClass(el.querySelector(`[data-value="${align}"]`), 'on');
|
|
1680
1972
|
el.setAttribute('se-cell-align', align);
|
|
1681
|
-
}
|
|
1973
|
+
}
|
|
1682
1974
|
|
|
1975
|
+
/**
|
|
1976
|
+
* @private
|
|
1977
|
+
* @description Disables or enables border properties.
|
|
1978
|
+
* @param {boolean} disabled Whether to disable or enable border properties.
|
|
1979
|
+
*/
|
|
1683
1980
|
_disableBorderProps(disabled) {
|
|
1684
1981
|
const { border_color, border_width, palette_border_button } = this.propTargets;
|
|
1685
1982
|
if (disabled) {
|
|
1686
|
-
border_color.
|
|
1687
|
-
border_width.
|
|
1688
|
-
palette_border_button.
|
|
1689
|
-
border_width.
|
|
1983
|
+
border_color.disabled = true;
|
|
1984
|
+
border_width.disabled = true;
|
|
1985
|
+
palette_border_button.disabled = true;
|
|
1986
|
+
border_width.disabled = true;
|
|
1690
1987
|
} else {
|
|
1691
|
-
border_color.
|
|
1692
|
-
border_width.
|
|
1693
|
-
palette_border_button.
|
|
1694
|
-
border_width.
|
|
1988
|
+
border_color.disabled = false;
|
|
1989
|
+
border_width.disabled = false;
|
|
1990
|
+
palette_border_button.disabled = false;
|
|
1991
|
+
border_width.disabled = false;
|
|
1695
1992
|
}
|
|
1696
|
-
}
|
|
1993
|
+
}
|
|
1697
1994
|
|
|
1995
|
+
/**
|
|
1996
|
+
* @private
|
|
1997
|
+
* @description Gets the border style.
|
|
1998
|
+
* @param {string} borderStyle The border style string.
|
|
1999
|
+
* @returns {{w: string, s: string, c: string}} The parsed border style object.
|
|
2000
|
+
* - w: The border width.
|
|
2001
|
+
* - s: The border style.
|
|
2002
|
+
* - c: The border color.
|
|
2003
|
+
*/
|
|
1698
2004
|
_getBorderStyle(borderStyle) {
|
|
1699
2005
|
const parts = borderStyle.split(/\s(?![^()]*\))/);
|
|
1700
2006
|
let w = '',
|
|
@@ -1722,15 +2028,20 @@ Table.prototype = {
|
|
|
1722
2028
|
}
|
|
1723
2029
|
|
|
1724
2030
|
return { w, s, c: converter.rgb2hex(c) };
|
|
1725
|
-
}
|
|
2031
|
+
}
|
|
1726
2032
|
|
|
2033
|
+
/**
|
|
2034
|
+
* @private
|
|
2035
|
+
* @description Applies properties to table cells.
|
|
2036
|
+
* @param {HTMLButtonElement} target The target element.
|
|
2037
|
+
*/
|
|
1727
2038
|
_submitProps(target) {
|
|
1728
2039
|
try {
|
|
1729
|
-
target.
|
|
2040
|
+
target.disabled = true;
|
|
1730
2041
|
|
|
1731
2042
|
const isTable = this.controller_table.form.contains(this.controller_props.currentTarget);
|
|
1732
2043
|
const targets = isTable ? [this._element] : this._selectedCells;
|
|
1733
|
-
const tr = targets[0];
|
|
2044
|
+
const tr = /** @type {HTMLTableCellElement} */ (targets[0]);
|
|
1734
2045
|
const trStyles = _w.getComputedStyle(tr);
|
|
1735
2046
|
const { border_format, border_color, border_style, border_width, back_color, font_color, cell_alignment, cell_alignment_vertical } = this.propTargets;
|
|
1736
2047
|
|
|
@@ -1753,14 +2064,16 @@ Table.prototype = {
|
|
|
1753
2064
|
top: [],
|
|
1754
2065
|
right: [],
|
|
1755
2066
|
bottom: [],
|
|
1756
|
-
middle: []
|
|
2067
|
+
middle: [],
|
|
2068
|
+
all: null
|
|
1757
2069
|
};
|
|
1758
2070
|
|
|
1759
2071
|
if (!isTable) {
|
|
2072
|
+
const trRow = /** @type {HTMLTableRowElement} */ (tr.parentElement);
|
|
1760
2073
|
// --- target cells roof
|
|
1761
2074
|
let { rs, re, cs, ce } = this._ref || {
|
|
1762
|
-
rs:
|
|
1763
|
-
re:
|
|
2075
|
+
rs: trRow.rowIndex || 0,
|
|
2076
|
+
re: trRow.rowIndex || 0,
|
|
1764
2077
|
cs: tr.cellIndex || 0,
|
|
1765
2078
|
ce: tr.cellIndex || 0
|
|
1766
2079
|
};
|
|
@@ -1770,17 +2083,17 @@ Table.prototype = {
|
|
|
1770
2083
|
rs -= rs;
|
|
1771
2084
|
ce -= cs;
|
|
1772
2085
|
cs -= cs;
|
|
1773
|
-
let prevRow =
|
|
2086
|
+
let prevRow = /** @type {HTMLElement} */ (trRow);
|
|
1774
2087
|
for (let i = 0, cellCnt = 0, len = targets.length, e, es, rowIndex = 0, cellIndex, colspan, rowspan; i < len; i++, cellCnt++) {
|
|
1775
|
-
e = targets[i];
|
|
2088
|
+
e = /** @type {HTMLTableCellElement} */ (targets[i]);
|
|
1776
2089
|
colspan = e.colSpan;
|
|
1777
2090
|
rowspan = e.rowSpan;
|
|
1778
2091
|
cellIndex = e.cellIndex - cellStartIndex;
|
|
1779
2092
|
|
|
1780
|
-
if (prevRow !== e.
|
|
2093
|
+
if (prevRow !== e.parentElement) {
|
|
1781
2094
|
rowIndex++;
|
|
1782
2095
|
cellCnt = 0;
|
|
1783
|
-
prevRow = e.
|
|
2096
|
+
prevRow = e.parentElement;
|
|
1784
2097
|
}
|
|
1785
2098
|
|
|
1786
2099
|
let c = 0;
|
|
@@ -1874,83 +2187,93 @@ Table.prototype = {
|
|
|
1874
2187
|
if (this._tdElement) {
|
|
1875
2188
|
this._recallStyleSelectedCells();
|
|
1876
2189
|
this.setCellInfo(this._tdElement, true);
|
|
1877
|
-
|
|
2190
|
+
dom.utils.addClass(this._tdElement, 'se-selected-cell-focus');
|
|
1878
2191
|
}
|
|
1879
2192
|
} catch (err) {
|
|
1880
2193
|
console.warn('[SUNEDITOR.plugins.table.setProps.error]', err);
|
|
1881
2194
|
} finally {
|
|
1882
|
-
target.
|
|
2195
|
+
target.disabled = false;
|
|
1883
2196
|
}
|
|
1884
|
-
}
|
|
2197
|
+
}
|
|
1885
2198
|
|
|
2199
|
+
/**
|
|
2200
|
+
* @private
|
|
2201
|
+
* @description Sets font styles.
|
|
2202
|
+
* @param {CSSStyleDeclaration} styles The style object to modify.
|
|
2203
|
+
*/
|
|
1886
2204
|
_setFontStyle(styles) {
|
|
1887
2205
|
const { font_bold, font_italic, font_strike, font_underline } = this.propTargets;
|
|
1888
|
-
styles.fontWeight =
|
|
1889
|
-
styles.fontStyle =
|
|
1890
|
-
styles.textDecoration = ((
|
|
1891
|
-
}
|
|
2206
|
+
styles.fontWeight = dom.utils.hasClass(font_bold, 'on') ? 'bold' : '';
|
|
2207
|
+
styles.fontStyle = dom.utils.hasClass(font_italic, 'on') ? 'italic' : '';
|
|
2208
|
+
styles.textDecoration = ((dom.utils.hasClass(font_strike, 'on') ? 'line-through ' : '') + (dom.utils.hasClass(font_underline, 'on') ? 'underline' : '')).trim();
|
|
2209
|
+
}
|
|
1892
2210
|
|
|
1893
2211
|
/**
|
|
1894
2212
|
* @private
|
|
1895
|
-
* @description
|
|
1896
|
-
* @param {
|
|
1897
|
-
* @param {"all"|"inside"|"horizon"|"vertical"|"outside"|"left"|"top"|"right"|"bottom"
|
|
1898
|
-
* @param {
|
|
1899
|
-
* @param {boolean} isTable table selected
|
|
2213
|
+
* @description Sets border format and styles.
|
|
2214
|
+
* @param {{left: Node[], top: Node[], right: Node[], bottom: Node[], all: Node[]}} cells The table cells categorized by border positions.
|
|
2215
|
+
* @param {string} borderKey Border style ("all"|"inside"|"horizon"|"vertical"|"outside"|"left"|"top"|"right"|"bottom")
|
|
2216
|
+
* @param {string} s The border style value.
|
|
1900
2217
|
*/
|
|
1901
2218
|
_setBorderStyles(cells, borderKey, s) {
|
|
1902
2219
|
const { left, top, right, bottom, all } = cells;
|
|
1903
2220
|
switch (borderKey) {
|
|
1904
2221
|
case 'inside':
|
|
1905
|
-
if (
|
|
1906
|
-
|
|
2222
|
+
if (all.length === 1) return;
|
|
2223
|
+
dom.utils.setStyle(
|
|
1907
2224
|
all.filter((c) => !bottom.includes(c)),
|
|
1908
2225
|
BORDER_NS.b,
|
|
1909
2226
|
s
|
|
1910
2227
|
);
|
|
1911
|
-
|
|
2228
|
+
dom.utils.setStyle(
|
|
1912
2229
|
all.filter((c) => !right.includes(c)),
|
|
1913
2230
|
BORDER_NS.r,
|
|
1914
2231
|
s
|
|
1915
2232
|
);
|
|
1916
2233
|
break;
|
|
1917
2234
|
case 'horizon':
|
|
1918
|
-
if (
|
|
1919
|
-
|
|
2235
|
+
if (all.length === 1) return;
|
|
2236
|
+
dom.utils.setStyle(
|
|
1920
2237
|
all.filter((c) => !bottom.includes(c)),
|
|
1921
2238
|
BORDER_NS.b,
|
|
1922
2239
|
s
|
|
1923
2240
|
);
|
|
1924
2241
|
break;
|
|
1925
2242
|
case 'vertical':
|
|
1926
|
-
if (
|
|
1927
|
-
|
|
2243
|
+
if (all.length === 1) return;
|
|
2244
|
+
dom.utils.setStyle(
|
|
1928
2245
|
all.filter((c) => !right.includes(c)),
|
|
1929
2246
|
BORDER_NS.r,
|
|
1930
2247
|
s
|
|
1931
2248
|
);
|
|
1932
2249
|
break;
|
|
1933
2250
|
case 'outside':
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
2251
|
+
dom.utils.setStyle(left, BORDER_NS.l, s);
|
|
2252
|
+
dom.utils.setStyle(top, BORDER_NS.t, s);
|
|
2253
|
+
dom.utils.setStyle(right, BORDER_NS.r, s);
|
|
2254
|
+
dom.utils.setStyle(bottom, BORDER_NS.b, s);
|
|
1938
2255
|
break;
|
|
1939
2256
|
case 'left':
|
|
1940
|
-
|
|
2257
|
+
dom.utils.setStyle(left, BORDER_NS.l, s);
|
|
1941
2258
|
break;
|
|
1942
2259
|
case 'top':
|
|
1943
|
-
|
|
2260
|
+
dom.utils.setStyle(top, BORDER_NS.t, s);
|
|
1944
2261
|
break;
|
|
1945
2262
|
case 'right':
|
|
1946
|
-
|
|
2263
|
+
dom.utils.setStyle(right, BORDER_NS.r, s);
|
|
1947
2264
|
break;
|
|
1948
2265
|
case 'bottom':
|
|
1949
|
-
|
|
2266
|
+
dom.utils.setStyle(bottom, BORDER_NS.b, s);
|
|
1950
2267
|
break;
|
|
1951
2268
|
}
|
|
1952
|
-
}
|
|
2269
|
+
}
|
|
1953
2270
|
|
|
2271
|
+
/**
|
|
2272
|
+
* @private
|
|
2273
|
+
* @description Selects multiple table cells and applies selection styles.
|
|
2274
|
+
* @param {Node} startCell The first cell in the selection.
|
|
2275
|
+
* @param {Node} endCell The last cell in the selection.
|
|
2276
|
+
*/
|
|
1954
2277
|
_setMultiCells(startCell, endCell) {
|
|
1955
2278
|
const rows = this._selectedTable.rows;
|
|
1956
2279
|
this._deleteStyleSelectedCells();
|
|
@@ -1958,7 +2281,7 @@ Table.prototype = {
|
|
|
1958
2281
|
if (startCell === endCell) {
|
|
1959
2282
|
if (!this._shift) return;
|
|
1960
2283
|
} else {
|
|
1961
|
-
|
|
2284
|
+
dom.utils.addClass(startCell, 'se-selected-table-cell');
|
|
1962
2285
|
}
|
|
1963
2286
|
|
|
1964
2287
|
let findSelectedCell = true;
|
|
@@ -2034,7 +2357,7 @@ Table.prototype = {
|
|
|
2034
2357
|
break;
|
|
2035
2358
|
}
|
|
2036
2359
|
|
|
2037
|
-
|
|
2360
|
+
dom.utils.addClass(cell, 'se-selected-table-cell');
|
|
2038
2361
|
}
|
|
2039
2362
|
|
|
2040
2363
|
if (rs > 0) {
|
|
@@ -2054,8 +2377,12 @@ Table.prototype = {
|
|
|
2054
2377
|
});
|
|
2055
2378
|
rowSpanArr = [];
|
|
2056
2379
|
}
|
|
2057
|
-
}
|
|
2380
|
+
}
|
|
2058
2381
|
|
|
2382
|
+
/**
|
|
2383
|
+
* @private
|
|
2384
|
+
* @description Resets the table picker display.
|
|
2385
|
+
*/
|
|
2059
2386
|
_resetTablePicker() {
|
|
2060
2387
|
if (!this.tableHighlight) return;
|
|
2061
2388
|
|
|
@@ -2067,10 +2394,14 @@ Table.prototype = {
|
|
|
2067
2394
|
unHighlight.width = '10em';
|
|
2068
2395
|
unHighlight.height = '10em';
|
|
2069
2396
|
|
|
2070
|
-
|
|
2397
|
+
dom.utils.changeTxt(this.tableDisplay, '1 x 1');
|
|
2071
2398
|
this.menu.dropdownOff();
|
|
2072
|
-
}
|
|
2399
|
+
}
|
|
2073
2400
|
|
|
2401
|
+
/**
|
|
2402
|
+
* @private
|
|
2403
|
+
* @description Resets the alignment properties for table cells.
|
|
2404
|
+
*/
|
|
2074
2405
|
_resetPropsAlign() {
|
|
2075
2406
|
const { cell_alignment } = this.propTargets;
|
|
2076
2407
|
const left = cell_alignment.querySelector('[data-value="left"]');
|
|
@@ -2079,35 +2410,54 @@ Table.prototype = {
|
|
|
2079
2410
|
const r_parent = right.parentElement;
|
|
2080
2411
|
l_parent.appendChild(right);
|
|
2081
2412
|
r_parent.appendChild(left);
|
|
2082
|
-
}
|
|
2413
|
+
}
|
|
2083
2414
|
|
|
2415
|
+
/**
|
|
2416
|
+
* @private
|
|
2417
|
+
* @description Handles color selection from the color palette.
|
|
2418
|
+
* @param {Node} button The button triggering the color palette.
|
|
2419
|
+
* @param {string} type The type of color selection.
|
|
2420
|
+
* @param {HTMLInputElement} color Color text input element.
|
|
2421
|
+
*/
|
|
2084
2422
|
_onColorPalette(button, type, color) {
|
|
2085
2423
|
if (this.controller_colorPicker.isOpen && type === this.sliderType) {
|
|
2086
2424
|
this.controller_colorPicker.close();
|
|
2087
2425
|
} else {
|
|
2088
2426
|
this.sliderType = type;
|
|
2089
|
-
|
|
2427
|
+
dom.utils.addClass(button, 'on');
|
|
2090
2428
|
this.colorPicker.init(color?.value || '', button);
|
|
2091
2429
|
this.controller_colorPicker.open(button, null, { isWWTarget: false, initMethod: null, addOffset: null });
|
|
2092
2430
|
}
|
|
2093
|
-
}
|
|
2431
|
+
}
|
|
2094
2432
|
|
|
2433
|
+
/**
|
|
2434
|
+
* @private
|
|
2435
|
+
* @description Closes table-related controllers.
|
|
2436
|
+
*/
|
|
2095
2437
|
_closeController() {
|
|
2096
2438
|
this.component.deselect();
|
|
2097
2439
|
this.controller_table.close();
|
|
2098
2440
|
this.controller_cell.close();
|
|
2099
|
-
}
|
|
2441
|
+
}
|
|
2100
2442
|
|
|
2443
|
+
/**
|
|
2444
|
+
* @private
|
|
2445
|
+
* @description Hides the resize line if it is visible.
|
|
2446
|
+
*/
|
|
2101
2447
|
__hideResizeLine() {
|
|
2102
2448
|
if (this._resizeLine) {
|
|
2103
2449
|
this._resizeLine.style.display = 'none';
|
|
2104
2450
|
this._resizeLine = null;
|
|
2105
2451
|
}
|
|
2106
|
-
}
|
|
2452
|
+
}
|
|
2107
2453
|
|
|
2454
|
+
/**
|
|
2455
|
+
* @private
|
|
2456
|
+
* @description Removes global event listeners and resets resize-related properties.
|
|
2457
|
+
*/
|
|
2108
2458
|
__removeGlobalEvents() {
|
|
2109
2459
|
this._resizing = false;
|
|
2110
|
-
this.
|
|
2460
|
+
this.ui.disableBackWrapper();
|
|
2111
2461
|
this.__hideResizeLine();
|
|
2112
2462
|
if (this._resizeLinePrev) {
|
|
2113
2463
|
this._resizeLinePrev.style.display = 'none';
|
|
@@ -2117,372 +2467,457 @@ Table.prototype = {
|
|
|
2117
2467
|
for (const k in globalEvents) {
|
|
2118
2468
|
if (globalEvents[k]) globalEvents[k] = this.eventManager.removeGlobalEvent(globalEvents[k]);
|
|
2119
2469
|
}
|
|
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
|
-
}
|
|
2470
|
+
}
|
|
2155
2471
|
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
const
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
newCell.
|
|
2173
|
-
currentCell.colSpan = currentColSpan - newCell.colSpan;
|
|
2174
|
-
currentRow.insertBefore(newCell, currentCell.nextElementSibling);
|
|
2175
|
-
} else {
|
|
2176
|
-
// colspan - 1
|
|
2177
|
-
let rowSpanArr = [];
|
|
2178
|
-
let spanIndex = [];
|
|
2472
|
+
/**
|
|
2473
|
+
* @description Splits a table cell either vertically or horizontally.
|
|
2474
|
+
* @param {"vertical"|"horizontal"} direction The direction to split the cell.
|
|
2475
|
+
*/
|
|
2476
|
+
#OnSplitCells(direction) {
|
|
2477
|
+
const vertical = direction === 'vertical';
|
|
2478
|
+
const currentCell = this._tdElement;
|
|
2479
|
+
const rows = this._trElements;
|
|
2480
|
+
const currentRow = this._trElement;
|
|
2481
|
+
const index = this._logical_cellIndex;
|
|
2482
|
+
const rowIndex = this._rowIndex;
|
|
2483
|
+
const newCell = CreateCellsHTML(currentCell.nodeName);
|
|
2484
|
+
|
|
2485
|
+
// vertical
|
|
2486
|
+
if (vertical) {
|
|
2487
|
+
const currentColSpan = currentCell.colSpan;
|
|
2488
|
+
newCell.rowSpan = currentCell.rowSpan;
|
|
2179
2489
|
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
colSpan =
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2490
|
+
// colspan > 1
|
|
2491
|
+
if (currentColSpan > 1) {
|
|
2492
|
+
newCell.colSpan = Math.floor(currentColSpan / 2);
|
|
2493
|
+
currentCell.colSpan = currentColSpan - newCell.colSpan;
|
|
2494
|
+
currentRow.insertBefore(newCell, currentCell.nextElementSibling);
|
|
2495
|
+
} else {
|
|
2496
|
+
// colspan - 1
|
|
2497
|
+
let rowSpanArr = [];
|
|
2498
|
+
let spanIndex = [];
|
|
2188
2499
|
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2500
|
+
for (let i = 0, len = this._rowCnt, cells, colSpan; i < len; i++) {
|
|
2501
|
+
cells = rows[i].cells;
|
|
2502
|
+
colSpan = 0;
|
|
2503
|
+
for (let c = 0, cLen = cells.length, cell, cs, rs, logcalIndex; c < cLen; c++) {
|
|
2504
|
+
cell = cells[c];
|
|
2505
|
+
cs = cell.colSpan - 1;
|
|
2506
|
+
rs = cell.rowSpan - 1;
|
|
2507
|
+
logcalIndex = c + colSpan;
|
|
2508
|
+
|
|
2509
|
+
if (spanIndex.length > 0) {
|
|
2510
|
+
for (let r = 0, arr; r < spanIndex.length; r++) {
|
|
2511
|
+
arr = spanIndex[r];
|
|
2512
|
+
if (arr.row > i) continue;
|
|
2513
|
+
if (logcalIndex >= arr.index) {
|
|
2514
|
+
colSpan += arr.cs;
|
|
2515
|
+
logcalIndex += arr.cs;
|
|
2516
|
+
arr.rs -= 1;
|
|
2517
|
+
arr.row = i + 1;
|
|
2518
|
+
if (arr.rs < 1) {
|
|
2519
|
+
spanIndex.splice(r, 1);
|
|
2520
|
+
r--;
|
|
2521
|
+
}
|
|
2522
|
+
} else if (c === cLen - 1) {
|
|
2523
|
+
arr.rs -= 1;
|
|
2524
|
+
arr.row = i + 1;
|
|
2525
|
+
if (arr.rs < 1) {
|
|
2526
|
+
spanIndex.splice(r, 1);
|
|
2527
|
+
r--;
|
|
2528
|
+
}
|
|
2208
2529
|
}
|
|
2209
2530
|
}
|
|
2210
2531
|
}
|
|
2211
|
-
}
|
|
2212
2532
|
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2533
|
+
if (logcalIndex <= index && rs > 0) {
|
|
2534
|
+
rowSpanArr.push({
|
|
2535
|
+
index: logcalIndex,
|
|
2536
|
+
cs: cs + 1,
|
|
2537
|
+
rs: rs,
|
|
2538
|
+
row: -1
|
|
2539
|
+
});
|
|
2540
|
+
}
|
|
2221
2541
|
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2542
|
+
if (cell !== currentCell && logcalIndex <= index && logcalIndex + cs >= index + currentColSpan - 1) {
|
|
2543
|
+
cell.colSpan += 1;
|
|
2544
|
+
break;
|
|
2545
|
+
}
|
|
2226
2546
|
|
|
2227
|
-
|
|
2547
|
+
if (logcalIndex > index) break;
|
|
2228
2548
|
|
|
2229
|
-
|
|
2549
|
+
colSpan += cs;
|
|
2550
|
+
}
|
|
2551
|
+
|
|
2552
|
+
spanIndex = spanIndex.concat(rowSpanArr).sort(function (a, b) {
|
|
2553
|
+
return a.index - b.index;
|
|
2554
|
+
});
|
|
2555
|
+
rowSpanArr = [];
|
|
2230
2556
|
}
|
|
2231
2557
|
|
|
2232
|
-
|
|
2233
|
-
return a.index - b.index;
|
|
2234
|
-
});
|
|
2235
|
-
rowSpanArr = [];
|
|
2558
|
+
currentRow.insertBefore(newCell, currentCell.nextElementSibling);
|
|
2236
2559
|
}
|
|
2560
|
+
} else {
|
|
2561
|
+
// horizontal
|
|
2562
|
+
const currentRowSpan = currentCell.rowSpan;
|
|
2563
|
+
newCell.colSpan = currentCell.colSpan;
|
|
2237
2564
|
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2565
|
+
// rowspan > 1
|
|
2566
|
+
if (currentRowSpan > 1) {
|
|
2567
|
+
newCell.rowSpan = Math.floor(currentRowSpan / 2);
|
|
2568
|
+
const newRowSpan = currentRowSpan - newCell.rowSpan;
|
|
2569
|
+
|
|
2570
|
+
const rowSpanArr = [];
|
|
2571
|
+
const nextRowIndex = dom.utils.getArrayIndex(rows, currentRow) + newRowSpan;
|
|
2244
2572
|
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2573
|
+
for (let i = 0, cells, colSpan; i < nextRowIndex; i++) {
|
|
2574
|
+
cells = rows[i].cells;
|
|
2575
|
+
colSpan = 0;
|
|
2576
|
+
for (let c = 0, cLen = cells.length, cell, cs, logcalIndex; c < cLen; c++) {
|
|
2577
|
+
logcalIndex = c + colSpan;
|
|
2578
|
+
if (logcalIndex >= index) break;
|
|
2579
|
+
|
|
2580
|
+
cell = cells[c];
|
|
2581
|
+
cs = cell.rowSpan - 1;
|
|
2582
|
+
if (cs > 0 && cs + i >= nextRowIndex && logcalIndex < index) {
|
|
2583
|
+
rowSpanArr.push({
|
|
2584
|
+
index: logcalIndex,
|
|
2585
|
+
cs: cell.colSpan
|
|
2586
|
+
});
|
|
2587
|
+
}
|
|
2588
|
+
colSpan += cell.colSpan - 1;
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2249
2591
|
|
|
2250
|
-
|
|
2251
|
-
|
|
2592
|
+
const nextRow = rows[nextRowIndex];
|
|
2593
|
+
const nextCells = nextRow.cells;
|
|
2594
|
+
let rs = rowSpanArr.shift();
|
|
2252
2595
|
|
|
2253
|
-
|
|
2254
|
-
cells = rows[i].cells;
|
|
2255
|
-
colSpan = 0;
|
|
2256
|
-
for (let c = 0, cLen = cells.length, cell, cs, logcalIndex; c < cLen; c++) {
|
|
2596
|
+
for (let c = 0, cLen = nextCells.length, colSpan = 0, cell, cs, logcalIndex, insertIndex; c < cLen; c++) {
|
|
2257
2597
|
logcalIndex = c + colSpan;
|
|
2258
|
-
|
|
2598
|
+
cell = nextCells[c];
|
|
2599
|
+
cs = cell.colSpan - 1;
|
|
2600
|
+
insertIndex = logcalIndex + cs + 1;
|
|
2259
2601
|
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
rowSpanArr.
|
|
2264
|
-
index: logcalIndex,
|
|
2265
|
-
cs: cell.colSpan
|
|
2266
|
-
});
|
|
2602
|
+
if (rs && insertIndex >= rs.index) {
|
|
2603
|
+
colSpan += rs.cs;
|
|
2604
|
+
insertIndex += rs.cs;
|
|
2605
|
+
rs = rowSpanArr.shift();
|
|
2267
2606
|
}
|
|
2268
|
-
colSpan += cell.colSpan - 1;
|
|
2269
|
-
}
|
|
2270
|
-
}
|
|
2271
|
-
|
|
2272
|
-
const nextRow = rows[nextRowIndex];
|
|
2273
|
-
const nextCells = nextRow.cells;
|
|
2274
|
-
let rs = rowSpanArr.shift();
|
|
2275
2607
|
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
insertIndex = logcalIndex + cs + 1;
|
|
2608
|
+
if (insertIndex >= index || c === cLen - 1) {
|
|
2609
|
+
nextRow.insertBefore(newCell, cell.nextElementSibling);
|
|
2610
|
+
break;
|
|
2611
|
+
}
|
|
2281
2612
|
|
|
2282
|
-
|
|
2283
|
-
colSpan += rs.cs;
|
|
2284
|
-
insertIndex += rs.cs;
|
|
2285
|
-
rs = rowSpanArr.shift();
|
|
2613
|
+
colSpan += cs;
|
|
2286
2614
|
}
|
|
2287
2615
|
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2616
|
+
currentCell.rowSpan = newRowSpan;
|
|
2617
|
+
} else {
|
|
2618
|
+
// rowspan - 1
|
|
2619
|
+
newCell.rowSpan = currentCell.rowSpan;
|
|
2620
|
+
const newRow = dom.utils.createElement('TR');
|
|
2621
|
+
newRow.appendChild(newCell);
|
|
2622
|
+
|
|
2623
|
+
for (let i = 0, cells; i < rowIndex; i++) {
|
|
2624
|
+
cells = rows[i].cells;
|
|
2625
|
+
if (cells.length === 0) return;
|
|
2626
|
+
|
|
2627
|
+
for (let c = 0, cLen = cells.length; c < cLen; c++) {
|
|
2628
|
+
if (i + cells[c].rowSpan - 1 >= rowIndex) {
|
|
2629
|
+
cells[c].rowSpan += 1;
|
|
2630
|
+
}
|
|
2631
|
+
}
|
|
2291
2632
|
}
|
|
2292
2633
|
|
|
2293
|
-
|
|
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;
|
|
2634
|
+
const physicalIndex = this._physical_cellIndex;
|
|
2635
|
+
const cells = currentRow.cells;
|
|
2306
2636
|
|
|
2307
2637
|
for (let c = 0, cLen = cells.length; c < cLen; c++) {
|
|
2308
|
-
if (
|
|
2309
|
-
|
|
2310
|
-
}
|
|
2638
|
+
if (c === physicalIndex) continue;
|
|
2639
|
+
cells[c].rowSpan += 1;
|
|
2311
2640
|
}
|
|
2641
|
+
|
|
2642
|
+
currentRow.parentNode.insertBefore(newRow, currentRow.nextElementSibling);
|
|
2312
2643
|
}
|
|
2644
|
+
}
|
|
2313
2645
|
|
|
2314
|
-
|
|
2315
|
-
|
|
2646
|
+
this.selectMenu_split.close();
|
|
2647
|
+
this.editor.focusEdge(currentCell);
|
|
2316
2648
|
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
cells[c].rowSpan += 1;
|
|
2320
|
-
}
|
|
2649
|
+
this._deleteStyleSelectedCells();
|
|
2650
|
+
this.history.push(false);
|
|
2321
2651
|
|
|
2322
|
-
|
|
2323
|
-
|
|
2652
|
+
this._setController(currentCell);
|
|
2653
|
+
this._selectedCell = this._fixedCell = currentCell;
|
|
2324
2654
|
}
|
|
2325
2655
|
|
|
2326
|
-
|
|
2327
|
-
|
|
2656
|
+
/**
|
|
2657
|
+
* @description Handles column operations such as insert and delete.
|
|
2658
|
+
* @param {"insert-left"|"insert-right"|"delete"} command The column operation to perform.
|
|
2659
|
+
*/
|
|
2660
|
+
#OnColumnEdit(command) {
|
|
2661
|
+
switch (command) {
|
|
2662
|
+
case 'insert-left':
|
|
2663
|
+
this.editTable('cell', 'left');
|
|
2664
|
+
break;
|
|
2665
|
+
case 'insert-right':
|
|
2666
|
+
this.editTable('cell', 'right');
|
|
2667
|
+
break;
|
|
2668
|
+
case 'delete':
|
|
2669
|
+
this.editTable('cell', null);
|
|
2670
|
+
}
|
|
2328
2671
|
|
|
2329
|
-
|
|
2330
|
-
|
|
2672
|
+
this._historyPush();
|
|
2673
|
+
}
|
|
2331
2674
|
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
}
|
|
2675
|
+
/**
|
|
2676
|
+
* @description Handles row operations such as insert and delete.
|
|
2677
|
+
* @param {"insert-above"|"insert-below"|"delete"} command The row operation to perform.
|
|
2678
|
+
*/
|
|
2679
|
+
#OnRowEdit(command) {
|
|
2680
|
+
switch (command) {
|
|
2681
|
+
case 'insert-above':
|
|
2682
|
+
this.editTable('row', 'up');
|
|
2683
|
+
break;
|
|
2684
|
+
case 'insert-below':
|
|
2685
|
+
this.editTable('row', 'down');
|
|
2686
|
+
break;
|
|
2687
|
+
case 'delete':
|
|
2688
|
+
this.editTable('row', null);
|
|
2689
|
+
}
|
|
2335
2690
|
|
|
2336
|
-
|
|
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);
|
|
2691
|
+
this._historyPush();
|
|
2346
2692
|
}
|
|
2347
2693
|
|
|
2348
|
-
|
|
2349
|
-
|
|
2694
|
+
/**
|
|
2695
|
+
* @description Handles mouse movement within the table picker.
|
|
2696
|
+
* @param {MouseEvent} e The mouse event.
|
|
2697
|
+
*/
|
|
2698
|
+
#OnMouseMoveTablePicker(e) {
|
|
2699
|
+
e.stopPropagation();
|
|
2350
2700
|
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
break;
|
|
2356
|
-
case 'insert-below':
|
|
2357
|
-
this.editTable('row', 'down');
|
|
2358
|
-
break;
|
|
2359
|
-
case 'delete':
|
|
2360
|
-
this.editTable('row', null);
|
|
2361
|
-
}
|
|
2701
|
+
let x = Math.ceil(e.offsetX / 18);
|
|
2702
|
+
let y = Math.ceil(e.offsetY / 18);
|
|
2703
|
+
x = x < 1 ? 1 : x;
|
|
2704
|
+
y = y < 1 ? 1 : y;
|
|
2362
2705
|
|
|
2363
|
-
|
|
2364
|
-
|
|
2706
|
+
if (this.options.get('_rtl')) {
|
|
2707
|
+
this.tableHighlight.style.left = x * 18 - 13 + 'px';
|
|
2708
|
+
x = 11 - x;
|
|
2709
|
+
}
|
|
2365
2710
|
|
|
2366
|
-
|
|
2367
|
-
|
|
2711
|
+
this.tableHighlight.style.width = x + 'em';
|
|
2712
|
+
this.tableHighlight.style.height = y + 'em';
|
|
2368
2713
|
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2714
|
+
const x_u = x < 5 ? 5 : x > 8 ? 10 : x + 2;
|
|
2715
|
+
const y_u = y < 5 ? 5 : y > 8 ? 10 : y + 2;
|
|
2716
|
+
this.tableUnHighlight.style.width = x_u + 'em';
|
|
2717
|
+
this.tableUnHighlight.style.height = y_u + 'em';
|
|
2373
2718
|
|
|
2374
|
-
|
|
2375
|
-
this.
|
|
2376
|
-
x = 11 - x;
|
|
2719
|
+
dom.utils.changeTxt(this.tableDisplay, x + ' x ' + y);
|
|
2720
|
+
this._tableXY = [x, y];
|
|
2377
2721
|
}
|
|
2378
2722
|
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
this.tableUnHighlight.style.height = y_u + 'em';
|
|
2723
|
+
/**
|
|
2724
|
+
* @description Executes the selected action when the table picker is clicked.
|
|
2725
|
+
*/
|
|
2726
|
+
#OnClickTablePicker() {
|
|
2727
|
+
this.action();
|
|
2728
|
+
}
|
|
2386
2729
|
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
}
|
|
2730
|
+
/**
|
|
2731
|
+
* @description Handles multi-selection of table cells.
|
|
2732
|
+
* @param {MouseEvent} e The mouse event.
|
|
2733
|
+
*/
|
|
2734
|
+
#OnCellMultiSelect(e) {
|
|
2735
|
+
this.editor._preventBlur = true;
|
|
2736
|
+
const target = /** @type {HTMLTableCellElement} */ (dom.query.getParentElement(dom.query.getEventTarget(e), dom.check.isTableCell));
|
|
2390
2737
|
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2738
|
+
if (this._shift) {
|
|
2739
|
+
if (target === this._fixedCell) {
|
|
2740
|
+
this._shift = false;
|
|
2741
|
+
this._deleteStyleSelectedCells();
|
|
2742
|
+
this._toggleEditor(true);
|
|
2743
|
+
this.__removeGlobalEvents();
|
|
2744
|
+
return;
|
|
2745
|
+
} else {
|
|
2746
|
+
this._toggleEditor(false);
|
|
2747
|
+
}
|
|
2748
|
+
} else if (!this._ref) {
|
|
2749
|
+
if (target === this._fixedCell) return;
|
|
2750
|
+
else this._toggleEditor(false);
|
|
2751
|
+
}
|
|
2394
2752
|
|
|
2395
|
-
|
|
2396
|
-
|
|
2753
|
+
if (!target || target === this._selectedCell || this._fixedCellName !== target.nodeName || this._selectedTable !== dom.query.getParentElement(target, 'TABLE')) {
|
|
2754
|
+
return;
|
|
2755
|
+
}
|
|
2397
2756
|
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
} else {
|
|
2401
|
-
return domUtils.createElement(nodeName, null, '<div><br></div>');
|
|
2757
|
+
this._selectedCell = target;
|
|
2758
|
+
this._setMultiCells(this._fixedCell, target);
|
|
2402
2759
|
}
|
|
2403
|
-
}
|
|
2404
2760
|
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2761
|
+
/**
|
|
2762
|
+
* @description Stops multi-selection of table cells.
|
|
2763
|
+
* @param {MouseEvent} e The mouse event.
|
|
2764
|
+
*/
|
|
2765
|
+
#OffCellMultiSelect(e) {
|
|
2766
|
+
e.stopPropagation();
|
|
2408
2767
|
|
|
2409
|
-
|
|
2410
|
-
if (target === this._fixedCell) {
|
|
2411
|
-
this._shift = false;
|
|
2412
|
-
this._deleteStyleSelectedCells();
|
|
2413
|
-
this._toggleEditor(true);
|
|
2768
|
+
if (!this._shift) {
|
|
2414
2769
|
this.__removeGlobalEvents();
|
|
2415
|
-
|
|
2416
|
-
} else {
|
|
2417
|
-
this.
|
|
2770
|
+
this._toggleEditor(true);
|
|
2771
|
+
} else if (this.__globalEvents.touchOff) {
|
|
2772
|
+
this.__globalEvents.touchOff = this.eventManager.removeGlobalEvent(this.__globalEvents.touchOff);
|
|
2418
2773
|
}
|
|
2419
|
-
|
|
2420
|
-
if (
|
|
2421
|
-
|
|
2774
|
+
|
|
2775
|
+
if (!this._fixedCell || !this._selectedTable) return;
|
|
2776
|
+
|
|
2777
|
+
this._setMergeSplitButton(!!this._fixedCell, !!this._selectedCell);
|
|
2778
|
+
this._selectedCells = Array.from(this._selectedTable.querySelectorAll('.se-selected-table-cell'));
|
|
2779
|
+
|
|
2780
|
+
const focusCell = this._selectedCells?.length > 0 ? this._selectedCell : this._fixedCell;
|
|
2781
|
+
this._setController(focusCell);
|
|
2422
2782
|
}
|
|
2423
2783
|
|
|
2424
|
-
|
|
2425
|
-
|
|
2784
|
+
/**
|
|
2785
|
+
* @description Handles the removal of shift-based selection.
|
|
2786
|
+
*/
|
|
2787
|
+
#OffCellShift() {
|
|
2788
|
+
if (!this._ref) this._closeController();
|
|
2426
2789
|
}
|
|
2427
2790
|
|
|
2428
|
-
|
|
2429
|
-
|
|
2791
|
+
/**
|
|
2792
|
+
* @description Handles the removal of touch-based selection.
|
|
2793
|
+
*/
|
|
2794
|
+
#OffCellTouch() {
|
|
2795
|
+
this.close();
|
|
2796
|
+
}
|
|
2430
2797
|
}
|
|
2431
2798
|
|
|
2432
|
-
|
|
2433
|
-
|
|
2799
|
+
/**
|
|
2800
|
+
* @private
|
|
2801
|
+
* @description Checks if the given node is a resizable table element.
|
|
2802
|
+
* @param {Node} node The DOM node to check.
|
|
2803
|
+
* @returns {boolean} True if the node is a table-related resizable element.
|
|
2804
|
+
*/
|
|
2805
|
+
function IsResizeEls(node) {
|
|
2806
|
+
return /^(TD|TH|TR)$/i.test(node?.nodeName);
|
|
2807
|
+
}
|
|
2434
2808
|
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2809
|
+
/**
|
|
2810
|
+
* @private
|
|
2811
|
+
* @description Checks if a table cell is at its edge based on the mouse event.
|
|
2812
|
+
* @param {MouseEvent} event The mouse event.
|
|
2813
|
+
* @param {Element} tableCell The table cell to check.
|
|
2814
|
+
* @returns {Object} An object containing edge detection details.
|
|
2815
|
+
*/
|
|
2816
|
+
function CheckCellEdge(event, tableCell) {
|
|
2817
|
+
const startX = event.clientX;
|
|
2818
|
+
const startWidth = numbers.get(_w.getComputedStyle(tableCell).width, CELL_DECIMAL_END);
|
|
2819
|
+
const rect = tableCell.getBoundingClientRect();
|
|
2820
|
+
const offsetX = Math.round(startX - rect.left);
|
|
2821
|
+
const isLeft = offsetX <= CELL_SELECT_MARGIN;
|
|
2822
|
+
const is = isLeft || startWidth - offsetX <= CELL_SELECT_MARGIN;
|
|
2441
2823
|
|
|
2442
|
-
|
|
2824
|
+
return {
|
|
2825
|
+
is,
|
|
2826
|
+
isLeft,
|
|
2827
|
+
startX
|
|
2828
|
+
};
|
|
2829
|
+
}
|
|
2443
2830
|
|
|
2444
|
-
|
|
2445
|
-
|
|
2831
|
+
/**
|
|
2832
|
+
* @private
|
|
2833
|
+
* @description Checks if a row is at its edge based on the mouse event.
|
|
2834
|
+
* @param {MouseEvent} event The mouse event.
|
|
2835
|
+
* @param {Element} tableCell The table row cell to check.
|
|
2836
|
+
* @returns {Object} An object containing row edge detection details.
|
|
2837
|
+
*/
|
|
2838
|
+
function CheckRowEdge(event, tableCell) {
|
|
2839
|
+
const startY = event.clientY;
|
|
2840
|
+
const startHeight = numbers.get(_w.getComputedStyle(tableCell).height, CELL_DECIMAL_END);
|
|
2841
|
+
const rect = tableCell.getBoundingClientRect();
|
|
2842
|
+
const is = Math.ceil(startHeight + rect.top - startY) <= ROW_SELECT_MARGIN;
|
|
2446
2843
|
|
|
2447
|
-
|
|
2448
|
-
|
|
2844
|
+
return {
|
|
2845
|
+
is,
|
|
2846
|
+
startY
|
|
2847
|
+
};
|
|
2449
2848
|
}
|
|
2450
2849
|
|
|
2451
|
-
|
|
2452
|
-
|
|
2850
|
+
/**
|
|
2851
|
+
* @private
|
|
2852
|
+
* @description Creates table cells as elements strings.
|
|
2853
|
+
* @param {string} nodeName The tag name of the cell (TD or TH).
|
|
2854
|
+
* @param {number} cnt The number of cells to create.
|
|
2855
|
+
* @returns {string} The created cells.
|
|
2856
|
+
*/
|
|
2857
|
+
function CreateCellsString(nodeName, cnt) {
|
|
2858
|
+
nodeName = nodeName.toLowerCase();
|
|
2859
|
+
return `<${nodeName}><div><br></div></${nodeName}>`.repeat(cnt);
|
|
2453
2860
|
}
|
|
2454
2861
|
|
|
2455
|
-
|
|
2456
|
-
|
|
2862
|
+
/**
|
|
2863
|
+
* @private
|
|
2864
|
+
* @description Creates table cells as element HTML.
|
|
2865
|
+
* @param {string} nodeName The tag name of the cell (TD or TH).
|
|
2866
|
+
* @returns {HTMLTableCellElement} The created cells.
|
|
2867
|
+
*/
|
|
2868
|
+
function CreateCellsHTML(nodeName) {
|
|
2869
|
+
nodeName = nodeName.toLowerCase();
|
|
2870
|
+
return /** @type {HTMLTableCellElement} */ (dom.utils.createElement(nodeName, null, '<div><br></div>'));
|
|
2457
2871
|
}
|
|
2458
2872
|
|
|
2873
|
+
/**
|
|
2874
|
+
* @private
|
|
2875
|
+
* @description Gets the maximum number of columns in a table.
|
|
2876
|
+
* @param {HTMLTableElement} table The table element.
|
|
2877
|
+
* @returns {number} The maximum number of columns in the table.
|
|
2878
|
+
*/
|
|
2459
2879
|
function GetMaxColumns(table) {
|
|
2880
|
+
const rows = table.rows;
|
|
2460
2881
|
let maxColumns = 0;
|
|
2461
2882
|
|
|
2462
|
-
for (
|
|
2883
|
+
for (let i = 0, len = rows.length; i < len; i++) {
|
|
2884
|
+
const cells = rows[i].cells;
|
|
2463
2885
|
let columnCount = 0;
|
|
2464
|
-
|
|
2465
|
-
|
|
2886
|
+
|
|
2887
|
+
for (let j = 0, jLen = cells.length; j < jLen; j++) {
|
|
2888
|
+
columnCount += cells[j].colSpan;
|
|
2466
2889
|
}
|
|
2890
|
+
|
|
2467
2891
|
maxColumns = Math.max(maxColumns, columnCount);
|
|
2468
2892
|
}
|
|
2469
2893
|
|
|
2470
2894
|
return maxColumns;
|
|
2471
2895
|
}
|
|
2472
2896
|
|
|
2897
|
+
/**
|
|
2898
|
+
* @private
|
|
2899
|
+
* @description Handles border style changes in table properties.
|
|
2900
|
+
* @param {string} command The border style command.
|
|
2901
|
+
*/
|
|
2473
2902
|
function OnPropsBorderEdit(command) {
|
|
2474
2903
|
this.propTargets.border_style.textContent = command;
|
|
2475
2904
|
this._disableBorderProps(command === BORDER_LIST[0]);
|
|
2476
2905
|
this.selectMenu_props_border.close();
|
|
2477
2906
|
}
|
|
2478
2907
|
|
|
2908
|
+
/**
|
|
2909
|
+
* @private
|
|
2910
|
+
* @description Handles border format changes in table properties.
|
|
2911
|
+
* @param {string} defaultCommand The default border format command.
|
|
2912
|
+
* @param {string} command The new border format command.
|
|
2913
|
+
*/
|
|
2479
2914
|
function OnPropsBorderFormatEdit(defaultCommand, command) {
|
|
2480
2915
|
const { border_format } = this.propTargets;
|
|
2481
2916
|
|
|
2482
2917
|
border_format.setAttribute('se-border-format', command);
|
|
2483
2918
|
border_format.firstElementChild.innerHTML = this.icons[BORDER_FORMATS[command]];
|
|
2484
|
-
if (command !== defaultCommand)
|
|
2485
|
-
else
|
|
2919
|
+
if (command !== defaultCommand) dom.utils.addClass(border_format, 'active');
|
|
2920
|
+
else dom.utils.removeClass(border_format, 'active');
|
|
2486
2921
|
|
|
2487
2922
|
this.selectMenu_props_border_format.close();
|
|
2488
2923
|
this.selectMenu_props_border_format_oneCell.close();
|
|
@@ -2490,7 +2925,7 @@ function OnPropsBorderFormatEdit(defaultCommand, command) {
|
|
|
2490
2925
|
|
|
2491
2926
|
// init element
|
|
2492
2927
|
function CreateSplitMenu(lang) {
|
|
2493
|
-
const menus =
|
|
2928
|
+
const menus = dom.utils.createElement(
|
|
2494
2929
|
'DIV',
|
|
2495
2930
|
null,
|
|
2496
2931
|
/*html*/ `
|
|
@@ -2506,7 +2941,7 @@ function CreateSplitMenu(lang) {
|
|
|
2506
2941
|
}
|
|
2507
2942
|
|
|
2508
2943
|
function CreateColumnMenu(lang, icons) {
|
|
2509
|
-
const menus =
|
|
2944
|
+
const menus = dom.utils.createElement(
|
|
2510
2945
|
'DIV',
|
|
2511
2946
|
null,
|
|
2512
2947
|
/*html*/ `
|
|
@@ -2525,7 +2960,7 @@ function CreateColumnMenu(lang, icons) {
|
|
|
2525
2960
|
}
|
|
2526
2961
|
|
|
2527
2962
|
function CreateRowMenu(lang, icons) {
|
|
2528
|
-
const menus =
|
|
2963
|
+
const menus = dom.utils.createElement(
|
|
2529
2964
|
'DIV',
|
|
2530
2965
|
null,
|
|
2531
2966
|
/*html*/ `
|
|
@@ -2554,7 +2989,7 @@ function CreateBorderMenu() {
|
|
|
2554
2989
|
</div>`;
|
|
2555
2990
|
}
|
|
2556
2991
|
|
|
2557
|
-
const menus =
|
|
2992
|
+
const menus = dom.utils.createElement('DIV', null, html);
|
|
2558
2993
|
return { items: BORDER_LIST, menus: menus.querySelectorAll('div') };
|
|
2559
2994
|
}
|
|
2560
2995
|
|
|
@@ -2575,7 +3010,7 @@ function CreateBorderFormatMenu(langs, icons, indideFormats) {
|
|
|
2575
3010
|
</button>`;
|
|
2576
3011
|
}
|
|
2577
3012
|
|
|
2578
|
-
const menus =
|
|
3013
|
+
const menus = dom.utils.createElement('DIV', null, html);
|
|
2579
3014
|
return { items, menus: menus.querySelectorAll('button') };
|
|
2580
3015
|
}
|
|
2581
3016
|
|
|
@@ -2588,7 +3023,7 @@ function CreateHTML() {
|
|
|
2588
3023
|
</div>
|
|
2589
3024
|
<div class="se-table-size-display">1 x 1</div>`;
|
|
2590
3025
|
|
|
2591
|
-
return
|
|
3026
|
+
return dom.utils.createElement('DIV', { class: 'se-dropdown se-selector-table' }, html);
|
|
2592
3027
|
}
|
|
2593
3028
|
|
|
2594
3029
|
function CreateHTML_controller_table({ lang, icons }) {
|
|
@@ -2633,9 +3068,13 @@ function CreateHTML_controller_table({ lang, icons }) {
|
|
|
2633
3068
|
</button>
|
|
2634
3069
|
</div>`;
|
|
2635
3070
|
|
|
2636
|
-
return
|
|
3071
|
+
return dom.utils.createElement('DIV', { class: 'se-controller se-controller-table' }, html);
|
|
2637
3072
|
}
|
|
2638
3073
|
|
|
3074
|
+
/**
|
|
3075
|
+
* @param {__se__EditorCore} editor
|
|
3076
|
+
* @returns {{ html: HTMLElement, splitButton: HTMLButtonElement, columnButton: HTMLButtonElement, rowButton: HTMLButtonElement, mergeButton: HTMLButtonElement }}
|
|
3077
|
+
*/
|
|
2639
3078
|
function CreateHTML_controller_cell({ lang, icons }, cellControllerTop) {
|
|
2640
3079
|
const html = /*html*/ `
|
|
2641
3080
|
<div class="se-arrow se-arrow-${cellControllerTop ? 'down se-visible-hidden' : 'up'}"></div>
|
|
@@ -2672,9 +3111,44 @@ function CreateHTML_controller_cell({ lang, icons }, cellControllerTop) {
|
|
|
2672
3111
|
</button>
|
|
2673
3112
|
</div>`;
|
|
2674
3113
|
|
|
2675
|
-
|
|
3114
|
+
const content = dom.utils.createElement('DIV', { class: 'se-controller se-controller-table-cell' }, html);
|
|
3115
|
+
|
|
3116
|
+
return {
|
|
3117
|
+
html: content,
|
|
3118
|
+
splitButton: content.querySelector('[data-command="onsplit"]'),
|
|
3119
|
+
columnButton: content.querySelector('[data-command="oncolumn"]'),
|
|
3120
|
+
rowButton: content.querySelector('[data-command="onrow"]'),
|
|
3121
|
+
mergeButton: content.querySelector('[data-command="merge"]')
|
|
3122
|
+
};
|
|
2676
3123
|
}
|
|
2677
3124
|
|
|
3125
|
+
/**
|
|
3126
|
+
|
|
3127
|
+
*/
|
|
3128
|
+
|
|
3129
|
+
/**
|
|
3130
|
+
* @typedef {Object} TableCtrlProps
|
|
3131
|
+
* @property {HTMLElement} html
|
|
3132
|
+
* @property {HTMLElement} controller_props_title
|
|
3133
|
+
* @property {HTMLButtonElement} borderButton
|
|
3134
|
+
* @property {HTMLButtonElement} borderFormatButton
|
|
3135
|
+
* @property {HTMLElement} cell_alignment
|
|
3136
|
+
* @property {HTMLElement} cell_alignment_vertical
|
|
3137
|
+
* @property {HTMLElement} cell_alignment_table_text
|
|
3138
|
+
* @property {HTMLButtonElement} border_style
|
|
3139
|
+
* @property {HTMLInputElement} border_color
|
|
3140
|
+
* @property {HTMLInputElement} border_width
|
|
3141
|
+
* @property {HTMLInputElement} back_color
|
|
3142
|
+
* @property {HTMLInputElement} font_color
|
|
3143
|
+
* @property {HTMLButtonElement} palette_border_button
|
|
3144
|
+
* @property {HTMLButtonElement} font_bold
|
|
3145
|
+
* @property {HTMLButtonElement} font_underline
|
|
3146
|
+
* @property {HTMLButtonElement} font_italic
|
|
3147
|
+
* @property {HTMLButtonElement} font_strike
|
|
3148
|
+
*
|
|
3149
|
+
* @param {__se__EditorCore} editor - Editor instance
|
|
3150
|
+
* @returns {TableCtrlProps}
|
|
3151
|
+
*/
|
|
2678
3152
|
function CreateHTML_controller_properties({ lang, icons, options }) {
|
|
2679
3153
|
const alignItems = options.get('_rtl') ? ['right', 'center', 'left', 'justify'] : ['left', 'center', 'right', 'justify'];
|
|
2680
3154
|
let alignHtml = '';
|
|
@@ -2682,14 +3156,12 @@ function CreateHTML_controller_properties({ lang, icons, options }) {
|
|
|
2682
3156
|
item = alignItems[i];
|
|
2683
3157
|
text = lang['align' + item.charAt(0).toUpperCase() + item.slice(1)];
|
|
2684
3158
|
alignHtml += /*html*/ `
|
|
2685
|
-
<
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
<span class="se-tooltip-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
</button>
|
|
2692
|
-
</li>`;
|
|
3159
|
+
<button type="button" class="se-btn se-tooltip" data-command="props_align" data-value="${item}" title="${text}" aria-label="${text}">
|
|
3160
|
+
${icons['align_' + item]}
|
|
3161
|
+
<span class="se-tooltip-inner">
|
|
3162
|
+
<span class="se-tooltip-text">${text}</span>
|
|
3163
|
+
</span>
|
|
3164
|
+
</button>`;
|
|
2693
3165
|
}
|
|
2694
3166
|
|
|
2695
3167
|
// vertical align html
|
|
@@ -2699,14 +3171,12 @@ function CreateHTML_controller_properties({ lang, icons, options }) {
|
|
|
2699
3171
|
item = verticalAligns[i];
|
|
2700
3172
|
text = lang['align' + item.charAt(0).toUpperCase() + item.slice(1)];
|
|
2701
3173
|
verticalAlignHtml += /*html*/ `
|
|
2702
|
-
<
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
<span class="se-tooltip-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
</button>
|
|
2709
|
-
</li>`;
|
|
3174
|
+
<button type="button" class="se-btn se-tooltip" data-command="props_align_vertical" data-value="${item}" title="${text}" aria-label="${text}">
|
|
3175
|
+
${icons['align_' + item]}
|
|
3176
|
+
<span class="se-tooltip-inner">
|
|
3177
|
+
<span class="se-tooltip-text">${text}</span>
|
|
3178
|
+
</span>
|
|
3179
|
+
</button>`;
|
|
2710
3180
|
}
|
|
2711
3181
|
|
|
2712
3182
|
const html = /*html*/ `
|
|
@@ -2789,12 +3259,14 @@ function CreateHTML_controller_properties({ lang, icons, options }) {
|
|
|
2789
3259
|
</div>
|
|
2790
3260
|
|
|
2791
3261
|
<div class="se-table-props-align">
|
|
2792
|
-
<label>${lang.align}</label>
|
|
2793
|
-
<div class="se-form-group se-form-w0 se-list-inner
|
|
2794
|
-
<
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
<
|
|
3262
|
+
<label>${lang.align} <span class="__se__a_table_t">( ${lang.table} )</span></label>
|
|
3263
|
+
<div class="se-form-group se-form-w0 se-list-inner">
|
|
3264
|
+
<div class="__se__a_h">
|
|
3265
|
+
${alignHtml}
|
|
3266
|
+
</div>
|
|
3267
|
+
<div class="__se__a_v">
|
|
3268
|
+
${verticalAlignHtml}
|
|
3269
|
+
</div>
|
|
2798
3270
|
</div>
|
|
2799
3271
|
</div>
|
|
2800
3272
|
</div>
|
|
@@ -2804,7 +3276,27 @@ function CreateHTML_controller_properties({ lang, icons, options }) {
|
|
|
2804
3276
|
</div>
|
|
2805
3277
|
</div>`;
|
|
2806
3278
|
|
|
2807
|
-
|
|
3279
|
+
const content = dom.utils.createElement('DIV', { class: 'se-controller se-table-props' }, html);
|
|
3280
|
+
|
|
3281
|
+
return {
|
|
3282
|
+
html: content,
|
|
3283
|
+
controller_props_title: content.querySelector('.se-controller-title'),
|
|
3284
|
+
borderButton: content.querySelector('[data-command="props_onborder_style"]'),
|
|
3285
|
+
borderFormatButton: content.querySelector('[data-command="props_onborder_format"]'),
|
|
3286
|
+
cell_alignment: content.querySelector('.se-table-props-align .__se__a_h'),
|
|
3287
|
+
cell_alignment_vertical: content.querySelector('.se-table-props-align .__se__a_v'),
|
|
3288
|
+
cell_alignment_table_text: content.querySelector('.se-table-props-align .__se__a_table_t'),
|
|
3289
|
+
border_style: content.querySelector('[data-command="props_onborder_style"] .se-txt'),
|
|
3290
|
+
border_color: content.querySelector('.__se_border_color'),
|
|
3291
|
+
border_width: content.querySelector('.__se__border_size'),
|
|
3292
|
+
back_color: content.querySelector('.__se_back_color'),
|
|
3293
|
+
font_color: content.querySelector('.__se_font_color'),
|
|
3294
|
+
palette_border_button: content.querySelector('[data-command="props_onpalette"][data-value="border"]'),
|
|
3295
|
+
font_bold: content.querySelector('[data-command="props_font_style"][data-value="bold"]'),
|
|
3296
|
+
font_underline: content.querySelector('[data-command="props_font_style"][data-value="underline"]'),
|
|
3297
|
+
font_italic: content.querySelector('[data-command="props_font_style"][data-value="italic"]'),
|
|
3298
|
+
font_strike: content.querySelector('[data-command="props_font_style"][data-value="strike"]')
|
|
3299
|
+
};
|
|
2808
3300
|
}
|
|
2809
3301
|
|
|
2810
3302
|
export default Table;
|