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 7 days ago
22 Sep 2026
Release timing varies
gaps range from 2 weeks to 3 months
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
15 years old
287 releases · first in 2011
Added support for custom elements! Congratulations and thanks to @pmdartus for making this happen, after ten months of hard work and lots of effort po
Attr as a Node, e.g. by checking its baseURI property or calling attr.cloneNode().Changed Attr to extend Node, to align with specifications. (@ExE-Boss)
console.timeLog().Attr to extend Node, to align with specifications. (@ExE-Boss)<noscript> children to be parsed as nodes, instead of as text, when runScripts is left as the default of undefined. (@ACHP)cssstyle to v2.1.0, which brings along fixes to handling of rgba() and hsl() colors. (@kraynel)<input>s and <textarea>s. (@Matthew-Goldberg)setTimeout(), setInterval(), and requestAnimationFrame(), particularly around window closing and recursive calls.One column per quarter.
Fixed Node v10 and v11 support when runScripts was set.
runScripts was set.<input>'s type="" attribute.<input type="range"> when max="" is less than min="".For this release we'd like to welcome @pmdartus to the core team. Among other work, he's driven the heroic effort of constructor prototype and reform
For this release we'd like to welcome @pmdartus to the core team. Among other work, he's driven the heroic effort of constructor prototype and reform in jsdom and its dependencies over the last few months, to allow us to move away from shared constructors and prototypes, and set the groundwork for custom elements support (coming soon!).
Breaking changes:
dom.runVMScript() API has been replaced with the more general dom.getInternalVMContext() API.Window now creates new instances of all the web platform globals. That is, our old shared constructor and prototypes caveat is no longer in play.Window now exposes all JavaScript-spec-defined globals uniformly. When runScripts is disabled, it exposes them as aliases of the ones from the outer Node.js environment. Whereas when runScripts is enabled, it exposes fresh copies of each global from the new scripting environment. (Previously, a few typed array classes would always be aliased, and with runScripts disabled, the other classes would not be exposed at all.)Other changes:
AbstractRange, Range, StaticRange, Selection, and window.getSelection() APIs.Comment, Text, and DocumentFragment.valueAsDate, valueAsNumber, stepUp() and stepDown() to <input> elements. (@kraynel)window.origin.document.origin.<template> to work correctly inside XML documents.<meta charset> or <meta http-equiv="charset"> elements.input.type to default to "text". (@connormeredith)<input> with fractional values for their step="" attribute. (@kontomondo)<input> elements.<input type="email" multiple pattern="..."> validation.fileReader.readAsDataURL() to always base64-encode the result. (@ytetsuro)<img> elements into documents without a browsing context to no longer crash when the canvas package is installed.window.setTimeout() or window.setInterval().getComputedStyle(). (@eps1lon)Fixed JSDOM.fromURL() handling of URLs with hashes in them, to no longer send the hash to the server and append an extra copy of it when constructing
JSDOM.fromURL() handling of URLs with hashes in them, to no longer send the hash to the server and append an extra copy of it when constructing the Document. (@rchl)focus events. (@eps1lon)mediaElement.addTextTrack(). (@mtsmfm)nwsapi minimum version to 2.2.0, which fixes issues with ::-webkit- prefixed pseudo-elements and namespaced attribute selectors.Added basic style inheritance in getComputedStyle() for the 'visibility' property. This sets the foundation for further work on inheritance, cascading
getComputedStyle() for the 'visibility' property. This sets the foundation for further work on inheritance, cascading, and specificity. (@eps1lon)shadowRoot.activeElement.readystatechange events during document loading.form.requestSubmit(), to match our existing stub for form.submit().el.tabIndex's default value, when no tabindex="" attribute was set, to reflect the updated specification.el.attachShadow() on something that's already a shadow host, to reflect the updated specification.<input type="range">.selectEl.value when no <option> is selected to return the empty string, instead of the value of the first option. (@tgohn)new FormData(formElement). (@brendo)"undefined". (@papandreou)el.getAttributeNS() or el.setAttributeNS().canvas as an optional ``peerDependency`, which apparently helps with Yarn PnP support.Moved the nonce property from HTMLScriptElement and HTMLStyleElement to HTMLElement. Note that it is still just a simple reflection of the attribute,
nonce property from HTMLScriptElement and HTMLStyleElement to HTMLElement. Note that it is still just a simple reflection of the attribute, and has not been updated for the rest of the changes in whatwg/html#2373.style and on<event> properties to properly track their related attributes for SVG elements. (@kbruneel)XMLHttpRequest merging preflight and response headers. (@thiagohirata)XMLHttpRequest reserializing content-type request headers unnecessarily. See whatwg/mimesniff#84 for more details. (@thiagohirata)element.tagName to be the ASCII uppercase of the element's qualified name, instead of the Unicode uppercase.Added the Headers class from the Fetch standard.
Headers class from the Fetch standard.element.translate getter and setter.XMLHttpRequest on the newly-released Node.js v12.form.elements to exclude <input type="image"> elements.pattern="" form control validation to apply the given regular expression to the whole string. (@kontomondo)Several potentially-breaking changes, each of them fairly unlikely to actually break anything:
Several potentially-breaking changes, each of them fairly unlikely to actually break anything:
JSDOM.fromFile() now treats .xht files as application/xhtml+xml, the same as it does for .xhtml and .xml. Previously, it would treat them as text/html.JSDOM constructor's contentType option has a charset parameter, and the first argument to the constructor is a binary data type (e.g. Buffer or ArrayBuffer), then the charset will override any sniffed encoding in the same way as a Content-Type header would in browser scenarios. Previously, the charset parameter was ignored.Blob or File constructor with the endings: "native" option, jsdom will now convert line endings to \n on all operating systems, for consistency. Previously, on Windows, it would convert line endings to \r\n.Added activation behavior for and elements whose href="" points to a javascript: URL or fragment.
<a> and <area> elements whose href="" points to a javascript: URL or fragment.<datalist> element's options property.<input> element's list property.PageTransitionEvent, and the firing of pageshow events during loading.External class as a property of window.innerHTML and outerHTML) to be spec-compliant. (@pmdartus)innerHTML) breaking after setting certain properties to non-string values.<style>s to no longer apply to documents without a browsing context. This includes fixing a crash that would occur with such styles if they had an @import rule.<option>'s label and value properties to return correct values in various edge cases.load event during document loading to target the Document, not the Window.pretendToBeVisual option to propagate to child subframes, as well as the main Window. (@pyrho)nwsapi version from v2.1.1 to v2.1.3, bringing along a few fixes in our selector engine.JSDOM.fragment() now creates fragments whose document has no browsing context, i.e. no associated Window. This means the defaultView property will be
Breaking changes:
JSDOM.fragment() now creates fragments whose document has no browsing context, i.e. no associated Window. This means the defaultView property will be null, resources will not load, etc.JSDOM.fragment(), called with no arguments, now creates a DocumentFragment with no children, instead of with a single child text node whose data was "undefined".Other changes:
element.blur() on a focused element.<link> elements into documents with no browsing context to no longer crash if the originating JSDOM was configured to fetch the resource. Now, per spec, <link> elements only attempt to fetch if they are browsing-context connected.<template> elements to have the correct semantics, of using a separate browsing-context-less document to store its contents. In particular this means resources will not be fetched for elements inside the <template>, as per spec.Added support for MutationObservers! (@pmdartus)
MutationObservers! (@pmdartus)<progress> element's value, max, and position properties.navigator.plugins and navigator.mimeTypes. (But, they are always empty.)<summary> elements respond to click events by toggling their parent <details>.<summary> elements to be focusable.isTrusted set to true.DOMParser-created documents to have their readyState set to "complete".<fieldset>s get disabled.getComputedStyle() to throw a sensible exception when passed the wrong argument, instead of one that exposes jsdom internals.saxes dependency, so that it now correctly errors on XML fragments like <foo bar:="1"/>.Added el.insertAdjacentElement() and el.insertAdjacentText().
el.insertAdjacentElement() and el.insertAdjacentText().reset event to form.reset(). (@epfremmer)type, value, and defaultValue properties to <output> elements, including their form reset behavior. (@epfremmer)outputEl.htmlFor property.<style> or <script> elements. This regressed in v11.6.0. To learn more, see V8 issue #6730.style property on <a> and <area> elements. This regressed in v13.0.0.node.isConnected to not always return false for nodes inside a shadow tree. (@pmdartus)<button type="reset"> and <input type="reset"> elements to actually perform a form reset when clicked, instead of doing nothing. (@epfremmer)el.setCustomValidity() for <output> and <fieldset>.click events, so that for example calling el.click() on the child of a submit button element will submit the form.focus/blur events to be composed.mediaElement.duration to default to NaN.olEl.start to default to 1.XMLHttpRequest against non-existant file: URLs to treat that as a network error, instead of crashing. (pascalbayer) Note that in the future we may completely disable XMLHttpRequest usage against file: URLs to follow the browser security model.document.title in SVG documents.titleElement.text to return the child text content, instead of being the same as titleElement.innerHTML.<textarea>s to properly account for child CDATA section nodes changing.Element.prototype[Symbol.unscopables].Removed support for v1.x of the `canvas` package, in favor of v2.x. This also removes support for canvas-prebuilt, since canvas v2.x has a built-in pr
Breaking change:
canvas package, in favor of v2.x. This also removes support for canvas-prebuilt, since canvas v2.x has a built-in prebuilt version.Other changes:
w3c-xmlserializer package. Previously we were just using the HTML serialization, even in XML documents.storageEvent.initStorageEvent() method.passive option to addEventListener().relList property to <a>, <area>, and <link> elements.Added support for shadow DOM! This includes shadow roots, slots, composed events, and more. (@pmdartus)
element.toggleAttribute() method.XMLHttpRequest sometimes sending an empty request body after a preflight request. (@andreasf)formElement.form property to use an algorithm that also checks the form="" attribute, instead of always looking for the closest ancestor <form> element. (@jamietre)canvas or canvas-prebuilt packages were installed, but failed to load. (@joscha)Dramatically upgraded our XML parser, from the unmaintained `sax` package to the well-maintained `saxes` replacement. This increases our specification
sax package to the well-maintained saxes replacement. This increases our specification conformance, including rejecting certain ill-formed XML documents that were previously accepted, and properly handling other constructs like empty comments, CDATA sections, and <script> elements. (@lddubeau)fieldsetEl.elements and fieldsetEl.type properties.options parameter to dom.runVMScript(). (@SimenB)fetch() implementations to see what element initiated the fetch. (@sarvaje)input and change events for <input> elements to be trusted and uncancelable.<script>s with the async attribute to not execute before sync <script>s that precede them. We still do not, in general, have proper execution of scripts during the initial parsing of a document, so this fix is more of a reduction of badness than an alignment with the specification. This behavior regressed in v12.0.0. (@sarvaje)This major release brings along our new resource loader API, finally bringing all the capabilities from jsdom v9 to the new (jsdom v10+) API. Thanks v
This major release brings along our new resource loader API, finally bringing all the capabilities from jsdom v9 to the new (jsdom v10+) API. Thanks very much to @sarvaje for his work to make this possible!
Breaking changes:
parse5 dependency to v5, which changes the format of the node locations returned by dom.nodeLocation().whatwg-url dependency to v7, which changes the origin of file: URLs to be an opaque origin (and thus file: URLs are no longer same origin to each other).Other changes:
countReset(), dir() and dirxml() methods to console.InputEvent class.window.status.htmlElement.draggable.window.frameElement to correctly return an actual HTMLElement instance, instead of a jsdom internal class.textarea elements to preserve their values.select.selectedOptions sometimes returning outdated results.:checked.window.name to default to the empty string, per spec, instead of "nodejs".Added window.localStorage, window.sessionStorage, and StorageEvent support. These are currently only stored in-memory; file an issue if you need persi
window.localStorage, window.sessionStorage, and StorageEvent support. These are currently only stored in-memory; file an issue if you need persistent (on-disk) storage capability so we can discuss adding that. This feature includes the new storageQuota option for controlling how much can be stored.element.closest(). (@caub)hashchange and popstate events to no longer bubble, per a specification update.cssstyle to v1.0.0, bringing along various fixes to our CSS parser and object model. (@eddies)nwsapi to v2.0.7, bringing along various fixes to our selector engine.Added node.getRootNode(). (@FrecksterGIT)
node.getRootNode(). (@FrecksterGIT)label.control. (@FrecksterGIT)el.labels for form control elements. (@FrecksterGIT)contentType of Documents created through <iframe>s.contentType and origin of Documents created through document.implementation.createDocument().sourceEl.srcset to return the value of the srcset="" attribute, instead of the cite="" attribute.node.normalize() to not modify non-Text nodes. (@lddubeau)cssstyle to v0.3.1, bringing along various fixes to our CSS parser and object model. (@jsakas)whatwg-url to v6.4.1, fixing the interaction of URL's href and searchParams properties.nwsmatcher to nwsapi, bringing along extensive fixes, performance improvements, and additional selector support.Added event.srcElement and event.returnValue.
event.srcElement and event.returnValue.XMLHttpRequest to correctly set the User-Agent header, and set it on CORS preflight requests. (@BehindTheMath)Added node.lookupPrefix(), node.lookupNamespaceURI() and node.isDefaultNamespace().
node.lookupPrefix(), node.lookupNamespaceURI() and node.isDefaultNamespace().Documents; previously it would not clone all of the appropriate state, and would sometimes add an extra document type node.textContent and nodeValue properties.canvas.toBlob() to properly pass through the JPEG quality argument, instead of always passing zero to node-canvas. (@challakoushik)Added the full constraint validation API, i.e. willValidate, validity, validationMessage, checkValidity(), reportValidity(), and setCustomValidity(),
willValidate, validity, validationMessage, checkValidity(), reportValidity(), and setCustomValidity(), on HTMLButtonElement, HTMLFieldSetElement, HTMLFormElement, HTMLInputElement, HTMLObjectElement, HTMLOutputElement, HTMLSelectElement, and HTMLTextAreaElement. (@kontomondo)getElementById() to DocumentFragment.Added the boolean return value to DOMTokenList's replace() method, per the recent spec addition.
DOMTokenList's replace() method, per the recent spec addition.FileReader's readAsBinaryString() method, as it has been added back to the specification.Window, instead of on Window.prototype. (@Fetz)<img> element's src="" attribute. (@atsikov)abort events on AbortSignals to have their isTrusted set to true.XMLHttpRequest's open() method.data: URL parsing throughout jsdom, by using the new whatwg-mimetype and data-urls packages..webidl files that were included in the npm package.Fixed another regression (since v11.6.0) in elements, where they would omit a series of parsing jsdomError events for any style sheet text containing
<style> elements, where they would omit a series of parsing jsdomError events for any style sheet text containing spaces.<style> and <script> elements are evaluated; for example, <script> elements inserted by innerHTML are no longer evaluated.Fixed one regression (since v11.6.0) in elements, where their sheet property would sometimes be null when it should not be.
<style> elements, where their sheet property would sometimes be null when it should not be.<style> element's sheet property would be left as a CSSStyleSheet despite it not being in the document.Another regression remains where we are emitting spurious CSS-parsing jsdomError events; see #2123. We also discovered a large amount of preexisting brokenness around <style>, <link>, and @import; see #2124 for more details.
We'll try to fix these soon, especially the regression.
Added a fully-functioning WebSocket implementation!
WebSocket implementation!window.performance implementation, including the basics of the High Resolution Time specification: performance.now(), performance.timeOrigin, and performance.toJSON().HTMLMeterElement, except for meterEl.labels.locationbar, menubar, personalbar, scrollbars, statusbar, and toolbar properties to Window.window.screen: availWidth, availHeight, colorDepth, and pixelDepth. All of its properties are now getters as well.window.devicePixelRatio.getModifierState() to MouseEvent and KeyboardEvent.HTMLInputElement's files property.endings option to the Blob constructor.MouseEvent when using element.click().popstate and hashchange events during fragment navigation to make them trusted events.data: URL parsing to not include the fragment portions.new Document() to be UTF-8.probablySupportsContext() and setContext() from HTMLCanvasElement, per spec updates.window.scrollLeft and window.scrollTop properties, and the window.createPopup() method.(This should have been a minor release; oops.)
(This should have been a minor release; oops.)
AbortSignal and AbortController.<input>s and implemented validation for more input types.For this release we'd like to welcome @Zirro to the core team; his contributions over the course of this year have enhanced jsdom immensely.
For this release we'd like to welcome @Zirro to the core team; his contributions over the course of this year have enhanced jsdom immensely.
SVGElement, SVGGraphicsElement, SVGSVGElement, SVGTests, SVGAnimatedString, SVGNumber, and SVGStringList. The main impact here is that SVG elements are now instances of SVGElement, instead of being simply Element (as they were in v11.3.0) or HTMLUnknownElement (as they were in v11.2.0 and previously). The only concrete subclass that is implemented is SVGSVGElement, for <svg> itself; other tags will not map to their correct classes, because those classes are not yet implemented.pretendToBeVisual option, which controls the presence of the new requestAnimationFrame() and cancelAnimationFrame() methods, and the new values of document.hidden/document.visibilityState. See the README for more information. (@SimenB)append() and prepend() methods to Document, DocumentFragment, and Element. (@caub)before(), after(), and replaceWith() methods to DocumentType, Element, and CharacterData. (@caub)node.isConnected.node.isSameNode().domParser.parseFromString(). (@myabc)input.value getter/setter logic for <input type="file">.NamedNodeMap, i.e. of element.attributes, such that retrieving named or indexed properties will now always work properly.domParser.parseFromString() to not parse HTML character entities in XML documents. (@myabc)xhr.abort() to clear any set headers.XMLHttpRequest to always decoded responses as UTF-8 when responseType is set to "json".XMLHttpRequest CORS header handling, especially with regard to preflights and Access-Control-Allow-Headers. (@ScottAlbertine)radioButton.click() to fire appropriate input and change events. (@liqwid)querySelector()/querySelectorAll() behavior for SVG elements inside <template> contents DocumentFragments, including those created by JSDOM.fragment(). (@caub)<script> elements, when includeNodeLocations is set.<applet> element, following the spec.For this release we'd like to formally welcome @TimothyGu to the core team, as a prolific contributor. He will join the illustrious ranks of those who
For this release we'd like to formally welcome @TimothyGu to the core team, as a prolific contributor. He will join the illustrious ranks of those who do so much work on jsdom that we no longer note their names in the changelog.
table.tHead, table.tFoot, and table.caption setters, and the table.createTBody() method.CompositionEvent and WheelEvent classes.<details> element implementation. (@Zirro)<marquee> and <picture> element implementations. (@Zirro)uiEvent.initUIEvent(), keyboardEvent.initKeyboardEvent(), and mouseEvent.initiMouseEvent() to match the latest specifications.DOMTokenList (used by, e.g., element.classList) to use proxies for improved specification compliance and "liveness".DOMException class to be spec-compliant, including its constructor signature.table.rows getter, and the table.createCaption() and table.deleteRow() methods.document.querySelector === documentFragment.querySelector, incorrectly).FocusEvent creation, which regressed in v11.2.0.UIEvent to only allow initializing with Window objects for its view property.tr.rowIndex and tr.deleteCall().<td> and <th> to be simply HTMLTableCellElement, and improved that class's spec compliance.label.click() to not trigger the labeled control's activation behavior when the control is disabled. (@schreifels)document.getElementsByName() to return a NodeList instead of a HTMLCollection. (@Zirro)XMLHttpRequest. (@Zirro)This release brings with it a much-awaited infrastructure change, as part of webidl2js v7.3.0 by the ever-amazing TimothyGu: jsdom can now generate sp
This release brings with it a much-awaited infrastructure change, as part of webidl2js v7.3.0 by the ever-amazing TimothyGu: jsdom can now generate spec-compliant versions of classes that have "Proxy-like" behavior, i.e. allow getting or setting keys in unusual ways. This enables a number of improvements, also by TimothyGu:
NodeList and HTMLCollection, such that retrieving properties via indices or (in HTMLCollection's case) id/name values will always work correctly.element.dataset support.<select> elements, as well as the corresponding item() and namedItem() methods.FileList indexed properties, i.e. fileList[i].select.options an instance of the newly-implemented HTMLOptionsCollection, instead of just a HTMLCollection.This infrastructure will allow us to improve and implement many other similar behaviors; that work is being tracked in #1129.
In addition to these improvements to the object model, we have more work to share:
document.clear(), document.captureEvents(), document.releaseEvents(), window.external.AddSearchProvider(), and window.external.IsSearchProviderInstalled(). (@Zirro)TreeWalker and NodeIterator.<textarea>'s value, defaultValue, and textContent per a recent spec changeid="undefined" shadowing the undefined property of the global object. (@TimothyGu)getElementsByClassName() to be ASCII case-insensitive, instead of using JavaScript's toLowerCase().XMLHttpRequest and FileReader behavior, mainly around event handlers, abort(), and network errors.NodeIterator.Added javascript: URL "navigation" via window.location, at least by evaluating the side effects. It still doesn't actually navigate anywhere. (@Forbes
javascript: URL "navigation" via window.location, at least by evaluating the side effects. It still doesn't actually navigate anywhere. (@ForbesLindesay)whatwg-url to v6.1.0, bringing along origin serialization changes and URLSearchParams among various other fixes. (@ForbesLindesay)javascript: URL loading for iframes to do proper percent-decoding and error reporting.XMLHttpRequest responses when they were over 1 MiB.close()d, which could cause strange errors since most objects are unusable at that point. (@Enverbalalic)Custom parsers, via the parser option to the old API, can no longer be specified. They were never tested, often broken, and a maintenance burden. The
Breaking changes:
parser option to the old API, can no longer be specified. They were never tested, often broken, and a maintenance burden. The defaults, of parse5 for HTML and sax for XML, now always apply.dom.nodeLocation() or the old API's jsdom.nodeLocation() now have a different structure.runScripts applies to event handler attributes; now they will no longer be converted into event handler functions unless runScripts: "dangerously" is set. However, event handler properties will now work with any runScripts option value, instead of being blocked.Other changes:
oneventname properties to various prototypes, ensures the correct order when interleaving event handlers and other event listeners, and ensures that event handlers are evaluated with the correct values in scope.Location properties to be on the instance, instead of the prototype, and to be non-configurable.HTMLCollection, and thus of parsing large documents. (@Zirro)getComputedStyle() by removing unsupported selectors from the default style sheet. (@flaviut)TypeError when given invalid values. (@TimothyGu)Symbol.toStringTag properties to be non-writable and non-enumerable. (@TimothyGu)tokenList.remove() when the DOMTokenList corresponded to a non-existant attribute. (@Zirro)fileReader.abort() to terminate ongoing reads properly.xhr.send() to support array buffer views, not just ArrayBuffers. (@ondras)GET requests to data: URLs using XMLHttpRequest. (@Zirro)runScripts.tokenList.replace() edge-case behavior."InvalidCharacterError" DOMExceptions, instead of "NamespaceError" DOMExceptions.input.select() to no longer throw on types where selection does not apply.event.initEvent() and various related methods to have additional defaults.XMLHttpRequest responses.xhr.getAllResponseHeaders(), and separating the header values with a comma-space (not just a comma).XMLHttpRequest.XMLHttpRequest.xhr.overrideMimeType() to no longer throw for invalid input.blob.close() and blob.isClosed().toString() methods on various prototypes, which were made redundant in v10.1.0 but we forgot to remove.Added the value sanitization algorithm for password, search, tel, text, color, email, and url input types. (@Zirro)
Symbol.toStringTag to all web platform classes, so that now Object.prototype.toString.call() works as expected on jsdom objects.select.selectedOptions property.toString() methods on various prototypes that returned "[object ClassName]" in an attempt to fake the Symbol.toStringTag behavior.XMLHttpRequest to pre-allocate a 1 MiB buffer, which it grows exponentially as needed, in order to avoid frequent buffer allocation and concatenation. (@skygon)runScripts and resources options into iframes.xhr.abort() during a readystatechange event.Apart from the new API, the following changes were made, with breaking changes bolded:
This release includes a complete overhaul of jsdom's API for creating and manipulating jsdoms. The new API is meant to be much more intuitive and have better defaults, with complete documentation in the newly-overhauled README. We hope you like it!
As discussed in the new README, the old API is still available and supported via require("jsdom/lib/old-api.js"), at least until we have ported all of its features over to the new API. It will, however, not be gaining any new features, and we suggest you try the new API unless you really need the customizable resource loading the old API provides.
Apart from the new API, the following changes were made, with breaking changes bolded:
omitJsdomErrors option to omitJSDOMErrors, for consistency with web platform APIs.document.dir. (@Zirro)<a> and <area> APIs to the latest specification, and fixed a few bugs with them. (@makana)<img> elements to no longer fire load events unless their image data is actually loaded (which generally only occurs when the canvas package is installed).XMLHttpRequest preflights to forward approved preflight headers to the actual request. (@mbroadst)htmlElement.dir to properly restrict its values to "ltr", "rtl", or "auto". (@Zirro)innerHTML to the empty string to no longer be a no-op. (@Zirro)window.postMessage(), so that now you don't always have to pass an origin of "*". (@jmlopez-rod)xhr.open() error message when there are not enough arguments. (@lencioni)Added the Option named constructor. (@NAlexPear)
Option named constructor. (@NAlexPear)canvas-prebuilt npm package as an alternative to canvas. (@asturur)setTimeout() and setInterval() to always return a positive integer, instead of returning 0 the first time were called. (@yefremov)jsdom.env() to preserve URL fragments across redirects. (@josephfrazier)optionEl.text and optionEl.value to be more spec-compliant.event.stopImmediatePropagation() to actually stop immediate propagation, not just propagation.clearTimeout() and clearInterval() to work correctly when using jsdom browserified.Added dummy properties offsetTop, offsetLeft, offsetWidth, and offsetHeight that always return 0, and offsetParent which always returns null, for all
offsetTop, offsetLeft, offsetWidth, and offsetHeight that always return 0, and offsetParent which always returns null, for all HTML elements. (@yefremov)Added forEach, keys, values, and entries methods to NodeList.
forEach, keys, values, and entries methods to NodeList.event.cancelBubble.scrollWidth, scrollHeight, clientTop, clientLeft, clientWidth, and clientHeight that always return 0 to all elements. (@alistairjcbrown)Blob, File, and FileReader to better match the File API specification. (@TimothyGu)XMLHttpRequest to match recent specification changes and test updates.element.getClientRects() to return an empty array, instead of an array containing a dummy bounding box. (@alistairjcbrown)navigator.vendor to return "Apple Computer, Inc." instead of "Google Inc.", since we have chosen the WebKit navigator compatibility mode.Removed the use of array.includes to fix a compatibility issue with Node.js v4.
array.includes to fix a compatibility issue with Node.js v4.Added CDATASection nodes, including document.createCDATASection. (@snuggs)
CDATASection nodes, including document.createCDATASection. (@snuggs)node.wholeText. (@jdanyow)document.body.document.embeds, document.plugsin, and document.scripts. These were supposed to be added in 9.5.0 but were mistakenly omitted.element.insertAdjacentHTML to work when the element has null or the document as its parent node, as long as the insertion position is "afterbegin" or "beforeend".{ once: true } option to addEventListener. (@i8-pi)XHTMLHttpRequest and POSTing JSON contents to an endpoint that requires CORS while using an Authorization header. (@dunnock)document.body and document.title to act more correctly in various edge cases.HTMLCollection named access to return the first element encountered, not the last.Fixed syntax errors in Node.js v4.
Fixed DOMTokenList and getElementsByClassName to only split on ASCII whitespace, not all Unicode whitespace.
DOMTokenList and getElementsByClassName to only split on ASCII whitespace, not all Unicode whitespace.Fixed an error that occurred when passing no class names to getElementsByClassName, e.g. getElementsByClassName("") or getElementsByClassName(" ").
getElementsByClassName, e.g. getElementsByClassName("") or getElementsByClassName(" ").Added the blob.isClosed property. (@TimothyGu)
blob.isClosed property. (@TimothyGu)file.lastModified property to be on File instead of on Blob. (@TimothyGu)file.lastModified property to default to the time of the File object's creation, not the time that the property is accessed. (@TimothyGu)"iframe" became focusable in v9.7.0.Fixed a performance regression introduced in 9.5.0 for modifying the DOM. It was particularly noticable during initial parsing of a document with many
Added EventListenerOptions support to addEventListener and removeEventListener, including both the once and capture options. (@GianlucaGuarini)
EventListenerOptions support to addEventListener and removeEventListener, including both the once and capture options. (@GianlucaGuarini)document.hasFocus() (@acusti)iframe will also focus the iframe itself. (@acusti)Added HTMLCollection.prototype[Symbol.iterator], so you can use for-of loops over HTMLCollections now. (@i8-pi)
HTMLCollection.prototype[Symbol.iterator], so you can use for-of loops over HTMLCollections now. (@i8-pi)file.lastModified to return the current time as the default, instead of 0.Attrs to properly clone the namespace prefix.XMLHttpRequest progress event ordering slightly to better match the spec and browsers.event.stopPropagation and event.stopImmediatePropagation on already-dispatched events, per the latest changes to the DOM Standard.Added document.scripts, document.embeds, and document.plugins.
document.scripts, document.embeds, and document.plugins.document.getElementsByTagName and document.getElementsByTagNameNS to return HTMLCollections instead of NodeLists, and to follow the spec algorithms more exactly.HTMLCollection-returning getters such as document.applets or table.cells to be more spec-compliant.agent and agentClass options, not just the agentOptions one.console.groupCollapse to be console.groupCollapsed (and changed the virtual console accordingly).Fixed error events from failed resource loads going missing since v9.4.3. I really should have tested that release better.
error events from failed resource loads going missing since v9.4.3. I really should have tested that release better.Fixed a leftover console.log introduced in the error handling path in v9.4.3.
console.log introduced in the error handling path in v9.4.3.Fixed spurious "jsdomError"s occuring when closing a window, due to aborted resource loads.
"jsdomError"s occuring when closing a window, due to aborted resource loads.Fixed what would happen when inline event handlers (such as element.onclick) would return non-boolean values (such as undefined); it would previously
element.onclick) would return non-boolean values (such as undefined); it would previously erroneously cancel the event, in many cases. (@dmethvin)Implemented the cloning steps for elements, so that cloned inputs properly copy over their value, checkedness, dirty value flag, and dirty checkedness
<input> elements, so that cloned inputs properly copy over their value, checkedness, dirty value flag, and dirty checkedness flag. (@matthewp)Added the DOMParser API. It is spec-compliant, including producing elements, except that the produced documents do not have the same URL as the creati
DOMParser API. It is spec-compliant, including producing <parsererror> elements, except that the produced documents do not have the same URL as the creating document (they instead always have "about:blank").parsingMode: "xml". Creating documents will now fail, just like in a browser, when ill-formed XHTML markup is used.<!ENTITY declarations.window.frameElement, although without appropriate cross-origin security checks.jsdom.evalVMScript public API.agent and agentClass in addition to agentOptions. (@frarees)<fieldset disabled>.FormData for recent spec fixes: blobs, files, and filenames should now all work like you'd expect.FormData constructor to use the proper, rather-complex, constructing the form data set algorithm.window object to be non-enumerable.<script> elements to load when they gain a src attribute while in a document.<link rel="stylesheet"> elements to load when their href attributes change while in a document.<img>s (when the canvas npm package is installed) that were specified via relative URL; this regressed in 9.2.1.<iframe> documents to have the correct referrer value (viz. the URL of their parent).input.checked inside click events on checkboxes.<iframe> element or the <iframe>'s window in appropriate scenarios involving name vs. id attributes on the <iframe>. (@matthewp)Added the Audio named constructor.
Audio named constructor.Image named constructor to follow the spec more closely (e.g. Image.prototype is now equal to HTMLImageElement.prototype).tabIndex setter, which regressed in 9.1.0, to no longer cause errors.Fixed 's selectionStart, selectionEnd, and selectionDirection getters to return null, instead of throwing, for elements that do not allow selection, p
<input>'s selectionStart, selectionEnd, and selectionDirection getters to return null, instead of throwing, for elements that do not allow selection, per a recent spec change.<base>'s href getter logic to return the attribute value instead of the empty string for unparseable URLs, per a recent spec change.error events on window beyond the first one.new URL to correctly throw for unparseable URLs, and all of URL's setters to correctly ignore invalid input instead of throwing.StyleSheetList.prototype.item to return null instead of undefined for out-of-bounds indices. (@Ginden)cssstyle minimum version to ensure all jsdom installs (not just fresh ones) get the benefit of cssstyle's recently-better background and width setters.Added jsdom.changeURL(window, newURL) for allowing you to override a window's existing URL. (@mummybot)
jsdom.changeURL(window, newURL) for allowing you to override a window's existing URL. (@mummybot)proxy option to be applied to all requests; previously it was not always passed through. (@nicolashenry)XMLHttpRequest response header filtering for cross-origin requests; this also fixes ProgressEvents fired from such XHRs. (@nicolashenry)Added a somewhat-reasonable implementation of focus and focus events. Although the full complexity of focus is not implemented, the following improvem
FocusEvent class, and now focus and blur events are fired appropriately.tabIndex now returns 0 by default for focusable elements.navigator to be to-spec:
appCodeName, product, productSub, vendor, and vendorSub; also changes userAgent, appName, platform, and version to be more browser-like instead of based on various Node.js information.language and languages.onLine.javaEnabled().noUI.formEl.action to return a value resolved relative to the document URL, or to return the document URL if the corresponding attribute is missing or empty.window.close() not correctly clearing event listeners on the document. (@Ojek)"jsdomError" will now be emitted to the virtual console.This major release removes jsdom's support for mutation events. Mutation events were never well-specified, and the modern DOM Standard omits them in t
This major release removes jsdom's support for mutation events. Mutation events were never well-specified, and the modern DOM Standard omits them in the hopes that they can be removed from browsers (although this has not yet happened in major browser engines). We had hoped to implement their modern alternative, mutation observers, before performing this removal, to give jsdom users the same capabilities.
However, recent performance investigations revealed that mutation events were the major bottleneck in most jsdom operations; tools like ecmarkup which make heavy use of jsdom had their running time halved by removing mutation events, which add serious overhead to every DOM mutation. As such, we are doing a major release with them removed, so that jsdom users can benefit from this massive performance gain.
Mutation observer support is in progress; please use the GitHub reactions feature to vote on that issue if you are impacted by this removal and are hoping for mutation observer support to replace it.
Your normal change log follows:
DOMTokenList.prototype.replace method. (@nicolashenry)DOMTokenList.prototype.contains to no longer validate its arguments, as per the latest spec. (@nicolashenry)responseURL property.ByteString algorithm.statusText to be "" instead of "OK".Blob constructor's type validation. (@nicolashenry)Added encoding handling (@nicolashenry)
jsdom.env, when given a URL or file, will decode the resulting bytes using signals like the Content-Type header, <meta charset> declaration, or presence of a BOM, in the same manner as web browsers.<script>/<link>/<iframe> tags, will also account for such signals.jsdom.jsdom(), which takes a string, still sets a "UTF-8" encoding by default, since there are no bytes or headers for it to sniff an encoding from.iframe.sandbox property, since it was not implemented and simply crashed when used.element.sourceIndex property, since it was nonstandard (Internet Explorer only).doc.body's onload="" attribute, for documents that do not have a browsing context.Fixed an issue where setting selected on an multi-select would clear all other selectedness.
selected on an multi-select would clear all other selectedness.Your coding agent can read these notes before it upgrades. Set up the MCP server →