jodit 4.2.14 → 4.2.17

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 (133) hide show
  1. package/CHANGELOG.md +64 -5
  2. package/es2015/jodit.css +115 -115
  3. package/es2015/jodit.fat.min.css +1 -1
  4. package/es2015/jodit.fat.min.js +2 -2
  5. package/es2015/jodit.js +928 -823
  6. package/es2015/jodit.min.css +1 -1
  7. package/es2015/jodit.min.js +2 -2
  8. package/es2015/plugins/debug/debug.js +1 -1
  9. package/es2015/plugins/debug/debug.min.js +1 -1
  10. package/es2015/plugins/speech-recognize/speech-recognize.css +1 -1
  11. package/es2015/plugins/speech-recognize/speech-recognize.js +11 -11
  12. package/es2015/plugins/speech-recognize/speech-recognize.min.js +2 -2
  13. package/es2018/jodit.css +115 -115
  14. package/es2018/jodit.fat.min.css +1 -1
  15. package/es2018/jodit.fat.min.js +2 -2
  16. package/es2018/jodit.js +928 -825
  17. package/es2018/jodit.min.css +1 -1
  18. package/es2018/jodit.min.js +2 -2
  19. package/es2018/plugins/debug/debug.js +1 -1
  20. package/es2018/plugins/debug/debug.min.js +1 -1
  21. package/es2018/plugins/speech-recognize/speech-recognize.css +1 -1
  22. package/es2018/plugins/speech-recognize/speech-recognize.js +11 -11
  23. package/es2018/plugins/speech-recognize/speech-recognize.min.js +2 -2
  24. package/es2021/jodit.css +115 -115
  25. package/es2021/jodit.fat.min.css +1 -1
  26. package/es2021/jodit.fat.min.js +2 -2
  27. package/es2021/jodit.js +922 -819
  28. package/es2021/jodit.min.css +1 -1
  29. package/es2021/jodit.min.js +2 -2
  30. package/es2021/plugins/debug/debug.js +1 -1
  31. package/es2021/plugins/debug/debug.min.js +1 -1
  32. package/es2021/plugins/speech-recognize/speech-recognize.css +1 -1
  33. package/es2021/plugins/speech-recognize/speech-recognize.js +11 -11
  34. package/es2021/plugins/speech-recognize/speech-recognize.min.js +2 -2
  35. package/es2021.en/jodit.css +115 -115
  36. package/es2021.en/jodit.fat.min.css +1 -1
  37. package/es2021.en/jodit.fat.min.js +2 -2
  38. package/es2021.en/jodit.js +922 -819
  39. package/es2021.en/jodit.min.css +1 -1
  40. package/es2021.en/jodit.min.js +2 -2
  41. package/es2021.en/plugins/debug/debug.js +1 -1
  42. package/es2021.en/plugins/debug/debug.min.js +1 -1
  43. package/es2021.en/plugins/speech-recognize/speech-recognize.css +1 -1
  44. package/es2021.en/plugins/speech-recognize/speech-recognize.js +11 -11
  45. package/es2021.en/plugins/speech-recognize/speech-recognize.min.js +2 -2
  46. package/es5/jodit.css +129 -129
  47. package/es5/jodit.fat.min.css +1 -1
  48. package/es5/jodit.fat.min.js +2 -2
  49. package/es5/jodit.js +950 -844
  50. package/es5/jodit.min.css +3 -3
  51. package/es5/jodit.min.js +2 -2
  52. package/es5/plugins/debug/debug.js +1 -1
  53. package/es5/plugins/debug/debug.min.js +1 -1
  54. package/es5/plugins/speech-recognize/speech-recognize.css +1 -1
  55. package/es5/plugins/speech-recognize/speech-recognize.js +11 -11
  56. package/es5/plugins/speech-recognize/speech-recognize.min.js +2 -2
  57. package/esm/core/constants.js +1 -1
  58. package/esm/core/helpers/utils/config-proto.js +1 -1
  59. package/esm/core/request/ajax.js +1 -1
  60. package/esm/core/selection/helpers/index.d.ts +9 -3
  61. package/esm/core/selection/helpers/index.js +48 -0
  62. package/esm/core/selection/selection.d.ts +6 -1
  63. package/esm/core/selection/selection.js +95 -117
  64. package/esm/core/ui/helpers/get-control-type.js +15 -9
  65. package/esm/core/ui/helpers/get-strong-control-types.js +1 -1
  66. package/esm/index.d.ts +6 -1
  67. package/esm/index.js +3 -2
  68. package/esm/jodit.d.ts +1 -1
  69. package/esm/jodit.js +1 -1
  70. package/esm/modules/file-browser/file-browser.js +1 -1
  71. package/esm/modules/history/history.js +1 -1
  72. package/esm/modules/image-editor/config.js +1 -1
  73. package/esm/modules/image-editor/image-editor.js +1 -1
  74. package/esm/modules/table/table.d.ts +3 -1
  75. package/esm/modules/table/table.js +38 -33
  76. package/esm/modules/toolbar/button/button.js +2 -1
  77. package/esm/modules/toolbar/button/select/select.js +2 -1
  78. package/esm/modules/uploader/helpers/send-files.js +33 -29
  79. package/esm/modules/uploader/uploader.js +1 -1
  80. package/esm/plugins/about/about.js +1 -1
  81. package/esm/plugins/add-new-line/config.js +1 -1
  82. package/esm/plugins/ai-assistant/config.js +1 -1
  83. package/esm/plugins/backspace/cases/check-remove-char.js +68 -54
  84. package/esm/plugins/bold/bold.js +1 -1
  85. package/esm/plugins/class-span/class-span.js +1 -1
  86. package/esm/plugins/clean-html/config.js +1 -1
  87. package/esm/plugins/clipboard/config.js +1 -1
  88. package/esm/plugins/color/config.js +1 -1
  89. package/esm/plugins/copy-format/copy-format.js +1 -1
  90. package/esm/plugins/drag-and-drop/drag-and-drop.d.ts +2 -0
  91. package/esm/plugins/drag-and-drop/drag-and-drop.js +43 -36
  92. package/esm/plugins/file/file.js +1 -1
  93. package/esm/plugins/font/config.js +1 -1
  94. package/esm/plugins/format-block/config.js +6 -4
  95. package/esm/plugins/fullsize/config.js +1 -1
  96. package/esm/plugins/hr/hr.js +1 -1
  97. package/esm/plugins/image/image.js +1 -1
  98. package/esm/plugins/image-properties/config.d.ts +0 -3
  99. package/esm/plugins/image-properties/config.js +3 -0
  100. package/esm/plugins/image-properties/interface.d.ts +121 -0
  101. package/esm/plugins/indent/config.js +1 -1
  102. package/esm/plugins/inline-popup/config/config.js +1 -1
  103. package/esm/plugins/justify/justify.js +10 -6
  104. package/esm/plugins/line-height/config.js +1 -1
  105. package/esm/plugins/link/config.js +1 -1
  106. package/esm/plugins/link/link.js +71 -64
  107. package/esm/plugins/mobile/config.js +1 -1
  108. package/esm/plugins/ordered-list/config.js +1 -1
  109. package/esm/plugins/paste/config.js +1 -1
  110. package/esm/plugins/print/print.js +1 -1
  111. package/esm/plugins/redo-undo/redo-undo.js +1 -1
  112. package/esm/plugins/search/config.js +1 -1
  113. package/esm/plugins/search/helpers/highlight-text-ranges.d.ts +0 -4
  114. package/esm/plugins/search/helpers/highlight-text-ranges.js +58 -49
  115. package/esm/plugins/source/config.js +1 -1
  116. package/esm/plugins/speech-recognize/config.js +1 -1
  117. package/esm/plugins/spellcheck/config.js +1 -1
  118. package/esm/plugins/symbols/config.js +1 -1
  119. package/esm/plugins/table/config.js +1 -1
  120. package/esm/plugins/table-keyboard-navigation/table-keyboard-navigation.js +35 -29
  121. package/esm/plugins/video/config.js +1 -1
  122. package/esm/types/toolbar.d.ts +1 -2
  123. package/package.json +1 -1
  124. package/types/core/selection/helpers/index.d.ts +9 -3
  125. package/types/core/selection/selection.d.ts +6 -1
  126. package/types/index.d.ts +6 -1
  127. package/types/jodit.d.ts +1 -1
  128. package/types/modules/table/table.d.ts +3 -1
  129. package/types/plugins/drag-and-drop/drag-and-drop.d.ts +2 -0
  130. package/types/plugins/image-properties/config.d.ts +0 -3
  131. package/types/plugins/image-properties/interface.d.ts +121 -0
  132. package/types/plugins/search/helpers/highlight-text-ranges.d.ts +0 -4
  133. package/types/types/toolbar.d.ts +1 -2
