Socket
Socket
Sign inDemoInstall

jsdom

Package Overview
Dependencies
91
Maintainers
3
Versions
259
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 11.7.0 to 11.8.0

lib/jsdom/living/constraint-validation/DefaultConstraintValidation-impl.js

26

lib/jsdom/living/generated/DocumentFragment.js

@@ -9,2 +9,3 @@ "use strict";

const Node = require("./Node.js");
const NonElementParentNode = require("./NonElementParentNode.js");
const ParentNode = require("./ParentNode.js");

@@ -33,2 +34,25 @@

DocumentFragment.prototype.getElementById = function getElementById(elementId) {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
if (arguments.length < 1) {
throw new TypeError(
"Failed to execute 'getElementById' on 'DocumentFragment': 1 argument required, but only " +
arguments.length +
" present."
);
}
const args = [];
{
let curArg = arguments[0];
curArg = conversions["DOMString"](curArg, {
context: "Failed to execute 'getElementById' on 'DocumentFragment': parameter 1"
});
args.push(curArg);
}
return utils.tryWrapperForImpl(this[impl].getElementById(...args));
};
DocumentFragment.prototype.prepend = function prepend() {

@@ -258,4 +282,6 @@ if (!this || !module.exports.is(this)) {

NonElementParentNode._mixedIntoPredicates.push(module.exports.is);
ParentNode._mixedIntoPredicates.push(module.exports.is);
const Impl = require("../nodes/DocumentFragment-impl.js");

@@ -23,2 +23,41 @@ "use strict";

HTMLButtonElement.prototype.checkValidity = function checkValidity() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl].checkValidity();
};
HTMLButtonElement.prototype.reportValidity = function reportValidity() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl].reportValidity();
};
HTMLButtonElement.prototype.setCustomValidity = function setCustomValidity(error) {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
if (arguments.length < 1) {
throw new TypeError(
"Failed to execute 'setCustomValidity' on 'HTMLButtonElement': 1 argument required, but only " +
arguments.length +
" present."
);
}
const args = [];
{
let curArg = arguments[0];
curArg = conversions["DOMString"](curArg, {
context: "Failed to execute 'setCustomValidity' on 'HTMLButtonElement': parameter 1"
});
args.push(curArg);
}
return this[impl].setCustomValidity(...args);
};
Object.defineProperty(HTMLButtonElement.prototype, "autofocus", {

@@ -227,2 +266,41 @@ get() {

Object.defineProperty(HTMLButtonElement.prototype, "willValidate", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl]["willValidate"];
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLButtonElement.prototype, "validity", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return utils.tryWrapperForImpl(this[impl]["validity"]);
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLButtonElement.prototype, "validationMessage", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl]["validationMessage"];
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLButtonElement.prototype, Symbol.toStringTag, {

@@ -229,0 +307,0 @@ value: "HTMLButtonElement",

@@ -23,2 +23,41 @@ "use strict";

HTMLFieldSetElement.prototype.checkValidity = function checkValidity() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl].checkValidity();
};
HTMLFieldSetElement.prototype.reportValidity = function reportValidity() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl].reportValidity();
};
HTMLFieldSetElement.prototype.setCustomValidity = function setCustomValidity(error) {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
if (arguments.length < 1) {
throw new TypeError(
"Failed to execute 'setCustomValidity' on 'HTMLFieldSetElement': 1 argument required, but only " +
arguments.length +
" present."
);
}
const args = [];
{
let curArg = arguments[0];
curArg = conversions["DOMString"](curArg, {
context: "Failed to execute 'setCustomValidity' on 'HTMLFieldSetElement': parameter 1"
});
args.push(curArg);
}
return this[impl].setCustomValidity(...args);
};
Object.defineProperty(HTMLFieldSetElement.prototype, "disabled", {

@@ -92,2 +131,43 @@ get() {

Object.defineProperty(HTMLFieldSetElement.prototype, "willValidate", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl]["willValidate"];
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLFieldSetElement.prototype, "validity", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return utils.getSameObject(this, "validity", () => {
return utils.tryWrapperForImpl(this[impl]["validity"]);
});
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLFieldSetElement.prototype, "validationMessage", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl]["validationMessage"];
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLFieldSetElement.prototype, Symbol.toStringTag, {

@@ -94,0 +174,0 @@ value: "HTMLFieldSetElement",

@@ -39,2 +39,18 @@ "use strict";

HTMLFormElement.prototype.checkValidity = function checkValidity() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl].checkValidity();
};
HTMLFormElement.prototype.reportValidity = function reportValidity() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl].reportValidity();
};
Object.defineProperty(HTMLFormElement.prototype, "acceptCharset", {

@@ -41,0 +57,0 @@ get() {

@@ -25,2 +25,41 @@ "use strict";

HTMLInputElement.prototype.checkValidity = function checkValidity() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl].checkValidity();
};
HTMLInputElement.prototype.reportValidity = function reportValidity() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl].reportValidity();
};
HTMLInputElement.prototype.setCustomValidity = function setCustomValidity(error) {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
if (arguments.length < 1) {
throw new TypeError(
"Failed to execute 'setCustomValidity' on 'HTMLInputElement': 1 argument required, but only " +
arguments.length +
" present."
);
}
const args = [];
{
let curArg = arguments[0];
curArg = conversions["DOMString"](curArg, {
context: "Failed to execute 'setCustomValidity' on 'HTMLInputElement': parameter 1"
});
args.push(curArg);
}
return this[impl].setCustomValidity(...args);
};
HTMLInputElement.prototype.select = function select() {

@@ -944,2 +983,41 @@ if (!this || !module.exports.is(this)) {

Object.defineProperty(HTMLInputElement.prototype, "willValidate", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl]["willValidate"];
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLInputElement.prototype, "validity", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return utils.tryWrapperForImpl(this[impl]["validity"]);
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLInputElement.prototype, "validationMessage", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl]["validationMessage"];
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLInputElement.prototype, "selectionStart", {

@@ -946,0 +1024,0 @@ get() {

@@ -23,2 +23,41 @@ "use strict";

HTMLObjectElement.prototype.checkValidity = function checkValidity() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl].checkValidity();
};
HTMLObjectElement.prototype.reportValidity = function reportValidity() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl].reportValidity();
};
HTMLObjectElement.prototype.setCustomValidity = function setCustomValidity(error) {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
if (arguments.length < 1) {
throw new TypeError(
"Failed to execute 'setCustomValidity' on 'HTMLObjectElement': 1 argument required, but only " +
arguments.length +
" present."
);
}
const args = [];
{
let curArg = arguments[0];
curArg = conversions["DOMString"](curArg, {
context: "Failed to execute 'setCustomValidity' on 'HTMLObjectElement': parameter 1"
});
args.push(curArg);
}
return this[impl].setCustomValidity(...args);
};
Object.defineProperty(HTMLObjectElement.prototype, "data", {

@@ -205,2 +244,41 @@ get() {

Object.defineProperty(HTMLObjectElement.prototype, "willValidate", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl]["willValidate"];
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLObjectElement.prototype, "validity", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return utils.tryWrapperForImpl(this[impl]["validity"]);
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLObjectElement.prototype, "validationMessage", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl]["validationMessage"];
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLObjectElement.prototype, "align", {

@@ -207,0 +285,0 @@ get() {

@@ -23,2 +23,41 @@ "use strict";

HTMLOutputElement.prototype.checkValidity = function checkValidity() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl].checkValidity();
};
HTMLOutputElement.prototype.reportValidity = function reportValidity() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl].reportValidity();
};
HTMLOutputElement.prototype.setCustomValidity = function setCustomValidity(error) {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
if (arguments.length < 1) {
throw new TypeError(
"Failed to execute 'setCustomValidity' on 'HTMLOutputElement': 1 argument required, but only " +
arguments.length +
" present."
);
}
const args = [];
{
let curArg = arguments[0];
curArg = conversions["DOMString"](curArg, {
context: "Failed to execute 'setCustomValidity' on 'HTMLOutputElement': parameter 1"
});
args.push(curArg);
}
return this[impl].setCustomValidity(...args);
};
Object.defineProperty(HTMLOutputElement.prototype, "name", {

@@ -50,2 +89,41 @@ get() {

Object.defineProperty(HTMLOutputElement.prototype, "willValidate", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl]["willValidate"];
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLOutputElement.prototype, "validity", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return utils.tryWrapperForImpl(this[impl]["validity"]);
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLOutputElement.prototype, "validationMessage", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl]["validationMessage"];
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLOutputElement.prototype, Symbol.toStringTag, {

@@ -52,0 +130,0 @@ value: "HTMLOutputElement",

@@ -145,2 +145,41 @@ "use strict";

HTMLSelectElement.prototype.checkValidity = function checkValidity() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl].checkValidity();
};
HTMLSelectElement.prototype.reportValidity = function reportValidity() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl].reportValidity();
};
HTMLSelectElement.prototype.setCustomValidity = function setCustomValidity(error) {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
if (arguments.length < 1) {
throw new TypeError(
"Failed to execute 'setCustomValidity' on 'HTMLSelectElement': 1 argument required, but only " +
arguments.length +
" present."
);
}
const args = [];
{
let curArg = arguments[0];
curArg = conversions["DOMString"](curArg, {
context: "Failed to execute 'setCustomValidity' on 'HTMLSelectElement': parameter 1"
});
args.push(curArg);
}
return this[impl].setCustomValidity(...args);
};
Object.defineProperty(HTMLSelectElement.prototype, "autofocus", {

@@ -445,2 +484,41 @@ get() {

Object.defineProperty(HTMLSelectElement.prototype, "willValidate", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl]["willValidate"];
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLSelectElement.prototype, "validity", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return utils.tryWrapperForImpl(this[impl]["validity"]);
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLSelectElement.prototype, "validationMessage", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl]["validationMessage"];
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLSelectElement.prototype, Symbol.toStringTag, {

@@ -447,0 +525,0 @@ value: "HTMLSelectElement",

@@ -24,2 +24,41 @@ "use strict";

HTMLTextAreaElement.prototype.checkValidity = function checkValidity() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl].checkValidity();
};
HTMLTextAreaElement.prototype.reportValidity = function reportValidity() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl].reportValidity();
};
HTMLTextAreaElement.prototype.setCustomValidity = function setCustomValidity(error) {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
if (arguments.length < 1) {
throw new TypeError(
"Failed to execute 'setCustomValidity' on 'HTMLTextAreaElement': 1 argument required, but only " +
arguments.length +
" present."
);
}
const args = [];
{
let curArg = arguments[0];
curArg = conversions["DOMString"](curArg, {
context: "Failed to execute 'setCustomValidity' on 'HTMLTextAreaElement': parameter 1"
});
args.push(curArg);
}
return this[impl].setCustomValidity(...args);
};
HTMLTextAreaElement.prototype.select = function select() {

@@ -624,2 +663,41 @@ if (!this || !module.exports.is(this)) {

Object.defineProperty(HTMLTextAreaElement.prototype, "willValidate", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl]["willValidate"];
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLTextAreaElement.prototype, "validity", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return utils.tryWrapperForImpl(this[impl]["validity"]);
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLTextAreaElement.prototype, "validationMessage", {
get() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return this[impl]["validationMessage"];
},
enumerable: true,
configurable: true
});
Object.defineProperty(HTMLTextAreaElement.prototype, "selectionStart", {

@@ -626,0 +704,0 @@ get() {

25

lib/jsdom/living/helpers/dates-and-times.js

@@ -109,3 +109,3 @@ "use strict";

const timeRe = /^([0-9]{2}):([0-9]{2})(?::([0-9]{2}(?:\.[0-9]{1,3})?))?$/;
const timeRe = /^([0-9]{2}):([0-9]{2})(?::([0-9]{2}(?:\.([0-9]{1,3}))?))?$/;

@@ -126,7 +126,8 @@ // https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#parse-a-time-string

}
const second = matches[3] !== undefined ? Number(matches[3]) : 0;
const second = matches[3] !== undefined ? Math.trunc(Number(matches[3])) : 0;
if (second < 0 || second >= 60) {
return null;
}
return { hour, minute, second };
const millisecond = matches[4] !== undefined ? Number(matches[4]) : 0;
return { hour, minute, second, millisecond };
}

@@ -138,12 +139,12 @@

}
function serializeTime({ hour, minute, second }) {
function serializeTime({ hour, minute, second, millisecond }) {
const hourStr = leftPad(`${hour}`, 2, "0");
const minuteStr = leftPad(`${minute}`, 2, "0");
const milliseconds = Math.trunc(second * 1000);
if (milliseconds === 0) {
if (millisecond === 0) {
return `${hourStr}:${minuteStr}`;
}
const secondIntegerStr = leftPad(`${Math.trunc(milliseconds / 1000)}`, 2, "0");
const secondDecimalStr = `${milliseconds % 1000 / 1000}`.slice(1);
return `${hourStr}:${minuteStr}:${secondIntegerStr}${secondDecimalStr}`;
const secondStr = leftPad(second, 2, "0");
const millisecondStr = leftPad(millisecond, 3, "0");
return `${hourStr}:${minuteStr}:${secondStr}.${millisecondStr}`;
}

@@ -154,6 +155,6 @@

let separatorIdx = str.indexOf("T");
if (!normalized && separatorIdx < -1) {
if (separatorIdx < 0 && !normalized) {
separatorIdx = str.indexOf(" ");
}
if (separatorIdx < -1) {
if (separatorIdx < 0) {
return null;

@@ -192,3 +193,3 @@ }

const weekRe = /^([0-9]{4})-W([0-9]{2})$/;
const weekRe = /^([0-9]{4,5})-W([0-9]{2})$/;

@@ -195,0 +196,0 @@ // https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#parse-a-week-string

@@ -8,3 +8,4 @@ "use strict";

stripLeadingAndTrailingASCIIWhitespace,
stripNewlines
stripNewlines,
splitOnCommas
} = require("./strings");

@@ -19,2 +20,3 @@ const {

} = require("./dates-and-times");
const whatwgURL = require("whatwg-url");

@@ -63,2 +65,20 @@ const submittableLocalNames = new Set(["button", "input", "keygen", "object", "select", "textarea"]);

// https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address
exports.isValidEmailAddress = (emailAddress, multiple = false) => {
const emailAddressRegExp = new RegExp("^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9]" +
"(?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}" +
"[a-zA-Z0-9])?)*$");
// A valid e-mail address list is a set of comma-separated tokens, where each token is itself
// a valid e - mail address.To obtain the list of tokens from a valid e - mail address list,
// an implementation must split the string on commas.
if (multiple) {
return splitOnCommas(emailAddress).every(value => emailAddressRegExp.test(value));
}
return emailAddressRegExp.test(emailAddress);
};
exports.isValidAbsoluteURL = url => {
return whatwgURL.parseURL(url) !== null;
};
exports.sanitizeValueByType = (input, val) => {

@@ -65,0 +85,0 @@ switch (input.type.toLowerCase()) {

@@ -54,2 +54,3 @@ "use strict";

exports.FileList = require("./generated/FileList").interface;
exports.ValidityState = require("./generated/ValidityState").interface;

@@ -56,0 +57,0 @@ exports.DOMParser = require("./generated/DOMParser").interface;

@@ -37,2 +37,3 @@ "use strict";

const DOMImplementation = require("../generated/DOMImplementation");
const NonElementParentNodeImpl = require("./NonElementParentNode-impl").implementation;
const ParentNodeImpl = require("./ParentNode-impl").implementation;

@@ -457,4 +458,5 @@ const Element = require("../generated/Element");

// This is implemented separately for Document (which has a _ids cache) and DocumentFragment (which does not).
getElementById(id) {
// return the first element
// Return the first element with this ID.
return this._ids[id] && this._ids[id].length > 0 ? this._ids[id][0] : null;

@@ -827,2 +829,3 @@ }

mixin(DocumentImpl.prototype, GlobalEventHandlersImpl.prototype);
mixin(DocumentImpl.prototype, NonElementParentNodeImpl.prototype);
mixin(DocumentImpl.prototype, ParentNodeImpl.prototype);

@@ -829,0 +832,0 @@

"use strict";
const { mixin } = require("../../utils");
const { domSymbolTree } = require("../helpers/internal-constants");
const NODE_TYPE = require("../node-type");
const NodeImpl = require("./Node-impl").implementation;
const NonElementParentNodeImpl = require("./NonElementParentNode-impl").implementation;
const ParentNodeImpl = require("./ParentNode-impl").implementation;
const NODE_TYPE = require("../node-type");
class DocumentFragmentImpl extends NodeImpl {

@@ -14,4 +15,20 @@ constructor(args, privateData) {

}
// This is implemented separately for Document (which has a _ids cache) and DocumentFragment (which does not).
getElementById(id) {
if (id === "") {
return null;
}
for (const descendant of domSymbolTree.treeIterator(this)) {
if (descendant.nodeType === NODE_TYPE.ELEMENT_NODE && descendant.getAttributeNS(null, "id") === id) {
return descendant;
}
}
return null;
}
}
mixin(DocumentFragmentImpl.prototype, NonElementParentNodeImpl.prototype);
mixin(DocumentFragmentImpl.prototype, ParentNodeImpl.prototype);

@@ -18,0 +35,0 @@

@@ -5,4 +5,13 @@ "use strict";

const { isDisabled } = require("../helpers/form-controls");
const DefaultConstraintValidationImpl =
require("../constraint-validation/DefaultConstraintValidation-impl").implementation;
const { mixin } = require("../../utils");
class HTMLButtonElementImpl extends HTMLElementImpl {
constructor(args, privateData) {
super(args, privateData);
this._customValidityErrorMessage = "";
}
_activationBehavior() {

@@ -51,6 +60,12 @@ const { form } = this;

}
_barredFromConstraintValidationSpecialization() {
return this.type === "reset" || this.type === "button";
}
}
mixin(HTMLButtonElementImpl.prototype, DefaultConstraintValidationImpl.prototype);
module.exports = {
implementation: HTMLButtonElementImpl
};
"use strict";
const HTMLElementImpl = require("./HTMLElement-impl").implementation;
const DefaultConstraintValidationImpl =
require("../constraint-validation/DefaultConstraintValidation-impl").implementation;
const { mixin } = require("../../utils");
const { closest } = require("../helpers/traversal");

@@ -9,6 +12,12 @@

}
_barredFromConstraintValidationSpecialization() {
return true;
}
}
mixin(HTMLFieldSetElementImpl.prototype, DefaultConstraintValidationImpl.prototype);
module.exports = {
implementation: HTMLFieldSetElementImpl
};

@@ -9,2 +9,3 @@ "use strict";

const { reflectURLAttribute } = require("../../utils");
const Event = require("../generated/Event");

@@ -14,2 +15,5 @@ // http://www.whatwg.org/specs/web-apps/current-work/#category-listed

// https://html.spec.whatwg.org/multipage/forms.html#category-submit
const submittableElements = new Set(["button", "input", "object", "select", "textarea"]);
const encTypes = new Set([

@@ -27,2 +31,5 @@ "application/x-www-form-urlencoded",

const constraintValidationPositiveResult = Symbol("positive");
const constraintValidationNegativeResult = Symbol("negative");
class HTMLFormElementImpl extends HTMLElementImpl {

@@ -128,2 +135,46 @@ _descendantAdded(parent, child) {

}
// If the checkValidity() method is invoked, the user agent must statically validate the
// constraints of the form element, and return true if the constraint validation returned
// a positive result, and false if it returned a negative result.
checkValidity() {
return this._staticallyValidateConstraints().result === constraintValidationPositiveResult;
}
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#interactively-validate-the-constraints
reportValidity() {
return this.checkValidity();
}
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#statically-validate-the-constraints
_staticallyValidateConstraints() {
const controls = [];
for (const el of domSymbolTree.treeIterator(this)) {
if (el.form === this && submittableElements.has(el.nodeName.toLowerCase())) {
controls.push(el);
}
}
const invalidControls = [];
for (const control of controls) {
if (control._isCandidateForConstraintValidation() && !control._satisfiesConstraints()) {
invalidControls.push(control);
}
}
if (invalidControls.length === 0) {
return { result: constraintValidationPositiveResult };
}
const unhandledInvalidControls = [];
for (const invalidControl of invalidControls) {
const notCancelled = invalidControl.dispatchEvent(Event.createImpl(["invalid", { cancelable: true }]));
if (notCancelled) {
unhandledInvalidControls.push(invalidControl);
}
}
return { result: constraintValidationNegativeResult, unhandledInvalidControls };
}
}

@@ -130,0 +181,0 @@

"use strict";
const conversions = require("webidl-conversions");
const DOMException = require("domexception");
const Event = require("../generated/Event");
const FileList = require("../generated/FileList");
const HTMLElementImpl = require("./HTMLElement-impl").implementation;
const idlUtils = require("../generated/utils");
const Event = require("../generated/Event");
const FileList = require("../generated/FileList");
const DefaultConstraintValidationImpl =
require("../constraint-validation/DefaultConstraintValidation-impl").implementation;
const ValidityState = require("../generated/ValidityState");
const { mixin } = require("../../utils");
const { domSymbolTree, cloningSteps } = require("../helpers/internal-constants");
const { closest } = require("../helpers/traversal");
const { isDisabled, sanitizeValueByType } = require("../helpers/form-controls");
const { parseFloatingPointNumber } = require("../helpers/strings");
const {
isDisabled,
isValidEmailAddress,
isValidAbsoluteURL,
sanitizeValueByType
} = require("../helpers/form-controls");
const {
parseFloatingPointNumber,
asciiCaseInsensitiveMatch,
splitOnCommas
} = require("../helpers/strings");
const {
parseDateString,

@@ -29,2 +42,12 @@ parseLocalDateAndTimeString,

const maxMinStepTypes = new Set(["date", "month", "week", "time", "datetime-local", "number", "range", "datetime"]);
// https://html.spec.whatwg.org/multipage/input.html#concept-input-apply
const applicableTypesForAttribute = {
max: maxMinStepTypes,
min: maxMinStepTypes,
step: maxMinStepTypes,
pattern: new Set(["text", "search", "tel", "url", "email", "password"])
};
function allowSelect(type) {

@@ -54,6 +77,5 @@ return selectAllowedTypes.has(type.toLowerCase());

// Necessary because Date.UTC() treats year within [0, 99] as [1900, 1999].
function getUTCMs(year, month = 1, day = 1, hour = 0, minute = 0, second = 0) {
const millisecond = second - Math.trunc(second);
function getUTCMs(year, month = 1, day = 1, hour = 0, minute = 0, second = 0, millisecond = 0) {
if (year > 99 || year < 0) {
return Date.UTC(year, month - 1, day, hour, minute, Math.trunc(second), millisecond);
return Date.UTC(year, month - 1, day, hour, minute, second, millisecond);
}

@@ -66,3 +88,3 @@ const d = new Date(0);

d.setUTCMinutes(minute);
d.setUTCSeconds(Math.trunc(second), millisecond);
d.setUTCSeconds(second, millisecond);
return d.valueOf();

@@ -81,3 +103,3 @@ }

}
return getUTCMs(date.year, date.month - 1, date.day);
return getUTCMs(date.year, date.month, date.day);
}

@@ -115,3 +137,3 @@ ],

}
return ((time.hours * 60 + time.minutes) * 60 + time.seconds) * 1000;
return ((time.hour * 60 + time.minute) * 60 + time.second) * 1000 + time.millisecond;
}

@@ -126,5 +148,5 @@ ],

}
const { date: { year, month, day }, time: { hour, minute, second } } = dateAndTime;
const { date: { year, month, day }, time: { hour, minute, second, millisecond } } = dateAndTime;
// Doesn't quite matter whether or not UTC is used, since the offset from 1970-01-01 local time is returned.
return getUTCMs(year, month, day, hour, minute, second);
return getUTCMs(year, month, day, hour, minute, second, millisecond);
}

