jodit 4.11.15 → 4.12.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 (67) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/es2015/jodit.css +1 -1
  3. package/es2015/jodit.fat.min.js +4 -4
  4. package/es2015/jodit.js +151 -14
  5. package/es2015/jodit.min.js +4 -4
  6. package/es2015/plugins/debug/debug.css +1 -1
  7. package/es2015/plugins/debug/debug.js +1 -1
  8. package/es2015/plugins/debug/debug.min.js +1 -1
  9. package/es2015/plugins/speech-recognize/speech-recognize.css +1 -1
  10. package/es2015/plugins/speech-recognize/speech-recognize.js +1 -1
  11. package/es2015/plugins/speech-recognize/speech-recognize.min.js +1 -1
  12. package/es2018/jodit.fat.min.js +4 -4
  13. package/es2018/jodit.min.js +24 -24
  14. package/es2018/plugins/debug/debug.min.js +1 -1
  15. package/es2018/plugins/speech-recognize/speech-recognize.min.js +1 -1
  16. package/es2021/jodit.css +1 -1
  17. package/es2021/jodit.fat.min.js +5 -5
  18. package/es2021/jodit.js +151 -14
  19. package/es2021/jodit.min.js +5 -5
  20. package/es2021/plugins/debug/debug.css +1 -1
  21. package/es2021/plugins/debug/debug.js +1 -1
  22. package/es2021/plugins/debug/debug.min.js +1 -1
  23. package/es2021/plugins/speech-recognize/speech-recognize.css +1 -1
  24. package/es2021/plugins/speech-recognize/speech-recognize.js +1 -1
  25. package/es2021/plugins/speech-recognize/speech-recognize.min.js +1 -1
  26. package/es2021.en/jodit.css +1 -1
  27. package/es2021.en/jodit.fat.min.js +5 -5
  28. package/es2021.en/jodit.js +151 -14
  29. package/es2021.en/jodit.min.js +6 -6
  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 +157 -14
  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 +48 -4
  51. package/esm/config.js +28 -3
  52. package/esm/core/constants.js +1 -1
  53. package/esm/core/helpers/utils/config-proto.d.ts +21 -0
  54. package/esm/core/helpers/utils/config-proto.js +32 -0
  55. package/esm/core/ui/icon.d.ts +10 -0
  56. package/esm/core/ui/icon.js +17 -1
  57. package/esm/jodit.d.ts +44 -0
  58. package/esm/jodit.js +47 -1
  59. package/esm/modules/widget/file-selector/file-selector.js +2 -1
  60. package/esm/plugins/link/link.js +2 -1
  61. package/esm/typings.d.ts +1 -0
  62. package/package.json +1 -1
  63. package/types/config.d.ts +48 -4
  64. package/types/core/helpers/utils/config-proto.d.ts +21 -0
  65. package/types/core/ui/icon.d.ts +10 -0
  66. package/types/jodit.d.ts +44 -0
  67. package/types/typings.d.ts +1 -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.11.15
4
+ * Version: v4.12.3
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -717,17 +717,61 @@ let ConfigPrototype = {};
717
717
  * ```
718
718
  */ (0,_swc_helpers_define_property__WEBPACK_IMPORTED_MODULE_0__._)(this, "disablePlugins", []);
719
719
  /**
720
- * Init and download extra plugins
720
+ * Init and download extra plugins that are **not** already bundled/registered.
721
+ *
722
+ * For every name in this list that is not found in the plugin registry, Jodit
723
+ * loads it **at runtime over the network** from:
724
+ *
725
+ * ```text
726
+ * <basePath>plugins/<name>/<name>(.min).js
727
+ * ```
728
+ *
729
+ * (see {@link Config.basePath} and {@link Config.minified}). If the plugin is
730
+ * already registered — e.g. you imported it statically, or you use a bundle
731
+ * that ships it (such as the `jodit-pro` / `jodit-pro-react` "all plugins"
732
+ * build) — it is **skipped** and no request is made; in that case you don't
733
+ * need `extraPlugins` at all, just add the plugin's button.
721
734
  *
722
735
  * ```typescript
