summaryrefslogtreecommitdiff
path: root/school/node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js
diff options
context:
space:
mode:
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.js114
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;