@@ -3,7 +3,7 @@
3
3
  * Released under MIT see LICENSE.txt in the project root for license information.
4
4
  * Copyright (c) 2013-2024 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
5
5
  */
6
- import { ConfigFlatten, isArray, isString } from "../../helpers/index.js";
6
+ import { ConfigFlatten, /*isArray,*/ isString } from "../../helpers/index.js";
7
7
  import { Config } from "../../../config.js";
8
8
  /**
9
9
  * Get control for button name
@@ -47,17 +47,23 @@ export function findControlType(path, controls) {
47
47
  else {
48
48
  key = namespaceOrKey;
49
49
  }
50
- const list = store[key]?.list;
50
+ // const list = store[key]?.list;
51
51
  return store[key]
52
52
  ? {
53
53
  name: key,
54
- ...ConfigFlatten(store[key]),
55
- list: isArray(list)
56
- ? list.reduce((acc, k) => {
57
- acc[k] = k;
58
- return acc;
59
- }, {})
60
- : list
54
+ ...ConfigFlatten(store[key])
55
+ // list: isArray(list)
56
+ // ? (<Array<string>>list).reduce(
57
+ // (
58
+ // acc: IDictionary<string | number>,
59
+ // k: string | number
60
+ // ) => {
61
+ // acc[String(k)] = k;
62
+ // return acc;
63
+ // },
64
+ // {}
65
+ // )
66
+ // : list
61
67
  }
62
68
  : undefined;
63
69
  }
@@ -5,8 +5,8 @@
5
5
  */
