Skip to content

Releases: xdan/jodit

4.15.3

Choose a tag to compare

@github-actions github-actions released this 14 Sep 16:21

🐛 Bug Fix

  • #1474 An iframe lost its box when the editor was created inside a hidden container. The resizer wraps every iframe in a <jodit> element and copied offsetWidth/offsetHeight into it, but both are 0 while an ancestor has display:none, so the wrapper was pinned to 0x0 and never corrected once the container became visible. The following content then painted over the video. The wrapper now falls back to the iframe's own width/height attributes when the element cannot be measured, and is left to size itself when there is nothing to fall back to. Relative values such as width="100%" are not turned into a fixed pixel box.

4.15.2

Choose a tag to compare

@github-actions github-actions released this 14 Sep 14:57

🐛 Bug Fix

  • Enter inside a table cell always inserted a <br>, even when the cell already contained a block. The cell check in the Enter plugin walked all the way up to the <td>/<th> and ignored any <p> or heading in between, so every line of a cell stayed inside one block and applying a block style restyled all of them at once. A cell that holds a real block is now split like anywhere else, while bare cell content keeps inserting a <br> (a cell cannot be split into two cells) and Shift+Enter still inserts a <br> everywhere. Reported by Kevin Sormann (li-life web+it, Jodit OEM).

4.15.1

Choose a tag to compare

@github-actions github-actions released this 10 Sep 15:09

🐛 Bug Fix

  • File browser: the "Sort by" select painted its dropdown caret over the option text. The .jodit-select caret rule was overridden by the more specific .jodit .jodit-input padding, so there was no room for the icon; the rule now lives inside .jodit, the caret is sized like a regular icon and the option labels use plain / instead of /, which macOS renders as colour emoji.

4.15.0

Choose a tag to compare

@github-actions github-actions released this 09 Sep 21:33

💅 Polish

  • Redrew the 82 built-in toolbar, dialog and image-editor icons as a consistent, compact SVG family with balanced strokes and rounded corners.
  • Improved small-size readability of lists, alignment and line-height controls; distinguished row and column insertion, clarified cell merging and splitting, and restored spacing in font-size and source-code icons.
  • Preserved theme colors and the text-color indicator, enlarged dropdown chevrons and refined the assistant icon. Updated visual regression snapshots for the new icon family.

🏠 Internal

  • Allow an explicit release version through make newversion releaseVersion=4.15.0; the default remains a patch increment.

4.14.7

Choose a tag to compare

@github-actions github-actions released this 09 Sep 10:36

🐛 Bug Fix

  • File browser: the Download item of the file context menu showed the upload icon (arrow pointing up into a tray). Added a dedicated download icon (arrow pointing down, same Font Awesome style as the rest of the set — also available via Jodit.modules.Icon.get('download')) and used it for that item. Fixes #1472.

4.14.6

Choose a tag to compare

@github-actions github-actions released this 08 Sep 11:01

🐛 Bug Fix

  • Security / iframe (editHTMLDocumentMode, stored XSS, CWE-79): with iframe: true and editHTMLDocumentMode: true a full HTML document assigned to editor.value was written straight into the live iframe document with document.write(), and safeHTML was only applied afterwards. Inline <script> elements and on* handlers therefore executed while the document was being parsed — before the sanitizer could remove them — in an iframe that is same-origin with the host page by default (iframeSandbox: null), so an attacker-supplied document could run script in the host application's origin as soon as another user opened it. The document is now parsed in an inert DOMParser document (no browsing context: nothing executes, no sub-resources are fetched), sanitized there via the safeHTML event, and only then adopted into the live iframe document; nodes coming from an inert parser are flagged "already started", so even a <script> the cleaner is configured to keep never executes — the same guarantee innerHTML gives in the regular mode. A partial value (no <html>/<body>) in that mode was also assigned to doc.body.innerHTML unsanitized before clean-html ran, which fired e.g. <img onerror>; it now goes through the regular sanitized path. Affected all versions with editHTMLDocumentMode through 4.14.5. Responsibly reported by @bp0lr (GHSA-w3xv-x3fm-59ph).

4.14.5

Choose a tag to compare

@github-actions github-actions released this 08 Sep 09:27

🏠 Internal

  • Upgraded ESLint 9 to 10 and @eslint/js 9 to 10. Replaced the unmaintained eslint-plugin-import with ESLint 10-compatible eslint-plugin-import-x 4, removed the obsolete compatibility wrapper, and upgraded eslint-plugin-mocha to 12 and Mocha to 12.
  • Migrated the release/build scripts from the vulnerable replace package to replace-in-file 9. ESLint 10's new checks removed redundant assignments and test errors now preserve their original cause.
  • Updated the screenshot-test image and its packages to Playwright 1.63.0 and refreshed affected browser snapshots. Fixed the Make target so updateTests=false no longer enables snapshot updates. Forced the patched qs 6.16.0 for Karma's server dependencies; npm audit now reports no known vulnerabilities.
  • Kept TypeScript at 6.0.3 because typescript-eslint does not yet support TypeScript 7 and the project build tools use the compiler API removed from TypeScript 7. Kept cssnano-preset-advanced at 8.0.10 because version 9 fails while loading its caniuse-api dependency under the TypeScript Webpack configuration.

