Skip to content

Commit

Permalink
Honor not in @supports
Browse files Browse the repository at this point in the history
  • Loading branch information
nzakas committed Jan 21, 2025
1 parent a4a6194 commit 5f1f770
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 19 deletions.
9 changes: 8 additions & 1 deletion docs/rules/baseline.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ a {
/* invalid - property value doesn't match @supports indicator */
@supports (accent-color: auto) {
a {
accent-color: red;
accent-color: abs(20% - 10px);
}
}

Expand All @@ -51,6 +51,13 @@ a {
accent-color: auto;
}
}

/* invalid - @supports says that this property isn't available */
@supports not (accent-color: auto) {
a {
accent-color: auto;
}
}
```

### Options
Expand Down
66 changes: 48 additions & 18 deletions src/rules/baseline.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,17 @@ class SupportsRule {
/**
* Adds a property to the rule.
* @param {string} property The name of the property.
* @returns {void}
* @returns {SupportedProperty} The supported property object.
*/
addProperty(property) {
this.#properties.set(property, new SupportedProperty(property));
if (this.#properties.has(property)) {
return this.#properties.get(property);
}

const supportedProperty = new SupportedProperty(property);
this.#properties.set(property, supportedProperty);

return supportedProperty;
}

/**
Expand Down Expand Up @@ -404,28 +411,42 @@ export default {
supportsRules.push(new SupportsRule());
},

"Atrule[name=supports] SupportsDeclaration > Declaration"(node) {
"Atrule[name=supports] > AtrulePrelude > Condition"(node) {
const supportsRule = supportsRules.last();

if (!supportsRule.hasProperty(node.property)) {
supportsRule.addProperty(node.property);
}
for (let i = 0; i < node.children.length; i++) {
const conditionChild = node.children[i];

// for now we can only check identifiers
node.value.children.forEach(child => {
if (child.type === "Identifier") {
supportsRule
.getProperty(node.property)
.addIdentifier(child.name);
return;
// if a SupportsDeclaration is preceded by "not" then we don't consider it
if (
conditionChild.type === "Identifier" &&
conditionChild.name === "not"
) {
i++;
continue;
}

if (child.type === "Function") {
supportsRule
.getProperty(node.property)
.addFunction(child.name);
// save the supported properties and values for this at-rule
if (conditionChild.type === "SupportsDeclaration") {
const { declaration } = conditionChild;
const property = declaration.property;
const supportedProperty =
supportsRule.addProperty(property);

declaration.value.children.forEach(child => {
if (child.type === "Identifier") {
supportedProperty.addIdentifier(child.name);
return;
}

if (child.type === "Function") {
supportedProperty.addFunction(child.name);
}
});

continue;
}
});
}
},

"Rule > Block > Declaration"(node) {
Expand Down Expand Up @@ -462,6 +483,15 @@ export default {
availability,
},
});

/*
* If the property isn't in baseline, then we don't go
* on to check the values. If the property itself isn't
* in baseline then chances are the values aren't too,
* and there's no need to report multiple errors for the
* same property.
*/
return;
}
}

Expand Down
16 changes: 16 additions & 0 deletions tests/rules/baseline.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,22 @@ ruleTester.run("baseline", rule, {
},
],
},
{
code: "@supports not (accent-color: auto) { a { accent-color: auto } }",
errors: [
{
messageId: "notBaselineProperty",
data: {
property: "accent-color",
availability: "widely",
},
line: 1,
column: 42,
endLine: 1,
endColumn: 54,
},
],
},
{
code: "a { width: abs(20% - 100px); }",
errors: [
Expand Down

0 comments on commit 5f1f770

Please sign in to comment.