jodit 4.12.37 → 4.12.39

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 (65) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +4 -4
  3. package/es2015/jodit.css +1 -1
  4. package/es2015/jodit.fat.min.js +4 -4
  5. package/es2015/jodit.js +69 -5
  6. package/es2015/jodit.min.js +5 -5
  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 +5 -5
  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 +69 -5
  20. package/es2021/jodit.min.js +7 -7
  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 +6 -6
  29. package/es2021.en/jodit.js +69 -5
  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 +69 -5
  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/config.d.ts +22 -0
  52. package/esm/config.js +14 -0
  53. package/esm/core/constants.js +1 -1
  54. package/esm/core/global.js +4 -0
  55. package/esm/core/helpers/utils/append-script.js +6 -0
  56. package/esm/core/helpers/utils/scroll-into-view.js +6 -2
  57. package/esm/plugins/fullsize/fullsize.js +11 -1
  58. package/esm/plugins/link/config.d.ts +8 -0
  59. package/esm/plugins/link/config.js +1 -0
  60. package/esm/plugins/link/link.js +30 -0
  61. package/esm/types/view.d.ts +6 -0
  62. package/package.json +1 -1
  63. package/types/config.d.ts +22 -0
  64. package/types/plugins/link/config.d.ts +8 -0
  65. package/types/types/view.d.ts +6 -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.37
4
+ * Version: v4.12.39
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -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.37
4
+ * Version: v4.12.39
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -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.37
4
+ * Version: v4.12.39
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -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.37
4
+ * Version: v4.12.39
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -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.37
4
+ * Version: v4.12.39
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -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.37
4
+ * Version: v4.12.39
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -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.37
4
+ * Version: v4.12.39
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
package/es5/polyfills.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.12.37
4
+ * Version: v4.12.39
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -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.37
4
+ * Version: v4.12.39
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
package/esm/config.d.ts CHANGED
@@ -267,6 +267,20 @@ declare class Config implements IViewOptions {
267
267
  * ```
268
268
  */
269
269
  shadowRoot: Nullable<ShadowRoot>;
270
+ /**
271
+ * CSP nonce applied to every `<style>`, `<script>` and `<link>` element
272
+ * Jodit injects at runtime (plugin styles, CDN scripts for ACE/beautify,
273
+ * downloaded stylesheets). Set it to the same nonce your server puts in the
274
+ * `Content-Security-Policy` header so a strict `style-src`/`script-src`
275
+ * policy does not block the editor.
276
+ *
277
+ * ```js
278
+ * Jodit.make('#editor', {
279
+ * nonce: 'r4nd0m'
280
+ * });
281
+ * ```
282
+ */
283
+ nonce: string;
270
284
  /**
271
285
  * Base CSS `z-index` for the editor UI (toolbar, popups, dialogs).
272
286
  * Set to a higher value when other page elements overlap the editor.
@@ -1383,6 +1397,14 @@ interface Config {
1383
1397
  * Wrap inserted link
1384
1398
  */
1385
1399
  processPastedLink: boolean;
1400
+ /**
1401
+ * When opening the link dialog for a new link with an empty URL field,
1402
+ * pre-fill it from the selected text if that text looks like a URL or
1403
+ * an email address (`example.com` → `https://example.com`,
1404
+ * `user@site.com` → `mailto:user@site.com`). Plain text that is not a
1405
+ * URL/email is left untouched. Default: false.
1406
+ */
1407
+ deriveUrlFromText: boolean;
1386
1408
  /**
1387
1409
  * Show `no follow` checkbox in link dialog.
1388
1410
  */
