jodit 4.6.6 → 4.6.10

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/CHANGELOG.md +41 -0
  2. package/es2015/jodit.css +1 -1
  3. package/es2015/jodit.fat.min.js +2 -2
  4. package/es2015/jodit.js +161 -25
  5. package/es2015/jodit.min.js +2 -2
  6. package/es2015/plugins/debug/debug.css +1 -1
  7. package/es2015/plugins/debug/debug.js +1 -1
  8. package/es2015/plugins/debug/debug.min.js +1 -1
  9. package/es2015/plugins/speech-recognize/speech-recognize.css +1 -1
  10. package/es2015/plugins/speech-recognize/speech-recognize.js +1 -1
  11. package/es2015/plugins/speech-recognize/speech-recognize.min.js +1 -1
  12. package/es2018/jodit.css +1 -1
  13. package/es2018/jodit.fat.min.js +2 -2
  14. package/es2018/jodit.js +161 -25
  15. package/es2018/jodit.min.js +2 -2
  16. package/es2018/plugins/debug/debug.css +1 -1
  17. package/es2018/plugins/debug/debug.js +1 -1
  18. package/es2018/plugins/debug/debug.min.js +1 -1
  19. package/es2018/plugins/speech-recognize/speech-recognize.css +1 -1
  20. package/es2018/plugins/speech-recognize/speech-recognize.js +1 -1
  21. package/es2018/plugins/speech-recognize/speech-recognize.min.js +1 -1
  22. package/es2021/jodit.css +1 -1
  23. package/es2021/jodit.fat.min.js +2 -2
  24. package/es2021/jodit.js +161 -25
  25. package/es2021/jodit.min.js +2 -2
  26. package/es2021/plugins/debug/debug.css +1 -1
  27. package/es2021/plugins/debug/debug.js +1 -1
  28. package/es2021/plugins/debug/debug.min.js +1 -1
  29. package/es2021/plugins/speech-recognize/speech-recognize.css +1 -1
  30. package/es2021/plugins/speech-recognize/speech-recognize.js +1 -1
  31. package/es2021/plugins/speech-recognize/speech-recognize.min.js +1 -1
  32. package/es2021.en/jodit.css +1 -1
  33. package/es2021.en/jodit.fat.min.js +2 -2
  34. package/es2021.en/jodit.js +161 -25
  35. package/es2021.en/jodit.min.js +2 -2
  36. package/es2021.en/plugins/debug/debug.css +1 -1
  37. package/es2021.en/plugins/debug/debug.js +1 -1
  38. package/es2021.en/plugins/debug/debug.min.js +1 -1
  39. package/es2021.en/plugins/speech-recognize/speech-recognize.css +1 -1
  40. package/es2021.en/plugins/speech-recognize/speech-recognize.js +1 -1
  41. package/es2021.en/plugins/speech-recognize/speech-recognize.min.js +1 -1
  42. package/es5/415.fat.min.js +1 -1
  43. package/es5/415.min.js +1 -1
  44. package/es5/5.fat.min.js +1 -1
  45. package/es5/5.min.js +1 -1
  46. package/es5/jodit.css +2 -2
  47. package/es5/jodit.fat.min.js +2 -2
  48. package/es5/jodit.js +161 -25
  49. package/es5/jodit.min.css +2 -2
  50. package/es5/jodit.min.js +2 -2
  51. package/es5/plugins/debug/debug.css +1 -1
  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 +1 -1
  56. package/es5/plugins/speech-recognize/speech-recognize.min.js +1 -1
  57. package/esm/core/constants.js +1 -1
  58. package/esm/core/helpers/array/index.d.ts +1 -0
  59. package/esm/core/helpers/array/index.js +1 -0
  60. package/esm/core/helpers/array/reconcile-arrays.d.ts +54 -0
  61. package/esm/core/helpers/array/reconcile-arrays.js +103 -0
  62. package/esm/core/ui/group/group.d.ts +4 -2
  63. package/esm/core/ui/group/group.js +31 -14
  64. package/esm/types/ui.d.ts +4 -1
  65. package/package.json +1 -1
  66. package/types/core/helpers/array/index.d.ts +1 -0
  67. package/types/core/helpers/array/reconcile-arrays.d.ts +54 -0
  68. package/types/core/ui/group/group.d.ts +4 -2
  69. package/types/types/ui.d.ts +4 -1
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * jodit - Jodit is an awesome and useful wysiwyg editor with filebrowser
3
3
  * Author: Chupurnov <chupurnov@gmail.com> (https://xdsoft.net/jodit/)
4
- * Version: v4.6.6
4
+ * Version: v4.6.10
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * jodit - Jodit is an awesome and useful wysiwyg editor with filebrowser
3
3
  * Author: Chupurnov <chupurnov@gmail.com> (https://xdsoft.net/jodit/)
4
- * Version: v4.6.6
4
+ * Version: v4.6.10
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * jodit - Jodit is an awesome and useful wysiwyg editor with filebrowser
3
3
  * Author: Chupurnov <chupurnov@gmail.com> (https://xdsoft.net/jodit/)
4
- * Version: v4.6.6
4
+ * Version: v4.6.10
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * jodit - Jodit is an awesome and useful wysiwyg editor with filebrowser
3
3
  * Author: Chupurnov <chupurnov@gmail.com> (https://xdsoft.net/jodit/)
4
- * Version: v4.6.6
4
+ * Version: v4.6.10
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * jodit - Jodit is an awesome and useful wysiwyg editor with filebrowser
3
3
  * Author: Chupurnov <chupurnov@gmail.com> (https://xdsoft.net/jodit/)
4
- * Version: v4.6.6
4
+ * Version: v4.6.10
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * jodit - Jodit is an awesome and useful wysiwyg editor with filebrowser
3
3
  * Author: Chupurnov <chupurnov@gmail.com> (https://xdsoft.net/jodit/)
4
- * Version: v4.6.6
4
+ * Version: v4.6.10
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -3,7 +3,7 @@
3
3
  * Released under MIT see LICENSE.txt in the project root for license information.
4
4
  * Copyright (c) 2013-2025 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
5
5
  */
6
- export const APP_VERSION = "4.6.6";
6
+ export const APP_VERSION = "4.6.10";
7
7
  // prettier-ignore
8
8
  export const ES = "es2020";
9
9
  export const IS_ES_MODERN = true;
@@ -7,5 +7,6 @@
7
7
  * @module helpers/array
8
8
  */
9
9
  export { asArray } from "./as-array";
10
+ export { applyArrayReconciliation, reconcileArrays, type ReconcileResult } from "./reconcile-arrays";
10
11
  export { splitArray } from "./split-array";
11
12
  export { toArray } from "./to-array";
@@ -7,5 +7,6 @@
7
7
  * @module helpers/array
8
8
  */
9
9
  export { asArray } from "./as-array.js";
10
+ export { applyArrayReconciliation, reconcileArrays } from "./reconcile-arrays.js";
10
11
  export { splitArray } from "./split-array.js";
11
12
  export { toArray } from "./to-array.js";
@@ -0,0 +1,54 @@
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-2025 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
5
+ */
6
+ /**
7
+ * @module helpers/array
8
+ */
9
+ export interface ReconcileResult<T> {
10
+ added: T[];
11
+ removed: T[];
12
+ kept: T[];
13
+ moved: Array<{
14
+ item: T;
15
+ from: number;
16
+ to: number;
17
+ }>;
18
+ }
19
+ /**
20
+ * Reconciles two arrays and returns the differences
21
+ * @param oldArray - The original array
22
+ * @param newArray - The new array to compare against
23
+ * @param keyFn - Optional function to generate unique keys for items (for object comparison)
24
+ * @returns Object containing added, removed, kept and moved items
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const old = [1, 2, 3, 4];
29
+ * const new = [2, 4, 5, 1];
30
+ * const result = reconcileArrays(old, new);
31
+ * // result.added = [5]
32
+ * // result.removed = [3]
33
+ * // result.kept = [2, 4, 1]
34
+ * // result.moved = [{item: 1, from: 0, to: 3}]
35
+ * ```
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * const old = [{id: 1, name: 'a'}, {id: 2, name: 'b'}];
40
+ * const new = [{id: 2, name: 'b'}, {id: 3, name: 'c'}];
41
+ * const result = reconcileArrays(old, new, item => item.id);
42
+ * // result.added = [{id: 3, name: 'c'}]
43
+ * // result.removed = [{id: 1, name: 'a'}]
44
+ * ```
45
+ */
46
+ export declare function reconcileArrays<T>(oldArray: T[], newArray: T[], keyFn?: (item: T) => string | number): ReconcileResult<T>;
47
+ /**
48
+ * Applies reconciliation patches to transform one array into another
49
+ * @param oldArray - The original array to transform
50
+ * @param newArray - The target array structure
51
+ * @param keyFn - Optional function to generate unique keys for items
52
+ * @returns New array matching the structure of newArray
53
+ */
54
+ export declare function applyArrayReconciliation<T>(oldArray: T[], newArray: T[], keyFn?: (item: T) => string | number): T[];
@@ -0,0 +1,103 @@
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-2025 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
5
+ */
6
+ /**
7
+ * Reconciles two arrays and returns the differences
8
+ * @param oldArray - The original array
9
+ * @param newArray - The new array to compare against
10
+ * @param keyFn - Optional function to generate unique keys for items (for object comparison)
11
+ * @returns Object containing added, removed, kept and moved items
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const old = [1, 2, 3, 4];
16
+ * const new = [2, 4, 5, 1];
17
+ * const result = reconcileArrays(old, new);
18
+ * // result.added = [5]
19
+ * // result.removed = [3]
20
+ * // result.kept = [2, 4, 1]
21
+ * // result.moved = [{item: 1, from: 0, to: 3}]
22
+ * ```
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * const old = [{id: 1, name: 'a'}, {id: 2, name: 'b'}];
27
+ * const new = [{id: 2, name: 'b'}, {id: 3, name: 'c'}];
28
+ * const result = reconcileArrays(old, new, item => item.id);
29
+ * // result.added = [{id: 3, name: 'c'}]
30
+ * // result.removed = [{id: 1, name: 'a'}]
31
+ * ```
32
+ */
33
+ export function reconcileArrays(oldArray, newArray, keyFn) {
34
+ const getKey = keyFn || ((item) => item);
35
+ const oldMap = new Map();
36
+ const newMap = new Map();
37
+ oldArray.forEach((item, index) => {
38
+ oldMap.set(getKey(item), { item, index });
39
+ });
40
+ newArray.forEach((item, index) => {
41
+ newMap.set(getKey(item), { item, index });
42
+ });
43
+ const added = [];
44
+ const removed = [];
45
+ const kept = [];
46
+ const moved = [];
47
+ // Find removed items
48
+ oldMap.forEach((value, key) => {
49
+ if (!newMap.has(key)) {
50
+ removed.push(value.item);
51
+ }
52
+ });
53
+ // Find added items and track kept/moved items
54
+ newMap.forEach((value, key) => {
55
+ const oldItem = oldMap.get(key);
56
+ if (!oldItem) {
57
+ added.push(value.item);
58
+ }
59
+ else {
60
+ kept.push(value.item);
61
+ if (oldItem.index !== value.index) {
62
+ moved.push({
63
+ item: value.item,
64
+ from: oldItem.index,
65
+ to: value.index
66
+ });
67
+ }
68
+ }
69
+ });
70
+ return {
71
+ added,
72
+ removed,
73
+ kept,
74
+ moved
75
+ };
76
+ }
77
+ /**
78
+ * Applies reconciliation patches to transform one array into another
79
+ * @param oldArray - The original array to transform
80
+ * @param newArray - The target array structure
81
+ * @param keyFn - Optional function to generate unique keys for items
82
+ * @returns New array matching the structure of newArray
83
+ */
84
+ export function applyArrayReconciliation(oldArray, newArray, keyFn) {
85
+ const result = reconcileArrays(oldArray, newArray, keyFn);
86
+ const output = [];
87
+ // Build the new array based on newArray order
88
+ newArray.forEach(item => {
89
+ const key = keyFn ? keyFn(item) : item;
90
+ const isNew = result.added.some(addedItem => (keyFn ? keyFn(addedItem) : addedItem) === key);
91
+ if (isNew) {
92
+ output.push(item);
93
+ }
94
+ else {
95
+ // Use the old item reference if it exists
96
+ const oldItem = oldArray.find(oldItem => (keyFn ? keyFn(oldItem) : oldItem) === key);
97
+ if (oldItem !== undefined) {
98
+ output.push(oldItem);
99
+ }
100
+ }
101
+ });
102
+ return output;
103
+ }
@@ -30,13 +30,15 @@ export declare class UIGroup<T extends IViewBased = IViewBased> extends UIElemen
30
30
  /**
31
31
  * Append new element into group
32
32
  */
33
- append(elm: IUIElement | IUIElement[], distElement?: string): this;
33
+ append(elm: IUIElement, index?: number): this;
34
+ append(elm: IUIElement, distElement?: string): this;
35
+ append(elm: IUIElement[], distElement?: string): this;
34
36
  /** @override */
35
37
  afterSetMod(name: string, value: ModType): void;
36
38
  /**
37
39
  * Allow set another container for the box of all children
38
40
  */
39
- protected appendChildToContainer(childContainer: HTMLElement): void;
41
+ protected appendChildToContainer(childContainer: HTMLElement, index?: number): void;
40
42
  /**
41
43
  * Remove element from group
42
44
  */
@@ -18,7 +18,6 @@ import { Component } from "../../component/component.js";
18
18
  import { component, watch } from "../../decorators/index.js";
19
19
  import { Dom } from "../../dom/dom.js";
20
20
  import { isArray } from "../../helpers/index.js";
21
- import { assert } from "../../helpers/utils/assert.js";
22
21
  import { UIElement } from "../element.js";
23
22
  let UIGroup = UIGroup_1 = class UIGroup extends UIElement {
24
23
  className() {
@@ -53,25 +52,35 @@ let UIGroup = UIGroup_1 = class UIGroup extends UIElement {
53
52
  this.elements.forEach(elm => elm.update());
54
53
  this.setMod('size', this.buttonSize);
55
54
  }
56
- /**
57
- * Append new element into group
58
- */
59
- append(elm, distElement) {
60
- if (isArray(elm)) {
61
- elm.forEach(item => this.append(item, distElement));
55
+ append(elms, distElementOrIndex) {
56
+ if (isArray(elms)) {
57
+ if (typeof distElementOrIndex === 'number') {
58
+ throw new Error('You can not use index when append array of elements');
59
+ }
60
+ elms.forEach(item => this.append(item, distElementOrIndex));
62
61
  return this;
63
62
  }
64
- this.elements.push(elm);
63
+ const elm = elms;
64
+ let index = undefined;
65
+ if (typeof distElementOrIndex === 'number') {
66
+ index = Math.min(Math.max(0, distElementOrIndex), this.elements.length);
67
+ this.elements.splice(index, 0, elm);
68
+ }
69
+ else {
70
+ this.elements.push(elm);
71
+ }
65
72
  if (elm.name) {
66
73
  elm.container.classList.add(this.getFullElName(elm.name));
67
74
  }
68
- if (distElement) {
69
- const distElm = this.getElm(distElement);
70
- assert(distElm != null, 'Element does not exist');
75
+ if (distElementOrIndex && typeof distElementOrIndex === 'string') {
76
+ const distElm = this.getElm(distElementOrIndex);
77
+ if (distElm == null) {
78
+ throw new Error('Element does not exist');
79
+ }
71
80
  distElm.appendChild(elm.container);
72
81
  }
73
82
  else {
74
- this.appendChildToContainer(elm.container);
83
+ this.appendChildToContainer(elm.container, index);
75
84
  }
76
85
  elm.parentElement = this;
77
86
  return this;
@@ -85,8 +94,16 @@ let UIGroup = UIGroup_1 = class UIGroup extends UIElement {
85
94
  /**
86
95
  * Allow set another container for the box of all children
87
96
  */
88
- appendChildToContainer(childContainer) {
89
- this.container.appendChild(childContainer);
97
+ appendChildToContainer(childContainer, index) {
98
+ if (index === undefined ||
99
+ index < 0 ||
100
+ index > this.elements.length - 1 ||
101
+ this.container.children[index] == null) {
102
+ this.container.appendChild(childContainer);
103
+ }
104
+ else {
105
+ this.container.insertBefore(childContainer, this.container.children[index]);
106
+ }
90
107
  }
91
108
  /**
92
109
  * Remove element from group
package/esm/types/ui.d.ts CHANGED
@@ -59,7 +59,10 @@ export interface IUIButton extends IViewComponent, IUIElement, IFocusable {
59
59
  export interface IUIGroup extends IUIElement {
60
60
  readonly elements: IUIElement[];
61
61
  readonly allChildren: IUIElement[];
62
- append(elm: IUIElement | IUIElement[], distElement?: string): this;
62
+ append(elm: IUIElement, index?: number): this;
63
+ append(elm: IUIElement, distElement?: string): this;
64
+ append(elms: IUIElement[], distElement?: string): this;
65
+ append(elm: IUIElement | IUIElement[], distElementOrIndex?: string | number): this;
63
66
  remove(elm: IUIElement): this;
64
67
  clear(): this;
65
68
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jodit",
3
- "version": "4.6.6",
3
+ "version": "4.6.10",
4
4
  "description": "Jodit is an awesome and useful wysiwyg editor with filebrowser",
5
5
  "main": "esm/index.js",
6
6
  "types": "types/index.d.ts",
@@ -7,5 +7,6 @@
7
7
  * @module helpers/array
8
8
  */
9
9
  export { asArray } from "./as-array";
10
+ export { applyArrayReconciliation, reconcileArrays, type ReconcileResult } from "./reconcile-arrays";
10
11
  export { splitArray } from "./split-array";
11
12
  export { toArray } from "./to-array";
@@ -0,0 +1,54 @@
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-2025 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
5
+ */
6
+ /**
7
+ * @module helpers/array
8
+ */
9
+ export interface ReconcileResult<T> {
10
+ added: T[];
11
+ removed: T[];
12
+ kept: T[];
13
+ moved: Array<{
14
+ item: T;
15
+ from: number;
16
+ to: number;
17
+ }>;
18
+ }
19
+ /**
20
+ * Reconciles two arrays and returns the differences
21
+ * @param oldArray - The original array
22
+ * @param newArray - The new array to compare against
23
+ * @param keyFn - Optional function to generate unique keys for items (for object comparison)
24
+ * @returns Object containing added, removed, kept and moved items
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const old = [1, 2, 3, 4];
29
+ * const new = [2, 4, 5, 1];
30
+ * const result = reconcileArrays(old, new);
31
+ * // result.added = [5]
32
+ * // result.removed = [3]
33
+ * // result.kept = [2, 4, 1]
34
+ * // result.moved = [{item: 1, from: 0, to: 3}]
35
+ * ```
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * const old = [{id: 1, name: 'a'}, {id: 2, name: 'b'}];
40
+ * const new = [{id: 2, name: 'b'}, {id: 3, name: 'c'}];
41
+ * const result = reconcileArrays(old, new, item => item.id);
42
+ * // result.added = [{id: 3, name: 'c'}]
43
+ * // result.removed = [{id: 1, name: 'a'}]
44
+ * ```
45
+ */
46
+ export declare function reconcileArrays<T>(oldArray: T[], newArray: T[], keyFn?: (item: T) => string | number): ReconcileResult<T>;
47
+ /**
48
+ * Applies reconciliation patches to transform one array into another
49
+ * @param oldArray - The original array to transform
50
+ * @param newArray - The target array structure
51
+ * @param keyFn - Optional function to generate unique keys for items
52
+ * @returns New array matching the structure of newArray
53
+ */
54
+ export declare function applyArrayReconciliation<T>(oldArray: T[], newArray: T[], keyFn?: (item: T) => string | number): T[];
@@ -30,13 +30,15 @@ export declare class UIGroup<T extends IViewBased = IViewBased> extends UIElemen
30
30
  /**
31
31
  * Append new element into group
32
32
  */
33
- append(elm: IUIElement | IUIElement[], distElement?: string): this;
33
+ append(elm: IUIElement, index?: number): this;
34
+ append(elm: IUIElement, distElement?: string): this;
35
+ append(elm: IUIElement[], distElement?: string): this;
34
36
  /** @override */
35
37
  afterSetMod(name: string, value: ModType): void;
36
38
  /**
37
39
  * Allow set another container for the box of all children
38
40
  */
39
- protected appendChildToContainer(childContainer: HTMLElement): void;
41
+ protected appendChildToContainer(childContainer: HTMLElement, index?: number): void;
40
42
  /**
41
43
  * Remove element from group
42
44
  */
@@ -59,7 +59,10 @@ export interface IUIButton extends IViewComponent, IUIElement, IFocusable {
59
59
  export interface IUIGroup extends IUIElement {
60
60
  readonly elements: IUIElement[];
61
61
  readonly allChildren: IUIElement[];
62
- append(elm: IUIElement | IUIElement[], distElement?: string): this;
62
+ append(elm: IUIElement, index?: number): this;
63
+ append(elm: IUIElement, distElement?: string): this;
64
+ append(elms: IUIElement[], distElement?: string): this;
65
+ append(elm: IUIElement | IUIElement[], distElementOrIndex?: string | number): this;
63
66
  remove(elm: IUIElement): this;
64
67
  clear(): this;
65
68
  }