mirror of
https://github.com/webstudio-is/webstudio.git
synced 2025-03-15 09:45:09 +00:00
experimental: improve color: currentcolor behavior (#3045)
Here slightly changed how color: currentcolor is treated. Before on color property inherited value was used. Though this didn't handle the case when inherited value is also currentcolor. Here found note in another spec which says color: currentcolor should be interpreted same as inherit keyword.
This commit is contained in:
apps/builder/app/shared
@ -38,18 +38,15 @@ test("use cascaded style when specified and fallback to initial value", () => {
|
||||
};
|
||||
// cascaded property
|
||||
expect(
|
||||
getComputedStyleDecl({ model, styleSelector, property: "width" })
|
||||
.computedValue
|
||||
getComputedStyleDecl({ model, styleSelector, property: "width" }).usedValue
|
||||
).toEqual({ type: "unit", unit: "px", value: 10 });
|
||||
// initial for not inherited property
|
||||
expect(
|
||||
getComputedStyleDecl({ model, styleSelector, property: "height" })
|
||||
.computedValue
|
||||
getComputedStyleDecl({ model, styleSelector, property: "height" }).usedValue
|
||||
).toEqual({ type: "keyword", value: "auto" });
|
||||
// initial for inherited property
|
||||
expect(
|
||||
getComputedStyleDecl({ model, styleSelector, property: "color" })
|
||||
.computedValue
|
||||
getComputedStyleDecl({ model, styleSelector, property: "color" }).usedValue
|
||||
).toEqual({ type: "keyword", value: "black" });
|
||||
});
|
||||
|
||||
@ -70,8 +67,7 @@ test("support initial keyword", () => {
|
||||
instanceSelector: ["body"],
|
||||
};
|
||||
expect(
|
||||
getComputedStyleDecl({ model, styleSelector, property: "width" })
|
||||
.computedValue
|
||||
getComputedStyleDecl({ model, styleSelector, property: "width" }).usedValue
|
||||
).toEqual({ type: "keyword", value: "auto" });
|
||||
});
|
||||
|
||||
@ -115,13 +111,11 @@ test("support inherit keyword", () => {
|
||||
};
|
||||
// should inherit declared value
|
||||
expect(
|
||||
getComputedStyleDecl({ model, styleSelector, property: "width" })
|
||||
.computedValue
|
||||
getComputedStyleDecl({ model, styleSelector, property: "width" }).usedValue
|
||||
).toEqual({ type: "unit", unit: "px", value: 10 });
|
||||
// should inherit initial value as height is not inherited
|
||||
expect(
|
||||
getComputedStyleDecl({ model, styleSelector, property: "height" })
|
||||
.computedValue
|
||||
getComputedStyleDecl({ model, styleSelector, property: "height" }).usedValue
|
||||
).toEqual({ type: "keyword", value: "auto" });
|
||||
});
|
||||
|
||||
@ -164,13 +158,11 @@ test("support unset keyword", () => {
|
||||
};
|
||||
// when property is not inherited use initial value
|
||||
expect(
|
||||
getComputedStyleDecl({ model, styleSelector, property: "width" })
|
||||
.computedValue
|
||||
getComputedStyleDecl({ model, styleSelector, property: "width" }).usedValue
|
||||
).toEqual({ type: "keyword", value: "auto" });
|
||||
// when property is inherited use inherited value
|
||||
expect(
|
||||
getComputedStyleDecl({ model, styleSelector, property: "color" })
|
||||
.computedValue
|
||||
getComputedStyleDecl({ model, styleSelector, property: "color" }).usedValue
|
||||
).toEqual({ type: "keyword", value: "blue" });
|
||||
});
|
||||
|
||||
@ -202,13 +194,11 @@ test("inherit style from ancestors", () => {
|
||||
};
|
||||
// inherited value
|
||||
expect(
|
||||
getComputedStyleDecl({ model, styleSelector, property: "color" })
|
||||
.computedValue
|
||||
getComputedStyleDecl({ model, styleSelector, property: "color" }).usedValue
|
||||
).toEqual({ type: "keyword", value: "blue" });
|
||||
// not inherited value
|
||||
expect(
|
||||
getComputedStyleDecl({ model, styleSelector, property: "width" })
|
||||
.computedValue
|
||||
getComputedStyleDecl({ model, styleSelector, property: "width" }).usedValue
|
||||
).toEqual({ type: "keyword", value: "auto" });
|
||||
});
|
||||
|
||||
@ -247,20 +237,12 @@ test("support currentcolor keyword", () => {
|
||||
};
|
||||
expect(
|
||||
getComputedStyleDecl({ model, styleSelector, property: "borderTopColor" })
|
||||
).toEqual(
|
||||
expect.objectContaining({
|
||||
computedValue: { type: "keyword", value: "currentcolor" },
|
||||
usedValue: { type: "keyword", value: "blue" },
|
||||
})
|
||||
);
|
||||
.usedValue
|
||||
).toEqual({ type: "keyword", value: "blue" });
|
||||
expect(
|
||||
getComputedStyleDecl({ model, styleSelector, property: "backgroundColor" })
|
||||
).toEqual(
|
||||
expect.objectContaining({
|
||||
computedValue: { type: "keyword", value: "currentColor" },
|
||||
usedValue: { type: "keyword", value: "blue" },
|
||||
})
|
||||
);
|
||||
.usedValue
|
||||
).toEqual({ type: "keyword", value: "blue" });
|
||||
});
|
||||
|
||||
test("in color property currentcolor is inherited", () => {
|
||||
@ -277,25 +259,27 @@ test("in color property currentcolor is inherited", () => {
|
||||
property: "color",
|
||||
value: { type: "keyword", value: "currentcolor" },
|
||||
},
|
||||
{
|
||||
breakpointId: "base",
|
||||
styleSourceId: "level3Local",
|
||||
property: "color",
|
||||
value: { type: "keyword", value: "currentcolor" },
|
||||
},
|
||||
];
|
||||
const model: StyleObjectModel = {
|
||||
styleSourcesByInstanceId: new Map([
|
||||
["level3", ["level3Local"]],
|
||||
["level2", ["level2Local"]],
|
||||
["level1", ["level1Local"]],
|
||||
]),
|
||||
styleByStyleSourceId: getStyleByStyleSourceId(styles),
|
||||
};
|
||||
const styleSelector: StyleSelector = {
|
||||
instanceSelector: ["level2", "level1"],
|
||||
instanceSelector: ["level3", "level2", "level1"],
|
||||
};
|
||||
expect(
|
||||
getComputedStyleDecl({ model, styleSelector, property: "color" })
|
||||
).toEqual(
|
||||
expect.objectContaining({
|
||||
computedValue: { type: "keyword", value: "currentcolor" },
|
||||
usedValue: { type: "keyword", value: "blue" },
|
||||
})
|
||||
);
|
||||
getComputedStyleDecl({ model, styleSelector, property: "color" }).usedValue
|
||||
).toEqual({ type: "keyword", value: "blue" });
|
||||
});
|
||||
|
||||
test("in root color property currentcolor is initial", () => {
|
||||
@ -315,11 +299,6 @@ test("in root color property currentcolor is initial", () => {
|
||||
instanceSelector: ["body"],
|
||||
};
|
||||
expect(
|
||||
getComputedStyleDecl({ model, styleSelector, property: "color" })
|
||||
).toEqual(
|
||||
expect.objectContaining({
|
||||
computedValue: { type: "keyword", value: "currentcolor" },
|
||||
usedValue: { type: "keyword", value: "black" },
|
||||
})
|
||||
);
|
||||
getComputedStyleDecl({ model, styleSelector, property: "color" }).usedValue
|
||||
).toEqual({ type: "keyword", value: "black" });
|
||||
});
|
||||
|
@ -108,20 +108,18 @@ export const getComputedStyleDecl = ({
|
||||
styleSelector: StyleSelector;
|
||||
property: Property;
|
||||
}): {
|
||||
computedValue: StyleValue;
|
||||
usedValue: StyleValue;
|
||||
} => {
|
||||
const { instanceSelector } = styleSelector;
|
||||
const propertyData = properties[property];
|
||||
const inherited = propertyData.inherited;
|
||||
const initialValue = propertyData.initial;
|
||||
let inheritedValue: StyleValue = initialValue;
|
||||
let computedValue: StyleValue = initialValue;
|
||||
|
||||
// start computing from the root
|
||||
for (const instanceId of Array.from(instanceSelector).reverse()) {
|
||||
// https://drafts.csswg.org/css-cascade-5/#inheriting
|
||||
inheritedValue = computedValue;
|
||||
const inheritedValue: StyleValue = computedValue;
|
||||
|
||||
// https://drafts.csswg.org/css-cascade-5/#cascaded
|
||||
const { cascadedValue } = getCascadedValue({ model, instanceId, property });
|
||||
@ -132,7 +130,12 @@ export const getComputedStyleDecl = ({
|
||||
// https://drafts.csswg.org/css-cascade-5/#defaulting-keywords
|
||||
if (matchKeyword(cascadedValue, "initial")) {
|
||||
specifiedValue = initialValue;
|
||||
} else if (matchKeyword(cascadedValue, "inherit")) {
|
||||
} else if (
|
||||
matchKeyword(cascadedValue, "inherit") ||
|
||||
// treat currentcolor as inherit when used on color property
|
||||
// https://www.w3.org/TR/css-color-3/#currentColor-def
|
||||
(property === "color" && matchKeyword(cascadedValue, "currentcolor"))
|
||||
) {
|
||||
specifiedValue = inheritedValue;
|
||||
} else if (matchKeyword(cascadedValue, "unset")) {
|
||||
if (inherited) {
|
||||
@ -158,17 +161,13 @@ export const getComputedStyleDecl = ({
|
||||
let usedValue: StyleValue = computedValue;
|
||||
// https://drafts.csswg.org/css-color-4/#resolving-other-colors
|
||||
if (matchKeyword(computedValue, "currentcolor")) {
|
||||
if (property === "color") {
|
||||
usedValue = inheritedValue;
|
||||
} else {
|
||||
const currentColor = getComputedStyleDecl({
|
||||
model,
|
||||
styleSelector,
|
||||
property: "color",
|
||||
});
|
||||
usedValue = currentColor.usedValue;
|
||||
}
|
||||
const currentColor = getComputedStyleDecl({
|
||||
model,
|
||||
styleSelector,
|
||||
property: "color",
|
||||
});
|
||||
usedValue = currentColor.usedValue;
|
||||
}
|
||||
|
||||
return { computedValue, usedValue };
|
||||
return { usedValue };
|
||||
};
|
||||
|
Reference in New Issue
Block a user