update to state of the art
This commit is contained in:
18
node_modules/jsdom/lib/jsdom/browser/Window.js
generated
vendored
18
node_modules/jsdom/lib/jsdom/browser/Window.js
generated
vendored
@@ -26,8 +26,8 @@ const Selection = require("../living/generated/Selection");
|
||||
const reportException = require("../living/helpers/runtime-script-errors");
|
||||
const { fireAnEvent } = require("../living/helpers/events");
|
||||
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");
|
||||
const jsGlobals = require("./js-globals.json");
|
||||
|
||||
@@ -642,6 +642,20 @@ function Window(options) {
|
||||
|
||||
this.getComputedStyle = function (elt) {
|
||||
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();
|
||||
const { forEach } = Array.prototype;
|
||||
|
47
node_modules/jsdom/lib/jsdom/living/helpers/focusing.js
generated
vendored
47
node_modules/jsdom/lib/jsdom/living/helpers/focusing.js
generated
vendored
@@ -1,35 +1,35 @@
|
||||
"use strict";
|
||||
const nodeType = require("../node-type.js");
|
||||
const FocusEvent = require("../generated/FocusEvent.js");
|
||||
const idlUtils = require("../generated/utils.js");
|
||||
const { isDisabled } = require("./form-controls.js");
|
||||
const { firstChildWithLocalName } = require("./traversal");
|
||||
const { createAnEvent } = require("./events");
|
||||
const { HTML_NS } = require("./namespaces");
|
||||
const { HTML_NS, SVG_NS } = require("./namespaces");
|
||||
const { isRenderedElement } = require("./svg/render");
|
||||
|
||||
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:
|
||||
// https://html.spec.whatwg.org/multipage/interaction.html#tabindex-value
|
||||
// However, some suggested elements are not focusable in web browsers, as detailed here:
|
||||
// https://github.com/whatwg/html/issues/5490
|
||||
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") {
|
||||
return true;
|
||||
}
|
||||
@@ -55,11 +55,26 @@ exports.isFocusableAreaElement = elImpl => {
|
||||
if (elImpl.hasAttributeNS(null, "contenteditable")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
// This does not check for a designMode Document as specified in
|
||||
// https://html.spec.whatwg.org/multipage/interaction.html#editing-host because the designMode
|
||||
// attribute is not implemented.
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
2
node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js
generated
vendored
2
node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js
generated
vendored
@@ -106,3 +106,5 @@ exports.getResolvedValue = (element, property) => {
|
||||
// So we skip to "any other property: The resolved value is the computed value."
|
||||
return getComputedValue(element, property);
|
||||
};
|
||||
|
||||
exports.SHADOW_DOM_PSEUDO_REGEXP = /^::(?:part|slotted)\(/i;
|
||||
|
46
node_modules/jsdom/lib/jsdom/living/helpers/svg/render.js
generated
vendored
Normal file
46
node_modules/jsdom/lib/jsdom/living/helpers/svg/render.js
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
"use strict";
|
||||
const { SVG_NS } = require("../namespaces");
|
||||
|
||||
// https://svgwg.org/svg2-draft/render.html#TermNeverRenderedElement
|
||||
const neverRenderedElements = new Set([
|
||||
"clipPath",
|
||||
"defs",
|
||||
"desc",
|
||||
"linearGradient",
|
||||
"marker",
|
||||
"mask",
|
||||
"metadata",
|
||||
"pattern",
|
||||
"radialGradient",
|
||||
"script",
|
||||
"style",
|
||||
"title",
|
||||
"symbol"
|
||||
]);
|
||||
|
||||
// https://svgwg.org/svg2-draft/render.html#Rendered-vs-NonRendered
|
||||
exports.isRenderedElement = elImpl => {
|
||||
if (neverRenderedElements.has(elImpl._localName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// This does not check for elements excluded because of conditional processing attributes or ‘switch’ structures,
|
||||
// because conditional processing is not implemented.
|
||||
// https://svgwg.org/svg2-draft/struct.html#ConditionalProcessing
|
||||
|
||||
// This does not check for computed style of display being none, since that is not yet implemented for HTML
|
||||
// focusability either (and there are no tests yet).
|
||||
|
||||
if (!elImpl.isConnected) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The spec is unclear about how to deal with non-SVG parents, so we only perform this check for SVG-namespace
|
||||
// parents.
|
||||
if (elImpl.parentElement && elImpl.parentElement._namespaceURI === SVG_NS &&
|
||||
!exports.isRenderedElement(elImpl.parentNode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
4
node_modules/jsdom/lib/jsdom/living/nodes/Document-impl.js
generated
vendored
4
node_modules/jsdom/lib/jsdom/living/nodes/Document-impl.js
generated
vendored
@@ -614,6 +614,10 @@ class DocumentImpl extends NodeImpl {
|
||||
}
|
||||
|
||||
_runPreRemovingSteps(oldNode) {
|
||||
// https://html.spec.whatwg.org/#focus-fixup-rule
|
||||
if (oldNode === this.activeElement) {
|
||||
this._lastFocusedElement = this.body;
|
||||
}
|
||||
for (const activeNodeIterator of this._workingNodeIterators) {
|
||||
activeNodeIterator._preRemovingSteps(oldNode);
|
||||
}
|
||||
|
16
node_modules/jsdom/lib/jsdom/living/nodes/Element-impl.js
generated
vendored
16
node_modules/jsdom/lib/jsdom/living/nodes/Element-impl.js
generated
vendored
@@ -78,6 +78,8 @@ class ElementImpl extends NodeImpl {
|
||||
this._attributes = NamedNodeMap.createImpl(this._globalObject, [], {
|
||||
element: this
|
||||
});
|
||||
|
||||
this._cachedTagName = null;
|
||||
}
|
||||
|
||||
_attach() {
|
||||
@@ -133,11 +135,17 @@ class ElementImpl extends NodeImpl {
|
||||
return this._prefix !== null ? this._prefix + ":" + this._localName : this._localName;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
get attributes() {
|
||||
|
8
node_modules/jsdom/lib/jsdom/living/nodes/HTMLButtonElement-impl.js
generated
vendored
8
node_modules/jsdom/lib/jsdom/living/nodes/HTMLButtonElement-impl.js
generated
vendored
@@ -1,10 +1,10 @@
|
||||
"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");
|
||||
|
||||
class HTMLButtonElementImpl extends HTMLElementImpl {
|
||||
constructor(globalObject, args, privateData) {
|
||||
@@ -42,7 +42,7 @@ class HTMLButtonElementImpl extends HTMLElementImpl {
|
||||
}
|
||||
|
||||
get type() {
|
||||
const typeAttr = (this.getAttributeNS(null, "type") || "").toLowerCase();
|
||||
const typeAttr = asciiLowercase(this.getAttributeNS(null, "type") || "");
|
||||
switch (typeAttr) {
|
||||
case "submit":
|
||||
case "reset":
|
||||
@@ -54,7 +54,7 @@ class HTMLButtonElementImpl extends HTMLElementImpl {
|
||||
}
|
||||
|
||||
set type(v) {
|
||||
v = String(v).toLowerCase();
|
||||
v = asciiLowercase(String(v));
|
||||
switch (v) {
|
||||
case "submit":
|
||||
case "reset":
|
||||
|
8
node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js
generated
vendored
8
node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js
generated
vendored
@@ -8,6 +8,7 @@ const HTMLOrSVGElementImpl = require("./HTMLOrSVGElement-impl").implementation;
|
||||
const { firstChildWithLocalName } = require("../helpers/traversal");
|
||||
const { isDisabled } = require("../helpers/form-controls");
|
||||
const { fireAnEvent } = require("../helpers/events");
|
||||
const { asciiLowercase } = require("../helpers/strings");
|
||||
|
||||
class HTMLElementImpl extends ElementImpl {
|
||||
constructor(globalObject, args, privateData) {
|
||||
@@ -37,10 +38,11 @@ class HTMLElementImpl extends ElementImpl {
|
||||
// https://html.spec.whatwg.org/multipage/dom.html#the-translate-attribute
|
||||
get translate() {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -86,7 +88,7 @@ class HTMLElementImpl extends ElementImpl {
|
||||
}
|
||||
|
||||
get draggable() {
|
||||
const attributeValue = this.getAttributeNS(null, "draggable");
|
||||
const attributeValue = asciiLowercase(this.getAttributeNS(null, "draggable") || "");
|
||||
|
||||
if (attributeValue === "true") {
|
||||
return true;
|
||||
|
20
node_modules/jsdom/lib/jsdom/living/nodes/HTMLFormElement-impl.js
generated
vendored
20
node_modules/jsdom/lib/jsdom/living/nodes/HTMLFormElement-impl.js
generated
vendored
@@ -5,7 +5,7 @@ const { serializeURL } = require("whatwg-url");
|
||||
const HTMLElementImpl = require("./HTMLElement-impl").implementation;
|
||||
const { domSymbolTree } = require("../helpers/internal-constants");
|
||||
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");
|
||||
const notImplemented = require("../../browser/not-implemented");
|
||||
const { parseURLToResultingURLRecord } = require("../helpers/document-base-url");
|
||||
@@ -47,14 +47,24 @@ class HTMLFormElementImpl extends HTMLElementImpl {
|
||||
super._descendantRemoved.apply(this, arguments);
|
||||
}
|
||||
|
||||
_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
|
||||
get elements() {
|
||||
// TODO: Return a HTMLFormControlsCollection
|
||||
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()
|
||||
});
|
||||
}
|
||||
|
||||
|
18
node_modules/jsdom/lib/jsdom/living/nodes/HTMLImageElement-impl.js
generated
vendored
18
node_modules/jsdom/lib/jsdom/living/nodes/HTMLImageElement-impl.js
generated
vendored
@@ -6,6 +6,11 @@ const { Canvas } = require("../../utils");
|
||||
const { parseURLToResultingURLRecord } = require("../helpers/document-base-url");
|
||||
|
||||
class HTMLImageElementImpl extends HTMLElementImpl {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
this._currentRequestState = "unavailable";
|
||||
}
|
||||
|
||||
_attrModified(name, value, oldVal) {
|
||||
// TODO: handle crossorigin
|
||||
if (name === "src" || ((name === "srcset" || name === "width" || name === "sizes") && value !== oldVal)) {
|
||||
@@ -50,7 +55,11 @@ class HTMLImageElementImpl extends HTMLElementImpl {
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
get currentSrc() {
|
||||
@@ -73,6 +82,7 @@ class HTMLImageElementImpl extends HTMLElementImpl {
|
||||
this._image = new Canvas.Image();
|
||||
}
|
||||
this._currentSrc = null;
|
||||
this._currentRequestState = "unavailable";
|
||||
const srcAttributeValue = this.getAttributeNS(null, "src");
|
||||
let urlString = null;
|
||||
if (srcAttributeValue !== null && srcAttributeValue !== "") {
|
||||
@@ -101,11 +111,15 @@ class HTMLImageElementImpl extends HTMLElementImpl {
|
||||
throw new Error(error);
|
||||
}
|
||||
this._currentSrc = srcAttributeValue;
|
||||
this._currentRequestState = "completely available";
|
||||
};
|
||||
|
||||
request = resourceLoader.fetch(urlString, {
|
||||
element: this,
|
||||
onLoad: onLoadImage
|
||||
onLoad: onLoadImage,
|
||||
onError: () => {
|
||||
this._currentRequestState = "broken";
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this._image.src = "";
|
||||
|
8
node_modules/jsdom/lib/jsdom/living/nodes/HTMLInputElement-impl.js
generated
vendored
8
node_modules/jsdom/lib/jsdom/living/nodes/HTMLInputElement-impl.js
generated
vendored
@@ -332,11 +332,11 @@ class HTMLInputElementImpl extends HTMLElementImpl {
|
||||
return null;
|
||||
}
|
||||
|
||||
_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]);
|
||||
}
|
||||
|
||||
get _mutable() {
|
||||
@@ -976,7 +976,7 @@ class HTMLInputElementImpl extends HTMLElementImpl {
|
||||
// and all of the input elements in the radio button group have a checkedness
|
||||
// that is false, then the element is suffering from being missing.
|
||||
case "radio":
|
||||
if (this._required && !this._isRadioGroupChecked()) {
|
||||
if (this._someInRadioGroup("_required") && !this._someInRadioGroup("checked")) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
Reference in New Issue
Block a user