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.
Files changed (110) hide show
  1. package/.idea/codeStyles/Project.xml +68 -0
  2. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  3. package/.idea/dictionaries/v_chupurnov.xml +10 -0
  4. package/.idea/encodings.xml +4 -0
  5. package/.idea/inspectionProfiles/Project_Default.xml +118 -0
  6. package/.idea/jodit.iml +12 -0
  7. package/.idea/jsLibraryMappings.xml +6 -0
  8. package/.idea/markdown-navigator-enh.xml +29 -0
  9. package/.idea/markdown-navigator.xml +55 -0
  10. package/.idea/misc.xml +6 -0
  11. package/.idea/modules.xml +8 -0
  12. package/.idea/prettier.xml +6 -0
  13. package/.idea/vcs.xml +6 -0
  14. package/.idea/watcherTasks.xml +4 -0
  15. package/.idea/workspace.xml +1264 -0
  16. package/build/jodit.css +2 -2
  17. package/build/jodit.es2018.css +1 -1
  18. package/build/jodit.es2018.en.css +1 -1
  19. package/build/jodit.es2018.en.js +4 -4
  20. package/build/jodit.es2018.en.min.js +2 -2
  21. package/build/jodit.es2018.js +4 -4
  22. package/build/jodit.es2018.min.js +2 -2
  23. package/build/jodit.js +4 -4
  24. package/build/jodit.min.css +1 -1
  25. package/build/jodit.min.js +2 -2
  26. package/package.json +2 -2
  27. package/.travis.yml +0 -7
  28. package/bower.json +0 -33
  29. package/build.js +0 -39
  30. package/docker/Dockerfile +0 -11
  31. package/docker/README.md +0 -45
  32. package/docker/build +0 -3
  33. package/docker/install +0 -7
  34. package/docker/start +0 -3
  35. package/docker/test +0 -3
  36. package/docker/uninstall +0 -3
  37. package/examples/arabic.lang.html +0 -76
  38. package/examples/assets/app.css +0 -175
  39. package/examples/assets/app.js +0 -57
  40. package/examples/assets/download.jpg +0 -0
  41. package/examples/assets/icon.png +0 -0
  42. package/examples/assets/logo.png +0 -0
  43. package/examples/assets/prism.css +0 -200
  44. package/examples/assets/prism.js +0 -1254
  45. package/examples/color-picker.html +0 -139
  46. package/examples/custom-icons.html +0 -173
  47. package/examples/custom-toolbar.html +0 -80
  48. package/examples/example.default.html +0 -75
  49. package/examples/fullsize.html +0 -75
  50. package/examples/index.html +0 -176
  51. package/examples/inline-mode.html +0 -116
  52. package/examples/oneinstance.html +0 -125
  53. package/icons.html +0 -50
  54. package/karma.conf.js +0 -157
  55. package/make.js +0 -10
  56. package/server.js +0 -101
  57. package/test/bootstrap.js +0 -1167
  58. package/test/test.html +0 -102
  59. package/test/test.index.html +0 -11
  60. package/test/tests/acceptance/clipboardTest.js +0 -1234
  61. package/test/tests/acceptance/commandsTest.js +0 -647
  62. package/test/tests/acceptance/creatorTest.js +0 -103
  63. package/test/tests/acceptance/deleteBackSpaceTest.js +0 -1289
  64. package/test/tests/acceptance/dialogTest.js +0 -188
  65. package/test/tests/acceptance/editorTest.js +0 -855
  66. package/test/tests/acceptance/enterTest.js +0 -1088
  67. package/test/tests/acceptance/eventsTest.js +0 -1246
  68. package/test/tests/acceptance/filebrowserTest.js +0 -1309
  69. package/test/tests/acceptance/i18nTest.js +0 -81
  70. package/test/tests/acceptance/iframeTest.js +0 -306
  71. package/test/tests/acceptance/imageTest.js +0 -1649
  72. package/test/tests/acceptance/inlineModeTest.js +0 -826
  73. package/test/tests/acceptance/interfaceTest.js +0 -119
  74. package/test/tests/acceptance/mobileTest.js +0 -229
  75. package/test/tests/acceptance/plugins/classSpan.js +0 -220
  76. package/test/tests/acceptance/plugins/cleanHtml.js +0 -351
  77. package/test/tests/acceptance/plugins/color.js +0 -188
  78. package/test/tests/acceptance/plugins/dragAndDropElement.js +0 -172
  79. package/test/tests/acceptance/plugins/focus.js +0 -115
  80. package/test/tests/acceptance/plugins/font.js +0 -316
  81. package/test/tests/acceptance/plugins/image.js +0 -79
  82. package/test/tests/acceptance/plugins/indent.js +0 -179
  83. package/test/tests/acceptance/plugins/inline-popup.js +0 -578
  84. package/test/tests/acceptance/plugins/insert.js +0 -17
  85. package/test/tests/acceptance/plugins/limit.js +0 -164
  86. package/test/tests/acceptance/plugins/link.js +0 -1640
  87. package/test/tests/acceptance/plugins/orderedList.js +0 -290
  88. package/test/tests/acceptance/plugins/placeholder.js +0 -138
  89. package/test/tests/acceptance/plugins/resizer.js +0 -329
  90. package/test/tests/acceptance/plugins/search.js +0 -623
  91. package/test/tests/acceptance/plugins/size.js +0 -344
  92. package/test/tests/acceptance/plugins/source.js +0 -218
  93. package/test/tests/acceptance/plugins/stat.js +0 -120
  94. package/test/tests/acceptance/plugins/tooltip.js +0 -97
  95. package/test/tests/acceptance/plugins/wrapTextNodes.js +0 -105
  96. package/test/tests/acceptance/pluginsTest.js +0 -2219
  97. package/test/tests/acceptance/selectionTest.js +0 -862
  98. package/test/tests/acceptance/statesTest.js +0 -310
  99. package/test/tests/acceptance/tableTest.js +0 -1988
  100. package/test/tests/acceptance/toolbarTest.js +0 -1747
  101. package/test/tests/acceptance/undoredoTest.js +0 -217
  102. package/test/tests/acceptance/uploaderTest.js +0 -187
  103. package/test/tests/artio.jpg +0 -0
  104. package/test/tests/units/helpersTest.js +0 -771
  105. package/test/tests/units/modules/dom.js +0 -282
  106. package/test/tests/units/objectObserverTest.js +0 -533
  107. package/test/tests/units/popupTest.js +0 -211
  108. package/test/tests/units/positionTest.js +0 -238
  109. package/test/tests/units/styleTest.js +0 -1361
  110. 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(/&quot;/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(/&nbsp;/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(/&/, '&amp;')
1035
- .replace(/</, '&lt;')
1036
- .replace('>', '&gt;')
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
- });