Skip to content

Commit dfda991

Browse files
BorisChioumoz-wptsync-bot
authored andcommitted
Convert position into length-percentage for basic shapes.
Per the spec issue: w3c/csswg-drafts#8695, we should convert the position components into `<length-percentage>` for the specified values of `at <position>`, for basic shapes. Also, update shape-outside/values/support/parsing-utils.js a little bit to make sure we convert the absolute length into px if it is in `calc()`, for the specified values. And remove calc() if possible for computed values. Differential Revision: https://phabricator.services.mozilla.com/D188780 bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1823475 gecko-commit: a3e9e98d521c05808ed81bc5e49e9b1f181fa388 gecko-reviewers: emilio
1 parent af7a934 commit dfda991

File tree

3 files changed

+88
-65
lines changed

3 files changed

+88
-65
lines changed

css/css-shapes/basic-shape-circle-ellipse-serialization.html

+11-12
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
"ellipse(closest-side farthest-side)");
3636

3737

38-
checkEquals("circle(at top 0% right 5px)", "circle(at right 5px top 0%)");
39-
checkEquals("ellipse(at top 0% right 10px)", "ellipse(at right 10px top 0%)");
38+
checkEquals("circle(at top 0% right 5px)", "circle(at calc(100% - 5px) 0%)");
39+
checkEquals("ellipse(at top 0% right 10px)", "ellipse(at calc(100% - 10px) 0%)");
4040
// Remove defaults like closest-side
4141
checkEquals("circle(closest-side at center)",
4242
"circle(at 50% 50%)");
@@ -57,20 +57,19 @@
5757
checkEquals("ellipse(closest-side 10% at 50% 50%)",
5858
"ellipse(closest-side 10% at 50% 50%)");
5959

60-
// Don't transform nonzero lengths
60+
// Transform to <length-percentage>.
6161
checkEquals("circle(at right 5px bottom 10px)",
62-
"circle(at right 5px bottom 10px)");
62+
"circle(at calc(100% - 5px) calc(100% - 10px))");
6363
checkEquals("ellipse(at right 5px bottom 10px)",
64-
"ellipse(at right 5px bottom 10px)");
64+
"ellipse(at calc(100% - 5px) calc(100% - 10px))");
6565

66-
// Convert keyword-percentage pairs to plain percentages
67-
// Convert zero lengths to 0%
68-
checkEquals("circle(at right 5% top 0px)", "circle(at 95% 0%)");
69-
checkEquals("ellipse(at right 5% top 0px)", "ellipse(at 95% 0%)");
66+
// Don't convert zero lengths to 0%
67+
checkEquals("circle(at right 5% top 0px)", "circle(at calc(95%) 0px)");
68+
checkEquals("ellipse(at right 5% top 0px)", "ellipse(at calc(95%) 0px)");
7069

71-
// Don't transform calcs
70+
// Transform calcs
7271
checkEquals("circle(at right calc(10% + 5px) bottom calc(10% + 5px))",
73-
"circle(at right calc(10% + 5px) bottom calc(10% + 5px))");
72+
"circle(at calc(90% - 5px) calc(90% - 5px))");
7473
checkEquals("ellipse(at right calc(10% + 5px) bottom calc(10% + 5px))",
75-
"ellipse(at right calc(10% + 5px) bottom calc(10% + 5px))");
74+
"ellipse(at calc(90% - 5px) calc(90% - 5px))");
7675
</script>

css/css-shapes/parsing/shape-outside-valid-position.html

