jodit 4.12.22 → 4.12.24

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 (97) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/es2015/jodit.css +1 -1
  3. package/es2015/jodit.fat.min.js +11 -11
  4. package/es2015/jodit.js +353 -86
  5. package/es2015/jodit.min.js +11 -11
  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 +11 -11
  13. package/es2018/jodit.min.js +15 -15
  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 +13 -13
  18. package/es2021/jodit.js +343 -85
  19. package/es2021/jodit.min.js +13 -13
  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 +14 -14
  28. package/es2021.en/jodit.js +321 -63
  29. package/es2021.en/jodit.min.js +13 -13
  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 +443 -153
  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 +30 -0
  51. package/esm/core/component/view-component.js +8 -0
  52. package/esm/core/constants.js +1 -1
  53. package/esm/core/helpers/checker/is-html-from-word.d.ts +1 -1
  54. package/esm/core/helpers/checker/is-html-from-word.js +12 -1
  55. package/esm/core/selection/style/api/wrap.js +18 -3
  56. package/esm/core/ui/popup/popup.js +4 -1
  57. package/esm/jodit.js +12 -0
  58. package/esm/modules/image-editor/image-editor.js +5 -0
  59. package/esm/modules/toolbar/button/content.d.ts +6 -0
  60. package/esm/modules/toolbar/button/content.js +26 -1
  61. package/esm/modules/uploader/helpers/send-files.js +9 -0
  62. package/esm/plugins/add-new-line/add-new-line.js +4 -1
  63. package/esm/plugins/ai-assistant/ai-assistant.js +7 -1
  64. package/esm/plugins/backspace/backspace.js +7 -3
  65. package/esm/plugins/backspace/cases/check-join-neighbors.js +15 -1
  66. package/esm/plugins/backspace/cases/index.d.ts +19 -3
  67. package/esm/plugins/backspace/cases/index.js +18 -13
  68. package/esm/plugins/backspace/config.d.ts +15 -0
  69. package/esm/plugins/clean-html/clean-html.d.ts +8 -0
  70. package/esm/plugins/clean-html/clean-html.js +16 -0
  71. package/esm/plugins/clean-html/config.d.ts +9 -0
  72. package/esm/plugins/clean-html/config.js +1 -0
  73. package/esm/plugins/color/color.js +21 -21
  74. package/esm/plugins/font/config.js +19 -0
  75. package/esm/plugins/inline-popup/inline-popup.d.ts +7 -0
  76. package/esm/plugins/inline-popup/inline-popup.js +18 -2
  77. package/esm/plugins/link/config.d.ts +6 -0
  78. package/esm/plugins/link/config.js +1 -0
  79. package/esm/plugins/link/link.js +8 -1
  80. package/esm/plugins/link/template.js +10 -1
  81. package/esm/plugins/paste/config.js +11 -2
  82. package/esm/plugins/search/ui/search.js +22 -12
  83. package/esm/plugins/select-cells/select-cells.d.ts +1 -1
  84. package/esm/plugins/select-cells/select-cells.js +39 -8
  85. package/esm/types/uploader.d.ts +23 -0
  86. package/package.json +1 -1
  87. package/types/config.d.ts +30 -0
  88. package/types/core/helpers/checker/is-html-from-word.d.ts +1 -1
  89. package/types/modules/toolbar/button/content.d.ts +6 -0
  90. package/types/plugins/backspace/cases/index.d.ts +19 -3
  91. package/types/plugins/backspace/config.d.ts +15 -0
  92. package/types/plugins/clean-html/clean-html.d.ts +8 -0
  93. package/types/plugins/clean-html/config.d.ts +9 -0
  94. package/types/plugins/inline-popup/inline-popup.d.ts +7 -0
  95. package/types/plugins/link/config.d.ts +6 -0
  96. package/types/plugins/select-cells/select-cells.d.ts +1 -1
  97. package/types/types/uploader.d.ts +23 -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.12.22
