diff options
Diffstat (limited to 'school/node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js')
-rw-r--r-- | school/node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/school/node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js b/school/node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js new file mode 100644 index 0000000..63e749d --- /dev/null +++ b/school/node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js @@ -0,0 +1,114 @@ +"use strict"; +const cssom = require("cssom"); +const defaultStyleSheet = require("../../browser/default-stylesheet"); +const { matchesDontThrow } = require("./selectors"); + +const { forEach, indexOf } = Array.prototype; + +let parsedDefaultStyleSheet; + +// Properties for which getResolvedValue is implemented. This is less than +// every supported property. +// https://drafts.csswg.org/indexes/#properties +exports.propertiesWithResolvedValueImplemented = { + __proto__: null, + + // https://drafts.csswg.org/css2/visufx.html#visibility + visibility: { + inherited: true, + initial: "visible", + computedValue: "as-specified" + } +}; + +exports.forEachMatchingSheetRuleOfElement = (elementImpl, handleRule) => { + function handleSheet(sheet) { + forEach.call(sheet.cssRules, rule => { + if (rule.media) { + if (indexOf.call(rule.media, "screen") !== -1) { + forEach.call(rule.cssRules, innerRule => { + if (matches(innerRule, elementImpl)) { + handleRule(innerRule); + } + }); + } + } else if (matches(rule, elementImpl)) { + handleRule(rule); + } + }); + } + + if (!parsedDefaultStyleSheet) { + parsedDefaultStyleSheet = cssom.parse(defaultStyleSheet); + } + + handleSheet(parsedDefaultStyleSheet); + forEach.call(elementImpl._ownerDocument.styleSheets._list, handleSheet); +}; + +function matches(rule, element) { + return matchesDontThrow(element, rule.selectorText); +} + +// 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) { + let value = ""; + + exports.forEachMatchingSheetRuleOfElement(element, rule => { + const propertyValue = rule.style.getPropertyValue(property); + // getPropertyValue returns "" if the property is not found + if (propertyValue !== "") { + value = propertyValue; + } + }); + + const inlineValue = element.style.getPropertyValue(property); + if (inlineValue !== "" && inlineValue !== null) { + value = inlineValue; + } + + return value; +} + +// https://drafts.csswg.org/css-cascade-4/#specified-value +function getSpecifiedValue(element, property) { + const cascade = getCascadedPropertyValue(element, property); + + if (cascade !== "") { + return cascade; + } + + // Defaulting + const { initial, inherited } = exports.propertiesWithResolvedValueImplemented[property]; + if (inherited && element.parentElement !== null) { + return getComputedValue(element.parentElement, property); + } + + // root element without parent element or inherited property + return initial; +} + +// https://drafts.csswg.org/css-cascade-4/#computed-value +function getComputedValue(element, property) { + const { computedValue } = exports.propertiesWithResolvedValueImplemented[property]; + if (computedValue === "as-specified") { + return getSpecifiedValue(element, property); + } + + throw new TypeError(`Internal error: unrecognized computed value instruction '${computedValue}'`); +} + +// https://drafts.csswg.org/cssom/#resolved-value +// Only implements `visibility` +exports.getResolvedValue = (element, property) => { + // Determined for special case properties, none of which are implemented here. + // So we skip to "any other property: The resolved value is the computed value." + return getComputedValue(element, property); +}; + +exports.SHADOW_DOM_PSEUDO_REGEXP = /^::(?:part|slotted)\(/i; |