6
6
  import { isArray } from "../../helpers/checker/is-array.js";
7
7
  import { ConfigProto, keys } from "../../helpers/utils/index.js";
8
- import { getControlType } from "./get-control-type.js";
9
8
  import { Config } from "../../../config.js";
9
+ import { getControlType } from "./get-control-type.js";
10
10
  /**
11
11
  * @private
12
12
  */
package/esm/index.d.ts CHANGED
@@ -3,8 +3,13 @@
3
3
  * Released under MIT see LICENSE.txt in the project root for license information.
4
4
  * Copyright (c) 2013-2024 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
5
5
  */
6
- import "./plugins/index";
6
+ /**
7
+ * [[include:README.md]]
8
+ * @packageDocumentation
9
+ * @module jodit
10
+ */
7
11
  import { Jodit as DefaultJodit } from "./jodit";
12
+ import "./plugins/index";
8
13
 
9
14
 
10
15
  export { DefaultJodit as Jodit };
package/esm/index.js CHANGED
@@ -8,14 +8,15 @@
8
8
  * @packageDocumentation
9
9
  * @module jodit
10
10
  */
11
+ // eslint-disable-next-line simple-import-sort/imports
12
+ import { Jodit as DefaultJodit } from "./jodit.js";
11
13
  import { isFunction, isString } from "./core/helpers/checker/index.js";
12
- import "./plugins/index.js";
13
14
  import * as constants from "./core/constants.js";
14
15
  import * as decorators from "./core/decorators/index.js";
15
16
  import * as Modules from "./modules/index.js";
16
17
  import * as Icons from "./styles/icons/index.js";
17
- import { Jodit as DefaultJodit } from "./jodit.js";
18
18
  import Languages from "./languages.js";
19
+ import "./plugins/index.js";
19
20
  // copy constants in Jodit