@@ -155,2 +177,4 @@ ],

this.indeterminate = false;
this._customValidityErrorMessage = "";
}

@@ -193,3 +217,3 @@

if (this.type === "checkbox" || (this.type === "radio" && !this._preCheckedRadioState)) {
const inputEvent = Event.createImpl(["input", { bubbles: true, cancelable: true }], {});
const inputEvent = Event.createImpl(["input", { isTrusted: true, bubbles: true, cancelable: true }], {});
this.dispatchEvent(inputEvent);

@@ -242,9 +266,12 @@

}
_removeOtherRadioCheckedness() {
get _otherRadioGroupElements() {
const wrapper = idlUtils.wrapperForImpl(this);
const root = this._radioButtonGroupRoot;
if (!root) {
return;
return [];
}
const result = [];
const name = wrapper.name.toLowerCase();

@@ -264,6 +291,14 @@

if (candidate !== this) {
candidate._checkedness = false;
result.push(candidate);
}
}
return result;
}
_removeOtherRadioCheckedness() {
for (const radioGroupElement of this._otherRadioGroupElements) {
radioGroupElement._checkedness = false;
}
}
get _radioButtonGroupRoot() {

@@ -286,8 +321,18 @@ const wrapper = idlUtils.wrapperForImpl(this);

}
_isRadioGroupChecked() {
if (this.checked) {
return true;
}
return this._otherRadioGroupElements.some(radioGroupElement => radioGroupElement.checked);
}
get form() {
return closest(this, "form");
}
get checked() {
return this._checkedness;
}
set checked(checked) {

@@ -300,2 +345,3 @@ this._checkedness = Boolean(checked);

}
get value() {

@@ -605,2 +651,201 @@ switch (valueAttributeMode(this.type)) {

get _parsedValue() {
const converter = this._convertStringToNumber;
if (converter !== undefined) {
return converter(this.value);
}
return this.value;
}
// https://html.spec.whatwg.org/multipage/input.html#attr-input-step
get _step() {
let step = this._defaultStep;
if (this.hasAttribute("step") && !asciiCaseInsensitiveMatch(this.getAttribute("step"), "any")) {
const parsedStep = parseFloatingPointNumber(this.getAttribute("step"));
if (!isNaN(parsedStep) && parsedStep > 0) {
step = parsedStep;
}
}
return step;
}
// https://html.spec.whatwg.org/multipage/input.html#concept-input-step-scale
get _stepScaleFactor() {
const dayInMilliseconds = 24 * 60 * 60 * 1000;
switch (this.type) {
case "week":
return 7 * dayInMilliseconds;
case "date":
return dayInMilliseconds;
case "datetime-local":
case "datetime":
case "time":
return 1000;
}
return 1;
}
// https://html.spec.whatwg.org/multipage/input.html#concept-input-step-default
get _defaultStep() {
if (this.type === "datetime-local" || this.type === "datetime" || this.type === "time") {
return 60;
}
return 1;
}
// https://html.spec.whatwg.org/multipage/input.html#concept-input-min-zero
get _stepBase() {
const parseAttribute = attributeName => parseFloatingPointNumber(this.getAttribute(attributeName));
if (this.hasAttribute("min")) {
const min = parseAttribute("min");
if (!isNaN(min)) {
return min;
}
}
if (this.hasAttribute("value")) {
const value = parseAttribute("value");
if (!isNaN(value)) {
return value;
}
}
return this._defaultStepBase;
}
// https://html.spec.whatwg.org/multipage/input.html#concept-input-step-default-base
get _defaultStepBase() {
if (this.type === "week") {
// The start of week 1970-W01
return 259200000;
}
return 0;
}
_attributeApplies(attribute) {
return applicableTypesForAttribute[attribute].has(this.type);
}
_barredFromConstraintValidationSpecialization() {
// https://html.spec.whatwg.org/multipage/input.html#hidden-state-(type=hidden)
// https://html.spec.whatwg.org/multipage/input.html#reset-button-state-(type=reset)
// https://html.spec.whatwg.org/multipage/input.html#button-state-(type=button)
const willNotValidateTypes = new Set(["hidden", "reset", "button"]);
// https://html.spec.whatwg.org/multipage/input.html#attr-input-readonly
const readOnly = this.hasAttribute("readonly");
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-disabled
return willNotValidateTypes.has(this.type) || readOnly;
}
get validity() {
if (!this._validity) {
this._validity = ValidityState.createImpl(this, {
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#suffering-from-being-missing
valueMissing: () => {
if (!this.hasAttribute("required")) {
return false;
}
if (this.type === "checkbox") {
// https://html.spec.whatwg.org/multipage/input.html#checkbox-state-(type=checkbox)
// Constraint validation: If the element is required and its checkedness is
// false, then the element is suffering from being missing.
return !this.checked;
} else if (this.type === "radio") {
// https://html.spec.whatwg.org/multipage/input.html#radio-button-state-(type=radio)
// Constraint validation: If an element in the radio button group is required,
// 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.
return !this._isRadioGroupChecked();
}
return this.value === "";
},
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#suffering-from-being-too-long
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-maxlength
// jsdom has no way at the moment to emulate a user interaction, so tooLong/tooShort have
// to be set to false.
tooLong: () => false,
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#suffering-from-being-too-short
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-minlength
tooShort: () => false,
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#suffering-from-an-overflow
// https://html.spec.whatwg.org/multipage/input.html#attr-input-max
rangeOverflow: () => this._attributeApplies("max") && this._maximum !== null &&
this._parsedValue > this._maximum,
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#suffering-from-an-underflow
// https://html.spec.whatwg.org/multipage/input.html#attr-input-min
rangeUnderflow: () => this._attributeApplies("min") && this._minimum !== null &&
this._parsedValue < this._minimum,
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#suffering-from-a-pattern-mismatch
patternMismatch: () => {
if (!this.hasAttribute("pattern") || !this._attributeApplies("pattern") || this.value === "") {
return false;
}
let regExp;
try {
regExp = new RegExp(this.getAttribute("pattern"), "u");
} catch (e) {
return false;
}
if (this.type === "email" && this.hasAttribute("multiple")) {
return splitOnCommas(this.value).every(value => regExp.test(value));
}
return !regExp.test(this.value);
},
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#suffering-from-a-step-mismatch
// https://html.spec.whatwg.org/multipage/input.html#attr-input-step
stepMismatch: () => {
// Constraint validation: When the element has an allowed value step, and the result of applying
// the algorithm to convert a string to a number to the string given by the element's value is a
// number, and that number subtracted from the step base is not an integral multiple of the
// allowed value step, the element is suffering from a step mismatch.
if (!this._attributeApplies("step")) {
return false;
}
const step = parseFloatingPointNumber(this.getAttribute("step"));
if (isNaN(step) || step <= 0) {
return false;
}
let number = this._parsedValue;
if (isNaN(number) || this.value === "") {
return false;
}
if (this._type === "month") {
number = parseMonthString(this.value).month - 1;
}
return number % (this._stepBase - (this._step * this._stepScaleFactor)) !== 0;
},
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#suffering-from-a-type-mismatch
typeMismatch: () => {
if (this.value === "") {
return false;
}
if (this.type === "email") {
// https://html.spec.whatwg.org/multipage/input.html#e-mail-state-(type=email)
// Constraint validation [multiple=false]: While the value of the element is neither the empty
// string nor a single valid e - mail address, the element is suffering from a type mismatch.
// Constraint validation [multiple=true]: While the value of the element is not a valid e-mail address list,
// the element is suffering from a type mismatch.
return !isValidEmailAddress(this.value, this.hasAttribute("multiple"));
} else if (this.type === "url") {
// https://html.spec.whatwg.org/multipage/input.html#url-state-(type=url)
// Constraint validation: While the value of the element is neither the empty string
// nor a valid absolute URL, the element is suffering from a type mismatch.
return !isValidAbsoluteURL(this.value);
}
return false;
}
});
}
return this._validity;
}
[cloningSteps](copy, node) {

@@ -614,4 +859,6 @@ copy._value = node._value;

mixin(HTMLInputElementImpl.prototype, DefaultConstraintValidationImpl.prototype);
module.exports = {
implementation: HTMLInputElementImpl
};
"use strict";
const HTMLElementImpl = require("./HTMLElement-impl").implementation;
const DefaultConstraintValidationImpl =
require("../constraint-validation/DefaultConstraintValidation-impl").implementation;
const { mixin } = require("../../utils");
const { reflectURLAttribute } = require("../../utils");

@@ -30,6 +33,12 @@ const { closest } = require("../helpers/traversal");

}
_barredFromConstraintValidationSpecialization() {
return true;
}
}
mixin(HTMLObjectElementImpl.prototype, DefaultConstraintValidationImpl.prototype);
module.exports = {
implementation: HTMLObjectElementImpl
};
"use strict";
const HTMLElementImpl = require("./HTMLElement-impl").implementation;
const DefaultConstraintValidationImpl =
require("../constraint-validation/DefaultConstraintValidation-impl").implementation;
const { mixin } = require("../../utils");
class HTMLOutputElementImpl extends HTMLElementImpl { }
class HTMLOutputElementImpl extends HTMLElementImpl {
_barredFromConstraintValidationSpecialization() {
return true;
}
}
mixin(HTMLOutputElementImpl.prototype, DefaultConstraintValidationImpl.prototype);
module.exports = {
implementation: HTMLOutputElementImpl
};

@@ -6,2 +6,6 @@ "use strict";

const idlUtils = require("../generated/utils.js");
const ValidityState = require("../generated/ValidityState");
const DefaultConstraintValidationImpl =
require("../constraint-validation/DefaultConstraintValidation-impl").implementation;
const { mixin } = require("../../utils");
const HTMLElementImpl = require("./HTMLElement-impl").implementation;

@@ -37,2 +41,4 @@ const NODE_TYPE = require("../node-type");

this._selectedOptions = null; // lazy
this._customValidityErrorMessage = "";
}

