Skip to content

build(deps): bump jodit from 4.12.21 to 4.12.26#4393

Merged
thorsten merged 1 commit into
mainfrom
dependabot/npm_and_yarn/jodit-4.12.26
Jun 19, 2026
Merged

build(deps): bump jodit from 4.12.21 to 4.12.26#4393
thorsten merged 1 commit into
mainfrom
dependabot/npm_and_yarn/jodit-4.12.26

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Jun 18, 2026

Copy link
Copy Markdown
Contributor

Bumps jodit from 4.12.21 to 4.12.26.

Release notes

Sourced from jodit's releases.

4.12.26

🐛 Bug Fix

  • Security / Helpers (prototype pollution): Jodit.modules.Helpers.set(chain, value, obj) walked the dot-separated chain and created/followed each segment without filtering prototype-mutating keys, so a chain such as __proto__.polluted (e.g. set('__proto__.polluted', 'yes', {})) could reach and mutate Object.prototype (CWE-1321). set now bails out when any segment is __proto__, constructor, or prototype, reusing the same guard added for Jodit.configure() in 4.12.18. Responsibly reported by Junming Wu.

4.12.25

🐛 Bug Fix

  • Source mode / complex scripts (Thai, Arabic, Hindi, Hebrew, Persian): the ACE source editor was loaded from CDN at version 1.4.2 (2018), which predates working bidirectional-text and combining-character support — complex-script text rendered misaligned with the underlying code ("invisible characters" after lines), the caret/selection landed on the wrong characters and copying lost as many characters as there were combining marks. The default sourceEditorCDNUrlsJS now points to ACE 1.43.3, which ships an automatic per-line bidi handler and years of complex-script rendering fixes; all existing source-mode integration tests pass against the new build, plus new regression tests for the Thai round-trip and the bidi layer.

4.12.24