723
- * var editor = Jodit.make('.editor', {
736
+ * // Dynamic loading: fetches <basePath>plugins/emoji/emoji.js
737
+ * const editor = Jodit.make('.editor', {
724
738
  * extraPlugins: ['emoji']
725
739
  * });
726
740
  * ```
727
- * It will try load %SCRIPT_PATH%/plugins/emoji/emoji.js and after load will try init it
741
+ *
742
+ * You can also pass an explicit URL to bypass the `basePath` convention:
743
+ *
744
+ * ```typescript
745
+ * const editor = Jodit.make('.editor', {
746
+ * extraPlugins: [{ name: 'emoji', url: 'https://cdn.example.com/emoji.js' }]
747
+ * });
748
+ * ```
749
+ *
750
+ * Note: if you see a request to a malformed URL (e.g. `.../src/main.tsx?t=...plugins/emoji/emoji.js`),
751
+ * it means `basePath` was auto-detected incorrectly under your bundler — set
752
+ * {@link Config.basePath} explicitly. See the Plugin System docs for details.
728
753
  */ (0,_swc_helpers_define_property__WEBPACK_IMPORTED_MODULE_0__._)(this, "extraPlugins", []);
729
754
  /**
730
- * Base path for download extra plugins
755
+ * Base path used to build the URL for dynamically loaded {@link Config.extraPlugins}
756
+ * (and their styles): `<basePath>plugins/<name>/<name>(.min).js`.
757
+ *
758
+ * When not set, Jodit auto-detects it from `document.currentScript`, then the
759
+ * last `<script src>` on the page, then `location.href`. That detection works
760
+ * for classic `<script>` includes, but **fails under ESM bundlers / dev
761
+ * servers** (Vite, Webpack dev, etc.) where there is no script tag for the
762
+ * bundle — it falls back to the entry module URL (e.g. `main.tsx`) and produces
763
+ * a broken plugin URL.
764
+ *
765
+ * Fix: host the plugin files at a public location and point `basePath` there
766
+ * (note the trailing slash):
767
+ *
768
+ * ```typescript
769
+ * const editor = Jodit.make('.editor', {
770
+ * basePath: 'https://your-site.com/jodit-assets/',
771
+ * extraPlugins: ['emoji']
772
+ * // → loads https://your-site.com/jodit-assets/plugins/emoji/emoji.js
773
+ * });
774
+ * ```
731
775
  */ (0,_swc_helpers_define_property__WEBPACK_IMPORTED_MODULE_0__._)(this, "basePath", void 0);
732
776
  /**
733
777
  * Additional buttons appended to the {@link Config.buttons} list
@@ -1764,7 +1808,7 @@ __webpack_require__.r(__webpack_exports__);
1764
1808
  * ```
1765
1809
  * @packageDocumentation
1766
1810
  * @module constants
1767
- */ const APP_VERSION = "4.11.15";
1811
+ */ const APP_VERSION = "4.12.3";
1768
1812
  // prettier-ignore
1769
1813
  const ES = "es2015";
1770
1814
  const IS_ES_MODERN = true;
@@ -7537,6 +7581,7 @@ const completeUrl = (url)=>{
7537
7581
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
7538
7582
  /* harmony export */ ConfigDeepFlatten: function() { return /* binding */ ConfigDeepFlatten; },
7539
7583
  /* harmony export */ ConfigFlatten: function() { return /* binding */ ConfigFlatten; },
7584
+ /* harmony export */ ConfigMerge: function() { return /* binding */ ConfigMerge; },
7540
7585
  /* harmony export */ ConfigProto: function() { return /* binding */ ConfigProto; }
7541
7586
  /* harmony export */ });
7542
7587
  /* harmony import */ var jodit_core_helpers_checker_is_array__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(17312);
@@ -7647,7 +7692,37 @@ function ConfigFlatten(obj) {
7647
7692
  * const plain = Jodit.modules.Helpers.ConfigDeepFlatten(editor.o.image);
7648
7693
  * console.log(JSON.stringify(plain)); // {"dialogWidth":500, "openOnDblClick": true, "editSrc": true, ...}
7649
7694
  * ```
7650
- */ function ConfigDeepFlatten(obj) {
7695
+ */ /**
7696
+ * Deep-merges `source` into `target` in-place.
7697
+ * Uses the same merge semantics as {@link ConfigProto}:
7698
+ * - Nested plain objects are merged recursively
7699
+ * - {@link isAtom | Atomic} values replace the target entirely
7700
+ * - Everything else (primitives, arrays, class instances) replaces the target value
7701
+ *
7702
+ * Designed for patching `Config.defaultOptions` without losing existing keys:
7703
+ *
7704
+ * ```js
7705
+ * Jodit.configure({
7706
+ * controls: {
7707
+ * someButton: { group: 'custom' }
7708
+ * }
7709
+ * });
7710
+ * // Only `controls.someButton` is touched — all other controls remain intact.
7711
+ * ```
7712
+ *
7713
+ * @see {@link ConfigProto} for the prototype-chain variant used at editor creation time
7714
+ */ function ConfigMerge(target, source) {
7715
+ Object.keys(source).forEach((key)=>{
7716
+ const srcVal = source[key];
7717
+ const tgtVal = target[key];
7718
+ if ((0,jodit_core_helpers_checker_is_plain_object__WEBPACK_IMPORTED_MODULE_1__.isPlainObject)(srcVal) && (0,jodit_core_helpers_checker_is_plain_object__WEBPACK_IMPORTED_MODULE_1__.isPlainObject)(tgtVal) && !(0,_extend__WEBPACK_IMPORTED_MODULE_5__.isAtom)(srcVal)) {
7719
+ ConfigMerge(tgtVal, srcVal);
7720
+ } else {
7721
+ target[key] = srcVal;
7722
+ }
7723
+ });
7724
+ }
7725
+ function ConfigDeepFlatten(obj) {
7651
7726
  return (0,_utils__WEBPACK_IMPORTED_MODULE_6__.keys)(obj, false).reduce((app, key)=>{
7652
7727
  app[key] = (0,jodit_core_helpers_checker_is_plain_object__WEBPACK_IMPORTED_MODULE_1__.isPlainObject)(obj[key]) ? ConfigDeepFlatten(obj[key]) : obj[key];
7653
7728
  return app;
@@ -8233,6 +8308,7 @@ __webpack_require__.r(__webpack_exports__);
8233
8308
  /* harmony export */ $$: function() { return /* reexport safe */ _selector__WEBPACK_IMPORTED_MODULE_23__.$$; },
8234
8309
  /* harmony export */ ConfigDeepFlatten: function() { return /* reexport safe */ _config_proto__WEBPACK_IMPORTED_MODULE_7__.ConfigDeepFlatten; },
8235
8310
  /* harmony export */ ConfigFlatten: function() { return /* reexport safe */ _config_proto__WEBPACK_IMPORTED_MODULE_7__.ConfigFlatten; },
8311
+ /* harmony export */ ConfigMerge: function() { return /* reexport safe */ _config_proto__WEBPACK_IMPORTED_MODULE_7__.ConfigMerge; },
8236
8312
  /* harmony export */ ConfigProto: function() { return /* reexport safe */ _config_proto__WEBPACK_IMPORTED_MODULE_7__.ConfigProto; },
8237
8313
  /* harmony export */ ConnectionError: function() { return /* reexport safe */ _error__WEBPACK_IMPORTED_MODULE_13__.ConnectionError; },
8238
8314
  /* harmony export */ LimitedStack: function() { return /* reexport safe */ _stack__WEBPACK_IMPORTED_MODULE_25__.LimitedStack; },
@@ -15483,8 +15559,9 @@ UISpacer = (0,_swc_helpers_ts_decorate__WEBPACK_IMPORTED_MODULE_0__.__decorate)(
15483
15559
  /* harmony export */ });
15484
15560
  /* harmony import */ var _swc_helpers_define_property__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(25045);
15485
15561
  /* harmony import */ var jodit_core_constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(81937);
15486
- /* harmony import */ var jodit_core_helpers__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(65946);
15487
- /* harmony import */ var jodit_core_helpers_utils_css__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(80991);
15562
+ /* harmony import */ var jodit_core_dom_dom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(23211);
15563
+ /* harmony import */ var jodit_core_helpers__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(65946);
15564
+ /* harmony import */ var jodit_core_helpers_utils_css__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(80991);
15488
15565
  /*!
15489
15566
  * Jodit Editor (https://xdsoft.net/jodit/)
15490
15567
  * Released under MIT see LICENSE.txt in the project root for license information.
@@ -15495,12 +15572,13 @@ UISpacer = (0,_swc_helpers_ts_decorate__WEBPACK_IMPORTED_MODULE_0__.__decorate)(
15495
15572
 
15496
15573
 
15497
15574
 
15575
+
15498
15576
  class Icon {
15499
15577
  static getIcon(name) {
15500
15578
  if (/<svg/i.test(name)) {
15501
15579
  return name;
15502
15580
  }
15503
- const icon = Icon.icons[name] || Icon.icons[name.replace(/-/g, '_')] || Icon.icons[name.replace(/_/g, '-')] || Icon.icons[(0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_2__.camelCase)(name)] || Icon.icons[(0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_2__.kebabCase)(name)] || Icon.icons[name.toLowerCase()];
15581
+ const icon = Icon.icons[name] || Icon.icons[name.replace(/-/g, '_')] || Icon.icons[name.replace(/_/g, '-')] || Icon.icons[(0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_3__.camelCase)(name)] || Icon.icons[(0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_3__.kebabCase)(name)] || Icon.icons[name.toLowerCase()];
15504
15582
  if (!jodit_core_constants__WEBPACK_IMPORTED_MODULE_1__.IS_PROD && !icon) {
15505
15583
  console.warn(`Icon "${name}" not found`);
15506
15584
  }
@@ -15543,12 +15621,12 @@ class Icon {
15543
15621
  }
15544
15622
  if (iconURL) {
15545
15623
  iconElement = jodit.c.span();
15546
- (0,jodit_core_helpers_utils_css__WEBPACK_IMPORTED_MODULE_3__.css)(iconElement, 'backgroundImage', 'url(' + iconURL.replace('{basePath}', (jodit === null || jodit === void 0 ? void 0 : jodit.basePath) || '') + ')');
15624
+ (0,jodit_core_helpers_utils_css__WEBPACK_IMPORTED_MODULE_4__.css)(iconElement, 'backgroundImage', 'url(' + iconURL.replace('{basePath}', (jodit === null || jodit === void 0 ? void 0 : jodit.basePath) || '') + ')');
15547
15625
  } else {
15548
15626
  var _jodit_o_extraIcons;
15549
15627
  const svg = iconFromEvent || Icon.get(name, '') || ((_jodit_o_extraIcons = jodit.o.extraIcons) === null || _jodit_o_extraIcons === void 0 ? void 0 : _jodit_o_extraIcons[name]);
15550
15628
  if (svg) {
15551
- iconElement = jodit.c.fromHTML(svg.trim());
15629
+ iconElement = Icon.toIconElement(jodit, svg.trim());
15552
15630
  if (!/^<svg/i.test(name)) {
15553
15631
  iconElement.classList.add('jodit-icon_' + clearName);
15554
15632
  }
@@ -15564,6 +15642,18 @@ class Icon {
15564
15642
  }
15565
15643
  return iconElement;
15566
15644
  }
15645
+ /**
15646
+ * Turn a raw icon string into an element with a `classList`.
15647
+ *
15648
+ * A plain-text icon (e.g. an emoji/text glyph) makes `fromHTML` return a
15649
+ * Text node, which has no `classList`; wrap it in a span so classes/styles
15650
+ * can be applied and `makeIcon` never crashes on `iconElement.classList`.
15651
+ * Note: SVG icons are `SVGElement` (not `HTMLElement`) but are still Element
15652
+ * nodes with a `classList`, so we check `isElement`, not `isHTMLElement`.
15653
+ */ static toIconElement(jodit, svg) {
15654
+ const node = jodit.c.fromHTML(svg);
15655
+ return jodit_core_dom_dom__WEBPACK_IMPORTED_MODULE_2__.Dom.isElement(node) ? node : jodit.c.span('jodit-icon_text', node);
15656
+ }
15567
15657
  }
15568
15658
  (0,_swc_helpers_define_property__WEBPACK_IMPORTED_MODULE_0__._)(Icon, "icons", {});
15569
15659
  (0,_swc_helpers_define_property__WEBPACK_IMPORTED_MODULE_0__._)(Icon, "__cache", new Map());
@@ -16662,6 +16752,51 @@ class Jodit extends jodit_modules__WEBPACK_IMPORTED_MODULE_10__.ViewWithToolbar
16662
16752
  */ static get defaultOptions() {
16663
16753
  return jodit_config__WEBPACK_IMPORTED_MODULE_9__.Config.defaultOptions;
16664
16754
  }
16755
+ /**
16756
+ * Deep-merges partial options into the global defaults without replacing
16757
+ * top-level objects. This lets you patch nested settings (e.g. a single
16758
+ * button inside `controls`) without losing the rest:
16759
+ *
16760
+ * ```js
16761
+ * // Add a custom button — all existing controls remain untouched
16762
+ * Jodit.configure({
16763
+ * controls: {
16764
+ * myButton: {
16765
+ * icon: 'pencil',
16766
+ * command: 'selectall'
16767
+ * }
16768
+ * }
16769
+ * });
16770
+ *
16771
+ * // Override only the `group` of an existing button
16772
+ * Jodit.configure({
16773
+ * controls: {
16774
+ * someButton: { group: 'custom' }
16775
+ * }
16776
+ * });
16777
+ *
16778
+ * // Works with any nested option
16779
+ * Jodit.configure({
16780
+ * createAttributes: {
16781
+ * div: { class: 'my-class' }
16782
+ * }
16783
+ * });
16784
+ *
16785
+ * // Use Jodit.atom() to replace a nested value entirely instead of merging
16786
+ * Jodit.configure({
16787
+ * controls: {
16788
+ * fontsize: {
16789
+ * list: Jodit.atom([8, 9, 10])
16790
+ * }
16791
+ * }
16792
+ * });
16793
+ * ```
16794
+ *
16795
+ * @see {@link ConfigMerge} for the merge algorithm
16796
+ * @see {@link ConfigProto} for per-instance prototype-based merge used at editor creation time
16797
+ */ static configure(options) {
16798
+ (0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_6__.ConfigMerge)(Jodit.defaultOptions, options);
16799
+ }
16665
16800
  get createInside() {
16666
16801
  return new jodit_modules__WEBPACK_IMPORTED_MODULE_10__.Create(()=>this.ed, this.o.createAttributes);
16667
16802
  }
@@ -24817,7 +24952,8 @@ jodit_core_ui__WEBPACK_IMPORTED_MODULE_2__.Icon.set('palette', (_palette_svg__WE
24817
24952
  type: 'submit',
24818
24953
  variant: 'primary',
24819
24954
  text: 'Insert'
24820
- }), form = new jodit_core_ui__WEBPACK_IMPORTED_MODULE_2__.UIForm(editor, [
24955
+ });
24956
+ const form = new jodit_core_ui__WEBPACK_IMPORTED_MODULE_2__.UIForm(editor, [
24821
24957
  new jodit_core_ui__WEBPACK_IMPORTED_MODULE_2__.UIInput(editor, {
24822
24958
  required: true,
24823
24959
  label: 'URL',
@@ -35058,7 +35194,8 @@ jodit_config__WEBPACK_IMPORTED_MODULE_2__.Config.prototype.controls.link = {
35058
35194
  }
35059
35195
  __generateForm(current, close) {
35060
35196
  const { jodit } = this;
35061
- const i18n = jodit.i18n.bind(jodit), { openInNewTabCheckbox, openInNewTabCheckboxDefaultChecked, noFollowCheckbox, formTemplate, formClassName, modeClassName } = jodit.o.link;
35197
+ const i18n = jodit.i18n.bind(jodit);
35198
+ const { openInNewTabCheckbox, openInNewTabCheckboxDefaultChecked, noFollowCheckbox, formTemplate, formClassName, modeClassName } = jodit.o.link;
35062
35199
  const html = formTemplate(jodit);
35063
35200
  const form = (0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_5__.isString)(html) ? jodit.c.fromHTML(html, {
35064
35201
  target_checkbox_box: openInNewTabCheckbox,