@@ -217,6 +223,44 @@

}
_barredFromConstraintValidationSpecialization() {
return this.hasAttribute("readonly");
}
// Constraint validation: If the element has its required attribute specified,
// and either none of the option elements in the select element's list of options
// have their selectedness set to true, or the only option element in the select
// element's list of options with its selectedness set to true is the placeholder
// label option, then the element is suffering from being missing.
get validity() {
if (!this._validity) {
this._validity = ValidityState.createImpl(this, {
valueMissing: () => {
if (!this.hasAttribute("required")) {
return false;
}
const selectedOptionIndex = this.selectedIndex;
return selectedOptionIndex < 0 || (selectedOptionIndex === 0 && this._hasPlaceholderOption);
}
});
}
return this._validity;
}
// If a select element has a required attribute specified, does not have a multiple attribute
// specified, and has a display size of 1; and if the value of the first option element in the
// select element's list of options (if any) is the empty string, and that option element's parent
// node is the select element(and not an optgroup element), then that option is the select
// element's placeholder label option.
// https://html.spec.whatwg.org/multipage/form-elements.html#placeholder-label-option
get _hasPlaceholderOption() {
return this.hasAttribute("required") && !this.hasAttribute("multiple") &&
this._displaySize === 1 && this.options.length > 0 && this.options.item(0).value === "" &&
this.options.item(0).parentNode._localName !== "optgroup";
}
}
mixin(HTMLSelectElementImpl.prototype, DefaultConstraintValidationImpl.prototype);
module.exports = {
implementation: HTMLSelectElementImpl
};