🚀 New Feature

  • Link dialog: new opt-in option link.ariaLabelInput (default false) adds an Aria label text field to the Insert/Edit link form. It reads the existing aria-label when editing and writes it to the <a> on submit (clearing it when empty) — useful for accessibility when several links share the same visible text (e.g. multiple "here" links a screen reader can't tell apart). Addresses #1204.
  • Image editor: new afterImageEditorSave event, fired when the user clicks Save / Save as in the image editor (crop/resize). The handler receives the action box { action: 'resize' | 'crop', box } (and the new name for Save as), so you can react to the applied crop/resize — e.g. update the image's aspect ratio or set its real size. The existing afterImageEditor only fired when the editor opened. Addresses #820.
  • Uploader: new uploader.beforeUpload(files) hook, called with the file list right before upload (or base64 read). Return false to abort — useful for client-side validation of size/type/count; this is the uploader (so this.j is the editor). Addresses #1329.
  • Table / Select cells: Ctrl/Cmd + click now toggles individual cells into a non-contiguous selection (clicking an already-selected cell removes it), in addition to the existing click-and-drag rectangular selection. The cell properties popup opens for the accumulated selection, and toolbar actions (background color, etc.) apply to every selected cell. Previously each Ctrl+click reset the selection to the single clicked cell. Fixes #1163.
  • Backspace/Delete: new option delete.disableCases (a Set<string>) lets you turn off individual Backspace/Delete cleanup behaviors that the plugin applies after the native deletion — e.g. delete: { disableCases: new Set(['join-neighbors']) } stops Backspace at the start of a paragraph from merging it into the previous one. Available keys: remove-unbreakable, remove-not-editable, remove-char, table-cell, remove-empty-parent, remove-empty-neighbor, join-two-lists, join-neighbors, unwrap-first-list-item. Addresses #1060.
  • Clean HTML: new opt-in option cleanHTML.collapseEmptyValueToEmptyString (default false). When the editor holds only a single empty block — e.g. <p><br></p> left in the DOM after the user deletes all content (contenteditable keeps that caret container) — editor.value and the synced source element now return an empty string '' instead of <p><br></p>, which is what forms usually expect on submit. Real content (including a <p><br></p> followed by other blocks) is never collapsed. Addresses #1149.

🐛 Bug Fix

  • Font select button: with the font control rendered as a select (controls: { font: { component: 'select' } }), unstyled text showed the editor's raw default font stack (e.g. -apple-system) on the button instead of Default. The font control's value now returns an empty value when the computed font-family equals the editor's own default, so the button shows the Default list entry. Fixes #1370.

4.12.23

🐛 Bug Fix

  • Search (Ctrl+F): pressing Enter in the search input submitted the parent <form> instead of jumping to the next match — the preventDefault() for Enter lived inside a debounced handler, so it ran only after the browser had already dispatched the form submission. Enter is now canceled synchronously, while the search logic itself stays debounced. Fixes #918.
  • i18n / language bundles: translations for keys that were missing from ar.js never reached the build — the master i18n key list was generated only from ar.js, and every other language is serialized as an array indexed by that list, so existing translations for the ordered-list menu items (Lower Alpha, Lower Greek, Lower Roman, Upper Alpha, Upper Roman — translated in de/es/fi/it/ja/pt_br) and a dozen other keys were silently dropped from every bundle. The key list is now built as the union of all language files. Fixes #997.
  • Custom ownerWindow (editor created inside an iframe): UI components (toolbar collection, popups, dialogs) always kept the global window as their owner window instead of the configured one. Popup/dropdown outside-click close handlers were therefore bound to the wrong window — clicks inside the iframe never reached them, so toolbar dropdowns did not close on an outside click. ViewComponent now inherits the owner window from its parent view. Fixes #965.
  • Toolbar content controls (getContent): controls rendered through getContent (e.g. the FileBrowser Upload button) never ran the status calculation, so their isDisabled/isActive/update callbacks were silently ignored — the Upload button stayed enabled even when the backend permissions (canI('FileUpload')) said otherwise. ToolbarContent.update() now evaluates the control's status like regular toolbar buttons and also propagates the disabled state to nested form controls (the file <input> of the Upload button). Thanks @​WatchfulEyeOfZod for the diagnosis and the patch draft. Fixes #1094.
  • Inline toolbar / Iframe mode: with iframe: true the selection toolbar (toolbarInlineForSelection) opened far away from the selected text — the popup was positioned by range.getBoundingClientRect(), whose coordinates are iframe-local, while the popup itself lives in the host document. The iframe offset is now added to the selection bound. Fixes #1058.
  • Paste toolbar button: the Paste from clipboard toolbar button inserted only the plain text flavor of the clipboard, while Ctrl+V pasted the full HTML — the button explicitly requested text/plain from navigator.clipboard.read() even when text/html was available. The button now prefers the HTML flavor (falling back to plain text), so both paste paths behave the same. Fixes #1061.
  • Format block (H1–H6 / paragraph): applying a heading to a block pasted from an external source seemed to do nothing — the tag actually changed, but leftover inline styles like font-weight: normal; font-size: 24px visually overrode the new format, so an <h2> looked exactly like the old text. When a block format is applied, the conflicting font-size/font-weight inline styles are now removed from the block (other styles like color stay). Fixes #1063.
  • Backspace/Delete next to a table: pressing Backspace at the start of a paragraph that follows a table (or Delete at the end of a paragraph before one) merged the paragraph's text into the <table> element itself — it landed after </tbody>, which is invalid HTML; on the next parse the browser foster-parents such content out of the table, corrupting the document and causing follow-up DOM errors (the Failed to execute 'appendChild' console spam from the report). The join logic now merges the text into the edge table cell (last cell for Backspace, first for Delete). Covers #1064.
  • Paste from Word (askBeforePasteFromWord): office content was frequently mis-detected as plain HTML, so the generic Paste as HTML dialog appeared instead of the Word one. The detector only matched a Microsoft Word N meta generator or mso- styles in double quotes combined with <font> tags — while the raw Word clipboard fragment uses single-quoted style='mso-…', unquoted class=MsoNormal, an unquoted ProgId meta and office XML namespaces (and modern Word emits no <font> at all); LibreOffice/OpenOffice content was never detected. The detector now also recognizes all of these markers. Fixes #1078.
  • Drag and drop (enableDragAndDropFileToEditor: false): dropping a file (e.g. a JPG from another window) into the editor still embedded it — with the option off no handler was bound to the drop event, nothing called preventDefault, and Firefox inserted the dropped image natively. With the option disabled the editor now cancels file drops, so they do nothing — as the option promises. Fixes #1077.
  • AI Assistant: the Insert After button placed the generated text after the first node of the selection — with several selected paragraphs the result landed inside/after the first paragraph instead of after the whole selection. The insertion point is now the collapsed end of the selection, so the result follows everything that was selected; single-word/sentence behavior is unchanged. Fixes #1263.
  • Color / Select cells: applying a text or background color from the main toolbar to table cells selected with the select-cells plugin (click or drag-select a cell — typical for tables pasted from Word) silently did nothing: the cell selection drops or collapses the native range, so the color was committed as a pending caret format in an empty <span> outside the table. When cells are selected and the native selection is collapsed, the forecolor/background commands now recolor the content of every selected cell (including nested spans carrying their own Word colors). Fixes #1250.
  • Shadow DOM / Table: clicking a table cell inside a Shadow DOM editor (the shadowRoot option, e.g. a Stencil/web component integration) never opened the cell properties popup (background, vertical align, split/merge, add/remove row & column). document.elementFromPoint does not pierce shadow boundaries — it returns the shadow host — so the select-cells plugin could not find the clicked cell on mouseup. The hit-testing now starts from the configured shadow root in select-cells (cell selection on click and drag-select), add-new-line (the Break line over tables/images) and Popup.getKeepBound. Fixes #1312.

4.12.22

🐛 Bug Fix

  • Clipboard (copy/cut inside the editor): copying or cutting a selection that sat entirely inside the text of a formatted element (e.g. selecting part of a bold-italic word with the mouse) put the bare text into the clipboard — the <strong>/<em>/… context was lost, so pasting it elsewhere dropped the formatting. Native browser copy keeps that context, but Jodit intercepts copy/cut and serialized only the range contents. The copied fragment is now wrapped in shallow clones of the selection's inline ancestors, like browsers do. Fixes #1202.

... (truncated)

Changelog

Sourced from jodit's changelog.

4.12.26

🐛 Bug Fix

  • Security / Helpers (prototype pollution): Jodit.modules.Helpers.set(chain, value, obj) walked the dot-separated chain and created/followed each segment without filtering prototype-mutating keys, so a chain such as __proto__.polluted (e.g. set('__proto__.polluted', 'yes', {})) could reach and mutate Object.prototype (CWE-1321). set now bails out when any segment is __proto__, constructor, or prototype, reusing the same guard added for Jodit.configure() in 4.12.18. Responsibly reported by Junming Wu.

4.12.25

🐛 Bug Fix

  • Source mode / complex scripts (Thai, Arabic, Hindi, Hebrew, Persian): the ACE source editor was loaded from CDN at version 1.4.2 (2018), which predates working bidirectional-text and combining-character support — complex-script text rendered misaligned with the underlying code ("invisible characters" after lines), the caret/selection landed on the wrong characters and copying lost as many characters as there were combining marks. The default sourceEditorCDNUrlsJS now points to ACE 1.43.3, which ships an automatic per-line bidi handler and years of complex-script rendering fixes; all existing source-mode integration tests pass against the new build, plus new regression tests for the Thai round-trip and the bidi layer.

4.12.24

🚀 New Feature

  • Link dialog: new opt-in option link.ariaLabelInput (default false) adds an Aria label text field to the Insert/Edit link form. It reads the existing aria-label when editing and writes it to the <a> on submit (clearing it when empty) — useful for accessibility when several links share the same visible text (e.g. multiple "here" links a screen reader can't tell apart). Addresses #1204.
  • Image editor: new afterImageEditorSave event, fired when the user clicks Save / Save as in the image editor (crop/resize). The handler receives the action box { action: 'resize' | 'crop', box } (and the new name for Save as), so you can react to the applied crop/resize — e.g. update the image's aspect ratio or set its real size. The existing afterImageEditor only fired when the editor opened. Addresses #820.
  • Uploader: new uploader.beforeUpload(files) hook, called with the file list right before upload (or base64 read). Return false to abort — useful for client-side validation of size/type/count; this is the uploader (so this.j is the editor). Addresses #1329.
  • Table / Select cells: Ctrl/Cmd + click now toggles individual cells into a non-contiguous selection (clicking an already-selected cell removes it), in addition to the existing click-and-drag rectangular selection. The cell properties popup opens for the accumulated selection, and toolbar actions (background color, etc.) apply to every selected cell. Previously each Ctrl+click reset the selection to the single clicked cell. Fixes #1163.
  • Backspace/Delete: new option delete.disableCases (a Set<string>) lets you turn off individual Backspace/Delete cleanup behaviors that the plugin applies after the native deletion — e.g. delete: { disableCases: new Set(['join-neighbors']) } stops Backspace at the start of a paragraph from merging it into the previous one. Available keys: remove-unbreakable, remove-not-editable, remove-char, table-cell, remove-empty-parent, remove-empty-neighbor, join-two-lists, join-neighbors, unwrap-first-list-item. Addresses #1060.
  • Clean HTML: new opt-in option cleanHTML.collapseEmptyValueToEmptyString (default false). When the editor holds only a single empty block — e.g. <p><br></p> left in the DOM after the user deletes all content (contenteditable keeps that caret container) — editor.value and the synced source element now return an empty string '' instead of <p><br></p>, which is what forms usually expect on submit. Real content (including a <p><br></p> followed by other blocks) is never collapsed. Addresses #1149.

🐛 Bug Fix

  • Font select button: with the font control rendered as a select (controls: { font: { component: 'select' } }), unstyled text showed the editor's raw default font stack (e.g. -apple-system) on the button instead of Default. The font control's value now returns an empty value when the computed font-family equals the editor's own default, so the button shows the Default list entry. Fixes #1370.

4.12.23

🐛 Bug Fix

  • Search (Ctrl+F): pressing Enter in the search input submitted the parent <form> instead of jumping to the next match — the preventDefault() for Enter lived inside a debounced handler, so it ran only after the browser had already dispatched the form submission. Enter is now canceled synchronously, while the search logic itself stays debounced. Fixes #918.
  • i18n / language bundles: translations for keys that were missing from ar.js never reached the build — the master i18n key list was generated only from ar.js, and every other language is serialized as an array indexed by that list, so existing translations for the ordered-list menu items (Lower Alpha, Lower Greek, Lower Roman, Upper Alpha, Upper Roman — translated in de/es/fi/it/ja/pt_br) and a dozen other keys were silently dropped from every bundle. The key list is now built as the union of all language files. Fixes #997.
  • Custom ownerWindow (editor created inside an iframe): UI components (toolbar collection, popups, dialogs) always kept the global window as their owner window instead of the configured one. Popup/dropdown outside-click close handlers were therefore bound to the wrong window — clicks inside the iframe never reached them, so toolbar dropdowns did not close on an outside click. ViewComponent now inherits the owner window from its parent view. Fixes #965.
  • Toolbar content controls (getContent): controls rendered through getContent (e.g. the FileBrowser Upload button) never ran the status calculation, so their isDisabled/isActive/update callbacks were silently ignored — the Upload button stayed enabled even when the backend permissions (canI('FileUpload')) said otherwise. ToolbarContent.update() now evaluates the control's status like regular toolbar buttons and also propagates the disabled state to nested form controls (the file <input> of the Upload button). Thanks @​WatchfulEyeOfZod for the diagnosis and the patch draft. Fixes #1094.
  • Inline toolbar / Iframe mode: with iframe: true the selection toolbar (toolbarInlineForSelection) opened far away from the selected text — the popup was positioned by range.getBoundingClientRect(), whose coordinates are iframe-local, while the popup itself lives in the host document. The iframe offset is now added to the selection bound. Fixes #1058.
  • Paste toolbar button: the Paste from clipboard toolbar button inserted only the plain text flavor of the clipboard, while Ctrl+V pasted the full HTML — the button explicitly requested text/plain from navigator.clipboard.read() even when text/html was available. The button now prefers the HTML flavor (falling back to plain text), so both paste paths behave the same. Fixes #1061.
  • Format block (H1–H6 / paragraph): applying a heading to a block pasted from an external source seemed to do nothing — the tag actually changed, but leftover inline styles like font-weight: normal; font-size: 24px visually overrode the new format, so an <h2> looked exactly like the old text. When a block format is applied, the conflicting font-size/font-weight inline styles are now removed from the block (other styles like color stay). Fixes #1063.
  • Backspace/Delete next to a table: pressing Backspace at the start of a paragraph that follows a table (or Delete at the end of a paragraph before one) merged the paragraph's text into the <table> element itself — it landed after </tbody>, which is invalid HTML; on the next parse the browser foster-parents such content out of the table, corrupting the document and causing follow-up DOM errors (the Failed to execute 'appendChild' console spam from the report). The join logic now merges the text into the edge table cell (last cell for Backspace, first for Delete). Covers #1064.
  • Paste from Word (askBeforePasteFromWord): office content was frequently mis-detected as plain HTML, so the generic Paste as HTML dialog appeared instead of the Word one. The detector only matched a Microsoft Word N meta generator or mso- styles in double quotes combined with <font> tags — while the raw Word clipboard fragment uses single-quoted style='mso-…', unquoted class=MsoNormal, an unquoted ProgId meta and office XML namespaces (and modern Word emits no <font> at all); LibreOffice/OpenOffice content was never detected. The detector now also recognizes all of these markers. Fixes #1078.
  • Drag and drop (enableDragAndDropFileToEditor: false): dropping a file (e.g. a JPG from another window) into the editor still embedded it — with the option off no handler was bound to the drop event, nothing called preventDefault, and Firefox inserted the dropped image natively. With the option disabled the editor now cancels file drops, so they do nothing — as the option promises. Fixes #1077.
  • AI Assistant: the Insert After button placed the generated text after the first node of the selection — with several selected paragraphs the result landed inside/after the first paragraph instead of after the whole selection. The insertion point is now the collapsed end of the selection, so the result follows everything that was selected; single-word/sentence behavior is unchanged. Fixes #1263.
  • Color / Select cells: applying a text or background color from the main toolbar to table cells selected with the select-cells plugin (click or drag-select a cell — typical for tables pasted from Word) silently did nothing: the cell selection drops or collapses the native range, so the color was committed as a pending caret format in an empty <span> outside the table. When cells are selected and the native selection is collapsed, the forecolor/background commands now recolor the content of every selected cell (including nested spans carrying their own Word colors). Fixes #1250.
  • Shadow DOM / Table: clicking a table cell inside a Shadow DOM editor (the shadowRoot option, e.g. a Stencil/web component integration) never opened the cell properties popup (background, vertical align, split/merge, add/remove row & column). document.elementFromPoint does not pierce shadow boundaries — it returns the shadow host — so the select-cells plugin could not find the clicked cell on mouseup. The hit-testing now starts from the configured shadow root in select-cells (cell selection on click and drag-select), add-new-line (the Break line over tables/images) and Popup.getKeepBound. Fixes #1312.

4.12.22

🐛 Bug Fix

  • Clipboard (copy/cut inside the editor): copying or cutting a selection that sat entirely inside the text of a formatted element (e.g. selecting part of a bold-italic word with the mouse) put the bare text into the clipboard — the <strong>/<em>/… context was lost, so pasting it elsewhere dropped the formatting. Native browser copy keeps that context, but Jodit intercepts copy/cut and serialized only the range contents. The copied fragment is now wrapped in shallow clones of the selection's inline ancestors, like browsers do. Fixes #1202.

... (truncated)

Commits

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    You can disable automated security fix PRs for this repo from the Security Alerts page.

Bumps [jodit](https://github.com/xdan/jodit) from 4.12.21 to 4.12.26.
- [Release notes](https://github.com/xdan/jodit/releases)
- [Changelog](https://github.com/xdan/jodit/blob/main/CHANGELOG.md)
- [Commits](xdan/jodit@4.12.21...4.12.26)

---
updated-dependencies:
- dependency-name: jodit
  dependency-version: 4.12.26
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file JavaScript Pull requests that update Javascript code labels Jun 18, 2026
@thorsten thorsten merged commit b7c9d28 into main Jun 19, 2026
13 checks passed
@thorsten thorsten deleted the dependabot/npm_and_yarn/jodit-4.12.26 branch June 19, 2026 04:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file JavaScript Pull requests that update Javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant