jodit 4.18.10 → 4.18.11

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 +15 -0
  2. package/es2015/jodit.css +1 -1
  3. package/es2015/jodit.fat.min.js +5 -5
  4. package/es2015/jodit.js +256 -71
  5. package/es2015/jodit.min.js +5 -5
  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.fat.min.js +5 -5
  13. package/es2018/jodit.min.js +5 -5
  14. package/es2018/plugins/debug/debug.min.js +1 -1
  15. package/es2018/plugins/speech-recognize/speech-recognize.min.js +1 -1
  16. package/es2021/jodit.css +1 -1
  17. package/es2021/jodit.fat.min.js +6 -6
  18. package/es2021/jodit.js +253 -71
  19. package/es2021/jodit.min.js +6 -6
  20. package/es2021/plugins/debug/debug.css +1 -1
  21. package/es2021/plugins/debug/debug.js +1 -1
  22. package/es2021/plugins/debug/debug.min.js +1 -1
  23. package/es2021/plugins/speech-recognize/speech-recognize.css +1 -1
  24. package/es2021/plugins/speech-recognize/speech-recognize.js +1 -1
  25. package/es2021/plugins/speech-recognize/speech-recognize.min.js +1 -1
  26. package/es2021.en/jodit.css +1 -1
  27. package/es2021.en/jodit.fat.min.js +6 -6
  28. package/es2021.en/jodit.js +253 -71
  29. package/es2021.en/jodit.min.js +6 -6
  30. package/es2021.en/plugins/debug/debug.css +1 -1
  31. package/es2021.en/plugins/debug/debug.js +1 -1
  32. package/es2021.en/plugins/debug/debug.min.js +1 -1
  33. package/es2021.en/plugins/speech-recognize/speech-recognize.css +1 -1
  34. package/es2021.en/plugins/speech-recognize/speech-recognize.js +1 -1
  35. package/es2021.en/plugins/speech-recognize/speech-recognize.min.js +1 -1
  36. package/es5/jodit.css +2 -2
  37. package/es5/jodit.fat.min.js +2 -2
  38. package/es5/jodit.js +303 -72
  39. package/es5/jodit.min.css +2 -2
  40. package/es5/jodit.min.js +2 -2
  41. package/es5/plugins/debug/debug.css +1 -1
  42. package/es5/plugins/debug/debug.js +1 -1
  43. package/es5/plugins/debug/debug.min.js +1 -1
  44. package/es5/plugins/speech-recognize/speech-recognize.css +1 -1
  45. package/es5/plugins/speech-recognize/speech-recognize.js +1 -1
  46. package/es5/plugins/speech-recognize/speech-recognize.min.js +1 -1
  47. package/es5/polyfills.fat.min.js +2 -2
  48. package/es5/polyfills.js +3 -3
  49. package/es5/polyfills.min.js +2 -2
  50. package/esm/core/async/async.js +2 -1
  51. package/esm/core/constants.js +1 -1
  52. package/esm/core/helpers/size/get-fixed-position-offset.d.ts +4 -2
  53. package/esm/core/helpers/size/get-fixed-position-offset.js +14 -2
  54. package/esm/plugins/add-new-line/add-new-line.d.ts +7 -0
  55. package/esm/plugins/add-new-line/add-new-line.js +45 -0
  56. package/esm/plugins/backspace/backspace.d.ts +7 -0
  57. package/esm/plugins/backspace/backspace.js +45 -2
  58. package/esm/plugins/backspace/cases/check-join-neighbors.js +69 -1
  59. package/esm/plugins/backspace/cases/check-remove-char.js +3 -1
  60. package/esm/plugins/backspace/cases/check-remove-content-not-editable.d.ts +4 -1
  61. package/esm/plugins/backspace/cases/check-remove-content-not-editable.js +39 -11
  62. package/esm/plugins/wrap-nodes/wrap-nodes.js +19 -2
  63. package/esm/types/async.d.ts +7 -0
  64. package/package.json +1 -1
  65. package/types/core/helpers/size/get-fixed-position-offset.d.ts +4 -2
  66. package/types/plugins/add-new-line/add-new-line.d.ts +7 -0
  67. package/types/plugins/backspace/backspace.d.ts +7 -0
  68. package/types/plugins/backspace/cases/check-remove-content-not-editable.d.ts +4 -1
  69. package/types/types/async.d.ts +7 -0
@@ -6,24 +6,52 @@
6
6
  import { Dom } from "../../../core/dom/index.js";
7
7
  import { call } from "../../../core/helpers/index.js";
8
8
  import { moveNodeInsideStart } from "../../../core/selection/helpers/index.js";
9
+ import { checkJoinNeighbors } from "./check-join-neighbors.js";
9
10
  /**
10
- * Checks if a non-editable element can be deleted
11
+ * Checks if a non-editable element can be deleted. A non-editable block goes
12
+ * whole, and the lines either side of it then join, as the spec's tests do:
13
+ * `<ul><li>one|</li></ul><div contenteditable="false">x</div><p>two</p>`
14
+ * gives `<ul><li>one|two</li></ul>`
11
15
  * @private
12
16
  */
