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
@@ -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
@@ -1758,7 +1802,7 @@ __webpack_require__.r(__webpack_exports__);
1758
1802
  * ```
1759
1803
  * @packageDocumentation
1760
1804
  * @module constants
1761
- */ const APP_VERSION = "4.11.15";
1805
+ */ const APP_VERSION = "4.12.3";
1762
1806
  // prettier-ignore
1763
1807
  const ES = "es2021";
1764
1808
  const IS_ES_MODERN = true;
@@ -7512,6 +7556,7 @@ const completeUrl = (url)=>{
7512
7556
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
7513
7557
  /* harmony export */ ConfigDeepFlatten: function() { return /* binding */ ConfigDeepFlatten; },
7514
7558
  /* harmony export */ ConfigFlatten: function() { return /* binding */ ConfigFlatten; },
7559
+ /* harmony export */ ConfigMerge: function() { return /* binding */ ConfigMerge; },
7515
7560
  /* harmony export */ ConfigProto: function() { return /* binding */ ConfigProto; }
7516
7561
  /* harmony export */ });
7517
7562
  /* harmony import */ var jodit_core_helpers_checker_is_array__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(17312);
@@ -7622,7 +7667,37 @@ function ConfigFlatten(obj) {
7622
7667
  * const plain = Jodit.modules.Helpers.ConfigDeepFlatten(editor.o.image);
7623
7668
  * console.log(JSON.stringify(plain)); // {"dialogWidth":500, "openOnDblClick": true, "editSrc": true, ...}
7624
7669
  * ```