4
+ * Version: v4.12.24
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -1698,6 +1698,14 @@ class ViewComponent extends _component__WEBPACK_IMPORTED_MODULE_1__.Component {
1698
1698
  * Attach component to View
1699
1699
  */ setParentView(jodit) {
1700
1700
  this.jodit = jodit;
1701
+ // Inherit the owner window from the parent view — for an editor
1702
+ // created with a custom `ownerWindow` (e.g. inside an iframe) the
1703
+ // component default (the global `window`) is wrong: outside-click
1704
+ // handlers of dropdowns/popups listened to the wrong window. See
1705
+ // https://github.com/xdan/jodit/issues/965
1706
+ if (jodit.ow) {
1707
+ this.ownerWindow = jodit.ow;
1708
+ }
1701
1709
  jodit.components.add(this);
1702
1710
  return this;
1703
1711
  }
@@ -1802,7 +1810,7 @@ __webpack_require__.r(__webpack_exports__);
1802
1810
  * ```
1803
1811
  * @packageDocumentation
1804
1812
  * @module constants
1805
- */ const APP_VERSION = "4.12.22";
1813
+ */ const APP_VERSION = "4.12.24";
1806
1814
  // prettier-ignore
1807
1815
  const ES = "es2021";
1808
1816
  const IS_ES_MODERN = true;
@@ -5170,9 +5178,15 @@ function isFastEqual(a, b) {
5170
5178
  */ /**
5171
5179
  * @module helpers/checker
5172
5180
  */ /**
5173
- * Detect if string is HTML from MS Word or Excel
5181
+ * Detect if string is HTML from MS Word, Excel or LibreOffice/OpenOffice
5174
5182
  */ function isHtmlFromWord(data) {
5175
- return data.search(/<meta.*?Microsoft Excel\s[\d].*?>/) !== -1 || data.search(/<meta.*?Microsoft Word\s[\d].*?>/) !== -1 || data.search(/style="[^"]*mso-/) !== -1 && data.search(/<font/) !== -1;
5183
+ return data.search(/<meta.*?Microsoft Excel\s[\d].*?>/) !== -1 || data.search(/<meta.*?Microsoft Word\s[\d].*?>/) !== -1 || // `<meta name=ProgId content=Word.Document>` attribute values are
5184
+ // unquoted in the raw Word clipboard fragment
5185
+ data.search(/<meta[^>]*?ProgId[^>]*?(Word|Excel)\./i) !== -1 || // LibreOffice/OpenOffice Writer & Calc
5186
+ data.search(/<meta[^>]*?(LibreOffice|OpenOffice)/i) !== -1 || // Office namespaces on the root element of the clipboard fragment
5187
+ data.search(/urn:schemas-microsoft-com:office:(word|excel)/) !== -1 || // `class=MsoNormal` and friends (unquoted/quoted)
5188
+ data.search(/<\w[^>]*\sclass=("|')?Mso/) !== -1 || // the raw Word clipboard uses SINGLE quotes: style='mso-…'
5189
+ data.search(/style='[^']*mso-/) !== -1 || data.search(/style="[^"]*mso-/) !== -1 && data.search(/<font/) !== -1;
5176
5190
  }
5177
5191
 
5178
5192
 
@@ -12314,8 +12328,9 @@ function toggleAttribute(jodit, value, elm, key, dry, mode) {
12314
12328
  /* harmony export */ });
12315
12329
  /* harmony import */ var jodit_core_dom__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27795);
12316
12330
  /* harmony import */ var jodit_core_helpers_utils_attr__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7909);
12317
- /* harmony import */ var _list_wrap_list__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(97110);
12318
- /* harmony import */ var _wrap_unwrapped_text__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(83335);
12331
+ /* harmony import */ var jodit_core_helpers_utils_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(80991);
12332
+ /* harmony import */ var _list_wrap_list__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(97110);
12333
+ /* harmony import */ var _wrap_unwrapped_text__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(83335);
12319
12334
  /*!
12320
12335
  * Jodit Editor (https://xdsoft.net/jodit/)
12321
12336
  * Released under MIT see LICENSE.txt in the project root for license information.
@@ -12324,12 +12339,29 @@ function toggleAttribute(jodit, value, elm, key, dry, mode) {
12324
12339
 
12325
12340
 
12326
12341
 
12342
+
12327
12343
  /**
12328
12344
  * Replaces the parent tag with the applicable one, or wraps the text and also replaces the tag
12329
12345
  * @private
12330
12346
  */ function wrap(commitStyle, font, jodit) {
12331
12347
  const wrapper = findOrCreateWrapper(commitStyle, font, jodit);
12332
- return commitStyle.elementIsList ? (0,_list_wrap_list__WEBPACK_IMPORTED_MODULE_2__.wrapList)(commitStyle, wrapper, jodit) : jodit_core_dom__WEBPACK_IMPORTED_MODULE_0__.Dom.replace(wrapper, commitStyle.element, jodit.createInside, true);
12348
+ if (commitStyle.elementIsList) {
12349
+ return (0,_list_wrap_list__WEBPACK_IMPORTED_MODULE_3__.wrapList)(commitStyle, wrapper, jodit);
12350
+ }
12351
+ const newWrapper = jodit_core_dom__WEBPACK_IMPORTED_MODULE_0__.Dom.replace(wrapper, commitStyle.element, jodit.createInside, true);
12352
+ if (commitStyle.elementIsBlock) {
12353
+ // Inline font styles left over from pasted content visually override
12354
+ // the new block format — e.g. an h2 with `font-weight: normal;
12355
+ // font-size: 24px` does not look like a heading at all, so the
12356
+ // command seems to do nothing. See
12357
+ // https://github.com/xdan/jodit/issues/1063
12358
+ (0,jodit_core_helpers_utils_css__WEBPACK_IMPORTED_MODULE_2__.css)(newWrapper, 'fontSize', null);
12359
+ (0,jodit_core_helpers_utils_css__WEBPACK_IMPORTED_MODULE_2__.css)(newWrapper, 'fontWeight', null);
12360
+ if (!(0,jodit_core_helpers_utils_attr__WEBPACK_IMPORTED_MODULE_1__.attr)(newWrapper, 'style')) {
12361
+ (0,jodit_core_helpers_utils_attr__WEBPACK_IMPORTED_MODULE_1__.attr)(newWrapper, 'style', null);
12362
+ }
12363
+ }
12364
+ return newWrapper;
12333
12365
  }
