jodit 4.2.25 → 4.2.32

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 (169) hide show
  1. package/.nvmrc +1 -1
  2. package/CHANGELOG.md +119 -5
  3. package/es2015/jodit.css +14 -2
  4. package/es2015/jodit.fat.min.css +1 -1
  5. package/es2015/jodit.fat.min.js +2 -2
  6. package/es2015/jodit.js +422 -284
  7. package/es2015/jodit.min.css +1 -1
  8. package/es2015/jodit.min.js +2 -2
  9. package/es2015/plugins/debug/debug.js +1 -1
  10. package/es2015/plugins/debug/debug.min.js +1 -1
  11. package/es2015/plugins/speech-recognize/speech-recognize.css +1 -1
  12. package/es2015/plugins/speech-recognize/speech-recognize.js +25 -18
  13. package/es2015/plugins/speech-recognize/speech-recognize.min.js +2 -2
  14. package/es2018/jodit.css +14 -2
  15. package/es2018/jodit.fat.min.css +1 -1
  16. package/es2018/jodit.fat.min.js +2 -2
  17. package/es2018/jodit.js +416 -278
  18. package/es2018/jodit.min.css +1 -1
  19. package/es2018/jodit.min.js +2 -2
  20. package/es2018/plugins/debug/debug.js +1 -1
  21. package/es2018/plugins/debug/debug.min.js +1 -1
  22. package/es2018/plugins/speech-recognize/speech-recognize.css +1 -1
  23. package/es2018/plugins/speech-recognize/speech-recognize.js +25 -18
  24. package/es2018/plugins/speech-recognize/speech-recognize.min.js +2 -2
  25. package/es2021/jodit.css +14 -2
  26. package/es2021/jodit.fat.min.css +1 -1
  27. package/es2021/jodit.fat.min.js +2 -2
  28. package/es2021/jodit.js +416 -278
  29. package/es2021/jodit.min.css +1 -1
  30. package/es2021/jodit.min.js +2 -2
  31. package/es2021/plugins/debug/debug.js +1 -1
  32. package/es2021/plugins/debug/debug.min.js +1 -1
  33. package/es2021/plugins/speech-recognize/speech-recognize.css +1 -1
  34. package/es2021/plugins/speech-recognize/speech-recognize.js +25 -18
  35. package/es2021/plugins/speech-recognize/speech-recognize.min.js +2 -2
  36. package/es2021.en/jodit.css +14 -2
  37. package/es2021.en/jodit.fat.min.css +1 -1
  38. package/es2021.en/jodit.fat.min.js +2 -2
  39. package/es2021.en/jodit.js +391 -272
  40. package/es2021.en/jodit.min.css +1 -1
  41. package/es2021.en/jodit.min.js +2 -2
  42. package/es2021.en/plugins/debug/debug.js +1 -1
  43. package/es2021.en/plugins/debug/debug.min.js +1 -1
  44. package/es2021.en/plugins/speech-recognize/speech-recognize.css +1 -1
  45. package/es2021.en/plugins/speech-recognize/speech-recognize.js +25 -18
  46. package/es2021.en/plugins/speech-recognize/speech-recognize.min.js +2 -2
  47. package/es5/164.fat.min.js +10 -0
  48. package/es5/164.js +4939 -0
  49. package/es5/164.min.js +10 -0
  50. package/es5/5.fat.min.js +10 -0
  51. package/es5/5.js +76 -0
  52. package/es5/5.min.js +10 -0
  53. package/es5/jodit.css +21 -6
  54. package/es5/jodit.fat.min.css +1 -1
  55. package/es5/jodit.fat.min.js +2 -2
  56. package/es5/jodit.js +817 -5709
  57. package/es5/jodit.min.css +3 -3
  58. package/es5/jodit.min.js +2 -2
  59. package/es5/plugins/debug/debug.js +1 -1
  60. package/es5/plugins/debug/debug.min.js +1 -1
  61. package/es5/plugins/speech-recognize/speech-recognize.css +1 -1
  62. package/es5/plugins/speech-recognize/speech-recognize.js +26 -19
  63. package/es5/plugins/speech-recognize/speech-recognize.min.js +2 -2
  64. package/esm/config.js +3 -7
  65. package/esm/core/async/async.js +2 -1
  66. package/esm/core/constants.d.ts +2 -0
  67. package/esm/core/constants.js +12 -8
  68. package/esm/core/decorators/watch/watch.js +0 -1
  69. package/esm/core/dom/dom.d.ts +2 -1
  70. package/esm/core/dom/dom.js +12 -6
  71. package/esm/core/event-emitter/event-emitter.js +3 -3
  72. package/esm/core/global.js +16 -3
  73. package/esm/core/helpers/array/to-array.d.ts +1 -6
  74. package/esm/core/helpers/array/to-array.js +1 -1
  75. package/esm/core/helpers/async/set-timeout.d.ts +0 -3
  76. package/esm/core/helpers/async/set-timeout.js +3 -2
  77. package/esm/core/helpers/checker/has-browser-color-picker.d.ts +0 -3
  78. package/esm/core/helpers/checker/has-browser-color-picker.js +2 -1
  79. package/esm/core/helpers/checker/is-url.d.ts +0 -3
  80. package/esm/core/helpers/checker/is-url.js +2 -1
  81. package/esm/core/helpers/html/apply-styles.js +3 -3
  82. package/esm/core/helpers/html/clean-from-word.js +2 -1
  83. package/esm/core/helpers/html/htmlspecialchars.d.ts +0 -3
  84. package/esm/core/helpers/html/htmlspecialchars.js +2 -1
  85. package/esm/core/helpers/normalize/normalize-key-aliases.js +2 -1
  86. package/esm/core/helpers/normalize/normalize-size.d.ts +1 -1
  87. package/esm/core/helpers/size/get-scroll-parent.js +3 -2
  88. package/esm/core/helpers/utils/complete-url.js +2 -1
  89. package/esm/core/helpers/utils/convert-media-url-to-video-embed.js +2 -1
  90. package/esm/core/helpers/utils/default-language.js +3 -2
  91. package/esm/core/helpers/utils/reset.js +3 -3
  92. package/esm/core/request/ajax.js +2 -1
  93. package/esm/core/selection/selection.js +1 -0
  94. package/esm/core/selection/style/api/has-same-style.js +15 -10
  95. package/esm/core/selection/style/api/toggle-attributes.js +2 -1
  96. package/esm/core/selection/style/commit-style.d.ts +1 -1
  97. package/esm/core/ui/button/tooltip/tooltip.d.ts +1 -0
  98. package/esm/core/ui/button/tooltip/tooltip.js +11 -5
  99. package/esm/core/ui/form/inputs/file/file.d.ts +1 -0
  100. package/esm/core/ui/form/inputs/file/file.js +1 -0
  101. package/esm/core/ui/form/validators/input.d.ts +3 -3
  102. package/esm/core/ui/form/validators/select.d.ts +1 -1
  103. package/esm/jodit.js +3 -0
  104. package/esm/modules/file-browser/config.js +9 -1
  105. package/esm/modules/file-browser/data-provider.js +0 -1
  106. package/esm/modules/file-browser/file-browser.js +0 -1
  107. package/esm/modules/table/table.d.ts +2 -3
  108. package/esm/modules/table/table.js +27 -35
  109. package/esm/modules/toolbar/button/button.d.ts +1 -1
  110. package/esm/plugins/add-new-line/add-new-line.js +4 -1
  111. package/esm/plugins/backspace/cases/check-remove-char.js +1 -0
  112. package/esm/plugins/clean-html/config.d.ts +3 -3
  113. package/esm/plugins/clean-html/helpers/visitor/filters/fill-empty-paragraph.js +9 -1
  114. package/esm/plugins/hotkeys/hotkeys.js +4 -2
  115. package/esm/plugins/iframe/config.d.ts +15 -3
  116. package/esm/plugins/iframe/config.js +1 -0
  117. package/esm/plugins/iframe/iframe.js +3 -0
  118. package/esm/plugins/indent/helpers.d.ts +1 -1
  119. package/esm/plugins/inline-popup/config/items/a.d.ts +2 -2
  120. package/esm/plugins/inline-popup/config/items/cells.d.ts +1 -1
  121. package/esm/plugins/inline-popup/config/items/img.d.ts +1 -1
  122. package/esm/plugins/search/config.js +2 -2
  123. package/esm/plugins/search/helpers/highlight-text-ranges.js +3 -1
  124. package/esm/plugins/select-cells/select-cells.js +1 -1
  125. package/esm/plugins/source/editor/engines/ace.d.ts +0 -1
  126. package/esm/plugins/speech-recognize/config.js +1 -1
  127. package/esm/plugins/speech-recognize/helpers/api.d.ts +1 -1
  128. package/esm/plugins/speech-recognize/helpers/api.js +5 -2
  129. package/esm/plugins/speech-recognize/helpers/sound.js +6 -4
  130. package/esm/plugins/stat/config.d.ts +1 -0
  131. package/esm/plugins/stat/config.js +1 -0
  132. package/esm/plugins/stat/stat.js +14 -3
  133. package/esm/plugins/symbols/langs/index.d.ts +2 -1
  134. package/esm/plugins/symbols/langs/index.js +2 -1
  135. package/esm/plugins/symbols/langs/ua.d.ts +1 -0
  136. package/esm/plugins/symbols/langs/ua.js +9 -0
  137. package/esm/plugins/table/config.js +19 -3
  138. package/esm/polyfills.d.ts +10 -0
  139. package/esm/polyfills.js +54 -0
  140. package/esm/tsconfig.json +1 -1
  141. package/package.json +1 -1
  142. package/types/core/constants.d.ts +2 -0
  143. package/types/core/dom/dom.d.ts +2 -1
  144. package/types/core/helpers/array/to-array.d.ts +1 -6
  145. package/types/core/helpers/async/set-timeout.d.ts +0 -3
  146. package/types/core/helpers/checker/has-browser-color-picker.d.ts +0 -3
  147. package/types/core/helpers/checker/is-url.d.ts +0 -3
  148. package/types/core/helpers/html/htmlspecialchars.d.ts +0 -3
  149. package/types/core/helpers/normalize/normalize-size.d.ts +1 -1
  150. package/types/core/selection/style/commit-style.d.ts +1 -1
  151. package/types/core/ui/button/tooltip/tooltip.d.ts +1 -0
  152. package/types/core/ui/form/inputs/file/file.d.ts +1 -0
  153. package/types/core/ui/form/validators/input.d.ts +3 -3
  154. package/types/core/ui/form/validators/select.d.ts +1 -1
  155. package/types/modules/table/table.d.ts +2 -3
  156. package/types/modules/toolbar/button/button.d.ts +1 -1
  157. package/types/plugins/clean-html/config.d.ts +3 -3
  158. package/types/plugins/iframe/config.d.ts +15 -3
  159. package/types/plugins/indent/helpers.d.ts +1 -1
  160. package/types/plugins/inline-popup/config/items/a.d.ts +2 -2
  161. package/types/plugins/inline-popup/config/items/cells.d.ts +1 -1
  162. package/types/plugins/inline-popup/config/items/img.d.ts +1 -1
  163. package/types/plugins/source/editor/engines/ace.d.ts +0 -1
  164. package/types/plugins/speech-recognize/helpers/api.d.ts +1 -1
  165. package/types/plugins/stat/config.d.ts +1 -0
  166. package/types/plugins/symbols/langs/index.d.ts +2 -1
  167. package/types/plugins/symbols/langs/ua.d.ts +1 -0
  168. package/types/polyfills.d.ts +10 -0
  169. package/types/tsconfig.json +1 -1