7625
- */ function ConfigDeepFlatten(obj) {
7670
+ */ /**
7671
+ * Deep-merges `source` into `target` in-place.
7672
+ * Uses the same merge semantics as {@link ConfigProto}:
7673
+ * - Nested plain objects are merged recursively
7674
+ * - {@link isAtom | Atomic} values replace the target entirely
7675
+ * - Everything else (primitives, arrays, class instances) replaces the target value
7676
+ *
7677
+ * Designed for patching `Config.defaultOptions` without losing existing keys:
7678
+ *
7679
+ * ```js
7680
+ * Jodit.configure({
7681
+ * controls: {
7682
+ * someButton: { group: 'custom' }
7683
+ * }
7684
+ * });
7685
+ * // Only `controls.someButton` is touched — all other controls remain intact.
7686
+ * ```
7687
+ *
7688
+ * @see {@link ConfigProto} for the prototype-chain variant used at editor creation time
7689
+ */ function ConfigMerge(target, source) {
7690
+ Object.keys(source).forEach((key)=>{
7691
+ const srcVal = source[key];
7692
+ const tgtVal = target[key];
7693
+ 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)) {
7694
+ ConfigMerge(tgtVal, srcVal);
7695
+ } else {
7696
+ target[key] = srcVal;
7697
+ }
7698
+ });
7699
+ }
7700
+ function ConfigDeepFlatten(obj) {
7626
7701
  return (0,_utils__WEBPACK_IMPORTED_MODULE_6__.keys)(obj, false).reduce((app, key)=>{
7627
7702
  app[key] = (0,jodit_core_helpers_checker_is_plain_object__WEBPACK_IMPORTED_MODULE_1__.isPlainObject)(obj[key]) ? ConfigDeepFlatten(obj[key]) : obj[key];
7628
7703
  return app;
@@ -8207,6 +8282,7 @@ __webpack_require__.r(__webpack_exports__);
8207
8282
  /* harmony export */ $$: function() { return /* reexport safe */ _selector__WEBPACK_IMPORTED_MODULE_23__.$$; },
8208
8283
  /* harmony export */ ConfigDeepFlatten: function() { return /* reexport safe */ _config_proto__WEBPACK_IMPORTED_MODULE_7__.ConfigDeepFlatten; },
8209
8284
  /* harmony export */ ConfigFlatten: function() { return /* reexport safe */ _config_proto__WEBPACK_IMPORTED_MODULE_7__.ConfigFlatten; },
8285
+ /* harmony export */ ConfigMerge: function() { return /* reexport safe */ _config_proto__WEBPACK_IMPORTED_MODULE_7__.ConfigMerge; },
8210
8286
  /* harmony export */ ConfigProto: function() { return /* reexport safe */ _config_proto__WEBPACK_IMPORTED_MODULE_7__.ConfigProto; },
8211
8287
  /* harmony export */ ConnectionError: function() { return /* reexport safe */ _error__WEBPACK_IMPORTED_MODULE_13__.ConnectionError; },
8212
8288
  /* harmony export */ LimitedStack: function() { return /* reexport safe */ _stack__WEBPACK_IMPORTED_MODULE_25__.LimitedStack; },
@@ -15367,8 +15443,9 @@ UISpacer = (0,_swc_helpers_ts_decorate__WEBPACK_IMPORTED_MODULE_0__.__decorate)(
15367
15443
  /* harmony export */ });
15368
15444
  /* harmony import */ var _swc_helpers_define_property__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(25045);
15369
15445
  /* harmony import */ var jodit_core_constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(81937);
15370
- /* harmony import */ var jodit_core_helpers__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(65946);
15371
- /* harmony import */ var jodit_core_helpers_utils_css__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(80991);
15446
+ /* harmony import */ var jodit_core_dom_dom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(23211);
15447
+ /* harmony import */ var jodit_core_helpers__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(65946);
15448
+ /* harmony import */ var jodit_core_helpers_utils_css__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(80991);
15372
15449
  /*!
15373
15450
  * Jodit Editor (https://xdsoft.net/jodit/)
15374
15451
  * Released under MIT see LICENSE.txt in the project root for license information.
@@ -15379,12 +15456,13 @@ UISpacer = (0,_swc_helpers_ts_decorate__WEBPACK_IMPORTED_MODULE_0__.__decorate)(
15379
15456
 
15380
15457
 
15381
15458
 
15459
+
15382
15460
  class Icon {
15383
15461
  static getIcon(name) {
15384
15462
  if (/<svg/i.test(name)) {
15385
15463
  return name;
15386
15464
  }
15387
- 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()];
15465
+ 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()];
15388
15466
  if (!jodit_core_constants__WEBPACK_IMPORTED_MODULE_1__.IS_PROD && !icon) {
15389
15467
  console.warn(`Icon "${name}" not found`);
15390
15468
  }
@@ -15425,11 +15503,11 @@ class Icon {
15425
15503
  }
15426
15504
  if (iconURL) {
15427
15505
  iconElement = jodit.c.span();
15428
- (0,jodit_core_helpers_utils_css__WEBPACK_IMPORTED_MODULE_3__.css)(iconElement, 'backgroundImage', 'url(' + iconURL.replace('{basePath}', jodit?.basePath || '') + ')');
15506
+ (0,jodit_core_helpers_utils_css__WEBPACK_IMPORTED_MODULE_4__.css)(iconElement, 'backgroundImage', 'url(' + iconURL.replace('{basePath}', jodit?.basePath || '') + ')');
15429
15507
  } else {
15430
15508
  const svg = iconFromEvent || Icon.get(name, '') || jodit.o.extraIcons?.[name];
15431
15509
  if (svg) {
15432
- iconElement = jodit.c.fromHTML(svg.trim());
15510
+ iconElement = Icon.toIconElement(jodit, svg.trim());
15433
15511
  if (!/^<svg/i.test(name)) {
15434
15512
  iconElement.classList.add('jodit-icon_' + clearName);
15435
15513
  }
@@ -15445,6 +15523,18 @@ class Icon {
15445
15523
  }
15446
15524
  return iconElement;
15447
15525
  }
15526
+ /**
15527
+ * Turn a raw icon string into an element with a `classList`.
15528
+ *
15529
+ * A plain-text icon (e.g. an emoji/text glyph) makes `fromHTML` return a
15530
+ * Text node, which has no `classList`; wrap it in a span so classes/styles
15531
+ * can be applied and `makeIcon` never crashes on `iconElement.classList`.
15532
+ * Note: SVG icons are `SVGElement` (not `HTMLElement`) but are still Element
15533
+ * nodes with a `classList`, so we check `isElement`, not `isHTMLElement`.
15534
+ */ static toIconElement(jodit, svg) {
15535
+ const node = jodit.c.fromHTML(svg);
15536
+ return jodit_core_dom_dom__WEBPACK_IMPORTED_MODULE_2__.Dom.isElement(node) ? node : jodit.c.span('jodit-icon_text', node);
15537
+ }
15448
15538
  }
15449
15539
  (0,_swc_helpers_define_property__WEBPACK_IMPORTED_MODULE_0__._)(Icon, "icons", {});
15450
15540
  (0,_swc_helpers_define_property__WEBPACK_IMPORTED_MODULE_0__._)(Icon, "__cache", new Map());
@@ -16532,6 +16622,51 @@ class Jodit extends jodit_modules__WEBPACK_IMPORTED_MODULE_9__.ViewWithToolbar {
16532
16622
  */ static get defaultOptions() {
16533
16623
  return jodit_config__WEBPACK_IMPORTED_MODULE_8__.Config.defaultOptions;
16534
16624
  }
16625
+ /**
16626
+ * Deep-merges partial options into the global defaults without replacing
16627
+ * top-level objects. This lets you patch nested settings (e.g. a single
16628
+ * button inside `controls`) without losing the rest:
16629
+ *
16630
+ * ```js
16631
+ * // Add a custom button — all existing controls remain untouched
16632
+ * Jodit.configure({
16633
+ * controls: {
16634
+ * myButton: {
16635
+ * icon: 'pencil',
16636
+ * command: 'selectall'
16637
+ * }
16638
+ * }
16639
+ * });
16640
+ *
16641
+ * // Override only the `group` of an existing button
16642
+ * Jodit.configure({
16643
+ * controls: {
16644
+ * someButton: { group: 'custom' }
16645
+ * }
16646
+ * });
16647
+ *
16648
+ * // Works with any nested option
16649
+ * Jodit.configure({
16650
+ * createAttributes: {
16651
+ * div: { class: 'my-class' }
16652
+ * }
16653
+ * });
16654
+ *
16655
+ * // Use Jodit.atom() to replace a nested value entirely instead of merging
16656
+ * Jodit.configure({
16657
+ * controls: {
16658
+ * fontsize: {
16659
+ * list: Jodit.atom([8, 9, 10])
16660
+ * }
16661
+ * }
16662
+ * });
16663
+ * ```
16664
+ *
16665
+ * @see {@link ConfigMerge} for the merge algorithm
16666
+ * @see {@link ConfigProto} for per-instance prototype-based merge used at editor creation time
16667
+ */ static configure(options) {
16668
+ (0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_5__.ConfigMerge)(Jodit.defaultOptions, options);
16669
+ }
16535
16670
  get createInside() {
16536
16671
  return new jodit_modules__WEBPACK_IMPORTED_MODULE_9__.Create(()=>this.ed, this.o.createAttributes);
16537
16672
  }
@@ -24613,7 +24748,8 @@ jodit_core_ui__WEBPACK_IMPORTED_MODULE_2__.Icon.set('palette', (_palette_svg__WE
24613
24748
  type: 'submit',
24614
24749
  variant: 'primary',
24615
24750
  text: 'Insert'
24616
- }), form = new jodit_core_ui__WEBPACK_IMPORTED_MODULE_2__.UIForm(editor, [
24751
+ });
24752
+ const form = new jodit_core_ui__WEBPACK_IMPORTED_MODULE_2__.UIForm(editor, [
24617
24753
  new jodit_core_ui__WEBPACK_IMPORTED_MODULE_2__.UIInput(editor, {
24618
24754
  required: true,
24619
24755
  label: 'URL',
@@ -34061,7 +34197,8 @@ jodit_config__WEBPACK_IMPORTED_MODULE_2__.Config.prototype.controls.link = {
34061
34197
  }
34062
34198
  __generateForm(current, close) {
34063
34199
  const { jodit } = this;
34064
- const i18n = jodit.i18n.bind(jodit), { openInNewTabCheckbox, openInNewTabCheckboxDefaultChecked, noFollowCheckbox, formTemplate, formClassName, modeClassName } = jodit.o.link;
34200
+ const i18n = jodit.i18n.bind(jodit);
34201
+ const { openInNewTabCheckbox, openInNewTabCheckboxDefaultChecked, noFollowCheckbox, formTemplate, formClassName, modeClassName } = jodit.o.link;
34065
34202
  const html = formTemplate(jodit);
34066
34203
  const form = (0,jodit_core_helpers__WEBPACK_IMPORTED_MODULE_5__.isString)(html) ? jodit.c.fromHTML(html, {
34067
34204
  target_checkbox_box: openInNewTabCheckbox,