suneditor 3.0.0-alpha.13 → 3.0.0-alpha.15
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/dist/suneditor.min.css +1 -1
- package/dist/suneditor.min.js +1 -1
- package/package.json +2 -1
- package/src/assets/icons/_default.js +9 -2
- package/src/assets/suneditor-contents.css +9 -22
- package/src/assets/suneditor.css +317 -183
- package/src/assets/variables.css +137 -0
- package/src/core/base/eventHandlers/handler_toolbar.js +1 -0
- package/src/core/base/eventHandlers/handler_ww_dragDrop.js +9 -2
- package/src/core/base/eventHandlers/handler_ww_key_input.js +1 -1
- package/src/core/base/eventManager.js +5 -0
- package/src/core/class/component.js +12 -8
- package/src/core/class/html.js +5 -5
- package/src/core/class/offset.js +11 -3
- package/src/core/class/selection.js +5 -4
- package/src/core/class/toolbar.js +1 -5
- package/src/core/class/viewer.js +29 -7
- package/src/core/editor.js +61 -1
- package/src/core/section/actives.js +5 -0
- package/src/core/section/constructor.js +35 -19
- package/src/core/section/documentType.js +143 -19
- package/src/helper/domUtils.js +5 -4
- package/src/langs/en.js +5 -0
- package/src/modules/Modal.js +108 -1
- package/src/plugins/command/exportPdf.js +1 -1
- package/src/plugins/command/list_bulleted.js +1 -1
- package/src/plugins/command/list_numbered.js +1 -1
- package/src/plugins/index.js +6 -0
- package/src/plugins/input/fontSize.js +3 -3
- package/src/plugins/input/pageNavigator.js +47 -0
- package/src/plugins/modal/drawing.js +426 -0
- package/src/plugins/modal/image.js +3 -2
- package/src/plugins/modal/math.js +72 -34
- package/src/themes/dark-variables.css +85 -0
- package/src/themes/test.css +0 -61
|
@@ -43,6 +43,7 @@ const DEFAULT_CONTENT_STYLES =
|
|
|
43
43
|
'margin|margin-block-end|margin-block-start|margin-bottom|margin-inline-end|margin-inline-start|margin-left|margin-right|margin-top|max-width|min-width|' +
|
|
44
44
|
'outline|overflow|' +
|
|
45
45
|
'position|padding|padding-bottom|padding-inline-start|padding-left|padding-right|padding-top|' +
|
|
46
|
+
'page-break-before|page-break-after|page-break-inside|' +
|
|
46
47
|
'rotate|rotateX|rotateY|' +
|
|
47
48
|
'table-layout|text-align|text-decoration|text-shadow|text-transform|top|' +
|
|
48
49
|
'text-indent|text-rendering|' +
|
|
@@ -118,7 +119,7 @@ const Constructor = function (editorTargets, options) {
|
|
|
118
119
|
const loadingBox = domUtils.createElement('DIV', { class: 'se-loading-box sun-editor-common' }, '<div class="se-loading-effect"></div>');
|
|
119
120
|
|
|
120
121
|
/** --- carrier wrapper --------------------------------------------------------------- */
|
|
121
|
-
const editor_carrier_wrapper = domUtils.createElement('DIV', { class: 'sun-editor sun-editor-carrier-wrapper sun-editor-common' + (o.get('_rtl') ? ' se-rtl' : '') });
|
|
122
|
+
const editor_carrier_wrapper = domUtils.createElement('DIV', { class: 'sun-editor sun-editor-carrier-wrapper sun-editor-common' + o.get('_themeClass') + (o.get('_rtl') ? ' se-rtl' : '') });
|
|
122
123
|
// menuTray
|
|
123
124
|
const menuTray = domUtils.createElement('DIV', { class: 'se-menu-tray' });
|
|
124
125
|
editor_carrier_wrapper.appendChild(menuTray);
|
|
@@ -185,7 +186,7 @@ const Constructor = function (editorTargets, options) {
|
|
|
185
186
|
for (let i = 0, len = editorTargets.length; i < len; i++) {
|
|
186
187
|
const editTarget = editorTargets[i];
|
|
187
188
|
const to = editTarget.options;
|
|
188
|
-
const top_div = domUtils.createElement('DIV', { class: 'sun-editor' + (to.get('_rtl') ? ' se-rtl' : '') });
|
|
189
|
+
const top_div = domUtils.createElement('DIV', { class: 'sun-editor' + o.get('_themeClass') + (to.get('_rtl') ? ' se-rtl' : '') });
|
|
189
190
|
const container = domUtils.createElement('DIV', { class: 'se-container' });
|
|
190
191
|
const editor_div = domUtils.createElement('DIV', { class: 'se-wrapper' + (o.get('type') === 'document' ? ' se-type-document' : '') });
|
|
191
192
|
|
|
@@ -215,7 +216,7 @@ const Constructor = function (editorTargets, options) {
|
|
|
215
216
|
if (statusbar) {
|
|
216
217
|
if (statusbarContainer) {
|
|
217
218
|
if (!default_status_bar) {
|
|
218
|
-
statusbarContainer.appendChild(domUtils.createElement('DIV', { class: 'sun-editor' }, statusbar));
|
|
219
|
+
statusbarContainer.appendChild(domUtils.createElement('DIV', { class: 'sun-editor' + o.get('_themeClass') }, statusbar));
|
|
219
220
|
default_status_bar = statusbar;
|
|
220
221
|
}
|
|
221
222
|
} else {
|
|
@@ -264,7 +265,7 @@ const Constructor = function (editorTargets, options) {
|
|
|
264
265
|
// toolbar container
|
|
265
266
|
const toolbar_container = o.get('toolbar_container');
|
|
266
267
|
if (toolbar_container) {
|
|
267
|
-
const top_div = domUtils.createElement('DIV', { class: 'sun-editor' + (o.get('_rtl') ? ' se-rtl' : '') });
|
|
268
|
+
const top_div = domUtils.createElement('DIV', { class: 'sun-editor' + o.get('_themeClass') + (o.get('_rtl') ? ' se-rtl' : '') });
|
|
268
269
|
const container = domUtils.createElement('DIV', { class: 'se-container' });
|
|
269
270
|
container.appendChild(toolbar);
|
|
270
271
|
if (subbar) container.appendChild(subbar);
|
|
@@ -362,6 +363,7 @@ export function InitOptions(options, editorTargets, plugins) {
|
|
|
362
363
|
o.set('v2Migration', !!options.v2Migration);
|
|
363
364
|
|
|
364
365
|
/** Base */
|
|
366
|
+
o.set('buttons', new Set(buttonList.toString().split(',')));
|
|
365
367
|
const modeValue = options.strictMode !== false;
|
|
366
368
|
o.set('strictMode', {
|
|
367
369
|
tagFilter: modeValue,
|
|
@@ -376,6 +378,8 @@ export function InitOptions(options, editorTargets, plugins) {
|
|
|
376
378
|
o.set('__pluginRetainFilter', options.__pluginRetainFilter ?? true);
|
|
377
379
|
o.set('mode', options.mode || 'classic'); // classic, inline, balloon, balloon-always
|
|
378
380
|
o.set('type', options.type?.split(':')[0] || ''); // document:header,page
|
|
381
|
+
o.set('theme', options.theme || '');
|
|
382
|
+
o.set('_themeClass', options.theme ? ` se-theme-${options.theme}` : '');
|
|
379
383
|
o.set('type-options', options.type?.split(':')[1] || '');
|
|
380
384
|
o.set('externalLibs', options.externalLibs || {});
|
|
381
385
|
o.set('keepStyleOnDelete', !!options.keepStyleOnDelete);
|
|
@@ -485,9 +489,9 @@ export function InitOptions(options, editorTargets, plugins) {
|
|
|
485
489
|
|
|
486
490
|
// etc
|
|
487
491
|
o.set('historyStackDelayTime', typeof options.historyStackDelayTime === 'number' ? options.historyStackDelayTime : 400);
|
|
488
|
-
o.set('_editableClass', 'sun-editor-editable' + (o.get('_rtl') ? ' se-rtl' : ''));
|
|
492
|
+
o.set('_editableClass', 'sun-editor-editable' + o.get('_themeClass') + (o.get('_rtl') ? ' se-rtl' : ''));
|
|
489
493
|
o.set('lineAttrReset', ['id'].concat(options.lineAttrReset && typeof options.lineAttrReset === 'string' ? options.lineAttrReset.toLowerCase().split('|') : []));
|
|
490
|
-
o.set('printClass', typeof options.printClass === 'string' ? options.printClass : null);
|
|
494
|
+
o.set('printClass', typeof options.printClass === 'string' ? options.printClass + ' ' + o.get('_editableClass') : null);
|
|
491
495
|
|
|
492
496
|
/** whitelist, blacklist */
|
|
493
497
|
// default line
|
|
@@ -571,6 +575,7 @@ export function InitOptions(options, editorTargets, plugins) {
|
|
|
571
575
|
o.set('_subMode', subbar.mode || 'balloon');
|
|
572
576
|
o.set('toolbar.sub_width', subbar.width ? (numbers.is(subbar.width) ? subbar.width + 'px' : subbar.width) : 'auto');
|
|
573
577
|
subButtons = o.get('_rtl') ? subbar.buttonList.reverse() : subbar.buttonList;
|
|
578
|
+
o.set('buttons_sub', new Set(subButtons.toString().split(',')));
|
|
574
579
|
}
|
|
575
580
|
}
|
|
576
581
|
|
|
@@ -986,7 +991,12 @@ function _defaultButtons(options, icons, lang) {
|
|
|
986
991
|
dir_rtl: ['', lang.dir_rtl, 'dir_rtl', '', icons.dir_rtl],
|
|
987
992
|
save: ['se-component-enabled', lang.save, 'save', '', icons.save],
|
|
988
993
|
newDocument: ['se-component-enabled', lang.newDocument, 'newDocument', '', icons.new_document],
|
|
989
|
-
selectAll: ['se-component-enabled', lang.selectAll, 'selectAll', '', icons.select_all]
|
|
994
|
+
selectAll: ['se-component-enabled', lang.selectAll, 'selectAll', '', icons.select_all],
|
|
995
|
+
pageBreak: ['se-component-enabled', lang.pageBreak, 'pageBreak', '', icons.page_break],
|
|
996
|
+
// document type buttons
|
|
997
|
+
pageUp: ['se-component-enabled', lang.pageUp, 'pageUp', '', icons.page_up],
|
|
998
|
+
pageDown: ['se-component-enabled', lang.pageDown, 'pageDown', '', icons.page_down],
|
|
999
|
+
pageNavigator: ['se-component-enabled', '', 'pageNavigator', 'input', '']
|
|
990
1000
|
};
|
|
991
1001
|
}
|
|
992
1002
|
|
|
@@ -1016,6 +1026,8 @@ function _createModuleGroup() {
|
|
|
1016
1026
|
* @returns {Object}
|
|
1017
1027
|
*/
|
|
1018
1028
|
function _createButton(className, title, dataCommand, dataType, innerHTML, _disabled, icons) {
|
|
1029
|
+
if (!innerHTML) innerHTML = '';
|
|
1030
|
+
|
|
1019
1031
|
const oLi = domUtils.createElement('LI');
|
|
1020
1032
|
const label = title || '';
|
|
1021
1033
|
const isDiv = /^INPUT|FIELD$/i.test(dataType);
|
|
@@ -1066,9 +1078,13 @@ export function UpdateButton(element, plugin, icons, lang) {
|
|
|
1066
1078
|
|
|
1067
1079
|
const noneInner = plugin.inner === false;
|
|
1068
1080
|
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1081
|
+
if (plugin.inner?.nodeType === 1) {
|
|
1082
|
+
element.appendChild(plugin.inner);
|
|
1083
|
+
} else {
|
|
1084
|
+
element.innerHTML = noneInner
|
|
1085
|
+
? ''
|
|
1086
|
+
: (plugin.inner || icons[plugin.icon] || plugin.icon || '<span class="se-icon-text">!</span>') + '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + (lang[plugin.title] || plugin.title) + '</span></span>';
|
|
1087
|
+
}
|
|
1072
1088
|
|
|
1073
1089
|
element.setAttribute('aria-label', plugin.title);
|
|
1074
1090
|
|
|
@@ -1081,24 +1097,24 @@ export function UpdateButton(element, plugin, icons, lang) {
|
|
|
1081
1097
|
}
|
|
1082
1098
|
|
|
1083
1099
|
// side, replace button
|
|
1084
|
-
if (plugin.
|
|
1085
|
-
domUtils.addClass(plugin.
|
|
1086
|
-
element.parentElement.appendChild(plugin.
|
|
1100
|
+
if (plugin.afterItem) {
|
|
1101
|
+
domUtils.addClass(plugin.afterItem, 'se-toolbar-btn');
|
|
1102
|
+
element.parentElement.appendChild(plugin.afterItem);
|
|
1087
1103
|
|
|
1088
1104
|
domUtils.addClass(element, 'se-side-btn-a');
|
|
1089
|
-
domUtils.addClass(plugin.
|
|
1105
|
+
domUtils.addClass(plugin.afterItem, 'se-side-btn-after');
|
|
1090
1106
|
}
|
|
1091
|
-
if (plugin.
|
|
1092
|
-
domUtils.addClass(plugin.
|
|
1093
|
-
element.parentElement.insertBefore(plugin.
|
|
1107
|
+
if (plugin.beforeItem) {
|
|
1108
|
+
domUtils.addClass(plugin.beforeItem, 'se-toolbar-btn');
|
|
1109
|
+
element.parentElement.insertBefore(plugin.beforeItem, element);
|
|
1094
1110
|
|
|
1095
|
-
if (plugin.
|
|
1111
|
+
if (plugin.afterItem) {
|
|
1096
1112
|
domUtils.addClass(element, 'se-side-btn');
|
|
1097
1113
|
domUtils.removeClass(element, 'se-side-btn-a');
|
|
1098
1114
|
} else {
|
|
1099
1115
|
domUtils.addClass(element, 'se-side-btn-b');
|
|
1100
1116
|
}
|
|
1101
|
-
domUtils.addClass(plugin.
|
|
1117
|
+
domUtils.addClass(plugin.beforeItem, 'se-side-btn-before');
|
|
1102
1118
|
}
|
|
1103
1119
|
if (plugin.replaceButton) {
|
|
1104
1120
|
element.parentElement.appendChild(plugin.replaceButton);
|
|
@@ -2,27 +2,38 @@
|
|
|
2
2
|
* @fileoverview DocumentType class
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { domUtils, numbers, env } from '../../helper';
|
|
5
|
+
import { domUtils, numbers, converter, env } from '../../helper';
|
|
6
6
|
|
|
7
|
+
const { _w } = env;
|
|
7
8
|
const A4_HEIGHT_INCHES = 11.7; // A4 height(inches)
|
|
8
|
-
const A4_HEIGHT = A4_HEIGHT_INCHES *
|
|
9
|
+
const A4_HEIGHT = A4_HEIGHT_INCHES * 96; // 1 inch = 96px
|
|
9
10
|
|
|
10
11
|
const DocumentType = function (editor, fc) {
|
|
11
12
|
// members
|
|
12
13
|
this.editor = editor;
|
|
14
|
+
this.selection = editor.selection;
|
|
15
|
+
this.offset = editor.offset;
|
|
13
16
|
this.fc = fc;
|
|
14
17
|
this.ww = fc.get('wysiwyg');
|
|
15
18
|
this.wwFrame = fc.get('wysiwygFrame');
|
|
16
19
|
this.wwWidth = -1;
|
|
20
|
+
this.wwHeight = -1;
|
|
21
|
+
this.isAutoHeight = fc.get('options').get('height') === 'auto';
|
|
22
|
+
this.displayPage = this.isAutoHeight ? _w : fc.get('wysiwyg');
|
|
17
23
|
this.innerHeaders = [];
|
|
18
24
|
this._wwHeaders = [];
|
|
19
25
|
this.inner = null;
|
|
20
26
|
this.page = null;
|
|
27
|
+
this.totalPages = 0;
|
|
28
|
+
this.pageNum = 0;
|
|
21
29
|
this.pageHeight = -1;
|
|
22
30
|
this.pages = [];
|
|
23
31
|
this.pages_line = [];
|
|
32
|
+
this.prevScrollTop = 0;
|
|
24
33
|
this.useHeader = editor.options.get('type-options').includes('header');
|
|
25
34
|
this.usePage = editor.options.get('type-options').includes('page');
|
|
35
|
+
this.navigatorButtons = [];
|
|
36
|
+
this.pageNavigator = null;
|
|
26
37
|
|
|
27
38
|
// init header
|
|
28
39
|
if (this.useHeader) {
|
|
@@ -42,6 +53,7 @@ const DocumentType = function (editor, fc) {
|
|
|
42
53
|
// init page
|
|
43
54
|
if (this.usePage) {
|
|
44
55
|
this.page = fc.get('documentTypePage');
|
|
56
|
+
this.pageNavigator = editor.plugins.pageNavigator;
|
|
45
57
|
}
|
|
46
58
|
};
|
|
47
59
|
|
|
@@ -85,43 +97,101 @@ DocumentType.prototype = {
|
|
|
85
97
|
rePage() {
|
|
86
98
|
if (!this.page) return;
|
|
87
99
|
|
|
88
|
-
const height = this.
|
|
100
|
+
const height = this.displayPage.scrollHeight ?? this.ww.scrollHeight;
|
|
89
101
|
if (this.pageHeight === height) return;
|
|
90
102
|
this.pageHeight = height;
|
|
91
103
|
|
|
92
|
-
const page = this.page;
|
|
93
|
-
const scrollTop = this.ww.scrollTop;
|
|
94
|
-
const wwWidth = this.wwFrame.offsetWidth + 1;
|
|
95
104
|
const totalPages = Math.ceil(height / A4_HEIGHT);
|
|
105
|
+
const scrollTop = (this.prevScrollTop = this._getWWScrollTop());
|
|
106
|
+
const wwWidth = this.wwFrame.offsetWidth + 1;
|
|
107
|
+
const pageBreaks = this.ww.querySelectorAll('.se-page-break');
|
|
108
|
+
|
|
109
|
+
const pages = [];
|
|
110
|
+
const pageTop = this.page.offsetTop;
|
|
111
|
+
for (let i = 0, len = pageBreaks.length; i < len; i++) {
|
|
112
|
+
pages.push({ number: i, top: pageBreaks[i].offsetTop - pageTop + pageBreaks[i].offsetHeight / 2 - scrollTop });
|
|
113
|
+
}
|
|
96
114
|
|
|
115
|
+
for (let i = 0, t; i < totalPages; i++) {
|
|
116
|
+
t = i * A4_HEIGHT - scrollTop;
|
|
117
|
+
let inserted = false;
|
|
118
|
+
for (let j = 0, jLen = pages.length; j < jLen; j++) {
|
|
119
|
+
if (t < pages[j].top) {
|
|
120
|
+
pages.splice(j, 0, { number: i + pageBreaks.length, top: t });
|
|
121
|
+
inserted = true;
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (!inserted) {
|
|
126
|
+
pages.push({ number: i + pageBreaks.length, top: t });
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// set page number
|
|
97
131
|
this.page.innerHTML = '';
|
|
98
132
|
this.pages = [];
|
|
99
|
-
for (let i = 0; i <
|
|
100
|
-
const pageNumber = domUtils.createElement('DIV', { style: `top:${i
|
|
101
|
-
page.appendChild(pageNumber);
|
|
133
|
+
for (let i = 0, len = pages.length; i < len; i++) {
|
|
134
|
+
const pageNumber = domUtils.createElement('DIV', { style: `top:${pages[i].top}px`, innerHTML: i + 1 }, `<div class="se-document-page-line" style="width: ${wwWidth}px;"></div>${i + 1}`);
|
|
135
|
+
this.page.appendChild(pageNumber);
|
|
102
136
|
this.pages.push(pageNumber);
|
|
103
137
|
}
|
|
104
138
|
|
|
105
139
|
this.pages_line = this.page.querySelectorAll('.se-document-page-line');
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
scrollPage() {
|
|
109
|
-
const scrollTop = this.wwFrame.scrollTop;
|
|
110
|
-
const pages = this.pages;
|
|
111
|
-
for (let i = 0, len = pages.length; i < len; i++) {
|
|
112
|
-
pages[i].style.top = `${i * A4_HEIGHT - scrollTop}px`;
|
|
113
|
-
}
|
|
140
|
+
this.totalPages = totalPages;
|
|
114
141
|
},
|
|
115
142
|
|
|
116
143
|
resizePage() {
|
|
117
144
|
const wwWidth = this.wwFrame.offsetWidth + 1;
|
|
118
|
-
|
|
145
|
+
const wwHeight = this.wwFrame.offsetHeight + 1;
|
|
146
|
+
if (wwWidth === this.wwWidth || wwHeight === this.wwHeight) return;
|
|
119
147
|
|
|
120
148
|
this.wwWidth = wwWidth;
|
|
149
|
+
this.wwHeight = wwHeight;
|
|
121
150
|
const pages_line = this.pages_line;
|
|
122
151
|
for (let i = 0, len = pages_line.length; i < len; i++) {
|
|
123
152
|
pages_line[i].style.width = `${wwWidth}px`;
|
|
124
153
|
}
|
|
154
|
+
|
|
155
|
+
this._displayCurrentPage();
|
|
156
|
+
},
|
|
157
|
+
|
|
158
|
+
scrollPage() {
|
|
159
|
+
const prevScrollTop = this.prevScrollTop;
|
|
160
|
+
const scrollTop = this._getWWScrollTop();
|
|
161
|
+
if (prevScrollTop === scrollTop) return;
|
|
162
|
+
|
|
163
|
+
const pages = this.pages;
|
|
164
|
+
for (let i = 0, len = pages.length; i < len; i++) {
|
|
165
|
+
pages[i].style.top = `${numbers.get(pages[i].style.top) - (scrollTop - prevScrollTop)}px`;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
this.prevScrollTop = scrollTop;
|
|
169
|
+
this._displayCurrentPage();
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
getCurrentPageNumber() {
|
|
173
|
+
if (this.totalPages <= 1) return 1;
|
|
174
|
+
|
|
175
|
+
const scrollTop = this.isAutoHeight ? _w.scrollY + this.wwHeight / 2 - this._getGlobalTop() : this._getWWScrollTop() + this.wwHeight / 2;
|
|
176
|
+
const pageNum = this.isAutoHeight ? Math.floor(scrollTop / A4_HEIGHT) : Math.ceil(scrollTop / A4_HEIGHT);
|
|
177
|
+
return (this.pageNum = pageNum < 1 ? 1 : pageNum > this.pages.length ? this.pages.length : pageNum);
|
|
178
|
+
},
|
|
179
|
+
|
|
180
|
+
pageUp() {
|
|
181
|
+
const pageNum = this.pageNum - 1 <= 1 ? 1 : this.pageNum - 1;
|
|
182
|
+
this._movePage(pageNum, false);
|
|
183
|
+
},
|
|
184
|
+
|
|
185
|
+
pageDown() {
|
|
186
|
+
const pageNum = this.pageNum + 1 > this.pages.length ? this.pages.length : this.pageNum + 1;
|
|
187
|
+
this._movePage(pageNum, false);
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
pageGo(pageNum) {
|
|
191
|
+
if (pageNum < 1) pageNum = 1;
|
|
192
|
+
else if (pageNum > this.pages.length) pageNum = this.pages.length;
|
|
193
|
+
|
|
194
|
+
this._movePage(pageNum, true);
|
|
125
195
|
},
|
|
126
196
|
|
|
127
197
|
on(line) {
|
|
@@ -146,6 +216,60 @@ DocumentType.prototype = {
|
|
|
146
216
|
item.textContent = header.textContent;
|
|
147
217
|
},
|
|
148
218
|
|
|
219
|
+
scrollWindow() {
|
|
220
|
+
if (!this.isAutoHeight) return;
|
|
221
|
+
this._displayCurrentPage();
|
|
222
|
+
},
|
|
223
|
+
|
|
224
|
+
_displayCurrentPage() {
|
|
225
|
+
const pageNum = this.getCurrentPageNumber();
|
|
226
|
+
this.pageNavigator?.display(pageNum, this.totalPages);
|
|
227
|
+
},
|
|
228
|
+
|
|
229
|
+
_getWWScrollTop() {
|
|
230
|
+
return this.displayPage.scrollTop || 0;
|
|
231
|
+
},
|
|
232
|
+
|
|
233
|
+
_movePage(pageNum, force) {
|
|
234
|
+
if (!force && this.pageNum === pageNum) return;
|
|
235
|
+
|
|
236
|
+
const globalTop = this._getGlobalTop();
|
|
237
|
+
const children = converter.nodeListToArray(this.ww.children);
|
|
238
|
+
const pageTop = this.page.offsetTop + numbers.get(this.pages[pageNum - 1].style.top) + this._getWWScrollTop();
|
|
239
|
+
for (let i = 0, len = children.length, c; i < len; i++) {
|
|
240
|
+
c = children[i];
|
|
241
|
+
if (c.offsetTop >= pageTop) {
|
|
242
|
+
if (!force) this.selection.setRange(c, 0, c, 0);
|
|
243
|
+
const scrollTop = i === 0 && !this.isAutoHeight ? 0 : c.offsetTop - this.page.offsetTop - c.offsetHeight + globalTop;
|
|
244
|
+
this._applyPageScroll(scrollTop, () => {
|
|
245
|
+
if (this.editor.toolbar._sticky) {
|
|
246
|
+
this.displayPage.scrollTo({ top: scrollTop - this.editor.context.get('toolbar.main').offsetHeight, behavior: 'smooth' });
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
this.pageNum = pageNum;
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
_applyPageScroll(top, callback) {
|
|
257
|
+
this.displayPage.scrollTo({ top, behavior: 'smooth' });
|
|
258
|
+
const checkScrollEnd = () => {
|
|
259
|
+
if (Math.abs((this.displayPage.scrollY ?? this.displayPage.scrollTop) - top) < 1) {
|
|
260
|
+
callback();
|
|
261
|
+
} else {
|
|
262
|
+
_w.requestAnimationFrame(checkScrollEnd);
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
_w.requestAnimationFrame(checkScrollEnd);
|
|
267
|
+
},
|
|
268
|
+
|
|
269
|
+
_getGlobalTop() {
|
|
270
|
+
return this.isAutoHeight ? this.offset.getGlobal(this.wwFrame).top : 0;
|
|
271
|
+
},
|
|
272
|
+
|
|
149
273
|
_findItem(header) {
|
|
150
274
|
const headers = this._wwHeaders;
|
|
151
275
|
const index = Array.prototype.indexOf.call(headers, header);
|
|
@@ -191,7 +315,7 @@ function OnClickHeader(ww, e) {
|
|
|
191
315
|
|
|
192
316
|
const header = this._wwHeaders[innerIndex];
|
|
193
317
|
if (header) {
|
|
194
|
-
this.
|
|
318
|
+
this.selection.scrollTo(header);
|
|
195
319
|
}
|
|
196
320
|
}
|
|
197
321
|
} finally {
|
package/src/helper/domUtils.js
CHANGED
|
@@ -1163,11 +1163,12 @@ export function applyInlineStylesAll(wwTarget, includeWW, styles) {
|
|
|
1163
1163
|
tempTarget.appendChild(wwTarget);
|
|
1164
1164
|
_d.body.appendChild(tempTarget);
|
|
1165
1165
|
|
|
1166
|
-
const elements = wwTarget.querySelectorAll('*');
|
|
1167
|
-
for (let i =
|
|
1166
|
+
const elements = includeWW ? [wwTarget].concat(Array.from(wwTarget.querySelectorAll('*'))) : wwTarget.querySelectorAll('*');
|
|
1167
|
+
for (let i = 0, el; (el = elements[i]); i++) {
|
|
1168
1168
|
const computedStyle = _w.getComputedStyle(el);
|
|
1169
|
-
|
|
1170
|
-
|
|
1169
|
+
const els = el.style;
|
|
1170
|
+
for (const props of styles) {
|
|
1171
|
+
els.setProperty(props, computedStyle.getPropertyValue(props) || '');
|
|
1171
1172
|
}
|
|
1172
1173
|
}
|
|
1173
1174
|
|
package/src/langs/en.js
CHANGED
|
@@ -69,6 +69,8 @@
|
|
|
69
69
|
dir_rtl: 'Right to left',
|
|
70
70
|
download: 'Download',
|
|
71
71
|
drag: 'Drag',
|
|
72
|
+
drawing: 'Drawing',
|
|
73
|
+
drawing_modal_title: 'Drawing',
|
|
72
74
|
edit: 'Edit',
|
|
73
75
|
exportPdf: 'Export to PDF',
|
|
74
76
|
exportWord: 'Export to Word',
|
|
@@ -137,6 +139,9 @@
|
|
|
137
139
|
numberedList: 'Numbered list',
|
|
138
140
|
outdent: 'Outdent',
|
|
139
141
|
pageBreak: 'Page break',
|
|
142
|
+
pageDown: 'Page down',
|
|
143
|
+
pageNumber: 'Page number',
|
|
144
|
+
pageUp: 'Page up',
|
|
140
145
|
paragraphStyle: 'Paragraph style',
|
|
141
146
|
preview: 'Preview',
|
|
142
147
|
print: 'print',
|
package/src/modules/Modal.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import CoreInjector from '../editorInjector/_core';
|
|
2
2
|
import { CreateTooltipInner } from '../core/section/constructor';
|
|
3
|
-
import { env } from '../helper';
|
|
3
|
+
import { domUtils, env } from '../helper';
|
|
4
4
|
|
|
5
5
|
const { _w } = env;
|
|
6
|
+
const DIRECTION_CURSOR_MAP = { w: 'ns-resize', h: 'ew-resize', c: 'nwse-resize', wRTL: 'ns-resize', hRTL: 'ew-resize', cRTL: 'nesw-resize' };
|
|
6
7
|
|
|
7
8
|
const Modal = function (inst, element) {
|
|
8
9
|
CoreInjector.call(this, inst.editor);
|
|
10
|
+
this.offset = this.editor.offset;
|
|
9
11
|
|
|
10
12
|
// members
|
|
11
13
|
this.inst = inst;
|
|
@@ -20,6 +22,8 @@ const Modal = function (inst, element) {
|
|
|
20
22
|
this._bindClose = null;
|
|
21
23
|
this._onClickEvent = null;
|
|
22
24
|
this._closeSignal = false;
|
|
25
|
+
// resie
|
|
26
|
+
this._resizeBody = null;
|
|
23
27
|
|
|
24
28
|
// add element
|
|
25
29
|
this._modalInner.appendChild(element);
|
|
@@ -27,6 +31,26 @@ const Modal = function (inst, element) {
|
|
|
27
31
|
// init
|
|
28
32
|
this.eventManager.addEvent(element.querySelector('form'), 'submit', Action.bind(this));
|
|
29
33
|
this._closeSignal = !this.eventManager.addEvent(element.querySelector('[data-command="close"]'), 'click', this.close.bind(this));
|
|
34
|
+
|
|
35
|
+
// resize
|
|
36
|
+
if (element.querySelector('.se-modal-resize-handle-w') || element.querySelector('.se-modal-resize-handle-h') || element.querySelector('.se-modal-resize-handle-c') || element.querySelector('.se-modal-resize-form')) {
|
|
37
|
+
if (!(this._resizeBody = element.querySelector('.se-modal-resize-form')) && (this._resizeBody = element.querySelector('.se-modal-body'))) {
|
|
38
|
+
this.eventManager.addEvent(element.querySelector('.se-modal-resize-handle-w'), 'mousedown', OnResizeMouseDown.bind(this, 'w'));
|
|
39
|
+
this.eventManager.addEvent(element.querySelector('.se-modal-resize-handle-h'), 'mousedown', OnResizeMouseDown.bind(this, 'h'));
|
|
40
|
+
this.eventManager.addEvent(element.querySelector('.se-modal-resize-handle-c'), 'mousedown', OnResizeMouseDown.bind(this, 'c'));
|
|
41
|
+
|
|
42
|
+
this._currentHandle = null;
|
|
43
|
+
this.__resizeDir = '';
|
|
44
|
+
this.__offetTop = 0;
|
|
45
|
+
this.__offetLeft = 0;
|
|
46
|
+
this.__globalEventHandlers = {
|
|
47
|
+
mousemove: OnResize.bind(this),
|
|
48
|
+
mouseup: OnResizeMouseUp.bind(this)
|
|
49
|
+
};
|
|
50
|
+
this._bindClose_mousemove = null;
|
|
51
|
+
this._bindClose_mouseup = null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
30
54
|
};
|
|
31
55
|
|
|
32
56
|
Modal.prototype = {
|
|
@@ -51,6 +75,16 @@ Modal.prototype = {
|
|
|
51
75
|
this._modalInner.style.display = 'block';
|
|
52
76
|
this.form.style.display = 'block';
|
|
53
77
|
|
|
78
|
+
if (this._resizeBody) {
|
|
79
|
+
const offset = this._saveOffset();
|
|
80
|
+
const { maxWidth, maxHeight } = _w.getComputedStyle(this.form);
|
|
81
|
+
const mw = `${this.form.offsetWidth - offset.width}px`;
|
|
82
|
+
const mh = `${this.form.offsetTop + (this.form.offsetHeight - this._resizeBody.offsetHeight)}px`;
|
|
83
|
+
// set max
|
|
84
|
+
if (maxWidth && typeof this.__resizeDir === 'string') domUtils.setStyle(this._resizeBody, 'max-width', `calc(${maxWidth} - ${mw})`);
|
|
85
|
+
if (maxHeight) domUtils.setStyle(this._resizeBody, 'max-height', `calc(${maxHeight} - ${mh})`);
|
|
86
|
+
}
|
|
87
|
+
|
|
54
88
|
if (this.focusElement) this.focusElement.focus();
|
|
55
89
|
},
|
|
56
90
|
|
|
@@ -59,6 +93,7 @@ Modal.prototype = {
|
|
|
59
93
|
* The plugin's "init" method is called.
|
|
60
94
|
*/
|
|
61
95
|
close() {
|
|
96
|
+
this.__removeGlobalEvent();
|
|
62
97
|
this._fixCurrentController(false);
|
|
63
98
|
_w.setTimeout(() => {
|
|
64
99
|
this.editor.opendModal = null;
|
|
@@ -73,6 +108,7 @@ Modal.prototype = {
|
|
|
73
108
|
this._modalArea.style.display = 'none';
|
|
74
109
|
|
|
75
110
|
if (typeof this.inst.init === 'function') this.inst.init();
|
|
111
|
+
if (typeof this.inst.off === 'function') this.inst.off(this.isUpdate);
|
|
76
112
|
this.editor.focus();
|
|
77
113
|
},
|
|
78
114
|
|
|
@@ -84,6 +120,26 @@ Modal.prototype = {
|
|
|
84
120
|
}
|
|
85
121
|
},
|
|
86
122
|
|
|
123
|
+
_saveOffset() {
|
|
124
|
+
const offset = this.offset.getGlobal(this._resizeBody);
|
|
125
|
+
this.__offetTop = offset.top;
|
|
126
|
+
this.__offetLeft = offset.left;
|
|
127
|
+
return offset;
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
__addGlobalEvent(dir) {
|
|
131
|
+
this.__removeGlobalEvent();
|
|
132
|
+
this.editor.enableBackWrapper(DIRECTION_CURSOR_MAP[dir]);
|
|
133
|
+
this._bindClose_mousemove = this.eventManager.addGlobalEvent('mousemove', this.__globalEventHandlers.mousemove, true);
|
|
134
|
+
this._bindClose_mouseup = this.eventManager.addGlobalEvent('mouseup', this.__globalEventHandlers.mouseup, true);
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
__removeGlobalEvent() {
|
|
138
|
+
this.editor.disableBackWrapper();
|
|
139
|
+
if (this._bindClose_mousemove) this._bindClose_mousemove = this.eventManager.removeGlobalEvent(this._bindClose_mousemove);
|
|
140
|
+
if (this._bindClose_mouseup) this._bindClose_mouseup = this.eventManager.removeGlobalEvent(this._bindClose_mouseup);
|
|
141
|
+
},
|
|
142
|
+
|
|
87
143
|
constructor: Modal
|
|
88
144
|
};
|
|
89
145
|
|
|
@@ -130,6 +186,57 @@ function CloseListener(e) {
|
|
|
130
186
|
this.close();
|
|
131
187
|
}
|
|
132
188
|
|
|
189
|
+
/** Resize events */
|
|
190
|
+
function OnResizeMouseDown(dir, e) {
|
|
191
|
+
domUtils.addClass((this._currentHandle = e.target), 'active');
|
|
192
|
+
this.__addGlobalEvent((this.__resizeDir = dir + (this.options.get('_rtl') ? 'RTL' : '')));
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function OnResize(e) {
|
|
196
|
+
switch (this.__resizeDir) {
|
|
197
|
+
case 'w':
|
|
198
|
+
case 'wRTL': {
|
|
199
|
+
const h = e.clientY - this.__offetTop - this._resizeBody.offsetHeight;
|
|
200
|
+
this._resizeBody.style.height = this._resizeBody.offsetHeight + h + 'px';
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
case 'h': {
|
|
204
|
+
const w = e.clientX - this.__offetLeft - this._resizeBody.offsetWidth;
|
|
205
|
+
this._resizeBody.style.width = this._resizeBody.offsetWidth + w + 'px';
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
case 'hRTL': {
|
|
209
|
+
const w = this.__offetLeft - e.clientX;
|
|
210
|
+
this._resizeBody.style.width = this._resizeBody.offsetWidth + w + 'px';
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
case 'c': {
|
|
214
|
+
const w = e.clientX - this.__offetLeft - this._resizeBody.offsetWidth;
|
|
215
|
+
const h = e.clientY - this.__offetTop - this._resizeBody.offsetHeight;
|
|
216
|
+
this._resizeBody.style.width = this._resizeBody.offsetWidth + w + 'px';
|
|
217
|
+
this._resizeBody.style.height = this._resizeBody.offsetHeight + h + 'px';
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
case 'cRTL': {
|
|
221
|
+
const w = this.__offetLeft - e.clientX;
|
|
222
|
+
const h = e.clientY - this.__offetTop - this._resizeBody.offsetHeight;
|
|
223
|
+
this._resizeBody.style.width = this._resizeBody.offsetWidth + w + 'px';
|
|
224
|
+
this._resizeBody.style.height = this._resizeBody.offsetHeight + h + 'px';
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
this._saveOffset();
|
|
230
|
+
|
|
231
|
+
if (typeof this.inst.modalResize === 'function') this.inst.modalResize();
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function OnResizeMouseUp() {
|
|
235
|
+
domUtils.removeClass(this._currentHandle, 'active');
|
|
236
|
+
this._currentHandle = null;
|
|
237
|
+
this.__removeGlobalEvent();
|
|
238
|
+
}
|
|
239
|
+
|
|
133
240
|
// HTML Creator ======================================================================================================
|
|
134
241
|
|
|
135
242
|
// Create a file input tag
|
|
@@ -45,7 +45,7 @@ ExportPdf.prototype = {
|
|
|
45
45
|
|
|
46
46
|
try {
|
|
47
47
|
const topArea = this.editor.frameContext.get('topArea');
|
|
48
|
-
const editableDiv = domUtils.createElement('div', { class: this.editor.frameContext.get('
|
|
48
|
+
const editableDiv = domUtils.createElement('div', { class: this.editor.frameContext.get('wysiwyg').className }, this.html.get());
|
|
49
49
|
ww = domUtils.createElement('div', { style: `position: absolute; left: -10000px; width: ${topArea.clientWidth}px; height: auto;` }, editableDiv);
|
|
50
50
|
|
|
51
51
|
if (this.apiUrl) {
|
|
@@ -8,7 +8,7 @@ const List_bulleted = function (editor) {
|
|
|
8
8
|
EditorInjector.call(this, editor);
|
|
9
9
|
this.title = this.lang.bulletedList;
|
|
10
10
|
this.icon = 'list_bulleted';
|
|
11
|
-
this.
|
|
11
|
+
this.afterItem = domUtils.createElement(
|
|
12
12
|
'button',
|
|
13
13
|
{ class: 'se-btn se-tooltip se-sub-arrow-btn', 'data-command': List_bulleted.key, 'data-type': 'dropdown' },
|
|
14
14
|
`${this.icons.arrow_down}<span class="se-tooltip-inner"><span class="se-tooltip-text">${this.lang.bulletedList}</span></span>`
|
|
@@ -8,7 +8,7 @@ const List_numbered = function (editor) {
|
|
|
8
8
|
EditorInjector.call(this, editor);
|
|
9
9
|
this.title = this.lang.numberedList;
|
|
10
10
|
this.icon = 'list_numbered';
|
|
11
|
-
this.
|
|
11
|
+
this.afterItem = domUtils.createElement(
|
|
12
12
|
'button',
|
|
13
13
|
{ class: 'se-btn se-tooltip se-sub-arrow-btn', 'data-command': List_numbered.key, 'data-type': 'dropdown' },
|
|
14
14
|
`${this.icons.arrow_down}<span class="se-tooltip-inner"><span class="se-tooltip-text">${this.lang.numberedList}</span></span>`
|
package/src/plugins/index.js
CHANGED
|
@@ -29,12 +29,14 @@ import image from './modal/image';
|
|
|
29
29
|
import video from './modal/video';
|
|
30
30
|
import audio from './modal/audio';
|
|
31
31
|
import math from './modal/math';
|
|
32
|
+
import drawing from './modal/drawing';
|
|
32
33
|
|
|
33
34
|
// file browser
|
|
34
35
|
import imageGallery from './fileBrowser/imageGallery';
|
|
35
36
|
|
|
36
37
|
// input
|
|
37
38
|
import fontSize from './input/fontSize';
|
|
39
|
+
import pageNavigator from './input/pageNavigator';
|
|
38
40
|
|
|
39
41
|
// popup
|
|
40
42
|
import anchor from './popup/anchor';
|
|
@@ -64,8 +66,10 @@ export {
|
|
|
64
66
|
video,
|
|
65
67
|
audio,
|
|
66
68
|
math,
|
|
69
|
+
drawing,
|
|
67
70
|
imageGallery,
|
|
68
71
|
fontSize,
|
|
72
|
+
pageNavigator,
|
|
69
73
|
anchor
|
|
70
74
|
};
|
|
71
75
|
export default {
|
|
@@ -93,7 +97,9 @@ export default {
|
|
|
93
97
|
video,
|
|
94
98
|
audio,
|
|
95
99
|
math,
|
|
100
|
+
drawing,
|
|
96
101
|
imageGallery,
|
|
97
102
|
fontSize,
|
|
103
|
+
pageNavigator,
|
|
98
104
|
anchor
|
|
99
105
|
};
|