+18-18
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,32 @@
55
<title>CSS Shapes Module Level 1: parsing shape-outside with valid position values</title>
66
<link rel="author" title="Eric Willigers" href="mailto:[email protected]">
77
<link rel="help" href="https://drafts.csswg.org/css-values-4/#typedef-position">
8+
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/8695">
89
<meta name="assert" content="shape-outside positions support the full '<position>' grammar.">
910
<script src="/resources/testharness.js"></script>
1011
<script src="/resources/testharnessreport.js"></script>
1112
<script src="/css/support/parsing-testcommon.js"></script>
1213
</head>
1314
<body>
1415
<script>
15-
// First serialization is being returned by Firefox/Edge, second by Blink/WebKit.
16-
test_valid_value("shape-outside", "circle(at 10%)", ["circle(at 10%)", "circle(at 10% 50%)"]);
16+
test_valid_value("shape-outside", "circle(at 10%)", "circle(at 10% 50%)");
1717
test_valid_value("shape-outside", "circle(at 20% 30px)");
18-
test_valid_value("shape-outside", "circle(at 30px center)", ["circle(at 30px center)", "circle(at 30px 50%)"]);
19-
test_valid_value("shape-outside", "circle(at 40px top)", ["circle(at 40px top)", "circle(at 40px 0%)"]);
20-
test_valid_value("shape-outside", "circle(at bottom 10% right 20%)", ["circle(at bottom 10% right 20%)", "circle(at 80% 90%)"]);
21-
test_valid_value("shape-outside", "circle(at bottom right)", ["circle(at bottom right)", "circle(at 100% 100%)"]);
22-
test_valid_value("shape-outside", "circle(at center)", ["circle(at center)", "circle(at 50% 50%)"]);
23-
test_valid_value("shape-outside", "circle(at center 50px)", ["circle(at center 50px)", "circle(at 50% 50px)"]);
24-
test_valid_value("shape-outside", "circle(at center bottom)", ["circle(at center bottom)", "circle(at 50% 100%)"]);
25-
test_valid_value("shape-outside", "circle(at center center)", ["circle(at center center)", "circle(at 50% 50%)"]);
26-
test_valid_value("shape-outside", "circle(at center left)", ["circle(at center left)", "circle(at 0% 50%)"]);
27-
test_valid_value("shape-outside", "circle(at left)", ["circle(at left)", "circle(at 0% 50%)"]);
28-
test_valid_value("shape-outside", "circle(at left bottom)", ["circle(at left bottom)", "circle(at 0% 100%)"]);
29-
test_valid_value("shape-outside", "circle(at left center)", ["circle(at left center)", "circle(at 0% 50%)"]);
30-
test_valid_value("shape-outside", "circle(at right 40%)", ["circle(at right 40%)", "circle(at 100% 40%)"]);
31-
test_valid_value("shape-outside", "circle(at right 30% top 60px)", ["circle(at right 30% top 60px)", "circle(at 70% 60px)"]);
32-
test_valid_value("shape-outside", "circle(at top)", ["circle(at top)", "circle(at 50% 0%)"]);
33-
test_valid_value("shape-outside", "circle(at top center)", ["circle(at top center)", "circle(at 50% 0%)"]);
18+
test_valid_value("shape-outside", "circle(at 30px center)", "circle(at 30px 50%)");
19+
test_valid_value("shape-outside", "circle(at 40px top)", "circle(at 40px 0%)");
20+
test_valid_value("shape-outside", "circle(at bottom 10% right 20%)", "circle(at calc(80%) calc(90%))");
21+
test_valid_value("shape-outside", "circle(at bottom right)", "circle(at 100% 100%)");
22+
test_valid_value("shape-outside", "circle(at center)", "circle(at 50% 50%)");
23+
test_valid_value("shape-outside", "circle(at center 50px)", "circle(at 50% 50px)");
24+
test_valid_value("shape-outside", "circle(at center bottom)", "circle(at 50% 100%)");
25+
test_valid_value("shape-outside", "circle(at center center)", "circle(at 50% 50%)");
26+
test_valid_value("shape-outside", "circle(at center left)", "circle(at 0% 50%)");
27+
test_valid_value("shape-outside", "circle(at left)", "circle(at 0% 50%)");
28+
test_valid_value("shape-outside", "circle(at left bottom)", "circle(at 0% 100%)");
29+
test_valid_value("shape-outside", "circle(at left center)", "circle(at 0% 50%)");
30+
test_valid_value("shape-outside", "circle(at right 40%)", "circle(at 100% 40%)");
31+
test_valid_value("shape-outside", "circle(at right 30% top 60px)", "circle(at calc(70%) 60px)");
32+
test_valid_value("shape-outside", "circle(at top)", "circle(at 50% 0%)");
33+
test_valid_value("shape-outside", "circle(at top center)","circle(at 50% 0%)");
3434
</script>
3535
</body>
3636
</html>

