🏠 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).