@@ -5,2 +5,7 @@ "use strict";

const DefaultConstraintValidationImpl =
require("../constraint-validation/DefaultConstraintValidation-impl").implementation;
const ValidityState = require("../generated/ValidityState");
const { mixin } = require("../../utils");
const DOMException = require("domexception");

@@ -17,2 +22,4 @@ const { closest } = require("../helpers/traversal");

this._dirtyValue = false;
this._customValidityErrorMessage = "";
}

@@ -181,6 +188,22 @@

}
_barredFromConstraintValidationSpecialization() {
return this.hasAttribute("readonly");
}
// https://html.spec.whatwg.org/multipage/form-elements.html#attr-textarea-required
get validity() {
if (!this._validity) {
this._validity = ValidityState.createImpl(this, {
valueMissing: () => this.hasAttribute("required") && this.value === ""
});
}
return this._validity;
}
}
mixin(HTMLTextAreaElementImpl.prototype, DefaultConstraintValidationImpl.prototype);
module.exports = {
implementation: HTMLTextAreaElementImpl
};
"use strict";
// https://dom.spec.whatwg.org/#interface-nonelementparentnode
// getElementById is implemented separately inside Document and DocumentFragment.
class NonElementParentNodeImpl {

@@ -4,0 +6,0 @@

{
"name": "jsdom",
"version": "11.7.0",
"version": "11.8.0",
"description": "A JavaScript implementation of many web standards",

@@ -5,0 +5,0 @@ "keywords": [

@@ -359,3 +359,3 @@ # jsdom

All invocations of the `framgment()` factory result in `DocumentFragment`s that share the same owner `Document` and `Window`. This allows many calls to `fragment()` with no extra overhead. But it also means that calls to `fragment()` cannot be customized with any options.
All invocations of the `fragment()` factory result in `DocumentFragment`s that share the same owner `Document` and `Window`. This allows many calls to `fragment()` with no extra overhead. But it also means that calls to `fragment()` cannot be customized with any options.

@@ -362,0 +362,0 @@ Note that serialization is not as easy with `DocumentFragment`s as it is with full `JSDOM` objects. If you need to serialize your DOM, you should probably use the `JSDOM` constructor more directly. But for the special case of a fragment containing a single element, it's pretty easy to do through normal means:

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc