jodit 3.2.37 → 3.2.44

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 (69) hide show
  1. package/README.md +2 -0
  2. package/build/jodit.min.css +2 -2
  3. package/build/jodit.min.js +2 -2
  4. package/package.json +1 -1
  5. package/src/Config.ts +6 -0
  6. package/src/Jodit.ts +18 -11
  7. package/src/index.ts +1 -0
  8. package/src/langs/ar.ts +1 -0
  9. package/src/langs/cs_cz.ts +2 -1
  10. package/src/langs/de.ts +1 -0
  11. package/src/langs/es.ts +1 -0
  12. package/src/langs/fr.ts +1 -0
  13. package/src/langs/hu.ts +2 -0
  14. package/src/langs/index.ts +2 -1
  15. package/src/langs/it.ts +223 -0
  16. package/src/langs/nl.ts +1 -0
  17. package/src/langs/pt_br.ts +1 -0
  18. package/src/langs/ru.ts +1 -0
  19. package/src/langs/tr.ts +1 -0
  20. package/src/langs/zh_cn.ts +1 -0
  21. package/src/modules/Create.ts +13 -2
  22. package/src/modules/Dom.ts +1 -1
  23. package/src/modules/Uploader.ts +22 -5
  24. package/src/modules/Widget.ts +64 -15
  25. package/src/modules/dialog/dialog.ts +5 -5
  26. package/src/modules/filebrowser/config.ts +698 -0
  27. package/src/modules/filebrowser/fileBrowser.ts +31 -685
  28. package/src/modules/helpers/checker/hasBrowserColorPicker.ts +27 -0
  29. package/src/modules/helpers/checker/index.ts +2 -1
  30. package/src/modules/helpers/html/cleanFromWord.ts +34 -21
  31. package/src/modules/helpers/html/clear.ts +2 -2
  32. package/src/modules/popup/popup.ts +1 -1
  33. package/src/modules/toolbar/button.ts +17 -8
  34. package/src/modules/toolbar/collection.ts +10 -0
  35. package/src/modules/view/panel.ts +1 -1
  36. package/src/plugins/hotkeys.ts +1 -1
  37. package/src/plugins/iframe.ts +4 -1
  38. package/src/plugins/resizer.ts +20 -10
  39. package/src/plugins/size.ts +10 -10
  40. package/src/plugins/source.ts +2 -4
  41. package/src/plugins/table.ts +78 -26
  42. package/src/styles/icons/index.ts +2 -0
  43. package/src/styles/icons/palette.svg +13 -0
  44. package/src/styles/modules/btn.less +3 -3
  45. package/src/styles/modules/dropdownlist.less +11 -0
  46. package/src/styles/modules/icon.less +10 -3
  47. package/src/styles/modules/toolbar.less +17 -1
  48. package/src/styles/plugins/table.less +2 -1
  49. package/src/styles/widgets/colorpicker.less +27 -5
  50. package/src/types/create.d.ts +2 -0
  51. package/src/types/fileBrowser.d.ts +5 -5
  52. package/src/types/toolbar.d.ts +3 -1
  53. package/src/types/view.d.ts +5 -4
  54. package/src/utils/lang-loader.js +1 -1
  55. package/test/bootstrap.js +50 -34
  56. package/test/test.html +2 -1
  57. package/test/tests/commandsTest.js +2 -2
  58. package/test/tests/editorTest.js +1 -65
  59. package/test/tests/enterTest.js +9 -9
  60. package/test/tests/filebrowserTest.js +1 -1
  61. package/test/tests/iframeTest.js +1 -11
  62. package/test/tests/imageTest.js +20 -20
  63. package/test/tests/interfaceTest.js +132 -12
  64. package/test/tests/plugins/dragAndDropElement.js +1 -1
  65. package/test/tests/plugins/size.js +110 -0
  66. package/test/tests/pluginsTest.js +6 -6
  67. package/test/tests/tableTest.js +17 -17
  68. package/test/tests/uploaderTest.js +38 -4
  69. package/webpack.config.js +0 -1
