fix: Pasting gradient into color field breaks CSS parser (#4593)

## Description

closes #4578

## Steps for reproduction

1. click button
2. expect xyz

## Code Review

- [ ] hi @kof, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
0000)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
This commit is contained in:
Ivan Starkov authored and GitHub committed 2024-12-16 15:46:20 +01:00
1 parent c779a8ec9e
commit 916d59f1ab
2 files changed
+34 -9

No files matched your search

@@ -1,10 +1,9 @@
import { parse } from "css-tree";
import type {
StyleProperty,
StyleValue,
InvalidValue,
} from "@webstudio-is/css-engine";
import { units, parseCssValue } from "@webstudio-is/css-data";
import { units, parseCssValue, cssTryParseValue } from "@webstudio-is/css-data";
import type { IntermediateStyleValue } from "./css-value-input";
import { evaluateMath } from "./evaluate-math";
import { toKebabCase } from "../keyword-utils";
@@ -13,7 +12,8 @@ const unitsList = Object.values(units).flat();
export const parseIntermediateOrInvalidValue = (
property: StyleProperty,
styleValue: IntermediateStyleValue | InvalidValue
styleValue: IntermediateStyleValue | InvalidValue,
originalValue?: string
): StyleValue => {
let value = styleValue.value.trim();
if (value.endsWith(";")) {
@@ -22,7 +22,15 @@ export const parseIntermediateOrInvalidValue = (
// When user enters a number, we don't know if its a valid unit value,
// so we are going to parse it with a unit and if its not invalid - we take it.
const ast = parse(value, { context: "value" });
const ast = cssTryParseValue(value);
if (ast === undefined) {
return {
type: "invalid",
value: originalValue ?? value,
};
}
const node =
"children" in ast && ast.children?.size === 1
? ast.children.first
@@ -119,16 +127,20 @@ export const parseIntermediateOrInvalidValue = (
// Users often mistype comma instead of dot and we want to be tolerant to that.
// We need to try replace comma with dot and then try all parsing options again.
if (value.includes(",")) {
return parseIntermediateOrInvalidValue(property, {
...styleValue,
value: value.replace(/,/g, "."),
});
return parseIntermediateOrInvalidValue(
property,
{
...styleValue,
value: value.replace(/,/g, "."),
},
originalValue ?? value
);
}
// If we are here it means that value can be Valid but our parseCssValue can't handle it
// or value is invalid
return {
type: "invalid",
value: value,
value: originalValue ?? value,
};
};
@@ -638,3 +638,16 @@ test("parse z-index", () => {
unit: "number",
});
});
test("parse color", () => {
expect(
parseIntermediateOrInvalidValue("color", {
type: "intermediate",
value: "linear-gradient(red, blue)",
unit: undefined,
})
).toEqual({
type: "invalid",
value: "linear-gradient(red, blue)",
});
});