jodit 4.15.6 → 4.15.8

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 (64) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/es2015/jodit.css +1 -1
  3. package/es2015/jodit.fat.min.js +4 -4
  4. package/es2015/jodit.js +112 -28
  5. package/es2015/jodit.min.js +4 -4
  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 +4 -4
  13. package/es2018/jodit.min.js +4 -4
  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 +5 -5
  18. package/es2021/jodit.js +110 -27
  19. package/es2021/jodit.min.js +5 -5
  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 +5 -5
  28. package/es2021.en/jodit.js +110 -27
  29. package/es2021.en/jodit.min.js +5 -5
  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 +153 -62
  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 +1 -1
  48. package/es5/polyfills.js +1 -1
  49. package/es5/polyfills.min.js +1 -1
  50. package/esm/config.d.ts +12 -1
  51. package/esm/core/constants.js +1 -1
  52. package/esm/plugins/clean-html/clean-html.d.ts +7 -3
  53. package/esm/plugins/clean-html/clean-html.js +37 -0
  54. package/esm/plugins/clean-html/config.d.ts +12 -1
  55. package/esm/plugins/clean-html/config.js +1 -0
  56. package/esm/plugins/clean-html/helpers/visitor/filters/try-remove-node.js +10 -0
  57. package/esm/plugins/drag-and-drop-element/drag-and-drop-element.d.ts +1 -0
  58. package/esm/plugins/drag-and-drop-element/drag-and-drop-element.js +19 -4
  59. package/esm/plugins/mobile/mobile.js +25 -4
  60. package/package.json +1 -1
  61. package/types/config.d.ts +12 -1
  62. package/types/plugins/clean-html/clean-html.d.ts +7 -3
  63. package/types/plugins/clean-html/config.d.ts +12 -1
  64. package/types/plugins/drag-and-drop-element/drag-and-drop-element.d.ts +1 -0