@@ -0,0 +1,27 @@
1
+ /*!
2
+ * Jodit Editor (https://xdsoft.net/jodit/)
3
+ * License GNU General Public License version 2 or later;
4
+ * Copyright 2013-2019 Valeriy Chupurnov https://xdsoft.net
5
+ */
6
+
7
+ /**
8
+ * Check if browser has a color picker (a new HTML5 attribute for input tag)
9
+ *
10
+ * @method hasBrowserColorPicker
11
+ * @return {boolean}
12
+ */
13
+ export const hasBrowserColorPicker = (): boolean => {
14
+ let supportsColor = true;
15
+
16
+ try {
17
+ const
18
+ a = document.createElement("input");
19
+
20
+ a.type = "color";
21
+ supportsColor = a.type === "color" && typeof a.selectionStart !== "number";
22
+ } catch (e) {
23
+ supportsColor = false;
24
+ }
25
+
26
+ return supportsColor;
27
+ };
@@ -11,4 +11,5 @@ export * from './isLicense';
11
11
  export * from './isNumeric';
12
12
  export * from './isPlainObject';
13
13
  export * from './isURL';
14
- export * from './isWindow';
14
+ export * from './isWindow';
15
+ export * from './hasBrowserColorPicker';
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  import { Dom } from '../../Dom';
8
+ import { trim } from '../string';
8
9
 
9
10
  /**
10
11
  * The method automatically cleans up content from Microsoft Word and other HTML sources to ensure clean, compliant
@@ -34,26 +35,36 @@ export const cleanFromWord = (html: string): string => {
34
35
  }
35
36
  switch (node.nodeType) {
36
37
  case Node.ELEMENT_NODE:
37
- if (node.nodeName === 'FONT') {
38
- Dom.unwrap(node);
39
- } else {
40
- [].slice
41
- .call((node as Element).attributes)
42
- .forEach((attr: Attr) => {
43
- if (
44
- [
45
- 'src',
46
- 'href',
47
- 'rel',
48
- 'content',
49
- ].indexOf(attr.name.toLowerCase()) ===
50
- -1
51
- ) {
52
- (node as Element).removeAttribute(
53
- attr.name
54
- );
55
- }
56
- });
38
+ switch (node.nodeName) {
39
+ case 'STYLE':
40
+ case 'LINK':
41
+ case 'META':
42
+ marks.push(node);
43
+ break;
44
+
45
+ case 'W:SDT':
46
+ case 'W:SDTPR':
47
+ case 'FONT':
48
+ Dom.unwrap(node);
49
+ break;
50
+
51
+ default:
52
+ Array.from((node as Element).attributes)
53
+ .forEach((attr: Attr) => {
54
+ if (
55
+ [
56
+ 'src',
57
+ 'href',
58
+ 'rel',
59
+ 'content',
60
+ ].indexOf(attr.name.toLowerCase()) ===
61
+ -1
62
+ ) {
63
+ (node as Element).removeAttribute(
64
+ attr.name
65
+ );
66
+ }
67
+ });
57
68
  }
58
69
  break;
59
70
  case Node.TEXT_NODE:
@@ -73,7 +84,9 @@ export const cleanFromWord = (html: string): string => {
73
84
  html = convertedString;
74
85
  }
75
86
 
87
+ html = html.split(/(\n)/).filter(trim).join('\n');
88
+
76
89
  return html
77
90
  .replace(/<(\/)?(html|colgroup|col|o:p)[^>]*>/g, '')
78
91
  .replace(/<!--[^>]*>/g, '');
79
- };
92
+ };
@@ -1,4 +1,4 @@
1
- /*!
1
+ /*!
2
2
  * Jodit Editor (https://xdsoft.net/jodit/)
3
3
  * License GNU General Public License version 2 or later;
4
4
  * Copyright 2013-2019 Valeriy Chupurnov https://xdsoft.net
@@ -28,4 +28,4 @@ export const clear = (value: string, removeEmptyBlocks = false): string => {
28
28
  }
29
29
 
30
30
  return value;
31
- };
31
+ };
@@ -115,7 +115,7 @@ export class Popup extends Component {
115
115
  * @param {boolean} [noStandartActions=false] No call standarts action
116
116
  */
