jsdom
Advanced tools
Comparing version 16.3.0 to 16.4.0
@@ -29,4 +29,4 @@ "use strict"; | ||
const SessionHistory = require("../living/window/SessionHistory"); | ||
const { forEachMatchingSheetRuleOfElement, getResolvedValue, propertiesWithResolvedValueImplemented } = | ||
require("../living/helpers/style-rules"); | ||
const { forEachMatchingSheetRuleOfElement, getResolvedValue, propertiesWithResolvedValueImplemented, | ||
SHADOW_DOM_PSEUDO_REGEXP } = require("../living/helpers/style-rules.js"); | ||
const CustomElementRegistry = require("../living/generated/CustomElementRegistry"); | ||
@@ -646,3 +646,17 @@ const jsGlobals = require("./js-globals.json"); | ||
elt = Element.convert(elt); | ||
let pseudoElt = arguments[1]; | ||
if (pseudoElt !== undefined && pseudoElt !== null) { | ||
pseudoElt = webIDLConversions.DOMString(pseudoElt); | ||
} | ||
if (pseudoElt !== undefined && pseudoElt !== null && pseudoElt !== "") { | ||
// TODO: Parse pseudoElt | ||
if (SHADOW_DOM_PSEUDO_REGEXP.test(pseudoElt)) { | ||
throw new TypeError("Tried to get the computed style of a Shadow DOM pseudo-element."); | ||
} | ||
notImplemented("window.computedStyle(elt, pseudoElt)", this); | ||
} | ||
const declaration = new CSSStyleDeclaration(); | ||
@@ -649,0 +663,0 @@ const { forEach } = Array.prototype; |
"use strict"; | ||
const nodeType = require("../node-type.js"); | ||
const FocusEvent = require("../generated/FocusEvent.js"); | ||
@@ -8,3 +7,4 @@ const idlUtils = require("../generated/utils.js"); | ||
const { createAnEvent } = require("./events"); | ||
const { HTML_NS } = require("./namespaces"); | ||
const { HTML_NS, SVG_NS } = require("./namespaces"); | ||
const { isRenderedElement } = require("./svg/render"); | ||
@@ -14,17 +14,5 @@ const focusableFormElements = new Set(["input", "select", "textarea", "button"]); | ||
// https://html.spec.whatwg.org/multipage/interaction.html#focusable-area, but also some of | ||
// https://html.spec.whatwg.org/multipage/interaction.html#focusing-steps: e.g., Documents are not actually focusable | ||
// areas, but their viewports are, and the first step of the latter algorithm translates Documents to their viewports. | ||
// https://html.spec.whatwg.org/multipage/interaction.html#focusing-steps and some of | ||
// https://svgwg.org/svg2-draft/interact.html#TermFocusable | ||
exports.isFocusableAreaElement = elImpl => { | ||
if (!elImpl._ownerDocument._defaultView && !elImpl._defaultView) { | ||
return false; | ||
} | ||
if (elImpl._nodeType === nodeType.DOCUMENT_NODE) { | ||
return true; | ||
} | ||
if (!Number.isNaN(parseInt(elImpl.getAttributeNS(null, "tabindex")))) { | ||
return true; | ||
} | ||
// We implemented most of the suggested focusable elements found here: | ||
@@ -35,2 +23,14 @@ // https://html.spec.whatwg.org/multipage/interaction.html#tabindex-value | ||
if (elImpl._namespaceURI === HTML_NS) { | ||
if (!elImpl._ownerDocument._defaultView) { | ||
return false; | ||
} | ||
if (!elImpl.isConnected) { | ||
return false; | ||
} | ||
if (!Number.isNaN(parseInt(elImpl.getAttributeNS(null, "tabindex")))) { | ||
return true; | ||
} | ||
if (elImpl._localName === "iframe") { | ||
@@ -61,2 +61,5 @@ return true; | ||
} | ||
return false; | ||
// This does not check for a designMode Document as specified in | ||
@@ -67,2 +70,14 @@ // https://html.spec.whatwg.org/multipage/interaction.html#editing-host because the designMode | ||
if (elImpl._namespaceURI === SVG_NS) { | ||
if (!Number.isNaN(parseInt(elImpl.getAttributeNS(null, "tabindex"))) && isRenderedElement(elImpl)) { | ||
return true; | ||
} | ||
if (elImpl._localName === "a" && elImpl.hasAttributeNS(null, "href")) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
return false; | ||
@@ -69,0 +84,0 @@ }; |
@@ -109,1 +109,3 @@ "use strict"; | ||
}; | ||
exports.SHADOW_DOM_PSEUDO_REGEXP = /^::(?:part|slotted)\(/i; |
@@ -617,2 +617,6 @@ "use strict"; | ||
_runPreRemovingSteps(oldNode) { | ||
// https://html.spec.whatwg.org/#focus-fixup-rule | ||
if (oldNode === this.activeElement) { | ||
this._lastFocusedElement = this.body; | ||
} | ||
for (const activeNodeIterator of this._workingNodeIterators) { | ||
@@ -619,0 +623,0 @@ activeNodeIterator._preRemovingSteps(oldNode); |
@@ -81,2 +81,4 @@ "use strict"; | ||
}); | ||
this._cachedTagName = null; | ||
} | ||
@@ -137,7 +139,13 @@ | ||
get tagName() { | ||
let qualifiedName = this._qualifiedName; | ||
if (this.namespaceURI === HTML_NS && this._ownerDocument._parsingMode === "html") { | ||
qualifiedName = asciiUppercase(qualifiedName); | ||
// This getter can be a hotpath in getComputedStyle. | ||
// All these are invariants during the instance lifetime so we can safely cache the computed tagName. | ||
// We could create it during construction but since we already identified this as potentially slow we do it lazily. | ||
if (this._cachedTagName === null) { | ||
if (this.namespaceURI === HTML_NS && this._ownerDocument._parsingMode === "html") { | ||
this._cachedTagName = asciiUppercase(this._qualifiedName); | ||
} else { | ||
this._cachedTagName = this._qualifiedName; | ||
} | ||
} | ||
return qualifiedName; | ||
return this._cachedTagName; | ||
} | ||
@@ -144,0 +152,0 @@ |
"use strict"; | ||
const HTMLElementImpl = require("./HTMLElement-impl").implementation; | ||
const { isDisabled, formOwner } = require("../helpers/form-controls"); | ||
const DefaultConstraintValidationImpl = | ||
require("../constraint-validation/DefaultConstraintValidation-impl").implementation; | ||
const { mixin } = require("../../utils"); | ||
const { getLabelsForLabelable } = require("../helpers/form-controls"); | ||
const { isDisabled, formOwner, getLabelsForLabelable } = require("../helpers/form-controls"); | ||
const { asciiLowercase } = require("../helpers/strings"); | ||
@@ -45,3 +45,3 @@ class HTMLButtonElementImpl extends HTMLElementImpl { | ||
get type() { | ||
const typeAttr = (this.getAttributeNS(null, "type") || "").toLowerCase(); | ||
const typeAttr = asciiLowercase(this.getAttributeNS(null, "type") || ""); | ||
switch (typeAttr) { | ||
@@ -58,3 +58,3 @@ case "submit": | ||
set type(v) { | ||
v = String(v).toLowerCase(); | ||
v = asciiLowercase(String(v)); | ||
switch (v) { | ||
@@ -61,0 +61,0 @@ case "submit": |
@@ -11,2 +11,3 @@ "use strict"; | ||
const { fireAnEvent } = require("../helpers/events"); | ||
const { asciiLowercase } = require("../helpers/strings"); | ||
@@ -41,6 +42,7 @@ class HTMLElementImpl extends ElementImpl { | ||
const translateAttr = this.getAttributeNS(null, "translate"); | ||
const translateAttrString = asciiLowercase(translateAttr || ""); | ||
if (translateAttr === "yes" || translateAttr === "") { | ||
if (translateAttrString === "yes" || (translateAttr && translateAttrString === "")) { | ||
return true; | ||
} else if (translateAttr === "no") { | ||
} else if (translateAttrString === "no") { | ||
return false; | ||
@@ -91,3 +93,3 @@ } | ||
get draggable() { | ||
const attributeValue = this.getAttributeNS(null, "draggable"); | ||
const attributeValue = asciiLowercase(this.getAttributeNS(null, "draggable") || ""); | ||
@@ -94,0 +96,0 @@ if (attributeValue === "true") { |
@@ -8,3 +8,3 @@ "use strict"; | ||
const { fireAnEvent } = require("../helpers/events"); | ||
const { isListed, isSubmittable, isSubmitButton } = require("../helpers/form-controls"); | ||
const { formOwner, isListed, isSubmittable, isSubmitButton } = require("../helpers/form-controls"); | ||
const HTMLCollection = require("../generated/HTMLCollection"); | ||
@@ -51,2 +51,14 @@ const notImplemented = require("../../browser/not-implemented"); | ||
_getElementNodes() { | ||
return domSymbolTree.treeToArray(this.getRootNode({}), { | ||
filter: node => { | ||
if (!isListed(node) || (node._localName === "input" && node.type === "image")) { | ||
return false; | ||
} | ||
return formOwner(node) === this; | ||
} | ||
}); | ||
} | ||
// https://html.spec.whatwg.org/multipage/forms.html#dom-form-elements | ||
@@ -56,6 +68,4 @@ get elements() { | ||
return HTMLCollection.createImpl(this._globalObject, [], { | ||
element: this, | ||
query: () => domSymbolTree.treeToArray(this, { | ||
filter: node => isListed(node) && (node._localName !== "input" || node.type !== "image") | ||
}) | ||
element: this.getRootNode({}), | ||
query: () => this._getElementNodes() | ||
}); | ||
@@ -62,0 +72,0 @@ } |
@@ -9,2 +9,7 @@ "use strict"; | ||
class HTMLImageElementImpl extends HTMLElementImpl { | ||
constructor(...args) { | ||
super(...args); | ||
this._currentRequestState = "unavailable"; | ||
} | ||
_attrModified(name, value, oldVal) { | ||
@@ -54,3 +59,7 @@ // TODO: handle crossorigin | ||
get complete() { | ||
return Boolean(this._image && this._image.complete); | ||
const srcAttributeValue = this.getAttributeNS(null, "src"); | ||
return srcAttributeValue === null || | ||
srcAttributeValue === "" || | ||
this._currentRequestState === "broken" || | ||
this._currentRequestState === "completely available"; | ||
} | ||
@@ -78,2 +87,3 @@ | ||
this._currentSrc = null; | ||
this._currentRequestState = "unavailable"; | ||
const srcAttributeValue = this.getAttributeNS(null, "src"); | ||
@@ -107,2 +117,3 @@ let urlString = null; | ||
this._currentSrc = srcAttributeValue; | ||
this._currentRequestState = "completely available"; | ||
}; | ||
@@ -112,3 +123,6 @@ | ||
element: this, | ||
onLoad: onLoadImage | ||
onLoad: onLoadImage, | ||
onError: () => { | ||
this._currentRequestState = "broken"; | ||
} | ||
}); | ||
@@ -115,0 +129,0 @@ } else { |
@@ -335,7 +335,7 @@ "use strict"; | ||
_isRadioGroupChecked() { | ||
if (this.checked) { | ||
_someInRadioGroup(name) { | ||
if (this[name]) { | ||
return true; | ||
} | ||
return this._otherRadioGroupElements.some(radioGroupElement => radioGroupElement.checked); | ||
return this._otherRadioGroupElements.some(radioGroupElement => radioGroupElement[name]); | ||
} | ||
@@ -980,3 +980,3 @@ | ||
case "radio": | ||
if (this._required && !this._isRadioGroupChecked()) { | ||
if (this._someInRadioGroup("_required") && !this._someInRadioGroup("checked")) { | ||
return true; | ||
@@ -983,0 +983,0 @@ } |
{ | ||
"name": "jsdom", | ||
"version": "16.3.0", | ||
"version": "16.4.0", | ||
"description": "A JavaScript implementation of many web standards", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
Sorry, the diff of this file is too big to display
2701282
454
69377