jodit 4.13.26 → 4.14.0

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 (167) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/es2015/jodit.css +1 -1
  3. package/es2015/jodit.fat.min.js +19 -19
  4. package/es2015/jodit.js +1104 -884
  5. package/es2015/jodit.min.js +20 -20
  6. package/es2015/plugins/debug/debug.css +1 -1
  7. package/es2015/plugins/debug/debug.js +10 -10
  8. package/es2015/plugins/debug/debug.min.js +4 -4
  9. package/es2015/plugins/speech-recognize/speech-recognize.css +1 -1
  10. package/es2015/plugins/speech-recognize/speech-recognize.js +2 -2
  11. package/es2015/plugins/speech-recognize/speech-recognize.min.js +2 -2
  12. package/es2018/jodit.fat.min.js +19 -19
  13. package/es2018/jodit.min.js +19 -19
  14. package/es2018/plugins/debug/debug.min.js +4 -4
  15. package/es2018/plugins/speech-recognize/speech-recognize.min.js +2 -2
  16. package/es2021/jodit.css +1 -1
  17. package/es2021/jodit.fat.min.js +29 -29
  18. package/es2021/jodit.js +1097 -875
  19. package/es2021/jodit.min.js +29 -29
  20. package/es2021/plugins/debug/debug.css +1 -1
  21. package/es2021/plugins/debug/debug.js +10 -10
  22. package/es2021/plugins/debug/debug.min.js +4 -4
  23. package/es2021/plugins/speech-recognize/speech-recognize.css +1 -1
  24. package/es2021/plugins/speech-recognize/speech-recognize.js +2 -2
  25. package/es2021/plugins/speech-recognize/speech-recognize.min.js +2 -2
  26. package/es2021.en/jodit.css +1 -1
  27. package/es2021.en/jodit.fat.min.js +29 -29
  28. package/es2021.en/jodit.js +1097 -875
  29. package/es2021.en/jodit.min.js +29 -29
  30. package/es2021.en/plugins/debug/debug.css +1 -1
  31. package/es2021.en/plugins/debug/debug.js +10 -10
  32. package/es2021.en/plugins/debug/debug.min.js +4 -4
  33. package/es2021.en/plugins/speech-recognize/speech-recognize.css +1 -1
  34. package/es2021.en/plugins/speech-recognize/speech-recognize.js +2 -2
  35. package/es2021.en/plugins/speech-recognize/speech-recognize.min.js +2 -2
  36. package/es5/jodit.css +2 -2
  37. package/es5/jodit.fat.min.js +2 -2
  38. package/es5/jodit.js +1221 -925
  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 +10 -10
  43. package/es5/plugins/debug/debug.min.js +2 -2
  44. package/es5/plugins/speech-recognize/speech-recognize.css +1 -1
  45. package/es5/plugins/speech-recognize/speech-recognize.js +2 -2
  46. package/es5/plugins/speech-recognize/speech-recognize.min.js +2 -2
  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/core/constants.js +1 -1
  51. package/esm/core/create/create.js +2 -2
  52. package/esm/core/dom/dom.d.ts +21 -13
  53. package/esm/core/dom/dom.js +58 -87
  54. package/esm/core/global.js +3 -2
  55. package/esm/core/helpers/html/apply-styles.js +14 -10
  56. package/esm/core/helpers/html/clean-from-word.js +8 -4
  57. package/esm/core/helpers/html/safe-html.js +23 -14
  58. package/esm/core/helpers/html/strip-tags.js +9 -4
  59. package/esm/core/helpers/utils/align.d.ts +0 -3
  60. package/esm/core/helpers/utils/align.js +15 -18
  61. package/esm/core/helpers/utils/append-script.js +13 -10
  62. package/esm/core/helpers/utils/attr.d.ts +3 -1
  63. package/esm/core/helpers/utils/attr.js +18 -0
  64. package/esm/core/helpers/utils/css.d.ts +18 -1
  65. package/esm/core/helpers/utils/css.js +15 -0
  66. package/esm/core/helpers/utils/print.js +17 -14
  67. package/esm/core/helpers/utils/reset.js +3 -0
  68. package/esm/core/helpers/utils/selector.js +11 -7
  69. package/esm/core/selection/helpers/move-node-inside-start.js +1 -1
  70. package/esm/core/selection/selection.js +29 -26
  71. package/esm/core/selection/style/api/get-suit-parent.js +10 -0
  72. package/esm/core/selection/style/api/is-same-attributes.js +5 -2
  73. package/esm/core/selection/style/api/toggle-attributes.js +8 -9
  74. package/esm/core/selection/style/api/wrap-unwrapped-text.js +2 -2
  75. package/esm/core/traits/elms.js +11 -3
  76. package/esm/core/ui/button/button/button.js +3 -3
  77. package/esm/core/ui/button/group/group.js +2 -1
  78. package/esm/core/ui/button/tooltip/tooltip.js +2 -2
  79. package/esm/core/ui/element.js +1 -1
  80. package/esm/core/ui/form/inputs/area/area.js +3 -2
  81. package/esm/core/ui/form/inputs/file/file.js +2 -1
  82. package/esm/core/ui/form/inputs/input/input.js +5 -5
  83. package/esm/core/ui/group/group.js +7 -7
  84. package/esm/core/ui/icon.js +2 -2
  85. package/esm/core/ui/popup/popup.js +10 -8
  86. package/esm/core/ui/progress-bar/progress-bar.js +3 -4
  87. package/esm/core/view/view-with-toolbar.js +1 -1
  88. package/esm/core/view/view.js +1 -1
  89. package/esm/jodit.js +30 -28
  90. package/esm/modules/dialog/alert.js +1 -1
  91. package/esm/modules/dialog/confirm.js +3 -2
  92. package/esm/modules/dialog/dialog.d.ts +6 -0
  93. package/esm/modules/dialog/dialog.js +40 -22
  94. package/esm/modules/dialog/prompt.js +4 -3
  95. package/esm/modules/file-browser/builders/context-menu.js +5 -5
  96. package/esm/modules/file-browser/config.js +3 -1
  97. package/esm/modules/file-browser/file-browser.js +7 -4
  98. package/esm/modules/file-browser/listeners/state-listeners.js +6 -6
  99. package/esm/modules/image-editor/image-editor.js +31 -17
  100. package/esm/modules/messages/messages.js +2 -1
  101. package/esm/modules/status-bar/status-bar.js +3 -4
  102. package/esm/modules/table/table.js +22 -18
  103. package/esm/modules/toolbar/button/button.js +4 -4
  104. package/esm/modules/toolbar/button/content.js +12 -4
  105. package/esm/modules/toolbar/collection/collection.js +4 -2
  106. package/esm/modules/uploader/config.js +3 -2
  107. package/esm/modules/uploader/helpers/process-old-browser-drag.js +1 -1
  108. package/esm/modules/uploader/uploader.js +7 -2
  109. package/esm/modules/widget/color-picker/color-picker.js +4 -4
  110. package/esm/modules/widget/file-selector/file-selector.js +6 -6
  111. package/esm/modules/widget/tabs/tabs.js +5 -5
  112. package/esm/plugins/add-new-line/add-new-line.js +8 -7
  113. package/esm/plugins/ai-assistant/ui/ui-ai-assistant.js +4 -4
  114. package/esm/plugins/backspace/cases/check-join-neighbors.js +4 -1
  115. package/esm/plugins/clean-html/helpers/visitor/filters/allow-attributes.js +5 -1
  116. package/esm/plugins/clean-html/helpers/visitor/filters/fill-empty-paragraph.js +1 -1
  117. package/esm/plugins/color/config.js +4 -4
  118. package/esm/plugins/copy-format/copy-format.js +1 -1
  119. package/esm/plugins/delete/delete.js +9 -2
  120. package/esm/plugins/drag-and-drop/drag-and-drop.js +1 -1
  121. package/esm/plugins/drag-and-drop-element/drag-and-drop-element.js +1 -1
  122. package/esm/plugins/enter/helpers/insert-paragraph.js +1 -1
  123. package/esm/plugins/enter/helpers/process-empty-li-leaf.js +2 -2
  124. package/esm/plugins/enter/helpers/wrap-text.js +1 -1
  125. package/esm/plugins/fullsize/fullsize.js +3 -2
  126. package/esm/plugins/iframe/iframe.js +6 -5
  127. package/esm/plugins/image-properties/readers/align.js +6 -5
  128. package/esm/plugins/image-properties/readers/index.js +3 -1
  129. package/esm/plugins/image-properties/ui/ui-image-form.js +2 -1
  130. package/esm/plugins/image-properties/writers/index.js +2 -1
  131. package/esm/plugins/image-properties/writers/link.js +1 -1
  132. package/esm/plugins/indent/config.js +3 -2
  133. package/esm/plugins/indent/indent.js +4 -2
  134. package/esm/plugins/media/media.js +10 -7
  135. package/esm/plugins/mobile/config.js +2 -2
  136. package/esm/plugins/paste-storage/paste-storage.js +5 -5
  137. package/esm/plugins/placeholder/placeholder.js +13 -11
  138. package/esm/plugins/print/print.js +2 -2
  139. package/esm/plugins/resize-cells/resize-cells.js +13 -15
  140. package/esm/plugins/resize-handler/resize-handler.js +3 -4
  141. package/esm/plugins/resizer/resizer.js +11 -10
  142. package/esm/plugins/search/helpers/highlight-text-ranges.js +1 -1
  143. package/esm/plugins/search/ui/search.js +1 -1
  144. package/esm/plugins/select/select.js +2 -2
  145. package/esm/plugins/select-cells/select-cells.js +5 -6
  146. package/esm/plugins/source/editor/engines/ace.js +2 -1
  147. package/esm/plugins/source/editor/engines/area.js +3 -3
  148. package/esm/plugins/source/source.js +2 -2
  149. package/esm/plugins/speech-recognize/speech-recognize.js +1 -1
  150. package/esm/plugins/sticky/sticky.js +1 -1
  151. package/esm/plugins/symbols/config.js +3 -2
  152. package/esm/plugins/symbols/symbols.js +6 -5
  153. package/esm/plugins/tab/cases/on-tab-inside-li.js +2 -2
  154. package/esm/plugins/table/config.js +18 -10
  155. package/esm/plugins/table-keyboard-navigation/table-keyboard-navigation.js +2 -2
  156. package/esm/plugins/wrap-nodes/wrap-nodes.js +2 -2
  157. package/esm/plugins/xpath/xpath.js +2 -3
  158. package/esm/types/index.d.ts +1 -0
  159. package/esm/types/vdom.d.ts +96 -0
  160. package/package.json +1 -1
  161. package/types/core/dom/dom.d.ts +21 -13
  162. package/types/core/helpers/utils/align.d.ts +0 -3
  163. package/types/core/helpers/utils/attr.d.ts +3 -1
  164. package/types/core/helpers/utils/css.d.ts +18 -1
  165. package/types/modules/dialog/dialog.d.ts +6 -0
  166. package/types/types/index.d.ts +1 -0
  167. package/types/types/vdom.d.ts +96 -0
