4 <title>Test for miscellaneous computed style issues
</title>
5 <script src=
"/tests/SimpleTest/SimpleTest.js"></script>
6 <link rel=
"stylesheet" type=
"text/css" href=
"/tests/SimpleTest/test.css"/>
7 <style id=
"style"></style>
10 <a target=
"_blank" href=
"https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug
</a>
12 <div id=
"content" style=
"display: none">
15 <script type=
"application/javascript">
17 /** Test for miscellaneous computed style issues **/
19 var frame_container = document.getElementById(
"display");
20 var noframe_container = document.getElementById(
"content");
22 (function test_bug_595650() {
23 // Test handling of horizontal and vertical percentages for border-radius.
24 var p = document.createElement(
"p");
25 p.setAttribute(
"style",
"width: 256px; height: 128px");
26 p.style.borderTopLeftRadius =
"1.5625%"; /*
1/
64 ==
4px
2px */
27 p.style.borderTopRightRadius =
"5px";
28 p.style.borderBottomRightRadius =
"5px 3px";
29 p.style.borderBottomLeftRadius =
"1.5625% 3.125%" /*
1/
64 1/
32 ==
4px
4px */
30 var cs = getComputedStyle(p,
"");
32 frame_container.appendChild(p);
33 is(cs.borderTopLeftRadius,
"1.5625%",
34 "computed value of % border-radius, with frame");
35 is(cs.borderTopRightRadius,
"5px",
36 "computed value of px border-radius, with frame");
37 is(cs.borderBottomRightRadius,
"5px 3px",
38 "computed value of px border-radius, with frame");
39 is(cs.borderBottomLeftRadius,
"1.5625% 3.125%",
40 "computed value of % border-radius, with frame");
42 noframe_container.appendChild(p);
43 is(cs.borderTopLeftRadius,
"1.5625%",
44 "computed value of % border-radius, without frame");
45 is(cs.borderTopRightRadius,
"5px",
46 "computed value of px border-radius, without frame");
47 is(cs.borderBottomRightRadius,
"5px 3px",
48 "computed value of px border-radius, without frame");
49 is(cs.borderBottomLeftRadius,
"1.5625% 3.125%",
50 "computed value of % border-radius, without frame");
55 (function test_bug_1292447() {
56 // Was for bug
595651 which tests that clamping of border-radius
57 // is reflected in computed style.
58 // For compatibility issue, resolved value is computed value now.
59 var p = document.createElement(
"p");
60 p.setAttribute(
"style",
"width: 190px; height: 90px; border: 5px solid;");
61 p.style.borderRadius =
"1000px";
62 var cs = getComputedStyle(p,
"");
64 frame_container.appendChild(p);
65 is(cs.borderTopLeftRadius,
"1000px",
66 "computed value of clamped border radius (top left)");
67 is(cs.borderTopRightRadius,
"1000px",
68 "computed value of clamped border radius (top right)");
69 is(cs.borderBottomRightRadius,
"1000px",
70 "computed value of clamped border radius (bottom right)");
71 is(cs.borderBottomLeftRadius,
"1000px",
72 "computed value of clamped border radius (bottom left)");
74 p.style.overflowY =
"scroll";
75 is(cs.borderTopLeftRadius,
"1000px",
76 "computed value of clamped border radius (top left, overflow-y)");
77 // Fennec doesn't have scrollbars for overflow:scroll content
78 if (p.clientWidth == p.offsetWidth -
10) {
79 is(cs.borderTopRightRadius,
"1000px",
80 "computed value of border radius (top right, overflow-y)");
81 is(cs.borderBottomRightRadius,
"1000px",
82 "computed value of border radius (bottom right, overflow-y)");
84 is(cs.borderTopRightRadius,
"1000px",
85 "computed value of clamped border radius (top right, overflow-y)");
86 is(cs.borderBottomRightRadius,
"1000px",
87 "computed value of clamped border radius (bottom right, overflow-y)");
89 is(cs.borderBottomLeftRadius,
"1000px",
90 "computed value of clamped border radius (bottom left, overflow-y)");
92 p.style.overflowY =
"hidden";
93 p.style.overflowX =
"scroll";
94 is(cs.borderTopLeftRadius,
"1000px",
95 "computed value of clamped border radius (top left, overflow-x)");
96 is(cs.borderTopRightRadius,
"1000px",
97 "computed value of clamped border radius (top right, overflow-x)");
98 // Fennec doesn't have scrollbars for overflow:scroll content
99 if (p.clientHeight == p.offsetHeight -
10) {
100 is(cs.borderBottomRightRadius,
"1000px",
101 "computed value of border radius (bottom right, overflow-x)");
102 is(cs.borderBottomLeftRadius,
"1000px",
103 "computed value of border radius (bottom left, overflow-x)");
105 is(cs.borderBottomRightRadius,
"1000px",
106 "computed value of clamped border radius (bottom right, overflow-x)");
107 is(cs.borderBottomLeftRadius,
"1000px",
108 "computed value of clamped border radius (bottom left, overflow-x)");
114 (function test_bug_647885_1() {
115 // Test that various background-position styles round-trip correctly
116 var backgroundPositions = [
117 [
"0 0",
"0px 0px",
"unitless 0" ],
118 [
"0px 0px",
"0px 0px",
"0 with units" ],
119 [
"0% 0%",
"0% 0%",
"0%" ],
120 [
"calc(0px) 0",
"0px 0px",
"0 calc with units x" ],
121 [
"0 calc(0px)",
"0px 0px",
"0 calc with units y" ],
122 [
"calc(3px - 3px) 0",
"0px 0px",
"computed 0 calc with units x" ],
123 [
"0 calc(3px - 3px)",
"0px 0px",
"computed 0 calc with units y" ],
124 [
"calc(0%) 0",
"0% 0px",
"0% calc x"],
125 [
"0 calc(0%)",
"0px 0%",
"0% calc y"],
126 [
"calc(3px + 2% - 2%) 0",
"calc(0% + 3px) 0px",
127 "computed 0% calc x"],
128 [
"0 calc(3px + 2% - 2%)",
"0px calc(0% + 3px)",
129 "computed 0% calc y"],
130 [
"calc(3px - 5px) calc(6px - 7px)",
"-2px -1px",
131 "negative pixel width"],
132 [
"",
"0% 0%",
"initial value" ],
135 var p = document.createElement(
"p");
136 var cs = getComputedStyle(p,
"");
137 frame_container.appendChild(p);
139 for (var i =
0; i < backgroundPositions.length; ++i) {
140 var test = backgroundPositions[i];
141 p.style.backgroundPosition = test[
0];
142 is(cs.backgroundPosition, test[
1],
"computed value of " + test[
2] +
" background-position");
148 (function test_bug_647885_2() {
149 // Test that various background-size styles round-trip correctly
150 var backgroundSizes = [
151 [
"0 0",
"0px 0px",
"unitless 0" ],
152 [
"0px 0px",
"0px 0px",
"0 with units" ],
153 [
"0% 0%",
"0% 0%",
"0%" ],
154 [
"calc(0px) 0",
"0px 0px",
"0 calc with units horizontal" ],
155 [
"0 calc(0px)",
"0px 0px",
"0 calc with units vertical" ],
156 [
"calc(3px - 3px) 0",
"0px 0px",
"computed 0 calc with units horizontal" ],
157 [
"0 calc(3px - 3px)",
"0px 0px",
"computed 0 calc with units vertical" ],
158 [
"calc(0%) 0",
"0% 0px",
"0% calc horizontal"],
159 [
"0 calc(0%)",
"0px 0%",
"0% calc vertical"],
160 [
"calc(3px + 2% - 2%) 0",
"calc(0% + 3px) 0px",
161 "computed 0% calc horizontal"],
162 [
"0 calc(3px + 2% - 2%)",
"0px calc(0% + 3px)",
163 "computed 0% calc vertical"],
164 [
"calc(3px - 5px) calc(6px - 9px)",
"0px 0px",
"negative pixel width" ],
165 [
"",
"auto",
"initial value" ],
168 var p = document.createElement(
"p");
169 var cs = getComputedStyle(p,
"");
170 frame_container.appendChild(p);
172 for (var i =
0; i < backgroundSizes.length; ++i) {
173 var test = backgroundSizes[i];
174 p.style.backgroundSize = test[
0];
175 is(cs.backgroundSize, test[
1],
"computed value of " + test[
2] +
" background-size");
181 (function test_bug_716628() {
182 // Test that various gradient styles round-trip correctly
183 var backgroundImages = [
184 [
"radial-gradient(at 10% bottom, #ffffff, black)",
185 "radial-gradient(at 10% 100%, rgb(255, 255, 255), rgb(0, 0, 0))",
186 "radial gradient 1" ],
187 [
"radial-gradient(#ffffff, black)",
188 "radial-gradient(rgb(255, 255, 255), rgb(0, 0, 0))",
189 "radial gradient 2" ],
190 [
"radial-gradient(farthest-corner, #ffffff, black)",
191 "radial-gradient(rgb(255, 255, 255), rgb(0, 0, 0))",
192 "radial gradient 3" ],
193 [
"linear-gradient(red, blue)",
194 "linear-gradient(rgb(255, 0, 0), rgb(0, 0, 255))",
195 "linear gradient 1" ],
196 [
"linear-gradient(to bottom, red, blue)",
197 "linear-gradient(rgb(255, 0, 0), rgb(0, 0, 255))",
198 "linear gradient 2" ],
199 [
"linear-gradient(to right, red, blue)",
200 "linear-gradient(to right, rgb(255, 0, 0), rgb(0, 0, 255))",
201 "linear gradient 3" ],
202 [
"linear-gradient(-45deg, red, blue)",
203 "linear-gradient(-45deg, rgb(255, 0, 0), rgb(0, 0, 255))",
204 "linear gradient with angle in degrees" ],
205 [
"linear-gradient(-0.125turn, red, blue)",
206 "linear-gradient(-45deg, rgb(255, 0, 0), rgb(0, 0, 255))",
207 "linear gradient with angle in turns" ],
210 var p = document.createElement(
"p");
211 var cs = getComputedStyle(p,
"");
212 frame_container.appendChild(p);
214 for (var i =
0; i < backgroundImages.length; ++i) {
215 var test = backgroundImages[i];
216 p.style.backgroundImage = test[
0];
217 is(cs.backgroundImage, test[
1],
"computed value of " + test[
2] +
" background-image");
223 (function test_bug_1363349_linear() {
224 const specPrefix =
"-webkit-gradient(linear, ";
225 const specSuffix =
", from(blue), to(lime))";
227 const expPrefix =
"linear-gradient(";
228 const expSuffix =
"rgb(0, 0, 255) 0%, rgb(0, 255, 0) 100%)";
231 [
"calc(5 + 5) top, calc(10 + 10) top",
233 "calc(num+num) in position"
235 [
"left calc(25% - 10%), right calc(75% + 10%)",
237 "calc(pct+pct) in position "
241 let p = document.createElement(
"p");
242 let cs = getComputedStyle(p,
"");
243 frame_container.appendChild(p);
245 for (let test of testcases) {
246 let specifiedStyle = specPrefix + test[
0] + specSuffix;
247 let expectedStyle = expPrefix;
249 expectedStyle += test[
1] +
", ";
251 expectedStyle += expSuffix;
253 p.style.backgroundImage = specifiedStyle;
254 is(cs.backgroundImage, expectedStyle,
255 "computed value of -webkit-gradient expression (" + test[
2] +
")");
256 p.style.backgroundImage =
"";
262 (function test_bug_1363349_radial() {
263 const specPrefix =
"-webkit-gradient(radial, ";
264 const specSuffix =
", from(blue), to(lime))";
266 const expPrefix =
"radial-gradient(";
267 const expSuffix =
"rgb(0, 0, 255) 0%, rgb(0, 255, 0) 100%)";
270 [
"1 2, 0, 3 4, calc(1 + 5)",
272 "calc(num+num) in radius"
274 [
"1 2, calc(1 + 2), 3 4, calc(1 + 5)",
276 "calc(num+num) in radius"
278 [
"calc(0 + 1) calc(1 + 1), calc(1 + 2), calc(1 + 2) 4, calc(1 + 5)",
280 "calc(num+num) in position and radius"
284 let p = document.createElement(
"p");
285 let cs = getComputedStyle(p,
"");
286 frame_container.appendChild(p);
288 for (let test of testcases) {
289 let specifiedStyle = specPrefix + test[
0] + specSuffix;
290 let expectedStyle = expPrefix;
292 expectedStyle += test[
1] +
", ";
294 expectedStyle += expSuffix;
296 p.style.backgroundImage = specifiedStyle;
297 is(cs.backgroundImage, expectedStyle,
298 "computed value of -webkit-gradient expression (" + test[
2] +
")");
299 p.style.backgroundImage =
"";
305 (function test_bug_1241623() {
306 // Test that -webkit-gradient() styles are approximated the way we expect:
308 // For compactness, we'll pull out the common prefix & suffix from all of the
309 // specified & expected styles, and construct the full expression on the fly:
310 const specPrefix =
"-webkit-gradient(linear, ";
311 const specSuffix =
", from(blue), to(lime))";
313 const expPrefix =
"linear-gradient(";
314 const expSuffix =
"rgb(0, 0, 255) 0%, rgb(0, 255, 0) 100%)";
318 // [ legacyDirection,
319 // modernDirection, // (empty string means use default direction)
320 // descriptionOfTestcase ],
322 // If start & end are at same point, we just produce a gradient with
323 // the default direction.
324 [
"left top, left top",
326 "start & end point are the same" ],
329 "start & end point are the same" ],
330 [
"center center, center center",
332 "start & end point are the same" ],
334 // If start & end use different units in the same coordinate, we generally
335 // can't extract a direction (because we can't know whether arbitrary
336 // percent values are larger or smaller than arbitrary pixel values). So
337 // we produce a gradient in the default direction.
338 [
"left top, 30 100%", // (Note: keywords like
"left" are really % vals.)
340 "start & end point have different units" ],
341 [
"100% 15, right bottom",
343 "start & end point have different units" ],
346 "start & end point have different units" ],
349 "start & end point have different units" ],
352 "start & end point have different units" ],
355 "start & end point have different units" ],
357 // Gradient starting/ending somewhere arbitrary in middle:
358 [
"center center, right top",
360 "from center to right top" ],
361 [
"left top, center center",
363 "from left top to center" ],
366 "from arbitrary point to another point in lower-left direction" ],
368 // Gradient using negative coordinates:
371 "from negative point to origin" ],
374 "from negative-x point to another point in lower-right direction" ],
377 "from negative-y point to another point in lower-left direction" ],
379 // Diagonal gradient between sides/corners:
380 [
"center top, left center",
382 "left/bottom-wards, using edge keywords" ],
383 [
"left center, center top",
385 "top/right-wards, using edge keywords" ],
386 [
"right center, center top",
388 "top/left-wards, using edge keywords" ],
389 [
"right top, center bottom",
391 "bottom/left-wards, using edge keywords" ],
392 [
"left top, right bottom",
394 "bottom/right-wards, using edge keywords" ],
395 [
"left bottom, right top",
397 "top/right-wards, using edge keywords" ],
400 let p = document.createElement(
"p");
401 let cs = getComputedStyle(p,
"");
402 frame_container.appendChild(p);
404 for (let test of testcases) {
405 let specifiedStyle = specPrefix + test[
0] + specSuffix;
406 let expectedStyle = expPrefix;
408 expectedStyle += test[
1] +
", ";
410 expectedStyle += expSuffix;
412 p.style.backgroundImage = specifiedStyle;
413 is(cs.backgroundImage, expectedStyle,
414 "computed value of -webkit-gradient expression (" + test[
2] +
")");
415 p.style.backgroundImage =
"";
421 (function test_bug_1293164() {
422 var p = document.createElement(
"p");
423 var cs = getComputedStyle(p,
"");
424 frame_container.appendChild(p);
426 var docPath = document.URL.substring(
0, document.URL.lastIndexOf(
"/") +
1);
428 var localURL =
"url(\"#foo\
")";
429 var nonLocalURL =
"url(\"foo.svg#foo\
")";
430 var resolvedNonLocalURL =
"url(\"" + docPath + "foo.svg#foo\
")";
444 for (var prop of testStyles) {
445 p.style[prop] = localURL;
446 is(cs[prop], localURL,
"computed value of " + prop);
447 p.style[prop] = nonLocalURL;
448 is(cs[prop], resolvedNonLocalURL,
"computed value of " + prop);
454 (function test_bug_1347164() {
455 // Test that computed color values are serialized as
"rgb()"
456 // IFF they're fully-opaque (and otherwise as
"rgba()").
458 [
"rgba(0, 0, 0, 1)",
"rgb(0, 0, 0)"],
459 [
"rgba(0, 0, 0, 0.5)",
"rgba(0, 0, 0, 0.5)"],
460 [
"hsla(0, 0%, 0%, 1)",
"rgb(0, 0, 0)"],
461 [
"hsla(0, 0%, 0%, 0.5)",
"rgba(0, 0, 0, 0.5)"],
465 [
"rgba(0 0 0 / 1)",
"rgb(0, 0, 0)"],
466 [
"rgba(0 0 0 / 0.1)",
"rgba(0, 0, 0, 0.1)"],
467 [
"rgb(0 0 0 / 1)",
"rgb(0, 0, 0)"],
468 [
"rgb(0 0 0 / 0.2)",
"rgba(0, 0, 0, 0.2)"],
469 [
"hsla(0 0% 0% / 1)",
"rgb(0, 0, 0)"],
470 [
"hsla(0deg 0% 0% / 0.3)",
"rgba(0, 0, 0, 0.3)"],
471 [
"hsl(0 0% 0% / 1)",
"rgb(0, 0, 0)"],
472 [
"hsl(0 0% 0% / 0.4)",
"rgba(0, 0, 0, 0.4)"],
475 var p = document.createElement(
"p");
476 var cs = getComputedStyle(p,
"");
477 frame_container.appendChild(p);
479 for (var i =
0; i < color.length; ++i) {
481 p.style.color = test[
0];
482 is(cs.color, test[
1],
"computed value of " + test[
0]);
484 for (var i =
0; i < css_color_4.length; ++i) {
485 var test = css_color_4[i];
486 p.style.color = test[
0];
487 is(cs.color, test[
1],
"css-color-4 computed value of " + test[
0]);
493 (function test_bug_1357117() {
494 // Test that vendor-prefixed gradient styles round-trip with the same prefix,
495 // or with no prefix.
496 var backgroundImages = [
497 // [ specified style,
498 // expected computed style,
499 // descriptionOfTestcase ],
500 // Linear gradient with legacy-gradient-line (needs prefixed syntax):
501 [
"-webkit-linear-gradient(10deg, red, blue)",
502 "-webkit-linear-gradient(10deg, rgb(255, 0, 0), rgb(0, 0, 255))",
503 "-webkit-linear-gradient with angled legacy-gradient-line" ],
505 // Linear gradient with box corner (needs prefixed syntax):
506 [
"-webkit-linear-gradient(top left, red, blue)",
507 "-webkit-linear-gradient(left top, rgb(255, 0, 0), rgb(0, 0, 255))",
508 "-webkit-linear-gradient with box corner" ],
510 // Linear gradient with default keyword (should be serialized without keyword):
511 [
"-webkit-linear-gradient(top, red, blue)",
512 "-webkit-linear-gradient(rgb(255, 0, 0), rgb(0, 0, 255))",
513 "-webkit-linear-gradient with legacy default direction keyword" ],
515 // Radial gradients (should be serialized using modern unprefixed style):
516 [
"-webkit-radial-gradient(contain, red, blue)",
517 "-webkit-radial-gradient(closest-side, rgb(255, 0, 0), rgb(0, 0, 255))",
518 "-webkit-radial-gradient with legacy 'contain' keyword" ],
521 var p = document.createElement(
"p");
522 var cs = getComputedStyle(p,
"");
523 frame_container.appendChild(p);
525 for (var i =
0; i < backgroundImages.length; ++i) {
526 var test = backgroundImages[i];
527 p.style.backgroundImage = test[
0];
528 is(cs.backgroundImage, test[
1],
529 "computed value of prefixed gradient expression (" + test[
2] +
")");
535 (function test_bug_1367028() {
536 const borderImageSubprops = [
537 "border-image-slice",
538 "border-image-outset",
543 values: [
"5 5 5 5",
"5 5 5",
"5 5",
"5"],
545 desc:
"identical four sides",
548 values: [
"5 6 5 6",
"5 6 5",
"5 6"],
550 desc:
"identical values on each axis",
553 values: [
"5 6 7 6",
"5 6 7"],
555 desc:
"identical values on left and right",
559 desc:
"identical values on top and bottom",
562 values: [
"5 5 6 6",
"5 6 6 5"],
563 desc:
"identical values on unrelated sides",
567 desc:
"different values on all sides",
571 let frameContainer = document.getElementById(
"display");
572 let p = document.createElement(
"p");
573 frameContainer.appendChild(p);
574 let cs = getComputedStyle(p);
576 for (let prop of borderImageSubprops) {
577 for (let {values, expected, desc} of rectValues) {
578 for (let value of values) {
579 p.style.setProperty(prop, value);
580 is(cs.getPropertyValue(prop),
581 expected ? expected : value, `${desc} for ${prop}`);
582 p.style.removeProperty(prop);
590 (function test_bug_1378368() {
591 // Test that negative results of calc()s in basic-shapes (e.g. polygon()) should
592 // not be clamped to
0px.
594 // [ specified style,
595 // expected computed style,
596 // descriptionOfTestcase ],
598 [
"polygon(calc(10px - 20px) 0px, 100px 100px, 0px 100px)",
599 "polygon(-10px 0px, 100px 100px, 0px 100px)",
600 "polygon with negative calc() coordinates" ],
602 [
"inset(calc(10px - 20px))",
604 "inset with negative calc() coordinates" ],
607 var p = document.createElement(
"p");
608 var cs = getComputedStyle(p,
"");
609 frame_container.appendChild(p);
611 for (let test of clipPaths) {
612 p.style.clipPath = test[
0];
613 is(cs.clipPath, test[
1],
614 "computed value of clip-path for basic-shapes (" + test[
2] +
")");
620 (function test_bug_1418433() {
621 // Test that the style data read through getComputedStyle is always up-to-date,
622 // even for non-displayed elements.
624 var d = document.createElement(
"div");
625 d.setAttribute(
"id",
"nonDisplayedDiv");
626 var cs = getComputedStyle(d, null);
627 noframe_container.appendChild(d);
629 // Test for stylesheet change, i.e., added/changed/removed
630 var style = document.getElementById(
"style");
631 is(cs.height,
"auto",
632 "computed value of display none element (before testing)");
633 style.textContent =
"#nonDisplayedDiv { height: 100px; }";
634 is(cs.height,
"100px",
635 "computed value of display none element (sheet added)");
636 style.textContent =
"#nonDisplayedDiv { height: 10px; }";
637 is(cs.height,
"10px",
638 "computed value of display none element (sheet changed)");
639 style.textContent =
"";
640 is(cs.height,
"auto",
641 "computed value of display none element (sheet removed)");
643 // Test for rule change, i.e., added/changed/removed
644 var styleSheet = style.sheet;
646 "computed value of display none element (before testing)");
647 styleSheet.insertRule(
"#nonDisplayedDiv { width: 100px; }",
0);
648 is(cs.width,
"100px",
649 "computed value of display none element (rule added)");
650 styleSheet.deleteRule(
0);
651 styleSheet.insertRule(
"#nonDisplayedDiv { width: 10px; }",
0);
653 "computed value of display none element (rule changed)");
654 styleSheet.deleteRule(
0);
656 "computed value of display none element (rule removed)");