@@ -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.15.6
4
+ * Version: v4.15.8
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.15.6
4
+ * Version: v4.15.8
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.15.6
4
+ * Version: v4.15.8
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.15.6
4
+ * Version: v4.15.8
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.15.6
4
+ * Version: v4.15.8
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.15.6
4
+ * Version: v4.15.8
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.15.6
4
+ * Version: v4.15.8
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
package/es5/polyfills.js CHANGED
@@ -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.15.6
4
+ * Version: v4.15.8
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.15.6
4
+ * Version: v4.15.8
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
package/esm/config.d.ts CHANGED
@@ -1021,7 +1021,8 @@ interface Config {
1021
1021
  */
1022
1022
  fillEmptyParagraph: boolean;
1023
1023
  /**
1024
- * Remove empty elements
1024
+ * Remove empty inline elements. Elements that in-page links can point
1025
+ * at (anything with an `id`, and `<a>` with a `name`) are kept.
1025
1026
  */
1026
1027
  removeEmptyElements: boolean;
1027
1028
  /**
@@ -1042,6 +1043,16 @@ interface Config {
1042
1043
  * names with single quotes: `font-family: 'Open Sans', sans-serif`.
1043
1044
  */
1044
1045
  singleQuotesInFontFamily: boolean;
1046
+ /**
1047
+ * Browsers keep a trailing `<br>` inside a block after you type into an
1048
+ * empty one (`<p>test<br></p>`), and the same `<br>` ends up in the
1049
+ * editor value. It renders nothing, but confuses consumers that compare
1050
+ * or post-process the HTML. With this option the value getter drops a
1051
+ * `<br>` that is the last node of a block (or of the whole value)
1052
+ * and follows other content. `<p><br></p>` and `text<br><br>` — an empty
1053
+ * line — are kept.
1054
+ */
1055
+ removeTrailingBr: boolean;
1045
1056
  /**
1046
1057
  * Replace old tags to new eg. <i> to <em>, <b> to <strong>
1047
1058
  */
@@ -3,7 +3,7 @@
3
3
  * Released under MIT see LICENSE.txt in the project root for license information.
4
4
  * Copyright (c) 2013-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net
5
5
  */
6
- export const APP_VERSION = "4.15.6";
6
+ export const APP_VERSION = "4.15.8";
7
7
  // prettier-ignore
8
8
  export const ES = "es2020";
9
9
  export const IS_ES_MODERN = true;
@@ -11,9 +11,6 @@
11
11
  import type { IJodit } from "../../types/index";
12
12
  import { Plugin } from "../../core/plugin/plugin";
13
13
  import "./config";
14
- /**
15
- * Clean HTML after removeFormat and insertHorizontalRule command
16
- */
17
14
  export declare class cleanHtml extends Plugin {
18
15
  /** @override */
19
16
  buttons: Plugin['buttons'];
@@ -50,6 +47,13 @@ export declare class cleanHtml extends Plugin {
50
47
  * survive that round trip. Names that already contain an apostrophe are
51
48
  * left alone.
52
49
  */
50
+ /**
51
+ * Drop a `<br>` that is the last node of a block (or of the value) and
52
+ * follows other content — the caret placeholder browsers leave behind
53
+ * after typing into an empty block. An empty block (`<p><br></p>`) and a
54
+ * deliberate empty line (`text<br><br>`) are kept.
55
+ */
56
+ private __removeTrailingBr;
53
57
  private __singleQuotesInFontFamily;
54
58
  protected onSafeHTML(sandBox: HTMLElement): void;
55
59
  /** @override */
@@ -24,6 +24,7 @@ import { getHash, removeFormatForCollapsedSelection, removeFormatForSelection, v
24
24
  /**
25
25
  * Clean HTML after removeFormat and insertHorizontalRule command
26
26
  */
27
+ const TRAILING_BR_BLOCKS = 'p, div, li, td, th, h1, h2, h3, h4, h5, h6, blockquote';
27
28
  export class cleanHtml extends Plugin {
28
29
  constructor() {
29
30
  super(...arguments);
@@ -107,6 +108,7 @@ export class cleanHtml extends Plugin {
107
108
  */
108
109
  onAfterGetValueFromEditor(data) {
109
110
  this.__singleQuotesInFontFamily(data);
111
+ this.__removeTrailingBr(data);
110
112
  if (!this.j.o.cleanHTML.collapseEmptyValueToEmptyString) {
111
113
  return;
112
114
  }
@@ -122,6 +124,41 @@ export class cleanHtml extends Plugin {
122
124
  * survive that round trip. Names that already contain an apostrophe are
123
125
  * left alone.
124
126
  */
127
+ /**
128
+ * Drop a `<br>` that is the last node of a block (or of the value) and
129
+ * follows other content — the caret placeholder browsers leave behind
130
+ * after typing into an empty block. An empty block (`<p><br></p>`) and a
131
+ * deliberate empty line (`text<br><br>`) are kept.
132
+ */
133
+ __removeTrailingBr(data) {
134
+ if (!this.j.o.cleanHTML.removeTrailingBr || !/<br/i.test(data.value)) {
135
+ return;
136
+ }
137
+ const box = this.j.c.div();
138
+ box.innerHTML = data.value;
139
+ const blocks = [
140
+ box,
141
+ ...box.querySelectorAll(TRAILING_BR_BLOCKS)
142
+ ];
143
+ blocks.forEach(block => {
144
+ var _a;
145
+ const last = block.lastChild;
146
+ if (!Dom.isTag(last, 'br')) {
147
+ return;
148
+ }
149
+ const prev = last.previousSibling;
150
+ if (!prev || Dom.isTag(prev, 'br')) {
151
+ return;
152
+ }
153
+ if (Dom.isText(prev) &&
154
+ !((_a = prev.nodeValue) === null || _a === void 0 ? void 0 : _a.trim()) &&
155
+ !prev.previousSibling) {
156
+ return;
157
+ }
158
+ Dom.safeRemove(last);
159
+ });
160
+ data.value = box.innerHTML;
161
+ }
125
162
  __singleQuotesInFontFamily(data) {
126
163
  if (!this.j.o.cleanHTML.singleQuotesInFontFamily ||
127
164
  !data.value.includes('&quot;')) {
@@ -20,7 +20,8 @@ declare module 'jodit/config' {
20
20
  */
21
21
  fillEmptyParagraph: boolean;
22
22
  /**
23
- * Remove empty elements
23
+ * Remove empty inline elements. Elements that in-page links can point
24
+ * at (anything with an `id`, and `<a>` with a `name`) are kept.
24
25
  */
25
26
  removeEmptyElements: boolean;
26
27
  /**
@@ -41,6 +42,16 @@ declare module 'jodit/config' {
41
42
  * names with single quotes: `font-family: 'Open Sans', sans-serif`.
42
43
  */
43
44
  singleQuotesInFontFamily: boolean;
45
+ /**
46
+ * Browsers keep a trailing `<br>` inside a block after you type into an
47
+ * empty one (`<p>test<br></p>`), and the same `<br>` ends up in the
48
+ * editor value. It renders nothing, but confuses consumers that compare
49
+ * or post-process the HTML. With this option the value getter drops a
50
+ * `<br>` that is the last node of a block (or of the whole value)
51
+ * and follows other content. `<p><br></p>` and `text<br><br>` — an empty
52
+ * line — are kept.
53
+ */
54
+ removeTrailingBr: boolean;
44
55
  /**
45
56
  * Replace old tags to new eg. <i> to <em>, <b> to <strong>
46
57
  */
@@ -12,6 +12,7 @@ Config.prototype.cleanHTML = {
12
12
  fillEmptyParagraph: true,
13
13
  collapseEmptyValueToEmptyString: false,
14
14
  singleQuotesInFontFamily: true,
15
+ removeTrailingBr: false,
15
16
  replaceNBSP: true,
16
17
  replaceOldTags: {
17
18
  i: 'em',
@@ -55,7 +55,17 @@ function isRemovableNode(jodit, node, current, allow, deny) {
55
55
  return (Dom.isElement(node) &&
56
56
  node.nodeName.match(IS_INLINE) != null &&
57
57
  !Dom.isTemporary(node) &&
58
+ !isFragmentTarget(node) &&
58
59
  trimInv(node.innerHTML).length === 0 &&
59
60
  (current == null || !Dom.isOrContains(node, current)) &&
60
61
  (liveCaret == null || !Dom.isOrContains(node, liveCaret)));
61
62
  }
63
+ /**
64
+ * An element with an `id`, or an `<a>` with a `name`, is where an in-page link
65
+ * (`#fragment`) lands. It is usually empty (`<a name="top"></a>`), and removing
66
+ * it silently breaks every link that points at it.
67
+ */
68
+ function isFragmentTarget(element) {
69
+ return (element.hasAttribute('id') ||
70
+ (element.nodeName === 'A' && element.hasAttribute('name')));
71
+ }
@@ -50,6 +50,7 @@ export declare class dragAndDropElement extends Plugin {
50
50
  * Mouse move handler handler
51
51
  */
52
52
  private onDrag;
53
+ private __ghostOffset;
53
54
  /**
54
55
  * Mouseup handler in any place
55
56
  */
@@ -136,6 +136,11 @@ export class dragAndDropElement extends Plugin {
136
136
  this.state = DragState.DRAGGING;
137
137
  }
138
138
  this.j.e.fire('hidePopup hideResizer');
139
+ // The ghost lives in the top document (position: fixed), but the
140
+ // mousemove comes from the editor document. In iframe mode those are
141
+ // different viewports, so the iframe's own offset has to be added or
142
+ // the ghost trails the pointer by exactly that distance (#1455).
143
+ const offset = this.__ghostOffset();
139
144
  if (!this.draggable.parentNode) {
140
145
  const target = dataBind(this.draggable, 'target');
141
146
  css(this.draggable, {
@@ -145,19 +150,29 @@ export class dragAndDropElement extends Plugin {
145
150
  position: 'fixed',
146
151
  opacity: 0.7,
147
152
  display: 'inline-block',
148
- left: event.clientX,
149
- top: event.clientY,
153
+ left: event.clientX + offset.left,
154
+ top: event.clientY + offset.top,
150
155
  width: (_a = target === null || target === void 0 ? void 0 : target.offsetWidth) !== null && _a !== void 0 ? _a : 100,
151
156
  height: (_b = target === null || target === void 0 ? void 0 : target.offsetHeight) !== null && _b !== void 0 ? _b : 100
152
157
  });
153
158
  Dom.append(getContainer(this.j, dragAndDropElement), this.draggable);
154
159
  }
155
160
  css(this.draggable, {
156
- left: event.clientX,
157
- top: event.clientY
161
+ left: event.clientX + offset.left,
162
+ top: event.clientY + offset.top
158
163
  });
164
+ // The caret goes into the editor document, so it keeps the raw
165
+ // (iframe-relative) coordinates.
159
166
  this.j.s.insertCursorAtPoint(event.clientX, event.clientY);
160
167
  }
168
+ __ghostOffset() {
169
+ const iframe = this.j.iframe;
170
+ if (!iframe) {
171
+ return { left: 0, top: 0 };
172
+ }
173
+ const rect = iframe.getBoundingClientRect();
174
+ return { left: rect.left, top: rect.top };
175
+ }
161
176
  /**
162
177
  * Mouseup handler in any place
163
178
  */
@@ -3,8 +3,10 @@
3
3
  * Released under MIT see LICENSE.txt in the project root for license information.
4
4
  * Copyright (c) 2013-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net
5
5
  */
6
+ import { Dom } from "../../core/dom/dom.js";
6
7
  import { pluginSystem } from "../../core/global.js";
7
8
  import { splitArray, toArray } from "../../core/helpers/index.js";
9
+ import { isString } from "../../core/helpers/checker/is-string.js";
8
10
  import { flatButtonsSet, isButtonGroup } from "../../core/ui/helpers/buttons.js";
9
11
  import "./config.js";
10
12
  const isButtonSeparator = (item) => item === '|' || item === '---' || item === '\n';
@@ -75,6 +77,22 @@ function fitToButtons(list, editor) {
75
77
  }
76
78
  return cleaned;
77
79
  }
80
+ /**
81
+ * The width that decides which breakpoint set the toolbar uses. A toolbar
82
+ * rendered into an external container (`toolbar` set to an element or a
83
+ * selector) lays out in that container, so its width is what matters there.
84
+ */
85
+ function adaptiveWidth(editor) {
86
+ var _a;
87
+ const { toolbar } = editor.o;
88
+ if (isString(toolbar) || Dom.isHTMLElement(toolbar)) {
89
+ const width = editor.toolbarContainer.offsetWidth;
90
+ if (width) {
91
+ return width;
92
+ }
93
+ }
94
+ return ((_a = editor.container.parentElement) !== null && _a !== void 0 ? _a : editor.container).offsetWidth;
95
+ }
78
96
  /**
79
97
  * Rebuild toolbar in depends on editor's width
80
98
  */
@@ -108,13 +126,16 @@ export function mobile(editor) {
108
126
  if (editor.o.toolbarAdaptive) {
109
127
  editor.e
110
128
  .on('resize afterInit recalcAdaptive changePlace afterAddPlace', () => {
111
- var _a, _b;
129
+ var _a;
112
130
  if (!editor.o.toolbar) {
113
131
  return;
114
132
  }
115
- const width = ((_a = editor.container.parentElement) !== null && _a !== void 0 ? _a : editor.container).offsetWidth;
116
133
  const newStore = (() => {
117
- if (editor.isFullSize || width >= editor.o.sizeLG) {
134
+ if (editor.isFullSize) {
135
+ return splitArray(editor.o.buttons);
136
+ }
137
+ const width = adaptiveWidth(editor);
138
+ if (width >= editor.o.sizeLG) {
118
139
  return splitArray(editor.o.buttons);
119
140
  }
120
141
  if (width >= editor.o.sizeMD) {
@@ -128,7 +149,7 @@ export function mobile(editor) {
128
149
  if (newStore.toString() !== store.toString()) {
129
150
  store = newStore;
130
151
  editor.e.fire('closeAllPopups');
131
- (_b = editor.toolbar) === null || _b === void 0 ? void 0 : _b.setRemoveButtons(editor.o.removeButtons).build(store.concat(editor.o.extraButtons));
152
+ (_a = editor.toolbar) === null || _a === void 0 ? void 0 : _a.setRemoveButtons(editor.o.removeButtons).build(store.concat(editor.o.extraButtons));
132
153
  }
133
154
  })
134
155
  .on(editor.ow, 'load resize', () => editor.e.fire('recalcAdaptive'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jodit",
3
- "version": "4.15.6",
3
+ "version": "4.15.8",
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",
package/types/config.d.ts CHANGED
@@ -1021,7 +1021,8 @@ interface Config {
1021
1021
  */
1022
1022
  fillEmptyParagraph: boolean;
1023
1023
  /**
1024
- * Remove empty elements
1024
+ * Remove empty inline elements. Elements that in-page links can point
1025
+ * at (anything with an `id`, and `<a>` with a `name`) are kept.
1025
1026
  */
1026
1027
  removeEmptyElements: boolean;
1027
1028
  /**
@@ -1042,6 +1043,16 @@ interface Config {
1042
1043
  * names with single quotes: `font-family: 'Open Sans', sans-serif`.
1043
1044
  */
1044
1045
  singleQuotesInFontFamily: boolean;
1046
+ /**
1047
+ * Browsers keep a trailing `<br>` inside a block after you type into an
1048
+ * empty one (`<p>test<br></p>`), and the same `<br>` ends up in the
1049
+ * editor value. It renders nothing, but confuses consumers that compare
1050
+ * or post-process the HTML. With this option the value getter drops a
1051
+ * `<br>` that is the last node of a block (or of the whole value)
1052
+ * and follows other content. `<p><br></p>` and `text<br><br>` — an empty
1053
+ * line — are kept.
1054
+ */
1055
+ removeTrailingBr: boolean;
1045
1056
  /**
1046
1057
  * Replace old tags to new eg. <i> to <em>, <b> to <strong>
1047
1058
  */
@@ -11,9 +11,6 @@
11
11
  import type { IJodit } from "../../types/index";
12
12
  import { Plugin } from "../../core/plugin/plugin";
13
13
  import "./config";
14
- /**
15
- * Clean HTML after removeFormat and insertHorizontalRule command
16
- */
17
14
  export declare class cleanHtml extends Plugin {
18
15
  /** @override */
19
16
  buttons: Plugin['buttons'];
@@ -50,6 +47,13 @@ export declare class cleanHtml extends Plugin {
50
47
  * survive that round trip. Names that already contain an apostrophe are
51
48
  * left alone.
52
49
  */
50
+ /**
51
+ * Drop a `<br>` that is the last node of a block (or of the value) and
52
+ * follows other content — the caret placeholder browsers leave behind
53
+ * after typing into an empty block. An empty block (`<p><br></p>`) and a
54
+ * deliberate empty line (`text<br><br>`) are kept.
55
+ */
56
+ private __removeTrailingBr;
53
57
  private __singleQuotesInFontFamily;
54
58
  protected onSafeHTML(sandBox: HTMLElement): void;
55
59
  /** @override */
@@ -20,7 +20,8 @@ declare module 'jodit/config' {
20
20
  */
21
21
  fillEmptyParagraph: boolean;
22
22
  /**
23
- * Remove empty elements
23
+ * Remove empty inline elements. Elements that in-page links can point
24
+ * at (anything with an `id`, and `<a>` with a `name`) are kept.
24
25
  */
25
26
  removeEmptyElements: boolean;
26
27
  /**
@@ -41,6 +42,16 @@ declare module 'jodit/config' {
41
42
  * names with single quotes: `font-family: 'Open Sans', sans-serif`.
42
43
  */
43
44
  singleQuotesInFontFamily: boolean;
45
+ /**
46
+ * Browsers keep a trailing `<br>` inside a block after you type into an
47
+ * empty one (`<p>test<br></p>`), and the same `<br>` ends up in the
48
+ * editor value. It renders nothing, but confuses consumers that compare
49
+ * or post-process the HTML. With this option the value getter drops a
50
+ * `<br>` that is the last node of a block (or of the whole value)
51
+ * and follows other content. `<p><br></p>` and `text<br><br>` — an empty
52
+ * line — are kept.
53
+ */
54
+ removeTrailingBr: boolean;
44
55
  /**
45
56
  * Replace old tags to new eg. <i> to <em>, <b> to <strong>
46
57
  */
@@ -50,6 +50,7 @@ export declare class dragAndDropElement extends Plugin {
50
50
  * Mouse move handler handler
51
51
  */
52
52
  private onDrag;
53
+ private __ghostOffset;
53
54
  /**
54
55
  * Mouseup handler in any place
55
56
  */