Releases: xdan/jodit
Releases Β· xdan/jodit
Release list
4.14.2
π 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-importallows eslint 10; TypeScript 7 needs a tsconfig migration first.
4.14.1
π Internal
- Release pipeline: the
jodit-reactandjodit-prorelease triggers, paused for the 4.14.0 rollout, are back on. Both wrappers were bumped to a new minor by hand (jodit-react5.5.0,jodit-pro4.14.0,jodit-pro-react5.6.0); this release lets the bots publish their first builds on top of it.
4.14.0
π Internal
- DOM access goes through the
Dommodule only. Groundwork for virtual-DOM editing, no public API changes: parameter types are widened, return types untouched. Newsrc/types/vdom.d.tsdescribes the structural subset of the browser DOM the editor relies on (VNode,VElement,VHTMLElement,VStyle,VDocument); browser nodes satisfy it, so existing call sites compile unchanged. TheDommutation/structural core (append,prepend,after,before,appendChildFirst,detach,unwrap,moveContent,sibling,hide/show) is typed against that subset and deduplicated (first/lastshare one traversal,prevWithClass/nextWithClassshare one helper). A new Virtual DOM contract suite indom.test.jsrunsDomagainst a non-browser VNode implementation, pinning the invariant at runtime. Acrosscore,modules,pluginsandjodit.ts: no directappendChild/insertBefore/removeChild/replaceChildleft outsideDom(was ~207 call sites),.style.x =βcss()/VStyle,get/setAttributeβattr(),querySelectorreduced to the sanctioned boundaries (user-supplied selectors inselector.ts, pasted stylesheet selectors inapply-styles.ts, theBASE_PATHbootstrap inconstants.ts, the sanitizers). #1441 - Dialog: open dialogs are tracked in a static registry;
setMaxZIndex/getMaxZIndexDialogread it instead of scanning the wholedestinationsubtree (usuallydocument.body) on every open and mousedown.
π New Feature
cssInline(element, key): exact inline read of a CSS property (thestyleattribute) β no computed style, no layout access, no number/color normalization.css(element, key, true)still works but is deprecated: its result goes throughnormalizeCssValue('0px'β0,boldβ700), which made it unusable for exact comparisons and save/restore. Internal call sites (popup/dialog z-index, indent, resizer, media, image properties readers, table widths) migrated.attrRaw(element, name, value?): attribute access with the name taken verbatim β no camelCase β kebab-case conversion, nodata-fallback, nopxstripping. Used by the sanitizers (safeHTML,cleanHTML.allowTags,cleanFromWord) and attribute comparison, whereattr()'s name normalization must never apply (onLoad,viewBox,xlink:href).VTokenList.lengthadded to the VNode subset.
π Bug Fix
- Paste from Word: attribute cleanup on inline SVG (
viewBox,preserveAspectRatio, β¦) silently skipped those attributes because the removal went throughattr(), which kebab-cased the names. UsesattrRawnow. - Uploader:
bind(form)matches<input type="FILE">again (attribute selectors are case-insensitive, theattr()comparison was not). - Dialog / Resize cells: dialog position and the cell resize handle keep fractional pixels; the numeric
css()setter truncated them to integers. - Resizer: an image with an inline
width: 0pxis treated as having an inline size again (cssInlinekeeps the raw'0px'wherecss(..., true)returned0).
π Polish
Dom.temporaryListis no longer deprecated: it is the history snapshot cleanup and is a plain tree walk (no selector engine, works onVNode).alignElementlooks the command up in aMapinstead of a plain object (no prototype keys).- Toolbar/plugin tag sets (
Dom.isTag(node, Set)) hoisted to module constants instead of being allocated per visited node. element.innerHTML = ''clears replaced withDom.detach(element)(table rows, tooltip, paste storage, delete, debug, inline container).
4.13.27
π New Feature
- Formatting / Lists: applying a CSS style (text color, background, font size, font family) to a fully selected list item now puts the style on the
<li>itself instead of wrapping the content in a<span>, so the bullet or number gets the same color and size as the text. Partially selected items, items with a nested list and element formats such as bold/italic keep wrapping the content as before; applying the same style again toggles it off the item. #1460
4.13.26
π Bug Fix
- Color picker: pressing Enter in the hex input applied the color and closed the popup, but Chrome then fired
changeon the removed, still-focused input, so the same color was applied a second time and toggled off again. The widget now applies a typed value only once. #1459 - Toolbar: closing a button popup by clicking outside while the hex input had focus threw
NotFoundError: Failed to execute 'removeChild'. Chrome firesblur/changein the middle ofremoveChild, the color callback re-entered the button's close routine, and it destructed the popup while the outer removal was still running.ToolbarButtonnow detaches the popup before closing it so a re-entrant close is a no-op, andPopup.close()blurs a focused control before removing the container so that Chrome and Firefox both run those handlers while the popup is still in the DOM (Firefox never fired them for a removed element, so the typed color was silently dropped there). #1458
4.13.25
π Bug Fix
- Decorators:
@cacheHTML(used byUIButton.createContainerandToolbarButton.createContainer) kept a single template element per class for the whole page lifetime, keyed only by the constructor. When an editor was created inside an iframe (ownerDocument/ownerWindowoptions) and that iframe was later removed, every subsequent editor receivedcloneNodecopies of a template that belonged to the destroyed document, and its toolbar buttons rendered but never reacted to clicks. The cache is now keyed by the owner document first and only then by the class, so each document builds its own templates. #1457
4.13.24
π Bug Fix
- Selection: applying a block format while the selection sat in bare text inside a container block (e.g. a
<div>that also holds paragraphs) replaced the whole container with the new element, merging all its blocks into one heading. The nearest-block search now skips container blocks that have block-level children and wraps the selected text island in a new block inside the container instead. Additionally, toggling a block format off inside a container (an<h3>inside a<div>) used to bare-unwrap the element, leaving orphan inline text that thewrapNodesplugin only restores at the editor root; such a block is now replaced with the default paragraph tag. Reported by Kevin Sormann (li-life web+it, Jodit PRO).
4.13.23
π Bug Fix
- Clean HTML: the plugin's asynchronous walker stole focus back from an element the user had navigated to. Shift+Tab moved focus out of the editor, but when the walker then removed an empty text node left near the old caret position, it restored the selection β and selecting re-focuses the editor, yanking focus away from the target element a fraction of a second later. The caret is now only restored while the editor still owns focus; cleaning is unchanged. Reported by Ralf Pichler (Uniquare, Jodit OEM).
4.13.22
π Bug Fix
- Image processor: an image with a percent-encoded data URI (
<img src="data:image/svg+xml,%3Csvg...">) madedataURItoBlobcallatobon a payload that is not base64, so the editor threwInvalidCharacterErrorout of the change handler β on every change while such an image was in the content. Percent-encoded payloads are now decoded as well, and a data URI that still cannot be decoded leaves the image untouched instead of breaking the editor. The plugin's private copy of the helper is gone; both paths sharemodules/uploader/helpers/data-uri-to-blob.
4.13.21
π Bug Fix
- Helpers: when the caret line can only be revealed by scrolling the page itself (e.g. the editor is half-visible in a small viewport),
scrollIntoViewIfNeededfell back toscrollIntoView()with the defaultblock: 'start'β the element was aligned to the viewport top and the page jumped as if PageDown was pressed on every Enter. The fallback now usesblock: 'nearest'and scrolls the minimal distance, one line at a time, like a native textarea. Reported by Ralf Pichler (Uniquare, Jodit OEM).