4.14.4

Choose a tag to compare

@github-actions github-actions released this 08 Sep 07:49

🏠 Internal

  • Updated development dependencies within their existing version ranges and refreshed transitive dependencies in package-lock.json. Highlights: Playwright 1.63.0, SWC 1.16.2, TypeScript 6.0.3, typescript-eslint 8.70.0, Less 4.9.1, PostCSS 8.5.28, Stylelint 17.15.0 and Webpack 5.110.3.
  • Major upgrades are handled separately: ESLint remains on 9, Mocha on 11 and cssnano-preset-advanced on 8 in this release.

4.14.3

Choose a tag to compare

@github-actions github-actions released this 08 Sep 07:19

🐛 Bug Fix

  • Selection: save(), fakes(), remove() and wrapInTag() leave selections crossing the editor boundary untouched. isInsideArea checks both boundaries, and restoreFakes() ignores nodes moved outside the editor.
  • Selection / caret: current() resolves the last text descendant when the caret follows a nested element and no longer returns a <br> outside the editor. Edge checks use the correct selection endpoint, including selections across blocks.
  • Selection / ranges and history: preserve backward selections through save/restore, formatting, expansion and undo/redo, including iframe editors. Restore and format all native disjoint ranges in Firefox; selected HTML and node iteration include all ranges without duplicate callbacks. Existing history snapshots remain supported.
  • Selection / insertion: invalid or unsupported cursor point lookups preserve the selection. Selecting the editor root selects its contents; positioning a cursor outside the root is rejected. Splitting validates the block, caret and optional edge before changing DOM. An empty sanitized fragment no longer deletes selected content, and insertion uses the surviving final child after hooks.
  • Selection / Shadow DOM: save() finds markers inside the editor's shadow tree and keeps the saved selection active.
  • Formatting: splitting a text node preserves live element offsets, so mixed text/element selection boundaries no longer omit part of the selected content. Temporary wrappers are cleaned up when callbacks throw or iteration stops early; ApplyStyle also restores the selection after a hook throws. Removed fragments are skipped when hooks replace or delete DOM, and formatting stops safely when a hook destroys the editor.
  • Formatting / CSS: explicit property resets such as color: null no longer throw. Wrapper cleanup runs after all attributes have been applied, preserving subsequent CSS rules, classes and unrelated attributes. Applying styles across nested elements overrides overlapping properties without discarding other styles. Formatting skips contenteditable="false" blocks and preserves styles inside protected inline content.
  • Formatting / links: extracting selected text no longer removes links from adjacent, unselected images by treating image-only fragments as empty.
  • Formatting / classes and lists: class and className accept multiple class tokens. Adjacent lists are matched correctly with multiple classes and numeric or boolean attributes. Removing a class fires afterToggleAttribute even when other classes remain.
  • TypeScript: corrected the declared argument order of beforeToggleList and the modes/return type of beforeUnwrapList to match existing runtime behavior. Runtime hook signatures are unchanged.
  • Languages: added missing Azerbaijani translations for Line height, Spellcheck, Speech Recognize and newline.

🏠 Internal

  • Simplified style iteration with for…of and guaranteed selection cleanup, removed intermediate array copies from caret edge checks, reused CSS reset rules across nested elements, and reused one scratch DOM Range during containment traversal instead of allocating one per node.
  • Added 92 selection and style regression/edge-case tests, including Shadow DOM, iframe, undo/redo, disjoint and backward selections, hook mutations, protected content, nested lists, CSS/attribute combinations and documents up to 3000 paragraphs. Browser suites verified in Chrome and Firefox; Chromium skips native multi-range cases it does not support.

4.14.2

Choose a tag to compare

@github-actions github-actions released this 02 Sep 02:19

🏠 Internal

  • Dev dependencies: webpack 5.109.2, less-loader 13, webpack-dev-middleware 8, eslint-plugin-simple-import-sort 14 (imports re-sorted), @types/node 26, synchronous-promise 2.0.18, cssnano-preset-advanced 8.0.10 (#1446, #1447, #1448, #1450, #1452, #1454, #1456). eslint 10 / eslint-plugin-mocha 12 stay on hold until eslint-plugin-import allows eslint 10; TypeScript 7 needs a tsconfig migration first.