package/esm/config.js CHANGED
@@ -278,6 +278,20 @@ class Config {
278
278
  * ```
279
279
  */
280
280
  this.shadowRoot = null;
281
+ /**
282
+ * CSP nonce applied to every `<style>`, `<script>` and `<link>` element
283
+ * Jodit injects at runtime (plugin styles, CDN scripts for ACE/beautify,
284
+ * downloaded stylesheets). Set it to the same nonce your server puts in the
285
+ * `Content-Security-Policy` header so a strict `style-src`/`script-src`
286
+ * policy does not block the editor.
287
+ *
288
+ * ```js
289
+ * Jodit.make('#editor', {
290
+ * nonce: 'r4nd0m'
291
+ * });
292
+ * ```
293
+ */
294
+ this.nonce = '';
281
295
  /**
282
296
  * Base CSS `z-index` for the editor UI (toolbar, popups, dialogs).
283
297
  * Set to a higher value when other page elements overlap the editor.
@@ -3,7 +3,7 @@
3
3
  * Released under MIT see LICENSE.txt in the project root for license information.
4
4
  * Copyright (c) 2013-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net
5
5
  */
6
- export const APP_VERSION = "4.12.37";
6
+ export const APP_VERSION = "4.12.39";
7
7
  // prettier-ignore
8
8
  export const ES = "es2020";
9
9
  export const IS_ES_MODERN = true;
@@ -74,6 +74,10 @@ export function getContainer(jodit, classFunc, tag = 'div', createInsideEditor =
74
74
  const box = c.element(tag, {
75
75
  className: `jodit jodit-${kebabCase(name)}-container jodit-box`
76
76
  });
77
+ // Let a strict CSP accept the injected <style>/<script> box
78
+ if (view.o.nonce && (tag === 'style' || tag === 'script')) {
79
+ box.setAttribute('nonce', view.o.nonce);
80
+ }
77
81
  box.classList.add(`jodit_theme_${view.o.theme || 'default'}`);
78
82
  body.appendChild(box);
79
83
  data[key] = box;
@@ -31,6 +31,9 @@ export const appendScriptAsync = cacheLoaders((jodit, url) => {
31
31
  async: true,
32
32
  src: completeUrl(url)
33
33
  });
34
+ if (jodit.o.nonce) {
35
+ script.setAttribute('nonce', jodit.o.nonce);
36
+ }
34
37
  jodit.e.one(script, 'error', reject).one(script, 'load', resolve);
35
38
  jodit.od.body.appendChild(script);
36
39
  });
@@ -47,6 +50,9 @@ export const appendStyleAsync = cacheLoaders((jodit, url) => {
47
50
  link.rel = 'stylesheet';
48
51
  link.media = 'all';
49
52
  link.crossOrigin = 'anonymous';
53
+ if (jodit.o.nonce) {
54
+ link.setAttribute('nonce', jodit.o.nonce);
55
+ }
50
56
  const callback = () => resolve(link);
51
57
  !jodit.isInDestruct &&
52
58
  jodit.e.on(link, 'load', callback).on(link, 'error', reject);
@@ -24,8 +24,12 @@ export function inView(elm, root, doc) {
24
24
  return false;
25
25
  }
26
26
  }
27
- // Check it's within the document viewport
28
- return (top <= ((doc.documentElement && doc.documentElement.clientHeight) || 0));
27
+ // Check it's within the document viewport: the element must not be below
28
+ // the viewport bottom, and (its bottom) must not be above the viewport top —
29
+ // the latter guard was missing, so an element scrolled above the top was
30
+ // wrongly reported as visible and never scrolled to. See #1279
31
+ const clientHeight = (doc.documentElement && doc.documentElement.clientHeight) || 0;
32
+ return top <= clientHeight && top + height >= 0;
29
33
  }
30
34
  /**
31
35
  * Scroll element into view if it is not in view
@@ -15,7 +15,7 @@ export function fullsize(editor) {
15
15
  editor.registerButton({
16
16
  name: 'fullsize'
17
17
  });
18
- let isEnabled = false, oldHeight = 0, oldWidth = 0, wasToggled = false;
18
+ let isEnabled = false, oldHeight = 0, oldWidth = 0, savedScrollLeft = 0, savedScrollTop = 0, wasToggled = false;
19
19
  const resize = () => {
20
20
  const { container, events } = editor;
21
21
  if (!events) {
@@ -72,6 +72,13 @@ export function fullsize(editor) {
72
72
  ((fullsizeStack.size === 1 && enable) ||
73
73
  (fullsizeStack.size === 0 && !enable));
74
74
  if (shouldToggleGlobalFullsize) {
75
+ // Entering fullsize sets `position: fixed` on <html>, which
76
+ // makes the browser reset the page scroll to the top. Remember
77
+ // the scroll position so it can be restored on exit (#1255).
78
+ if (enable) {
79
+ savedScrollLeft = editor.ow.scrollX;
80
+ savedScrollTop = editor.ow.scrollY;
81
+ }
75
82
  let node = container.parentNode;
76
83
  while (node &&
77
84
  node.nodeType !== Node.DOCUMENT_NODE &&
@@ -80,6 +87,9 @@ export function fullsize(editor) {
80
87
  node = node.parentNode;
81
88
  }
82
89
  resize();
90
+ if (!enable) {
91
+ editor.ow.scrollTo(savedScrollLeft, savedScrollTop);
92
+ }
83
93
  }
84
94
  events.fire('afterResize');
85
95
  };
@@ -27,6 +27,14 @@ declare module 'jodit/config' {
27
27
  * Wrap inserted link
28
28
  */
29
29
  processPastedLink: boolean;
30
+ /**
31
+ * When opening the link dialog for a new link with an empty URL field,
32
+ * pre-fill it from the selected text if that text looks like a URL or
33
+ * an email address (`example.com` → `https://example.com`,
34
+ * `user@site.com` → `mailto:user@site.com`). Plain text that is not a
35
+ * URL/email is left untouched. Default: false.
36
+ */
37
+ deriveUrlFromText: boolean;
30
38
  /**
31
39
  * Show `no follow` checkbox in link dialog.
32
40
  */
