jodit 4.17.1 → 4.17.3

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 (71) hide show
  1. package/.nvmrc +1 -0
  2. package/CHANGELOG.md +12 -0
  3. package/es2015/jodit.css +1 -1
  4. package/es2015/jodit.fat.min.js +4 -4
  5. package/es2015/jodit.js +182 -7
  6. package/es2015/jodit.min.js +4 -4
  7. package/es2015/plugins/debug/debug.css +1 -1
  8. package/es2015/plugins/debug/debug.js +1 -1
  9. package/es2015/plugins/debug/debug.min.js +1 -1
  10. package/es2015/plugins/speech-recognize/speech-recognize.css +1 -1
  11. package/es2015/plugins/speech-recognize/speech-recognize.js +1 -1
  12. package/es2015/plugins/speech-recognize/speech-recognize.min.js +1 -1
  13. package/es2018/jodit.fat.min.js +4 -4
  14. package/es2018/jodit.min.js +4 -4
  15. package/es2018/plugins/debug/debug.min.js +1 -1
  16. package/es2018/plugins/speech-recognize/speech-recognize.min.js +1 -1
  17. package/es2021/jodit.css +1 -1
  18. package/es2021/jodit.fat.min.js +6 -6
  19. package/es2021/jodit.js +182 -7
  20. package/es2021/jodit.min.js +6 -6
  21. package/es2021/plugins/debug/debug.css +1 -1
  22. package/es2021/plugins/debug/debug.js +1 -1
  23. package/es2021/plugins/debug/debug.min.js +1 -1
  24. package/es2021/plugins/speech-recognize/speech-recognize.css +1 -1
  25. package/es2021/plugins/speech-recognize/speech-recognize.js +1 -1
  26. package/es2021/plugins/speech-recognize/speech-recognize.min.js +1 -1
  27. package/es2021.en/jodit.css +1 -1
  28. package/es2021.en/jodit.fat.min.js +24 -24
  29. package/es2021.en/jodit.js +182 -7
  30. package/es2021.en/jodit.min.js +6 -6
  31. package/es2021.en/plugins/debug/debug.css +1 -1
  32. package/es2021.en/plugins/debug/debug.js +1 -1
  33. package/es2021.en/plugins/debug/debug.min.js +1 -1
  34. package/es2021.en/plugins/speech-recognize/speech-recognize.css +1 -1
  35. package/es2021.en/plugins/speech-recognize/speech-recognize.js +1 -1
  36. package/es2021.en/plugins/speech-recognize/speech-recognize.min.js +1 -1
  37. package/es5/jodit.css +2 -2
  38. package/es5/jodit.fat.min.js +2 -2
  39. package/es5/jodit.js +217 -7
  40. package/es5/jodit.min.css +2 -2
  41. package/es5/jodit.min.js +2 -2
  42. package/es5/plugins/debug/debug.css +1 -1
  43. package/es5/plugins/debug/debug.js +1 -1
  44. package/es5/plugins/debug/debug.min.js +1 -1
  45. package/es5/plugins/speech-recognize/speech-recognize.css +1 -1
  46. package/es5/plugins/speech-recognize/speech-recognize.js +1 -1
  47. package/es5/plugins/speech-recognize/speech-recognize.min.js +1 -1
  48. package/es5/polyfills.fat.min.js +1 -1
  49. package/es5/polyfills.js +1 -1
  50. package/es5/polyfills.min.js +1 -1
  51. package/esm/core/constants.js +1 -1
  52. package/esm/core/helpers/html/safe-html.js +15 -0
  53. package/esm/core/selection/helpers/composed-ranges.d.ts +21 -0
  54. package/esm/core/selection/helpers/composed-ranges.js +45 -0
  55. package/esm/core/selection/helpers/index.d.ts +1 -0
  56. package/esm/core/selection/helpers/index.js +1 -0
  57. package/esm/core/selection/selection.d.ts +23 -0
  58. package/esm/core/selection/selection.js +80 -4
  59. package/esm/jodit.js +5 -0
  60. package/esm/plugins/clean-html/clean-html.d.ts +8 -0
  61. package/esm/plugins/clean-html/clean-html.js +13 -0
  62. package/examples/build/es2015/jodit.min.css +1 -0
  63. package/examples/build/es2015/jodit.min.js +10 -0
  64. package/examples/build/es2015/plugins/debug/debug.min.js +10 -0
  65. package/examples/build/es2015/plugins/speech-recognize/speech-recognize.min.css +1 -0
  66. package/examples/build/es2015/plugins/speech-recognize/speech-recognize.min.js +10 -0
  67. package/package.json +1 -1
  68. package/types/core/selection/helpers/composed-ranges.d.ts +21 -0
  69. package/types/core/selection/helpers/index.d.ts +1 -0
  70. package/types/core/selection/selection.d.ts +23 -0
  71. package/types/plugins/clean-html/clean-html.d.ts +8 -0