@@ -196,11 +196,13 @@ export class Selection {
196
196
  Number(new Date()) +
197
197
  '_' +
198
198
  String(Math.random()).slice(2);
199
- marker.style.lineHeight = '0';
200
- marker.style.display = 'none';
199
+ css(marker, {
200
+ lineHeight: '0',
201
+ display: 'none'
202
+ });
201
203
  Dom.markTemporary(marker);
202
204
  attr(marker, 'data-' + consts.MARKER_CLASS, atStart ? 'start' : 'end');
203
- marker.appendChild(this.j.createInside.text(consts.INVISIBLE_SPACE));
205
+ Dom.append(marker, this.j.createInside.text(consts.INVISIBLE_SPACE));
204
206
  if (newRange) {
205
207
  if (Dom.isOrContains(this.area, atStart ? newRange.startContainer : newRange.endContainer)) {
206
208
  // Here need do unsafe inserting
@@ -216,9 +218,11 @@ export class Selection {
216
218
  */
217
219
  restore() {
218
220
  let range = false;
219
- const markAttr = (start) => `span[data-${consts.MARKER_CLASS}=${start ? 'start' : 'end'}]`;
220
- const start = this.area.querySelector(markAttr(true));
221
- const end = this.area.querySelector(markAttr(false));
221
+ const markerFilter = (start) => (node) => Dom.isMarker(node) &&
222
+ attr(node, 'data-' + consts.MARKER_CLASS) ===
223
+ (start ? 'start' : 'end');
224
+ const start = Dom.first(this.area, markerFilter(true));
225
+ const end = Dom.first(this.area, markerFilter(false));
222
226
  if (!start) {
223
227
  return;
224
228
  }
@@ -472,7 +476,7 @@ export class Selection {
472
476
  Dom.safeInsertNode(range, node);
473
477
  }
474
478
  else {
475
- this.area.appendChild(node);
479
+ Dom.append(this.area, node);
476
480
  }
477
481
  [
478
482
  () => firstChild === null || firstChild === void 0 ? void 0 : firstChild.previousSibling,
@@ -486,7 +490,7 @@ export class Selection {
486
490
  });
487
491
  }
488
492
  else {
489
- this.area.appendChild(node);
493
+ Dom.append(this.area, node);
490
494
  }
491
495
  const setCursor = (node) => {
492
496
  if (Dom.isBlock(node)) {
@@ -540,7 +544,7 @@ export class Selection {
540
544
  node.innerHTML = html.toString();
541
545
  }
542
546
  else {
543
- node.appendChild(html);
547
+ Dom.append(node, html);
544
548
  }
545
549
  if (!this.j.isEditorMode() &&
546
550
  this.j.e.fire('insertHTML', node.innerHTML) === false) {
@@ -549,9 +553,7 @@ export class Selection {
549
553
  if (!node.lastChild) {
550
554
  return;
551
555
  }
552
- while (node.firstChild) {
553
- fragment.appendChild(node.firstChild);
554
- }
556
+ Dom.moveContent(node, fragment);
555
557
  this.insertNode(fragment, insertCursorAfter, false);
556
558
  // There is no need to use synchronizeValues because you need to apply the changes immediately
557
559
  this.j.__imdSynchronizeValues();
@@ -566,7 +568,7 @@ export class Selection {
566
568
  insertImage(url, styles = null, defaultWidth = null) {
567
569
  const image = isString(url) ? this.j.createInside.element('img') : url;
568
570
  if (isString(url)) {
569
- image.setAttribute('src', url);
571
+ attr(image, 'src', url);
570
572
  }
571
573
  if (defaultWidth != null) {
572
574
  let dw = defaultWidth.toString();
@@ -584,8 +586,10 @@ export class Selection {
584
586
  const onload = () => {
585
587
  if (image.naturalHeight < image.offsetHeight ||
586
588
  image.naturalWidth < image.offsetWidth) {
587
- image.style.width = '';
588
- image.style.height = '';
589
+ css(image, {
590
+ width: '',
591
+ height: ''
592
+ });
589
593
  }
590
594
  image.removeEventListener('load', onload);
591
595
  };
@@ -674,7 +678,7 @@ export class Selection {
674
678
  }
675
679
  else {
676
680
  const currentB = this.j.createInside.text(INVISIBLE_SPACE);
677
- current.appendChild(currentB);
681
+ Dom.append(current, currentB);
678
682
  current = currentB;
679
683
  }
680
684
  }
@@ -825,7 +829,7 @@ export class Selection {
825
829
  if (!start) {
826
830
  const fakeNode = this.j.createInside.text(consts.INVISIBLE_SPACE);
827
831
  if (!Dom.isTag(last, INSEPARABLE_TAGS)) {
828
- last.appendChild(fakeNode);
832
+ Dom.append(last, fakeNode);
829
833
  last = fakeNode;
830
834
  }
831
835
  else {
@@ -893,7 +897,7 @@ export class Selection {
893
897
  const range = sel.getRangeAt(0);
894
898
  const clonedSelection = range.cloneContents();
895
899
  const div = this.j.createInside.div();
896
- div.appendChild(clonedSelection);
900
+ Dom.append(div, clonedSelection);
897
901
  return div.innerHTML;
898
902
  }
899
903
  return '';
@@ -1033,11 +1037,10 @@ export class Selection {
1033
1037
  return toArray(node.childNodes).some(child => this.__isOrContainsBlock(child));
1034
1038
  }
1035
1039
  __wrapRunInFont(run) {
1036
- var _a;
1037
1040
  const font = this.j.createInside.element('font');
1038
1041
  const [first] = run;
1039
- (_a = first.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(font, first);
1040
- run.forEach(node => font.appendChild(node));
1042
+ Dom.before(first, font);
1043
+ run.forEach(node => Dom.append(font, node));
1041
1044
  return font;
1042
1045
  }
1043
1046
  /**
@@ -1048,7 +1051,7 @@ export class Selection {
1048
1051
  const font = this.jodit.createInside.element('font', INVISIBLE_SPACE);
1049
1052
  this.insertNode(font, false, false);
1050
1053
  if (fakes && fakes[0]) {
1051
- font.appendChild(fakes[0]);
1054
+ Dom.append(font, fakes[0]);
1052
1055
  }
1053
1056
  yield font;
1054
1057
  Dom.unwrap(font);
@@ -1183,7 +1186,7 @@ export class Selection {
1183
1186
  try {
1184
1187
  clearEmpties(fragment);
1185
1188
  clearEmpties(currentBox);
1186
- currentBox.parentNode.insertBefore(fragment, currentBox);
1189
+ Dom.before(currentBox, fragment);
1187
1190
  if (!edge && cursorOnTheRight && (br === null || br === void 0 ? void 0 : br.parentNode)) {
1188
1191
  const range = this.createRange();
1189
1192
  range.setStartBefore(br);
@@ -1197,9 +1200,9 @@ export class Selection {
1197
1200
  }
1198
1201
  // After splitting some part can be empty
1199
1202
  const fillFakeParent = (fake) => {
1200
- var _a, _b, _c;
1201
- if (((_a = fake === null || fake === void 0 ? void 0 : fake.parentNode) === null || _a === void 0 ? void 0 : _a.firstChild) === ((_b = fake === null || fake === void 0 ? void 0 : fake.parentNode) === null || _b === void 0 ? void 0 : _b.lastChild)) {
1202
- (_c = fake === null || fake === void 0 ? void 0 : fake.parentNode) === null || _c === void 0 ? void 0 : _c.appendChild(br.cloneNode());
1203
+ const parent = fake === null || fake === void 0 ? void 0 : fake.parentNode;
1204
+ if (parent && parent.firstChild === parent.lastChild) {
1205
+ Dom.append(parent, br.cloneNode());
1203
1206
  }
1204
1207
  };
1205
1208
  fillFakeParent(prevFake);
@@ -15,6 +15,7 @@ import { isSuitElement } from "./is-suit-element.js";
15
15
  * @private
16
16
  */
17
17
  export function getSuitParent(style, node, root) {
18
+ var _a;
18
19
  const { parentNode } = node;
19
20
  if (parentNode === root ||
20
21
  !Dom.isHTMLElement(parentNode) ||
@@ -28,6 +29,15 @@ export function getSuitParent(style, node, root) {
28
29
  !Dom.isBlock(parentNode)) {
29
30
  return getSuitParent(style, parentNode, root);
30
31
  }
32
+ // <li>|test|</li> => apply the CSS style to the <li> itself, so the
33
+ // list marker (bullet/number) gets the same color and size as the text.
34
+ // Only for pure style commits: bold/italic keep wrapping the content.
35
+ // See #1460
36
+ if (Dom.isTag(parentNode, 'li') &&
37
+ !style.isElementCommit &&
38
+ ((_a = style.options.attributes) === null || _a === void 0 ? void 0 : _a.style)) {
39
+ return parentNode;
40
+ }
31
41
  if (isSuitElement(style, parentNode, false) &&
32
42
  (!Dom.isBlock(parentNode) || style.elementIsBlock)) {
33
43
  return parentNode;
@@ -6,6 +6,7 @@
6
6
  import { size } from "../../../helpers/size/object-size.js";
7
7
  import { attr } from "../../../helpers/utils/index.js";
8
8
  import { assert } from "../../../helpers/utils/assert.js";
9
+ import { attrRaw } from "../../../helpers/utils/attr.js";
9
10
  import { hasSameStyle } from "./has-same-style.js";
10
11
  /**
11
12
  * Checks that every attribute from `attrs` is present on the element with
@@ -30,6 +31,8 @@ export function isSameAttributes(elm, attrs) {
30
31
  }
31
32
  export function elementsEqualAttributes(elm1, elm2) {
32
33
  return (elm1.attributes.length === elm2.attributes.length &&
33
- Array.from(elm1.attributes).every(attr => elm2.hasAttribute(attr.name) &&
34
- elm2.getAttribute(attr.name) === attr.value));
34
+ Array.from(elm1.attributes).every(
35
+ // `attrRaw` on purpose: the comparison must use the exact
36
+ // attribute name from the live list, without `attr()` name mangling
37
+ attr => attrRaw(elm2, attr.name) === attr.value));
35
38
  }
@@ -9,9 +9,8 @@ import { getContainer } from "../../../global.js";
9
9
  import { isBoolean, isNumber, isPlainObject, isString } from "../../../helpers/checker/index.js";
10
10
  import { normalizeCssValue } from "../../../helpers/normalize/normalize-css-value.js";
11
11
  import { size } from "../../../helpers/size/object-size.js";
12
- import { kebabCase } from "../../../helpers/string/kebab-case.js";
13
12
  import { assert, attr } from "../../../helpers/utils/index.js";
14
- import { css } from "../../../helpers/utils/css.js";
13
+ import { css, cssInline } from "../../../helpers/utils/css.js";
15
14
  import { dataBind } from "../../../helpers/utils/data-bind.js";
16
15
  import { _PREFIX, CHANGE, UNSET, UNWRAP } from "../constants.js";
17
16
  const tak = 'toggleAttributes';
@@ -47,7 +46,7 @@ export function toggleAttributes(commitStyle, elm, jodit, mode, dry = false) {
47
46
  function toggleStyle(commitStyle, jodit, style, elm, dry, mode) {
48
47
  assert(isPlainObject(style) && size(style), 'Style must be an object');
49
48
  Object.keys(style).forEach((rule) => {
50
- const inlineValue = elm.style.getPropertyValue(kebabCase(rule));
49
+ const inlineValue = cssInline(elm, rule);
51
50
  const newValue = style[rule];
52
51
  if (inlineValue === '' && newValue == null) {
53
52
  return;
@@ -140,8 +139,8 @@ function getShadowRoot(jodit) {
140
139
  position: 'absolute',
141
140
  border: 0
142
141
  });
143
- iframe.src = 'about:blank';
144
- container.appendChild(iframe);
142
+ attr(iframe, 'src', 'about:blank');
143
+ Dom.append(container, iframe);
145
144
  const doc = (_a = iframe.contentWindow) === null || _a === void 0 ? void 0 : _a.document;
146
145
  const shadowRoot = !doc ? jodit.od.body : doc.body;
147
146
  dataBind(jodit, 'shadowRoot', shadowRoot);
@@ -157,11 +156,11 @@ function getNativeCSSValue(jodit, elm, key) {
157
156
  // browser default black) is recognised. Without this, applying black after
158
157
  // the default font color was changed was wrongly treated as a no-op (#1311).
159
158
  const wrapper = jodit.create.element('div');
160
- wrapper.style.color = css(jodit.editor, 'color');
159
+ css(wrapper, 'color', css(jodit.editor, 'color'));
161
160
  const newElm = jodit.create.element(elm.tagName.toLowerCase());
162
- newElm.style.cssText = elm.style.cssText;
163
- wrapper.appendChild(newElm);
164
- root.appendChild(wrapper);
161
+ attr(newElm, 'style', attr(elm, 'style'));
162
+ Dom.append(wrapper, newElm);
163
+ Dom.append(root, wrapper);
165
164
  const result = css(newElm, key);
166
165
  Dom.safeRemove(wrapper);
167
166
  return result;
@@ -40,12 +40,12 @@ export function wrapUnwrappedText(style, elm, jodit) {
40
40
  range.setEndAfter(end);
41
41
  const fragment = range.extractContents();
42
42
  const wrapper = ci.element(style.element);
43
- wrapper.appendChild(fragment);
43
+ Dom.append(wrapper, fragment);
44
44
  Dom.safeInsertNode(range, wrapper);
45
45
  if (style.elementIsBlock) {
46
46
  if (Dom.isEmpty(wrapper) &&
47
47
  !Dom.isTag(wrapper.firstElementChild, 'br')) {
48
- wrapper.appendChild(ci.element('br'));
48
+ Dom.append(wrapper, ci.element('br'));
49
49
  }
50
50
  }
51
51
  return wrapper;
@@ -3,18 +3,26 @@
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 { toArray } from "../helpers/array/to-array.js";
6
+ import { Dom } from "../dom/dom.js";
7
7
  export class Elms {
8
8
  /**
9
9
  * Return element with BEM class name
10
10
  */
11
11
  getElm(elementName) {
12
- return this.container.querySelector(`.${this.getFullElName(elementName)}`);
12
+ const className = this.getFullElName(elementName);
13
+ return Dom.first(this.container, node => Dom.isHTMLElement(node) && node.classList.contains(className));
13
14
  }
14
15
  /**
15
16
  * Return elements with BEM class name
16
17
  */
17
18
  getElms(elementName) {
18
- return toArray(this.container.querySelectorAll(`.${this.getFullElName(elementName)}`));
19
+ const className = this.getFullElName(elementName);
20
+ const result = [];
21
+ Dom.each(this.container, node => {
22
+ if (Dom.isHTMLElement(node) && node.classList.contains(className)) {
23
+ result.push(node);
24
+ }
25
+ });
26
+ return result;
19
27
  }
20
28
  }
@@ -142,7 +142,7 @@ let UIButton = class UIButton extends UIElement {
142
142
  }
143
143
  Dom.detach(this.icon);
144
144
  const iconElement = Icon.makeIcon(this.j, this.state.icon);
145
- iconElement && this.icon.appendChild(iconElement);
145
+ iconElement && Dom.append(this.icon, iconElement);
146
146
  }
147
147
  /**
148
148
  * Set focus on an element
@@ -168,8 +168,8 @@ let UIButton = class UIButton extends UIElement {
168
168
  });
169
169
  const icon = this.j.c.span(cn + '__icon');
170
170
  const text = this.j.c.span(cn + '__text');
171
- button.appendChild(icon);
172
- button.appendChild(text);
171
+ Dom.append(button, icon);
172
+ Dom.append(button, text);
173
173
  return button;
174
174
  }
175
175
  constructor(jodit, state) {
@@ -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 "../../../decorators/component/component.js";
17
+ import { Dom } from "../../../dom/dom.js";
17
18
  import { assert } from "../../../helpers/utils/assert.js";
18
19
  import { UIButton } from "../button/button.js";
19
20
  import { UIGroup } from "../../group/group.js";
@@ -33,7 +34,7 @@ let UIButtonGroup = class UIButtonGroup extends UIGroup {
33
34
  appendChildToContainer(childContainer) {
34
35
  const options = this.getElm('options');
35
36
  assert(options != null, 'Options does not exist');
36
- options.appendChild(childContainer);
37
+ Dom.append(options, childContainer);
37
38
  }
38
39
  constructor(jodit, options = {
39
40
  radio: true
@@ -64,7 +64,7 @@ let UITooltip = UITooltip_1 = class UITooltip extends UIElement {
64
64
  }
65
65
  __onAttach(container) {
66
66
  // TODO Move it inside __show method. Now it is here because testcase failed with capturing
67
- getContainer(this.j, UITooltip_1).appendChild(this.container);
67
+ Dom.append(getContainer(this.j, UITooltip_1), this.container);
68
68
  this.__attachedContainers.add(container);
69
69
  this.__attachedContainers.add(this.j.container);
70
70
  this.j.e
@@ -174,7 +174,7 @@ let UITooltip = UITooltip_1 = class UITooltip extends UIElement {
174
174
  if (this.__isOpened) {
175
175
  this.__isOpened = false;
176
176
  this.setMod('visible', false);
177
- this.getElm('content').innerHTML = '';
177
+ Dom.detach(this.getElm('content'));
178
178
  css(this.container, {
179
179
  left: -5000
180
180
  });
@@ -98,7 +98,7 @@ let UIElement = UIElement_1 = class UIElement extends ViewComponent {
98
98
  * Append container to element
99
99
  */
100
100
  appendTo(element) {
101
- element.appendChild(this.container);
101
+ Dom.append(element, this.container);
102
102
  return this;
103
103
  }
104
104
  /**
@@ -16,6 +16,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
16
16
  var UITextArea_1;
17
17
  import { watch } from "../../../../decorators/index.js";
18
18
  import { component } from "../../../../decorators/component/component.js";
19
+ import { css } from "../../../../helpers/utils/css.js";
19
20
  import { UIInput } from "../input/input.js";
20
21
  let UITextArea = UITextArea_1 = class UITextArea extends UIInput {
21
22
  /** @override */
@@ -31,12 +32,12 @@ let UITextArea = UITextArea_1 = class UITextArea extends UIInput {
31
32
  this.state = { ...UITextArea_1.defaultState };
32
33
  Object.assign(this.state, state);
33
34
  if (this.state.resizable === false) {
34
- this.nativeInput.style.resize = 'none';
35
+ css(this.nativeInput, 'resize', 'none');
35
36
  }
36
37
  }
37
38
  onChangeStateSize() {
38
39
  const { size, resizable } = this.state;
39
- this.nativeInput.style.resize = resizable ? 'auto' : 'none';
40
+ css(this.nativeInput, 'resize', resizable ? 'auto' : 'none');
40
41
  this.nativeInput.rows = size !== null && size !== void 0 ? size : 5;
41
42
  }
42
43
  };
@@ -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 "../../../../decorators/component/component.js";
17
+ import { Dom } from "../../../../dom/dom.js";
17
18
  import { UIButton } from "../../../button/button/button.js";
18
19
  import { UIInput } from "../input/input.js";
19
20
  let UIFileInput = class UIFileInput extends UIInput {
@@ -35,7 +36,7 @@ let UIFileInput = class UIFileInput extends UIInput {
35
36
  const { nativeInput } = this;
36
37
  nativeInput.classList.add(this.getFullElName('input'));
37
38
  container.classList.add(this.componentName);
38
- container.appendChild(nativeInput);
39
+ Dom.append(container, nativeInput);
39
40
  return container;
40
41
  }
41
42
  createNativeInput(options) {
@@ -83,7 +83,7 @@ let UIInput = UIInput_1 = class UIInput extends UIElement {
83
83
  }
84
84
  else {
85
85
  this.__errorBox.innerText = this.j.i18n(value, this.j.i18n(this.state.label || ''));
86
- this.container.appendChild(this.__errorBox);
86
+ Dom.append(this.container, this.__errorBox);
87
87
  }
88
88
  }
89
89
  get value() {
@@ -125,11 +125,11 @@ let UIInput = UIInput_1 = class UIInput extends UIElement {
125
125
  __markInputInvalid() {
126
126
  var _a, _b, _c, _d;
127
127
  if (this.error) {
128
- this.nativeInput.setAttribute('aria-invalid', 'true');
128
+ attr(this.nativeInput, 'aria-invalid', 'true');
129
129
  (_b = (_a = this.nativeInput).setCustomValidity) === null || _b === void 0 ? void 0 : _b.call(_a, this.error);
130
130
  }
131
131
  else {
132
- this.nativeInput.removeAttribute('aria-invalid');
132
+ attr(this.nativeInput, 'aria-invalid', null);
133
133
  (_d = (_c = this.nativeInput).setCustomValidity) === null || _d === void 0 ? void 0 : _d.call(_c, '');
134
134
  }
135
135
  }
@@ -142,8 +142,8 @@ let UIInput = UIInput_1 = class UIInput extends UIElement {
142
142
  }
143
143
  const { nativeInput } = this;
144
144
  nativeInput.classList.add(this.getFullElName('input'));
145
- this.wrapper.appendChild(nativeInput);
146
- container.appendChild(this.wrapper);
145
+ Dom.append(this.wrapper, nativeInput);
146
+ Dom.append(container, this.wrapper);
147
147
  attr(nativeInput, 'dir', this.j.o.direction || 'auto');
148
148
  return container;
149
149
  }
@@ -81,7 +81,7 @@ let UIGroup = UIGroup_1 = class UIGroup extends UIElement {
81
81
  if (distElm == null) {
82
82
  throw new Error('Element does not exist');
83
83
  }
84
- distElm.appendChild(elm.container);
84
+ Dom.append(distElm, elm.container);
85
85
  }
86
86
  else {
87
87
  this.appendChildToContainer(elm.container, index);
@@ -99,14 +99,14 @@ let UIGroup = UIGroup_1 = class UIGroup extends UIElement {
99
99
  * Allow set another container for the box of all children
100
100
  */
101
101
  appendChildToContainer(childContainer, index) {
102
- if (index === undefined ||
103
- index < 0 ||
104
- index > this.elements.length - 1 ||
105
- this.container.children[index] == null) {
106
- this.container.appendChild(childContainer);
102
+ const ref = index === undefined || index < 0 || index > this.elements.length - 1
103
+ ? null
104
+ : this.container.children[index];
105
+ if (ref == null) {
106
+ Dom.append(this.container, childContainer);
107
107
  }
108
108
  else {
109
- this.container.insertBefore(childContainer, this.container.children[index]);
109
+ Dom.before(ref, childContainer);
110
110
  }
111
111
  }
112
112
  /**
@@ -80,9 +80,9 @@ export class Icon {
80
80
  }
81
81
  if (iconElement) {
82
82
  iconElement.classList.add('jodit-icon');
83
- iconElement.style.fill = fill;
83
+ css(iconElement, 'fill', fill);
84
84
  if (scale != null) {
85
- iconElement.style.transform = `scale(${scale})`;
85
+ css(iconElement, 'transform', `scale(${scale})`);
86
86
  }
87
87
  jodit.o.cache &&
88
88
  this.__cache.set(cacheKey, iconElement.cloneNode(true));
@@ -19,6 +19,7 @@ import { Dom } from "../../dom/dom.js";
19
19
  import { eventEmitter, getContainer } from "../../global.js";
20
20
  import { attr, css, getFixedPositionOffset, isFunction, isString, kebabCase, markOwner, position, ucfirst } from "../../helpers/index.js";
21
21
  import { assert } from "../../helpers/utils/assert.js";
22
+ import { cssInline } from "../../helpers/utils/css.js";
22
23
  import { UIElement } from "../element.js";
23
24
  import { UIGroup } from "../group/group.js";
24
25
  const EVENTS_FOR_AUTOCLOSE = [
@@ -35,7 +36,7 @@ export class Popup extends UIGroup {
35
36
  appendChildToContainer(childContainer) {
36
37
  const content = this.getElm('content');
37
38
  assert(content, 'Content element should exist');
38
- content.appendChild(childContainer);
39
+ Dom.append(content, childContainer);
39
40
  }
40
41
  updateParentElement(target) {
41
42
  if (target !== this && Component.isInstanceOf(target, Popup)) {
@@ -85,12 +86,12 @@ export class Popup extends UIGroup {
85
86
  ? getBound
86
87
  : this.getKeepBound(getBound);
87
88
  if (parentContainer) {
88
- parentContainer.appendChild(this.container);
89
+ Dom.append(parentContainer, this.container);
89
90
  }
90
91
  else {
91
92
  const popupContainer = getContainer(this.jodit, Popup);
92
93
  if (parentContainer !== this.container.parentElement) {
93
- popupContainer.appendChild(this.container);
94
+ Dom.append(popupContainer, this.container);
94
95
  }
95
96
  }
96
97
  this.updatePosition();
@@ -99,11 +100,11 @@ export class Popup extends UIGroup {
99
100
  return this;
100
101
  }
101
102
  __calculateZIndex() {
102
- if (this.container.style.zIndex) {
103
+ if (cssInline(this.container, 'zIndex')) {
103
104
  return;
104
105
  }
105
106
  const checkView = (view) => {
106
- const zIndex = view.container.style.zIndex || view.o.zIndex;
107
+ const zIndex = cssInline(view.container, 'zIndex') || view.o.zIndex;
107
108
  if (zIndex) {
108
109
  this.setZIndex(1 + parseInt(zIndex.toString(), 10));
109
110
  return true;
@@ -119,8 +120,9 @@ export class Popup extends UIGroup {
119
120
  if (checkView(pe.j)) {
120
121
  return;
121
122
  }
122
- if (pe.container.style.zIndex) {
123
- this.setZIndex(1 + parseInt(pe.container.style.zIndex.toString(), 10));
123
+ const parentZIndex = cssInline(pe.container, 'zIndex');
124
+ if (parentZIndex) {
125
+ this.setZIndex(1 + parseInt(parentZIndex.toString(), 10));
124
126
  return;
125
127
  }
126
128
  if (!pe.parentElement && pe.container.parentElement) {
@@ -325,7 +327,7 @@ export class Popup extends UIGroup {
325
327
  * Set ZIndex
326
328
  */
327
329
  setZIndex(index) {
328
- this.container.style.zIndex = index.toString();
330
+ css(this.container, 'zIndex', index.toString());
329
331
  }
330
332
  constructor(jodit, smart = true) {
331
333
  super(jodit);
@@ -27,7 +27,7 @@ export class ProgressBar extends UIElement {
27
27
  */
28
28
  show() {
29
29
  const container = this.j.workplace || this.j.container;
30
- container.appendChild(this.container);
30
+ Dom.append(container, this.container);
31
31
  return this;
32
32
  }
33
33
  hide() {
@@ -35,7 +35,7 @@ export class ProgressBar extends UIElement {
35
35
  return this;
36
36
  }
37
37
  progress(percentage) {
38
- this.container.style.width = percentage.toFixed(2) + '%';
38
+ css(this.container, 'width', percentage.toFixed(2) + '%');
39
39
  return this;
40
40
  }
41
41
  showFileUploadAnimation(from, to) {
@@ -59,10 +59,9 @@ export class ProgressBar extends UIElement {
59
59
  left: pos.left + start.x,
60
60
  top: pos.top + start.y
61
61
  });
62
- box.appendChild(el);
62
+ Dom.append(box, el);
63
63
  this.__animationElement = el;
64
64
  // Force reflow before starting transition
65
- // eslint-disable-next-line no-unused-expressions
66
65
  el.offsetWidth;
67
66
  css(el, {
68
67
  left: pos.left + end.x,
@@ -50,7 +50,7 @@ export class ViewWithToolbar extends View {
50
50
  anchor = anchor.nextElementSibling;
51
51
  }
52
52
  if (anchor !== box) {
53
- this.container.insertBefore(box, anchor);
53
+ anchor ? Dom.before(anchor, box) : Dom.append(this.container, box);
54
54
  }
55
55
  }
56
56
  /**
@@ -246,7 +246,7 @@ let View = View_1 = class View extends Component {
246
246
  }
247
247
  /** Add some element to box */
248
248
  addDisclaimer(elm) {
249
- this.container.appendChild(elm);
249
+ Dom.append(this.container, elm);
250
250
  }
251
251
  /**
252
252
  * Call before destruct