12334
12366
  const WRAP_NODES = new Set([
12335
12367
  'td',
@@ -12350,7 +12382,7 @@ const WRAP_NODES = new Set([
12350
12382
  if (box) {
12351
12383
  return box;
12352
12384
  }
12353
- return (0,_wrap_unwrapped_text__WEBPACK_IMPORTED_MODULE_3__.wrapUnwrappedText)(commitStyle, font, jodit);
12385
+ return (0,_wrap_unwrapped_text__WEBPACK_IMPORTED_MODULE_4__.wrapUnwrappedText)(commitStyle, font, jodit);
12354
12386
  }
12355
12387
  (0,jodit_core_helpers_utils_attr__WEBPACK_IMPORTED_MODULE_1__.attr)(font, 'size', null);
12356
12388
  return font;
@@ -15946,7 +15978,9 @@ class Popup extends jodit_core_ui_group_group__WEBPACK_IMPORTED_MODULE_9__.UIGro
15946
15978
  * Calculate static bound for point
15947
15979
  */ getKeepBound(getBound) {
15948
15980
  const oldBound = getBound();
15949
- const elmUnderCursor = this.od.elementFromPoint(oldBound.left, oldBound.top);
15981
+ // Inside Shadow DOM `document.elementFromPoint` returns the shadow
15982
+ // host, so the lookup must start from the shadow root
15983
+ const elmUnderCursor = (this.j.o.shadowRoot ?? this.od).elementFromPoint(oldBound.left, oldBound.top);
15950
15984
  if (!elmUnderCursor) {
15951
15985
  return getBound;
15952
15986
  }
@@ -17614,6 +17648,16 @@ class Jodit extends jodit_modules__WEBPACK_IMPORTED_MODULE_9__.ViewWithToolbar {
17614
17648
  const init = ()=>{
17615
17649
  if (opt.enableDragAndDropFileToEditor && opt.uploader && (opt.uploader.url || opt.uploader.insertImageAsBase64URI)) {
17616
17650
  this.uploader.bind(this.editor);
17651
+ } else if (!opt.enableDragAndDropFileToEditor) {
17652
+ // Without a bound uploader nobody cancels a file drop, and
17653
+ // Firefox inserts the dropped image natively — the option
17654
+ // must mean "do nothing". See
17655
+ // https://github.com/xdan/jodit/issues/1077
17656
+ this.e.on(editor, 'drop', (e)=>{
17657
+ if (e.dataTransfer?.files?.length) {
17658
+ e.preventDefault();
17659
+ }
17660
+ });
17617
17661
  }
17618
17662
  // in initEditor - the editor could change
17619
17663
  if (!this.__elementToPlace.get(this.editor)) {
@@ -21955,12 +21999,17 @@ class ImageEditor extends jodit_core_component__WEBPACK_IMPORTED_MODULE_2__.View
21955
21999
  self.j.alert('The name should not be empty');
21956
22000
  return false;
21957
22001
  }
22002
+ self.j.e.fire('afterImageEditorSave', data, name);
21958
22003
  self.onSave(name, data, self.hide, (e)=>{
21959
22004
  self.j.alert(e.message);
21960
22005
  });
21961
22006
  });
21962
22007
  break;
21963
22008
  case self.buttons.save:
22009
+ // Notify listeners that a crop/resize was applied,
22010
+ // passing the action box (action + box dimensions).
22011
+ // See https://github.com/xdan/jodit/issues/820
22012
+ self.j.e.fire('afterImageEditorSave', data);
21964
22013
  self.onSave(undefined, data, self.hide, (e)=>{
21965
22014
  self.j.alert(e.message);
21966
22015
  });
@@ -23713,13 +23762,34 @@ class ToolbarContent extends jodit_core_ui_button__WEBPACK_IMPORTED_MODULE_5__.U
23713
23762
  return 'ToolbarContent';
23714
23763
  }
23715
23764
  /** @override */ update() {
23716
- const content = this.control.getContent(this.j, this);
23765
+ const { control } = this;
23766
+ const content = control.getContent(this.j, this);
23717
23767
  if ((0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_4__.isString)(content) || content.parentNode !== this.container) {
23718
23768
  jodit_core_dom__WEBPACK_IMPORTED_MODULE_3__.Dom.detach(this.container);
23719
23769
  this.container.appendChild((0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_4__.isString)(content) ? this.j.create.fromHTML(content) : content);
23720
23770
  }
23771
+ // Content controls never went through the ToolbarButton status
23772
+ // calculation, so `isDisabled`/`isActive`/`update` declared on the
23773
+ // control were silently ignored (e.g. the FileBrowser Upload button
23774
+ // ignored the backend permissions). See
23775
+ // https://github.com/xdan/jodit/issues/1094
23776
+ this.state.disabled = Boolean(control.isDisabled?.(this.j, this));
23777
+ this.state.activated = Boolean(control.isActive?.(this.j, this));
23778
+ control.update?.(this.j, this);
23779
+ // The first update() runs before the state watchers are attached, so
23780
+ // apply the calculated state explicitly (the calls are idempotent)
23781
+ this.onChangeDisabled();
23782
+ this.onChangeActivated();
23721
23783
  super.update();
23722
23784
  }
23785
+ /**
23786
+ * The content is arbitrary HTML — propagate the disabled state to the
23787
+ * nested form controls (e.g. the file input of the Upload button),
23788
+ * otherwise they stay interactive.
23789
+ */ onChangeDisabled() {
23790
+ super.onChangeDisabled();
23791
+ this.container.querySelectorAll('input,button,select,textarea').forEach((elm)=>(0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_4__.attr)(elm, 'disabled', this.state.disabled || null));
23792
+ }
23723
23793
  /** @override */ createContainer() {
23724
23794
  return this.j.c.span(this.componentName);
23725
23795
  }
@@ -24439,6 +24509,15 @@ function processOldBrowserDrag(self, cData, handlerSuccess, handlerError, onFina
24439
24509
  if (!fileList.length) {
24440
24510
  return Promise.reject((0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_0__.error)('Need files'));
24441
24511
  }
24512
+ // Client-side validation hook — returning `false` aborts the upload.
24513
+ // See https://github.com/xdan/jodit/issues/1329
24514
+ if ((0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_0__.isFunction)(o.beforeUpload)) {
24515
+ if (o.beforeUpload.call(uploader, fileList) === false) {
24516
+ const err = (0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_0__.error)('Upload canceled');
24517
+ (handlerError || o.defaultHandlerError).call(uploader, err);
24518
+ return Promise.reject(err);
24519
+ }
24520
+ }
24442
24521
  const promises = [];
24443
24522
  if (o.insertImageAsBase64URI) {
24444
24523
  readImagesWithReader(fileList, o.imagesExtensions, promises, uploader, handlerSuccess, o.defaultHandlerSuccess);
@@ -25375,7 +25454,9 @@ const ns = 'addnewline';
25375
25454
  }
25376
25455
  __onMouseMove(e) {
25377
25456
  const editor = this.j;
25378
- let currentElement = editor.ed.elementFromPoint(e.clientX, e.clientY);
25457
+ // Inside Shadow DOM `document.elementFromPoint` returns the shadow
25458
+ // host, so the lookup must start from the shadow root
25459
+ let currentElement = (editor.o.shadowRoot ?? editor.ed).elementFromPoint(e.clientX, e.clientY);
25379
25460
  if (!jodit_modules__WEBPACK_IMPORTED_MODULE_5__.Dom.isHTMLElement(currentElement) || !jodit_modules__WEBPACK_IMPORTED_MODULE_5__.Dom.isOrContains(editor.editor, currentElement)) {
25380
25461
  return;
25381
25462
  }
@@ -25565,7 +25646,13 @@ jodit_core_ui_icon__WEBPACK_IMPORTED_MODULE_0__.Icon.set('enter', (_enter_svg__W
25565
25646
  return new _ui_ui_ai_assistant__WEBPACK_IMPORTED_MODULE_8__.UiAiAssistant(jodit, {
25566
25647
  onInsertAfter (html) {
25567
25648
  jodit.s.focus();
25568
- jodit.s.setCursorAfter(jodit.s.current());
25649
+ // `current()` returns a node of the selection START, so with
25650
+ // several selected paragraphs the result landed after the
25651
+ // first one — collapse the range to the END of the selection
25652
+ // instead. See https://github.com/xdan/jodit/issues/1263
25653
+ const range = jodit.s.range;
25654
+ range.collapse(false);
25655
+ jodit.s.selectRange(range);
25569
25656
  jodit.s.insertHTML(html);
25570
25657
  __dialog.close();
25571
25658
  },
@@ -26042,10 +26129,14 @@ class backspace extends jodit_core_plugin__WEBPACK_IMPORTED_MODULE_5__.Plugin {
26042
26129
  return false;
26043
26130
  }
26044
26131
  (0,jodit_core_selection_helpers__WEBPACK_IMPORTED_MODULE_6__.moveNodeInsideStart)(jodit, fakeNode, backspace);
26045
- if (_cases__WEBPACK_IMPORTED_MODULE_9__.cases.some((func)=>{
26132
+ const disabled = jodit.o.delete.disableCases;
26133
+ if (_cases__WEBPACK_IMPORTED_MODULE_9__.casesMap.some(([key, func])=>{
26134
+ if (disabled && disabled.has(key)) {
26135
+ return;
26136
+ }
26046
26137
  if ((0,jodit_core_helpers_checker_is_function__WEBPACK_IMPORTED_MODULE_4__.isFunction)(func) && func(jodit, fakeNode, backspace, mode)) {
26047
26138
  if (!jodit_core_constants__WEBPACK_IMPORTED_MODULE_1__.IS_PROD) {
26048
- console.info('Remove case:', func.name);
26139
+ console.info('Remove case:', key);
26049
26140
  }
26050
26141
  return true;
26051
26142
  }
@@ -26134,13 +26225,26 @@ jodit_core_global__WEBPACK_IMPORTED_MODULE_3__.pluginSystem.add('backspace', bac
26134
26225
  jodit.s.setCursorBefore(fakeNode);
26135
26226
  return true;
26136
26227
  }
26137
- if (sibling && (checkMoveListContent(jodit, mainClosestBox, sibling, backspace) || moveContentAndRemoveEmpty(jodit, mainClosestBox, sibling, backspace))) {
26228
+ if (sibling && (checkMoveListContent(jodit, mainClosestBox, sibling, backspace) || moveContentAndRemoveEmpty(jodit, mainClosestBox, resolveTableSibling(sibling, backspace), backspace))) {
26138
26229
  jodit.s.setCursorBefore(fakeNode);
26139
26230
  return true;
26140
26231
  }
26141
26232
  }
26142
26233
  return false;
26143
26234
  }
26235
+ /**
26236
+ * Content cannot be merged into the `<table>` element itself — it would land
26237
+ * between the table sections (after `</tbody>`), which is invalid HTML and
26238
+ * gets foster-parented out of the table on the next parse. Merge into the
26239
+ * edge cell instead. See https://github.com/xdan/jodit/issues/1064
26240
+ * @private
26241
+ */ function resolveTableSibling(sibling, backspace) {
26242
+ if (!jodit_core_dom_dom__WEBPACK_IMPORTED_MODULE_1__.Dom.isTag(sibling, 'table')) {
26243
+ return sibling;
26244
+ }
26245
+ const cells = sibling.querySelectorAll('td,th');
26246
+ return cells.length ? cells[backspace ? cells.length - 1 : 0] : null;
26247
+ }
26144
26248
  function checkMoveListContent(jodit, mainClosestBox, sibling, backspace) {
26145
26249
  // Process UL/LI/OL cases
26146
26250
  const siblingIsList = jodit_core_dom_dom__WEBPACK_IMPORTED_MODULE_1__.Dom.isTag(sibling, jodit_core_constants__WEBPACK_IMPORTED_MODULE_0__.LIST_TAGS);
@@ -26721,8 +26825,9 @@ function checkRepeatRemoveCharAction(backspace, sibling, fakeNode, mode, removed
26721
26825
 
26722
26826
  "use strict";
26723
26827
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
26724
- /* harmony export */ cases: function() { return /* binding */ cases; }
26828
+ /* harmony export */ casesMap: function() { return /* binding */ casesMap; }
26725
26829
  /* harmony export */ });
26830
+ /* unused harmony export cases */
26726
26831
  /* harmony import */ var _check_join_neighbors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26106);
26727
26832
  /* harmony import */ var _check_join_two_lists__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(80951);
26728
26833
  /* harmony import */ var _check_remove_char__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(58881);
@@ -26748,18 +26853,52 @@ function checkRepeatRemoveCharAction(backspace, sibling, fakeNode, mode, removed
26748
26853
 
26749
26854
 
26750
26855
  /**
26856
+ * Ordered delete/backspace cases with stable keys. The first one returning
26857
+ * `true` wins. The keys are stable across minified builds (function names are
26858
+ * mangled by terser) so they can be referenced by `delete.disableCases`.
26751
26859
  * @private
26752
- */ const cases = [
26753
- _check_remove_unbreakable_element__WEBPACK_IMPORTED_MODULE_6__.checkRemoveUnbreakableElement,
26754
- _check_remove_content_not_editable__WEBPACK_IMPORTED_MODULE_3__.checkRemoveContentNotEditable,
26755
- _check_remove_char__WEBPACK_IMPORTED_MODULE_2__.checkRemoveChar,
26756
- _check_table_cell__WEBPACK_IMPORTED_MODULE_7__.checkTableCell,
26757
- _check_remove_empty_parent__WEBPACK_IMPORTED_MODULE_5__.checkRemoveEmptyParent,
26758
- _check_remove_empty_neighbor__WEBPACK_IMPORTED_MODULE_4__.checkRemoveEmptyNeighbor,
26759
- _check_join_two_lists__WEBPACK_IMPORTED_MODULE_1__.checkJoinTwoLists,
26760
- _check_join_neighbors__WEBPACK_IMPORTED_MODULE_0__.checkJoinNeighbors,
26761
- _check_unwrap_first_list_item__WEBPACK_IMPORTED_MODULE_8__.checkUnwrapFirstListItem
26860
+ */ const casesMap = [
26861
+ [
26862
+ 'remove-unbreakable',
26863
+ _check_remove_unbreakable_element__WEBPACK_IMPORTED_MODULE_6__.checkRemoveUnbreakableElement
26864
+ ],
26865
+ [
26866
+ 'remove-not-editable',
26867
+ _check_remove_content_not_editable__WEBPACK_IMPORTED_MODULE_3__.checkRemoveContentNotEditable
26868
+ ],
26869
+ [
26870
+ 'remove-char',
26871
+ _check_remove_char__WEBPACK_IMPORTED_MODULE_2__.checkRemoveChar
26872
+ ],
26873
+ [
26874
+ 'table-cell',
26875
+ _check_table_cell__WEBPACK_IMPORTED_MODULE_7__.checkTableCell
26876
+ ],
26877
+ [
26878
+ 'remove-empty-parent',
26879
+ _check_remove_empty_parent__WEBPACK_IMPORTED_MODULE_5__.checkRemoveEmptyParent
26880
+ ],
26881
+ [
26882
+ 'remove-empty-neighbor',
26883
+ _check_remove_empty_neighbor__WEBPACK_IMPORTED_MODULE_4__.checkRemoveEmptyNeighbor
26884
+ ],
26885
+ [
26886
+ 'join-two-lists',
26887
+ _check_join_two_lists__WEBPACK_IMPORTED_MODULE_1__.checkJoinTwoLists
26888
+ ],
26889
+ [
26890
+ 'join-neighbors',
26891
+ _check_join_neighbors__WEBPACK_IMPORTED_MODULE_0__.checkJoinNeighbors
26892
+ ],
26893
+ [
26894
+ 'unwrap-first-list-item',
26895
+ _check_unwrap_first_list_item__WEBPACK_IMPORTED_MODULE_8__.checkUnwrapFirstListItem
26896
+ ]
26762
26897
  ];
26898
+ /**
26899
+ * @private
26900
+ * @deprecated Use `casesMap` to also get the stable case keys.
26901
+ */ const cases = casesMap.map(([, fn])=>fn);
26763
26902
 
26764
26903
 
26765
26904
  /***/ }),
@@ -27241,6 +27380,18 @@ jodit_core_ui_icon__WEBPACK_IMPORTED_MODULE_5__.Icon.set('class-span', (_class_s
27241
27380
  jodit_core_dom_dom__WEBPACK_IMPORTED_MODULE_3__.Dom.safeRemove(iframe);
27242
27381
  return false;
27243
27382
  }
27383
+ /**
27384
+ * Collapse a value that holds only a single empty block (e.g.
27385
+ * `<p><br></p>` left after deleting all content) to an empty string —
27386
+ * opt-in via `cleanHTML.collapseEmptyValueToEmptyString`. See #1149
27387
+ */ onAfterGetValueFromEditor(data) {
27388
+ if (!this.j.o.cleanHTML.collapseEmptyValueToEmptyString) {
27389
+ return;
27390
+ }
27391
+ if (/^<([a-z][a-z0-9]*)\b[^>]*>(?:<br\/?>)?<\/\1>$/i.test(data.value.trim())) {
27392
+ data.value = '';
27393
+ }
27394
+ }
27244
27395
  onSafeHTML(sandBox) {
27245
27396
  const sanitizer = this.j.o.cleanHTML.sanitizer;
27246
27397
  if (sanitizer) {
@@ -27280,6 +27431,9 @@ jodit_core_ui_icon__WEBPACK_IMPORTED_MODULE_5__.Icon.set('class-span', (_class_s
27280
27431
  (0,_swc_helpers_ts_decorate__WEBPACK_IMPORTED_MODULE_1__.__decorate)([
27281
27432
  (0,jodit_core_decorators__WEBPACK_IMPORTED_MODULE_2__.watch)(':beforeSetNativeEditorValue')
27282
27433
  ], cleanHtml.prototype, "onBeforeSetNativeEditorValue", null);
27434
+ (0,_swc_helpers_ts_decorate__WEBPACK_IMPORTED_MODULE_1__.__decorate)([
27435
+ (0,jodit_core_decorators__WEBPACK_IMPORTED_MODULE_2__.watch)(':afterGetValueFromEditor')
27436
+ ], cleanHtml.prototype, "onAfterGetValueFromEditor", null);
27283
27437
  (0,_swc_helpers_ts_decorate__WEBPACK_IMPORTED_MODULE_1__.__decorate)([
27284
27438
  (0,jodit_core_decorators__WEBPACK_IMPORTED_MODULE_2__.watch)(':safeHTML')
27285
27439
  ], cleanHtml.prototype, "onSafeHTML", null);
@@ -27309,6 +27463,7 @@ jodit_config__WEBPACK_IMPORTED_MODULE_1__.Config.prototype.cleanHTML = {
27309
27463
  timeout: 300,
27310
27464
  removeEmptyElements: true,
27311
27465
  fillEmptyParagraph: true,
27466
+ collapseEmptyValueToEmptyString: false,
27312
27467
  replaceNBSP: true,
27313
27468
  replaceOldTags: {
27314
27469
  i: 'em',
@@ -28329,25 +28484,33 @@ jodit_core_ui_icon__WEBPACK_IMPORTED_MODULE_0__.Icon.set('copy', (_icons_copy_sv
28329
28484
  });
28330
28485
  const callback = (command, second, third)=>{
28331
28486
  const colorHEX = (0,jodit_core_helpers___WEBPACK_IMPORTED_MODULE_1__.normalizeColor)(third);
28332
- switch(command){
28333
- case 'background':
28334
- editor.s.commitStyle({
28335
- attributes: {
28336
- style: {
28337
- backgroundColor: !colorHEX ? '' : colorHEX
28338
- }
28339
- }
28340
- });
28341
- break;
28342
- case 'forecolor':
28487
+ const value = !colorHEX ? '' : colorHEX;
28488
+ const style = command === 'background' ? {
28489
+ backgroundColor: value
28490
+ } : {
28491
+ color: value
28492
+ };
28493
+ // Cells selected with the `select-cells` plugin drop or collapse the
28494
+ // native range, so `commitStyle` would paint a pending caret format
28495
+ // outside the table instead of the selection the user sees. Apply the
28496
+ // style to the content of every selected cell instead. See #1250
28497
+ const selectedCells = editor.getInstance('Table', editor.o).getAllSelectedCells();
28498
+ if (selectedCells.length && editor.s.isCollapsed()) {
28499
+ selectedCells.forEach((cell)=>{
28500
+ editor.s.select(cell, true);
28343
28501
  editor.s.commitStyle({
28344
28502
  attributes: {
28345
- style: {
28346
- color: !colorHEX ? '' : colorHEX
28347
- }
28503
+ style
28348
28504
  }
28349
28505
  });
28350
- break;
28506
+ });
28507
+ editor.s.sel?.removeAllRanges();
28508
+ } else {
28509
+ editor.s.commitStyle({
28510
+ attributes: {
28511
+ style
28512
+ }
28513
+ });
28351
28514
  }
28352
28515
  editor.synchronizeValues();
28353
28516
  return false;
@@ -30379,6 +30542,25 @@ jodit_config__WEBPACK_IMPORTED_MODULE_4__.Config.prototype.controls.font = {
30379
30542
  return v.toLowerCase().replace(/['"]+/g, '').replace(/[^a-z0-9-]+/g, ',');
30380
30543
  }
30381
30544
  },
30545
+ // When no font is explicitly set, the computed font-family equals the
30546
+ // editor's own default (e.g. `-apple-system, …`). Return '' so the
30547
+ // button shows the `Default` list entry instead of that raw stack.
30548
+ // See #1370
30549
+ value: (editor)=>{
30550
+ const current = editor.s.current();
30551
+ if (!current) {
30552
+ return;
30553
+ }
30554
+ const box = jodit_core_dom__WEBPACK_IMPORTED_MODULE_0__.Dom.closest(current, jodit_core_dom__WEBPACK_IMPORTED_MODULE_0__.Dom.isElement, editor.editor);
30555
+ if (!box) {
30556
+ return;
30557
+ }
30558
+ const value = (0,jodit_core_helpers_utils_css__WEBPACK_IMPORTED_MODULE_2__.css)(box, 'font-family').toString();
30559
+ if (value === (0,jodit_core_helpers_utils_css__WEBPACK_IMPORTED_MODULE_2__.css)(editor.editor, 'font-family').toString()) {
30560
+ return '';
30561
+ }
30562
+ return value;
30563
+ },
30382
30564
  tooltip: 'Font family'
30383
30565
  };
30384
30566
 
@@ -33801,10 +33983,30 @@ const align = {
33801
33983
  this.j.async.setTimeout(()=>{
33802
33984
  const sel = this.j.s.sel;
33803
33985
  if (sel && !sel.isCollapsed) {
33804
- this.showPopup(()=>this.j.s.range.getBoundingClientRect(), 'selection');
33986
+ this.showPopup(()=>this.__selectionBound(), 'selection');
33805
33987
  }
33806
33988
  }, 1);
33807
33989
  }
33990
+ /**
33991
+ * The selection rect comes from the editor document — in iframe mode its
33992
+ * coordinates are iframe-local, while the popup lives in the host
33993
+ * document, so the iframe offset must be added. See
33994
+ * https://github.com/xdan/jodit/issues/1058
33995
+ */ __selectionBound() {
33996
+ const rect = this.j.s.range.getBoundingClientRect();
33997
+ let { left, top } = rect;
33998
+ if (this.j.iframe) {
33999
+ const offset = (0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_5__.position)(this.j.iframe, this.j, true);
34000
+ left += offset.left;
34001
+ top += offset.top;
34002
+ }
34003
+ return {
34004
+ left,
34005
+ top,
34006
+ width: rect.width,
34007
+ height: rect.height
34008
+ };
34009
+ }
33808
34010
  onSelectionStart() {
33809
34011
  this.snapRange = this.j.s.range.cloneRange();
33810
34012
  }
@@ -33836,7 +34038,7 @@ const align = {
33836
34038
  if (!node) {
33837
34039
  return;
33838
34040
  }
33839
- this.showPopup(()=>range.getBoundingClientRect(), type);
34041
+ this.showPopup(()=>this.__selectionBound(), type);
33840
34042
  }
33841
34043
  /**
33842
34044
  * In not collapsed selection - only one image
@@ -34482,6 +34684,7 @@ jodit_config__WEBPACK_IMPORTED_MODULE_2__.Config.prototype.link = {
34482
34684
  noFollowCheckbox: true,
34483
34685
  openInNewTabCheckbox: true,
34484
34686
  openInNewTabCheckboxDefaultChecked: false,
34687
+ ariaLabelInput: false,
34485
34688
  modeClassName: 'input',
34486
34689
  selectMultipleClassName: true,
34487
34690
  preventReadOnlyNavigation: true,
@@ -34637,7 +34840,7 @@ jodit_config__WEBPACK_IMPORTED_MODULE_2__.Config.prototype.controls.link = {
34637
34840
  const currentElement = current;
34638
34841
  const isImageContent = jodit_core_dom__WEBPACK_IMPORTED_MODULE_3__.Dom.isImage(currentElement);
34639
34842
  let { content_input } = elements;
34640
- const { className_input } = elements, { className_select } = elements;
34843
+ const { className_input } = elements, { className_select } = elements, { aria_label_input } = elements;
34641
34844
  if (!content_input) {
34642
34845
  content_input = jodit.c.element('input', {
34643
34846
  type: 'hidden',
@@ -34660,6 +34863,9 @@ jodit_config__WEBPACK_IMPORTED_MODULE_2__.Config.prototype.controls.link = {
34660
34863
  if (!isImageContent && current) {
34661
34864
  content_input.value = getSelectionText();
34662
34865
  }
34866
+ if (aria_label_input) {
34867
+ aria_label_input.value = link ? (0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_5__.attr)(link, 'aria-label') || '' : '';
34868
+ }
34663
34869
  if (link) {
34664
34870
  url_input.value = (0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_5__.attr)(link, 'href') || '';
34665
34871
  if (modeClassName) {
@@ -34747,6 +34953,10 @@ jodit_config__WEBPACK_IMPORTED_MODULE_2__.Config.prototype.controls.link = {
34747
34953
  }
34748
34954
  (0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_5__.attr)(a, 'rel', relParts.length ? relParts.join(' ') : null);
34749
34955
  }
34956
+ if (aria_label_input) {
34957
+ const ariaLabel = aria_label_input.value.trim();
34958
+ (0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_5__.attr)(a, 'aria-label', ariaLabel || null);
34959
+ }
34750
34960
  jodit.e.fire('applyLink', jodit, a, form);
34751
34961
  });
34752
34962
  jodit.synchronizeValues();
@@ -34886,7 +35096,7 @@ function writeImage(a, content_input, textWasChanged, url_input) {
34886
35096
  */
34887
35097
 
34888
35098
  const formTemplate = (editor)=>{
34889
- const { openInNewTabCheckbox, noFollowCheckbox, modeClassName, selectSizeClassName, selectMultipleClassName, selectOptionsClassName } = editor.o.link;
35099
+ const { openInNewTabCheckbox, noFollowCheckbox, ariaLabelInput, modeClassName, selectSizeClassName, selectMultipleClassName, selectOptionsClassName } = editor.o.link;
34890
35100
  return new jodit_core_ui_form__WEBPACK_IMPORTED_MODULE_1__.UIForm(editor, [
34891
35101
  new jodit_core_ui_form__WEBPACK_IMPORTED_MODULE_1__.UIBlock(editor, [
34892
35102
  new jodit_core_ui_form__WEBPACK_IMPORTED_MODULE_1__.UIInput(editor, {
@@ -34898,6 +35108,13 @@ const formTemplate = (editor)=>{
34898
35108
  required: true
34899
35109
  })
34900
35110
  ]),
35111
+ ariaLabelInput ? new jodit_core_ui_form__WEBPACK_IMPORTED_MODULE_1__.UIBlock(editor, [
35112
+ new jodit_core_ui_form__WEBPACK_IMPORTED_MODULE_1__.UIInput(editor, {
35113
+ name: 'ariaLabel',
35114
+ ref: 'aria_label_input',
35115
+ label: 'Aria label'
35116
+ })
35117
+ ]) : null,
34901
35118
  new jodit_core_ui_form__WEBPACK_IMPORTED_MODULE_1__.UIBlock(editor, [
34902
35119
  new jodit_core_ui_form__WEBPACK_IMPORTED_MODULE_1__.UIInput(editor, {
34903
35120
  name: 'content',
@@ -35772,7 +35989,13 @@ jodit_config__WEBPACK_IMPORTED_MODULE_1__.Config.prototype.controls.paste = {
35772
35989
  try {
35773
35990
  const items = await navigator.clipboard.read();
35774
35991
  if (items && items.length) {
35775
- const textBlob = await items[0].getType(jodit_core_constants__WEBPACK_IMPORTED_MODULE_0__.TEXT_PLAIN);
35992
+ const item = items[0];
35993
+ // Prefer the HTML flavor so the button behaves like the
35994
+ // Ctrl+V shortcut (which receives text/html from the
35995
+ // native paste event). See
35996
+ // https://github.com/xdan/jodit/issues/1061
35997
+ const type = item.types?.includes(jodit_core_constants__WEBPACK_IMPORTED_MODULE_0__.TEXT_HTML) ? jodit_core_constants__WEBPACK_IMPORTED_MODULE_0__.TEXT_HTML : jodit_core_constants__WEBPACK_IMPORTED_MODULE_0__.TEXT_PLAIN;
35998
+ const textBlob = await item.getType(type);
35776
35999
  text = await new Response(textBlob).text();
35777
36000
  }
35778
36001
  error = false;
@@ -38378,20 +38601,30 @@ class UISearch extends jodit_core_ui__WEBPACK_IMPORTED_MODULE_6__.UIElement {
38378
38601
  return false;
38379
38602
  }).on(this.queryInput, 'input', ()=>{
38380
38603
  this.setMod('empty-query', !(0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_5__.trim)(this.queryInput.value).length);
38381
- }).on(this.queryInput, 'keydown', this.j.async.debounce(async (e)=>{
38382
- switch(e.key){
38383
- case jodit_core_constants__WEBPACK_IMPORTED_MODULE_2__.KEY_ENTER:
38604
+ }).on(this.queryInput, 'keydown', (()=>{
38605
+ const debounced = this.j.async.debounce(async (e)=>{
38606
+ switch(e.key){
38607
+ case jodit_core_constants__WEBPACK_IMPORTED_MODULE_2__.KEY_ENTER:
38608
+ if (await jodit.e.fire('searchNext')) {
38609
+ this.close();
38610
+ }
38611
+ break;
38612
+ default:
38613
+ jodit.e.fire(this, 'needUpdateCounters');
38614
+ break;
38615
+ }
38616
+ }, this.j.defaultTimeout);
38617
+ return (e)=>{
38618
+ // Must be canceled synchronously — inside the debounced
38619
+ // handler the browser has already submitted the parent
38620
+ // form. See https://github.com/xdan/jodit/issues/918
38621
+ if (e.key === jodit_core_constants__WEBPACK_IMPORTED_MODULE_2__.KEY_ENTER) {
38384
38622
  e.preventDefault();
38385
38623
  e.stopImmediatePropagation();
38386
- if (await jodit.e.fire('searchNext')) {
38387
- this.close();
38388
- }
38389
- break;
38390
- default:
38391
- jodit.e.fire(this, 'needUpdateCounters');
38392
- break;
38393
- }
38394
- }, this.j.defaultTimeout));
38624
+ }
38625
+ debounced(e);
38626
+ };
38627
+ })());
38395
38628
  }
38396
38629
  }
38397
38630
  (0,_swc_helpers_ts_decorate__WEBPACK_IMPORTED_MODULE_1__.__decorate)([
@@ -38503,15 +38736,36 @@ class selectCells extends jodit_core_plugin__WEBPACK_IMPORTED_MODULE_7__.Plugin
38503
38736
  }
38504
38737
  /**
38505
38738
  * Mouse click inside the table
38506
- */ onStartSelection(cell) {
38739
+ */ onStartSelection(cell, event) {
38507
38740
  if (this.j.o.readonly) {
38508
38741
  return;
38509
38742
  }
38743
+ const table = jodit_core_dom_dom__WEBPACK_IMPORTED_MODULE_4__.Dom.closest(cell, 'table', this.j.editor);
38744
+ // Ctrl/Cmd + click toggles a single cell into the existing selection
38745
+ // instead of resetting it — non-contiguous multi-cell selection.
38746
+ // See https://github.com/xdan/jodit/issues/1163
38747
+ if ((event?.ctrlKey || event?.metaKey) && cell !== this.j.editor && table && jodit_core_dom_dom__WEBPACK_IMPORTED_MODULE_4__.Dom.isCell(cell)) {
38748
+ if (this.__tableModule.getAllSelectedCells().includes(cell)) {
38749
+ this.__tableModule.removeSelection(cell);
38750
+ } else {
38751
+ if (!cell.firstChild) {
38752
+ cell.appendChild(this.j.createInside.element('br'));
38753
+ }
38754
+ this.__tableModule.addSelection(cell);
38755
+ }
38756
+ this.__selectedCell = cell;
38757
+ this.j.s.sel?.removeAllRanges();
38758
+ if (this.__tableModule.getAllSelectedCells().length) {
38759
+ this.j.e.fire('showPopup', table, ()=>(0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_6__.position)(cell, this.j), 'cells');
38760
+ } else {
38761
+ this.j.e.fire('hidePopup', 'cells');
38762
+ }
38763
+ return false;
38764
+ }
38510
38765
  this.unselectCells();
38511
38766
  if (cell === this.j.editor) {
38512
38767
  return;
38513
38768
  }
38514
- const table = jodit_core_dom_dom__WEBPACK_IMPORTED_MODULE_4__.Dom.closest(cell, 'table', this.j.editor);
38515
38769
  if (!cell || !table) {
38516
38770
  return;
38517
38771
  }
@@ -38546,7 +38800,9 @@ class selectCells extends jodit_core_plugin__WEBPACK_IMPORTED_MODULE_7__.Plugin
38546
38800
  if (this.j.isLockedNotBy(key)) {
38547
38801
  return;
38548
38802
  }
38549
- const node = this.j.ed.elementFromPoint(e.clientX, e.clientY);
38803
+ // Inside Shadow DOM `document.elementFromPoint` returns the shadow
38804
+ // host, so the lookup must start from the shadow root
38805
+ const node = (this.j.o.shadowRoot ?? this.j.ed).elementFromPoint(e.clientX, e.clientY);
38550
38806
  if (!node) {
38551
38807
  return;
38552
38808
  }
@@ -38605,7 +38861,9 @@ class selectCells extends jodit_core_plugin__WEBPACK_IMPORTED_MODULE_7__.Plugin
38605
38861
  }
38606
38862
  this.__isSelectionMode = false;
38607
38863
  this.j.unlock();
38608
- const node = this.j.ed.elementFromPoint(e.clientX, e.clientY);
38864
+ // Inside Shadow DOM `document.elementFromPoint` returns the shadow
38865
+ // host, so the lookup must start from the shadow root
38866
+ const node = (this.j.o.shadowRoot ?? this.j.ed).elementFromPoint(e.clientX, e.clientY);
38609
38867
  if (!node) {
38610
38868
  return;
38611
38869
  }
@@ -42030,7 +42288,7 @@ module.exports["default"] = {"Type something":"Start writing...","pencil":"Edit"
42030
42288
  /***/ 53414:
42031
42289
  /***/ (function(module) {
42032
42290
 
42033
- module.exports["default"] = ["Type something","About Jodit","Jodit Editor","Jodit User's Guide","contains detailed help for using","For information about the license, please go to our website:","Buy full version","Copyright © XDSoft.net - Chupurnov Valeriy. All rights reserved.","Anchor","Open in new tab","Open in fullsize","Clear Formatting","Fill color or set the text color","Redo","Undo","Bold","Italic","Insert Unordered List","Insert Ordered List","Align Center","Align Justify","Align Left","Align Right","Insert Horizontal Line","Insert Image","Insert file","Insert youtube/vimeo video","Insert link","Font size","Font family","Insert format block","Normal","Heading 1","Heading 2","Heading 3","Heading 4","Quote","Code","Insert","Insert table","Decrease Indent","Increase Indent","Select Special Character","Insert Special Character","Paint format","Change mode","Margins","top","right","bottom","left","Styles","Classes","Align","Right","Center","Left","--Not Set--","Src","Title","Alternative","Link","Open link in new tab","Image","file","Advanced","Image properties","Cancel","Ok","File Browser","Error on load list","Error on load folders","Are you sure?","Enter Directory name","Create directory","type name","Drop image","Drop file","or click","Alternative text","Upload","Browse","Background","Text","Top","Middle","Bottom","Insert column before","Insert column after","Insert row above","Insert row below","Delete table","Delete row","Delete column","Empty cell","Chars: %d","Words: %d","Strike through","Underline","superscript","subscript","Cut selection","Select all","Break","Search for","Replace with","Replace","Paste","Choose Content to Paste","source","bold","italic","brush","link","undo","redo","table","image","eraser","paragraph","fontsize","video","font","about","print","underline","strikethrough","indent","outdent","fullsize","shrink","hr","ul","ol","cut","selectall","Embed code","Open link","Edit link","No follow","Unlink","Update","pencil","Eye"," URL","Edit","Horizontal align","Filter","Sort by changed","Sort by name","Sort by size","Add folder","Reset","Save","Save as ...","Resize","Crop","Width","Height","Keep Aspect Ratio","Yes","No","Remove","Select","Select %s","Vertical align","Split","Merge","Add column","Add row","License: %s","Delete","Split vertical","Split horizontal","Border","Your code is similar to HTML. Keep as HTML?","Paste as HTML","Keep","Insert as Text","Insert only Text","You can only edit your own images. Download this image on the host?","The image has been successfully uploaded to the host!","palette","There are no files","Rename","Enter new name","preview","download","Paste from clipboard","Your browser doesn't support direct access to the clipboard.","Copy selection","copy","Border radius","Show all","Apply","Please fill out this field","Please enter a web address","Default","Circle","Dot","Quadrate","Find","Find Previous","Find Next","The pasted content is coming from a Microsoft Word/Excel document. Do you want to keep the format or clean it up?","Word Paste Detected","Clean","Insert className","Press Alt for custom resizing","Line height","spellcheck","Speech Recognize","All"]
42291
+ module.exports["default"] = [" URL","--Not Set--","About Jodit","Add column","Add folder","Add row","Advanced","Align","Align Center","Align Justify","Align Left","Align Right","All","Alternative","Alternative text","Anchor","Apply","Are you sure?","Background","Bold","Border","Border radius","Bottom","Break","Browse","Buy full version","Cancel","Center","Change mode","Chars: %d","Choose Content to Paste","Circle","Class name","Classes","Clean","Clear Formatting","Code","Copy selection","Copyright © XDSoft.net - Chupurnov Valeriy. All rights reserved.","Create directory","Crop","Cut selection","Decrease Indent","Default","Delete","Delete column","Delete row","Delete table","Dot","Drop file","Drop image","Edit","Edit link","Embed code","Empty cell","Enter Directory name","Enter new name","Error on load folders","Error on load list","Eye","File Browser","Fill color or set the text color","Filter","Find","Find Next","Find Previous","Font family","Font size","For information about the license, please go to our website:","Free Non-commercial Version","Heading 1","Heading 2","Heading 3","Heading 4","Height","Horizontal align","Image","Image properties","Increase Indent","Insert","Insert Horizontal Line","Insert Image","Insert Ordered List","Insert Special Character","Insert Unordered List","Insert as Text","Insert className","Insert column after","Insert column before","Insert file","Insert format block","Insert link","Insert only Text","Insert row above","Insert row below","Insert table","Insert youtube/vimeo video","Interim Results","Italic","Jodit Editor","Jodit User's Guide","Keep","Keep Aspect Ratio","Left","License: %s","Line height","Link","Lower Alpha","Lower Greek","Lower Roman","Margins","Merge","Middle","No","No follow","Normal","Ok","Open in fullsize","Open in new tab","Open link","Open link in new tab","Paint format","Paste","Paste as HTML","Paste from clipboard","Please enter a web address","Please fill out this field","Press Alt for custom resizing","Print","Quadrate","Quote","Redo","Remove","Rename","Replace","Replace with","Reset","Resize","Right","Save","Save as ...","Search for","Select","Select %s","Select Special Character","Select all","Show all","Sort by changed","Sort by name","Sort by size","Sound","Speech Recognize","Split","Split horizontal","Split vertical","Src","Strike through","Styles","Text","The image has been successfully uploaded to the host!","The pasted content is coming from a Microsoft Word/Excel document. Do you want to keep the format or clean it up?","There are no files","Title","Top","Type something","Underline","Undo","Unlink","Update","Upload","Upper Alpha","Upper Roman","Vertical align","Width","Word Paste Detected","Words: %d","Yes","You can only edit your own images. Download this image on the host?","Your browser doesn't support direct access to the clipboard.","Your code is similar to HTML. Keep as HTML?","about","apply","bold","bottom","brush","circle","contains detailed help for using","copy","cut","default","dot","download","edit","eraser","file","font","fontsize","fullsize","hr","image","indent","italic","left","link","ol","or click","outdent","palette","paragraph","pencil","preview","print","redo","right","selectall","shrink","sound","source","spellcheck","square","strikethrough","subscript","superscript","table","top","type name","ul","underline","undo","video"]
42034
42292
 
42035
42293
  /***/ }),
42036
42294