@@ -6,7 +6,7 @@
6
6
  /**
7
7
  * @module helpers/html
8
8
  */
9
- import { IS_PROD } from "../../constants.js";
9
+ import { globalDocument, IS_PROD } from "../../constants.js";
10
10
  import { Dom } from "../../dom/dom.js";
11
11
  import { trim } from "../string/trim.js";
12
12
  import { $$ } from "../utils/selector.js";
@@ -36,9 +36,9 @@ export function applyStyles(html) {
36
36
  }
37
37
  html = html.substring(html.indexOf('<html '), html.length);
38
38
  html = html.substring(0, html.lastIndexOf('</html>') + '</html>'.length);
39
- const iframe = document.createElement('iframe');
39
+ const iframe = globalDocument.createElement('iframe');
40
40
  iframe.style.display = 'none';
41
- document.body.appendChild(iframe);
41
+ globalDocument.body.appendChild(iframe);
42
42
  let convertedString = '', collection = [];
43
43
  try {
44
44
  const iframeDoc = iframe.contentDocument ||
@@ -6,6 +6,7 @@
6
6
  /**
7
7
  * @module helpers/html
8
8
  */
9
+ import { globalDocument } from "../../constants.js";
9
10
  import { Dom } from "../../dom/dom.js";
10
11
  import { toArray } from "../array/to-array.js";
11
12
  import { trim } from "../string/trim.js";
@@ -20,7 +21,7 @@ export function cleanFromWord(html) {
20
21
  }
21
22
  let convertedString = '';
22
23
  try {
23
- const div = document.createElement('div');
24
+ const div = globalDocument.createElement('div');
24
25
  div.innerHTML = html;
25
26
  const marks = [];
26
27
  if (div.firstChild) {
@@ -3,9 +3,6 @@
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
- /**
7
- * @module helpers/html
8
- */
9
6
  /**
10
7
  * Convert special characters to HTML entities
11
8
  */
@@ -6,11 +6,12 @@
6
6
  /**
7
7
  * @module helpers/html
8
8
  */
9
+ import { globalDocument } from "../../constants.js";
9
10
  /**
10
11
  * Convert special characters to HTML entities
11
12
  */
12
13
  export function htmlspecialchars(html) {
13
- const tmp = document.createElement('div');
14
+ const tmp = globalDocument.createElement('div');
14
15
  tmp.textContent = html;
15
16
  return tmp.innerHTML;
16
17
  }
@@ -15,7 +15,8 @@ export function normalizeKeyAliases(keys) {
15
15
  ctrl: 2,
16
16
  control: 2,
17
17
  alt: 3,
18
- shift: 4
18
+ shift: 4,
19
+ space: 5
19
20
  };
20
21
  return keys
21
22
  .replace(/\+\+/g, '+add')
@@ -9,4 +9,4 @@
9
9
  /**
10
10
  * Normalize value to CSS meters
11
11
  */
12
- export declare const normalizeSize: (value: string | number, units: 'px' | 'pt') => string;
12
+ export declare const normalizeSize: (value: string | number, units: "px" | "pt") => string;
@@ -3,6 +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 { globalDocument } from "../../constants.js";
6
7
  import { Dom } from "../../dom/dom.js";
7
8
  import { css } from "../utils/index.js";
8
9
  export function getScrollParent(node) {
@@ -16,6 +17,6 @@ export function getScrollParent(node) {
16
17
  return node;
17
18
  }
18
19
  return (getScrollParent(node.parentNode) ||
19
- document.scrollingElement ||
20
- document.body);
20
+ globalDocument.scrollingElement ||
21
+ globalDocument.body);
21
22
  }
@@ -3,11 +3,12 @@
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 { globalWindow } from "../../constants.js";
6
7
  /**
7
8
  * @module helpers/utils
8
9
  */
9
10
  export const completeUrl = (url) => {
10
- if (window.location.protocol === 'file:' && /^\/\//.test(url)) {
11
+ if (globalWindow.location.protocol === 'file:' && /^\/\//.test(url)) {
11
12
  url = 'https:' + url;
12
13
  }
13
14
  return url;
@@ -6,6 +6,7 @@
6
6
  /**
7
7
  * @module helpers/utils
8
8
  */
9
+ import { globalDocument } from "../../constants.js";
9
10
  import { isURL } from "../checker/is-url.js";
10
11
  import { parseQuery } from "./parse-query.js";
11
12
  /**
@@ -15,7 +16,7 @@ export const convertMediaUrlToVideoEmbed = (url, width = 400, height = 345) => {
15
16
  if (!isURL(url)) {
16
17
  return url;
17
18
  }
18
- const parser = document.createElement('a'), pattern1 = /(?:http?s?:\/\/)?(?:www\.)?(?:vimeo\.com)\/?(.+)/g;
19
+ const parser = globalDocument.createElement('a'), pattern1 = /(?:http?s?:\/\/)?(?:www\.)?(?:vimeo\.com)\/?(.+)/g;
19
20
  parser.href = url;
20
21
  if (!width) {
21
22
  width = 400;
@@ -6,6 +6,7 @@
6
6
  /**
7
7
  * @module helpers/utils
8
8
  */
9
+ import { globalDocument } from "../../constants.js";
9
10
  import { isString } from "../checker/is-string.js";
10
11
  /**
11
12
  * Try define user language
@@ -14,8 +15,8 @@ export const defaultLanguage = (language, defaultLanguage = 'en') => {
14
15
  if (language !== 'auto' && isString(language)) {
15
16
  return language;
16
17
  }
17
- if (document.documentElement && document.documentElement.lang) {
18
- return document.documentElement.lang;
18
+ if (globalDocument.documentElement && globalDocument.documentElement.lang) {
19
+ return globalDocument.documentElement.lang;
19
20
  }
20
21
  if (navigator.language) {
21
22
  return navigator.language.substring(0, 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 { IS_PROD } from "../../constants.js";
6
+ import { globalDocument, IS_PROD } from "../../constants.js";
7
7
  import { isFunction } from "../checker/is-function.js";
8
8
  import { get } from "./get.js";
9
9
  const map = {};
@@ -17,10 +17,10 @@ const map = {};
17
17
  */
18
18
  export function reset(key) {
19
19
  if (!(key in map)) {
20
- const iframe = document.createElement('iframe');
20
+ const iframe = globalDocument.createElement('iframe');
21
21
  try {
22
22
  iframe.src = 'about:blank';
23
- document.body.appendChild(iframe);
23
+ globalDocument.body.appendChild(iframe);
24
24
  if (!iframe.contentWindow) {
25
25
  return null;
26
26
  }
@@ -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 { Async } from "../async/index.js";
17
+ import { globalWindow } from "../constants.js";
17
18
  import { autobind } from "../decorators/autobind/autobind.js";
18
19
  import { buildQuery, ConfigProto, isFunction, isPlainObject, isString, parseQuery } from "../helpers/index.js";
19
20
  import * as error from "../helpers/utils/error/index.js";
@@ -42,7 +43,7 @@ export class Ajax {
42
43
  return this.o.queryBuild.call(this, obj, prefix);
43
44
  }
44
45
  if (isString(obj) ||
45
- obj instanceof window.FormData ||
46
+ obj instanceof globalWindow.FormData ||
46
47
  (typeof obj === 'object' && obj != null && isFunction(obj.append))) {
47
48
  return obj;
48
49
  }
@@ -593,6 +593,7 @@ export class Selection {
593
593
  /**
594
594
  * Call callback for all selection node
595
595
  */
596
+ // eslint-disable-next-line complexity
596
597
  eachSelection(callback) {
597
598
  const sel = this.sel;
598
599
  if (!sel || !sel.rangeCount) {
@@ -3,6 +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 { globalDocument } from "../../../constants.js";
6
7
  import { Dom } from "../../../dom/dom.js";
7
8
  import { isVoid } from "../../../helpers/checker/is-void.js";
8
9
  import { normalizeCssValue } from "../../../helpers/normalize/normalize-css-value.js";
@@ -29,11 +30,13 @@ export function hasSameStyle(elm, rules) {
29
30
  .toLowerCase() === value.toString().toLowerCase());
30
31
  }));
31
32
  }
32
- const elm = document.createElement('div');
33
- elm.style.color = 'red';
34
- assert(hasSameStyle(elm, { color: 'red' }), 'Style test');
35
- assert(hasSameStyle(elm, { fontSize: null }), 'Style test');
36
- assert(hasSameStyle(elm, { fontSize: '' }), 'Style test');
33
+ if (globalDocument) {
34
+ const elm = globalDocument.createElement('div');
35
+ elm.style.color = 'red';
36
+ assert(hasSameStyle(elm, { color: 'red' }), 'Style test');
37
+ assert(hasSameStyle(elm, { fontSize: null }), 'Style test');
38
+ assert(hasSameStyle(elm, { fontSize: '' }), 'Style test');
39
+ }
37
40
  /**
38
41
  * Element has the similar styles keys
39
42
  */
@@ -45,8 +48,10 @@ export function hasSameStyleKeys(elm, rules) {
45
48
  return value !== '';
46
49
  }));
47
50
  }
48
- const elm2 = document.createElement('div');
49
- elm2.style.color = 'red';
50
- assert(hasSameStyleKeys(elm2, { color: 'red' }), 'Style test');
51
- assert(!hasSameStyleKeys(elm2, { font: 'Arial', color: 'red' }), 'Style test');
52
- assert(!hasSameStyleKeys(elm2, { border: '1px solid #ccc' }), 'Style test');
51
+ if (globalDocument) {
52
+ const elm2 = globalDocument.createElement('div');
53
+ elm2.style.color = 'red';
54
+ assert(hasSameStyleKeys(elm2, { color: 'red' }), 'Style test');
55
+ assert(!hasSameStyleKeys(elm2, { font: 'Arial', color: 'red' }), 'Style test');
56
+ assert(!hasSameStyleKeys(elm2, { border: '1px solid #ccc' }), 'Style test');
57
+ }
@@ -3,6 +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 { globalDocument } from "../../../constants.js";
6
7
  import { Dom } from "../../../dom/dom.js";
7
8
  import { getContainer } from "../../../global.js";
8
9
  import { isBoolean, isNumber, isPlainObject, isString } from "../../../helpers/checker/index.js";
@@ -129,7 +130,7 @@ function getShadowRoot(jodit) {
129
130
  return dataBind(jodit, 'shadowRoot');
130
131
  }
131
132
  const container = getContainer(jodit);
132
- const iframe = document.createElement('iframe');
133
+ const iframe = globalDocument.createElement('iframe');
133
134
  css(iframe, {
134
135
  width: 0,
135
136
  height: 0,
@@ -23,7 +23,7 @@ export declare class CommitStyle implements ICommitStyle {
23
23
  */
24
24
  get isElementCommit(): boolean;
25
25
  get defaultTag(): HTMLTagNames;
26
- get elementIsDefault(): Boolean;
26
+ get elementIsDefault(): boolean;
27
27
  constructor(options: IStyleOptions);
28
28
  apply(jodit: IJodit): void;
29
29
  }
@@ -16,6 +16,7 @@ export declare class UITooltip extends UIElement {
16
16
  className(): string;
17
17
  protected render(): string;
18
18
  constructor(view: IViewBased);
19
+ private __onAttach;
19
20
  private __listenClose;
20
21
  private __addListenersOnEnter;
21
22
  private __removeListenersOnLeave;
@@ -51,15 +51,21 @@ let UITooltip = UITooltip_1 = class UITooltip extends UIElement {
51
51
  if (!view.o.textIcons &&
52
52
  view.o.showTooltip &&
53
53
  !view.o.useNativeTooltip) {
54
+ this.j.e.on('getContainer', (box) => {
55
+ this.__onAttach(box);
56
+ });
54
57
  view.hookStatus(STATUSES.ready, () => {
55
- // TODO Move it inside __show method. Now it is here because testcase failed with capturing
56
- getContainer(this.j, UITooltip_1).appendChild(this.container);
57
- view.e.on(view.container, 'mouseenter.tooltip', this.__onMouseEnter, {
58
- capture: true
59
- });
58
+ this.__onAttach(this.j.container);
60
59
  });
61
60
  }
62
61
  }
62
+ __onAttach(container) {
63
+ // TODO Move it inside __show method. Now it is here because testcase failed with capturing
64
+ getContainer(this.j, UITooltip_1).appendChild(this.container);
65
+ this.j.e.on(container, 'mouseenter.tooltip', this.__onMouseEnter, {
66
+ capture: true
67
+ });
68
+ }
63
69
  __addListenersOnEnter() {
64
70
  if (this.__listenClose) {
65
71
  return;
@@ -13,6 +13,7 @@ export declare class UIFileInput extends UIInput {
13
13
  private button;
14
14
  state: UIInput['state'] & {
15
15
  onlyImages: boolean;
16
+ tooltip?: string;
16
17
  };
17
18
  /** @override */
18
19
  className(): string;
@@ -23,6 +23,7 @@ let UIFileInput = class UIFileInput extends UIInput {
23
23
  }
24
24
  createContainer(options) {
25
25
  this.button = new UIButton(this.j, {
26
+ tooltip: options.tooltip,
26
27
  icon: {
27
28
  name: 'plus'
28
29
  }
@@ -6,12 +6,12 @@
6
6
  /**
7
7
  * @module ui/form
8
8
  */
9
- import type { IUIInput, IUIInputValidator } from "../../../../types";
9
+ import type { IUIInputValidator } from "../../../../types";
10
10
  /**
11
11
  * Input is required
12
12
  */
13
- export declare const required: IUIInputValidator<IUIInput>;
13
+ export declare const required: IUIInputValidator;
14
14
  /**
15
15
  * Input value should be valid URL
16
16
  */
17
- export declare const url: IUIInputValidator<IUIInput>;
17
+ export declare const url: IUIInputValidator;
@@ -10,4 +10,4 @@ import type { IUIInputValidator } from "../../../../types";
10
10
  /**
11
11
  * Select is required
12
12
  */
13
- export declare const required: IUIInputValidator<import("../../../../types").IUIInput>;
13
+ export declare const required: IUIInputValidator;
package/esm/jodit.js CHANGED
@@ -844,6 +844,9 @@ let Jodit = Jodit_1 = class Jodit extends ViewWithToolbar {
844
844
  }
845
845
  }
846
846
  catch (e) {
847
+ if (!IS_PROD) {
848
+ throw e;
849
+ }
847
850
  this.destruct();
848
851
  throw e;
849
852
  }
@@ -220,10 +220,12 @@ Config.prototype.filebrowser = {
220
220
  Config.prototype.controls.filebrowser = {
221
221
  upload: {
222
222
  icon: 'plus',
223
+ tooltip: 'Upload file',
223
224
  isInput: true,
224
225
  isDisabled: (browser) => !browser.dataProvider.canI('FileUpload'),
225
- getContent: (filebrowser) => {
226
+ getContent: (filebrowser, btnInt) => {
226
227
  const btn = new UIFileInput(filebrowser, {
228
+ tooltip: btnInt.control.tooltip,
227
229
  onlyImages: filebrowser.state.onlyImages
228
230
  });
229
231
  filebrowser.e.fire('bindUploader.filebrowser', btn.container);
@@ -232,6 +234,7 @@ Config.prototype.controls.filebrowser = {
232
234
  },
233
235
  remove: {
234
236
  icon: 'bin',
237
+ tooltip: 'Remove file',
235
238
  isDisabled: (browser) => {
236
239
  return (!browser.state.activeElements.length ||
237
240
  !browser.dataProvider.canI('FileRemove'));
@@ -241,11 +244,13 @@ Config.prototype.controls.filebrowser = {
241
244
  }
242
245
  },
243
246
  update: {
247
+ tooltip: 'Update file list',
244
248
  exec: (editor) => {
245
249
  editor.e.fire('update.filebrowser');
246
250
  }
247
251
  },
248
252
  select: {
253
+ tooltip: 'Select file',
249
254
  icon: 'check',
250
255
  isDisabled: (browser) => !browser.state.activeElements.length,
251
256
  exec: (editor) => {
@@ -253,6 +258,7 @@ Config.prototype.controls.filebrowser = {
253
258
  }
254
259
  },
255
260
  edit: {
261
+ tooltip: 'Edit image',
256
262
  icon: 'pencil',
257
263
  isDisabled: (browser) => {
258
264
  const selected = browser.state.activeElements;
@@ -266,6 +272,7 @@ Config.prototype.controls.filebrowser = {
266
272
  }
267
273
  },
268
274
  tiles: {
275
+ tooltip: 'Tiles view',
269
276
  icon: 'th',
270
277
  isActive: (filebrowser) => filebrowser.state.view === 'tiles',
271
278
  exec: (filebrowser) => {
@@ -273,6 +280,7 @@ Config.prototype.controls.filebrowser = {
273
280
  }
274
281
  },
275
282
  list: {
283
+ tooltip: 'List view',
276
284
  icon: 'th-list',
277
285
  isActive: (filebrowser) => filebrowser.state.view === 'list',
278
286
  exec: (filebrowser) => {
@@ -354,7 +354,6 @@ let DataProvider = class DataProvider {
354
354
  data: {}
355
355
  };
356
356
  }
357
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
358
357
  const query = this.o[type];
359
358
  if (query.data === undefined) {
360
359
  query.data = {
@@ -41,7 +41,6 @@ let FileBrowser = class FileBrowser extends ViewWithToolbar {
41
41
  get dataProvider() {
42
42
  return makeDataProvider(this, this.options);
43
43
  }
44
- // eslint-disable-next-line no-unused-vars
45
44
  onSelect(callback) {
46
45
  return () => {
47
46
  if (this.state.activeElements.length) {
@@ -62,11 +62,10 @@ export declare class Table extends ViewComponent<IJodit> {
62
62
  * Remove row
63
63
  */
64
64
  removeRow(table: HTMLTableElement, rowIndex: number): void;
65
- private static __appendColumn;
66
65
  /**
67
66
  * Insert column before / after all the columns containing the selected cells
68
67
  */
69
- appendColumn(table: HTMLTableElement, j: number, after: boolean): void;
68
+ appendColumn(table: HTMLTableElement, selectedCell: HTMLTableCellElement, insertAfter?: boolean): void;
70
69
  private static __removeColumn;
71
70
  /**
72
71
  * Remove column by index
@@ -86,7 +85,7 @@ export declare class Table extends ViewComponent<IJodit> {
86
85
  normalizeTable(table: HTMLTableElement): void;
87
86
  private static __mergeSelected;
88
87
  /**
89
- * It combines all of the selected cells into one. The contents of the cells will also be combined
88
+ * It combines all the selected cells into one. The contents of the cells will also be combined
90
89
  */
91
90
  mergeSelected(table: HTMLTableElement): void;
92
91
  private static __splitHorizontal;
@@ -36,7 +36,6 @@ export class Table extends ViewComponent {
36
36
  const selector = cssPath(td);
37
37
  selector && selectors.push(selector);
38
38
  });
39
- // eslint-disable-next-line no-prototype-builtins
40
39
  style.innerHTML = selectors.length
41
40
  ? selectors.join(',') +
42
41
  `{${this.jodit.options.table.selectionCellStyle}}`
@@ -254,46 +253,39 @@ export class Table extends ViewComponent {
254
253
  removeRow(table, rowIndex) {
255
254
  return Table.__removeRow(table, rowIndex);
256
255
  }
257
- static __appendColumn(table, j, after, create) {
256
+ /**
257
+ * Insert column before / after all the columns containing the selected cells
258
+ */
259
+ appendColumn(table, selectedCell, insertAfter = true) {
258
260
  const box = Table.__formalMatrix(table);
259
- let i;
260
- if (j === undefined || j < 0) {
261
- j = Table.__getColumnsCount(table) - 1;
261
+ if (!insertAfter && Dom.isCell(selectedCell.previousElementSibling)) {
262
+ return this.appendColumn(table, selectedCell.previousElementSibling, true);
262
263
  }
263
- for (i = 0; i < box.length; i += 1) {
264
- const cell = create.element('td');
265
- const td = box[i][j];
266
- let added = false;
267
- if (after) {
268
- if ((box[i] && td && j + 1 >= box[i].length) ||
269
- td !== box[i][j + 1]) {
270
- if (td.nextSibling) {
271
- Dom.before(td.nextSibling, cell);
272
- }
273
- else {
274
- td.parentNode && td.parentNode.appendChild(cell);
275
- }
276
- added = true;
264
+ const columnIndex = insertAfter
265
+ ? selectedCell.cellIndex + ((selectedCell.colSpan || 1) - 1)
266
+ : selectedCell.cellIndex;
267
+ const newColumnIndex = insertAfter ? columnIndex + 1 : columnIndex;
268
+ for (let i = 0; i < box.length;) {
269
+ const cells = box[i];
270
+ if (cells[columnIndex] !== cells[newColumnIndex] ||
271
+ columnIndex === newColumnIndex) {
272
+ const cell = this.j.createInside.element('td');
273
+ if (insertAfter) {
274
+ Dom.after(cells[columnIndex], cell);
277
275
  }
278
- }
279
- else {
280
- if (j - 1 < 0 ||
281
- (box[i][j] !== box[i][j - 1] && box[i][j].parentNode)) {
282
- Dom.before(box[i][j], cell);
283
- added = true;
276
+ else {
277
+ Dom.before(cells[columnIndex], cell);
278
+ }
279
+ if (cells[columnIndex].rowSpan > 1) {
280
+ cell.rowSpan = cells[columnIndex].rowSpan;
284
281
  }
285
282
  }
286
- if (!added) {
287
- attr(box[i][j], 'colspan', parseInt(attr(box[i][j], 'colspan') || '1', 10) + 1);
283
+ else {
284
+ cells[columnIndex].colSpan += 1;
288
285
  }
286
+ i += cells[columnIndex].rowSpan || 1;
289
287
  }
290
288
  }
291
- /**
292
- * Insert column before / after all the columns containing the selected cells
293
- */
294
- appendColumn(table, j, after) {
295
- return Table.__appendColumn(table, j, after, this.j.createInside);
296
- }
297
289
  static __removeColumn(table, j) {
298
290
  const box = Table.__formalMatrix(table);
299
291
  let dec;
@@ -511,7 +503,7 @@ export class Table extends ViewComponent {
511
503
  alreadyMerged.delete(first);
512
504
  Table.__unmark(__marked);
513
505
  Table.__normalizeTable(table);
514
- toArray(table.rows).forEach((tr, index) => {
506
+ toArray(table.rows).forEach(tr => {
515
507
  if (!tr.cells.length) {
516
508
  Dom.safeRemove(tr);
517
509
  }
@@ -520,7 +512,7 @@ export class Table extends ViewComponent {
520
512
  }
521
513
  }
522
514
  /**
523
- * It combines all of the selected cells into one. The contents of the cells will also be combined
515
+ * It combines all the selected cells into one. The contents of the cells will also be combined
524
516
  */
525
517
  mergeSelected(table) {
526
518
  return Table.__mergeSelected(table, this.j);
@@ -20,7 +20,7 @@ export declare class ToolbarButton<T extends IViewBased = IViewBased> extends UI
20
20
  theme: string;
21
21
  currentValue: string;
22
22
  hasTrigger: boolean;
23
- size: "small" | "tiny" | "xsmall" | "middle" | "large";
23
+ size: "tiny" | "xsmall" | "small" | "middle" | "large";
24
24
  name: string;
25
25
  value: string | number | boolean;
26
26
  variant: import("../../../types").ButtonVariant;
@@ -120,7 +120,9 @@ export class addNewLine extends Plugin {
120
120
  editor.e
121
121
  .off(editor.editor, '.' + ns)
122
122
  .off(editor.container, '.' + ns)
123
+ .off('.' + ns)
123
124
  .on([editor.ow, editor.ew, editor.editor], 'scroll' + '.' + ns, this.__hideForce)
125
+ .on('finishedCleanHTMLWorker' + '.' + ns, this.__hideForce)
124
126
  .on(editor.editor, 'click' + '.' + ns, this.__hide)
125
127
  .on(editor.container, 'mouseleave' + '.' + ns, this.__hide)
126
128
  .on(editor.editor, 'mousemove' + '.' + ns, this.__onMouseMove);
@@ -208,7 +210,8 @@ export class addNewLine extends Plugin {
208
210
  Dom.safeRemove(this.__line);
209
211
  this.j.e
210
212
  .off([this.j.ow, this.j.ew, this.j.editor], '.' + ns)
211
- .off(this.j.container, '.' + ns);
213
+ .off(this.j.container, '.' + ns)
214
+ .off('.' + ns);
212
215
  }
213
216
  }
214
217
  __decorate([
@@ -20,6 +20,7 @@ import { findMostNestedNeighbor } from "../helpers.js";
20
20
  * ```
21
21
  * @private
22
22
  */
23
+ // eslint-disable-next-line complexity
23
24
  export function checkRemoveChar(jodit, fakeNode, backspace, mode) {
24
25
  const step = backspace ? -1 : 1;
25
26
  const anotherSibling = Dom.sibling(fakeNode, !backspace);
@@ -19,9 +19,9 @@ declare module 'jodit/config' {
19
19
  removeEmptyElements: boolean;
20
20
  replaceOldTags: IDictionary<HTMLTagNames> | false;
21
21
  /**
22
- * Use iframe[sandbox] to paste HTML code into the editor to check it for safety
23
- * Allows you not to run scripts and handlers, but it works much slower
24
- * @example
22
+ * You can use an iframe with the sandbox attribute to safely paste and test HTML code.
23
+ * It prevents scripts and handlers from running, but it does slow things down.
24
+ *
25
25
  * ```javascript
26
26
  * Jodit.make('#editor', {
27
27
  * cleanHTML: {
@@ -5,13 +5,21 @@
5
5
  */
6
6
  import { INSEPARABLE_TAGS } from "../../../../../core/constants.js";
7
7
  import { Dom } from "../../../../../core/dom/dom.js";
8
+ const TABLE_CONTAINER_TAGS = new Set([
9
+ 'table',
10
+ 'tbody',
11
+ 'thead',
12
+ 'tfoot',
13
+ 'tr'
14
+ ]);
8
15
  /**
9
16
  * @private
10
17
  */
11
18
  export function fillEmptyParagraph(jodit, nodeElm, hadEffect) {
12
19
  if (jodit.o.cleanHTML.fillEmptyParagraph &&
13
20
  Dom.isBlock(nodeElm) &&
14
- Dom.isEmpty(nodeElm, INSEPARABLE_TAGS)) {
21
+ Dom.isEmpty(nodeElm, INSEPARABLE_TAGS) &&
22
+ !Dom.isTag(nodeElm, TABLE_CONTAINER_TAGS)) {
15
23
  const br = jodit.createInside.element('br');
16
24
  nodeElm.appendChild(br);
17
25
  return true;