css/css-shapes/shape-outside/values/support/parsing-utils.js

+59-35
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,14 @@ function buildTestCases(testCases, testType) {
129129
return results;
130130
}
131131

132+
function isAbsoluteLength(unit) {
133+
return unit == "cm" || unit == "mm" || unit == "Q" || unit == "in" ||
134+
unit == "pt" || unit == "pc" || unit == "px";
135+
}
132136

133137
function buildPositionTests(shape, valid, type, units) {
134138
var results = new Array();
135-
var convert = type.indexOf('computed') != -1 ? true : false;
139+
var is_computed = type.indexOf('computed') != -1 ? true : false;
136140

137141
if(Object.prototype.toString.call( units ) === '[object Array]') {
138142
units.forEach(function(unit) {
@@ -144,23 +148,47 @@ function buildPositionTests(shape, valid, type, units) {
144148
validPositions.forEach(function(test) {
145149
var testCase = [], testName, actual, expected;
146150
// skip if this isn't explicitly testing length units
147-
if( !(type.indexOf('lengthUnit') != -1 && test[0].indexOf("u1") == -1)) {
151+
if (!(type.indexOf('lengthUnit') != -1 && test[0].indexOf("u1") == -1)) {
148152
// actual
149153
actual = shape + '(at ' + setUnit(test[0], false, units) +')';
150154

155+
let position = test[1];
156+
let convert = is_computed;
157+
if (!is_computed) {
158+
// For specified values.
159+
// Note: "[convert]" tag is used only for the specified
160+
// value.
161+
if (position.includes('[convert]')) {
162+
// We should convert the absolute length into the
163+
// canonical unit in calc(), for specified values.
164+
// e.g.
165+
// 1. "circle(at 1pt 50%)" serializes as
166+
// "circle(at 1pt 50%)".
167+
// 2. "circle(at calc(1pt) 50%)" serializes as
168+
// "circle(at calc(1.33px) 50%)".
169+
convert = isAbsoluteLength(units);
170+
}
171+
} else if (test.length == 3) {
172+
// Use the 3rd element as the expected computed value.
173+
position = test[2];
174+
}
175+
176+
// Remove the tag if there is.
177+
position = position.replace('[convert] ', '');
178+
151179
// expected
152-
// if(convert && shape == 'circle')
153-
// expected = shape + '(at ' + setUnit(test[1], convert, units) +')';
154-
// else if(convert && shape == 'ellipse')
155-
// expected = shape + '(at ' + setUnit(test[1], convert, units) +')';
156-
// else
157-
expected = shape + '(at ' + setUnit(test[1], convert, units) +')';
180+
// if(convert && shape == 'circle')
181+
// expected = shape + '(at ' + setUnit(test[1], convert, units) +')';
182+
// else if(convert && shape == 'ellipse')
183+
// expected = shape + '(at ' + setUnit(test[1], convert, units) +')';
184+
// else
185+
expected = shape + '(at ' + setUnit(position, convert, units) +')';
158186

159187
// name
160188
if (type == 'lengthUnit + inline')
161189
testName = 'test unit (inline): ' + units +' - '+ actual;
162190
else if (type == 'lengthUnit + computed')
163-
testName = 'test unit (computed): ' + units +' - '+ actual;
191+
testName = 'test unit (computed): ' + units +' - '+ actual;
164192
else
165193
testName = (actual + ' serializes as ' + expected +' - '+ type);
166194

@@ -549,39 +577,35 @@ var validPositions = [
549577
////// [ keyword length | keyword length], [ keyword length | keyword percent] x 5 keywords
550578
["left 50% top 50%", "50% 50%"],
551579
["left 50% top 50u1", "50% 50u1"],
552-
["left 50% bottom 70%", "50% 30%"],
553-
["left 50% bottom 70u1", "left 50% bottom 70u1"],
580+
["left 50% bottom 70%", "50% calc(30%)", "50% 30%"],
581+
["left 50% bottom 70u1", "[convert] 50% calc(100% - 70u1)"],
554582
["left 50u1 top 50%", "50u1 50%"],
555583
["left 50u1 top 50u1", "50u1 50u1"],
556-
["left 50u1 bottom 70%", "50u1 30%"],
557-
["left 50u1 bottom 70u1", "left 50u1 bottom 70u1"],
584+
["left 50u1 bottom 70%", "50u1 calc(30%)", "50u1 30%"],
558585

559586
["top 50% left 50%", "50% 50%"],
560587
["top 50% left 50u1", "50u1 50%"],
561-
["top 50% right 80%", "20% 50%"],
562-
["top 50% right 80u1", "right 80u1 top 50%"],
588+
["top 50% right 80%", "calc(20%) 50%", "20% 50%"],
589+
["top 50% right 80u1", "[convert] calc(100% - 80u1) 50%"],
563590
["top 50u1 left 50%", "50% 50u1"],
564591
["top 50u1 left 50u1", "50u1 50u1"],
565-
["top 50u1 right 80%", "20% 50u1"],
566-
["top 50u1 right 80u1", "right 80u1 top 50u1"],
567-
568-
["bottom 70% left 50%", "50% 30%"],
569-
["bottom 70% left 50u1", "50u1 30%"],
570-
["bottom 70% right 80%", "20% 30%"],
571-
["bottom 70% right 80u1", "right 80u1 top 30%"],
572-
["bottom 70u1 left 50%", "left 50% bottom 70u1"],
573-
["bottom 70u1 left 50u1", "left 50u1 bottom 70u1"],
574-
["bottom 70u1 right 80%", "left 20% bottom 70u1"],
575-
["bottom 70u1 right 80u1", "right 80u1 bottom 70u1"],
576-
577-
["right 80% top 50%", "20% 50%"],
578-
["right 80% top 50u1", "20% 50u1"],
579-
["right 80% bottom 70%", "20% 30%"],
580-
["right 80% bottom 70u1", "left 20% bottom 70u1"],
581-
["right 80u1 top 50%", "right 80u1 top 50%"],
582-
["right 80u1 top 50u1", "right 80u1 top 50u1"],
583-
["right 80u1 bottom 70%", "right 80u1 top 30%"],
584-
["right 80u1 bottom 70u1", "right 80u1 bottom 70u1"],
592+
["top 50u1 right 80%", "calc(20%) 50u1", "20% 50u1"],
593+
594+
["bottom 70% left 50%", "50% calc(30%)", "50% 30%"],
595+
["bottom 70% left 50u1", "50u1 calc(30%)", "50u1 30%"],
596+
["bottom 70% right 80%", "calc(20%) calc(30%)", "20% 30%"],
597+
["bottom 70% right 80u1", "[convert] calc(100% - 80u1) calc(30%)", "calc(100% - 80u1) 30%"],
598+
["bottom 70u1 left 50%", "[convert] 50% calc(100% - 70u1)"],
599+
["bottom 70u1 right 50%", "[convert] calc(50%) calc(100% - 70u1)", "50% calc(100% - 70u1)"],
600+
["bottom 70u1 right 80u1", "[convert] calc(100% - 80u1) calc(100% - 70u1)"],
601+
602+
["right 80% top 50%", "calc(20%) 50%", "20% 50%"],
603+
["right 80% top 50u1", "calc(20%) 50u1", "20% 50u1"],
604+
["right 80% bottom 70%", "calc(20%) calc(30%)", "20% 30%"],
605+
["right 80% bottom 70u1", "[convert] calc(20%) calc(100% - 70u1)", "20% calc(100% - 70u1)"],
606+
["right 80u1 top 50%", "[convert] calc(100% - 80u1) 50%"],
607+
["right 80u1 bottom 70%", "[convert] calc(100% - 80u1) calc(30%)", "calc(100% - 80u1) 30%"],
608+
["right 80u1 bottom 70u1", "[convert] calc(100% - 80u1) calc(100% - 70u1)"],
585609
];
586610

587611
var invalidPositions = [

0 commit comments

Comments
 (0)