13
17
  export function checkRemoveContentNotEditable(jodit, fakeNode, backspace) {
14
- let neighbor = Dom.findSibling(fakeNode, backspace);
15
- if (!neighbor &&
16
- fakeNode.parentElement &&
17
- fakeNode.parentElement !== jodit.editor) {
18
- neighbor = Dom.findSibling(fakeNode.parentElement, backspace);
18
+ let node = fakeNode;
19
+ let neighbor = Dom.findSibling(node, backspace);
20
+ // Past the edges of the blocks the caret is at, but not into a table cell
21
+ while (!neighbor &&
22
+ node.parentElement &&
23
+ node.parentElement !== jodit.editor &&
24
+ !Dom.isCell(node.parentElement)) {
25
+ node = node.parentElement;
26
+ neighbor = Dom.findSibling(node, backspace);
27
+ // At the start of a list item, Backspace takes the bullet off first,
28
+ // unless the item before it is a non-editable one to remove
29
+ if (backspace &&
30
+ Dom.isLeaf(node) &&
31
+ !(Dom.isLeaf(neighbor) && isNotEditable(jodit, neighbor))) {
32
+ return false;
33
+ }
19
34
  }
20
- if (Dom.isElement(neighbor) &&
21
- !Dom.isContentEditable(neighbor, jodit.editor)) {
22
- call(backspace ? Dom.before : Dom.after, neighbor, fakeNode);
23
- Dom.safeRemove(neighbor);
24
- moveNodeInsideStart(jodit, fakeNode, backspace);
35
+ if (isNotEditable(jodit, neighbor)) {
36
+ if (Dom.isBlock(neighbor)) {
37
+ // Backspace after a removed list item leaves the items apart: the
38
+ // next press takes the bullet off, as for any later item
39
+ const joinLines = !(backspace && Dom.isLeaf(neighbor));
40
+ Dom.safeRemove(neighbor);
41
+ if (joinLines) {
42
+ checkJoinNeighbors(jodit, fakeNode, backspace);
43
+ }
44
+ }
45
+ else {
46
+ call(backspace ? Dom.before : Dom.after, neighbor, fakeNode);
47
+ Dom.safeRemove(neighbor);
48
+ moveNodeInsideStart(jodit, fakeNode, backspace);
49
+ }
25
50
  call(backspace ? jodit.s.setCursorBefore : jodit.s.setCursorAfter, fakeNode);
26
51
  return true;
27
52
  }
28
53
  return false;
29
54
  }
55
+ function isNotEditable(jodit, node) {
56
+ return Dom.isElement(node) && !Dom.isContentEditable(node, jodit.editor);
57
+ }
@@ -13,6 +13,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
13
13
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
14
14
  return c > 3 && r && Object.defineProperty(target, key, r), r;
15
15
  };
16
+ import { NO_EMPTY_TAGS } from "../../core/constants.js";
16
17
  import { autobind } from "../../core/decorators/index.js";
17
18
  import { Dom } from "../../core/dom/index.js";
18
19
  import { pluginSystem } from "../../core/global.js";
@@ -45,7 +46,9 @@ class wrapNodes extends Plugin {
45
46
  * Some element which needs to append in block
46
47
  */
47
48
  this.isNotWrapped = (n) => Dom.isElement(n) &&
48
- !(Dom.isBlock(n) || Dom.isTag(n, this.j.o.wrapNodes.exclude));
49
+ !(Dom.isBlock(n) ||
50
+ Dom.isTag(n, this.j.o.wrapNodes.exclude) ||
51
+ holdsBlock(n));
49
52
  }
50
53
  /** @override **/
51
54
  afterInit(jodit) {
@@ -81,7 +84,9 @@ class wrapNodes extends Plugin {
81
84
  isChanged = true;
82
85
  const box = jodit.createInside.element(jodit.o.enter);
83
86
  Dom.before(child, box);
84
- while (child && this.isSuitable(child)) {
87
+ // `exclude` keeps a <br> from starting a box, but one between loose lines stays with them
88
+ while (child &&
89
+ (this.isSuitable(child) || Dom.isTag(child, 'br'))) {
85
90
  const next = child.nextSibling;
86
91
  Dom.append(box, child);
87
92
  child = next;
@@ -124,6 +129,18 @@ __decorate([
124
129
  __decorate([
125
130
  autobind
126
131
  ], wrapNodes.prototype, "preprocessInput", null);
132
+ /**
133
+ * A block can't go in a paragraph, so neither can an element that holds one,
134
+ * such as a `<span>` round a `<p>`. Embedded content such as an `<iframe>` can.
135
+ */
136
+ function holdsBlock(elm) {
137
+ for (const node of Dom.eachGen(elm)) {
138
+ if (Dom.isBlock(node) && !Dom.isTag(node, NO_EMPTY_TAGS)) {
139
+ return true;
140
+ }
141
+ }
142
+ return false;
143
+ }
127
144
  function checkAloneListLeaf(child, jodit) {
128
145
  let result = child;
129
146
  let next = child;
@@ -20,6 +20,13 @@ interface RejectablePromise<T> extends Promise<T> {
20
20
  }
21
21
  export interface IAsync extends IDestructible {
22
22
  delay(timeout: number | IAsyncParams): Promise<void>;
23
+ /**
24
+ * Calls `callback` after `timeout` milliseconds, unless the view is
25
+ * destroyed first. A timeout of 0, or none, calls it at once, before
26
+ * returning, where `window.setTimeout(callback, 0)` would wait for the
27
+ * current event to finish. To run after the browser has handled an event,
28
+ * such as moving the caret on a keydown, use a timeout of at least 1.
29
+ */
23
30
  setTimeout<T = any>(callback: (...args: T[]) => void, timeout: number | IAsyncParams, ...args: T[]): number;
24
31
  updateTimeout(label: string, timeout: number): Nullable<number>;
25
32
  clearTimeout(timer: number): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jodit",
3
- "version": "4.18.10",
3
+ "version": "4.18.11",
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",
@@ -15,7 +15,9 @@ import type { IPoint } from "../../../types/index";
15
15
  * ancestor's top-left corner. The returned offset should be subtracted from
16
16
  * the desired viewport coordinates before applying them.
17
17
  *
18
- * Returns `{ x: 0, y: 0 }` when no such ancestor exists (the common case), so
19
- * call sites keep their previous behaviour unchanged.
18
+ * Without such an ancestor the containing block is the layout viewport. Its
19
+ * offset is `{ x: 0, y: 0 }` in most browsers, but WebKit measures client
20
+ * rects from the visual viewport, so once the page is pinch-zoomed and panned
21
+ * the layout viewport starts above and to the left of the client origin.
20
22
  */
21
23
  export declare function getFixedPositionOffset(elm: HTMLElement): IPoint;
@@ -30,6 +30,13 @@ export declare class addNewLine extends Plugin {
30
30
  protected afterInit(editor: IJodit): void;
31
31
  private __addEventListeners;
32
32
  private __onClickLine;
33
+ /**
34
+ * A paragraph holding only an embed has no place for the caret, so the
35
+ * arrow keys can't get past one that ends the content, or before one that
36
+ * starts it. When an arrow key leaves the caret where it was and there is
37
+ * content beyond it, a new line goes there, as when the line is clicked.
38
+ */
39
+ protected onArrowKey(e: KeyboardEvent): void;
33
40
  protected onDblClickEditor(e: MouseEvent): void;
34
41
  private __onMouseMove;
35
42
  /** @override */
@@ -19,6 +19,13 @@ export declare class backspace extends Plugin {
19
19
  * Listener BackSpace or Delete button
20
20
  */
21
21
  private onDelete;
22
+ /**
23
+ * The browser types at the end of the text before the caret on its line,
24
+ * in that text's formatting, but not inside a link. Moving the caret there
25
+ * too makes a paste and the toolbar agree with what's typed:
26
+ * `<p>one</p><p><b>|two</b></p>` joins to `<p>one|<b>two</b></p>`
27
+ */
28
+ private moveCaretToTextBefore;
22
29
  /**
23
30
  * Remove node and replace cursor position out of it
24
31
  */
@@ -8,7 +8,10 @@
8
8
  */
9
9
  import type { IJodit } from "../../../types/index";
10
10
  /**
11
- * Checks if a non-editable element can be deleted
11
+ * Checks if a non-editable element can be deleted. A non-editable block goes
12
+ * whole, and the lines either side of it then join, as the spec's tests do:
13
+ * `<ul><li>one|</li></ul><div contenteditable="false">x</div><p>two</p>`
14
+ * gives `<ul><li>one|two</li></ul>`
12
15
  * @private
13
16
  */
14
17
  export declare function checkRemoveContentNotEditable(jodit: IJodit, fakeNode: Text, backspace: boolean): boolean;
@@ -20,6 +20,13 @@ interface RejectablePromise<T> extends Promise<T> {
20
20
  }
21
21
  export interface IAsync extends IDestructible {
22
22
  delay(timeout: number | IAsyncParams): Promise<void>;
23
+ /**
24
+ * Calls `callback` after `timeout` milliseconds, unless the view is
25
+ * destroyed first. A timeout of 0, or none, calls it at once, before
26
+ * returning, where `window.setTimeout(callback, 0)` would wait for the
27
+ * current event to finish. To run after the browser has handled an event,
28
+ * such as moving the caret on a keydown, use a timeout of at least 1.
29
+ */
23
30
  setTimeout<T = any>(callback: (...args: T[]) => void, timeout: number | IAsyncParams, ...args: T[]): number;
24
31
  updateTimeout(label: string, timeout: number): Nullable<number>;
25
32
  clearTimeout(timer: number): void;