117
117
  open(
118
- content: any,
118
+ content: string | HTMLElement | IControlTypeStrong,
119
119
  rightAlign?: boolean,
120
120
  noStandartActions: boolean = false
121
121
  ) {
@@ -130,15 +130,17 @@ export class ToolbarButton extends ToolbarElement implements IToolbarButton {
130
130
  popup
131
131
  ) !== false
132
132
  ) {
133
- popup.open(
134
- control.popup(
135
- this.jodit,
136
- getTarget(),
137
- control,
138
- popup.close,
139
- this
140
- )
133
+ const popupElm = control.popup(
134
+ this.jodit,
135
+ getTarget(),
136
+ control,
137
+ popup.close,
138
+ this
141
139
  );
140
+
141
+ if (popupElm) {
142
+ popup.open(popupElm);
143
+ }
142
144
  }
143
145
  /**
144
146
  * Fired after popup was opened for some control button
@@ -230,6 +232,13 @@ export class ToolbarButton extends ToolbarElement implements IToolbarButton {
230
232
 
231
233
  this.container.classList.add('jodit_toolbar_btn-' + clearName);
232
234
 
235
+ if (this.jodit.options.direction) {
236
+ const
237
+ direction = this.jodit.options.direction.toLowerCase() === 'rtl' ? 'rtl' : 'ltr';
238
+
239
+ this.container.style.direction = direction;
240
+ }
241
+
233
242
  if (control.isInput) {
234
243
  this.container.classList.add('jodit_toolbar-input');
235
244
  } else {
@@ -237,10 +237,20 @@ export class ToolbarCollection<T extends IViewBased = IViewBased>
237
237
 
238
238
  container: HTMLElement;
239
239
 
240
+ /**
241
+ * Set direction
242
+ * @param direction
243
+ */
244
+ setDirection(direction: 'rtl' | 'ltr'): void {
245
+ this.container.style.direction = direction;
246
+ this.container.setAttribute('dir', direction);
247
+ }
248
+
240
249
  constructor(jodit: IViewBased) {
241
250
  super(<T>jodit);
242
251
  this.container = this.jodit.create.element('ul');
243
252
  this.container.classList.add('jodit_toolbar');
253
+
244
254
  this.initEvents();
245
255
  }
246
256
 
@@ -20,7 +20,7 @@ export class Panel extends Component implements IPanel {
20
20
  public container: HTMLDivElement;
21
21
 
22
22
  /**
23
- * @property {Create} Creator
23
+ * @property {Create} Native DOM element creator
24
24
  */
25
25
  public create: Create;
26
26
 
@@ -18,13 +18,13 @@ declare module '../Config' {
18
18
  /**
19
19
  * You can redefine hotkeys for some command
20
20
  *
21
+ * @example
21
22
  * var jodit = new Jodit('#editor', {
22
23
  * commandToHotkeys: {
23
24
  * bold: 'ctrl+shift+b',
24
25
  * italic: ['ctrl+i', 'ctrl+b'],
25
26
  * }
26
27
  * })
27
- * @type {{}}
28
28
  */
29
29
  Config.prototype.commandToHotkeys = {
30
30
  removeFormat: ['ctrl+shift+m', 'cmd+shift+m'],
@@ -207,6 +207,7 @@ export function iframe(editor: IJodit) {
207
207
  editor.iframe = editor.ownerDocument.createElement(
208
208
  'iframe'
209
209
  ) as HTMLIFrameElement;
210
+
210
211
  editor.iframe.style.display = 'block';
211
212
  editor.iframe.src = 'about:blank';
212
213
  editor.iframe.className = 'jodit_wysiwyg_iframe';
@@ -227,6 +228,8 @@ export function iframe(editor: IJodit) {
227
228
  editor.editorDocument = doc;
228
229
  editor.editorWindow = editor.iframe.contentWindow as Window;
229
230
 
231
+ editor.create.inside.setDocument(doc);
232
+
230
233
  editor.editor = doc.body as HTMLBodyElement;
231
234
 
232
235
  if (editor.options.height === 'auto') {
@@ -263,7 +266,7 @@ export function iframe(editor: IJodit) {
263
266
  e.matches || (e.matches = Element.prototype.matches); // fix inside iframe polifill
264
267
  })((editor.editorWindow as any).Element.prototype);
265
268
 
266
- // throw events in our word
269
+ // throw events in our world
267
270
  if (editor.editorDocument.documentElement) {
268
271
  editor.events
269
272
  .on(
@@ -48,6 +48,7 @@ Config.prototype.useTableResizer = true;
48
48
  * @property{boolean} useImageResizer=true Use true image editing frame size
49
49
  */
50
50
  Config.prototype.useImageResizer = true;
51
+
51
52
  /**
52
53
  * @property {object} resizer
53
54
  * @property {int} resizer.min_width=10 The minimum width for the editable element
@@ -66,10 +67,11 @@ Config.prototype.resizer = {
66
67
  * @param {Jodit} editor
67
68
  */
68
69
  export function resizer(editor: IJodit) {
69
- // let clicked = false,
70
- // resized = false,
71
- const LOCK_KEY = 'resizer';
72
- let handle: HTMLElement,
70
+ const
71
+ LOCK_KEY = 'resizer';
72
+
73
+ let
74
+ handle: HTMLElement,
73
75
  currentElement: null | HTMLElement,
74
76
  resizeElementClicked: boolean = false,
75
77
  isResizing: boolean = false,
@@ -82,12 +84,11 @@ export function resizer(editor: IJodit) {
82
84
  new_w: number,
83
85
  diff_x: number,
84
86
  diff_y: number,
85
- // timeouts = [],
86
-
87
87
  resizerIsVisible: boolean = false,
88
88
  timeoutSizeViewer: number = 0;
89
89
 
90
- const resizerElm: HTMLElement = editor.create.fromHTML(
90
+ const
91
+ resizerElm: HTMLElement = editor.create.fromHTML(
91
92
  '<div data-editor_id="' +
92
93
  editor.id +
93
94
  '" style="display:none" class="jodit_resizer">' +
@@ -98,18 +99,22 @@ export function resizer(editor: IJodit) {
98
99
  '<span>100x100</span>' +
99
100
  '</div>'
100
101
  ),
102
+
101
103
  sizeViewer: HTMLSpanElement = resizerElm.getElementsByTagName(
102
104
  'span'
103
105
  )[0],
106
+
104
107
  hideResizer = () => {
105
108
  isResizing = false;
106
109
  resizerIsVisible = false;
107
110
  currentElement = null;
108
111
  resizerElm.style.display = 'none';
109
112
  },
113
+
110
114
  hideSizeViewer = () => {
111
115
  sizeViewer.style.opacity = '0';
112
116
  },
117
+
113
118
  showSizeViewer = (w: number, h: number) => {
114
119
  if (!editor.options.resizer.showSize) {
115
120
  return;
@@ -129,9 +134,11 @@ export function resizer(editor: IJodit) {
129
134
  editor.options.resizer.hideSizeTimeout
130
135
  );
131
136
  },
137
+
132
138
  updateSize = () => {
133
139
  if (resizerIsVisible && currentElement && resizerElm) {
134
- const workplacePosition: IBound = offset(
140
+ const
141
+ workplacePosition: IBound = offset(
135
142
  (resizerElm.parentNode ||
136
143
  editor.ownerDocument
137
144
  .documentElement) as HTMLElement,
@@ -152,8 +159,9 @@ export function resizer(editor: IJodit) {
152
159
  // 1 - because need move border higher and toWYSIWYG the left than the picture
153
160
  // 2 - in box-sizing: border-box mode width is real width indifferent by border-width.
154
161
 
155
- const newTop: number = pos.top - 1 - workplacePosition.top;
156
- const newLeft: number = pos.left - 1 - workplacePosition.left;
162
+ const
163
+ newTop: number = pos.top - 1 - workplacePosition.top,
164
+ newLeft: number = pos.left - 1 - workplacePosition.left;
157
165
 
158
166
  if (
159
167
  top !== newTop ||
@@ -178,6 +186,7 @@ export function resizer(editor: IJodit) {
178
186
  }
179
187
  }
180
188
  },
189
+
181
190
  showResizer = () => {
182
191
  if (editor.options.readonly) {
183
192
  return;
@@ -199,6 +208,7 @@ export function resizer(editor: IJodit) {
199
208
 
200
209
  updateSize();
201
210
  },
211
+
202
212
  /**
203
213
  * Bind an edit element toWYSIWYG element
204
214
  * @param {HTMLElement} element The element that you want toWYSIWYG add a function toWYSIWYG resize
@@ -26,6 +26,7 @@ Config.prototype.allowResizeY = true;
26
26
  export function size(editor: IJodit) {
27
27
  const setHeight = (height: number | string) => {
28
28
  css(editor.container, 'height', height);
29
+
29
30
  if (editor.options.saveHeightInStorage) {
30
31
  editor.storage.set('height', height);
31
32
  }
@@ -70,17 +71,16 @@ export function size(editor: IJodit) {
70
71
  'mousemove touchmove',
71
72
  throttle((e: MouseEvent) => {
72
73
  if (isResized) {
73
- setHeight(
74
- editor.options.allowResizeY
75
- ? start.h + e.clientY - start.y
76
- : start.h
77
- );
78
- setWidth(
79
- editor.options.allowResizeX
80
- ? start.w + e.clientX - start.x
81
- : start.w
82
- );
74
+ if (editor.options.allowResizeY) {
75
+ setHeight(start.h + e.clientY - start.y);
76
+ }
77
+
78
+ if (editor.options.allowResizeX) {
79
+ setWidth(start.w + e.clientX - start.x);
80
+ }
81
+
83
82
  resizeWorkspaceImd();
83
+
84
84
  editor.events.fire('resize');
85
85
  }
86
86
  }, editor.defaultTimeout / 10)
@@ -137,12 +137,10 @@ export class source extends Plugin {
137
137
  if (
138
138
  eventOnFinalize &&
139
139
  urls[i] === undefined &&
140
- this.jodit &&
141
- this.jodit.events &&
142
140
  !this.isDestructed
143
141
  ) {
144
- this.jodit.events.fire(eventOnFinalize);
145
- this.jodit.events.fire(this.jodit.ownerWindow, eventOnFinalize);
142
+ this.jodit && this.jodit.events && this.jodit.events.fire(eventOnFinalize);
143
+ this.jodit && this.jodit.events && this.jodit.events.fire(this.jodit.ownerWindow, eventOnFinalize);
146
144
 
147
145
  return;
148
146
  }
@@ -15,6 +15,7 @@ import {
15
15
  offset,
16
16
  scrollIntoView,
17
17
  } from '../modules/helpers/';
18
+ import { setTimeout } from '../modules/helpers/async';
18
19
  import { IControlType } from '../types/toolbar';
19
20
  import { IBound, IDictionary } from '../types/types';
20
21
  import { IJodit } from '../types';
@@ -87,8 +88,10 @@ Config.prototype.controls.table = {
87
88
  '</div>' +
88
89
  '</form>'
89
90
  ) as HTMLFormElement,
91
+
90
92
  rows: HTMLSpanElement = form.querySelectorAll('span')[0],
91
93
  cols: HTMLSpanElement = form.querySelectorAll('span')[1],
94
+
92
95
  blocksContainer: HTMLDivElement = form.querySelector(
93
96
  '.jodit_form-container'
94
97
  ) as HTMLDivElement,
@@ -285,14 +288,31 @@ Config.prototype.controls.table = {
285
288
  * Process tables in editor
286
289
  */
287
290
  export class TableProcessor extends Plugin {
288
- public static isCell(tag: Node | null): boolean {
291
+ static isCell(tag: Node | null): boolean {
289
292
  return !!tag && /^TD|TH$/i.test(tag.nodeName);
290
293
  }
294
+
291
295
  private __key: string = 'table_processor_observer';
296
+
292
297
  private __selectMode: boolean = false;
293
298
 
294
299
  private __resizerDelta: number = 0;
295
300
  private __resizerHandler: HTMLElement;
301
+
302
+ showResizer() {
303
+ clearTimeout(this.hideTimeout);
304
+ this.__resizerHandler.style.display = 'block';
305
+ }
306
+
307
+ hideResizer() {
308
+ clearTimeout(this.hideTimeout);
309
+ this.hideTimeout = setTimeout(() => {
310
+ this.__resizerHandler.style.display = 'none';
311
+ }, this.jodit.defaultTimeout);
312
+ }
313
+
314
+ private hideTimeout: number;
315
+
296
316
  private __drag: boolean = false;
297
317
 
298
318
  private __wholeTable: boolean | null;
@@ -355,11 +375,12 @@ export class TableProcessor extends Plugin {
355
375
  'jodit_table_resizer'
356
376
  );
357
377
 
358
- let startX: number = 0; // , startLeft = 0;
378
+ let startX: number = 0;
379
+
359
380
  this.jodit.events
360
381
  .on(
361
382
  this.__resizerHandler,
362
- 'mousedown touchstart',
383
+ 'mousedown.table touchstart.table',
363
384
  (event: MouseEvent) => {
364
385
  this.__drag = true;
365
386
 
@@ -416,12 +437,28 @@ export class TableProcessor extends Plugin {
416
437
  }
417
438
  )
418
439
  .on(
419
- this.jodit.ownerWindow,
420
- 'mousemove touchmoove',
440
+ this.__resizerHandler,
441
+ 'mouseenter.table',
442
+ () => {
443
+ clearTimeout(this.hideTimeout);
444
+ }
445
+ )
446
+ .on(
447
+ this.jodit.editorWindow,
448
+ 'mousemove.table touchmove.table',
421
449
  (event: MouseEvent) => {
422
450
  if (this.__drag) {
423
451
  let x = event.clientX;
424
452
 
453
+ const workplacePosition: IBound = offset(
454
+ (this.__resizerHandler.parentNode ||
455
+ this.jodit.ownerDocument
456
+ .documentElement) as HTMLElement,
457
+ this.jodit,
458
+ this.jodit.ownerDocument,
459
+ true
460
+ );
461
+
425
462
  if (x < this.__minX) {
426
463
  x = this.__minX;
427
464
  }
@@ -429,12 +466,13 @@ export class TableProcessor extends Plugin {
429
466
  x = this.__maxX;
430
467
  }
431
468
 
432
- this.__resizerDelta = x - startX;
433
- this.__resizerHandler.style.left = x + 'px';
469
+ this.__resizerDelta = x - startX + (!this.jodit.options.iframe ? 0 : workplacePosition.left);
470
+ this.__resizerHandler.style.left = (x - (this.jodit.options.iframe ? 0 : workplacePosition.left)) + 'px';
434
471
 
435
472
  this.jodit.editorWindow
436
473
  .getSelection()
437
474
  .removeAllRanges();
475
+
438
476
  if (event.preventDefault) {
439
477
  event.preventDefault();
440
478
  }
@@ -442,7 +480,7 @@ export class TableProcessor extends Plugin {
442
480
  }
443
481
  );
444
482
 
445
- this.jodit.container.appendChild(this.__resizerHandler);
483
+ this.jodit.workplace.appendChild(this.__resizerHandler);
446
484
  }
447
485
  }
448
486
  };
@@ -463,21 +501,32 @@ export class TableProcessor extends Plugin {
463
501
  offsetX: number = 0,
464
502
  delta: number = 0
465
503
  ) {
466
- const box = offset(cell, this.jodit, this.jodit.editorDocument);
504
+ const
505
+ box = offset(cell, this.jodit, this.jodit.editorDocument);
506
+
467
507
  if (offsetX <= consts.NEARBY || box.width - offsetX <= consts.NEARBY) {
468
- const parentBox: IBound = offset(
469
- table,
470
- this.jodit,
471
- this.jodit.editorDocument
472
- );
508
+ const
509
+ workplacePosition: IBound = offset(
510
+ (this.__resizerHandler.parentNode ||
511
+ this.jodit.ownerDocument
512
+ .documentElement) as HTMLElement,
513
+ this.jodit,
514
+ this.jodit.ownerDocument,
515
+ true
516
+ ),
517
+ parentBox: IBound = offset(
518
+ table,
519
+ this.jodit,
520
+ this.jodit.editorDocument
521
+ );
473
522
 
474
523
  this.__resizerHandler.style.left =
475
- (offsetX <= consts.NEARBY ? box.left : box.left + box.width) +
476
- delta +
477
- 'px';
524
+ ((offsetX <= consts.NEARBY ? box.left : box.left + box.width) - workplacePosition.left + delta) + 'px';
525
+
478
526
  this.__resizerHandler.style.height = parentBox.height + 'px';
479
- this.__resizerHandler.style.top = parentBox.top + 'px';
480
- this.__resizerHandler.style.display = 'block';
527
+ this.__resizerHandler.style.top = (parentBox.top - workplacePosition.top) + 'px';
528
+
529
+ this.showResizer();
481
530
 
482
531
  if (offsetX <= consts.NEARBY) {
483
532
  const prevTD = Dom.prev(
@@ -499,7 +548,7 @@ export class TableProcessor extends Plugin {
499
548
  this.__setWorkCell(cell, !nextTD ? false : null);
500
549
  }
501
550
  } else {
502
- this.__resizerHandler.style.display = 'none';
551
+ this.hideResizer();
503
552
  }
504
553
  }
505
554
 
@@ -577,12 +626,13 @@ export class TableProcessor extends Plugin {
577
626
  }
578
627
  };
579
628
 
580
- public observe(table: HTMLTableElement) {
629
+ observe(table: HTMLTableElement) {
581
630
  (table as any)[this.__key] = true;
631
+
582
632
  let start: HTMLTableCellElement;
583
633
 
584
634
  this.jodit.events
585
- .on(table, 'mousedown touchstart', (event: MouseEvent) => {
635
+ .on(table, 'mousedown.table touchstart.table', (event: MouseEvent) => {
586
636
  if (this.jodit.options.readonly) {
587
637
  return;
588
638
  }
@@ -607,15 +657,15 @@ export class TableProcessor extends Plugin {
607
657
  this.__selectMode = true;
608
658
  }
609
659
  })
610
- .on(table, 'mouseleave', (e: MouseEvent) => {
660
+ .on(table, 'mouseleave.table', (e: MouseEvent) => {
611
661
  if (
612
662
  this.__resizerHandler &&
613
663
  this.__resizerHandler !== e.relatedTarget
614
664
  ) {
615
- this.__resizerHandler.style.display = 'none';
665
+ this.hideResizer();
616
666
  }
617
667
  })
618
- .on(table, 'mousemove touchmove', (event: MouseEvent) => {
668
+ .on(table, 'mousemove.table touchmove.table', (event: MouseEvent) => {
619
669
  if (this.jodit.options.readonly) {
620
670
  return;
621
671
  }
@@ -658,7 +708,8 @@ export class TableProcessor extends Plugin {
658
708
  }
659
709
  }
660
710
 
661
- const max = box[bound[1][0]][bound[1][1]],
711
+ const
712
+ max = box[bound[1][0]][bound[1][1]],
662
713
  min = box[bound[0][0]][bound[0][1]];
663
714
 
664
715
  this.jodit.events.fire(
@@ -780,6 +831,7 @@ export class TableProcessor extends Plugin {
780
831
  '%';
781
832
  }
782
833
  }
834
+
783
835
  editor.setEditorValue();
784
836
  editor.selection.focus();
785
837
  }
@@ -78,6 +78,7 @@ import * as update from './update.svg';
78
78
  import * as upload from './upload.svg';
79
79
  import * as valign from './valign.svg';
80
80
  import * as video from './video.svg';
81
+ import * as palette from './palette.svg';
81
82
 
82
83
  export {
83
84
  about,
@@ -154,4 +155,5 @@ export {
154
155
  upload,
155
156
  valign,
156
157
  video,
158
+ palette
157
159
  };
@@ -0,0 +1,13 @@
1
+ <svg x="0px" y="0px" viewBox="0 0 459 459">
2
+ <g>
3
+ <g>
4
+ <path d="M229.5,0C102,0,0,102,0,229.5S102,459,229.5,459c20.4,0,38.25-17.85,38.25-38.25c0-10.2-2.55-17.85-10.2-25.5
5
+ c-5.1-7.65-10.2-15.3-10.2-25.5c0-20.4,17.851-38.25,38.25-38.25h45.9c71.4,0,127.5-56.1,127.5-127.5C459,91.8,357,0,229.5,0z
6
+ M89.25,229.5c-20.4,0-38.25-17.85-38.25-38.25S68.85,153,89.25,153s38.25,17.85,38.25,38.25S109.65,229.5,89.25,229.5z
7
+ M165.75,127.5c-20.4,0-38.25-17.85-38.25-38.25S145.35,51,165.75,51S204,68.85,204,89.25S186.15,127.5,165.75,127.5z
8
+ M293.25,127.5c-20.4,0-38.25-17.85-38.25-38.25S272.85,51,293.25,51s38.25,17.85,38.25,38.25S313.65,127.5,293.25,127.5z
9
+ M369.75,229.5c-20.4,0-38.25-17.85-38.25-38.25S349.35,153,369.75,153S408,170.85,408,191.25S390.15,229.5,369.75,229.5z"
10
+ />
11
+ </g>
12
+ </g>
13
+ </svg>
@@ -9,10 +9,10 @@
9
9
  border-radius: 0;
10
10
 
11
11
  background-color: #f5f5f5;
12
- background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);
13
- border-color: #cccccc;
12
+ background-image: linear-gradient(to bottom, #fff, #e6e6e6);
13
+ border-color: #ccc;
14
14
  text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
15
- color: #333333;
15
+ color: #333;
16
16
 
17
17
  background-repeat: repeat-x;
18
18
  outline: 0;