jsdom is feeling the AGI!
This release is dedicated to @scttcper, who unleashed @codex upon jsdom and found tons of performance improvements. Along the way, he found and fixed many correctness issues as well.
We really appreciate his thoughtful PRs, which did a great job following the project's contribution guidelines, and were clearly human-curated, with their PR descriptions edited to be brief and respectful of the maintainers' time.
Thanks to @scttcper, as well as all the other contributors of this release (most of whom were AI-assisted).
- Added named access to elements on
document, such asdocument.myFormfor<form name="myForm">. (@vojtisprime11) - Added
QuotaExceededError, including its use for storage quota errors and oversizedcrypto.getRandomValues()requests. - Added support for the relaxed DOM naming rules when creating elements, attributes, and document types.
- Improved performance of DOM construction, tree mutations, range operations, and live collection access, especially on large documents. (@scttcper, @erezrokah)
- Improved performance of
getComputedStyle(), style changes, and CSS serialization. (@scttcper, @jhult) - Improved performance of event dispatch, form control and label lookups, and updates to
<select>elements and radio button groups. (@scttcper) - Reduced memory use when creating and working with DOM nodes, attributes, event listeners, and mutation observers. (@scttcper)
- Changed
window.close()to preserve access to the document and its DOM through retained references. - Fixed
element.querySelectorAll()returning no matches when the first part of the selector matches the element itself, which regressed in v30.0.0. (@asamuzaK) - Fixed case sensitivity in CSS attribute selectors, including selectors matching
data-state="",title="", and other case-sensitive values. (@asamuzaK) - Fixed
document.querySelector()failing to find a matching element when an earlier element has the same ID but does not match the rest of the selector. (@vojtisprime11) - Fixed
:focusmatching in shadow trees. (@asamuzaK) - Fixed DOM insertion and replacement, including valid
document.replaceChildren()calls, invalid document element and doctype placements, and mutations duringelement.replaceWith(). - Fixed the ordering of script execution, custom element callbacks, iframe loading, and mutation observer notifications during DOM insertion, including in shadow trees.
- Fixed queued events and navigation continuing after
window.close()or iframe removal, and prevented new scripts, resource loads, timers, and animation frames from starting in destroyed documents. (@scttcper) - Fixed parent documents waiting indefinitely for loading to finish when a child iframe removes itself during loading.
- Fixed request cancellation across redirects, during pending
requestInterceptor()callbacks, and when reusing anXMLHttpRequestafter aborting it. - Fixed resource loading and
JSDOM.fromURL()potentially hanging when response handling throws and response stream cleanup does not finish. - Fixed successful cached resource loads being treated as aborted.
- Fixed
getComputedStyle()anddocument.styleSheetsusing the wrong stylesheet order after inserting or updating<style>elements. - Fixed
getComputedStyle()ignoring nested@importand@mediarules in imported stylesheets, and returning stale results after imports finish loading. - Fixed style invalidation, stylesheet removal, and frame source updates in shadow trees.
- Fixed repeated
getComputedStyle()calls changing case-sensitive background URLs, and inconsistent resolution of border shorthands containing system colors. (@scttcper) - Fixed computed border widths, including borderless elements incorrectly reporting
16px, which regressed in v30.0.0. (@Alberto-BaseNet) - Fixed
getComputedStyle()to resolve'font-weight'keywords to numeric values. (@tianrking) - Fixed
getComputedStyle()to convert lengths to pixels inside CSS math functions containing percentages, and to resolve percentages in'font-size'math functions. (@soroushm) - Fixed serialization of
min()andmax()containing nestedcalc(), which regressed in v30.0.0. (@asamuzaK) - Fixed CSS values mixing lengths or percentages with math functions, such as
'grid-template-columns'values containing both100pxandcalc(). (@rome-xi) - Fixed parsing of
'background'and'border'shorthands with adjacent components, such asurl(a.png)no-repeat, including a crash when parsing inline styles. Also fixed handling of invalid shorthand assignments and escaped or unusual characters in CSS declarations. (@asamuzaK) - Fixed parsing of unitless zero values in
'flex'shorthands, such as35 1 0, and rejection of negative'flex-basis'lengths and percentages. (@asamuzaK) - Fixed shorthand style assignments producing extra mutation records and custom element callbacks for intermediate values. (@scttcper)
- Fixed
RangeandSelectionhandling of CDATA sections, including boundary offsets and range cloning, extraction, deletion, insertion, and stringification. (@scttcper) - Fixed
text.normalize()incorrectly removing the text node or merging its siblings. (@scttcper) - Fixed cloning and importing CDATA sections and processing instructions whose contents have been modified, and serialization of CDATA sections adopted into HTML documents.
- Fixed stale named-property collections on
window, and incorrect named access from empty or namespacedid=""andname=""values. (@scttcper) - Fixed elements in documents created with
DOMParserordocument.implementation.createHTMLDocument()appearing as named properties onwindowand being retained in memory. (@Iaotle) - Fixed memory leaks from mutation observers retaining observed nodes, abort signals retaining removed event listeners, and storage event tracking retaining closed windows. (@scttcper)
- Fixed
storageevents being sent to windows created after the storage change, and ensured surviving recipients still receive events when the source document is destroyed. - Fixed attribute lookups after namespace prefix changes, and namespaced attributes incorrectly affecting ID lookups and element behavior. (@scttcper)
- Fixed
input.listin detached element trees. (@scttcper) - Fixed
attr.ownerDocumentafter setting an attribute node on an element in another document or adopting its element. (@Kjubikstronk) - Fixed fresh
element.getElementsByTagName()calls using the previous document's case-sensitivity rules after adoption between HTML and XML documents. (@Kjubikstronk) - Fixed
element.tagNamereturning stale casing after adoption between HTML and XML documents. - Fixed radio button grouping and checkedness updates for controls with different form owners, controls outside their form, unnamed controls, and canceled clicks.
- Fixed
<select>selection updates when moving options, and unintended selection resets when moving a whole<select>or changing unrelated descendants. - Fixed cloning
<input>elements to preserveinput.indeterminate. - Fixed focus state after removing a focused element or its ancestor, including inside shadow trees.
- Fixed script execution when inserting children into a connected, empty
<script>. (@Kjubikstronk) - Fixed incorrect script execution after changes to
src="", and handling oftype="",for="", andevent="". - Fixed
document.currentScriptduring nested script execution and scripts in shadow trees. - Fixed event dispatch,
window.event, and default passive listener handling for non-node event targets, and event dispatch when user code modifieswindow.constructor. - Fixed
volumechangeandratechangeevents to fire asynchronously. (@christianaurichzm) - Fixed DOM APIs accepting user-created proxies around DOM objects where genuine DOM objects are required.
- Fixed XPath iterator invalidation after DOM mutations and errors for invalid result types.
- Fixed
NodeIteratortraversal when its filter removes nodes. - Fixed
fileReader.readAsText()to honor the blob's MIME type charset when no supported explicit encoding is supplied. - Fixed fractional seconds in time input parsing and serialization. (@Jaybhade)
- Fixed large
input.valueAsNumberassignments for time and local date/time inputs. - Fixed hard wrapping of
<textarea>values to use the numerictextarea.colsvalue. - Fixed
document.readyStateto be"complete"for documents created withdocument.implementation.createDocument()anddocument.implementation.createHTMLDocument(). - Fixed
element.translatefor emptytranslate=""values and elements without a parent. - Fixed XML parsing of lone surrogates to replace them with the Unicode replacement character.
- Fixed
node.lookupNamespaceURI()for thexmlandxmlnsprefixes. (@vojtisprime11) - Fixed
<base>elements to ignoredata:andjavascript:URLs. (@vojtisprime11) - Fixed
svgElement.viewportElementinside<symbol>elements. - Fixed the default
blobEvent.timecodeto beNaN. - Fixed the object shape and property descriptors of
CSS.