NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #451 most downloaded on npm
A JavaScript implementation of many web standards
Last release today
04 Oct 2026
Release timing varies
gaps range from 2 weeks to 3 months
Nearly every release is documented
notes for 59 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
15 years old
288 releases · first in 2011
Nothing published for this version
Fixed spurious window blur and focusout events and incorrect event.relatedTarget values when focusing an element after removing the previously focused
blur and focusout events and incorrect event.relatedTarget values when focusing an element after removing the previously focused element, which regressed in v30.1.0. (@asamuzaK)document.documentElement.focus(). (@asamuzaK)blur listeners becoming active, and text selections made by focus and blur listeners being overwritten. (@asamuzaK)element.focus() incorrectly focusing disabled form controls and <input type="hidden"> elements with tabindex="". (@scttcper)style.setProperty() calls changing existing !important priorities, serialized styles, or mutation records. (@FedgeNo)!important handling when updating CSS longhands after shorthands, using variables or CSS-wide keywords, and assigning style properties directly. (@FedgeNo)<noscript> parsing with includeNodeLocations: true or inside frames to honor the runScripts option.storageQuota option being ignored by frames.charset parameters in <meta> elements, and encoding detection incorrectly using incomplete <meta> tags. (@FedgeNo)constructor, toString, __proto__, or "null", and incorrect reuse of namespace prefixes declared on sibling elements.element.innerHTML and element.outerHTML in XML documents to reject invalid characters in attribute values and avoid stack overflows on large strings.:lang(), :nth-child(... of ...) after mutations, and :has() with duplicate IDs or nested logical pseudo-classes. (@asamuzaK)One column per quarter.
This release is dedicated to @scttcper , who unleashed @codex upon jsdom and found tons of performance improvements. Along the way, he found and fixed
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).
document, such as document.myForm for <form name="myForm">. (@vojtisprime11)QuotaExceededError, including its use for storage quota errors and oversized crypto.getRandomValues() requests.getComputedStyle(), style changes, and CSS serialization. (@scttcper, @jhult)<select> elements and radio button groups. (@scttcper)window.close() to preserve access to the document and its DOM through retained references.element.querySelectorAll() returning no matches when the first part of the selector matches the element itself, which regressed in v30.0.0. (@asamuzaK)data-state="", title="", and other case-sensitive values. (@asamuzaK)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):focus matching in shadow trees. (@asamuzaK)document.replaceChildren() calls, invalid document element and doctype placements, and mutations during element.replaceWith().window.close() or iframe removal, and prevented new scripts, resource loads, timers, and animation frames from starting in destroyed documents. (@scttcper)requestInterceptor() callbacks, and when reusing an XMLHttpRequest after aborting it.JSDOM.fromURL() potentially hanging when response handling throws and response stream cleanup does not finish.getComputedStyle() and document.styleSheets using the wrong stylesheet order after inserting or updating <style> elements.getComputedStyle() ignoring nested @import and @media rules in imported stylesheets, and returning stale results after imports finish loading.getComputedStyle() calls changing case-sensitive background URLs, and inconsistent resolution of border shorthands containing system colors. (@scttcper)16px, which regressed in v30.0.0. (@Alberto-BaseNet)getComputedStyle() to resolve 'font-weight' keywords to numeric values. (@tianrking)getComputedStyle() to convert lengths to pixels inside CSS math functions containing percentages, and to resolve percentages in 'font-size' math functions. (@soroushm)min() and max() containing nested calc(), which regressed in v30.0.0. (@asamuzaK)'grid-template-columns' values containing both 100px and calc(). (@rome-xi)'background' and 'border' shorthands with adjacent components, such as url(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)'flex' shorthands, such as 35 1 0, and rejection of negative 'flex-basis' lengths and percentages. (@asamuzaK)Range and Selection handling of CDATA sections, including boundary offsets and range cloning, extraction, deletion, insertion, and stringification. (@scttcper)text.normalize() incorrectly removing the text node or merging its siblings. (@scttcper)window, and incorrect named access from empty or namespaced id="" and name="" values. (@scttcper)DOMParser or document.implementation.createHTMLDocument() appearing as named properties on window and being retained in memory. (@Iaotle)storage events being sent to windows created after the storage change, and ensured surviving recipients still receive events when the source document is destroyed.input.list in detached element trees. (@scttcper)attr.ownerDocument after setting an attribute node on an element in another document or adopting its element. (@Kjubikstronk)element.getElementsByTagName() calls using the previous document's case-sensitivity rules after adoption between HTML and XML documents. (@Kjubikstronk)element.tagName returning stale casing after adoption between HTML and XML documents.<select> selection updates when moving options, and unintended selection resets when moving a whole <select> or changing unrelated descendants.<input> elements to preserve input.indeterminate.<script>. (@Kjubikstronk)src="", and handling of type="", for="", and event="".document.currentScript during nested script execution and scripts in shadow trees.window.event, and default passive listener handling for non-node event targets, and event dispatch when user code modifies window.constructor.volumechange and ratechange events to fire asynchronously. (@christianaurichzm)NodeIterator traversal when its filter removes nodes.fileReader.readAsText() to honor the blob's MIME type charset when no supported explicit encoding is supplied.input.valueAsNumber assignments for time and local date/time inputs.<textarea> values to use the numeric textarea.cols value.document.readyState to be "complete" for documents created with document.implementation.createDocument() and document.implementation.createHTMLDocument().element.translate for empty translate="" values and elements without a parent.node.lookupNamespaceURI() for the xml and xmlns prefixes. (@vojtisprime11)<base> elements to ignore data: and javascript: URLs. (@vojtisprime11)svgElement.viewportElement inside <symbol> elements.blobEvent.timecode to be NaN.CSS.Fixed getComputedStyle() with calc() and other functions throwing an exception, which regressed in v30.0.0. ( @asamuzaK )
Node.js minimum version raised to ^22.22.2 || ^24.15.0 || >=26.0.0 .
Breaking changes:
^22.22.2 || ^24.15.0 || >=26.0.0.Other changes:
CSS.escape() and CSS.supports() functions. (@asamuzaK)'background-position-x' and 'background-position-y' CSS properties. (@olagokemills)getComputedStyle() to convert length values into pixels. (@asamuzaK)getPropertyValue(). (@asamuzaK)document.evaluate() (@dokson)Fixed 'border-radius' computed style serialization. ( @asamuzaK )
Added basic support for the ratio CSS type. ( @asamuzaK )
Significantly improved and sped up getComputedStyle() . Computed value rules are now applied across a broader set of properties, and include fixes rel
getComputedStyle(). Computed value rules are now applied across a broader set of properties, and include fixes related to inheritance, defaulting keywords, custom properties, and color-related values such as currentcolor and system colors. (@asamuzaK)'background' and 'border' shorthand parsing. (@asamuzaK)Fixed CSS parsing of 'border' , 'background' , and their sub-shorthands containing keywords or var() . ( @asamuzaK )
'border', 'background', and their sub-shorthands containing keywords or var(). (@asamuzaK)getComputedStyle() to return a more functional CSSStyleDeclaration object, including indexed access support, which regressed in v29.0.0.Node.js v22.13.0+ is now the minimum supported v22 version (was v22.12.0+).
Breaking changes:
Other changes:
@acemir/cssom and cssstyle dependencies with fresh internal implementations built on webidl2js wrappers and the css-tree parser. Serialization, parsing, and API behavior is improved in various ways, especially around edge cases.CSSCounterStyleRule and CSSNamespaceRule to jsdom Windows.cssMediaRule.matches and cssSupportsRule.matches getters.MediaList, using css-tree instead of naive comma-splitting. Invalid queries become "not all" per spec.cssKeyframeRule.keyText getter/setter validation.cssStyleRule.selectorText setter validation: invalid selectors are now rejected.styleSheet.ownerNode, styleSheet.href, and styleSheet.title.Document initialization performance by lazily initializing the CSS selector engine, avoiding ~0.5 ms of overhead per Document. (@thypon)CSSStyleDeclaration modifications to properly trigger custom element reactions.@media rule parsing.CSSStyleSheet's "disallow modification" flag not being checked in all mutation methods.XMLHttpRequest's response getter returning parsed JSON during the LOADING state instead of null.getComputedStyle() crashing in XHTML documents when stylesheets contained at-rules such as @page or @font-face.XMLHttpRequest caused by a race condition with the worker thread's idle timeout.Added blob.text() , blob.arrayBuffer() , and blob.bytes() methods.
blob.text(), blob.arrayBuffer(), and blob.bytes() methods.getComputedStyle() to account for CSS specificity when multiple rules apply. (@asamuzaK)XMLHttpRequest performance by using a persistent worker thread, avoiding ~400ms of setup overhead on every synchronous request after the first one.node.getRootNode(), node.isConnected, and event.dispatchEvent() by caching the root node of document-connected trees.getComputedStyle() to correctly handle !important priority. (@asamuzaK)document.getElementById() to return the first element in tree order when multiple elements share the same ID.<svg> elements to no longer incorrectly proxy event handlers to the Window.FileReader event timing and fileReader.result state to more closely follow the spec.XMLHttpRequest encountered dispatch errors.fetch() has been used before importing jsdom, by working around undici v6/v7 incompatibilities.Fixed require("url").parse() deprecation warning when using WebSocket s.
<iframe> and <frame> loads.WebSockets are no longer correctly throttled to one connection per origin. This is a result of the bug at nodejs/undici#4743.<a> and <area> elements in non-UTF-8 documents.XMLHttpRequest fetches and WebSocket upgrade requests to be interceptable by the new customizable resource loading. (Except synchronous XMLHttpRequests.)ArrayBuffers or typed arrays to various APIs, where they would not correctly snapshot the data.require("url").parse() deprecation warning when using WebSockets.<iframe>, <frame>, and <img> (when canvas is installed) to fire load events, not error events, on non-OK HTTP responses.XMLHttpRequest.Added TextEncoder and TextDecoder .
TextEncoder and TextDecoder.@exodus/bytes package; it is now much more correct. (@ChALkeR)<meta charset> or using the parent frame's encoding.Ranges were used and then the elements referred to by those ranges were removed.Improved CSS parsing and CSSOM object APIs via updates to `@acemir/cssom`. (@acemir)
@acemir/cssom. (@acemir)Added CSSGroupingRule, CSSNestedDeclarations, CSSConditionRule, CSSContainerRule, CSSScopeRule, CSSSupportsRule, CSSLayerBlockRule, and CSSLayerStatem
CSSGroupingRule, CSSNestedDeclarations, CSSConditionRule, CSSContainerRule, CSSScopeRule, CSSSupportsRule, CSSLayerBlockRule, and CSSLayerStatementRule to jsdom Windows. (@acemir)@acemir/cssom. (@acemir)@import-ed stylesheets to be properly exposed to CSSOM, and not to overwrite the sheet created from the <link> or <style> element. (@acemir)Improved CSS parsing by switching to `@acemir/cssom`, including support for nested selectors, nested declarations, layer statements, and improved at-r
@acemir/cssom, including support for nested selectors, nested declarations, layer statements, and improved at-rule validation. (@acemir)package.json "engines" field to reflect the new minimum Node.js versions needed to run jsdom, as noted in the changelog for v27.0.1.This release inadvertently raised the minimum Node.js version from v20.0.0 to v20.19.0+, v22.12.0+, v24.0.0+. (This happened via a dependency update.)
This release inadvertently raised the minimum Node.js version from v20.0.0 to v20.19.0+, v22.12.0+, v24.0.0+. (This happened via a dependency update.) This probably should have been a breaking (major) change, instead of happening in a patch version, since it prevents using earlier Node.js versions.
After further testing, we found that most of our development dependencies also require these versions, and so it's not feasible for the jsdom project to support earlier Node.js versions. (For example, our testing frameworks will not run on them.) If you need to use such earlier versions, or otherwise are working in an environment which gives related errors such as ERR_REQUIRE_ESM, then please stick with the v26.1.0 release of jsdom. (Noting, of course, that such versions are unsupported, and we will not respond to bug reports opened against them.)
Subsequent jsdom releases will explicitly require these minimum Node.js versions, and will have CI testing to ensure that the minimum version is not accidentally raised again.
Normal changelog:
class="" attribute changes is only possible with a new version of jsdom. (@asamuzaK)Node.js v20 is now the minimum supported version.
BeforeUnloadEvent, BlobEvent, DeviceMotionEvent (omitting requestPermission()), DeviceOrientationEvent (omitting requestPermission()), PointerEvent, PromiseRejectionEvent, and TransitionEvent.movementX and movementY to MouseEvent. (These are from the Pointer Lock specification, the rest of which is not implemented.)customElements.getName(). (@mash-graz)"jsdomError" events are now documented, with specific type properties and other properties that depend on the type.sendTo() was renamed to forwardTo().jsdomErrors option to forwardTo() can be used to control which errors are sent to the Node.js console. This replaces the previous omitJSDOMErrors boolean option."jsdomError"s for failed XMLHttpRequest fetches are no longer emitted."jsdomError"s to the Node.js console are streamlined.nwsapi to @asamuzakjp/dom-selector, closing over 20 selector-related bugs.tough-cookie, which now considers URLs like http://localhost/ to be secure contexts (per the spec), and thus will return Secure-flagged cookies for such URLs. (@colincasey)cssstyle, which brings along many improvements and fixes to the CSSStyleDeclaration object and its properties.element.click() to fire a PointerEvent instead of a MouseEvent.<input> element's pattern="" attribute to use the v regular expression flag, instead of u.Window object, including named properties and changing various data properties to accessor properties.document.createEvent() to accept a more correct set of event names.ElementInternals accessibility getters and setters. (They were introduced in v23.1.0, but due to inadequate test coverage never actually worked.)Object.defineProperty() on certain objects, such as HTMLSelectElement instances.jsdom.reconfigure({ url }) not updating document.baseURI or properties derived from it. (This regressed in v26.1.0.)initial, inherit, and unset keywords, to resolve correctly. (@asamuzaK)display style resolution. (@asamuzaK)cssstyle, which brings along various CSS parsing fixes.Breaking change: upgraded tough-cookie, which now considers URLs like http://localhost/ to be secure contexts (per the spec), and thus will return Sec…
tough-cookie, which now considers URLs like http://localhost/ to be secure contexts (per the spec), and thus will return Secure-flagged cookies for such URLs. (@colincasey)customElements.getName(). (@mash-graz)<input> element's pattern="" attribute to use the v regular expression flag, instead of u.jsdom.reconfigure({ url }) not updating document.baseURI or properties derived from it. This regressed in v26.1.0.initial, inherit, and unset keywords, to resolve correctly. This is especially important since the change in v27.0.0-beta.1 to use system colors in the user agent stylesheet. (@asamuzaK)background property parsing and serialization. (@asamuzaK)display style resolution. (@asamuzaK)@asamuzakjp/dom-selector, which notably fixed repeated use of the :scope selector. (@asamuzaK)Significantly improved specification conformance for the Window object, including named properties and changing various data properties to accessor pr
Significantly improved specification conformance for the Window object, including named properties and changing various data properties to accessor properties. This is not likely to be breaking, but since it's a complex change to such a core object, we're happy to do another beta testing release with this included before graduating the v27 line to stable.
Additionally, updated cssstyle to v4.4.0, which brings along various conformance fixes to the CSSStyleDeclaration object and its properties.
Node.js v20+ is now the minimum supported version.
Breaking changes:
getComputedStyle()."jsdomError" events are now documented, with specific type properties and other properties that depend on the type.sendTo() was renamed to forwardTo().jsdomErrors option to sendTo() can be used to control which errors are sent to the Node.js console. This replaces the previous omitJSDOMErrors boolean option."jsdomError"s for failed XMLHttpRequest fetches are no longer emitted."jsdomError"s to the Node.js console are streamlined.Other changes:
ElementInternals accessibility getters and setters. (They were introduced in v23.1.0, but due to inadequate test coverage never actually worked.)Object.defineProperty() on certain objects, such as HTMLSelectElement instances.The following non-breaking changes are included in this release:
This release includes several changes that might be disruptive, and so are being tested as a beta release before the next major release. Hopefully, they will not be breaking, but your help testing would be appreciated.
Mostly notably, this switches our CSS selector engine from nwsapi to @asamuzakjp/dom-selector. This was attempted back in 23.2.0, but reverted in 24.0.0 because of performance concerns. Since that time, @asamuzakjp/dom-selector has improved its performance significantly. On the real-world benchmarks from #3659, we see the new version taking 1.1x as long (compared to 1.5x with the previous attempt). We hope this lower performance overhead will be enough to allow us to stick with the new selector engine. As a sample of how much more capable it is, 19 independent selector-related bugs were closed by merging in this new version.
Please test with the new selector engine and report back with any performance concerns on the issue tracker, ideally before we make the next stable release.
The other major change in this prerelease is the addition of many new event constructors. Previously, we have avoided implementing event constructors unless we implemented their attendant specification. For example, we did not implement BeforeUnloadEvent since we don't implement unloading of documents; we did not implement BlobEvent since we did not implement the MediaStream Recording specification; etc. However, these are common popular requests, and so we've chosen to implement these event constructors without implementing their related specifications.
If this causes you any problems, e.g. due to breaking feature detection, please open an issue on the issue tracker, ideally before we make the next stable release.
The full list of implemented event constructors is: BeforeUnloadEvent, BlobEvent, DeviceMotionEvent (omitting requestPermission()), DeviceOrientationEvent (omitting requestPermission()), PointerEvent, PromiseRejectionEvent, and TransitionEvent.
The following non-breaking changes are included in this release:
movementX and movementY to MouseEvent. (These are from the Pointer Lock specification, the rest of which is not implemented.)element.click() to fire a PointerEvent instead of a MouseEvent.document.createEvent() to accept a more correct set of event names.Added at least partial support for various SVG elements and their classes: (SVGDefsElement), (SVGDescElement), (SVGGElement), (SVGMetadataElement), (S
<defs> (SVGDefsElement), <desc> (SVGDescElement), <g> (SVGGElement), <metadata> (SVGMetadataElement), <switch> (SVGSwitchElement), and <symbol> (SVGSymbolElement).SVGAnimatedPreserveAspectRatio and SVGAnimatedRect, including support in the reflection layer.SVGSVGElement createSVGRect() method, and the SVGRect type (which is distinct from DOMRect.)HTMLFormElement.SVGElement viewportElement() method to correctly establish the viewport based on ancestor elements.form-data dependency in favor of our own smaller implementation of multipart/form-data serialization. No functional changes are expected.Breaking change: `canvas` peer dependency requirement has been upgraded from v2 to v3. (@sebastianwachter)
Breaking change: canvas peer dependency requirement has been upgraded from v2 to v3. (@sebastianwachter)
Other changes:
AbortSignal.any(). (@jdbevan)ElementInternals labels property. The form-associated callbacks are not yet supported. (@hesxenon)whatwg-url, adding support for URL.parse().cssstyle and rrweb-cssom, to improve CSS parsing capabilities.nwsapi, improving CSS selector matching.parse5, fixing a bug around <noframes> elements and HTML entity decoding.JSDOM.fromURL() to properly reject the returned promise if the server redirects to an invalid URL, instead of causing an uncaught exception.Updated dependencies, notably tough-cookie, which no longer prints a deprecation warning.
tough-cookie, which no longer prints a deprecation warning.This major release changes the prototype of a jsdom's EventTarget.prototype to point to the Object.prototype inside the jsdom, instead of pointing to
This major release changes the prototype of a jsdom's EventTarget.prototype to point to the Object.prototype inside the jsdom, instead of pointing to the Node.js Object.prototype. Thus, the prototype chain of Window stays entirely within the jsdom, never crossing over into the Node.js realm.
This only occurs when runScripts is set to non-default values of "dangerously" or "outside-only", as with the default value, there is no separate Object.prototype inside the jsdom.
This will likely not impact many programs, but could cause some changes in instanceof behavior, and so out of an abundance of caution, we're releasing it as a new major version.
Fixed calls to postMessage() that were done as a bare property (i.e., postMessage() instead of window.postMessage()).
postMessage() that were done as a bare property (i.e., postMessage() instead of window.postMessage()).Fixed an issue with the in operator applied to EventTarget methods, e.g. 'addEventListener' in window, which only appeared in Node.js ≥22.5.0. (@legen
in operator applied to EventTarget methods, e.g. 'addEventListener' in window, which only appeared in Node.js ≥22.5.0. (@legendecas)blur(): it no longer fires focus and focusin on the Document, and blur and focusout no longer have their relatedTarget property set. (@asamuzaK)Fixed selection methods to trigger the selectionchange event on the Document object. (@piotr-oles)
selectionchange event on the Document object. (@piotr-oles)Added the getSetCookie() method to the Headers class. (@ushiboy)
getSetCookie() method to the Headers class. (@ushiboy)Object.prototype, like "constructor" or "toString".rweb-cssom, which can now parse additional CSS constructs.This release reverts our selector engine back to `nwsapi`. As discussed in #3659, the performance regressions from `@asamuzakjp/dom-selector` turned o
This release reverts our selector engine back to nwsapi. As discussed in #3659, the performance regressions from @asamuzakjp/dom-selector turned out to be higher than anticipated. In the future, we can revisit @asamuzakjp/dom-selector after it reaches nwsapi's performance on the two real-world benchmarks provided by the community.
Since reverting to nwsapi causes several functionality regressions, e.g. removing :has() support, we've decided to make this a major version.
Additionally:
input.maxLength, input.minLength, input.size, progress.max, tableCell.colSpan, tableCell.rowSpan, tableCol.span, textArea.cols, textArea.maxLength, textArea.minLength, textArea.rows.This release switches our CSS selector engine from `nwsapi` to `@asamuzakjp/dom-selector`. The new engine is more actively maintained, and supports ma
This release switches our CSS selector engine from nwsapi to @asamuzakjp/dom-selector. The new engine is more actively maintained, and supports many new selectors: see the package's documentation for the full list. It also works better with shadow trees.
There is a potential of a performance regression due to this change. In our stress test benchmark, which runs most of these 273 selectors against this 128 KiB document, the new engine completes the benchmark only 0.25x as fast. However, we're hopeful that in more moderate usage this will not be a significant issue. Any help speeding up @asamuzakjp/dom-selector is appreciated, and feel free to open an issue if this has had a significant impact on your project.
Added an initial implementation of ElementInternals, including the shadowRoot getter and the string-valued ARIA properties. (@zjffun)
ElementInternals, including the shadowRoot getter and the string-valued ARIA properties. (@zjffun)Element.history.pushState() and history.replaceState() to follow the latest specification, notably with regards to how they handle empty string inputs and what new URLs are possible.input.valueAsANumber setter to handle NaN correctly. (@alexandertrefz)cssstyle which contains several bug fixes.Fixed the incorrect canvas peer dependency introduced in v23.0.0.
canvas peer dependency introduced in v23.0.0.Node.js v18 is now the minimum supported version.
whatwg-url which integrates various additions to the URL and URLSearchParams objects.Added crypto.randomUUID(). (@jamesbvaughan)
crypto.randomUUID(). (@jamesbvaughan)DOMRect and DOMRectReadOnly.AbortSignal.timeout().abortSignal.throwIfAborted().submitter argument to the FormData constructor. (@jenseng)getComputedStyle()'s results for color-based properties, to resolve named colors and attempt to provide initial inheritance support. (@hoekz-wwt)Window's event handler properties (e.g. oncopy, ontouchstart, etc.) to reflect the latest list from the standard.DOMParser-created documents to inherit their URL from the creating document.…and a testing package we relied on was recently deprecated.
Fixed setRangeText() used on and elements to calculate the new end index correctly. (@pmstss)
setRangeText() used on <input> and <textarea> elements to calculate the new end index correctly. (@pmstss)pageX, pageY, offsetX, and offsetY on MouseEvents during dispatch. (@jenseng)nwsapi to v2.2.4, bringing along various fixes to our selector engine.Fixed jsdom.reconfigure() to also adjust the URL as seen by the history API, so that e.g. history.replaceState(null, "") would not mess up the URL. (@
jsdom.reconfigure() to also adjust the URL as seen by the history API, so that e.g. history.replaceState(null, "") would not mess up the URL. (@jdufresne)location.hash = "" to leave any # in location.href.cssom with rweb-cssom, since the latter is maintained. (@seanparmelee)Added x, y, pageX, pageY, offsetX, and offsetY to MouseEvent. (@jenseng, @ViniciusFXavier)
x, y, pageX, pageY, offsetX, and offsetY to MouseEvent. (@jenseng, @ViniciusFXavier)unset with getComputedStyle(). (@jsnajdr)submitter property to SubmitEvent. (@jenseng)MouseEvent's screenX and screenY to no longer coerce to integers, allowing fractional values. (@jenseng)formEl.submit() to not longer fire submit events. (@jenseng)<link> is removed. (@jsnajdr)pointer-events to inherit when used with getComputedStyle(). (@jnajdr)<script> elements with no src="" to no longer fire load events. (@t1ger2080)getComputedStyle() to cache its results, which should make it much faster. (@jsnajdr)A potentially-breaking bug fix:
A potentially-breaking bug fix:
window, document, location, and top properties of Window to be non-configurable. (@ExE-Boss)Other changes:
<input type=image> submitting forms. (@jenseng)location setter to the Window object, which forwards to the location.href setter. Setting the URL is still only implemented for fragment navigations, however. (@ExE-Boss)defer="" <script> elements that are added after DOMContentLoaded to execute, instead of being skipped.selectElement.selectedOptions being incorrect when optionElement.selected is set. This was a regression introduced in v20.0.1. Unfortunately this also reverts the performance improvement when appending <option> elements that was introduced then. (@eps1lon)self, locationbar, menubar, personalbar, scrollbars, statusbar, toolbar, frames, parent, external, length, and screen properties of Window to be replaceable: that is, setting them will override their values, instead of having the new value be ignored. (@ExE-Boss)JSDOM.fromURL() in the browser build of jsdom. (@LungZeno)Updated dependencies, notably w3c-xmlserializer, which fixes using DOMParser on XML documents containing emoji.
w3c-xmlserializer, which fixes using DOMParser on XML documents containing emoji.Fixed xhr.abort() to no longer give an exception when the constructed XMLHttpRequest was invalid. (@whamtet)
xhr.abort() to no longer give an exception when the constructed XMLHttpRequest was invalid. (@whamtet)event.getModifierState() on MouseEvent and KeyboardEvent instances to properly consult the ctrlKey, altKey, metaKey, and shiftKey properties of the event. (@juzerzarif)window.customElements property. (@bicknellr)Improved the performance of appending elements to elements. (@TheHound)
<option> elements to <select> elements. (@TheHound)location.pathname getter to not crash when the JSDOM instance was created using an opaque-path URL, including the default URL of about:blank.crypto.getRandomValues() to accept typed array subclasses. (@sebamarynissen)nwsapi fixed some selectors bugs, and tough-cookie fixed some cookie bugs.Node.js v14 is now the minimum supported version.
crypto.getRandomValues(). (@sjrd)HTMLFormControlsCollection and RadioNodeList, so formEl.elements now behaves correctly. (@UndefinedBehavior)signal option to addEventListener(). (@cheap-glitch):root pseudoclass to work correctly. (@hughs-ch)parse5, bringing along some HTML parsing and serialization fixes. (@fb55)Changed jsdom.nodeLocation() to return undefined when used on nodes that originate via fragment parsing (e.g., via innerHTML). Previously it would ret
jsdom.nodeLocation() to return undefined when used on nodes that originate via fragment parsing (e.g., via innerHTML). Previously it would return based on the node location of the fragment string, which made node locations unreliable with respect to the original document source. This restores the behavior that was present in v14.0.0, and was accidentally broken in v14.1.0. (@bakkot)window.close() inside the Window's load event to no longer crash. (@MattiasBuelens)Fixed connectedCallback to fire in situations involving document fragments, which was broken in v18.0.1. (@GrantGryczan)
connectedCallback to fire in situations involving document fragments, which was broken in v18.0.1. (@GrantGryczan)Fixed headers.append() and headers.set() to normalize values. (@MattiasBuelens)
headers.append() and headers.set() to normalize values. (@MattiasBuelens)pageshow events to have bubbles: true and cancelable: true. (@MattiasBuelens)reason property on AbortSignals, along with the corresponding reason argument to abortSignal.abort() and AbortSignal.abort(). (@MattiasBuelens)Fixed live Ranges to update correctly after calling node.normalize(). (@hgiesel)
Ranges to update correctly after calling node.normalize(). (@hgiesel)Ranges to update correctly after removing child nodes. (@hgiesel)inputEl.valueAsDate = null to no longer throw an exception, but instead set the value to the empty string. (@simon-weimann)node.contains(). (@GrantGryczan)Potentially-breaking bug fixes:
Potentially-breaking bug fixes:
ResourceLoader's strictSSL option (which defaults to true).Promise and TypeError instances are created to be the jsdom global, not the Node.js global. This could affect any code that uses instanceof.Other changes:
tagName cache, allowing it to return a lowercase value once it's in the XML document. (@LucasLefevre)Breaking change: Node v12 is now the minimum supported version.
Breaking change: Node v12 is now the minimum supported version.
Added AbortSignal.abort(). (@ninevra)
AbortSignal.abort(). (@ninevra)x and y properties to the return value of getBoundingClientRect(). (@eiko)textareaEl.value if the wrap="" attribute is specified. (@ninevra)<textarea>s according to recent HTML Standard updates. (@ninevra)getComputedStyle(). (@romain-trotard)Removed the dependency on the deprecated `request` package, in the process fixing several issues with the XMLHttpRequest implementation around header…
parentNode.replaceChildren(). (@ninevra)null or undefined as an exception. (@mbest)request package, in the process fixing several issues with the XMLHttpRequest implementation around header processing. Special thanks to vegardbb for completing this months-long effort!Fixed infinite recursion when using MutationObservers to observe elements inside a MutationObserver callback.
MutationObservers to observe elements inside a MutationObserver callback.Fixed Access-Control-Allow-Headers: * to work with XMLHttpRequest. (@silviot)
Access-Control-Allow-Headers: * to work with XMLHttpRequest. (@silviot)xhr.response to strip any leading BOM when xhr.responseType is "json".new Text() and new Comment() constructors to properly set the resulting node's ownerDocument.customElements.whenDefined() to resolve its returned promise with the custom element constructor, per recent spec updates. (@ExE-Boss)<svg><template></template></svg> does not throw an exception, but instead correctly produces a SVG-namespace <template> element.domParser.parseFromString() to treat <noscript> elements appropriately.<form> element and instead associated using the form="" attribute.legendEl.form to return the correct result based on its parent <fieldset>.optionEl.text to exclude <script> descendants.input and change events when disconnected.inputEl.indeterminate to reset to its previous value when canceling a click event on a checkbox or radio button.onclick="...code...") when there were global variables named element or formOwner. (@ExE-Boss)WeakRefs are available, fixed NodeIterator to no longer stop working when more than ten NodeIterator instances are created, and to use less memory due to inactive NodeIterators sticking around. (@ExE-Boss)Fixed a regression that broke customElements.get() in v16.5.0. (@fdesforges)
customElements.get() in v16.5.0. (@fdesforges)window.event to have a setter which overwrites the window.event property with the given value, per the specification. This fixes an issue where after upgrading to jsdom v16.5.0 you would no longer be able to set a global variable named event in the jsdom context.Added inputEvent.inputType. (@diegohaz)
window.queueMicrotask().window.event.inputEvent.inputType. (@diegohaz)ondragexit from Window and friends, per a spec update.about:blank iframes. Previously it was getting set to the parent's URL. (@SimonMueller)hidden="" attribute to cause display: none per the user-agent stylesheet. (@ph-fritsche)new File() constructor to no longer convert / to :, per a pending spec update.MutationObserver instance as their this value.<input type=checkbox> and <input type=radio> to be mutable even when disabled, per a spec update.XMLHttpRequest to not fire a redundant final progress event if a progress event was previously fired with the same loaded value. This would usually occur with small files.XMLHttpRequest to expose the Content-Length header on cross-origin responses.xhr.response to return null for failures that occur during the middle of the download.localStorage or dataset. (@ExE-Boss)Added a not-implemented warning if you try to use the second pseudo-element argument to getComputedStyle(), unless you pass a ::part or ::slotted pseu
getComputedStyle(), unless you pass a ::part or ::slotted pseudo-element, in which case we throw an error per the spec. (@ExE-Boss)el.tagName, which also indirectly improves performance of selector matching and style computation. (@eps1lon)form.elements to respect the form="" attribute, so that it can contain non-descendant form controls. (@ccwebdesign)el.focus() to do nothing on disconnected elements. (@eps1lon)el.focus() to work on SVG elements. (@zjffun)<body> element. (@eps1lon)imgEl.complete to return true for <img> elements with empty or unset src="" attributes. (@strager)imgEl.complete to return true if an error occurs loading the <img>, when canvas is enabled. (@strager)imgEl.complete to return false if the <img> element's src="" attribute is reset. (@strager)valueMissing validation check for <input type="radio">. (@zjffun)translate="" and draggable="" attribute processing to use ASCII case-insensitivity, instead of Unicode case-insensitivity. (@zjffun)Added firing of focusin and focusout when using el.focus() and el.blur(). (@trueadm)
focusin and focusout when using el.focus() and el.blur(). (@trueadm)contenteditable="" attribute to be considered as focusable. (@jamieliu386)window.NodeFilter to be per-Window, instead of shared across all Windows. (@ExE-Boss)handleEvent properties as event listeners. (@ExE-Boss)load event instead of an error event, when the canvas package is installed. (@strager)Updated StyleSheetList for better spec compliance; notably it no longer inherits from Array.prototype. (@ExE-Boss)
StyleSheetList for better spec compliance; notably it no longer inherits from Array.prototype. (@ExE-Boss)requestAnimationFrame() from preventing process exit. This likely regressed in v16.1.0.setTimeout() to no longer leak the closures passed in to it. This likely regressed in v16.1.0. (@AviVahl)click() on a <label> element, or one of its descendants.getComputedStyle() to consider inline style="" attributes. (@eps1lon)<input type="number">'s stepUp() and stepDown() functions to be properly decimal-based, instead of floating point-based.selectEl.value would not invalidate properties such as selectEl.selectedOptions. (@ExE-Boss)<input>'s src property, and <ins>/<del>'s cite property, to properly reflect as URLs.window.addEventLister, window.removeEventListener, and window.dispatchEvent to properly be inherited from EventTarget, instead of being distinct functions. (@ExE-Boss)addEventListener.data: URLs.<input type="month"> that could occur in some time zones and for some times.document.implementation.createDocument() to return an XMLDocument, instead of a Document. (@ExE-Boss)Your coding agent can read these notes before it upgrades. Set up the MCP server →