@@ -14,6 +14,7 @@ Config.prototype.link = {
14
14
  followOnDblClick: false,
15
15
  processVideoLink: true,
16
16
  processPastedLink: true,
17
+ deriveUrlFromText: false,
17
18
  noFollowCheckbox: true,
18
19
  openInNewTabCheckbox: true,
19
20
  openInNewTabCheckboxDefaultChecked: false,
@@ -167,6 +167,12 @@ export class link extends Plugin {
167
167
  }
168
168
  else {
169
169
  Dom.hide(unlink);
170
+ if (jodit.o.link.deriveUrlFromText &&
171
+ url_input &&
172
+ !isImageContent &&
173
+ !url_input.value.trim()) {
174
+ url_input.value = guessUrlFromText(content_input.value);
175
+ }
170
176
  if (openInNewTabCheckbox && target_checkbox) {
171
177
  target_checkbox.checked = openInNewTabCheckboxDefaultChecked;
172
178
  }
@@ -293,6 +299,30 @@ __decorate([
293
299
  autobind
294
300
  ], link.prototype, "__onClickReadOnlyLink", null);
295
301
  pluginSystem.add('link', link);
302
+ /**
303
+ * Guess a usable `href` from the selected text for the link dialog.
304
+ * Returns an empty string when the text is not a plausible URL/email,
305
+ * so plain text (e.g. "click here") is left untouched.
306
+ */
307
+ function guessUrlFromText(text) {
308
+ const value = text.trim();
309
+ if (!value || /\s/.test(value)) {
310
+ return '';
311
+ }
312
+ // already an explicit scheme, an anchor or a relative path
313
+ if (/^(https?:|mailto:|tel:|ftp:|#|\/|\.{1,2}\/)/i.test(value)) {
314
+ return value;
315
+ }
316
+ // email address -> mailto:
317
+ if (/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
318
+ return `mailto:${value}`;
319
+ }
320
+ // bare domain like example.com or www.example.com/path -> https://
321
+ if (/^[a-z0-9-]+(\.[a-z0-9-]+)+(\/\S*)?$/i.test(value)) {
322
+ return `https://${value}`;
323
+ }
324
+ return '';
325
+ }
296
326
  function writeClasses(modeClassName, className_input, className_select, a) {
297
327
  var _a;
298
328
  if (modeClassName && (className_input !== null && className_input !== void 0 ? className_input : className_select)) {
@@ -63,6 +63,12 @@ interface IViewOptions extends ILanguageOptions, IToolbarOptions {
63
63
  createAttributes?: IDictionary<Attributes | NodeFunction>;
64
64
  events?: IDictionary<(...args: any[]) => any>;
65
65
  shadowRoot?: Nullable<ShadowRoot>;
66
+ /**
67
+ * CSP nonce applied to every `<style>`/`<script>`/`<link>` element Jodit
68
+ * injects at runtime, so a strict `style-src`/`script-src` policy does not
69
+ * block them.
70
+ */
71
+ nonce?: string;
66
72
  popupRoot?: Nullable<HTMLElement>;
67
73
  ownerWindow?: Window;
68
74
  language?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jodit",
3
- "version": "4.12.37",
3
+ "version": "4.12.39",
4
4
  "description": "Jodit is an awesome and useful wysiwyg editor with filebrowser",
5
5
  "main": "esm/index.js",
6
6
  "types": "types/index.d.ts",
package/types/config.d.ts CHANGED
@@ -267,6 +267,20 @@ declare class Config implements IViewOptions {
267
267
  * ```
268
268
  */
269
269
  shadowRoot: Nullable<ShadowRoot>;
270
+ /**
271
+ * CSP nonce applied to every `<style>`, `<script>` and `<link>` element
272
+ * Jodit injects at runtime (plugin styles, CDN scripts for ACE/beautify,
273
+ * downloaded stylesheets). Set it to the same nonce your server puts in the
274
+ * `Content-Security-Policy` header so a strict `style-src`/`script-src`
275
+ * policy does not block the editor.
276
+ *
277
+ * ```js
278
+ * Jodit.make('#editor', {
279
+ * nonce: 'r4nd0m'
280
+ * });
281
+ * ```
282
+ */
283
+ nonce: string;
270
284
  /**
271
285
  * Base CSS `z-index` for the editor UI (toolbar, popups, dialogs).
272
286
  * Set to a higher value when other page elements overlap the editor.
@@ -1383,6 +1397,14 @@ interface Config {
1383
1397
  * Wrap inserted link
1384
1398
  */
1385
1399
  processPastedLink: boolean;
1400
+ /**
1401
+ * When opening the link dialog for a new link with an empty URL field,
1402
+ * pre-fill it from the selected text if that text looks like a URL or
1403
+ * an email address (`example.com` → `https://example.com`,
1404
+ * `user@site.com` → `mailto:user@site.com`). Plain text that is not a
1405
+ * URL/email is left untouched. Default: false.
1406
+ */
1407
+ deriveUrlFromText: boolean;
1386
1408
  /**
1387
1409
  * Show `no follow` checkbox in link dialog.
1388
1410
  */
@@ -27,6 +27,14 @@ declare module 'jodit/config' {
27
27
  * Wrap inserted link
28
28
  */
29
29
  processPastedLink: boolean;
30
+ /**
31
+ * When opening the link dialog for a new link with an empty URL field,
32
+ * pre-fill it from the selected text if that text looks like a URL or
33
+ * an email address (`example.com` → `https://example.com`,
34
+ * `user@site.com` → `mailto:user@site.com`). Plain text that is not a
35
+ * URL/email is left untouched. Default: false.
36
+ */
37
+ deriveUrlFromText: boolean;
30
38
  /**
31
39
  * Show `no follow` checkbox in link dialog.
32
40
  */
@@ -63,6 +63,12 @@ interface IViewOptions extends ILanguageOptions, IToolbarOptions {
63
63
  createAttributes?: IDictionary<Attributes | NodeFunction>;
64
64
  events?: IDictionary<(...args: any[]) => any>;
65
65
  shadowRoot?: Nullable<ShadowRoot>;
66
+ /**
67
+ * CSP nonce applied to every `<style>`/`<script>`/`<link>` element Jodit
68
+ * injects at runtime, so a strict `style-src`/`script-src` policy does not
69
+ * block them.
70
+ */
71
+ nonce?: string;
66
72
  popupRoot?: Nullable<HTMLElement>;
67
73
  ownerWindow?: Window;
68
74
  language?: string;