jodit 3.8.1 → 3.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.idea/codeStyles/Project.xml +68 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/dictionaries/v_chupurnov.xml +10 -0
- package/.idea/encodings.xml +4 -0
- package/.idea/inspectionProfiles/Project_Default.xml +118 -0
- package/.idea/jodit.iml +12 -0
- package/.idea/jsLibraryMappings.xml +6 -0
- package/.idea/markdown-navigator-enh.xml +29 -0
- package/.idea/markdown-navigator.xml +55 -0
- package/.idea/misc.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/prettier.xml +6 -0
- package/.idea/vcs.xml +6 -0
- package/.idea/watcherTasks.xml +4 -0
- package/.idea/workspace.xml +1264 -0
- package/build/jodit.css +2 -2
- package/build/jodit.es2018.css +1 -1
- package/build/jodit.es2018.en.css +1 -1
- package/build/jodit.es2018.en.js +4 -4
- package/build/jodit.es2018.en.min.js +2 -2
- package/build/jodit.es2018.js +4 -4
- package/build/jodit.es2018.min.js +2 -2
- package/build/jodit.js +4 -4
- package/build/jodit.min.css +1 -1
- package/build/jodit.min.js +2 -2
- package/package.json +2 -2
- package/.travis.yml +0 -7
- package/bower.json +0 -33
- package/build.js +0 -39
- package/docker/Dockerfile +0 -11
- package/docker/README.md +0 -45
- package/docker/build +0 -3
- package/docker/install +0 -7
- package/docker/start +0 -3
- package/docker/test +0 -3
- package/docker/uninstall +0 -3
- package/examples/arabic.lang.html +0 -76
- package/examples/assets/app.css +0 -175
- package/examples/assets/app.js +0 -57
- package/examples/assets/download.jpg +0 -0
- package/examples/assets/icon.png +0 -0
- package/examples/assets/logo.png +0 -0
- package/examples/assets/prism.css +0 -200
- package/examples/assets/prism.js +0 -1254
- package/examples/color-picker.html +0 -139
- package/examples/custom-icons.html +0 -173
- package/examples/custom-toolbar.html +0 -80
- package/examples/example.default.html +0 -75
- package/examples/fullsize.html +0 -75
- package/examples/index.html +0 -176
- package/examples/inline-mode.html +0 -116
- package/examples/oneinstance.html +0 -125
- package/icons.html +0 -50
- package/karma.conf.js +0 -157
- package/make.js +0 -10
- package/server.js +0 -101
- package/test/bootstrap.js +0 -1167
- package/test/test.html +0 -102
- package/test/test.index.html +0 -11
- package/test/tests/acceptance/clipboardTest.js +0 -1234
- package/test/tests/acceptance/commandsTest.js +0 -647
- package/test/tests/acceptance/creatorTest.js +0 -103
- package/test/tests/acceptance/deleteBackSpaceTest.js +0 -1289
- package/test/tests/acceptance/dialogTest.js +0 -188
- package/test/tests/acceptance/editorTest.js +0 -855
- package/test/tests/acceptance/enterTest.js +0 -1088
- package/test/tests/acceptance/eventsTest.js +0 -1246
- package/test/tests/acceptance/filebrowserTest.js +0 -1309
- package/test/tests/acceptance/i18nTest.js +0 -81
- package/test/tests/acceptance/iframeTest.js +0 -306
- package/test/tests/acceptance/imageTest.js +0 -1649
- package/test/tests/acceptance/inlineModeTest.js +0 -826
- package/test/tests/acceptance/interfaceTest.js +0 -119
- package/test/tests/acceptance/mobileTest.js +0 -229
- package/test/tests/acceptance/plugins/classSpan.js +0 -220
- package/test/tests/acceptance/plugins/cleanHtml.js +0 -351
- package/test/tests/acceptance/plugins/color.js +0 -188
- package/test/tests/acceptance/plugins/dragAndDropElement.js +0 -172
- package/test/tests/acceptance/plugins/focus.js +0 -115
- package/test/tests/acceptance/plugins/font.js +0 -316
- package/test/tests/acceptance/plugins/image.js +0 -79
- package/test/tests/acceptance/plugins/indent.js +0 -179
- package/test/tests/acceptance/plugins/inline-popup.js +0 -578
- package/test/tests/acceptance/plugins/insert.js +0 -17
- package/test/tests/acceptance/plugins/limit.js +0 -164
- package/test/tests/acceptance/plugins/link.js +0 -1640
- package/test/tests/acceptance/plugins/orderedList.js +0 -290
- package/test/tests/acceptance/plugins/placeholder.js +0 -138
- package/test/tests/acceptance/plugins/resizer.js +0 -329
- package/test/tests/acceptance/plugins/search.js +0 -623
- package/test/tests/acceptance/plugins/size.js +0 -344
- package/test/tests/acceptance/plugins/source.js +0 -218
- package/test/tests/acceptance/plugins/stat.js +0 -120
- package/test/tests/acceptance/plugins/tooltip.js +0 -97
- package/test/tests/acceptance/plugins/wrapTextNodes.js +0 -105
- package/test/tests/acceptance/pluginsTest.js +0 -2219
- package/test/tests/acceptance/selectionTest.js +0 -862
- package/test/tests/acceptance/statesTest.js +0 -310
- package/test/tests/acceptance/tableTest.js +0 -1988
- package/test/tests/acceptance/toolbarTest.js +0 -1747
- package/test/tests/acceptance/undoredoTest.js +0 -217
- package/test/tests/acceptance/uploaderTest.js +0 -187
- package/test/tests/artio.jpg +0 -0
- package/test/tests/units/helpersTest.js +0 -771
- package/test/tests/units/modules/dom.js +0 -282
- package/test/tests/units/objectObserverTest.js +0 -533
- package/test/tests/units/popupTest.js +0 -211
- package/test/tests/units/positionTest.js +0 -238
- package/test/tests/units/styleTest.js +0 -1361
- package/webpack.config.js +0 -308
package/test/bootstrap.js
DELETED
|
@@ -1,1167 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Jodit Editor (https://xdsoft.net/jodit/)
|
|
3
|
-
* Released under MIT see LICENSE.txt in the project root for license information.
|
|
4
|
-
* Copyright (c) 2013-2021 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/* eslint no-unused-vars: 0 */
|
|
8
|
-
/* eslint-disable tsdoc/syntax */
|
|
9
|
-
|
|
10
|
-
typeof window.chai !== 'undefined' &&
|
|
11
|
-
(function () {
|
|
12
|
-
chai.config.includeStack = true;
|
|
13
|
-
chai.config.showDiff = true;
|
|
14
|
-
})();
|
|
15
|
-
|
|
16
|
-
typeof window.mocha !== 'undefined' && mocha.timeout(15000);
|
|
17
|
-
|
|
18
|
-
const oldI18n = Jodit.prototype.i18n,
|
|
19
|
-
oldAjaxSender = Jodit.modules.Ajax.prototype.send,
|
|
20
|
-
naturalPromise = window.Promise;
|
|
21
|
-
|
|
22
|
-
function mockPromise() {
|
|
23
|
-
window.Promise = SynchronousPromise;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function unmockPromise() {
|
|
27
|
-
window.Promise = naturalPromise;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
*
|
|
32
|
-
* @param {number} timeout
|
|
33
|
-
* @return {*}
|
|
34
|
-
*/
|
|
35
|
-
function delay(timeout) {
|
|
36
|
-
return new naturalPromise(resolve => {
|
|
37
|
-
setTimeout(resolve, timeout);
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const defaultPermissions = {
|
|
42
|
-
permissions: {
|
|
43
|
-
allowFiles: true,
|
|
44
|
-
allowFileMove: true,
|
|
45
|
-
allowFileUpload: true,
|
|
46
|
-
allowFileUploadRemote: true,
|
|
47
|
-
allowFileRemove: true,
|
|
48
|
-
allowFileRename: true,
|
|
49
|
-
allowFolders: true,
|
|
50
|
-
allowFolderMove: true,
|
|
51
|
-
allowFolderCreate: true,
|
|
52
|
-
allowFolderRemove: true,
|
|
53
|
-
allowFolderRename: true,
|
|
54
|
-
allowImageResize: true,
|
|
55
|
-
allowImageCrop: true
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
function mockAjax() {
|
|
60
|
-
if (typeof window.chai !== 'undefined') {
|
|
61
|
-
let temp = {};
|
|
62
|
-
Jodit.modules.Ajax.prototype.send = function () {
|
|
63
|
-
const ajax = this;
|
|
64
|
-
|
|
65
|
-
const request = this.prepareRequest();
|
|
66
|
-
|
|
67
|
-
let action = request.data.action;
|
|
68
|
-
let path = request.data.path;
|
|
69
|
-
|
|
70
|
-
if (!action && request.data.get) {
|
|
71
|
-
action = request.data.get('action');
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (
|
|
75
|
-
action === undefined &&
|
|
76
|
-
request.url &&
|
|
77
|
-
request.url.match(/action=/)
|
|
78
|
-
) {
|
|
79
|
-
const actionExec = /action=([\w]+)/.exec(request.url);
|
|
80
|
-
action = actionExec[1];
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const files = path => {
|
|
84
|
-
const list = [
|
|
85
|
-
{
|
|
86
|
-
file: '1966051_524428741092238_1051008806888563137_o.jpg',
|
|
87
|
-
thumb: '_thumbs/1966051_524428741092238_1051008806888563137_o.jpg',
|
|
88
|
-
changed: '03/15/2018 12:40 PM',
|
|
89
|
-
size: '126.59kB',
|
|
90
|
-
isImage: true
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
file: 'images.jpg',
|
|
94
|
-
thumb: '_thumbs/images.jpg',
|
|
95
|
-
changed: '01/15/2018 12:40 PM',
|
|
96
|
-
size: '6.84kB',
|
|
97
|
-
isImage: true
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
file: 'ibanez-s520-443140.jpg',
|
|
101
|
-
thumb: '_thumbs/ibanez-s520-443140.jpg',
|
|
102
|
-
changed: '04/15/2018 12:40 PM',
|
|
103
|
-
size: '18.73kB',
|
|
104
|
-
isImage: true
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
file: 'test.txt',
|
|
108
|
-
thumb: '_thumbs/test.txt.png',
|
|
109
|
-
changed: '05/15/2018 12:40 PM',
|
|
110
|
-
size: '18.72kB',
|
|
111
|
-
isImage: false
|
|
112
|
-
}
|
|
113
|
-
];
|
|
114
|
-
|
|
115
|
-
switch (path) {
|
|
116
|
-
case 'test':
|
|
117
|
-
return [list[1], list[2]];
|
|
118
|
-
|
|
119
|
-
case 'ceicom':
|
|
120
|
-
return [list[0], list[3]];
|
|
121
|
-
|
|
122
|
-
default:
|
|
123
|
-
return list;
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
return new Promise(function (resolve) {
|
|
128
|
-
switch (action) {
|
|
129
|
-
case 'folderCreate': {
|
|
130
|
-
temp.folderName = ajax.options.data.name;
|
|
131
|
-
resolve({
|
|
132
|
-
success: true,
|
|
133
|
-
time: '2020-08-04 19:03:23',
|
|
134
|
-
data: { code: 220 }
|
|
135
|
-
});
|
|
136
|
-
break;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
case 'folderRemove':
|
|
140
|
-
case 'folderRename': {
|
|
141
|
-
temp.folderName = ajax.options.data.newname;
|
|
142
|
-
resolve({
|
|
143
|
-
success: true,
|
|
144
|
-
time: '2020-08-04 19:03:23',
|
|
145
|
-
data: { code: 220 }
|
|
146
|
-
});
|
|
147
|
-
break;
|
|
148
|
-
}
|
|
149
|
-
case 'fileUpload': {
|
|
150
|
-
const file = ajax.options.data.get('files[0]');
|
|
151
|
-
resolve({
|
|
152
|
-
success: true,
|
|
153
|
-
time: '2018-03-31 23:38:54',
|
|
154
|
-
data: {
|
|
155
|
-
baseurl: 'https://xdsoft.net/jodit/files/',
|
|
156
|
-
messages: [],
|
|
157
|
-
files: [file.name],
|
|
158
|
-
isImages: [/\.(png|jpg|gif)$/.test(file.name)],
|
|
159
|
-
code: 220
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
break;
|
|
163
|
-
}
|
|
164
|
-
case 'files':
|
|
165
|
-
resolve({
|
|
166
|
-
success: true,
|
|
167
|
-
time: '2018-03-15 12:49:49',
|
|
168
|
-
data: {
|
|
169
|
-
sources: [
|
|
170
|
-
{
|
|
171
|
-
name: 'default',
|
|
172
|
-
baseurl:
|
|
173
|
-
'https://xdsoft.net/jodit/files/',
|
|
174
|
-
path: '',
|
|
175
|
-
files: files(path)
|
|
176
|
-
}
|
|
177
|
-
],
|
|
178
|
-
code: 220
|
|
179
|
-
}
|
|
180
|
-
});
|
|
181
|
-
break;
|
|
182
|
-
case 'folders': {
|
|
183
|
-
const folderName = temp.folderName || 'ceicom';
|
|
184
|
-
delete temp.folderName;
|
|
185
|
-
|
|
186
|
-
resolve({
|
|
187
|
-
success: true,
|
|
188
|
-
time: '2018-03-15 12:49:49',
|
|
189
|
-
data: {
|
|
190
|
-
sources: [
|
|
191
|
-
{
|
|
192
|
-
name: 'default',
|
|
193
|
-
title: 'Some files',
|
|
194
|
-
baseurl:
|
|
195
|
-
'https://xdsoft.net/jodit/files/',
|
|
196
|
-
path: '',
|
|
197
|
-
folders:
|
|
198
|
-
path === ''
|
|
199
|
-
? ['.', folderName, 'test']
|
|
200
|
-
: []
|
|
201
|
-
}
|
|
202
|
-
],
|
|
203
|
-
code: 220
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
break;
|
|
207
|
-
}
|
|
208
|
-
case 'permissions':
|
|
209
|
-
resolve({
|
|
210
|
-
success: true,
|
|
211
|
-
time: '2018-03-15 12:49:49',
|
|
212
|
-
data: defaultPermissions,
|
|
213
|
-
code: 220
|
|
214
|
-
});
|
|
215
|
-
break;
|
|
216
|
-
case 'fileUploadRemote':
|
|
217
|
-
resolve({
|
|
218
|
-
success: true,
|
|
219
|
-
time: '2018-03-15 12:45:03',
|
|
220
|
-
data: {
|
|
221
|
-
newfilename: 'artio.jpg',
|
|
222
|
-
baseurl: 'https://xdsoft.net/jodit/files/',
|
|
223
|
-
code: 220
|
|
224
|
-
}
|
|
225
|
-
});
|
|
226
|
-
break;
|
|
227
|
-
case 'getLocalFileByUrl':
|
|
228
|
-
switch (ajax.options.data.url) {
|
|
229
|
-
case location.protocol +
|
|
230
|
-
'//' +
|
|
231
|
-
location.host +
|
|
232
|
-
'/artio.jpg':
|
|
233
|
-
case location.protocol +
|
|
234
|
-
'//' +
|
|
235
|
-
location.host +
|
|
236
|
-
'/tests/artio.jpg':
|
|
237
|
-
case location.protocol +
|
|
238
|
-
'//' +
|
|
239
|
-
location.host +
|
|
240
|
-
'/test/tests/artio.jpg':
|
|
241
|
-
case location.protocol +
|
|
242
|
-
'//' +
|
|
243
|
-
location.host +
|
|
244
|
-
'/jodit/test/tests/artio.jpg':
|
|
245
|
-
case 'https://xdsoft.net/jodit/files/th.jpg':
|
|
246
|
-
resolve({
|
|
247
|
-
success: true,
|
|
248
|
-
time: '2018-03-15 12:55:00',
|
|
249
|
-
data: {
|
|
250
|
-
path: '',
|
|
251
|
-
name: 'th.jpg',
|
|
252
|
-
source: 'default',
|
|
253
|
-
code: 220
|
|
254
|
-
}
|
|
255
|
-
});
|
|
256
|
-
break;
|
|
257
|
-
default:
|
|
258
|
-
resolve({
|
|
259
|
-
success: false,
|
|
260
|
-
time: '2018-03-15 12:08:54',
|
|
261
|
-
data: {
|
|
262
|
-
messages: [
|
|
263
|
-
'File does not exist or is above the root of the connector'
|
|
264
|
-
],
|
|
265
|
-
code: 424
|
|
266
|
-
}
|
|
267
|
-
});
|
|
268
|
-
break;
|
|
269
|
-
}
|
|
270
|
-
break;
|
|
271
|
-
default:
|
|
272
|
-
break;
|
|
273
|
-
}
|
|
274
|
-
});
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
function unmockAjax() {
|
|
280
|
-
Jodit.modules.Ajax.prototype.send = oldAjaxSender;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
if (typeof window.chai !== 'undefined') {
|
|
284
|
-
mockPromise();
|
|
285
|
-
mockAjax();
|
|
286
|
-
window.FormData = function () {
|
|
287
|
-
this.data = {};
|
|
288
|
-
this.append = function (key, value) {
|
|
289
|
-
this.data[key] = value;
|
|
290
|
-
};
|
|
291
|
-
this.get = function (key) {
|
|
292
|
-
return this.data[key];
|
|
293
|
-
};
|
|
294
|
-
};
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
const i18nkeys = [];
|
|
298
|
-
const excludeI18nKeys = [
|
|
299
|
-
'bar',
|
|
300
|
-
'Classe 1',
|
|
301
|
-
'Classe 2',
|
|
302
|
-
'Classe 3',
|
|
303
|
-
'Classe 4',
|
|
304
|
-
'Classe 5',
|
|
305
|
-
'classSpan',
|
|
306
|
-
'text3',
|
|
307
|
-
'text2',
|
|
308
|
-
'text1',
|
|
309
|
-
'Class name',
|
|
310
|
-
'https://',
|
|
311
|
-
'http://',
|
|
312
|
-
'rect',
|
|
313
|
-
'empty',
|
|
314
|
-
'adddate',
|
|
315
|
-
'URL',
|
|
316
|
-
'Custom',
|
|
317
|
-
'list_test',
|
|
318
|
-
'OS System Font',
|
|
319
|
-
'insert Header 1',
|
|
320
|
-
'insert Header 2',
|
|
321
|
-
'Empty editor',
|
|
322
|
-
'Helvetica,sans-serif',
|
|
323
|
-
'Helvetica',
|
|
324
|
-
'Arial,Helvetica,sans-serif',
|
|
325
|
-
'Arial',
|
|
326
|
-
'Georgia,serif',
|
|
327
|
-
'Georgia',
|
|
328
|
-
'Impact,Charcoal,sans-serif',
|
|
329
|
-
'Impact',
|
|
330
|
-
'Tahoma,Geneva,sans-serif',
|
|
331
|
-
'Tahoma',
|
|
332
|
-
"'Times New Roman',Times,serif",
|
|
333
|
-
'Times New Roman',
|
|
334
|
-
'Verdana,Geneva,sans-serif',
|
|
335
|
-
'Verdana',
|
|
336
|
-
'Lower Alpha',
|
|
337
|
-
'Lower Greek',
|
|
338
|
-
'Lower Roman',
|
|
339
|
-
'Upper Alpha',
|
|
340
|
-
'Upper Roman'
|
|
341
|
-
];
|
|
342
|
-
|
|
343
|
-
Jodit.prototype.i18n = function (key) {
|
|
344
|
-
!excludeI18nKeys.includes(key) &&
|
|
345
|
-
!i18nkeys.includes(key) &&
|
|
346
|
-
!key.includes('<svg') &&
|
|
347
|
-
i18nkeys.push(key);
|
|
348
|
-
|
|
349
|
-
return oldI18n.apply(this, arguments);
|
|
350
|
-
};
|
|
351
|
-
|
|
352
|
-
Jodit.defaultOptions.events.afterInit = function (editor) {
|
|
353
|
-
editor &&
|
|
354
|
-
editor.container.setAttribute('data-test-case', window.mochaTestName);
|
|
355
|
-
};
|
|
356
|
-
Jodit.defaultOptions.filebrowser.saveStateInStorage = false;
|
|
357
|
-
Jodit.defaultOptions.observer.timeout = 0;
|
|
358
|
-
Jodit.defaultOptions.filebrowser.defaultTimeout = 0;
|
|
359
|
-
Jodit.modules.View.defaultOptions.defaultTimeout = 0;
|
|
360
|
-
|
|
361
|
-
if (Jodit.defaultOptions.cleanHTML) {
|
|
362
|
-
Jodit.defaultOptions.cleanHTML.timeout = 0;
|
|
363
|
-
Jodit.defaultOptions.cleanHTML.fillEmptyParagraph = false;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
Jodit.defaultOptions.sourceEditor = 'area';
|
|
367
|
-
Jodit.defaultOptions.language = 'en';
|
|
368
|
-
Jodit.defaultOptions.iframeCSSLinks.push('/app.css');
|
|
369
|
-
Jodit.defaultOptions.iframeStyle +=
|
|
370
|
-
'* {\
|
|
371
|
-
-webkit-box-sizing: border-box;\
|
|
372
|
-
-moz-box-sizing: border-box;\
|
|
373
|
-
box-sizing: border-box;\
|
|
374
|
-
}\
|
|
375
|
-
td,th {\
|
|
376
|
-
padding: 2px 5px;\
|
|
377
|
-
vertical-align: top;\
|
|
378
|
-
}';
|
|
379
|
-
|
|
380
|
-
if (String.prototype.repeat === undefined) {
|
|
381
|
-
String.prototype.repeat = function (count) {
|
|
382
|
-
const result = [];
|
|
383
|
-
|
|
384
|
-
for (let i = 0; i < count; i++) {
|
|
385
|
-
result.push(this);
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
return result.join('');
|
|
389
|
-
};
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
var expect = typeof chai !== 'undefined' ? chai.expect : function () {},
|
|
393
|
-
stuff = [];
|
|
394
|
-
|
|
395
|
-
var stringify = Jodit.ns.Helpers.stringify;
|
|
396
|
-
var box = document.createElement('div');
|
|
397
|
-
|
|
398
|
-
document.body.appendChild(box);
|
|
399
|
-
|
|
400
|
-
function flatten(obj) {
|
|
401
|
-
var result = Object.create(obj);
|
|
402
|
-
for (var key in result) {
|
|
403
|
-
// eslint-disable-next-line no-self-assign
|
|
404
|
-
result[key] = result[key];
|
|
405
|
-
}
|
|
406
|
-
return result;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
function getBox() {
|
|
410
|
-
return box;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
function removeStuff() {
|
|
414
|
-
Object.keys(Jodit.instances).forEach(function (key) {
|
|
415
|
-
Jodit.instances[key].destruct();
|
|
416
|
-
});
|
|
417
|
-
|
|
418
|
-
stuff.forEach(function (elm) {
|
|
419
|
-
elm && elm.parentNode && elm.parentNode.removeChild(elm);
|
|
420
|
-
});
|
|
421
|
-
|
|
422
|
-
stuff.length = 0;
|
|
423
|
-
|
|
424
|
-
Array.from(
|
|
425
|
-
document.querySelectorAll(
|
|
426
|
-
'.jodit.jodit-dialog.jodit-dialog_active_true'
|
|
427
|
-
)
|
|
428
|
-
).forEach(function (dialog) {
|
|
429
|
-
simulateEvent('close_dialog', 0, dialog);
|
|
430
|
-
});
|
|
431
|
-
|
|
432
|
-
Jodit.modules.Ajax.log.length = 0;
|
|
433
|
-
|
|
434
|
-
getBox().removeAttribute('style');
|
|
435
|
-
|
|
436
|
-
mockPromise();
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
if (typeof afterEach === 'function') {
|
|
440
|
-
afterEach(removeStuff);
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
if (typeof beforeEach === 'function') {
|
|
444
|
-
beforeEach(function () {
|
|
445
|
-
window.mochaTestName = this.test.ctx.currentTest.fullTitle();
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
/**
|
|
450
|
-
* Create and insert into DOM test textarea
|
|
451
|
-
*
|
|
452
|
-
* @param [id]
|
|
453
|
-
* @param [noput]
|
|
454
|
-
* @returns {HTMLTextAreaElement}
|
|
455
|
-
*/
|
|
456
|
-
function appendTestArea(id, noput) {
|
|
457
|
-
const textarea = document.createElement('textarea');
|
|
458
|
-
textarea.setAttribute('id', id || 'editor_' + new Date().getTime());
|
|
459
|
-
box.appendChild(textarea);
|
|
460
|
-
|
|
461
|
-
!noput && stuff.push(textarea);
|
|
462
|
-
return textarea;
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
/**
|
|
466
|
-
* Jodit Factory
|
|
467
|
-
*
|
|
468
|
-
* @param {object} [options]
|
|
469
|
-
* @param {HTMLElement|undefined} [element]
|
|
470
|
-
* @return {Jodit}
|
|
471
|
-
*/
|
|
472
|
-
function getJodit(options, element) {
|
|
473
|
-
const editor = new Jodit(element || appendTestArea(), options);
|
|
474
|
-
|
|
475
|
-
window.scrollTo(
|
|
476
|
-
0,
|
|
477
|
-
Jodit.modules.Helpers.offset(editor.container, editor, editor.od).top
|
|
478
|
-
);
|
|
479
|
-
|
|
480
|
-
editor.container &&
|
|
481
|
-
editor.container.setAttribute('data-test-case', window.mochaTestName);
|
|
482
|
-
|
|
483
|
-
return editor;
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
/**
|
|
487
|
-
* Create empty DIV block and but it inside Box
|
|
488
|
-
*
|
|
489
|
-
* @param [id]
|
|
490
|
-
* @param [noput]
|
|
491
|
-
* @returns {HTMLDivElement}
|
|
492
|
-
*/
|
|
493
|
-
function appendTestDiv(id, noput) {
|
|
494
|
-
const textarea = document.createElement('div');
|
|
495
|
-
textarea.setAttribute('id', id || 'editor_' + new Date().getTime());
|
|
496
|
-
box.appendChild(textarea);
|
|
497
|
-
!noput && stuff.push(textarea);
|
|
498
|
-
return textarea;
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
function trim(value) {
|
|
502
|
-
return value.replace(/^[\s\r\t\n]+/g, '').replace(/[\s\r\t\n]+$/g, '');
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
function toFixedWithoutRounding(value, precision) {
|
|
506
|
-
const factorError = Math.pow(10, 14);
|
|
507
|
-
const factorTruncate = Math.pow(10, 14 - precision);
|
|
508
|
-
const factorDecimal = Math.pow(10, precision);
|
|
509
|
-
return (
|
|
510
|
-
Math.floor(Math.floor(value * factorError + 1) / factorTruncate) /
|
|
511
|
-
factorDecimal
|
|
512
|
-
);
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
function sortStyles(matches) {
|
|
516
|
-
let styles = matches
|
|
517
|
-
.replace(/"/g, "'")
|
|
518
|
-
.replace(/"/g, "'")
|
|
519
|
-
.split(';');
|
|
520
|
-
|
|
521
|
-
styles = styles.map(trim).filter(function (elm) {
|
|
522
|
-
return elm.length;
|
|
523
|
-
});
|
|
524
|
-
|
|
525
|
-
let border = null;
|
|
526
|
-
|
|
527
|
-
styles = styles
|
|
528
|
-
.map(function (elm) {
|
|
529
|
-
const keyValue = elm.split(':').map(trim);
|
|
530
|
-
|
|
531
|
-
if (keyValue[0] === 'border-image') {
|
|
532
|
-
return null;
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
if (/rgb\(/.test(keyValue[1])) {
|
|
536
|
-
keyValue[1] = keyValue[1].replace(
|
|
537
|
-
/rgb\([^)]+\)/,
|
|
538
|
-
function (match) {
|
|
539
|
-
return Jodit.modules.Helpers.normalizeColor(match);
|
|
540
|
-
}
|
|
541
|
-
);
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
if (keyValue[0].match(/^border$/)) {
|
|
545
|
-
keyValue[1] = keyValue[1].split(/[\s]+/);
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
if (keyValue[0].match(/^border-(style|width|color)/)) {
|
|
549
|
-
if (border == null) {
|
|
550
|
-
border = keyValue;
|
|
551
|
-
keyValue[0] = 'border';
|
|
552
|
-
keyValue[1] = [keyValue[1]];
|
|
553
|
-
} else {
|
|
554
|
-
border[1].push(keyValue[1]);
|
|
555
|
-
return null;
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
if (/font-family/i.test(keyValue[0])) {
|
|
560
|
-
keyValue[1] = keyValue[1]
|
|
561
|
-
.split(',')
|
|
562
|
-
.map(Jodit.modules.Helpers.trim)
|
|
563
|
-
.map(function (value) {
|
|
564
|
-
return value.replace(/['"]/g, '');
|
|
565
|
-
})
|
|
566
|
-
.join(',');
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
if (/%$/.test(keyValue[1])) {
|
|
570
|
-
const fl = parseFloat(keyValue[1]),
|
|
571
|
-
nt = parseInt(keyValue[1], 10);
|
|
572
|
-
if (fl - nt > 0) {
|
|
573
|
-
keyValue[1] = toFixedWithoutRounding(fl, 2) + '%';
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
return keyValue;
|
|
578
|
-
})
|
|
579
|
-
.filter(function (a) {
|
|
580
|
-
return a != null;
|
|
581
|
-
})
|
|
582
|
-
.map(function (a) {
|
|
583
|
-
return a
|
|
584
|
-
.map(function (item) {
|
|
585
|
-
return typeof item === 'string'
|
|
586
|
-
? item
|
|
587
|
-
: item.sort().join(' ');
|
|
588
|
-
})
|
|
589
|
-
.join(':');
|
|
590
|
-
})
|
|
591
|
-
.sort(function (a, b) {
|
|
592
|
-
if (a < b) {
|
|
593
|
-
return -1;
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
return a > b ? 1 : 0;
|
|
597
|
-
});
|
|
598
|
-
|
|
599
|
-
return styles.join(';');
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
function sortAttributes(html) {
|
|
603
|
-
const tag = /<([^>]+)>/g;
|
|
604
|
-
const reg = /([a-z_-]+)[\s]*=[\s]*"([^"]*)"/i,
|
|
605
|
-
tags = [];
|
|
606
|
-
|
|
607
|
-
let matches, tagMatch;
|
|
608
|
-
|
|
609
|
-
while ((tagMatch = tag.exec(html))) {
|
|
610
|
-
const attrs = [];
|
|
611
|
-
|
|
612
|
-
let newTag = tagMatch[0];
|
|
613
|
-
|
|
614
|
-
do {
|
|
615
|
-
matches = reg.exec(newTag);
|
|
616
|
-
|
|
617
|
-
if (!matches) {
|
|
618
|
-
break;
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
if (matches[1].toLowerCase() === 'style') {
|
|
622
|
-
matches[2] = sortStyles(matches[2]);
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
if (matches[1].toLowerCase() !== 'unselectable') {
|
|
626
|
-
attrs.push({
|
|
627
|
-
name: matches[1].toLowerCase(),
|
|
628
|
-
value: matches[2]
|
|
629
|
-
});
|
|
630
|
-
|
|
631
|
-
newTag = newTag.replace(
|
|
632
|
-
matches[0],
|
|
633
|
-
'attribute:' + attrs.length
|
|
634
|
-
);
|
|
635
|
-
} else {
|
|
636
|
-
newTag = newTag.replace(' ' + matches[0], '');
|
|
637
|
-
}
|
|
638
|
-
} while (matches);
|
|
639
|
-
|
|
640
|
-
attrs.sort(function (a, b) {
|
|
641
|
-
if (a.name < b.name) {
|
|
642
|
-
return -1;
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
return a.name > b.name ? 1 : 0;
|
|
646
|
-
});
|
|
647
|
-
|
|
648
|
-
attrs.forEach(function (elm, i) {
|
|
649
|
-
newTag = newTag.replace(
|
|
650
|
-
'attribute:' + (i + 1),
|
|
651
|
-
elm.name + '="' + elm.value + '"'
|
|
652
|
-
);
|
|
653
|
-
});
|
|
654
|
-
|
|
655
|
-
tags.push({
|
|
656
|
-
name: tagMatch[0],
|
|
657
|
-
value: newTag
|
|
658
|
-
});
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
tags.forEach(function (elm) {
|
|
662
|
-
html = html.replace(elm.name, elm.value);
|
|
663
|
-
});
|
|
664
|
-
|
|
665
|
-
return html
|
|
666
|
-
.replace(/ /g, ' ')
|
|
667
|
-
.replace(Jodit.INVISIBLE_SPACE_REG_EXP(), '');
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
/**
|
|
671
|
-
* Fill the box some elements for space
|
|
672
|
-
* @param count
|
|
673
|
-
*/
|
|
674
|
-
function fillBoxBr(count) {
|
|
675
|
-
for (let i = 0; i < 100; i += 1) {
|
|
676
|
-
const br = document.createElement('br');
|
|
677
|
-
getBox().appendChild(br);
|
|
678
|
-
stuff.push(br);
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
const codeKey = {
|
|
683
|
-
8: 'Backspace',
|
|
684
|
-
13: 'Enter',
|
|
685
|
-
38: 'ArrowUp',
|
|
686
|
-
40: 'ArrowDown',
|
|
687
|
-
55: '7',
|
|
688
|
-
56: '8',
|
|
689
|
-
73: 'i',
|
|
690
|
-
70: 'f',
|
|
691
|
-
72: 'h',
|
|
692
|
-
75: 'k',
|
|
693
|
-
86: 'v',
|
|
694
|
-
89: 'y',
|
|
695
|
-
114: 'F3'
|
|
696
|
-
};
|
|
697
|
-
|
|
698
|
-
const keyCode = Object.keys(codeKey).reduce((res, code) => {
|
|
699
|
-
res[codeKey[code]] = code;
|
|
700
|
-
return res;
|
|
701
|
-
}, {});
|
|
702
|
-
|
|
703
|
-
/**
|
|
704
|
-
*
|
|
705
|
-
* @param {string|string[]} type
|
|
706
|
-
* @param {string|number|HTMLElement|Jodit} keyCodeOrElement
|
|
707
|
-
* @param {HTMLElement|Jodit} [element]
|
|
708
|
-
* @param {Function} [applyOpt]
|
|
709
|
-
*
|
|
710
|
-
* @returns boolean
|
|
711
|
-
*/
|
|
712
|
-
function simulateEvent(type, keyCodeOrElement, elementOrApplyOpt, applyOpt) {
|
|
713
|
-
if (Array.isArray(type)) {
|
|
714
|
-
return type.forEach(function (event) {
|
|
715
|
-
simulateEvent(event, keyCodeOrElement, elementOrApplyOpt, applyOpt);
|
|
716
|
-
});
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
let element = elementOrApplyOpt;
|
|
720
|
-
if (typeof keyCodeOrElement === 'object') {
|
|
721
|
-
element = keyCodeOrElement;
|
|
722
|
-
keyCodeOrElement = null;
|
|
723
|
-
|
|
724
|
-
if (typeof elementOrApplyOpt === 'function') {
|
|
725
|
-
applyOpt = elementOrApplyOpt;
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
if (Array.isArray(element)) {
|
|
730
|
-
return element.forEach(function (elm) {
|
|
731
|
-
simulateEvent(type, keyCodeOrElement, elm, applyOpt);
|
|
732
|
-
});
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
if (element instanceof Jodit) {
|
|
736
|
-
element = element.editor;
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
const evt = (element.ownerDocument || document).createEvent('HTMLEvents');
|
|
740
|
-
|
|
741
|
-
evt.initEvent(type, true, true);
|
|
742
|
-
|
|
743
|
-
if (keyCodeOrElement) {
|
|
744
|
-
if (typeof keyCodeOrElement === 'number') {
|
|
745
|
-
evt.keyCode = keyCodeOrElement;
|
|
746
|
-
evt.which = keyCodeOrElement;
|
|
747
|
-
evt.key = codeKey[keyCodeOrElement];
|
|
748
|
-
} else if (typeof keyCodeOrElement !== 'object') {
|
|
749
|
-
evt.key = keyCodeOrElement;
|
|
750
|
-
evt.which = keyCode[keyCodeOrElement];
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
if (applyOpt) {
|
|
755
|
-
applyOpt(evt);
|
|
756
|
-
} else if (element.getBoundingClientRect) {
|
|
757
|
-
const pos = Jodit.modules.Helpers.position(element);
|
|
758
|
-
evt.clientX = pos.left + 5;
|
|
759
|
-
evt.clientY = pos.top + 5;
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
if (type.match(/^mouse/)) {
|
|
763
|
-
['pageX', 'pageY', 'clientX', 'clientY'].forEach(function (key) {
|
|
764
|
-
if (evt[key] === undefined) {
|
|
765
|
-
evt[key] = 0;
|
|
766
|
-
}
|
|
767
|
-
});
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
if (type.match(/^touch/) && !evt.changedTouches) {
|
|
771
|
-
const changedTouches = {};
|
|
772
|
-
|
|
773
|
-
['pageX', 'pageY', 'clientX', 'clientY'].forEach(function (key) {
|
|
774
|
-
changedTouches[key] = evt[key];
|
|
775
|
-
});
|
|
776
|
-
|
|
777
|
-
evt.changedTouches = changedTouches;
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
return element.dispatchEvent(evt);
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
/**
|
|
784
|
-
* @param {Jodit} editor
|
|
785
|
-
* @return {HTMLElement|null}
|
|
786
|
-
*/
|
|
787
|
-
function getOpenedPopup(editor) {
|
|
788
|
-
const popups = editor.ownerDocument.querySelectorAll(
|
|
789
|
-
'[role="popup"][data-editor_id="' + editor.id + '"]:last-child'
|
|
790
|
-
);
|
|
791
|
-
return popups.length ? popups[popups.length - 1] : null;
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
/**
|
|
795
|
-
* @param {Jodit} editor
|
|
796
|
-
* @return {HTMLElement|null}
|
|
797
|
-
*/
|
|
798
|
-
function getOpenedDialog(editor) {
|
|
799
|
-
const dlgs = editor.ownerDocument.querySelectorAll('.jodit-dialog');
|
|
800
|
-
|
|
801
|
-
return dlgs.length ? dlgs[dlgs.length - 1] : null;
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
/**
|
|
805
|
-
* Find button inside element
|
|
806
|
-
*
|
|
807
|
-
* @param {string} buttonName
|
|
808
|
-
* @param {Jodit|Element} joditOrElement
|
|
809
|
-
* @param {string} [role]
|
|
810
|
-
* @param {boolean} [last]
|
|
811
|
-
* @returns {HTMLElement|null}
|
|
812
|
-
*/
|
|
813
|
-
function getButton(buttonName, joditOrElement, role, last) {
|
|
814
|
-
const elm = joditOrElement.container || joditOrElement;
|
|
815
|
-
|
|
816
|
-
return (
|
|
817
|
-
elm.querySelector(
|
|
818
|
-
'.jodit-toolbar-button.jodit-toolbar-button_' +
|
|
819
|
-
buttonName +
|
|
820
|
-
(last ? ':last-child' : '') +
|
|
821
|
-
' [role="' +
|
|
822
|
-
(role || 'button') +
|
|
823
|
-
'"]'
|
|
824
|
-
) ||
|
|
825
|
-
elm.querySelector(
|
|
826
|
-
'.jodit-ui-button.jodit-ui-button_' +
|
|
827
|
-
buttonName +
|
|
828
|
-
(last ? ':last-child' : '') +
|
|
829
|
-
'[role="' +
|
|
830
|
-
(role || 'button') +
|
|
831
|
-
'"]'
|
|
832
|
-
)
|
|
833
|
-
);
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
/**
|
|
837
|
-
* Click and trigger some button event
|
|
838
|
-
*
|
|
839
|
-
* @param {string} buttonName
|
|
840
|
-
* @param {Jodit|HTMLElement} joditOrElement
|
|
841
|
-
* @param {string} [role]
|
|
842
|
-
* @param {boolean} [last]
|
|
843
|
-
*/
|
|
844
|
-
function clickButton(buttonName, joditOrElement, role, last) {
|
|
845
|
-
simulateEvent(
|
|
846
|
-
'click',
|
|
847
|
-
0,
|
|
848
|
-
getButton(buttonName, joditOrElement, role, last)
|
|
849
|
-
);
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
function clickTrigger(buttonName, joditOrElement) {
|
|
853
|
-
clickButton(buttonName, joditOrElement, 'trigger');
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
/**
|
|
857
|
-
* Select table cells
|
|
858
|
-
* @param {Jodit} editor
|
|
859
|
-
* @param {number[]} indexes
|
|
860
|
-
*/
|
|
861
|
-
function selectCells(editor, indexes) {
|
|
862
|
-
const cells = editor.editor.querySelectorAll('td,th');
|
|
863
|
-
indexes.forEach(index => {
|
|
864
|
-
editor.getInstance('Table', editor.options).addSelection(cells[index]);
|
|
865
|
-
});
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
/**
|
|
869
|
-
* Set listener and remove it after first call
|
|
870
|
-
*
|
|
871
|
-
* @param {string} event
|
|
872
|
-
* @param {HTMLElement} element
|
|
873
|
-
* @param {Function} callback
|
|
874
|
-
*/
|
|
875
|
-
function one(event, element, callback) {
|
|
876
|
-
const on = function () {
|
|
877
|
-
element.removeEventListener(event, on);
|
|
878
|
-
callback.apply(element, arguments);
|
|
879
|
-
};
|
|
880
|
-
|
|
881
|
-
element.addEventListener(event, on);
|
|
882
|
-
}
|
|
883
|
-
|
|
884
|
-
/**
|
|
885
|
-
* Set one handler for load image
|
|
886
|
-
*
|
|
887
|
-
* @param {HTMLImageElement} image
|
|
888
|
-
* @param {Function} callback
|
|
889
|
-
*/
|
|
890
|
-
function onLoadImage(image, callback) {
|
|
891
|
-
if (!image.complete) {
|
|
892
|
-
one('load', image, callback);
|
|
893
|
-
} else {
|
|
894
|
-
callback.apply(image);
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
-
/**
|
|
899
|
-
*
|
|
900
|
-
* @param {HTMLElement} element
|
|
901
|
-
* @param {string} pastedText
|
|
902
|
-
* @param {string} type
|
|
903
|
-
*/
|
|
904
|
-
function simulatePaste(element, pastedText, type) {
|
|
905
|
-
simulateEvent('paste', element, function (data) {
|
|
906
|
-
data.clipboardData = {
|
|
907
|
-
types: [type || 'text/html'],
|
|
908
|
-
getData: function () {
|
|
909
|
-
return pastedText;
|
|
910
|
-
}
|
|
911
|
-
};
|
|
912
|
-
});
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
function setCursor(elm, inEnd) {
|
|
916
|
-
const range = document.createRange();
|
|
917
|
-
range.selectNodeContents(elm);
|
|
918
|
-
range.collapse(!inEnd);
|
|
919
|
-
window.getSelection().removeAllRanges();
|
|
920
|
-
window.getSelection().addRange(range);
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
/**
|
|
924
|
-
* Set cursor inside editor by some char
|
|
925
|
-
*
|
|
926
|
-
* @param {Jodit} editor
|
|
927
|
-
* @param {string} [char]
|
|
928
|
-
* @return boolean
|
|
929
|
-
*/
|
|
930
|
-
function setCursorToChar(editor, char = '|') {
|
|
931
|
-
const r = editor.s.createRange();
|
|
932
|
-
let foundEdges = [];
|
|
933
|
-
|
|
934
|
-
Jodit.modules.Dom.each(editor.editor, function (node) {
|
|
935
|
-
if (node.nodeType === Node.TEXT_NODE && node.nodeValue.includes(char)) {
|
|
936
|
-
let index = -1;
|
|
937
|
-
do {
|
|
938
|
-
index = node.nodeValue.indexOf(char, index + 1);
|
|
939
|
-
|
|
940
|
-
if (index !== -1) {
|
|
941
|
-
node.nodeValue = node.nodeValue.replace(char, '');
|
|
942
|
-
foundEdges.push([node, index]);
|
|
943
|
-
}
|
|
944
|
-
} while (index !== -1);
|
|
945
|
-
}
|
|
946
|
-
|
|
947
|
-
return true;
|
|
948
|
-
});
|
|
949
|
-
|
|
950
|
-
if (foundEdges.length) {
|
|
951
|
-
if (foundEdges[0]) {
|
|
952
|
-
r.setStart(foundEdges[0][0], foundEdges[0][1]);
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
if (foundEdges[1]) {
|
|
956
|
-
r.setEnd(foundEdges[1][0], foundEdges[1][1]);
|
|
957
|
-
}
|
|
958
|
-
|
|
959
|
-
editor.s.selectRange(r);
|
|
960
|
-
|
|
961
|
-
return true;
|
|
962
|
-
}
|
|
963
|
-
|
|
964
|
-
return false;
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
/**
|
|
968
|
-
* Set cursor inside editor by some char
|
|
969
|
-
*
|
|
970
|
-
* @param {Jodit} editor
|
|
971
|
-
* @param {string} [char]
|
|
972
|
-
* @return boolean
|
|
973
|
-
*/
|
|
974
|
-
function replaceCursorToChar(editor, char = '|') {
|
|
975
|
-
editor.s.save();
|
|
976
|
-
editor.s.markers.forEach(m => {
|
|
977
|
-
Jodit.modules.Dom.after(m, editor.createInside.text(char));
|
|
978
|
-
});
|
|
979
|
-
|
|
980
|
-
return false;
|
|
981
|
-
}
|
|
982
|
-
|
|
983
|
-
function createPoint(x, y, color, fixed = false) {
|
|
984
|
-
const div = document.createElement('div');
|
|
985
|
-
|
|
986
|
-
div.setAttribute(
|
|
987
|
-
'style',
|
|
988
|
-
'position: ' +
|
|
989
|
-
(fixed ? 'fixed' : 'absolute') +
|
|
990
|
-
'; z-index: 1000000000;width: 5px; height: 5px; background: ' +
|
|
991
|
-
(color || 'red') +
|
|
992
|
-
';'
|
|
993
|
-
);
|
|
994
|
-
|
|
995
|
-
div.style.left = parseInt(x, 10) + 'px';
|
|
996
|
-
div.style.top = parseInt(y, 10) + 'px';
|
|
997
|
-
|
|
998
|
-
document.body.appendChild(div);
|
|
999
|
-
stuff.push(div);
|
|
1000
|
-
}
|
|
1001
|
-
|
|
1002
|
-
function offset(el) {
|
|
1003
|
-
const rect = el.getBoundingClientRect(),
|
|
1004
|
-
scrollLeft = window.pageXOffset || document.documentElement.scrollLeft,
|
|
1005
|
-
scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
|
1006
|
-
|
|
1007
|
-
return {
|
|
1008
|
-
top: rect.top + scrollTop,
|
|
1009
|
-
left: rect.left + scrollLeft,
|
|
1010
|
-
width: rect.width,
|
|
1011
|
-
height: rect.height
|
|
1012
|
-
};
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
/**
|
|
1016
|
-
* innerHTML property for SVGElement
|
|
1017
|
-
* Copyright(c) 2010, Jeff Schiller
|
|
1018
|
-
*
|
|
1019
|
-
* Licensed under the Apache License, Version 2
|
|
1020
|
-
*
|
|
1021
|
-
* Works in a SVG document in Chrome 6+, Safari 5+, Firefox 4+ and IE9+.
|
|
1022
|
-
* Works in a HTML5 document in Chrome 7+, Firefox 4+ and IE9+.
|
|
1023
|
-
* Does not work in Opera since it doesn't support the SVGElement interface yet.
|
|
1024
|
-
*
|
|
1025
|
-
* I haven't decided on the best name for this property - thus the duplication.
|
|
1026
|
-
*/
|
|
1027
|
-
(function () {
|
|
1028
|
-
const serializeXML = function (node, output) {
|
|
1029
|
-
const nodeType = node.nodeType;
|
|
1030
|
-
|
|
1031
|
-
if (nodeType === 3) {
|
|
1032
|
-
output.push(
|
|
1033
|
-
node.textContent
|
|
1034
|
-
.replace(/&/, '&')
|
|
1035
|
-
.replace(/</, '<')
|
|
1036
|
-
.replace('>', '>')
|
|
1037
|
-
);
|
|
1038
|
-
} else if (nodeType === 1) {
|
|
1039
|
-
output.push('<', node.tagName);
|
|
1040
|
-
|
|
1041
|
-
if (node.hasAttributes()) {
|
|
1042
|
-
const attrMap = node.attributes;
|
|
1043
|
-
|
|
1044
|
-
for (let i = 0, len = attrMap.length; i < len; ++i) {
|
|
1045
|
-
const attrNode = attrMap.item(i);
|
|
1046
|
-
output.push(' ', attrNode.name, "='", attrNode.value, "'");
|
|
1047
|
-
}
|
|
1048
|
-
}
|
|
1049
|
-
|
|
1050
|
-
if (node.hasChildNodes()) {
|
|
1051
|
-
output.push('>');
|
|
1052
|
-
const childNodes = node.childNodes;
|
|
1053
|
-
|
|
1054
|
-
for (let i = 0, len = childNodes.length; i < len; i += 1) {
|
|
1055
|
-
serializeXML(childNodes.item(i), output);
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
|
-
output.push('</', node.tagName, '>');
|
|
1059
|
-
} else {
|
|
1060
|
-
output.push('/>');
|
|
1061
|
-
}
|
|
1062
|
-
} else if (nodeType === 8) {
|
|
1063
|
-
output.push('<!--', node.nodeValue, '-->');
|
|
1064
|
-
} else {
|
|
1065
|
-
throw new Error(
|
|
1066
|
-
'Error serializing XML. Unhandled node of type: ' + nodeType
|
|
1067
|
-
);
|
|
1068
|
-
}
|
|
1069
|
-
};
|
|
1070
|
-
|
|
1071
|
-
// The innerHTML DOM property for SVGElement.
|
|
1072
|
-
Object.defineProperty(SVGElement.prototype, 'innerHTML', {
|
|
1073
|
-
get: function () {
|
|
1074
|
-
const output = [];
|
|
1075
|
-
let childNode = this.firstChild;
|
|
1076
|
-
|
|
1077
|
-
while (childNode) {
|
|
1078
|
-
serializeXML(childNode, output);
|
|
1079
|
-
childNode = childNode.nextSibling;
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
return output.join('');
|
|
1083
|
-
},
|
|
1084
|
-
set: function (markupText) {
|
|
1085
|
-
// Wipe out the current contents of the element.
|
|
1086
|
-
while (this.firstChild) {
|
|
1087
|
-
this.removeChild(this.firstChild);
|
|
1088
|
-
}
|
|
1089
|
-
|
|
1090
|
-
try {
|
|
1091
|
-
// Parse the markup into valid nodes.
|
|
1092
|
-
const dXML = new DOMParser();
|
|
1093
|
-
|
|
1094
|
-
dXML.async = false;
|
|
1095
|
-
// Wrap the markup into a SVG node to ensure parsing works.
|
|
1096
|
-
const sXML =
|
|
1097
|
-
"<svg xmlns='http://www.w3.org/2000/svg'>" +
|
|
1098
|
-
markupText +
|
|
1099
|
-
'</svg>';
|
|
1100
|
-
const svgDocElement = dXML.parseFromString(
|
|
1101
|
-
sXML,
|
|
1102
|
-
'text/xml'
|
|
1103
|
-
).documentElement;
|
|
1104
|
-
|
|
1105
|
-
// Now take each node, import it and append to this element.
|
|
1106
|
-
let childNode = svgDocElement.firstChild;
|
|
1107
|
-
|
|
1108
|
-
while (childNode) {
|
|
1109
|
-
this.appendChild(
|
|
1110
|
-
this.ownerDocument.importNode(childNode, true)
|
|
1111
|
-
);
|
|
1112
|
-
|
|
1113
|
-
childNode = childNode.nextSibling;
|
|
1114
|
-
}
|
|
1115
|
-
} catch (e) {
|
|
1116
|
-
throw new Error('Error parsing XML string' + e.toString());
|
|
1117
|
-
}
|
|
1118
|
-
}
|
|
1119
|
-
});
|
|
1120
|
-
|
|
1121
|
-
// The innerSVG DOM property for SVGElement.
|
|
1122
|
-
Object.defineProperty(SVGElement.prototype, 'innerSVG', {
|
|
1123
|
-
get: function () {
|
|
1124
|
-
return this.innerHTML;
|
|
1125
|
-
},
|
|
1126
|
-
set: function (markupText) {
|
|
1127
|
-
this.innerHTML = markupText;
|
|
1128
|
-
}
|
|
1129
|
-
});
|
|
1130
|
-
})();
|
|
1131
|
-
|
|
1132
|
-
// Files
|
|
1133
|
-
function FileImage() {
|
|
1134
|
-
return {
|
|
1135
|
-
name: 'logo.gif',
|
|
1136
|
-
dataURI:
|
|
1137
|
-
'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==',
|
|
1138
|
-
type: 'image/gif'
|
|
1139
|
-
};
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1142
|
-
// Files
|
|
1143
|
-
function FileXLS() {
|
|
1144
|
-
return {
|
|
1145
|
-
name: 'file.xls',
|
|
1146
|
-
type: 'application/xls'
|
|
1147
|
-
};
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
|
-
if (typeof window.chai !== 'undefined') {
|
|
1151
|
-
window.FileReader = function () {
|
|
1152
|
-
const self = this;
|
|
1153
|
-
self.result = null;
|
|
1154
|
-
/**
|
|
1155
|
-
*
|
|
1156
|
-
* @param {FileImage} file
|
|
1157
|
-
*/
|
|
1158
|
-
self.readAsDataURL = function (file) {
|
|
1159
|
-
self.result = file.dataURI;
|
|
1160
|
-
self.onloadend && self.onloadend();
|
|
1161
|
-
};
|
|
1162
|
-
};
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
|
-
Object.defineProperty(navigator, 'userAgent', {
|
|
1166
|
-
value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 YaBrowser/18.9.0.3363 Yowser/2.5 Safari/537.36'
|
|
1167
|
-
});
|