Skip to content

Commit

Permalink
fix: Pasting gradient into color field breaks CSS parser (#4593)
Browse files Browse the repository at this point in the history
## 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
  • Loading branch information
istarkov authored Dec 16, 2024
1 parent c779a8e commit 916d59f
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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(";")) {
Expand All @@ -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
Expand Down Expand Up @@ -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,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -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)",
});
});

0 comments on commit 916d59f

Please sign in to comment.