20
21
  Object.keys(constants).forEach((key) => {
21
22
  DefaultJodit[key] = constants[key];
package/esm/jodit.d.ts CHANGED
@@ -12,8 +12,8 @@ import type { AjaxOptions, CanPromise, CustomCommand, ICreate, IDictionary, IFil
12
12
  import type * as Modules from "./modules";
13
13
  import * as constants from "./core/constants";
14
14
  import { Dlgs } from "./core/traits/dlgs";
15
- import { Selection, ViewWithToolbar } from "./modules";
16
15
  import { Config } from "./config";
16
+ import { Selection, ViewWithToolbar } from "./modules";
17
17
  /**
18
18
  * Class Jodit. Main class
19
19
  */
package/esm/jodit.js CHANGED
@@ -21,8 +21,8 @@ import { eventEmitter, instances, modules, pluginSystem } from "./core/global.js
21
21
  import { asArray, attr, callPromise, ConfigProto, css, error, isFunction, isJoditObject, isNumber, isPromise, isString, isVoid, kebabCase, markAsAtomic, normalizeKeyAliases, resolveElement, toArray, ucfirst } from "./core/helpers/index.js";
22
22
  import { Ajax } from "./core/request/index.js";
23
23
  import { Dlgs } from "./core/traits/dlgs.js";
24
- import { Create, Dom, History, Plugin, Selection, StatusBar, STATUSES, ViewWithToolbar } from "./modules/index.js";
25
24
  import { Config } from "./config.js";
25
+ import { Create, Dom, History, Plugin, Selection, StatusBar, STATUSES, ViewWithToolbar } from "./modules/index.js";
26
26
  const __defaultStyleDisplayKey = 'data-jodit-default-style-display';
27
27
  const __defaultClassesKey = 'data-jodit-default-classes';
28
28
  let Jodit = Jodit_1 = class Jodit extends ViewWithToolbar {
@@ -23,6 +23,7 @@ import { ConfigProto, error, isAbortError, isFunction, isString, trim } from "..
23
23
  import { Storage } from "../../core/storage/index.js";
24
24
  import { Dlgs } from "../../core/traits/dlgs.js";
25
25
  import { ViewWithToolbar } from "../../core/view/view-with-toolbar.js";
26
+ import { Config } from "../../config.js";
26
27
  import "./config.js";
27
28
  import { loadItems } from "./fetch/load-items.js";
28
29
  import { loadTree } from "./fetch/load-tree.js";
@@ -32,7 +33,6 @@ import { stateListeners } from "./listeners/state-listeners.js";
32
33
  import { DEFAULT_SOURCE_NAME } from "./data-provider.js";
33
34
  import { makeDataProvider } from "./factories.js";
34
35
  import { FileBrowserFiles, FileBrowserTree } from "./ui/index.js";
35
- import { Config } from "../../config.js";
36
36
  let FileBrowser = class FileBrowser extends ViewWithToolbar {
37
37
  /** @override */
38
38
  className() {
@@ -15,10 +15,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
15
15
  };
16
16
  import { ViewComponent } from "../../core/component/index.js";
17
17
  import { debounce } from "../../core/decorators/index.js";
18
+ import { Config } from "../../config.js";
18
19
  import { Command } from "./command.js";
19
20
  import { Snapshot } from "./snapshot.js";
20
21
  import { Stack } from "./stack.js";
21
- import { Config } from "../../config.js";
22
22
  Config.prototype.history = {
23
23
  enable: true,
24
24
  maxHistoryLength: Infinity,
@@ -4,9 +4,9 @@
4
4
  * Copyright (c) 2013-2024 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
5
5
  */
6
6
  import { Icon } from "../../core/ui/icon.js";
7
+ import { Config } from "../../config.js";
7
8
  import cropIcon from "./icons/crop.svg.js";
8
9
  import resizeIcon from "./icons/resize.svg.js";
9
- import { Config } from "../../config.js";
10
10
  Config.prototype.imageeditor = {
11
11
  min_width: 20,
12
12
  min_height: 20,
@@ -19,9 +19,9 @@ import { autobind, component, debounce, throttle } from "../../core/decorators/i
19
19
  import { Dom } from "../../core/dom/index.js";
20
20
  import { $$, attr, call, css, refs, toArray, trim } from "../../core/helpers/index.js";
21
21
  import { Button } from "../../core/ui/button/index.js";
22
+ import { Config } from "../../config.js";
22
23
  import "./config.js";
23
24
  import { form } from "./templates/form.js";
24
- import { Config } from "../../config.js";
25
25
  const jie = 'jodit-image-editor';
26
26
  const TABS = {
27
27
  resize: 'resize',
@@ -38,6 +38,7 @@ export declare class Table extends ViewComponent<IJodit> {
38
38
  private static __formalMatrix;
39
39
  /**
40
40
  * Generate formal table martix columns*rows
41
+ * @param table - Working table
41
42
  * @param callback - if return false cycle break
42
43
  */
43
44
  formalMatrix(table: HTMLTableElement, callback?: (cell: HTMLTableCellElement, row: number, col: number, colSpan: number, rowSpan: number) => false | void): HTMLTableCellElement[][];
@@ -54,7 +55,6 @@ export declare class Table extends ViewComponent<IJodit> {
54
55
  * @param line - Insert a new line after/before this
55
56
  * line contains the selected cell
56
57
  * @param after - Insert a new line after line contains the selected cell
57
- * @param create - Instance of Create class
58
58
  */
59
59
  appendRow(table: HTMLTableElement, line: false | HTMLTableRowElement, after: boolean): void;
60
60
  private static __removeRow;
@@ -78,6 +78,8 @@ export declare class Table extends ViewComponent<IJodit> {
78
78
  */
79
79
  getSelectedBound(table: HTMLTableElement, selectedCells: HTMLTableCellElement[]): number[][];
80
80
  private static __normalizeTable;
81
+ private static __removeExtraColspans;
82
+ private static __removeExtraRowspans;
81
83
  /**
82
84
  * Try recalculate all coluns and rows after change
83
85
  */
@@ -137,6 +137,7 @@ export class Table extends ViewComponent {
137
137
  }
138
138
  /**
139
139
  * Generate formal table martix columns*rows
140
+ * @param table - Working table
140
141
  * @param callback - if return false cycle break
141
142
  */
142
143
  formalMatrix(table, callback) {
@@ -205,7 +206,6 @@ export class Table extends ViewComponent {
205
206
  * @param line - Insert a new line after/before this
206
207
  * line contains the selected cell
207
208
  * @param after - Insert a new line after line contains the selected cell
208
- * @param create - Instance of Create class
209
209
  */
210
210
  appendRow(table, line, after) {
211
211
  return Table.__appendRow(table, line, after, this.j.createInside);
@@ -374,13 +374,36 @@ export class Table extends ViewComponent {
374
374
  return Table.__getSelectedBound(table, selectedCells);
375
375
  }
376
376
  static __normalizeTable(table) {
377
- let i, j, min, not;
378
377
  const __marked = [], box = Table.__formalMatrix(table);
379
- // remove extra colspans
380
- for (j = 0; j < box[0].length; j += 1) {
381
- min = 1000000;
382
- not = false;
383
- for (i = 0; i < box.length; i += 1) {
378
+ Table.__removeExtraColspans(box, __marked);
379
+ Table.__removeExtraRowspans(box, __marked);
380
+ // remove rowspans and colspans equal 1 and empty class
381
+ for (let i = 0; i < box.length; i += 1) {
382
+ for (let j = 0; j < box[i].length; j += 1) {
383
+ if (box[i][j] === undefined) {
384
+ continue; // broken table
385
+ }
386
+ if (box[i][j].hasAttribute('rowspan') &&
387
+ box[i][j].rowSpan === 1) {
388
+ attr(box[i][j], 'rowspan', null);
389
+ }
390
+ if (box[i][j].hasAttribute('colspan') &&
391
+ box[i][j].colSpan === 1) {
392
+ attr(box[i][j], 'colspan', null);
393
+ }
394
+ if (box[i][j].hasAttribute('class') &&
395
+ !attr(box[i][j], 'class')) {
396
+ attr(box[i][j], 'class', null);
397
+ }
398
+ }
399
+ }
400
+ Table.__unmark(__marked);
401
+ }
402
+ static __removeExtraColspans(box, __marked) {
403
+ for (let j = 0; j < box[0].length; j += 1) {
404
+ let min = 1000000;
405
+ let not = false;
406
+ for (let i = 0; i < box.length; i += 1) {
384
407
  if (box[i][j] === undefined) {
385
408
  continue; // broken table
386
409
  }
@@ -391,7 +414,7 @@ export class Table extends ViewComponent {
391
414
  min = Math.min(min, box[i][j].colSpan);
392
415
  }
393
416
  if (!not) {
394
- for (i = 0; i < box.length; i += 1) {
417
+ for (let i = 0; i < box.length; i += 1) {
395
418
  if (box[i][j] === undefined) {
396
419
  continue; // broken table
397
420
  }
@@ -399,10 +422,13 @@ export class Table extends ViewComponent {
399
422
  }
400
423
  }
401
424
  }
402
- // remove extra rowspans
425
+ }
426
+ static __removeExtraRowspans(box, marked) {
427
+ let i = 0;
428
+ let j = 0;
403
429
  for (i = 0; i < box.length; i += 1) {
404
- min = 1000000;
405
- not = false;
430
+ let min = 1000000;
431
+ let not = false;
406
432
  for (j = 0; j < box[i].length; j += 1) {
407
433
  if (box[i][j] === undefined) {
408
434
  continue; // broken table
@@ -418,31 +444,10 @@ export class Table extends ViewComponent {
418
444
  if (box[i][j] === undefined) {
419
445
  continue; // broken table
420
446
  }
421
- Table.__mark(box[i][j], 'rowspan', box[i][j].rowSpan - min + 1, __marked);
422
- }
423
- }
424
- }
425
- // remove rowspans and colspans equal 1 and empty class
426
- for (i = 0; i < box.length; i += 1) {
427
- for (j = 0; j < box[i].length; j += 1) {
428
- if (box[i][j] === undefined) {
429
- continue; // broken table
430
- }
431
- if (box[i][j].hasAttribute('rowspan') &&
432
- box[i][j].rowSpan === 1) {
433
- attr(box[i][j], 'rowspan', null);
434
- }
435
- if (box[i][j].hasAttribute('colspan') &&
436
- box[i][j].colSpan === 1) {
437
- attr(box[i][j], 'colspan', null);
438
- }
439
- if (box[i][j].hasAttribute('class') &&
440
- !attr(box[i][j], 'class')) {
441
- attr(box[i][j], 'class', null);
447
+ Table.__mark(box[i][j], 'rowspan', box[i][j].rowSpan - min + 1, marked);
442
448
  }
443
449
  }
444
450
  }
445
- Table.__unmark(__marked);
446
451
  }
447
452
  /**
448
453
  * Try recalculate all coluns and rows after change
@@ -98,7 +98,8 @@ let ToolbarButton = class ToolbarButton extends UIButton {
98
98
  }
99
99
  createContainer() {
100
100
  const cn = this.componentName;
101
- const container = this.j.c.span(cn), button = super.createContainer();
101
+ const container = this.j.c.span(cn);
102
+ const button = super.createContainer();
102
103
  attr(container, 'role', 'listitem');
103
104
  button.classList.remove(cn);
104
105
  button.classList.add(cn + '__button');
@@ -14,6 +14,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
14
14
  return c > 3 && r && Object.defineProperty(target, key, r), r;
15
15
  };
16
16
  import { component } from "../../../../core/decorators/index.js";
17
+ import { isPlainObject } from "../../../../core/helpers/checker/is-plain-object.js";
17
18
  import { isString } from "../../../../core/helpers/checker/is-string.js";
18
19
  import { ToolbarButton } from "../button.js";
19
20
  let ToolbarSelect = class ToolbarSelect extends ToolbarButton {
@@ -33,7 +34,7 @@ let ToolbarSelect = class ToolbarSelect extends ToolbarButton {
33
34
  const keys = Object.keys(list);
34
35
  key = keys[0];
35
36
  }
36
- const text = (list[key.toString()] || key).toString();
37
+ const text = (isPlainObject(list) ? list[key.toString()] || key : key).toString();
37
38
  this.state.text =
38
39
  this.control.textTemplate?.(this.jodit, text) ?? text;
39
40
  }
@@ -19,34 +19,7 @@ export function sendFiles(uploader, files, handlerSuccess, handlerError, process
19
19
  }
20
20
  const promises = [];
21
21
  if (o.insertImageAsBase64URI) {
22
- let file, i;
23
- for (i = 0; i < fileList.length; i += 1) {
24
- file = fileList[i];
25
- if (file && file.type) {
26
- const mime = file.type.match(/\/([a-z0-9]+)/i);
27
- const extension = mime[1] ? mime[1].toLowerCase() : '';
28
- if (o.imagesExtensions.includes(extension)) {
29
- const reader = new FileReader();
30
- promises.push(uploader.j.async.promise((resolve, reject) => {
31
- reader.onerror = reject;
32
- reader.onloadend = () => {
33
- const resp = {
34
- baseurl: '',
35
- files: [reader.result],
36
- isImages: [true]
37
- };
38
- const handler = isFunction(handlerSuccess)
39
- ? handlerSuccess
40
- : o.defaultHandlerSuccess;
41
- handler.call(uploader, resp);
42
- resolve(resp);
43
- };
44
- reader.readAsDataURL(file);
45
- }));
46
- fileList[i] = null;
47
- }
48
- }
49
- }
22
+ readImagesWithReader(fileList, o.imagesExtensions, promises, uploader, handlerSuccess, o.defaultHandlerSuccess);
50
23
  }
51
24
  fileList = fileList.filter(a => a);
52
25
  if (fileList.length) {
@@ -57,7 +30,7 @@ export function sendFiles(uploader, files, handlerSuccess, handlerError, process
57
30
  for (let i = 0; i < fileList.length; i += 1) {
58
31
  file = fileList[i];
59
32
  if (file) {
60
- const hasRealExtension = /\.[\d\w]+$/.test(file.name);
33
+ const hasRealExtension = /\.\w+$/.test(file.name);
61
34
  const mime = file.type.match(/\/([a-z0-9]+)/i);
62
35
  const extension = mime && mime[1] ? mime[1].toLowerCase() : '';
63
36
  let newName = fileList[i].name ||
@@ -106,3 +79,34 @@ export function sendFiles(uploader, files, handlerSuccess, handlerError, process
106
79
  }
107
80
  return Promise.all(promises);
108
81
  }
82
+ function readImagesWithReader(fileList, imagesExtensions, promises, uploader, handlerSuccess, defaultHandlerSuccess) {
83
+ let file, i;
84
+ for (i = 0; i < fileList.length; i += 1) {
85
+ file = fileList[i];
86
+ if (file && file.type) {
87
+ const mime = file.type.match(/\/([a-z0-9]+)/i);
88
+ const extension = mime[1] ? mime[1].toLowerCase() : '';
89
+ if (!imagesExtensions.includes(extension)) {
90
+ continue;
91
+ }
92
+ const reader = new FileReader();
93
+ promises.push(uploader.j.async.promise((resolve, reject) => {
94
+ reader.onerror = reject;
95
+ reader.onloadend = () => {
96
+ const resp = {
97
+ baseurl: '',
98
+ files: [reader.result],
99
+ isImages: [true]
100
+ };
101
+ const handler = isFunction(handlerSuccess)
102
+ ? handlerSuccess
103
+ : defaultHandlerSuccess;
104
+ handler.call(uploader, resp);
105
+ resolve(resp);
106
+ };
107
+ reader.readAsDataURL(file);
108
+ }));
109
+ fileList[i] = null;
110
+ }
111
+ }
112
+ }
@@ -6,9 +6,9 @@
6
6
  import { STATUSES, ViewComponent } from "../../core/component/index.js";
7
7
  import { IS_ES_NEXT, IS_IE } from "../../core/constants.js";
8
8
  import { ConfigProto, error, isFunction, isJoditObject } from "../../core/helpers/index.js";
9
+ import { Config } from "../../config.js";
9
10
  import { ajaxInstances, hasFiles, hasItems, processOldBrowserDrag, send, sendFiles } from "./helpers/index.js";
10
11
  import "./config.js";
11
- import { Config } from "../../config.js";
12
12
  export class Uploader extends ViewComponent {
13
13
  get j() {
14
14
  return this.jodit;
@@ -8,8 +8,8 @@ import { HOMEPAGE } from "../../core/constants.js";
8
8
  import { pluginSystem } from "../../core/global.js";
9
9
  import { css, isLicense, normalizeLicense } from "../../core/helpers/index.js";
10
10
  import { Icon } from "../../core/ui/icon.js";
11
- import aboutIcon from "./about.svg.js";
12
11
  import { Config } from "../../config.js";
12
+ import aboutIcon from "./about.svg.js";
13
13
  Config.prototype.controls.about = {
14
14
  exec: (editor) => {
15
15
  const dialog = editor.dlg({ closeOnClickOverlay: true }), i = editor.i18n.bind(editor);
@@ -4,8 +4,8 @@
4
4
  * Copyright (c) 2013-2024 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
5
5
  */
6
6
  import { Icon } from "../../core/ui/icon.js";
7
- import enterIcon from "./enter.svg.js";
8
7
  import { Config } from "../../config.js";
8
+ import enterIcon from "./enter.svg.js";
9
9
  Config.prototype.addNewLine = true;
10
10
  Config.prototype.addNewLineOnDBLClick = true;
11
11
  Config.prototype.addNewLineTagsTriggers = [
@@ -4,9 +4,9 @@
4
4
  * Copyright (c) 2013-2024 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
5
5
  */
6
6
  import { Icon } from "../../core/ui/icon.js";
7
+ import { Config } from "../../config.js";
7
8
  import magicWandIcon from "./ai-assistant.svg.js";
8
9
  import chatBotIcon from "./chat-bot.svg.js";
9
- import { Config } from "../../config.js";
10
10
  const aiAssistantDefaults = {
11
11
  aiCommonPrefixPrompt: '',
12
12
  aiCommonSuffixPrompt: '',
@@ -23,19 +23,12 @@ import { findMostNestedNeighbor } from "../helpers.js";
23
23
  export function checkRemoveChar(jodit, fakeNode, backspace, mode) {
24
24
  const step = backspace ? -1 : 1;
25
25
  const anotherSibling = Dom.sibling(fakeNode, !backspace);
26
- let sibling = Dom.sibling(fakeNode, backspace), removeNeighbor = null;
27
- let charRemoved = false, removed;
28
- const getNextInlineSibling = (sibling) => {
29
- let nextSibling = Dom.sibling(sibling, backspace);
30
- if (!nextSibling &&
31
- sibling.parentNode &&
32
- sibling.parentNode !== jodit.editor) {
33
- nextSibling = findMostNestedNeighbor(sibling, !backspace, jodit.editor, true);
34
- }
35
- return nextSibling;
36
- };
26
+ let sibling = Dom.sibling(fakeNode, backspace);
27
+ let removeNeighbor = null;
28
+ let charRemoved = false;
29
+ let removed;
37
30
  if (!sibling) {
38
- sibling = getNextInlineSibling(fakeNode);
31
+ sibling = getNextInlineSibling(fakeNode, backspace, jodit.editor);
39
32
  }
40
33
  while (sibling && (Dom.isText(sibling) || Dom.isInlineBlock(sibling))) {
41
34
  while (Dom.isInlineBlock(sibling)) {
@@ -45,57 +38,21 @@ export function checkRemoveChar(jodit, fakeNode, backspace, mode) {
45
38
  break;
46
39
  }
47
40
  if (sibling.nodeValue?.length) {
48
- // For Unicode escapes
49
- let value = toArray(sibling.nodeValue);
50
- const length = value.length;
51
- let index = backspace ? length - 1 : 0;
52
- if (value[index] === INVISIBLE_SPACE) {
53
- while (value[index] === INVISIBLE_SPACE) {
54
- index += step;
55
- }
56
- }
57
- removed = value[index];
58
- if (value[index + step] === INVISIBLE_SPACE) {
59
- index += step;
60
- while (value[index] === INVISIBLE_SPACE) {
61
- index += step;
62
- }
63
- index += backspace ? 1 : -1;
64
- }
65
- if (backspace && index < 0) {
66
- value = [];
67
- }
68
- else {
69
- value = value.slice(backspace ? 0 : index + 1, backspace ? index : length);
70
- }
71
- if (!anotherSibling ||
72
- !Dom.isText(anotherSibling) ||
73
- (!backspace ? / $/ : /^ /).test(anotherSibling.nodeValue ?? '') ||
74
- !trimInv(anotherSibling.nodeValue || '').length) {
75
- for (let i = backspace ? value.length - 1 : 0; backspace ? i >= 0 : i < value.length; i += backspace ? -1 : 1) {
76
- if (value[i] === ' ') {
77
- value[i] = NBSP_SPACE;
78
- }
79
- else {
80
- break;
81
- }
82
- }
41
+ removed = tryRemoveChar(sibling, backspace, step, anotherSibling);
42
+ if (!sibling.nodeValue.length &&
43
+ Dom.isInlineBlock(sibling.parentNode)) {
44
+ sibling.nodeValue = INVISIBLE_SPACE;
83
45
  }
84
- sibling.nodeValue = value.join('');
85
46
  }
86
47
  if (!sibling.nodeValue?.length) {
87
48
  removeNeighbor = sibling;
88
49
  }
89
50
  if (!isVoid(removed) && removed !== INVISIBLE_SPACE) {
51
+ checkRepeatRemoveCharAction(backspace, sibling, fakeNode, mode, removed, jodit);
90
52
  charRemoved = true;
91
- call(backspace ? Dom.after : Dom.before, sibling, fakeNode);
92
- if (mode === 'sentence' ||
93
- (mode === 'word' && removed !== ' ' && removed !== NBSP_SPACE)) {
94
- checkRemoveChar(jodit, fakeNode, backspace, mode);
95
- }
96
53
  break;
97
54
  }
98
- const nextSibling = getNextInlineSibling(sibling);
55
+ const nextSibling = getNextInlineSibling(sibling, backspace, jodit.editor);
99
56
  if (removeNeighbor) {
100
57
  Dom.safeRemove(removeNeighbor);
101
58
  removeNeighbor = null;
@@ -117,6 +74,13 @@ export function checkRemoveChar(jodit, fakeNode, backspace, mode) {
117
74
  }
118
75
  return charRemoved;
119
76
  }
77
+ function getNextInlineSibling(sibling, backspace, root) {
78
+ let nextSibling = Dom.sibling(sibling, backspace);
79
+ if (!nextSibling && sibling.parentNode && sibling.parentNode !== root) {
80
+ nextSibling = findMostNestedNeighbor(sibling, !backspace, root, true);
81
+ }
82
+ return nextSibling;
83
+ }
120
84
  /**
121
85
  * Helper removes all empty inline parents
122
86
  */
@@ -141,3 +105,53 @@ function addBRInsideEmptyBlock(jodit, node) {
141
105
  Dom.after(node, jodit.createInside.element('br'));
142
106
  }
143
107
  }
108
+ function tryRemoveChar(sibling, backspace, step, anotherSibling) {
109
+ // For Unicode escapes
110
+ let value = toArray(sibling.nodeValue);
111
+ const length = value.length;
112
+ let index = backspace ? length - 1 : 0;
113
+ if (value[index] === INVISIBLE_SPACE) {
114
+ while (value[index] === INVISIBLE_SPACE) {
115
+ index += step;
116
+ }
117
+ }
118
+ const removed = value[index];
119
+ if (value[index + step] === INVISIBLE_SPACE) {
120
+ index += step;
121
+ while (value[index] === INVISIBLE_SPACE) {
122
+ index += step;
123
+ }
124
+ index += backspace ? 1 : -1;
125
+ }
126
+ if (backspace && index < 0) {
127
+ value = [];
128
+ }
129
+ else {
130
+ value = value.slice(backspace ? 0 : index + 1, backspace ? index : length);
131
+ }
132
+ replaceSpaceOnNBSP(anotherSibling, backspace, value);
133
+ sibling.nodeValue = value.join('');
134
+ return removed;
135
+ }
136
+ function replaceSpaceOnNBSP(anotherSibling, backspace, value) {
137
+ if (!anotherSibling ||
138
+ !Dom.isText(anotherSibling) ||
139
+ (!backspace ? / $/ : /^ /).test(anotherSibling.nodeValue ?? '') ||
140
+ !trimInv(anotherSibling.nodeValue || '').length) {
141
+ for (let i = backspace ? value.length - 1 : 0; backspace ? i >= 0 : i < value.length; i += backspace ? -1 : 1) {
142
+ if (value[i] === ' ') {
143
+ value[i] = NBSP_SPACE;
144
+ }
145
+ else {
146
+ break;
147
+ }
148
+ }
149
+ }
150
+ }
151
+ function checkRepeatRemoveCharAction(backspace, sibling, fakeNode, mode, removed, jodit) {
152
+ call(backspace ? Dom.after : Dom.before, sibling, fakeNode);
153
+ if (mode === 'sentence' ||
154
+ (mode === 'word' && removed !== ' ' && removed !== NBSP_SPACE)) {
155
+ checkRemoveChar(jodit, fakeNode, backspace, mode);
156
+ }
157
+ }
@@ -6,6 +6,7 @@
6
6
  import { pluginSystem } from "../../core/global.js";
7
7
  import { isArray } from "../../core/helpers/index.js";
8
8
  import { Icon } from "../../core/ui/icon.js";
9
+ import { Config } from "../../config.js";
9
10
  import "./interface.js";
10
11
  import "./config.js";
11
12
  import boldIcon from "./icons/bold.svg.js";
@@ -14,7 +15,6 @@ import strikethroughIcon from "./icons/strikethrough.svg.js";
14
15
  import subscriptIcon from "./icons/subscript.svg.js";
15
16
  import superscriptIcon from "./icons/superscript.svg.js";
16
17
  import underlineIcon from "./icons/underline.svg.js";
17
- import { Config } from "../../config.js";
18
18
  /**
19
19
  * Adds `bold`,` strikethrough`, `underline` and` italic` buttons to Jodit
20
20
  */
@@ -8,8 +8,8 @@ import { pluginSystem } from "../../core/global.js";
8
8
  import { memorizeExec } from "../../core/helpers/utils/utils.js";
9
9
  import { Plugin } from "../../core/plugin/index.js";
10
10
  import { Icon } from "../../core/ui/icon.js";
11
- import classSpanIcon from "./class-span.svg.js";
12
11
  import { Config } from "../../config.js";
12
+ import classSpanIcon from "./class-span.svg.js";
13
13
  Config.prototype.controls.classSpan = {
14
14
  command: 'applyClassName',
15
15
  exec: memorizeExec,
@@ -4,8 +4,8 @@
4
4
  * Copyright (c) 2013-2024 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
5
5
  */
6
6
  import { Icon } from "../../core/ui/icon.js";
7
- import eraserIcon from "./eraser.svg.js";
8
7
  import { Config } from "../../config.js";
8
+ import eraserIcon from "./eraser.svg.js";
9
9
  Config.prototype.cleanHTML = {
10
10
  timeout: 300,
11
11
  removeEmptyElements: true,