🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

jsdom

Package Overview
Dependencies
Maintainers
6
Versions
285
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jsdom - npm Package Compare versions

Comparing version
29.0.1
to
29.0.2
lib/generated/css-property-metadata.js

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

+296
-68

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

const idlUtils = require("../../../generated/idl/utils.js");
const propertyDefinitions = require("../../../generated/css-property-definitions");
const propertyDescriptors = require("../../../generated/css-property-descriptors");
const propertyMetadata = require("../../../generated/css-property-metadata");
const { asciiLowercase } = require("../helpers/strings");
const computedStyle = require("./helpers/computed-style");
const cssValues = require("./helpers/css-values");
const csstree = require("./helpers/patched-csstree");
const {

@@ -15,7 +21,3 @@ borderProperties,

} = require("./helpers/shorthand-properties");
const {
hasVarFunc, isGlobalKeyword, parsePropertyValue
} = require("./helpers/css-values");
const csstree = require("./helpers/patched-csstree");
const { asciiLowercase } = require("../helpers/strings");
const { systemColors } = require("./helpers/system-colors");

@@ -25,3 +27,3 @@ class CSSStyleDeclarationImpl {

// `_priorities` and `#values` together represent the spec's "declarations".
#computed;
_computed;
_readonly = false;

@@ -34,6 +36,9 @@ _priorities = new Map();

// Internal private fields.
#computedValueOpts = new Map();
#cachedPropertyValues = new Map();
constructor(globalObject, args, { computed, ownerNode, parentRule } = {}) {
this._globalObject = globalObject;
this.#computed = Boolean(computed);
this._computed = Boolean(computed);
this.parentRule = parentRule || null;

@@ -49,3 +54,3 @@ this.#ownerNode = ownerNode || null;

get cssText() {
if (this.#computed) {
if (this._computed) {
return "";

@@ -94,29 +99,39 @@ }

this._priorities.clear();
try {
this.#updating = true;
const valueObj = csstree.parse(text, { context: "declarationList", parseValue: false });
if (valueObj?.children) {
const properties = new Map();
let shouldSkipNext = false;
for (const item of valueObj.children) {
if (item.type === "Atrule") {
continue;
}
if (item.type === "Rule") {
shouldSkipNext = true;
continue;
}
if (shouldSkipNext === true) {
shouldSkipNext = false;
continue;
}
const {
important,
property,
value: { value }
} = item;
if (typeof property === "string" && typeof value === "string") {
const priority = important ? "important" : "";
const isCustomProperty = property.startsWith("--");
if (isCustomProperty || hasVarFunc(value)) {
this.#updating = true;
const valueObj = csstree.parse(text, { context: "declarationList", parseValue: false });
if (valueObj?.children) {
const properties = new Map();
let shouldSkipNext = false;
for (const item of valueObj.children) {
if (item.type === "Atrule") {
continue;
}
if (item.type === "Rule") {
shouldSkipNext = true;
continue;
}
if (shouldSkipNext === true) {
shouldSkipNext = false;
continue;
}
const {
important,
property,
value: { value }
} = item;
if (typeof property === "string" && typeof value === "string") {
const priority = important ? "important" : "";
const isCustomProperty = property.startsWith("--");
if (isCustomProperty || cssValues.hasVarFunc(value)) {
if (properties.has(property)) {
const { priority: itemPriority } = properties.get(property);
if (!itemPriority) {
properties.set(property, { property, value, priority });
}
} else {
properties.set(property, { property, value, priority });
}
} else {
const parsedValue = cssValues.parsePropertyValue(property, value);
if (parsedValue) {
if (properties.has(property)) {

@@ -131,30 +146,15 @@ const { priority: itemPriority } = properties.get(property);

} else {
const parsedValue = parsePropertyValue(property, value);
if (parsedValue) {
if (properties.has(property)) {
const { priority: itemPriority } = properties.get(property);
if (!itemPriority) {
properties.set(property, { property, value, priority });
}
} else {
properties.set(property, { property, value, priority });
}
} else {
this.removeProperty(property);
}
this.removeProperty(property);
}
}
}
const parsedProperties = prepareProperties(properties);
for (const [property, item] of parsedProperties) {
const { priority, value } = item;
this._priorities.set(property, priority);
this.setProperty(property, value, priority);
}
}
} catch {
return;
} finally {
this.#updating = false;
const parsedProperties = prepareProperties(properties);
for (const [property, item] of parsedProperties) {
const { priority, value } = item;
this._priorities.set(property, priority);
this.setProperty(property, value, priority);
}
}
this.#updating = false;
this.#updateStyleAttribute();

@@ -189,6 +189,21 @@ }

getPropertyValue(property) {
if (this.#values.has(property)) {
return this.#values.get(property).toString();
const value = this.#values.get(property) ?? "";
if (this._computed) {
if (this.#cachedPropertyValues.has(property)) {
const cachedValue = this.#cachedPropertyValues.get(property);
// Return the cached resolved value if the specified value haven't changed.
if (value === cachedValue.value) {
return cachedValue.resolvedValue;
}
}
const resolvedValue = this.#getComputedValue(property, value);
if (propertyDefinitions.has(property)) {
const { longhands } = propertyDefinitions.get(property);
if (!longhands) {
this.#cachedPropertyValues.set(property, { resolvedValue, value });
}
}
return resolvedValue;
}
return "";
return value;
}

@@ -289,3 +304,3 @@

#updateStyleAttribute() {
if (this.#computed || !this.#ownerNode || this.#ownerNode._settingCssText) {
if (this._computed || !this.#ownerNode || this.#ownerNode._settingCssText) {
return;

@@ -325,2 +340,215 @@ }

#getComputedValue(property, value) {
// Invalid or unsupported property.
if (!propertyDefinitions.has(property) && !property.startsWith("--")) {
return "";
}
const { inherited, initial = "", longhands } = cssValues.getPropertyDefinition(property);
const { caseSensitive, functionTypes = {} } = this.#getPropertyMetadata(property);
const isColor = Boolean(functionTypes.color || functionTypes.paint);
if (!value || cssValues.isGlobalKeyword(value)) {
value = computedStyle.replaceEmptyValueAndKeywords(
property,
value,
this.#ownerNode,
{ inherit: inherited === "yes", initial, isColor, longhands }
);
}
if (property === "color" && /currentcolor/i.test(value)) {
value = computedStyle.getInheritedPropertyValue(
property,
this.#ownerNode,
{ inherit: true, initial, isColor }
);
}
if (cssValues.hasVarFunc(value)) {
// TODO: Resolve css var().
}
if (longhands) {
if (isColor) {
value = asciiLowercase(value);
if (systemColors.has(value)) {
return value;
}
}
return this.#resolveShorthand(property, value);
}
return this.#resolveLonghand(property, value, { caseSensitive, isColor });
}
#getPropertyMetadata(property) {
if (propertyMetadata.has(property)) {
return propertyMetadata.get(property);
}
const value = this.#values.get(property) ?? "";
// TODO: Also check if all or part of the value is quoted.
const caseSensitive = (cssValues.hasVarFunc(value) || value.startsWith("--")) ? true : undefined;
return { caseSensitive };
}
#resolveShorthand(property, value) {
// TODO: resolve other shorthands e.g. background, flex etc.
switch (property) {
case "margin":
case "padding": {
return this.#resolvePositionShorthand(property);
}
default: {
if (property.startsWith("border")) {
return this.#resolveBorderShorthands(property);
}
return value;
}
}
}
#resolvePositionShorthand(property) {
const shorthandItem = shorthandProperties.get(property);
if (!shorthandItem || !shorthandItem.shorthandFor) {
return "";
}
const longhandValues = [];
for (const [longhandProperty] of shorthandItem.shorthandFor) {
longhandValues.push(this.getPropertyValue(longhandProperty));
}
return getPositionValue(longhandValues);
}
#resolveLonghand(property, value, { caseSensitive, isColor }) {
const options = this.#prepareComputedValueOpts();
const parsedValue = cssValues.parsePropertyValue(property, value, {
caseSensitive,
...options
});
if (isColor) {
const resolvedValue = cssValues.serializeColor(parsedValue, options);
if (resolvedValue) {
return resolvedValue;
}
}
// TODO: Resolve special cases other than color.
return value;
}
#resolveBorderShorthands(property) {
switch (property) {
case "border": {
const values = [];
for (const item of ["top", "right", "bottom", "left"]) {
const value = this.getPropertyValue(`border-${item}`);
if (!value) {
return "";
}
values.push(value);
}
const [top, right, bottom, left] = values;
if (top === right && top === bottom && top === left) {
return top;
}
return "";
}
case "border-top":
case "border-right":
case "border-bottom":
case "border-left": {
const values = [];
for (const item of ["width", "style", "color"]) {
const value = this.getPropertyValue(`${property}-${item}`);
if (!value) {
return "";
}
values.push(value);
}
return values.join(" ");
}
// border-width, border-style, border-color
default: {
return this.#resolvePositionShorthand(property);
}
}
}
// Options are used when resolving relative values or specified values.
#prepareComputedValueOpts() {
if (!this.#computedValueOpts.has("options")) {
this.#computedValueOpts.set("options", { format: "computedValue" });
}
const options = this.#computedValueOpts.get("options");
// Return the cached options if the specified raw values haven't changed.
const rawColorScheme = this.#values.get("color-scheme") ?? "";
const rawColor = this.#values.get("color") ?? "";
if (
this.#computedValueOpts.get("rawColorScheme") === rawColorScheme &&
this.#computedValueOpts.get("rawColor") === rawColor
) {
return options;
}
// Store current raw values for future cache validation.
this.#computedValueOpts.set("rawColorScheme", rawColorScheme);
this.#computedValueOpts.set("rawColor", rawColor);
// Prepare color-scheme.
const colorScheme = computedStyle.replaceEmptyValueAndKeywords(
"color-scheme",
rawColorScheme,
this.#ownerNode,
{ inherit: true, initial: "normal" }
);
this.#cachedPropertyValues.set("color-scheme", {
resolvedValue: colorScheme,
value: rawColorScheme
});
options.colorScheme = colorScheme;
// Prepare current color.
let currentColor = computedStyle.replaceEmptyValueAndKeywords(
"color",
rawColor,
this.#ownerNode,
{ inherit: true, initial: "canvastext" }
);
currentColor = asciiLowercase(currentColor);
// Replace currentcolor keyword.
if (currentColor === "currentcolor") {
currentColor = computedStyle.getInheritedPropertyValue(
"color",
this.#ownerNode,
{ inherit: true, initial: "canvastext", isColor: true }
);
}
// Resolve system colors.
if (systemColors.has(currentColor)) {
currentColor = cssValues.resolveSystemColorValue(currentColor, colorScheme);
} else {
// Resolve named colors.
if (/^[a-z]+$/.test(currentColor)) {
currentColor = cssValues.resolveColor(currentColor, { format: "computedValue" });
}
this.#cachedPropertyValues.set("color", {
resolvedValue: currentColor,
value: rawColor
});
}
options.currentColor = currentColor;
// TODO: Add customProperty, dimension etc.
// Store options.
this.#computedValueOpts.set("options", options);
return options;
}
/**

@@ -340,3 +568,3 @@ * Helper to handle border property expansion.

if (property === "border") {
properties.set(property, { propery: property, value, priority });
properties.set(property, { property, value, priority });
} else {

@@ -390,3 +618,3 @@ for (const itemProperty of this.#values.keys()) {

}
if (value && !hasVarFunc(value)) {
if (value && !cssValues.hasVarFunc(value)) {
const longhandValues = [];

@@ -397,3 +625,3 @@ const shorthandItem = shorthandProperties.get(shorthandProperty);

if (longhandProperty === property) {
if (isGlobalKeyword(value)) {
if (cssValues.isGlobalKeyword(value)) {
hasGlobalKeyword = true;

@@ -408,3 +636,3 @@ }

}
if (isGlobalKeyword(longhandValue)) {
if (cssValues.isGlobalKeyword(longhandValue)) {
hasGlobalKeyword = true;

@@ -501,3 +729,3 @@ }

}
if (value && !hasVarFunc(value)) {
if (value && !cssValues.hasVarFunc(value)) {
const longhandValues = [];

@@ -504,0 +732,0 @@ const { shorthandFor, position: shorthandPosition } = shorthandProperties.get(shorthandProperty);

+108
-221

@@ -5,12 +5,12 @@ "use strict";

const path = require("node:path");
const { parseStyleSheet } = require("./css-parser");
const CSSStyleRule = require("../../../../generated/idl/CSSStyleRule.js");
const Specificity = require("@bramus/specificity").default;
const CSSImportRule = require("../../../../generated/idl/CSSImportRule.js");
const CSSMediaRule = require("../../../../generated/idl/CSSMediaRule.js");
const Specificity = require("@bramus/specificity").default;
const CSSStyleProperties = require("../../../../generated/idl/CSSStyleProperties.js");
const { getSpecifiedColor, getComputedOrUsedColor } = require("./colors");
const CSSStyleRule = require("../../../../generated/idl/CSSStyleRule.js");
const { asciiLowercase } = require("../../helpers/strings");
const { evaluateMediaList } = require("../MediaList-impl.js");
const { deprecatedAliases, systemColors } = require("./system-colors");
const { parseStyleSheet } = require("./css-parser");
const { isGlobalKeyword } = require("./css-values");
const { systemColors } = require("./system-colors");

@@ -23,96 +23,2 @@ const defaultStyleSheet = fs.readFileSync(

// Properties for which getResolvedValue is implemented. This is less than
// every supported property.
// https://drafts.csswg.org/indexes/#properties
const propertiesWithResolvedValueImplemented = {
"__proto__": null,
// https://drafts.csswg.org/css2/visufx.html#visibility
"visibility": {
inherited: true,
initial: "visible",
computedValue: "as-specified"
},
// https://svgwg.org/svg2-draft/interact.html#PointerEventsProperty
"pointer-events": {
inherited: true,
initial: "auto",
computedValue: "as-specified"
},
// https://drafts.csswg.org/css-backgrounds-3/#propdef-background-color
"background-color": {
inherited: false,
initial: "transparent",
computedValue: "computed-color"
},
// https://drafts.csswg.org/css-logical-1/#propdef-border-block-end-color
"border-block-start-color": {
inherited: false,
initial: "currentcolor",
computedValue: "computed-color"
},
"border-block-end-color": {
inherited: false,
initial: "currentcolor",
computedValue: "computed-color"
},
"border-inline-start-color": {
inherited: false,
initial: "currentcolor",
computedValue: "computed-color"
},
"border-inline-end-color": {
inherited: false,
initial: "currentcolor",
computedValue: "computed-color"
},
// https://drafts.csswg.org/css-backgrounds-3/#propdef-border-bottom-color
"border-top-color": {
inherited: false,
initial: "currentcolor",
computedValue: "computed-color"
},
"border-right-color": {
inherited: false,
initial: "currentcolor",
computedValue: "computed-color"
},
"border-bottom-color": {
inherited: false,
initial: "currentcolor",
computedValue: "computed-color"
},
"border-left-color": {
inherited: false,
initial: "currentcolor",
computedValue: "computed-color"
},
// https://drafts.csswg.org/css-ui-4/#propdef-caret-color
"caret-color": {
inherited: true,
initial: "auto",
computedValue: "computed-color"
},
// https://drafts.csswg.org/css-color-4/#propdef-color
"color": {
inherited: true,
initial: "canvastext",
computedValue: "computed-color"
},
// https://drafts.csswg.org/css-ui-4/#propdef-outline-color
"outline-color": {
inherited: false,
initial: "invert",
computedValue: "computed-color"
},
// https://drafts.csswg.org/css-display/#the-display-properties
// Currently only "as-specified" is supported as a computed value
"display": {
inherited: false,
initial: "inline",
computedValue: "as-specified"
}
};
const implementedProperties = Object.keys(propertiesWithResolvedValueImplemented);
function getComputedStyleDeclaration(elementImpl) {

@@ -133,2 +39,3 @@ const styleCache = elementImpl._ownerDocument._styleCache;

}
clonedDeclaration._readonly = true;

@@ -138,8 +45,3 @@ return clonedDeclaration;

const declaration = prepareComputedStyleDeclaration(elementImpl, { styleCache });
// TODO: Remove later.
for (const property of implementedProperties) {
declaration.setProperty(property, getResolvedValue(elementImpl, property));
}
const declaration = prepareComputedStyleDeclaration(elementImpl, styleCache);
declaration._readonly = true;

@@ -150,3 +52,3 @@

function prepareComputedStyleDeclaration(elementImpl, { styleCache }) {
function prepareComputedStyleDeclaration(elementImpl, styleCache) {
const { style } = elementImpl;

@@ -246,138 +148,123 @@ const declaration = CSSStyleProperties.createImpl(elementImpl._globalObject, [], {

function matches(selectorText, elementImpl) {
try {
const domSelector = elementImpl._ownerDocument._getDOMSelector();
const { ast, match, pseudoElement } = domSelector.check(selectorText, elementImpl);
// `pseudoElement` is a pseudo-element selector (e.g. `::before`).
// However, we do not support getComputedStyle(element, pseudoElement), so `match` is set to `false`.
if (pseudoElement) {
return {
match: false
};
}
return { ast, match, pseudoElement };
} catch {
// fall through
const domSelector = elementImpl._ownerDocument._getDOMSelector();
const { ast, match, pseudoElement } = domSelector.check(selectorText, elementImpl);
// `pseudoElement` is a pseudo-element selector (e.g. `::before`).
// However, we do not support getComputedStyle(element, pseudoElement), so `match` is set to `false`.
if (pseudoElement) {
return {
match: false
};
}
return {
match: false
};
return { ast, match, pseudoElement };
}
// Naive implementation of https://drafts.csswg.org/css-cascade-4/#cascading
// based on the previous jsdom implementation of getComputedStyle.
// Does not implement https://drafts.csswg.org/css-cascade-4/#cascade-specificity,
// or rather specificity is only implemented by the order in which the matching
// rules appear. The last rule is the most specific while the first rule is
// the least specific.
function getCascadedPropertyValue(element, property) {
const cached = element._ownerDocument._styleCache.get(element);
if (cached) {
return cached.getPropertyValue(property);
}
return getComputedStyleDeclaration(element).getPropertyValue(property);
}
// https://drafts.csswg.org/css-cascade-4/#specified-value
function getSpecifiedValue(element, property) {
const { initial, inherited, computedValue } = propertiesWithResolvedValueImplemented[property];
const cascade = getCascadedPropertyValue(element, property);
if (cascade !== "") {
if (computedValue === "computed-color") {
return getSpecifiedColor(cascade);
function replaceEmptyValueAndKeywords(property, value, elementImpl, { inherit, initial, isColor, longhands }) {
if (value === "") {
if (longhands) {
return "";
} else if (!inherit || !elementImpl.parentElement) {
return initial;
}
return cascade;
value = getInheritedPropertyValue(property, elementImpl, { inherit, initial, isColor });
}
// Defaulting
if (inherited && element.parentElement !== null) {
return getComputedValue(element.parentElement, property);
if (isGlobalKeyword(value)) {
value = replaceGlobalKeywords(property, value, elementImpl, { inherit, initial, isColor });
}
// root element without parent element or inherited property
return initial;
return value;
}
// https://drafts.csswg.org/css-cascade-4/#computed-value
function getComputedValue(element, property) {
const { computedValue, inherited, initial } = propertiesWithResolvedValueImplemented[property];
let specifiedValue = getSpecifiedValue(element, property);
// https://drafts.csswg.org/css-cascade/#defaulting-keywords
switch (specifiedValue) {
case "initial": {
specifiedValue = initial;
break;
function getInheritedPropertyValue(property, elementImpl, { inherit, initial, isColor }) {
const styleCache = elementImpl._ownerDocument._styleCache;
const { parentElement } = elementImpl;
if (!parentElement) {
return initial;
}
let parent = parentElement;
while (parent) {
let declaration;
if (styleCache.has(parent)) {
declaration = styleCache.get(parent);
} else {
declaration = prepareComputedStyleDeclaration(parent, styleCache);
}
case "inherit": {
if (element.parentElement !== null) {
specifiedValue = getComputedValue(element.parentElement, property);
} else {
specifiedValue = initial;
// For color-related properties, unset the _computed flag to retrieve the specified value.
// @asamuzakjp/css-color handles the resolution of the specified value.
if (isColor) {
declaration._computed = false;
}
let value = declaration.getPropertyValue(property);
if (isColor) {
// Restore the _computed flag.
declaration._computed = true;
// If the value is a system color value, retrieve it again as a computed value.
if (value && systemColors.has(asciiLowercase(value))) {
value = declaration.getPropertyValue(property);
}
break;
}
case "unset": {
if (inherited && element.parentElement !== null) {
specifiedValue = getComputedValue(element.parentElement, property);
} else {
specifiedValue = initial;
if (value) {
if (isColor && isGlobalKeyword(value)) {
return replaceGlobalKeywords(property, value, parent, { inherit, initial, isColor });
}
return value;
} else if (!parent.parentElement || !inherit) {
break;
}
// TODO: https://drafts.csswg.org/css-cascade-5/#revert-layer
case "revert-layer": {
break;
}
// TODO: https://drafts.csswg.org/css-cascade-5/#default
case "revert": {
break;
}
default: {
// fall through; specifiedValue is not a CSS-wide keyword.
}
parent = parent.parentElement;
}
if (computedValue === "as-specified") {
return specifiedValue;
} else if (computedValue === "computed-color") {
let value = asciiLowercase(specifiedValue);
// https://drafts.csswg.org/css-color-4/#resolving-other-colors
if (specifiedValue === "currentcolor") {
if (property === "color") {
if (element.parentElement !== null) {
return getComputedValue(element.parentElement, "color");
return initial;
}
function replaceGlobalKeywords(property, value, elementImpl, { inherit, initial, isColor }) {
let element = elementImpl;
while (element) {
switch (value) {
case "initial": {
return initial;
}
case "inherit": {
if (!element.parentElement) {
return initial;
}
value = initial;
} else {
return getComputedValue(element, "color");
value = getInheritedPropertyValue(property, element, { inherit, initial, isColor });
break;
}
}
if (systemColors.has(value) || deprecatedAliases.has(value)) {
let key = value;
if (deprecatedAliases.has(value)) {
key = deprecatedAliases.get(value);
case "unset": {
if (!inherit || !element.parentElement) {
return initial;
}
value = getInheritedPropertyValue(property, element, { inherit, initial, isColor });
break;
}
const { light, dark } = systemColors.get(key);
const colorScheme = getCascadedPropertyValue(element, "color-scheme");
if (colorScheme === "dark") {
return dark;
case "revert-layer": {
// TODO: https://drafts.csswg.org/css-cascade-5/#revert-layer
return value;
}
return light;
case "revert": {
// TODO: https://drafts.csswg.org/css-cascade-5/#default
return value;
}
default: {
// fall through; value is not a CSS-wide keyword.
}
}
return getComputedOrUsedColor(specifiedValue);
if (element.parentElement) {
if (!value) {
element = element.parentElement;
} else if (isGlobalKeyword(value)) {
return replaceGlobalKeywords(property, value, element, { inherit, initial, isColor });
} else {
return value;
}
} else {
return initial;
}
}
throw new TypeError(`Internal error: unrecognized computed value instruction '${computedValue}'`);
return value;
}
// https://drafts.csswg.org/cssom/#resolved-value
// Only implements the properties that are defined in propertiesWithResolvedValueImplemented.
function getResolvedValue(element, property) {
// We can always use the computed value with the current set of propertiesWithResolvedValueImplemented:
// * Color properties end up with the used value, but we don't implement any actual differences between used and
// computed that https://drafts.csswg.org/css-cascade-5/#used-value gestures at.
// * The other properties fall back to the "any other property: The resolved value is the computed value." case.
return getComputedValue(element, property);
}
function invalidateStyleCache(elementImpl) {

@@ -389,6 +276,6 @@ if (elementImpl._attached) {

module.exports = {
SHADOW_DOM_PSEUDO_REGEXP: /^::(?:part|slotted)\(/i,
getComputedStyleDeclaration,
invalidateStyleCache
};
exports.SHADOW_DOM_PSEUDO_REGEXP = /^::(?:part|slotted)\(/i;
exports.getComputedStyleDeclaration = getComputedStyleDeclaration;
exports.getInheritedPropertyValue = getInheritedPropertyValue;
exports.invalidateStyleCache = invalidateStyleCache;
exports.replaceEmptyValueAndKeywords = replaceEmptyValueAndKeywords;

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

const { asciiLowercase } = require("../../helpers/strings");
const { systemColors } = require("./system-colors");

@@ -20,50 +21,2 @@ // Constants

// System colors
// @see https://drafts.csswg.org/css-color/#css-system-colors
// @see https://drafts.csswg.org/css-color/#deprecated-system-colors
const SYS_COLORS = new Set([
"accentcolor",
"accentcolortext",
"activeborder",
"activecaption",
"activetext",
"appworkspace",
"background",
"buttonborder",
"buttonface",
"buttonhighlight",
"buttonshadow",
"buttontext",
"canvas",
"canvastext",
"captiontext",
"field",
"fieldtext",
"graytext",
"highlight",
"highlighttext",
"inactiveborder",
"inactivecaption",
"inactivecaptiontext",
"infobackground",
"infotext",
"linktext",
"mark",
"marktext",
"menu",
"menutext",
"scrollbar",
"selecteditem",
"selecteditemtext",
"threeddarkshadow",
"threedface",
"threedhighlight",
"threedlightshadow",
"threedshadow",
"visitedtext",
"window",
"windowframe",
"windowtext"
]);
// AST node types

@@ -95,2 +48,11 @@ const AST_TYPES = Object.freeze({

function getPropertyDefinition(property) {
if (propertyDefinitions.has(property)) {
return propertyDefinitions.get(property);
} else if (property.startsWith("--")) {
return { inherited: "yes", initial: "" };
}
return {};
}
/**

@@ -173,3 +135,3 @@ * Checks if the value is a global keyword.

}
const cacheKey = `resolveCalc_${val}`;
const cacheKey = `resolveCalc_${val}_${opt.format}`;
const cachedValue = lruCache.get(cacheKey);

@@ -520,12 +482,12 @@ if (typeof cachedValue === "string") {

* @param {Array<object>} val - The AST value.
* @param {object} [opt={ format: "specifiedValue" }] - The options for parsing.
* @returns {string|undefined} The serialized color.
*/
function serializeColor(val) {
function serializeColor(val, opt = { format: "specifiedValue" }) {
const [item] = val;
const { name, type, value } = item ?? {};
const lowerCasedName = asciiLowercase(`${name}`);
switch (type) {
case AST_TYPES.FUNCTION: {
const res = resolveColor(`${name}(${value})`, {
format: "specifiedValue"
});
const res = resolveColor(`${lowerCasedName}(${value})`, opt);
if (res) {

@@ -537,5 +499,3 @@ return res;

case AST_TYPES.HASH: {
const res = resolveColor(`#${value}`, {
format: "specifiedValue"
});
const res = resolveColor(`#${value}`, opt);
if (res) {

@@ -547,8 +507,9 @@ return res;

case AST_TYPES.IDENTIFIER: {
if (SYS_COLORS.has(name)) {
return name;
if (systemColors.has(lowerCasedName)) {
if (opt.format === "specifiedValue") {
return lowerCasedName;
}
return resolveSystemColorValue(lowerCasedName, opt.colorScheme);
}
const res = resolveColor(name, {
format: "specifiedValue"
});
const res = resolveColor(lowerCasedName, opt);
if (res) {

@@ -711,3 +672,3 @@ return res;

default: {
return serializeColor(value, opt);
return serializeColor(value);
}

@@ -738,6 +699,6 @@ }

case AST_TYPES.URL: {
return serializeURL(value, opt);
return serializeURL(value);
}
default: {
return serializeGradient(value, opt);
return serializeGradient(value);
}

@@ -747,2 +708,13 @@ }

function resolveSystemColorValue(value, colorScheme = "normal") {
if (!systemColors.has(value)) {
return value;
}
const { light, dark } = systemColors.get(value);
if (colorScheme === "dark") {
return dark;
}
return light;
}
/**

@@ -828,2 +800,3 @@ * Resolves a border shorthand value.

exports.AST_TYPES = AST_TYPES;
exports.getPropertyDefinition = getPropertyDefinition;
exports.hasCalcFunc = hasCalcFunc;

@@ -836,2 +809,3 @@ exports.hasVarFunc = hasVarFunc;

exports.resolveCalc = resolveCalc;
exports.resolveColor = resolveColor;
exports.resolveColorValue = resolveColorValue;

@@ -842,2 +816,3 @@ exports.resolveFunctionValue = resolveFunctionValue;

exports.resolveNumericValue = resolveNumericValue;
exports.resolveSystemColorValue = resolveSystemColorValue;
exports.serializeAngle = serializeAngle;

@@ -844,0 +819,0 @@ exports.serializeColor = serializeColor;

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

const backgroundColor = require("../properties/backgroundColor");
const backgroundSize = require("../properties/backgroundSize");
const border = require("../properties/border");

@@ -217,4 +216,3 @@ const borderWidth = require("../properties/borderWidth");

const { value: propertyValue } = properties.get(property);
const parsedValue = background.shorthandFor.get(property).parse(propertyValue);
const values = splitValue(parsedValue, {
const values = splitValue(propertyValue, {
delimiter: ","

@@ -226,6 +224,6 @@ });

if (property === backgroundColor.property) {
bgValues[bgLength - 1][property] = parsedValue[0];
bgValues[bgLength - 1][property] = values[0];
} else {
for (let i = 0; i < bgLength; i++) {
bgValues[i][property] = values[i];
bgValues[i][property] = values[i] !== undefined ? values[i] : values[0];
}

@@ -236,10 +234,34 @@ }

const bg = [];
for (const [longhand, value] of Object.entries(bgValue)) {
if (!value || value === background.initialValues.get(longhand)) {
let hasPosition = false;
const originValue = bgValue["background-origin"];
const clipValue = bgValue["background-clip"];
const isDefaultBox =
originValue === background.initialValues.get("background-origin") &&
clipValue === background.initialValues.get("background-clip");
for (const longhand of background.initialValues.keys()) {
const value = bgValue[longhand];
if (!value) {
continue;
}
if (longhand === backgroundSize.property) {
bg.push(`/ ${value}`);
} else {
bg.push(value);
if (longhand === "background-origin") {
if (!isDefaultBox) {
bg.push(originValue);
}
} else if (longhand === "background-clip") {
if (!isDefaultBox && originValue !== clipValue) {
bg.push(clipValue);
}
} else if (value !== background.initialValues.get(longhand)) {
if (longhand === "background-position") {
hasPosition = true;
bg.push(value);
} else if (longhand === "background-size") {
if (hasPosition) {
bg.push(`/ ${value}`);
} else {
bg.push(background.initialValues.get("background-position"), `/ ${value}`);
}
} else {
bg.push(value);
}
}

@@ -1334,3 +1356,3 @@ }

const { logicalPropertyGroup: shorthandProperty } = propertyDefinitions.get(property) ?? {};
if (borderProperties.has(property)) {
if (borderProperties.has(property) && !hasVarFunc(value)) {
borders.set(property, { property, value, priority });

@@ -1337,0 +1359,0 @@ } else if (shorthandProperties.has(shorthandProperty)) {

"use strict";
// https://drafts.csswg.org/css-color-4/#css-system-colors
module.exports.systemColors = new Map([
const systemColors = new Map([
[

@@ -123,3 +123,3 @@ "accentcolor", {

// https://drafts.csswg.org/css-color-4/#deprecated-system-colors
module.exports.deprecatedAliases = new Map([
const deprecatedAliases = new Map([
["activeborder", "buttonborder"],

@@ -149,1 +149,11 @@ ["activecaption", "canvas"],

]);
function getAllSystemColors() {
const allColors = new Map(systemColors);
for (const [alias, target] of deprecatedAliases) {
allColors.set(alias, systemColors.get(target));
}
return allColors;
}
exports.systemColors = getAllSystemColors();

@@ -70,21 +70,38 @@ "use strict";

const bg = [];
for (const [longhand, value] of Object.entries(bgValue)) {
let hasPosition = false;
const originValue = bgValue[backgroundOrigin.property];
const clipValue = bgValue[backgroundClip.property];
const isDefaultBox =
originValue === initialValues.get(backgroundOrigin.property) &&
clipValue === initialValues.get(backgroundClip.property);
for (const [longhand] of shorthandFor) {
const value = bgValue[longhand];
if (value) {
const arr = bgMap.get(longhand);
arr.push(value);
bgMap.set(longhand, arr);
if (value !== initialValues.get(longhand)) {
if (longhand === backgroundSize.property) {
bg.push(`/ ${value}`);
} else {
bg.push(value);
if (longhand === backgroundOrigin.property) {
if (!isDefaultBox) {
bg.push(originValue);
}
} else if (longhand === backgroundImage.property) {
if (v === "none") {
bg.push(value);
} else if (longhand === backgroundClip.property) {
if (!isDefaultBox && originValue !== clipValue) {
bg.push(clipValue);
}
} else if (longhand === backgroundColor.property) {
if (v === "transparent") {
} else if (value !== initialValues.get(longhand)) {
if (longhand === backgroundPosition.property) {
hasPosition = true;
bg.push(value);
} else if (longhand === backgroundSize.property) {
if (hasPosition) {
bg.push(`/ ${value}`);
} else {
bg.push(initialValues.get(backgroundPosition.property), `/ ${value}`);
}
} else {
bg.push(value);
}
} else if (longhand === backgroundImage.property && v === "none") {
bg.push(value);
} else if (longhand === backgroundColor.property && v === "transparent") {
bg.push(value);
}

@@ -119,2 +136,5 @@ }

const val = this.getPropertyValue(longhand);
if (!val || parsers.hasVarFunc(val)) {
return "";
}
if (longhand === backgroundImage.property) {

@@ -128,3 +148,3 @@ if (val === "none" && v === "none" && this.getPropertyValue(backgroundColor.property) === "transparent") {

});
l = imgValues.length;
l = Math.max(l, imgValues.length);
bgMap.set(longhand, imgValues);

@@ -137,8 +157,7 @@ }

} else if (val !== initialValues.get(longhand)) {
bgMap.set(
longhand,
parsers.splitValue(val, {
delimiter: ","
})
);
const values = parsers.splitValue(val, {
delimiter: ","
});
l = Math.max(l, values.length);
bgMap.set(longhand, values);
}

@@ -156,49 +175,69 @@ }

for (let i = 0; i < l; i++) {
bgValues[i] = [];
}
for (const [longhand, values] of bgMap) {
for (let i = 0; i < l; i++) {
switch (longhand) {
case backgroundColor.property: {
if (i === l - 1) {
const value = values[0];
if (parsers.hasVarFunc(value)) {
return "";
}
if (value && value !== initialValues.get(longhand)) {
const bgValue = bgValues[i];
bgValue.push(value);
}
}
break;
const bg = [];
let hasPosition = false;
let originValue, clipValue;
const originValues = bgMap.get(backgroundOrigin.property);
const clipValues = bgMap.get(backgroundClip.property);
if (originValues) {
if (originValues[i] !== undefined) {
originValue = originValues[i];
} else {
originValue = initialValues.get(backgroundOrigin.property);
}
} else {
originValue = initialValues.get(backgroundOrigin.property);
}
if (clipValues) {
if (clipValues[i] !== undefined) {
clipValue = clipValues[i];
} else {
clipValue = initialValues.get(backgroundClip.property);
}
} else {
clipValue = initialValues.get(backgroundClip.property);
}
const isDefaultBox =
originValue === initialValues.get(backgroundOrigin.property) &&
clipValue === initialValues.get(backgroundClip.property);
for (const [longhand] of shorthandFor) {
let value;
if (bgMap.has(longhand)) {
const values = bgMap.get(longhand);
value = values[i] !== undefined ? values[i] : initialValues.get(longhand);
} else {
value = initialValues.get(longhand);
}
if (parsers.hasVarFunc(value)) {
return "";
}
if (longhand === backgroundOrigin.property) {
if (!isDefaultBox) {
bg.push(originValue);
}
case backgroundSize.property: {
const value = values[i];
if (parsers.hasVarFunc(value)) {
return "";
}
if (value && value !== initialValues.get(longhand)) {
const bgValue = bgValues[i];
bgValue.push(`/ ${value}`);
}
break;
} else if (longhand === backgroundClip.property) {
if (!isDefaultBox && originValue !== clipValue) {
bg.push(clipValue);
}
default: {
const value = values[i];
if (parsers.hasVarFunc(value)) {
return "";
} else if (longhand === backgroundColor.property) {
if (i === l - 1 && (value !== initialValues.get(longhand) || bgMap.has(longhand))) {
bg.push(value);
}
} else if (value !== initialValues.get(longhand)) {
if (longhand === backgroundPosition.property) {
hasPosition = true;
bg.push(value);
} else if (longhand === backgroundSize.property) {
if (hasPosition) {
bg.push(`/ ${value}`);
} else {
bg.push(initialValues.get(backgroundPosition.property), `/ ${value}`);
}
if (value && value !== initialValues.get(longhand)) {
const bgValue = bgValues[i];
bgValue.push(value);
}
} else {
bg.push(value);
}
}
}
bgValues.push(bg.join(" "));
}
const backgrounds = [];
for (const bgValue of bgValues) {
backgrounds.push(bgValue.join(" "));
}
return backgrounds.join(", ");
return bgValues.join(", ");
},

@@ -205,0 +244,0 @@ enumerable: true,

{
"name": "jsdom",
"version": "29.0.1",
"version": "29.0.2",
"description": "A JavaScript implementation of many web standards",

@@ -26,4 +26,4 @@ "keywords": [

"dependencies": {
"@asamuzakjp/css-color": "^5.0.1",
"@asamuzakjp/dom-selector": "^7.0.3",
"@asamuzakjp/css-color": "^5.1.5",
"@asamuzakjp/dom-selector": "^7.0.6",
"@bramus/specificity": "^2.4.2",

@@ -30,0 +30,0 @@ "@csstools/css-syntax-patches-for-csstree": "^1.1.1",

"use strict";
// https://drafts.csswg.org/css-color-4/#named-color
const namedColors = {
__proto__: null,
aliceblue: [0xF0, 0xF8, 0xFF],
antiquewhite: [0xFA, 0xEB, 0xD7],
aqua: [0x00, 0xFF, 0xFF],
aquamarine: [0x7F, 0xFF, 0xD4],
azure: [0xF0, 0xFF, 0xFF],
beige: [0xF5, 0xF5, 0xDC],
bisque: [0xFF, 0xE4, 0xC4],
black: [0x00, 0x00, 0x00],
blanchedalmond: [0xFF, 0xEB, 0xCD],
blue: [0x00, 0x00, 0xFF],
blueviolet: [0x8A, 0x2B, 0xE2],
brown: [0xA5, 0x2A, 0x2A],
burlywood: [0xDE, 0xB8, 0x87],
cadetblue: [0x5F, 0x9E, 0xA0],
chartreuse: [0x7F, 0xFF, 0x00],
chocolate: [0xD2, 0x69, 0x1E],
coral: [0xFF, 0x7F, 0x50],
cornflowerblue: [0x64, 0x95, 0xED],
cornsilk: [0xFF, 0xF8, 0xDC],
crimson: [0xDC, 0x14, 0x3C],
cyan: [0x00, 0xFF, 0xFF],
darkblue: [0x00, 0x00, 0x8B],
darkcyan: [0x00, 0x8B, 0x8B],
darkgoldenrod: [0xB8, 0x86, 0x0B],
darkgray: [0xA9, 0xA9, 0xA9],
darkgreen: [0x00, 0x64, 0x00],
darkgrey: [0xA9, 0xA9, 0xA9],
darkkhaki: [0xBD, 0xB7, 0x6B],
darkmagenta: [0x8B, 0x00, 0x8B],
darkolivegreen: [0x55, 0x6B, 0x2F],
darkorange: [0xFF, 0x8C, 0x00],
darkorchid: [0x99, 0x32, 0xCC],
darkred: [0x8B, 0x00, 0x00],
darksalmon: [0xE9, 0x96, 0x7A],
darkseagreen: [0x8F, 0xBC, 0x8F],
darkslateblue: [0x48, 0x3D, 0x8B],
darkslategray: [0x2F, 0x4F, 0x4F],
darkslategrey: [0x2F, 0x4F, 0x4F],
darkturquoise: [0x00, 0xCE, 0xD1],
darkviolet: [0x94, 0x00, 0xD3],
deeppink: [0xFF, 0x14, 0x93],
deepskyblue: [0x00, 0xBF, 0xFF],
dimgray: [0x69, 0x69, 0x69],
dimgrey: [0x69, 0x69, 0x69],
dodgerblue: [0x1E, 0x90, 0xFF],
firebrick: [0xB2, 0x22, 0x22],
floralwhite: [0xFF, 0xFA, 0xF0],
forestgreen: [0x22, 0x8B, 0x22],
fuchsia: [0xFF, 0x00, 0xFF],
gainsboro: [0xDC, 0xDC, 0xDC],
ghostwhite: [0xF8, 0xF8, 0xFF],
gold: [0xFF, 0xD7, 0x00],
goldenrod: [0xDA, 0xA5, 0x20],
gray: [0x80, 0x80, 0x80],
green: [0x00, 0x80, 0x00],
greenyellow: [0xAD, 0xFF, 0x2F],
grey: [0x80, 0x80, 0x80],
honeydew: [0xF0, 0xFF, 0xF0],
hotpink: [0xFF, 0x69, 0xB4],
indianred: [0xCD, 0x5C, 0x5C],
indigo: [0x4B, 0x00, 0x82],
ivory: [0xFF, 0xFF, 0xF0],
khaki: [0xF0, 0xE6, 0x8C],
lavender: [0xE6, 0xE6, 0xFA],
lavenderblush: [0xFF, 0xF0, 0xF5],
lawngreen: [0x7C, 0xFC, 0x00],
lemonchiffon: [0xFF, 0xFA, 0xCD],
lightblue: [0xAD, 0xD8, 0xE6],
lightcoral: [0xF0, 0x80, 0x80],
lightcyan: [0xE0, 0xFF, 0xFF],
lightgoldenrodyellow: [0xFA, 0xFA, 0xD2],
lightgray: [0xD3, 0xD3, 0xD3],
lightgreen: [0x90, 0xEE, 0x90],
lightgrey: [0xD3, 0xD3, 0xD3],
lightpink: [0xFF, 0xB6, 0xC1],
lightsalmon: [0xFF, 0xA0, 0x7A],
lightseagreen: [0x20, 0xB2, 0xAA],
lightskyblue: [0x87, 0xCE, 0xFA],
lightslategray: [0x77, 0x88, 0x99],
lightslategrey: [0x77, 0x88, 0x99],
lightsteelblue: [0xB0, 0xC4, 0xDE],
lightyellow: [0xFF, 0xFF, 0xE0],
lime: [0x00, 0xFF, 0x00],
limegreen: [0x32, 0xCD, 0x32],
linen: [0xFA, 0xF0, 0xE6],
magenta: [0xFF, 0x00, 0xFF],
maroon: [0x80, 0x00, 0x00],
mediumaquamarine: [0x66, 0xCD, 0xAA],
mediumblue: [0x00, 0x00, 0xCD],
mediumorchid: [0xBA, 0x55, 0xD3],
mediumpurple: [0x93, 0x70, 0xDB],
mediumseagreen: [0x3C, 0xB3, 0x71],
mediumslateblue: [0x7B, 0x68, 0xEE],
mediumspringgreen: [0x00, 0xFA, 0x9A],
mediumturquoise: [0x48, 0xD1, 0xCC],
mediumvioletred: [0xC7, 0x15, 0x85],
midnightblue: [0x19, 0x19, 0x70],
mintcream: [0xF5, 0xFF, 0xFA],
mistyrose: [0xFF, 0xE4, 0xE1],
moccasin: [0xFF, 0xE4, 0xB5],
navajowhite: [0xFF, 0xDE, 0xAD],
navy: [0x00, 0x00, 0x80],
oldlace: [0xFD, 0xF5, 0xE6],
olive: [0x80, 0x80, 0x00],
olivedrab: [0x6B, 0x8E, 0x23],
orange: [0xFF, 0xA5, 0x00],
orangered: [0xFF, 0x45, 0x00],
orchid: [0xDA, 0x70, 0xD6],
palegoldenrod: [0xEE, 0xE8, 0xAA],
palegreen: [0x98, 0xFB, 0x98],
paleturquoise: [0xAF, 0xEE, 0xEE],
palevioletred: [0xDB, 0x70, 0x93],
papayawhip: [0xFF, 0xEF, 0xD5],
peachpuff: [0xFF, 0xDA, 0xB9],
peru: [0xCD, 0x85, 0x3F],
pink: [0xFF, 0xC0, 0xCB],
plum: [0xDD, 0xA0, 0xDD],
powderblue: [0xB0, 0xE0, 0xE6],
purple: [0x80, 0x00, 0x80],
rebeccapurple: [0x66, 0x33, 0x99],
red: [0xFF, 0x00, 0x00],
rosybrown: [0xBC, 0x8F, 0x8F],
royalblue: [0x41, 0x69, 0xE1],
saddlebrown: [0x8B, 0x45, 0x13],
salmon: [0xFA, 0x80, 0x72],
sandybrown: [0xF4, 0xA4, 0x60],
seagreen: [0x2E, 0x8B, 0x57],
seashell: [0xFF, 0xF5, 0xEE],
sienna: [0xA0, 0x52, 0x2D],
silver: [0xC0, 0xC0, 0xC0],
skyblue: [0x87, 0xCE, 0xEB],
slateblue: [0x6A, 0x5A, 0xCD],
slategray: [0x70, 0x80, 0x90],
slategrey: [0x70, 0x80, 0x90],
snow: [0xFF, 0xFA, 0xFA],
springgreen: [0x00, 0xFF, 0x7F],
steelblue: [0x46, 0x82, 0xB4],
tan: [0xD2, 0xB4, 0x8C],
teal: [0x00, 0x80, 0x80],
thistle: [0xD8, 0xBF, 0xD8],
tomato: [0xFF, 0x63, 0x47],
turquoise: [0x40, 0xE0, 0xD0],
violet: [0xEE, 0x82, 0xEE],
wheat: [0xF5, 0xDE, 0xB3],
white: [0xFF, 0xFF, 0xFF],
whitesmoke: [0xF5, 0xF5, 0xF5],
yellow: [0xFF, 0xFF, 0x00],
yellowgreen: [0x9A, 0xCD, 0x32]
};
// Implements some of https://drafts.csswg.org/css-color-4/#resolving-sRGB-values and
// https://drafts.csswg.org/css-color-4/#serializing-sRGB-values, in a somewhat fragile way since
// we're not using a real parser/serializer. Attempts to cover:
// * hex colors
// * 'rgb()' and 'rgba()' values
// * named colors
// * 'transparent'
exports.getSpecifiedColor = color => {
const lowercasedColor = color.toLowerCase();
if (Object.hasOwn(namedColors, lowercasedColor) || lowercasedColor === "transparent") {
return lowercasedColor;
}
return sharedSpecifiedAndComputedAndUsed(color);
};
exports.getComputedOrUsedColor = color => {
const lowercasedColor = color.toLowerCase();
const fromNamedColors = namedColors[lowercasedColor];
if (fromNamedColors !== undefined) {
return `rgb(${fromNamedColors.join(", ")})`;
}
if (lowercasedColor === "transparent") {
return "rgba(0, 0, 0, 0)";
}
return sharedSpecifiedAndComputedAndUsed(color);
};
function sharedSpecifiedAndComputedAndUsed(color) {
if (/^#[0-9A-Fa-f]{6}$/.test(color) || /^#[0-9A-Fa-f]{3}$/.test(color)) {
return hexToRGB(color.slice(1));
}
if (/^#[0-9A-Fa-f]{8}$/.test(color) || /^#[0-9A-Fa-f]{4}$/.test(color)) {
return hexToRGBA(color.slice(1));
}
if (/^rgba?\(/.test(color)) {
return color.split(",").map(s => s.trim()).join(", ");
}
return color;
}
function hexToRGB(color) {
if (color.length === 6) {
const [r1, r2, g1, g2, b1, b2] = color.split("");
return `rgb(${hexesToDecimals([r1, r2], [g1, g2], [b1, b2]).join(", ")})`;
}
if (color.length === 3) {
const [r1, g1, b1] = color.split("");
return `rgb(${hexesToDecimals([r1, r1], [g1, g1], [b1, b1]).join(", ")})`;
}
return "rgb(0, 0, 0)";
}
function hexToRGBA(color) {
if (color.length === 8) {
const [r1, r2, g1, g2, b1, b2, a1, a2] = color.split("");
return `rgba(${hexesToDecimals([r1, r2], [g1, g2], [b1, b2]).join(", ")}, ${hexToPercent(a1, a2)})`;
}
if (color.length === 4) {
const [r1, g1, b1, a1] = color.split("");
return `rgba(${hexesToDecimals([r1, r1], [g1, g1], [b1, b1]).join(", ")}, ${hexToPercent(a1, a1)})`;
}
return "rgba(0, 0, 0, 1)";
}
function hexToDecimal(d1, d2) {
return parseInt(d1, 16) * 16 + parseInt(d2, 16);
}
function hexesToDecimals(...hexes) {
return hexes.map(pair => hexToDecimal(pair[0], pair[1]));
}
function hexToPercent(d1, d2) {
return Math.floor(1000 * hexToDecimal(d1, d2) / 255) / 1000;
}
"use strict";
const parsers = require("../helpers/css-values");
const property = "border-block-end-color";
const descriptor = {
set(v) {
v = v.trim();
if (parsers.hasVarFunc(v)) {
this._setProperty(property, v);
} else {
const val = parse(v);
if (typeof val === "string") {
const priority = this._priorities.get(property) ?? "";
this._setProperty(property, val, priority);
}
}
},
get() {
return this.getPropertyValue(property);
},
enumerable: true,
configurable: true
};
/**
* Parses the border-block-end-color property value.
*
* @param {string} v - The value to parse.
* @returns {string|undefined} The parsed value or undefined if invalid.
*/
function parse(v) {
if (v === "") {
return v;
}
const value = parsers.parsePropertyValue(property, v);
if (Array.isArray(value) && value.length === 1) {
return parsers.resolveColorValue(value);
} else if (typeof value === "string") {
return value;
}
return undefined;
}
module.exports = {
descriptor,
parse,
property
};
"use strict";
const parsers = require("../helpers/css-values");
const property = "border-block-start-color";
const descriptor = {
set(v) {
v = v.trim();
if (parsers.hasVarFunc(v)) {
this._setProperty(property, v);
} else {
const val = parse(v);
if (typeof val === "string") {
const priority = this._priorities.get(property) ?? "";
this._setProperty(property, val, priority);
}
}
},
get() {
return this.getPropertyValue(property);
},
enumerable: true,
configurable: true
};
/**
* Parses the border-block-start-color property value.
*
* @param {string} v - The value to parse.
* @returns {string|undefined} The parsed value or undefined if invalid.
*/
function parse(v) {
if (v === "") {
return v;
}
const value = parsers.parsePropertyValue(property, v);
if (Array.isArray(value) && value.length === 1) {
return parsers.resolveColorValue(value);
} else if (typeof value === "string") {
return value;
}
return undefined;
}
module.exports = {
descriptor,
parse,
property
};
"use strict";
const parsers = require("../helpers/css-values");
const property = "border-collapse";
const descriptor = {
set(v) {
v = v.trim();
if (parsers.hasVarFunc(v)) {
this._setProperty(property, v);
} else {
const val = parse(v);
if (typeof val === "string") {
const priority = this._priorities.get(property) ?? "";
this._setProperty(property, val, priority);
}
}
},
get() {
return this.getPropertyValue(property);
},
enumerable: true,
configurable: true
};
/**
* Parses the border-collapse property value.
*
* @param {string} v - The value to parse.
* @returns {string|undefined} The parsed value or undefined if invalid.
*/
function parse(v) {
if (v === "") {
return v;
}
const value = parsers.parsePropertyValue(property, v);
if (Array.isArray(value) && value.length === 1) {
return parsers.resolveKeywordValue(value);
} else if (typeof value === "string") {
return value;
}
return undefined;
}
module.exports = {
descriptor,
parse,
property
};
"use strict";
const parsers = require("../helpers/css-values");
const property = "border-inline-end-color";
const descriptor = {
set(v) {
v = v.trim();
if (parsers.hasVarFunc(v)) {
this._setProperty(property, v);
} else {
const val = parse(v);
if (typeof val === "string") {
const priority = this._priorities.get(property) ?? "";
this._setProperty(property, val, priority);
}
}
},
get() {
return this.getPropertyValue(property);
},
enumerable: true,
configurable: true
};
/**
* Parses the border-inline-end-color property value.
*
* @param {string} v - The value to parse.
* @returns {string|undefined} The parsed value or undefined if invalid.
*/
function parse(v) {
if (v === "") {
return v;
}
const value = parsers.parsePropertyValue(property, v);
if (Array.isArray(value) && value.length === 1) {
return parsers.resolveColorValue(value);
} else if (typeof value === "string") {
return value;
}
return undefined;
}
module.exports = {
descriptor,
parse,
property
};
"use strict";
const parsers = require("../helpers/css-values");
const property = "border-inline-start-color";
const descriptor = {
set(v) {
v = v.trim();
if (parsers.hasVarFunc(v)) {
this._setProperty(property, v);
} else {
const val = parse(v);
if (typeof val === "string") {
const priority = this._priorities.get(property) ?? "";
this._setProperty(property, val, priority);
}
}
},
get() {
return this.getPropertyValue(property);
},
enumerable: true,
configurable: true
};
/**
* Parses the border-inline-start-color property value.
*
* @param {string} v - The value to parse.
* @returns {string|undefined} The parsed value or undefined if invalid.
*/
function parse(v) {
if (v === "") {
return v;
}
const value = parsers.parsePropertyValue(property, v);
if (Array.isArray(value) && value.length === 1) {
return parsers.resolveColorValue(value);
} else if (typeof value === "string") {
return value;
}
return undefined;
}
module.exports = {
descriptor,
parse,
property
};
"use strict";
const parsers = require("../helpers/css-values");
const property = "clear";
const descriptor = {
set(v) {
v = v.trim();
if (parsers.hasVarFunc(v)) {
this._setProperty(property, v);
} else {
const val = parse(v);
if (typeof val === "string") {
const priority = this._priorities.get(property) ?? "";
this._setProperty(property, val, priority);
}
}
},
get() {
return this.getPropertyValue(property);
},
enumerable: true,
configurable: true
};
/**
* Parses the clear property value.
*
* @param {string} v - The value to parse.
* @returns {string|undefined} The parsed value or undefined if invalid.
*/
function parse(v) {
if (v === "") {
return v;
}
const value = parsers.parsePropertyValue(property, v);
if (Array.isArray(value) && value.length === 1) {
return parsers.resolveKeywordValue(value);
} else if (typeof value === "string") {
return value;
}
return undefined;
}
module.exports = {
descriptor,
parse,
property
};
"use strict";
const parsers = require("../helpers/css-values");
const property = "color";
const descriptor = {
set(v) {
v = v.trim();
if (parsers.hasVarFunc(v)) {
this._setProperty(property, v);
} else {
const val = parse(v);
if (typeof val === "string") {
const priority = this._priorities.get(property) ?? "";
this._setProperty(property, val, priority);
}
}
},
get() {
return this.getPropertyValue(property);
},
enumerable: true,
configurable: true
};
/**
* Parses the color property value.
*
* @param {string} v - The value to parse.
* @returns {string|undefined} The parsed value or undefined if invalid.
*/
function parse(v) {
if (v === "") {
return v;
}
const value = parsers.parsePropertyValue(property, v);
if (Array.isArray(value) && value.length === 1) {
return parsers.resolveColorValue(value);
} else if (typeof value === "string") {
return value;
}
return undefined;
}
module.exports = {
descriptor,
parse,
property
};
"use strict";
const parsers = require("../helpers/css-values");
const property = "float";
const descriptor = {
set(v) {
v = v.trim();
if (parsers.hasVarFunc(v)) {
this._setProperty(property, v);
} else {
const val = parse(v);
if (typeof val === "string") {
const priority = this._priorities.get(property) ?? "";
this._setProperty(property, val, priority);
}
}
},
get() {
return this.getPropertyValue(property);
},
enumerable: true,
configurable: true
};
/**
* Parses the float property value.
*
* @param {string} v - The value to parse.
* @returns {string|undefined} The parsed value or undefined if invalid.
*/
function parse(v) {
if (v === "") {
return v;
}
const value = parsers.parsePropertyValue(property, v);
if (Array.isArray(value) && value.length === 1) {
return parsers.resolveKeywordValue(value);
} else if (typeof value === "string") {
return value;
}
return undefined;
}
module.exports = {
descriptor,
parse,
property
};
"use strict";
const parsers = require("../helpers/css-values");
const property = "flood-color";
const descriptor = {
set(v) {
v = v.trim();
if (parsers.hasVarFunc(v)) {
this._setProperty(property, v);
} else {
const val = parse(v);
if (typeof val === "string") {
const priority = this._priorities.get(property) ?? "";
this._setProperty(property, val, priority);
}
}
},
get() {
return this.getPropertyValue(property);
},
enumerable: true,
configurable: true
};
/**
* Parses the flood-color property value.
*
* @param {string} v - The value to parse.
* @returns {string|undefined} The parsed value or undefined if invalid.
*/
function parse(v) {
if (v === "") {
return v;
}
const value = parsers.parsePropertyValue(property, v);
if (Array.isArray(value) && value.length === 1) {
return parsers.resolveColorValue(value);
} else if (typeof value === "string") {
return value;
}
return undefined;
}
module.exports = {
descriptor,
parse,
property
};
"use strict";
const parsers = require("../helpers/css-values");
const property = "lighting-color";
const descriptor = {
set(v) {
v = v.trim();
if (parsers.hasVarFunc(v)) {
this._setProperty(property, v);
} else {
const val = parse(v);
if (typeof val === "string") {
const priority = this._priorities.get(property) ?? "";
this._setProperty(property, val, priority);
}
}
},
get() {
return this.getPropertyValue(property);
},
enumerable: true,
configurable: true
};
/**
* Parses the lighting-color property value.
*
* @param {string} v - The value to parse.
* @returns {string|undefined} The parsed value or undefined if invalid.
*/
function parse(v) {
if (v === "") {
return v;
}
const value = parsers.parsePropertyValue(property, v);
if (Array.isArray(value) && value.length === 1) {
return parsers.resolveColorValue(value);
} else if (typeof value === "string") {
return value;
}
return undefined;
}
module.exports = {
descriptor,
parse,
property
};
"use strict";
const parsers = require("../helpers/css-values");
const property = "outline-color";
const descriptor = {
set(v) {
v = v.trim();
if (parsers.hasVarFunc(v)) {
this._setProperty(property, v);
} else {
const val = parse(v);
if (typeof val === "string") {
const priority = this._priorities.get(property) ?? "";
this._setProperty(property, val, priority);
}
}
},
get() {
return this.getPropertyValue(property);
},
enumerable: true,
configurable: true
};
/**
* Parses the outline-color property value.
*
* @param {string} v - The value to parse.
* @returns {string|undefined} The parsed value or undefined if invalid.
*/
function parse(v) {
if (v === "") {
return v;
}
const value = parsers.parsePropertyValue(property, v);
if (Array.isArray(value) && value.length === 1) {
return parsers.resolveColorValue(value);
} else if (typeof value === "string") {
return value;
}
return undefined;
}
module.exports = {
descriptor,
parse,
property
};
"use strict";
const parsers = require("../helpers/css-values");
const property = "stop-color";
const descriptor = {
set(v) {
v = v.trim();
if (parsers.hasVarFunc(v)) {
this._setProperty(property, v);
} else {
const val = parse(v);
if (typeof val === "string") {
const priority = this._priorities.get(property) ?? "";
this._setProperty(property, val, priority);
}
}
},
get() {
return this.getPropertyValue(property);
},
enumerable: true,
configurable: true
};
/**
* Parses the stop-color property value.
*
* @param {string} v - The value to parse.
* @returns {string|undefined} The parsed value or undefined if invalid.
*/
function parse(v) {
if (v === "") {
return v;
}
const value = parsers.parsePropertyValue(property, v);
if (Array.isArray(value) && value.length === 1) {
return parsers.resolveColorValue(value);
} else if (typeof value === "string") {
return value;
}
return undefined;
}
module.exports = {
descriptor,
parse,
property
};
"use strict";
const parsers = require("../helpers/css-values");
const property = "text-emphasis-color";
const descriptor = {
set(v) {
v = v.trim();
if (parsers.hasVarFunc(v)) {
this._setProperty(property, v);
} else {
const val = parse(v);
if (typeof val === "string") {
const priority = this._priorities.get(property) ?? "";
this._setProperty(property, val, priority);
}
}
},
get() {
return this.getPropertyValue(property);
},
enumerable: true,
configurable: true
};
/**
* Parses the text-emphasis-color property value.
*
* @param {string} v - The value to parse.
* @returns {string|undefined} The parsed value or undefined if invalid.
*/
function parse(v) {
if (v === "") {
return v;
}
const value = parsers.parsePropertyValue(property, v);
if (Array.isArray(value) && value.length === 1) {
return parsers.resolveColorValue(value);
} else if (typeof value === "string") {
return value;
}
return undefined;
}
module.exports = {
descriptor,
parse,
property
};
"use strict";
const parsers = require("../helpers/css-values");
const property = "-webkit-text-fill-color";
const descriptor = {
set(v) {
v = v.trim();
if (parsers.hasVarFunc(v)) {
this._setProperty(property, v);
} else {
const val = parse(v);
if (typeof val === "string") {
const priority = this._priorities.get(property) ?? "";
this._setProperty(property, val, priority);
}
}
},
get() {
return this.getPropertyValue(property);
},
enumerable: true,
configurable: true
};
/**
* Parses the -webkit-text-fill-color property value.
*
* @param {string} v - The value to parse.
* @returns {string|undefined} The parsed value or undefined if invalid.
*/
function parse(v) {
if (v === "") {
return v;
}
const value = parsers.parsePropertyValue(property, v);
if (Array.isArray(value) && value.length === 1) {
return parsers.resolveColorValue(value);
} else if (typeof value === "string") {
return value;
}
return undefined;
}
module.exports = {
descriptor,
parse,
property
};
"use strict";
const parsers = require("../helpers/css-values");
const property = "-webkit-text-stroke-color";
const descriptor = {
set(v) {
v = v.trim();
if (parsers.hasVarFunc(v)) {
this._setProperty(property, v);
} else {
const val = parse(v);
if (typeof val === "string") {
const priority = this._priorities.get(property) ?? "";
this._setProperty(property, val, priority);
}
}
},
get() {
return this.getPropertyValue(property);
},
enumerable: true,
configurable: true
};
/**
* Parses the -webkit-text-stroke-color property value.
*
* @param {string} v - The value to parse.
* @returns {string|undefined} The parsed value or undefined if invalid.
*/
function parse(v) {
if (v === "") {
return v;
}
const value = parsers.parsePropertyValue(property, v);
if (Array.isArray(value) && value.length === 1) {
return parsers.resolveColorValue(value);
} else if (typeof value === "string") {
return value;
}
return undefined;
}
module.exports = {
descriptor,
parse,
property
};

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