package/es2015/jodit.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * jodit - Jodit is an awesome and useful wysiwyg editor with filebrowser
3
3
  * Author: Chupurnov <chupurnov@gmail.com> (https://xdsoft.net/jodit/)
4
- * Version: v4.17.1
4
+ * Version: v4.17.3
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -1805,7 +1805,7 @@ __webpack_require__.r(__webpack_exports__);
1805
1805
  * ```
1806
1806
  * @packageDocumentation
1807
1807
  * @module constants
1808
- */ const APP_VERSION = "4.17.1";
1808
+ */ const APP_VERSION = "4.17.3";
1809
1809
  // prettier-ignore
1810
1810
  const ES = "es2015";
1811
1811
  const IS_ES_MODERN = true;
@@ -6222,6 +6222,21 @@ function isSmuggledForeignHtml(elm) {
6222
6222
  jodit_core_dom_dom__WEBPACK_IMPORTED_MODULE_0__.Dom.safeRemove(elm);
6223
6223
  }
6224
6224
  }
6225
+ // `<noscript>` is parsed as markup in a document with scripting off (the
6226
+ // inert document the value is sanitized in) and as raw text in one with
6227
+ // scripting on (the live editor). The same serialized bytes therefore
6228
+ // describe two different trees, and markup hidden as inert text in the
6229
+ // first comes alive as elements in the second. The element has no use in
6230
+ // editor content, so it goes, together with everything it carried.
6231
+ const noscript = [];
6232
+ jodit_core_dom_dom__WEBPACK_IMPORTED_MODULE_0__.Dom.each(box, (node)=>{
6233
+ if (jodit_core_dom_dom__WEBPACK_IMPORTED_MODULE_0__.Dom.isElement(node) && node.nodeName === 'NOSCRIPT') {
6234
+ noscript.push(node);
6235
+ }
6236
+ });
6237
+ for (const elm of noscript){
6238
+ jodit_core_dom_dom__WEBPACK_IMPORTED_MODULE_0__.Dom.safeRemove(elm);
6239
+ }
6225
6240
  const removeEvents = (_options_removeEventAttributes = options.removeEventAttributes) !== null && _options_removeEventAttributes !== void 0 ? _options_removeEventAttributes : options.removeOnError;
6226
6241
  // Single synchronous traversal of the subtree. Besides removing event
6227
6242
  // handlers and `javascript:` links, `sanitizeHTMLElement` neutralises
@@ -10596,6 +10611,70 @@ class Response {
10596
10611
  }
10597
10612
 
10598
10613
 
10614
+ /***/ }),
10615
+
10616
+ /***/ 43134:
10617
+ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
10618
+
10619
+ "use strict";
10620
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
10621
+ /* harmony export */ composedRanges: function() { return /* binding */ composedRanges; }
10622
+ /* harmony export */ });
10623
+ /* harmony import */ var jodit_core_helpers_checker__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(28686);
10624
+ /*!
10625
+ * Jodit Editor (https://xdsoft.net/jodit/)
10626
+ * Released under MIT see LICENSE.txt in the project root for license information.
10627
+ * Copyright (c) 2013-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net
10628
+ */ /**
10629
+ * @module selection
10630
+ */
10631
+ function isInside(node, shadowRoot) {
10632
+ return node === shadowRoot || shadowRoot.contains(node);
10633
+ }
10634
+ function usable(ranges, shadowRoot) {
10635
+ return Array.isArray(ranges) && ranges.length > 0 && ranges.every((range)=>isInside(range.startContainer, shadowRoot));
10636
+ }
10637
+ /**
10638
+ * Ranges of a selection that lies inside the given shadow tree.
10639
+ *
10640
+ * `window.getSelection()` stops at the shadow boundary and reports the host
10641
+ * instead of the node the caret is really in. `getComposedRanges` is the
10642
+ * standard way to ask past that boundary.
10643
+ *
10644
+ * @returns `null` when the browser has no `getComposedRanges`, or when neither
10645
+ * call shape returned ranges that point inside the shadow tree — in which case
10646
+ * there is nothing better to offer than the plain window selection.
10647
+ */ function composedRanges(selection, shadowRoot) {
10648
+ const getComposedRanges = selection.getComposedRanges;
10649
+ if (!(0,jodit_core_helpers_checker__WEBPACK_IMPORTED_MODULE_0__.isFunction)(getComposedRanges)) {
10650
+ return null;
10651
+ }
10652
+ for (const args of [
10653
+ [
10654
+ {
10655
+ shadowRoots: [
10656
+ shadowRoot
10657
+ ]
10658
+ }
10659
+ ],
10660
+ [
10661
+ shadowRoot
10662
+ ]
10663
+ ]){
10664
+ let ranges;
10665
+ try {
10666
+ ranges = getComposedRanges.apply(selection, args);
10667
+ } catch (unused) {
10668
+ continue;
10669
+ }
10670
+ if (usable(ranges, shadowRoot)) {
10671
+ return ranges;
10672
+ }
10673
+ }
10674
+ return null;
10675
+ }
10676
+
10677
+
10599
10678
  /***/ }),
10600
10679
 
10601
10680
  /***/ 42259:
@@ -10603,14 +10682,16 @@ class Response {
10603
10682
 
10604
10683
  "use strict";
10605
10684
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
10685
+ /* harmony export */ composedRanges: function() { return /* reexport safe */ _composed_ranges__WEBPACK_IMPORTED_MODULE_2__.composedRanges; },
10606
10686
  /* harmony export */ cursorInTheEdgeOfString: function() { return /* binding */ cursorInTheEdgeOfString; },
10607
10687
  /* harmony export */ findCorrectCurrentNode: function() { return /* binding */ findCorrectCurrentNode; },
10608
- /* harmony export */ moveNodeInsideStart: function() { return /* reexport safe */ _move_node_inside_start__WEBPACK_IMPORTED_MODULE_2__.moveNodeInsideStart; }
10688
+ /* harmony export */ moveNodeInsideStart: function() { return /* reexport safe */ _move_node_inside_start__WEBPACK_IMPORTED_MODULE_3__.moveNodeInsideStart; }
10609
10689
  /* harmony export */ });
10610
10690
  /* harmony import */ var jodit_core_constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(81937);
10611
10691
  /* harmony import */ var jodit_core_dom_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(23211);
10612
- /* harmony import */ var _move_node_inside_start__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(89817);
10613
- /* harmony import */ var _move_the_node_along_the_edge_outward__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7470);
10692
+ /* harmony import */ var _composed_ranges__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(43134);
10693
+ /* harmony import */ var _move_node_inside_start__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(89817);
10694
+ /* harmony import */ var _move_the_node_along_the_edge_outward__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7470);
10614
10695
  /*!
10615
10696
  * Jodit Editor (https://xdsoft.net/jodit/)
10616
10697
  * Released under MIT see LICENSE.txt in the project root for license information.
@@ -10621,6 +10702,7 @@ class Response {
10621
10702
 
10622
10703
 
10623
10704
 
10705
+
10624
10706
  /**
10625
10707
  * Despite the name, returns `true` when the cursor is NOT at the checked edge
10626
10708
  * of the text node: there is significant (non invisible-space) text between
@@ -10850,11 +10932,87 @@ class Selection {
10850
10932
  /**
10851
10933
  * Return current selection object
10852
10934
  */ get sel() {
10853
- if (this.j.o.shadowRoot && (0,jodit_core_helpers_checker__WEBPACK_IMPORTED_MODULE_6__.isFunction)(this.j.o.shadowRoot.getSelection)) {
10854
- return this.j.o.shadowRoot.getSelection();
10935
+ const { shadowRoot } = this.j.o;
10936
+ if (shadowRoot) {
10937
+ if ((0,jodit_core_helpers_checker__WEBPACK_IMPORTED_MODULE_6__.isFunction)(shadowRoot.getSelection)) {
10938
+ return shadowRoot.getSelection();
10939
+ }
10940
+ const composed = this.__composedSelection(shadowRoot);
10941
+ if (composed) {
10942
+ return composed;
10943
+ }
10855
10944
  }
10856
10945
  return this.win.getSelection();
10857
10946
  }
10947
+ /**
10948
+ * Selection of a shadow tree in a browser without `ShadowRoot.getSelection`.
10949
+ *
10950
+ * `ShadowRoot.getSelection()` is a non-standard method that WebKit never
10951
+ * implemented, and `window.getSelection()` stops at the shadow boundary: for
10952
+ * a caret inside the shadow tree it reports the host, or the document
10953
+ * itself. Everything downstream then works on the wrong tree, which is why
10954
+ * Backspace used to throw `HierarchyRequestError` and Enter did nothing when
10955
+ * the editor lived in a shadow root in Safari.
10956
+ *
10957
+ * The standard replacement is `Selection.getComposedRanges()`, which does
10958
+ * reach into a shadow tree it is given. It hands back `StaticRange`s, and
10959
+ * the editor mutates ranges constantly, so they are turned into live ones.
10960
+ *
10961
+ * Reads are answered from those ranges; everything else, including the
10962
+ * writes (`addRange`, `removeAllRanges`, `setBaseAndExtent`), goes to the
10963
+ * real selection, which does accept nodes inside a shadow tree. Reading is
10964
+ * the only side the browser blocks.
10965
+ *
10966
+ * @returns `null` when the browser offers neither API, so the caller falls
10967
+ * back to the plain window selection.
10968
+ */ __composedSelection(shadowRoot) {
10969
+ const selection = this.win.getSelection();
10970
+ if (!selection) {
10971
+ return null;
10972
+ }
10973
+ // Firefox has no `ShadowRoot.getSelection` either, but its window
10974
+ // selection does see into a shadow tree. Where the plain selection
10975
+ // already points at the right node there is nothing to work around, and
10976
+ // taking it over would change behaviour that works today.
10977
+ const { anchorNode } = selection;
10978
+ if (anchorNode && jodit_core_dom_dom__WEBPACK_IMPORTED_MODULE_4__.Dom.isOrContains(shadowRoot, anchorNode)) {
10979
+ return null;
10980
+ }
10981
+ const ranges = (0,_helpers__WEBPACK_IMPORTED_MODULE_11__.composedRanges)(selection, shadowRoot);
10982
+ if (!ranges) {
10983
+ return null;
10984
+ }
10985
+ const live = ranges.map((staticRange)=>{
10986
+ const range = this.createRange();
10987
+ range.setStart(staticRange.startContainer, staticRange.startOffset);
10988
+ range.setEnd(staticRange.endContainer, staticRange.endOffset);
10989
+ return range;
10990
+ });
10991
+ const first = live[0];
10992
+ const overrides = {
10993
+ rangeCount: live.length,
10994
+ getRangeAt: (index)=>live[index],
10995
+ isCollapsed: live.every((range)=>range.collapsed),
10996
+ // Without these the editor asks the window selection where the
10997
+ // caret is, is told "outside the editable area", and resets the
10998
+ // caret to the start of it — which is the focus loss that shows up
10999
+ // right after a successful Backspace.
11000
+ anchorNode: first ? first.startContainer : null,
11001
+ anchorOffset: first ? first.startOffset : 0,
11002
+ focusNode: first ? first.endContainer : null,
11003
+ focusOffset: first ? first.endOffset : 0,
11004
+ toString: ()=>live.map((range)=>range.toString()).join('')
11005
+ };
11006
+ return new Proxy(selection, {
11007
+ get (target, property) {
11008
+ if ((0,jodit_core_helpers_checker__WEBPACK_IMPORTED_MODULE_6__.isString)(property) && property in overrides) {
11009
+ return overrides[property];
11010
+ }
11011
+ const value = Reflect.get(target, property, target);
11012
+ return (0,jodit_core_helpers_checker__WEBPACK_IMPORTED_MODULE_6__.isFunction)(value) ? value.bind(target) : value;
11013
+ }
11014
+ });
11015
+ }
10858
11016
  /**
10859
11017
  * Return first selected range or create new
10860
11018
  */ get range() {
@@ -17969,6 +18127,11 @@ class Jodit extends jodit_modules__WEBPACK_IMPORTED_MODULE_11__.ViewWithToolbar
17969
18127
  }
17970
18128
  if (this.editor) {
17971
18129
  this.editor.innerHTML = data.value;
18130
+ // Fired synchronously, before any task can run: the value was
18131
+ // sanitized in an inert document and re-parsed here with scripting
18132
+ // on, and the two parsers do not always agree. Listeners get to
18133
+ // look at the tree that actually exists.
18134
+ this.e.fire('afterSetNativeEditorValue');
17972
18135
  }
17973
18136
  }
17974
18137
  /**
@@ -28822,6 +28985,15 @@ class cleanHtml extends jodit_core_plugin_plugin__WEBPACK_IMPORTED_MODULE_7__.Pl
28822
28985
  return false;
28823
28986
  }
28824
28987
  }
28988
+ /**
28989
+ * The value was sanitized in an inert document and has just been re-parsed
28990
+ * into the live editor with scripting on. Where the two parsers disagree
28991
+ * (`<noscript>`, raw-text elements), markup that was inert text a moment
28992
+ * ago is a real element now, so the live tree is sanitized once more, in
28993
+ * the same call stack, before any handler it might carry can fire.
28994
+ */ onAfterSetNativeEditorValue() {
28995
+ ;(0,jodit_core_helpers_html_safe_html__WEBPACK_IMPORTED_MODULE_6__.safeHTML)(this.j.editor, this.j.o.cleanHTML);
28996
+ }
28825
28997
  /**
28826
28998
  * Event handler when manually assigning a value to the HTML editor.
28827
28999
  */ onBeforeSetNativeEditorValue(data) {
@@ -28948,6 +29120,9 @@ class cleanHtml extends jodit_core_plugin_plugin__WEBPACK_IMPORTED_MODULE_7__.Pl
28948
29120
  (0,_swc_helpers_ts_decorate__WEBPACK_IMPORTED_MODULE_1__.__decorate)([
28949
29121
  (0,jodit_core_decorators__WEBPACK_IMPORTED_MODULE_2__.watch)(':beforeCommand')
28950
29122
  ], cleanHtml.prototype, "beforeCommand", null);
29123
+ (0,_swc_helpers_ts_decorate__WEBPACK_IMPORTED_MODULE_1__.__decorate)([
29124
+ (0,jodit_core_decorators__WEBPACK_IMPORTED_MODULE_2__.watch)(':afterSetNativeEditorValue')
29125
+ ], cleanHtml.prototype, "onAfterSetNativeEditorValue", null);
28951
29126
  (0,_swc_helpers_ts_decorate__WEBPACK_IMPORTED_MODULE_1__.__decorate)([
28952
29127
  (0,jodit_core_decorators__WEBPACK_IMPORTED_MODULE_2__.watch)(':beforeSetNativeEditorValue')
28953
29128
  ], cleanHtml.prototype, "onBeforeSetNativeEditorValue", null);