commit 0c6ed1566edb833553a755ec04e3751f87c60fa2
parent fc08283ebd2f736ee75d47c5491707fd76ce4ef7
Author: Daniil Sakhapov <sakhapov@chromium.org>
Date: Tue, 21 Oct 2025 10:30:46 +0000
Bug 1994821 [wpt PR 55485] - Implement border-shape interpolation type, a=testonly
Automatic update from web-platform-tests
Implement border-shape interpolation type
This CL implements CSS transitions and animations for the `border-shape`
property by introducing a new `CSSBorderShapeInterpolationType` that
reuses the existing basic shape and shape interpolation infrastructure.
The interpolation logic handles both single and dual-shape syntax by
converting the outer and inner shapes from `StyleBorderShape` into lists
of basic shapes, and then delegates interpolation to the shared list and
shape interpolation helpers.
- Introduces `CSSBorderShapeInterpolationType` and registers it for
`border-shape`.
- Refactors the interpolation pipeline to use property-specific
subclasses for non-interpolable values, mirroring the approach used
for `clip-path` and `shape-outside`.
- Fixes CSSValueFromComputedStyleInternal to produce values in
accordance with what ParseSingleValue produces.
Bug: 450326418
Change-Id: Ib98df13ecdf741b1797027bf438e9cd3bacb3b6a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7036598
Commit-Queue: Daniil Sakhapov <sakhapov@chromium.org>
Reviewed-by: Kevin Ellis <kevers@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1531016}
--
wpt-commits: c77b44757d9cdcf440951a2fb9d7e21aa465f9dd
wpt-pr: 55485
Diffstat:
1 file changed, 91 insertions(+), 0 deletions(-)
diff --git a/testing/web-platform/tests/css/css-borders/tentative/border-shape/border-shape-animation.tentative.html b/testing/web-platform/tests/css/css-borders/tentative/border-shape/border-shape-animation.tentative.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>border-shape interpolation</title>
+<link rel="help" href="https://drafts.csswg.org/css-borders-4/#border-shape">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/interpolation-testcommon.js"></script>
+
+<body>
+ <script>
+ // // Outer and inner shapes are identical when only one value is specified.
+ // test_interpolation({
+ // property: 'border-shape',
+ // from: 'circle(10px at 10px 10px)',
+ // to: 'circle(30px at 30px 30px)',
+ // }, [
+ // { at: 0, expect: 'circle(10px at 10px 10px)' },
+ // { at: 0.5, expect: 'circle(20px at 20px 20px)' },
+ // { at: 1, expect: 'circle(30px at 30px 30px)' },
+ // ]);
+
+ // // Explicit inner shape animates alongside the outer shape.
+ // test_interpolation({
+ // property: 'border-shape',
+ // from: 'circle(20px at 10px 20px) circle(10px at 10px 20px)',
+ // to: 'circle(40px at 30px 40px) circle(20px at 30px 40px)',
+ // }, [
+ // { at: 0, expect: 'circle(20px at 10px 20px) circle(10px at 10px 20px)' },
+ // { at: 0.5, expect: 'circle(30px at 20px 30px) circle(15px at 20px 30px)' },
+ // { at: 1, expect: 'circle(40px at 30px 40px) circle(20px at 30px 40px)' },
+ // ]);
+
+ // // With different shapes, we interpolate discretely.
+ // test_interpolation({
+ // property: 'border-shape',
+ // behavior: 'allow-discrete',
+ // from: 'circle(20px at 10px 20px) circle(10px at 10px 20px)',
+ // to: 'polygon(10px 10px, 100px 10px, 10px 100px) polygon(20px 20px, 80px 20px, 20px 80px)',
+ // }, [
+ // { at: 0, expect: 'circle(20px at 10px 20px) circle(10px at 10px 20px)' },
+ // { at: 1, expect: 'polygon(10px 10px, 100px 10px, 10px 100px) polygon(20px 20px, 80px 20px, 20px 80px)' },
+ // ]);
+
+ // With different coordinate boxes, we interpolate discretely.
+ test_interpolation({
+ property: 'border-shape',
+ behavior: 'allow-discrete',
+ from: 'circle() border-box circle() content-box',
+ to: 'circle() content-box circle() border-box',
+ }, [
+ { at: 0, expect: 'circle() border-box circle() content-box' },
+ { at: 1, expect: 'circle() content-box circle() border-box' },
+ ]);
+
+ // // With the same coordinate boxes, we interpolate normally.
+ // test_interpolation({
+ // property: 'border-shape',
+ // from: 'circle(20px at 10px 20px) border-box circle(10px at 10px 20px) border-box',
+ // to: 'circle(40px at 30px 40px) border-box circle(20px at 30px 40px) border-box',
+ // }, [
+ // { at: 0, expect: 'circle(20px at 10px 20px) circle(10px at 10px 20px)' },
+ // { at: 0.5, expect: 'circle(30px at 20px 30px) circle(15px at 20px 30px)' },
+ // { at: 1, expect: 'circle(40px at 30px 40px) circle(20px at 30px 40px)' },
+ // ]);
+
+ // // With different number of shapes, inner shape becomes identical to outer shape.
+ // test_interpolation({
+ // property: 'border-shape',
+ // from: 'circle(20px at 10px 20px)',
+ // to: 'circle(40px at 30px 40px) circle(40px at 30px 40px)',
+ // }, [
+ // { at: 0, expect: 'circle(20px at 10px 20px) circle(20px at 10px 20px)' },
+ // { at: 0.5, expect: 'circle(30px at 20px 30px) circle(30px at 20px 30px)' },
+ // { at: 1, expect: 'circle(40px at 30px 40px) circle(40px at 30px 40px)' },
+ // ]);
+
+ // // From none to a shape, we interpolate discretely.
+ // test_interpolation({
+ // property: 'border-shape',
+ // behavior: 'allow-discrete',
+ // from: 'none',
+ // to: 'circle() circle()',
+ // }, [
+ // { at: 0, expect: 'none' },
+ // { at: 0.5, expect: 'none' },
+ // { at: 1, expect: 'circle() circle()' },
+ // ]);
+ </script>
+</body>
+\ No newline at end of file