diff options
Diffstat (limited to 'layout/base/tests/chrome')
121 files changed, 5787 insertions, 0 deletions
diff --git a/layout/base/tests/chrome/animated.gif b/layout/base/tests/chrome/animated.gif Binary files differnew file mode 100644 index 0000000000..b2895487bd --- /dev/null +++ b/layout/base/tests/chrome/animated.gif diff --git a/layout/base/tests/chrome/blue-32x32.png b/layout/base/tests/chrome/blue-32x32.png Binary files differnew file mode 100644 index 0000000000..deefd19b2a --- /dev/null +++ b/layout/base/tests/chrome/blue-32x32.png diff --git a/layout/base/tests/chrome/bug1041200_frame.html b/layout/base/tests/chrome/bug1041200_frame.html new file mode 100644 index 0000000000..0030ec0edd --- /dev/null +++ b/layout/base/tests/chrome/bug1041200_frame.html @@ -0,0 +1,2 @@ +<body onload='parent.childLoaded()' style='background:lime'> +<p>Hello<p>Hello<p>Hello<p>Hello<p>Hello<p> diff --git a/layout/base/tests/chrome/bug1041200_window.html b/layout/base/tests/chrome/bug1041200_window.html new file mode 100644 index 0000000000..005f7bcd13 --- /dev/null +++ b/layout/base/tests/chrome/bug1041200_window.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for Bug 1041200</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/paint_listener.js"></script> +</head> +<body> +<iframe style="width:700px; height:500px; margin-top:200px;" id="ourFrame"></iframe> +<script> +var SpecialPowers = window.arguments[0].SpecialPowers; +var SimpleTest = window.arguments[0].SimpleTest; +var ok = window.arguments[0].ok; +var info = window.arguments[0].info; + +var viewer = SpecialPowers.setFullZoom(window, 2); + +SimpleTest.waitForExplicitFinish(); + +window.onload = function() { + window.waitForAllPaintsFlushed(function () { + // Supply random key to ensure load actually happens + ourFrame.src = "bug1041200_frame.html?" + Math.random(); + }, document.getElementById("ourFrame").contentDocument); +}; + +window.childLoaded = function() { + setTimeout(function() { + window.waitForAllPaintsFlushed(function(x1, y1, x2, y2) { + // We set the full zoom of this window too, so we need to account for it here. + ok(x2 - x1 >= 700 / 2 && y2 - y1 >= 500 / 2, + "expected to see invalidate of entire frame, got " + [x1,y1,x2,y2].join(',')); + SimpleTest.finish(); + window.close(); + }); + }, 0); +}; +</script> + diff --git a/layout/base/tests/chrome/bug1722890.html b/layout/base/tests/chrome/bug1722890.html new file mode 100644 index 0000000000..76175eb33d --- /dev/null +++ b/layout/base/tests/chrome/bug1722890.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> + <head> + <style> +div { + position: fixed; + width: 20px; + height: 20px; + background: blue; + left: 0; +} + </style> + </head> + <body> + <div style="top:0"></div> + <div style="bottom:0"></div> + </body> +</html> diff --git a/layout/base/tests/chrome/bug1722890_ref.html b/layout/base/tests/chrome/bug1722890_ref.html new file mode 100644 index 0000000000..8bf8e39713 --- /dev/null +++ b/layout/base/tests/chrome/bug1722890_ref.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> + <head> + <style> +div { + position: fixed; + width: 10px; + height: 10px; + background: blue; + left: 0; +} + </style> + </head> + <body> + <div style="top:0"></div> + <div style="bottom:0"></div> + </body> +</html> + diff --git a/layout/base/tests/chrome/bug1769161_1.html b/layout/base/tests/chrome/bug1769161_1.html new file mode 100644 index 0000000000..b1cc3b6ded --- /dev/null +++ b/layout/base/tests/chrome/bug1769161_1.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<style> +div { + width: 1in; + height: 1in; + background-color: blue; +} +body { + margin: 0; +} +@page { + size: 20in; +} +</style> +<body> + <div></div> +</body> diff --git a/layout/base/tests/chrome/bug1769161_1_ref.html b/layout/base/tests/chrome/bug1769161_1_ref.html new file mode 100644 index 0000000000..ab56d8d045 --- /dev/null +++ b/layout/base/tests/chrome/bug1769161_1_ref.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<style> +div { + width: 0.5in; + height: 0.5in; + background-color: blue; +} +body { + margin: 0; +} +@page { + size: 10in; +} +</style> +<body> + <div></div> +</body> diff --git a/layout/base/tests/chrome/bug1769161_2.html b/layout/base/tests/chrome/bug1769161_2.html new file mode 100644 index 0000000000..7728d0bd95 --- /dev/null +++ b/layout/base/tests/chrome/bug1769161_2.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<style> +div { + width: 2in; + height: 2in; + background-color: blue; +} +body { + margin: 0; +} +@page { + size: 10in; +} +</style> +<body> + <div></div> +</body> diff --git a/layout/base/tests/chrome/bug1769161_2_ref.html b/layout/base/tests/chrome/bug1769161_2_ref.html new file mode 100644 index 0000000000..3916e26a17 --- /dev/null +++ b/layout/base/tests/chrome/bug1769161_2_ref.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<style> +div { + width: 10in; + height: 10in; + background-color: blue; +} +body { + margin: 0; +} +@page { + size: 50in; +} +</style> +<body> + <div></div> +</body> diff --git a/layout/base/tests/chrome/bug1769161_3.html b/layout/base/tests/chrome/bug1769161_3.html new file mode 100644 index 0000000000..b1cc3b6ded --- /dev/null +++ b/layout/base/tests/chrome/bug1769161_3.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<style> +div { + width: 1in; + height: 1in; + background-color: blue; +} +body { + margin: 0; +} +@page { + size: 20in; +} +</style> +<body> + <div></div> +</body> diff --git a/layout/base/tests/chrome/bug1769161_3_ref.html b/layout/base/tests/chrome/bug1769161_3_ref.html new file mode 100644 index 0000000000..b786e1ad2b --- /dev/null +++ b/layout/base/tests/chrome/bug1769161_3_ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<style> +div { + width: 0.5in; + height: 0.5in; + background-color: blue; +} +body { + margin: 0; +} +@page { + size: 10in; + margin: 2in; +} +</style> +<body> + <div></div> +</body> diff --git a/layout/base/tests/chrome/bug1769161_4.html b/layout/base/tests/chrome/bug1769161_4.html new file mode 100644 index 0000000000..7728d0bd95 --- /dev/null +++ b/layout/base/tests/chrome/bug1769161_4.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<style> +div { + width: 2in; + height: 2in; + background-color: blue; +} +body { + margin: 0; +} +@page { + size: 10in; +} +</style> +<body> + <div></div> +</body> diff --git a/layout/base/tests/chrome/bug1769161_4_ref.html b/layout/base/tests/chrome/bug1769161_4_ref.html new file mode 100644 index 0000000000..be2de41058 --- /dev/null +++ b/layout/base/tests/chrome/bug1769161_4_ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<style> +div { + width: 10in; + height: 10in; + background-color: blue; +} +body { + margin: 0; +} +@page { + size: 50in; + margin: 10in; +} +</style> +<body> + <div></div> +</body> diff --git a/layout/base/tests/chrome/bug495648.rdf b/layout/base/tests/chrome/bug495648.rdf new file mode 100644 index 0000000000..b7045aa70a --- /dev/null +++ b/layout/base/tests/chrome/bug495648.rdf @@ -0,0 +1,214 @@ +<?xml version="1.0"?> +<RDF:RDF xmlns:NS1="http://sitedelta.schierla.de/SD-rdf#" + xmlns:NC="http://home.netscape.com/NC-rdf#" + xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=19&btnG=Suche&meta=" + NC:name="19 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Bag RDF:about="urn:root:bag"> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=1&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=2&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=3&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=4&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=5&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=6&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=7&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=8&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=9&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=10&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=11&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=12&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=13&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=14&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=15&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=16&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=17&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=18&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=19&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=20&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=21&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=22&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=23&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=24&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=25&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=26&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=27&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=28&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=29&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=30&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=31&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=32&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=33&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=34&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=35&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=36&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=37&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=38&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=39&btnG=Suche&meta="/> + <RDF:li RDF:resource="http://www.google.de/search?hl=de&q=40&btnG=Suche&meta="/> + </RDF:Bag> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=2&btnG=Suche&meta=" + NC:name="2 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=12&btnG=Suche&meta=" + NC:name="12 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=5&btnG=Suche&meta=" + NC:name="5 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=6&btnG=Suche&meta=" + NC:name="6 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=22&btnG=Suche&meta=" + NC:name="22 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=17&btnG=Suche&meta=" + NC:name="17 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="urn:root"> + <NC:links RDF:resource="urn:root:bag"/> + </RDF:Description> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=8&btnG=Suche&meta=" + NC:name="8 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=1&btnG=Suche&meta=" + NC:name="1 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=16&btnG=Suche&meta=" + NC:name="16 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=21&btnG=Suche&meta=" + NC:name="21 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=20&btnG=Suche&meta=" + NC:name="20 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=9&btnG=Suche&meta=" + NC:name="9 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=11&btnG=Suche&meta=" + NC:name="11 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=14&btnG=Suche&meta=" + NC:name="14 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=23&btnG=Suche&meta=" + NC:name="23 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=24&btnG=Suche&meta=" + NC:name="24 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=18&btnG=Suche&meta=" + NC:name="18 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www0.pafnet.de/user/322033" + NC:name="pafnet - You2_xD" + NS1:nextScan="1243707104073" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=3&btnG=Suche&meta=" + NC:name="3 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=7&btnG=Suche&meta=" + NC:name="7 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=15&btnG=Suche&meta=" + NC:name="15 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=4&btnG=Suche&meta=" + NC:name="4 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=13&btnG=Suche&meta=" + NC:name="13 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=10&btnG=Suche&meta=" + NC:name="10 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=25&btnG=Suche&meta=" + NC:name="25 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=26&btnG=Suche&meta=" + NC:name="26 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=27&btnG=Suche&meta=" + NC:name="27 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=28&btnG=Suche&meta=" + NC:name="28 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=29&btnG=Suche&meta=" + NC:name="29 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=30&btnG=Suche&meta=" + NC:name="30 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=31&btnG=Suche&meta=" + NC:name="31 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=32&btnG=Suche&meta=" + NC:name="32 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=33&btnG=Suche&meta=" + NC:name="33 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=34&btnG=Suche&meta=" + NC:name="34 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=35&btnG=Suche&meta=" + NC:name="35 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=36&btnG=Suche&meta=" + NC:name="36 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=37&btnG=Suche&meta=" + NC:name="37 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=38&btnG=Suche&meta=" + NC:name="38 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=39&btnG=Suche&meta=" + NC:name="39 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> + <RDF:Description RDF:about="http://www.google.de/search?hl=de&q=40&btnG=Suche&meta=" + NC:name="40 - Google-Suche" + NS1:nextScan="0" + NS1:status="0" /> +</RDF:RDF> diff --git a/layout/base/tests/chrome/bug551434_childframe.html b/layout/base/tests/chrome/bug551434_childframe.html new file mode 100644 index 0000000000..3d7bd6c13a --- /dev/null +++ b/layout/base/tests/chrome/bug551434_childframe.html @@ -0,0 +1,4 @@ +<script> +var gKeyDownChild = 0, gKeyPressChild = 0, gKeyUpChild = 0; +</script> +<input id='i4' onkeydown="gKeyDownChild++" onkeypress="gKeyPressChild++" onkeyup="gKeyUpChild++; this.parentNode.removeChild(this);"> diff --git a/layout/base/tests/chrome/chrome.ini b/layout/base/tests/chrome/chrome.ini new file mode 100644 index 0000000000..13f65215c0 --- /dev/null +++ b/layout/base/tests/chrome/chrome.ini @@ -0,0 +1,138 @@ +[DEFAULT] +prefs = + layout.css.constructable-stylesheets.enabled=true + layout.css.individual-transform.enabled=true + layout.css.motion-path.enabled=true + layout.css.page-size.enabled=true +skip-if = os == 'android' +support-files = + animated.gif + blue-32x32.png + bug1722890.html + bug1722890_ref.html + bug1769161_1.html + bug1769161_1_ref.html + bug1769161_2.html + bug1769161_2_ref.html + bug1769161_3.html + bug1769161_3_ref.html + bug1769161_4.html + bug1769161_4_ref.html + bug551434_childframe.html + chrome_content_integration_window.xhtml + default_background_window.xhtml + dialog_with_positioning_window.xhtml + file_bug458898.html + green.png + printpreview_bug1713404_ref.html + printpreview_bug1730091_ref.html + printpreview_bug396024_helper.xhtml + printpreview_bug482976_helper.xhtml + printpreview_helper.xhtml + printpreview_downloadable_font.html + printpreview_downloadable_font_ref.html + printpreview_downloadable_font_in_iframe.html + printpreview_downloadable_font_in_iframe_ref.html + printpreview_font_api.html + printpreview_font_api_ref.html + printpreview_font_mozprintcallback.html + printpreview_font_mozprintcallback_ref.html + printpreview_quirks.html + printpreview_quirks_ref.html + printpreview_images.html + printpreview_images_ref.html + printpreview_images_sw.html + printpreview_images_sw_ref.html + printpreview_images_sw.js + printpreview_image_select.html + printpreview_image_select_ref.html + printpreview_mixed_page_size_001.html + printpreview_mixed_page_size_002.html + printpreview_pps_uw2.html + printpreview_pps_uw2_ref.html + printpreview_pps_uw2_no_margin_ref.html + printpreview_pps_uw4.html + printpreview_pps_uw4_ref.html + printpreview_pps_uw9.html + printpreview_pps_uw9_ref.html + printpreview_pps2.html + printpreview_pps2_ref.html + printpreview_pps4.html + printpreview_pps4_ref.html + printpreview_pps6.html + printpreview_pps6_ref.html + printpreview_pps9.html + printpreview_pps9_ref.html + printpreview_pps16.html + printpreview_pps16_ref.html + printpreview_prettyprint.xml + printpreview_prettyprint_ref.xhtml + printpreview_mask.html + print_page_size1.html + print_page_size1_ref.html + print_page_size2.html + print_page_size2_ref.html + print_page_size3.html + print_page_size3_ref.html + print_page_size4.html + print_page_size4_ref.html + red.png + color_adjust.html + color_adjust_ref.html + test_document_adopted_styles.html + test_document_adopted_styles_ref.html + test_shadow_root_adopted_styles.html + test_shadow_root_adopted_styles_ref.html + test_shared_adopted_styles.html + test_shared_adopted_styles_ref.html + file_bug1018265.xhtml + markA.ttf + markB.ttf + +[test_bug396367-1.html] +[test_bug396367-2.html] +[test_bug420499.xhtml] +[test_bug458898.html] +[test_bug465448.xhtml] +support-files = + file_bug465448.html +[test_bug514660.xhtml] +[test_bug533845.xhtml] +skip-if = os == 'linux' && !debug # Bug 1208197 +[test_bug551434.html] +[test_bug708062.html] +[test_bug812817.xhtml] +[test_bug1018265.xhtml] +[test_bug1041200.xhtml] +skip-if = os == 'win' && bits == 64 # Bug 1272321 +support-files = + bug1041200_frame.html + bug1041200_window.html +[test_chrome_content_integration.xhtml] +[test_color_scheme_browser.xhtml] +[test_default_background.xhtml] +[test_dialog_with_positioning.html] +tags = openwindow +[test_fixed_bg_scrolling_repaints.html] +[test_prerendered_transforms.html] +[test_printer_default_settings.html] +[test_printpreview.xhtml] +skip-if = (os == "linux" && bits == 32) || (verify && (os == 'win')) # Disabled on Linux32 for bug 1278957 +[test_printpreview_bug396024.xhtml] +skip-if = (verify && (os == 'win')) +[test_printpreview_bug482976.xhtml] +skip-if = (verify && (os == 'win')) +[test_scrolling_repaints.html] +[test_will_change.html] +skip-if = true +[test_get_printer_basic_attributes.html] +[test_get_printer_paper_sizes.html] +[test_get_printer_orientation.html] +[test_getClientRectsAndTexts.html] +[test_css_visibility_propagation.xhtml] +support-files = + window_css_visibility_propagation-1.xhtml + window_css_visibility_propagation-2.xhtml + window_css_visibility_propagation-3.html + window_css_visibility_propagation-4.html + frame_css_visibility_propagation.html diff --git a/layout/base/tests/chrome/chrome_content_integration_window.xhtml b/layout/base/tests/chrome/chrome_content_integration_window.xhtml new file mode 100644 index 0000000000..1dd1b7f882 --- /dev/null +++ b/layout/base/tests/chrome/chrome_content_integration_window.xhtml @@ -0,0 +1,45 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<window title="Content/chrome integration subwindow" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="runTests()" + style="background:black; -moz-appearance:none;"> + <script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script> + + <stack style="align-items: center; height: 300px; width: 200px;"> + <!-- the bottom 100px is a strip of black that should be visible through the content iframe --> + <vbox style="background:pink; border-bottom:100px solid black"/> + <!-- the middle 100px is a strip of black in the content iframe --> + <!-- the bottom 100px of the iframe is transparent, the top 100px is yellow --> + <iframe type="content" style="border:none; width: 10px; height: 10px;" + transparent="transparent" + src="data:text/html,<div style='position:absolute;left:0;top:0;width:100%;height:100px;background:yellow;border-bottom:100px solid black'>"/> + <!-- the top 100px is a strip of black above the content iframe --> + <vbox style="border-top:100px solid black;"/> + </stack> + + <script type="application/javascript"> + <![CDATA[ + var imports = [ "SimpleTest", "is", "isnot", "ok", "SpecialPowers" ]; + for (var name of imports) { + window[name] = window.arguments[0][name]; + } + + function runTests() { + var testCanvas = snapshotWindow(window); + + var refCanvas = snapshotWindow(window); + var ctx = refCanvas.getContext('2d'); + ctx.fillStyle = "black"; + ctx.fillRect(0, 0, refCanvas.width, refCanvas.height); + + var comparison = compareSnapshots(testCanvas, refCanvas, true); + ok(comparison[0], "Rendering OK, got " + comparison[1] + ", expected " + comparison[2]); + + var tester = window.SimpleTest; + window.close(); + tester.finish(); + } + ]]> + </script> +</window> diff --git a/layout/base/tests/chrome/color_adjust.html b/layout/base/tests/chrome/color_adjust.html new file mode 100644 index 0000000000..4a9846e28d --- /dev/null +++ b/layout/base/tests/chrome/color_adjust.html @@ -0,0 +1,9 @@ +<!doctype html> +<style> +.test { + background-color: black; + color: white; + color-adjust: exact; +} +</style> +<span class="test">Some text goes here</span> diff --git a/layout/base/tests/chrome/color_adjust_ref.html b/layout/base/tests/chrome/color_adjust_ref.html new file mode 100644 index 0000000000..f5986f93bf --- /dev/null +++ b/layout/base/tests/chrome/color_adjust_ref.html @@ -0,0 +1,8 @@ +<!doctype html> +<style> +.test { + background-color: black; + color: white; +} +</style> +<span class="test">Some text goes here</span> diff --git a/layout/base/tests/chrome/default_background_window.xhtml b/layout/base/tests/chrome/default_background_window.xhtml new file mode 100644 index 0000000000..4bc49c0f36 --- /dev/null +++ b/layout/base/tests/chrome/default_background_window.xhtml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="runTests()"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script> + + <iframe type="content" id="f" src="about:blank" style="border:1px solid black;"/> + + <script> + <![CDATA[ + SimpleTest.waitForExplicitFinish(); + + var imports = [ "SimpleTest", "is", "isnot", "ok" ]; + for (var name of imports) { + window[name] = window.arguments[0][name]; + } + + function snapshot(win) { + var el = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas"); + el.width = win.innerWidth; + el.height = win.innerHeight; + + var ctx = el.getContext("2d"); + ctx.drawWindow(win, 0, 0, + win.innerWidth, win.innerHeight, + "rgba(0,0,0,0)", 0); + return el; + } + + var color = '#2468AC'; + var prefs = Cc["@mozilla.org/preferences-service;1"] + .getService(Ci.nsIPrefBranch); + var backgroundPref = matchMedia('(prefers-color-scheme:dark)').matches + ? 'browser.display.background_color.dark' + : 'browser.display.background_color'; + prefs.setCharPref(backgroundPref, color); + // On Windows, this preference is true by default, we make it + // false to ensure we're using the color set above for our reference. + prefs.setBoolPref('browser.display.use_system_colors', false); + + function runTests() { + var f = document.getElementById("f"); + + var testCanvas = snapshot(f.contentWindow); + prefs.clearUserPref(backgroundPref); + // Reset sys colors pref so we're using the system color for our test. + prefs.clearUserPref('browser.display.use_system_colors'); + + var refCanvas = snapshot(f.contentWindow); + var ctx = refCanvas.getContext('2d'); + ctx.fillStyle = color; + ctx.fillRect(0, 0, refCanvas.width, refCanvas.height); + + var comparison = compareSnapshots(testCanvas, refCanvas, true); + ok(comparison[0], "Rendering OK, got " + comparison[1] + ", expected " + comparison[2]); + + + var tester = window.SimpleTest; + window.close(); + tester.finish(); + } + ]]> + </script> +</window> diff --git a/layout/base/tests/chrome/dialog_with_positioning_window.xhtml b/layout/base/tests/chrome/dialog_with_positioning_window.xhtml new file mode 100644 index 0000000000..a854248b21 --- /dev/null +++ b/layout/base/tests/chrome/dialog_with_positioning_window.xhtml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="setTimeout(runTest, 0)"> + <vbox> + <label value="powered by example.com" style="padding: 16px;"/> + </vbox> + <hbox id="t" style="display: block; position: fixed; right: 16px; bottom: 16px;"> + <button label="OK"/> + </hbox> +<script><![CDATA[ +var SimpleTest = window.arguments[0].SimpleTest; +var SpecialPowers = window.arguments[0].SpecialPowers; +var is = window.arguments[0].is; +var ok = window.arguments[0].ok; + +// We run this off a setTimeout from onload, because the XUL window +// only does its intrinsic-height layout after the load event has +// finished +function runTest() { + var t = document.getElementById("t"); + var tBottom = t.getBoundingClientRect().bottom; + is(tBottom, document.documentElement.getBoundingClientRect().bottom - 16, + "check fixed-pos element t bottom positioned correctly"); + ok(tBottom < 200, "fixed-pos element t bottom must be sane, less than 200 (got " + tBottom + ")"); + window.close(); + SimpleTest.finish(); +} +]]></script> +</window> diff --git a/layout/base/tests/chrome/file_bug1018265.xhtml b/layout/base/tests/chrome/file_bug1018265.xhtml new file mode 100644 index 0000000000..a645c325df --- /dev/null +++ b/layout/base/tests/chrome/file_bug1018265.xhtml @@ -0,0 +1,50 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1018265 +--> +<window title="Mozilla Bug 1018265" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="setTimeout(run, 0);"> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for Bug 1018265 **/ + + var testcontent = null; + + function run() { + testcontent = document.getElementById("testcontent"); + shouldHaveTwoNonHiddenContentViewers(); + testcontent.setAttribute("src", "foobarpage"); + setTimeout(errorPageLoaded, 2500) + } + + function errorPageLoaded() { + testcontent.addEventListener("pageshow", didGoBack, true); + setTimeout(function() {testcontent.contentWindow.history.back();}, 0); + } + + function didGoBack(e) { + testcontent.removeEventListener("pageshow", didGoBack, true); + shouldHaveTwoNonHiddenContentViewers(); + window.arguments[0].done(); + window.close(); + } + + function getContentViewer(win) { + return win.docShell.contentViewer; + } + + function shouldHaveTwoNonHiddenContentViewers() { + window.arguments[0].is(getContentViewer(testcontent.contentWindow).isHidden, false, "Top level ContentViewer should not be hidden."); + window.arguments[0].is(getContentViewer(testcontent.contentWindow.frames[0]).isHidden, false, " Iframe's ContentViewer should not be hidden."); + } + ]]> + </script> + + <browser type="content" id="testcontent" flex="1" src="data:text/html,<iframe></iframe>"/> +</window> diff --git a/layout/base/tests/chrome/file_bug458898.html b/layout/base/tests/chrome/file_bug458898.html new file mode 100644 index 0000000000..6db840689d --- /dev/null +++ b/layout/base/tests/chrome/file_bug458898.html @@ -0,0 +1 @@ +<div style='height:200px; width:100px;'> diff --git a/layout/base/tests/chrome/file_bug465448.html b/layout/base/tests/chrome/file_bug465448.html new file mode 100644 index 0000000000..5df5b61375 --- /dev/null +++ b/layout/base/tests/chrome/file_bug465448.html @@ -0,0 +1 @@ +<body onload='window.opener.loaded()'><div style='height:200px; width:100px;'> diff --git a/layout/base/tests/chrome/frame_css_visibility_propagation.html b/layout/base/tests/chrome/frame_css_visibility_propagation.html new file mode 100644 index 0000000000..dbb5d819d1 --- /dev/null +++ b/layout/base/tests/chrome/frame_css_visibility_propagation.html @@ -0,0 +1 @@ +<button id="button">Button</button> diff --git a/layout/base/tests/chrome/green.png b/layout/base/tests/chrome/green.png Binary files differnew file mode 100644 index 0000000000..25b76c3c6f --- /dev/null +++ b/layout/base/tests/chrome/green.png diff --git a/layout/base/tests/chrome/markA.ttf b/layout/base/tests/chrome/markA.ttf Binary files differnew file mode 100644 index 0000000000..353e7ac332 --- /dev/null +++ b/layout/base/tests/chrome/markA.ttf diff --git a/layout/base/tests/chrome/markB.ttf b/layout/base/tests/chrome/markB.ttf Binary files differnew file mode 100644 index 0000000000..c683ddf945 --- /dev/null +++ b/layout/base/tests/chrome/markB.ttf diff --git a/layout/base/tests/chrome/print_page_size1.html b/layout/base/tests/chrome/print_page_size1.html new file mode 100644 index 0000000000..851b910f26 --- /dev/null +++ b/layout/base/tests/chrome/print_page_size1.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<style> +@page { + size: 3in; + margin: 0; +} +div { + position: absolute; + background: blue; + width: 20px; + height: 20px; +} +.upper { + top: 1in; +} +.lower{ + bottom: 1.5in; +} +.left{ + left: 1in; +} +.right{ + right: 1.5in; +} +</style> +<body> +<div class="upper left"></div> +<div class="upper right"></div> +<div class="lower left"></div> +<div class="lower right"></div> +</body> diff --git a/layout/base/tests/chrome/print_page_size1_ref.html b/layout/base/tests/chrome/print_page_size1_ref.html new file mode 100644 index 0000000000..cc3ff8598f --- /dev/null +++ b/layout/base/tests/chrome/print_page_size1_ref.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<style> +@page { + size: 2in; + margin: 0.5in; +} +div { + position: absolute; + background: blue; + width: 20px; + height: 20px; +} +.upper { + top: 0.5in; +} +.lower{ + bottom: 0; +} +.left{ + left: 0.5in; +} +.right{ + right: 0; +} +</style> +<body> +<div class="upper left"></div> +<div class="upper right"></div> +<div class="lower left"></div> +<div class="lower right"></div> +</body> diff --git a/layout/base/tests/chrome/print_page_size2.html b/layout/base/tests/chrome/print_page_size2.html new file mode 100644 index 0000000000..d9a181576d --- /dev/null +++ b/layout/base/tests/chrome/print_page_size2.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<style> +@page { + size: 20in 3in; + margin: 0; +} +div { + position: absolute; + background: blue; + width: 20px; + height: 20px; +} +.upper { + top: 0; +} +.lower{ + bottom: 0; +} +.left{ + left: 0; +} +.right{ + right: 0; +} +</style> +<body> +<div class="upper left"></div> +<div class="upper right"></div> +<div class="lower left"></div> +<div class="lower right"></div> +</body> diff --git a/layout/base/tests/chrome/print_page_size2_ref.html b/layout/base/tests/chrome/print_page_size2_ref.html new file mode 100644 index 0000000000..0a40acc0eb --- /dev/null +++ b/layout/base/tests/chrome/print_page_size2_ref.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<style> +@page { + size: 20in 5in; + margin: 0; +} +div { + position: absolute; + background: blue; + width: 20px; + height: 20px; +} +.upper { + top: 0; +} +.lower{ + /* This accounts for the difference in @page{ size: ... }, as long as the + * page is placed aligned to the upper left corner of the paper. + */ + bottom: 2in; +} +.left{ + left: 0; +} +.right{ + right: 0; +} +</style> +<body> +<div class="upper left"></div> +<div class="upper right"></div> +<div class="lower left"></div> +<div class="lower right"></div> +</body> diff --git a/layout/base/tests/chrome/print_page_size3.html b/layout/base/tests/chrome/print_page_size3.html new file mode 100644 index 0000000000..45c9709817 --- /dev/null +++ b/layout/base/tests/chrome/print_page_size3.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<style> +@page { + size: 3in; + margin: 0; +} +div { + position: absolute; + background: blue; + width: 1in; + height: 1in; +} +.upper { + top: 0in; +} +.lower{ + bottom: 0in; +} +.left{ + left: 0in; +} +.right{ + right: 0in; +} +</style> +<body> +<div class="upper left"></div> +<div class="upper right"></div> +<div class="lower left"></div> +<div class="lower right"></div> +</body> diff --git a/layout/base/tests/chrome/print_page_size3_ref.html b/layout/base/tests/chrome/print_page_size3_ref.html new file mode 100644 index 0000000000..cc6f69a7ad --- /dev/null +++ b/layout/base/tests/chrome/print_page_size3_ref.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<style> +@page { + margin: 0; +} +div { + position: absolute; + background: blue; + width: 1in; + height: 1in; +} +/* These positions assume the test case was placed in the upper left corner of + * the page, rather than being centered or scaled. + */ +.upper { + top: 0; +} +.lower{ + top: 2in; +} +.left{ + left: 0; +} +.right{ + left: 2in; +} +</style> +<body> +<div class="upper left"></div> +<div class="upper right"></div> +<div class="lower left"></div> +<div class="lower right"></div> +</body> diff --git a/layout/base/tests/chrome/print_page_size4.html b/layout/base/tests/chrome/print_page_size4.html new file mode 100644 index 0000000000..ef6077e2a1 --- /dev/null +++ b/layout/base/tests/chrome/print_page_size4.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<style> +@page { + size: 10in; + margin: 0; +} +div { + position: absolute; + background: blue; + width: 1in; + height: 1in; +} +.upper { + top: 0; +} +.lower{ + bottom: 0; +} +.left{ + left: 0; +} +.right{ + right: 0; +} +</style> +<body> +<div class="upper left"></div> +<div class="upper right"></div> +<div class="lower left"></div> +<div class="lower right"></div> +</body> diff --git a/layout/base/tests/chrome/print_page_size4_ref.html b/layout/base/tests/chrome/print_page_size4_ref.html new file mode 100644 index 0000000000..3d32134824 --- /dev/null +++ b/layout/base/tests/chrome/print_page_size4_ref.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<style> +@page { + size: 20in; + margin: 0; +} +div { + position: absolute; + background: blue; + width: 2in; + height: 2in; +} +.upper { + top: 0; +} +.lower{ + bottom: 0; +} +.left{ + left: 0; +} +.right{ + right: 0; +} +</style> +<body> +<div class="upper left"></div> +<div class="upper right"></div> +<div class="lower left"></div> +<div class="lower right"></div> +</body> diff --git a/layout/base/tests/chrome/printpreview_bug1713404_ref.html b/layout/base/tests/chrome/printpreview_bug1713404_ref.html new file mode 100644 index 0000000000..a08074b8a2 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_bug1713404_ref.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<style> +@page { + margin: 2in; +} +div { + /* The default header/footer size in Firefox. */ + font-size: 10pt; + position: absolute; +} +.upper { + top: 0; +} +.lower{ + bottom: 0; +} +.left{ + left: 0; +} +.right{ + right: 0; +} +</style> +<div class="upper left">|</div> +<div class="upper right">||</div> +<div class="lower left">|||</div> +<div class="lower right">||||</div> diff --git a/layout/base/tests/chrome/printpreview_bug1730091_ref.html b/layout/base/tests/chrome/printpreview_bug1730091_ref.html new file mode 100644 index 0000000000..ac1577b852 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_bug1730091_ref.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<style> +@page{ + margin: 0; +} +div { + /* The default header/footer size in Firefox */ + font-size: 10pt; + position: absolute; +} +.upper { + top: 0; +} +.lower{ + bottom: 0; +} +.left{ + left: 0; +} +.right{ + right: 0; +} +</style> +<div class="upper left">||||</div> +<div class="upper right">||||</div> +<div class="lower left">||||</div> +<div class="lower right">||||</div> diff --git a/layout/base/tests/chrome/printpreview_bug396024_helper.xhtml b/layout/base/tests/chrome/printpreview_bug396024_helper.xhtml new file mode 100644 index 0000000000..404e689ef7 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_bug396024_helper.xhtml @@ -0,0 +1,112 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=396024 +--> +<window title="Mozilla Bug 396024" onload="run()" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> +<iframe id="i" src="about:blank" type="content"></iframe> +<iframe src="about:blank" type="content"></iframe> +<script type="application/javascript"> +<![CDATA[ +// Note: We can't use window.frames directly here because the type="content" +// attributes isolate the frames into their own BrowsingContext hierarchies. +let frameElts = document.getElementsByTagName("iframe"); + +var is = window.arguments[0].is; +var ok = window.arguments[0].ok; +var todo = window.arguments[0].todo; +var SimpleTest = window.arguments[0].SimpleTest; +var gWbp; +function printpreview() { + gWbp = frameElts[1].contentWindow.docShell.initOrReusePrintPreviewViewer(); + var listener = { + onLocationChange: function(webProgress, request, location, flags) { }, + onProgressChange: function(webProgress, request, curSelfProgress, + maxSelfProgress, curTotalProgress, + maxTotalProgress) { }, + onSecurityChange: function(webProgress, request, state) { }, + onStateChange: function(webProgress, request, stateFlags, status) { }, + onStatusChange: function(webProgress, request, status, message) { }, + onContentBlockingEvent: function(webProgress, request, event) { }, + QueryInterface: function(iid) { + if (iid.equals(Ci.nsIWebProgressListener) || + iid.equals(Ci.nsISupportsWeakReference)) + return this; + throw Components.Exception("", Cr.NS_NOINTERFACE); + } + } + let settings = Cc["@mozilla.org/gfx/printsettings-service;1"] + .getService(Ci.nsIPrintSettingsService).createNewPrintSettings(); + gWbp.printPreview(settings, frameElts[0].contentWindow, listener); +} + +function exitprintpreview() { + frameElts[1].contentWindow.docShell.exitPrintPreview(); +} + +function finish() { + SimpleTest.finish(); + window.close(); +} + +function run() +{ +/** Test for Bug 396024 **/ + var printService = Cc["@mozilla.org/gfx/printsettings-service;1"] + .getService(Ci.nsIPrintSettingsService); + + if (printService.lastUsedPrinterName != '') { + printpreview(); + ok(gWbp.doingPrintPreview, "Should be doing print preview"); + exitprintpreview(); + ok(!gWbp.doingPrintPreview, "Should not be doing print preview anymore1"); + printpreview(); + setTimeout(run2, 0) + } else { + todo(false, "No printer seems installed on this machine, that is necessary for this test"); + finish(); + } +} + +function run2() { + var loadhandler = function() { + document.getElementById("i").removeEventListener("load", arguments.callee, true); + setTimeout(run3, 0); + }; + document.getElementById("i").addEventListener("load", loadhandler, true); + frameElts[0].contentWindow.location.reload(); +} + +function run3() { + gWbp = frameElts[1].contentWindow.docShell.initOrReusePrintPreviewViewer(); + ok(gWbp.doingPrintPreview, "Should be doing print preview"); + exitprintpreview(); + setTimeout(run4, 0); +} + +function run4() { + var i = document.getElementById("i"); + i.remove(); + var loadhandler = function() { + document.getElementById("i").removeEventListener("load", loadhandler, true); + setTimeout(run5, 0); + }; + i.addEventListener("load", loadhandler, true); + document.documentElement.getBoundingClientRect(); + document.documentElement.prepend(i); +} + +function run5() { + gWbp = frameElts[1].contentWindow.docShell.initOrReusePrintPreviewViewer(); + ok(!gWbp.doingPrintPreview, "Should not be doing print preview anymore2"); + + //XXX this shouldn't be necessary, see bug 405555 + printpreview(); + exitprintpreview(); + finish(); //should not have crashed after all of this +} +]]></script> +</window> diff --git a/layout/base/tests/chrome/printpreview_bug482976_helper.xhtml b/layout/base/tests/chrome/printpreview_bug482976_helper.xhtml new file mode 100644 index 0000000000..cd23c90d7b --- /dev/null +++ b/layout/base/tests/chrome/printpreview_bug482976_helper.xhtml @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=482976 +--> +<window title="Mozilla Bug 482976" onload="run1()" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> +<iframe src="about:blank" type="content"></iframe> +<iframe src="about:blank" type="content"></iframe> +<script type="application/javascript"> +<![CDATA[ +// Note: We can't use window.frames directly here because the type="content" +// attributes isolate the frames into their own BrowsingContext hierarchies. +let frameElts = document.getElementsByTagName("iframe"); + +var is = window.arguments[0].is; +var ok = window.arguments[0].ok; +var todo = window.arguments[0].todo; +var SimpleTest = window.arguments[0].SimpleTest; +var gWbp; +var gPrintPreviewWin; +function printpreview() { + var listener = { + onLocationChange: function(webProgress, request, location, flags) { }, + onProgressChange: function(webProgress, request, curSelfProgress, + maxSelfProgress, curTotalProgress, + maxTotalProgress) { }, + onSecurityChange: function(webProgress, request, state) { }, + onStateChange: function(webProgress, request, stateFlags, status) { }, + onStatusChange: function(webProgress, request, status, message) { }, + onContentBlockingEvent: function(webProgress, request, event) { }, + QueryInterface: function(iid) { + if (iid.equals(Ci.nsIWebProgressListener) || + iid.equals(Ci.nsISupportsWeakReference)) + return this; + throw Components.Exception("", Cr.NS_NOINTERFACE); + } + } + + let settings = Cc["@mozilla.org/gfx/printsettings-service;1"] + .getService(Ci.nsIPrintSettingsService).createNewPrintSettings(); + + gPrintPreviewWin = frameElts[0].contentWindow.printPreview(settings, listener); + gWbp = gPrintPreviewWin.docShell.contentViewer; + gWbp.QueryInterface(Ci.nsIWebBrowserPrint); +} + +function exitprintpreview() { + gPrintPreviewWin.docShell.exitPrintPreview(); + gPrintPreviewWin.close(); +} + +function finish() { + SimpleTest.finish(); + window.close(); +} + +async function run1() { + printpreview(); + ok(gWbp.doingPrintPreview, "Should be doing print preview"); + exitprintpreview(); + ok(!gWbp.doingPrintPreview, "Should not be doing print preview anymore"); + finish(); +} +]]></script> +</window> diff --git a/layout/base/tests/chrome/printpreview_downloadable_font.html b/layout/base/tests/chrome/printpreview_downloadable_font.html new file mode 100644 index 0000000000..6e30c55f79 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_downloadable_font.html @@ -0,0 +1,24 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html lang="en-US"> +<head> +<title></title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<link rel="help" href="https://drafts.csswg.org/css-fonts/#font-face-rule"> +<style type="text/css"> + +@font-face { + font-family: "MarkA"; + src: url(markA.ttf); +} + +body { font-family: "MarkA"; } + +</style> +</head> +<body> + +<p>A</p> + +</body> +</html> diff --git a/layout/base/tests/chrome/printpreview_downloadable_font_in_iframe.html b/layout/base/tests/chrome/printpreview_downloadable_font_in_iframe.html new file mode 100644 index 0000000000..edee6ecca2 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_downloadable_font_in_iframe.html @@ -0,0 +1,25 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html lang="en-US"> +<head> +<title></title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<link rel="help" href="https://drafts.csswg.org/css-fonts/#font-face-rule"> +</head> +<iframe style="width:300px; height: 300px; border: 0" + srcdoc="<!DOCTYPE HTML> + <html> + <style> + @font-face { + font-family: 'MarkA'; + src: url(markA.ttf); + } + + body { font-family: 'MarkA'; } + </style> + <body> + <p>A</p> + </body> + </html>"> +</iframe> +</html> diff --git a/layout/base/tests/chrome/printpreview_downloadable_font_in_iframe_ref.html b/layout/base/tests/chrome/printpreview_downloadable_font_in_iframe_ref.html new file mode 100644 index 0000000000..0a2a50c665 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_downloadable_font_in_iframe_ref.html @@ -0,0 +1,24 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html lang="en-US"> +<head> +<title></title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +</head> +<iframe style="width:300px; height: 300px; border: 0" + srcdoc="<!DOCTYPE HTML> + <html> + <style> + @font-face { + font-family: 'MarkB'; + src: url(markB.ttf); + } + + body { font-family: 'MarkB'; } + </style> + <body> + <p>B</p> + </body> + </html>"> +</iframe> +</html> diff --git a/layout/base/tests/chrome/printpreview_downloadable_font_ref.html b/layout/base/tests/chrome/printpreview_downloadable_font_ref.html new file mode 100644 index 0000000000..5967abb5ba --- /dev/null +++ b/layout/base/tests/chrome/printpreview_downloadable_font_ref.html @@ -0,0 +1,23 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html lang="en-US"> +<head> +<title></title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<style type="text/css"> + +@font-face { + font-family: "MarkB"; + src: url(markB.ttf); +} + +body { font-family: "MarkB"; } + +</style> +</head> +<body> + +<p>B</p> + +</body> +</html> diff --git a/layout/base/tests/chrome/printpreview_font_api.html b/layout/base/tests/chrome/printpreview_font_api.html new file mode 100644 index 0000000000..1f82d5f2d9 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_font_api.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <style type="text/css"> + .test { + font-family: test, monospace; + } + </style> +</head> +<body> + <p class="test">lmnop</p> + <script> + const fontData = "data:font/opentype;base64,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"; + + let testFontFace = new FontFace('test', 'url(' + fontData + ')'); + document.fonts.add(testFontFace); + testFontFace.loaded.then(() => { + window.postMessage("ready", "*"); + }).catch((e) => { + window.postMessage("error", "*"); + }); + </script> +</body> +</html>
\ No newline at end of file diff --git a/layout/base/tests/chrome/printpreview_font_api_ref.html b/layout/base/tests/chrome/printpreview_font_api_ref.html new file mode 100644 index 0000000000..61b052b4a6 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_font_api_ref.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <style type="text/css"> + @font-face { + font-family: test; + src: url(data:font/opentype;base64,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); + } + .test { + /* + * Intentionally use a different fallback font than the test file so that + * if the font fails to load the test and reference will still be + * different. + */ + font-family: test, sans-serif; + } + </style> +</head> +<body> + <p class="test">lmnop</p> +</body> +</html> diff --git a/layout/base/tests/chrome/printpreview_font_mozprintcallback.html b/layout/base/tests/chrome/printpreview_font_mozprintcallback.html new file mode 100644 index 0000000000..1b4296e90a --- /dev/null +++ b/layout/base/tests/chrome/printpreview_font_mozprintcallback.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> +</head> +<body> + <canvas id="canvas" width="200" height="200"></canvas> + <script> + const fontData = "data:font/opentype;base64,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"; + let canvas = document.getElementById('canvas'); + canvas.mozPrintCallback = (obj) => { + let testFontFace = new FontFace('test', 'url(' + fontData + ')'); + document.fonts.add(testFontFace); + testFontFace.load().then(() => { + let ctx = obj.context; + ctx.font = '10px test, monospace'; + ctx.fillText("lmnop", 20, 20); + obj.done(); + window.postMessage("ready", "*"); + }).catch((e) => { + obj.done(); + window.postMessage("error", "*"); + }); + }; + </script> +</body> +</html> diff --git a/layout/base/tests/chrome/printpreview_font_mozprintcallback_ref.html b/layout/base/tests/chrome/printpreview_font_mozprintcallback_ref.html new file mode 100644 index 0000000000..e4dd82bc58 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_font_mozprintcallback_ref.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <style type="text/css"> + @font-face { + font-family: test; + src: url(data:font/opentype;base64,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); + } + </style> +</head> +<body> + <canvas id="canvas" width="200" height="200"></canvas> + <script> + let canvas = document.getElementById('canvas'); + canvas.mozPrintCallback = (obj) => { + let ctx = obj.context; + // Intentionally use a different fallback font than the test file so that + // if the font fails to load the test and reference will still be + // different. + ctx.font = '10px test, sans-serif'; + ctx.fillText("lmnop", 20, 20); + obj.done(); + window.postMessage("ready", "*"); + }; + </script> +</body> +</html> diff --git a/layout/base/tests/chrome/printpreview_helper.xhtml b/layout/base/tests/chrome/printpreview_helper.xhtml new file mode 100644 index 0000000000..055f75c8f5 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_helper.xhtml @@ -0,0 +1,1721 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<window onload="runTests()" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <iframe style="min-height: 200px; min-width: 600px" type="content"></iframe> + <iframe style="min-height: 200px; min-width: 600px" type="content"></iframe> +<script type="application/javascript"> +<![CDATA[ +// Note: We can't use window.frames directly here because the type="content" +// attributes isolate the frames into their own BrowsingContext hierarchies. +let frameElts = document.getElementsByTagName("iframe"); + +var is = window.arguments[0].is; +var isnot = window.arguments[0].isnot; +var ok = window.arguments[0].ok; +var todo = window.arguments[0].todo; +var info = window.arguments[0].info; +var SimpleTest = window.arguments[0].SimpleTest; +var gWbp; +var gPrintPreviewWindow; +var gPrintPreviewBrowser; +var ctx1; +var ctx2; +var counter = 0; + +var file = Cc["@mozilla.org/file/directory_service;1"] + .getService(Ci.nsIProperties) + .get("TmpD", Ci.nsIFile); +filePath = file.path; + +function printpreview(options = {}) { + let resolve; + let promise = new Promise(r => { resolve = r }); + var listener = { + onLocationChange: function(webProgress, request, location, flags) { }, + onProgressChange: function(webProgress, request, curSelfProgress, + maxSelfProgress, curTotalProgress, + maxTotalProgress) { + info("onProgressChange", [...arguments].join(", ")); + }, + onSecurityChange: function(webProgress, request, state) { }, + onStateChange: function(webProgress, request, stateFlags, status) { + info("onStateChange", [...arguments].join(", ")); + if (stateFlags & Ci.nsIWebProgressListener.STATE_STOP) { + setTimeout(resolve, 0); + } + }, + onStatusChange: function(webProgress, request, status, message) { + info("onStatusChange", [...arguments].join(", ")); + }, + onContentBlockingEvent: function(webProgress, request, event) { + info("onContentBlockingEvent", [...arguments].join(", ")); + }, + QueryInterface: function(iid) { + if (iid.equals(Ci.nsIWebProgressListener) || + iid.equals(Ci.nsISupportsWeakReference)) + return this; + throw Components.Exception("", Cr.NS_NOINTERFACE); + } + } + var settings = Cc["@mozilla.org/gfx/printsettings-service;1"] + .getService(Ci.nsIPrintSettingsService).createNewPrintSettings(); + settings.printBGColors = true; + settings.headerStrLeft = ""; + settings.headerStrRight = ""; + settings.footerStrLeft = ""; + settings.footerStrRight = ""; + settings.unwriteableMarginTop = 0; + settings.unwriteableMarginRight = 0; + settings.unwriteableMarginLeft = 0; + settings.unwriteableMarginBottom = 0; + if (options.settings) { + for (let key in options.settings) { + settings[key] = options.settings[key]; + } + } + var before = 0; + var after = 0; + function beforeprint() { ++before; } + function afterprint() { ++after; } + frameElts[0].contentWindow.addEventListener("beforeprint", beforeprint, true); + frameElts[0].contentWindow.addEventListener("afterprint", afterprint, true); + { + let bc = frameElts[0].contentWindow.browsingContext; + let browser = document.createXULElement("browser"); + browser.setAttribute("type", "content"); + browser.style.minHeight = "800px"; + browser.style.maxWidth = browser.style.minWidth = "800px"; + browser.setAttribute("initialBrowsingContextGroupId", bc.group.id); + browser.setAttribute("nodefaultsrc", "true"); + document.documentElement.appendChild(browser); + gPrintPreviewBrowser = browser; + + // Force contentViewer creation and layout. + browser.browsingContext.docShell.document; + browser.getBoundingClientRect(); + + gPrintPreviewWindow = frameElts[0].contentWindow.printPreview(settings, listener, browser.browsingContext.docShell); + } + gWbp = gPrintPreviewWindow.docShell.contentViewer; + gWbp.QueryInterface(Ci.nsIWebBrowserPrint); + is(before, 1, "Should have called beforeprint listener!"); + if (!options.hasMozPrintCallback) { + // If there's a mozPrintCallback the after print event won't fire until + // later. + is(after, 1, "Should have called afterprint listener!"); + } + frameElts[0].contentWindow.removeEventListener("beforeprint", beforeprint, true); + frameElts[0].contentWindow.removeEventListener("afterprint", afterprint, true); + return promise; +} + +function exitprintpreview() { + gPrintPreviewWindow.docShell.exitPrintPreview(); + gPrintPreviewBrowser.remove(); +} + +function finish() { + SimpleTest.finish(); + window.close(); +} + +async function runTests() +{ + // This ensures we actually test the lazy-load of images in printpreview_images. + await SpecialPowers.pushPrefEnv({ + set: [ + ["dom.image-lazy-loading.root-margin.top", 0], + ["dom.image-lazy-loading.root-margin.bottom", 0], + ["dom.image-lazy-loading.root-margin.left", 0], + ["dom.image-lazy-loading.root-margin.right", 0], + ], + }); + startTest1(); +} + +function compareCanvases(options = {}) { + const canvas1 = document.getElementsByTagName("canvas")[0]; + const canvas2 = document.getElementsByTagName("canvas")[1]; + let maxDifference = {}; + const differingPixels = window.windowUtils.compareCanvases(canvas1, canvas2, maxDifference); + if (differingPixels) { + todo(false, "different: " + differingPixels + ", maxDifference: " + maxDifference.value); + todo(false, "TEST CASE: " + canvas1.toDataURL()); + todo(false, "REFERENCE: " + canvas2.toDataURL()); + } + + let maxAllowedDifferent = options.maxDifferent || 0; + let maxAllowedDifference = options.maxDifference || 0; + return differingPixels <= maxAllowedDifferent && maxDifference.value <= maxAllowedDifference; +} + +function addHTMLContent(parent) { + var n = parent.ownerDocument.createElement("div"); + parent.appendChild(n); + var s = "<iframe width='500' height='40' src='data:text/plain,ThisIsAnIframeCreatedDuringPrintPreview'></iframe>"; + s += "<table>"; + for (var i = 1; i < 501; ++i) { + s += "<tr><td>Cell A" + i + "</td><td>Cell B" + i + "</td><td>Cell C" + i + "</td></tr>"; + } + s += "</table>"; + n.innerHTML = s; +} + +async function startTest1() { + ctx1 = document.getElementsByTagName("canvas")[0].getContext("2d"); + ctx2 = document.getElementsByTagName("canvas")[1].getContext("2d"); + frameElts[0].contentDocument.body.innerHTML = "<div> </div><div>" + counter + " timers</div><div> </div>"; + + // Note this timeout is needed so that we can check that timers run + // after print preview, but not during it. + frameElts[0].contentWindow.wrappedJSObject.counter = counter; + frameElts[0].contentWindow.counterTimeout = "document.body.firstChild.nextSibling.innerHTML = ++counter + ' timers';" + + "window.setTimeout(counterTimeout, 0);"; + frameElts[0].contentWindow.setTimeout(frameElts[0].contentWindow.counterTimeout, 0); + frameElts[0].contentDocument.body.firstChild.innerHTML = "Print preview"; + + await printpreview(); + drawPrintPreviewWindow(ctx1); + frameElts[0].contentDocument.body.firstChild.innerHTML = "Galley presentation"; + + // Add some elements. + addHTMLContent(frameElts[0].contentDocument.body.lastChild); + // Delete them. + frameElts[0].contentDocument.body.lastChild.innerHTML = ""; + // And readd. + addHTMLContent(frameElts[0].contentDocument.body.lastChild); + + setTimeout(finalizeTest1, 1000); +} + +function finalizeTest1() { + drawPrintPreviewWindow(ctx2); + exitprintpreview(); + ok(compareCanvases(), "Canvas should be the same!"); + counter = frameElts[0].contentWindow.counter; + // This timeout is needed so that we can check that timers do run after + // print preview. + setTimeout(runTest2, 1000); +} + +function runTest2() { + isnot(frameElts[0].contentDocument.body.firstChild.nextSibling.textContent, "0 timers", "Timers should have run!"); + isnot(frameElts[0].contentWindow.counter, 0, "Timers should have run!"); + counter = frameElts[0].contentWindow.counter; + frameElts[0].contentWindow.counterTimeout = ""; + setTimeout(runTest3, 0); +} + +var elementIndex = 0; +var compareEmptyElement = true; +var emptyFormElements = + ["<input type='text'>", + "<input type='password'>", + "<input type='file'>", + "<input type='button'>", + "<input type='submit'>", + "<input type='reset'>", + "<input type='checkbox'>", + "<input type='radio'>", + "<select></select>", + "<select size='5'></select>", + "<textarea></textarea>"]; + +var formElements = + ["<input type='text' value='text'>", + "<input type='password' value='password'>", + "<input type='file' value='" + filePath + "'>", + "<input type='button' value='button'>", + "<input type='submit' value='submit button'>", + "<input type='reset' value='reset button'>", + "<input type='checkbox' checked>", + "<input type='radio' checked>", + "<select><option>option1</option></select>", + "<select size='5'><option>1</option><option>2</option><option>3</option></select>", + "<textarea value='textarea'>textarea</textarea>"]; + +function runTest3() { + if (compareEmptyElement) { + var currentIndex = elementIndex; + ++elementIndex; + if (elementIndex >= emptyFormElements.length) { + elementIndex = 0; + compareEmptyElement = false; + } + compareFormElementPrint(emptyFormElements[currentIndex], emptyFormElements[currentIndex], true); + return; + } else if (elementIndex < emptyFormElements.length) { + var currentIndex = elementIndex; + ++elementIndex; + compareFormElementPrint(emptyFormElements[currentIndex], formElements[currentIndex], false); + return; + } + + setTimeout(runTest4, 0) +} + +async function compareFormElementPrint(el1, el2, equals) { + frameElts[0].contentDocument.body.innerHTML = el1; + frameElts[0].contentDocument.body.firstChild.value = + frameElts[0].contentDocument.body.firstChild.getAttribute('value'); + await printpreview(); + drawPrintPreviewWindow(ctx1); + exitprintpreview(); + frameElts[0].contentDocument.body.innerHTML = el2; + frameElts[0].contentDocument.body.firstChild.value = + frameElts[0].contentDocument.body.firstChild.getAttribute('value'); + await printpreview(); + drawPrintPreviewWindow(ctx2); + exitprintpreview(); + is(compareCanvases(), equals, + "Comparing print preview didn't succeed [" + el1 + " : " + el2 + "]"); + setTimeout(runTest3, 100); +} + +// This is a crash test for bug 539060. +function runTest4() { + frameElts[0].contentDocument.body.innerHTML = + "<iframe style='display: none;' src='data:text/html,<iframe>'></iframe>"; + setTimeout(runTest4end, 500); +} + +async function runTest4end() { + await printpreview(); + exitprintpreview(); + + runTest5(); +} + +// This is a crash test for bug 595337 +async function runTest5() { + frameElts[0].contentDocument.body.innerHTML = + '<iframe style="position: fixed; visibility: hidden; bottom: 10em;"></iframe>' + + '<input contenteditable="true" style="display: table; page-break-before: left; width: 10000px;">'; + await printpreview(); + exitprintpreview(); + + setTimeout(runTest6, 0); +} + +// Crash test for bug 878037 +function runTest6() { + frameElts[0].contentDocument.body.innerHTML = + '<style> li { list-style-image: url("animated.gif"); } </style>' + + '<li>Firefox will crash if you try and print this page</li>'; + + setTimeout(runTest6end, 500); +} + +async function runTest6end() { + await printpreview(); + exitprintpreview(); + + requestAnimationFrame(function() { setTimeout(runTest7); } ); +} + +async function runTest7() { + var contentText = "<a href='#'>mozilla</a><input>test<select><option>option1</option></select>"; + // Create normal content + frameElts[0].contentDocument.body.innerHTML = + "<div>" + contentText + "</div>"; + frameElts[0].contentDocument.body.firstChild.value = + frameElts[0].contentDocument.body.firstChild.getAttribute('value'); + await printpreview(); + drawPrintPreviewWindow(ctx1); + exitprintpreview(); + + frameElts[0].contentDocument.body.innerHTML = "<div></div>"; + var sr = frameElts[0].contentDocument.body.firstChild.attachShadow({mode: "open"}); + sr.innerHTML = contentText; + await printpreview(); + drawPrintPreviewWindow(ctx2); + exitprintpreview(); + ok(compareCanvases(), "Printing light DOM and shadow DOM should create same output"); + + requestAnimationFrame(function() { setTimeout(runTest8); } ); +} + +async function runTest8() { + // Test that fonts loaded with CSS and JS are printed the same. + const iframeElement = document.getElementsByTagName("iframe")[0]; + + // First, snapshot the page with font defined in CSS. + await new Promise((resolve) => { + iframeElement.addEventListener("load", resolve, { capture: true, once: true }); + iframeElement.setAttribute("src", "printpreview_font_api_ref.html"); + }); + await printpreview(); + drawPrintPreviewWindow(ctx1); + exitprintpreview(); + + // Second, snapshot the page with font loaded in JS. + await new Promise((resolve) => { + iframeElement.addEventListener("message", resolve, { capture: true, once: true }); + iframeElement.setAttribute("src", "printpreview_font_api.html"); + }); + await printpreview(); + drawPrintPreviewWindow(ctx2); + exitprintpreview(); + ok(compareCanvases(), "Printing pages with fonts loaded from CSS and JS should be the same."); + + requestAnimationFrame(function() { setTimeout(runTest9); } ); +} + +// Test for bug 1487649 +async function runTest9() { + frameElts[0].contentDocument.body.innerHTML = ` + <svg width="100" height="100"> + <rect width='100' height='100' fill='lime'/> + </svg> + `; + + await printpreview(); + drawPrintPreviewWindow(ctx1); + exitprintpreview(); + + frameElts[0].contentDocument.body.innerHTML = ` + <svg width="100" height="100"> + <defs> + <g id="useme"> + <rect width='100' height='100' fill='lime'/> + </g> + </defs> + <use /> + </svg> + `; + + // Set the attribute explicitly because this is a chrome document, and the + // href attribute would get sanitized. + frameElts[0].contentDocument.querySelector("use").setAttribute("href", "#useme"); + + // Ensure the <use> shadow tree is created so we test what we want to test. + frameElts[0].contentDocument.body.offsetTop; + + await printpreview(); + drawPrintPreviewWindow(ctx2); + exitprintpreview(); + ok(compareCanvases(), "Printing <use> subtrees should create same output"); + + requestAnimationFrame(function() { setTimeout(runTest10); } ); +} + +function drawPrintPreviewWindow(ctx) { + let width = gPrintPreviewWindow.innerWidth; + let height = gPrintPreviewWindow.innerHeight; + ctx.canvas.width = width; + ctx.canvas.height = height; + ctx.drawWindow(gPrintPreviewWindow, 0, 0, width, height, "rgb(255, 255, 255)"); +} + +// Test for bug 1524640 +async function runTest10() { + // Test that fonts loaded during mozprint callback are loaded into the cloned + // document. + const iframeElement = document.getElementsByTagName("iframe")[0]; + + // First, snapshot the page with font defined in CSS. + await new Promise((resolve) => { + iframeElement.addEventListener("load", resolve, { capture: true, once: true }); + iframeElement.setAttribute("src", "printpreview_font_mozprintcallback_ref.html"); + }); + let mozPrintCallbackDone = new Promise((resolve) => { + iframeElement.addEventListener("message", resolve, { capture: true, once: true }); + }); + await printpreview({ hasMozPrintCallback: true }); + await mozPrintCallbackDone; + drawPrintPreviewWindow(ctx1); + exitprintpreview(); + + // Second, snapshot the page with font loaded in JS. + await new Promise((resolve) => { + iframeElement.addEventListener("load", resolve, { capture: true, once: true }); + iframeElement.setAttribute("src", "printpreview_font_mozprintcallback.html"); + }); + mozPrintCallbackDone = new Promise((resolve) => { + iframeElement.addEventListener("message", resolve, { capture: true, once: true }); + }); + await printpreview({ hasMozPrintCallback: true }); + // Wait for the mozprintcallback to finish. + await mozPrintCallbackDone; + drawPrintPreviewWindow(ctx2); + + exitprintpreview(); + ok(compareCanvases(), "Printing pages with fonts loaded from a mozPrintCallback should be the same."); + + requestAnimationFrame(function() { setTimeout(runTest11); } ); +} + +async function compareFiles(src1, src2, options = {}) { + const BASE = "https://example.org/chrome/layout/base/tests/chrome/"; + + info(`Comparing ${src1} with ${src2}`); + const iframeElement = document.getElementsByTagName("iframe")[0]; + + let messagePromise = null; + if (options.waitForMessage) { + messagePromise = new Promise(resolve => { + iframeElement.addEventListener("message", resolve, { capture: true, once: true }); + }); + } + + await new Promise((resolve) => { + iframeElement.addEventListener("load", resolve, { capture: true, once: true }); + iframeElement.setAttribute("src", new URL(src1, BASE).href); + }); + let mediaElements = iframeElement.contentDocument.querySelectorAll( + "audio, video" + ); + for (let mediaElement of mediaElements) { + let { widget } = SpecialPowers.wrap(iframeElement.contentWindow) + .windowGlobalChild.getActor("UAWidgets") + .widgets.get(mediaElement); + await widget.impl.Utils.l10n.translateRoots(); + } + + if (messagePromise) { + info("awaiting for message to arrive"); + await messagePromise; + } + + await printpreview(options.test || options); + drawPrintPreviewWindow(ctx1); + exitprintpreview(); + + await new Promise((resolve) => { + iframeElement.addEventListener("load", resolve, { capture: true, once: true }); + iframeElement.setAttribute("src", new URL(src2, BASE).href); + }); + mediaElements = iframeElement.contentDocument.querySelectorAll( + "audio, video" + ); + for (let mediaElement of mediaElements) { + let { widget } = SpecialPowers.wrap(iframeElement.contentWindow) + .windowGlobalChild.getActor("UAWidgets") + .widgets.get(mediaElement); + await widget.impl.Utils.l10n.translateRoots(); + } + + await printpreview(options.ref || options); + drawPrintPreviewWindow(ctx2); + exitprintpreview(); + + is(compareCanvases(options), !options.expectDifference, `Printing ${src1} and ${src2} should${options.expectDifference ? ' not' : ''} produce the same results`); +} + +// bug 1567105 +async function runTest11() { + await compareFiles("printpreview_quirks.html", "printpreview_quirks_ref.html"); + requestAnimationFrame(function() { setTimeout(runTest12); } ); +} + +// bug 1621415 +async function runTest12() { + await compareFiles("test_document_adopted_styles.html", "test_document_adopted_styles_ref.html"); + requestAnimationFrame(function() { setTimeout(runTest13); } ); +} + +// bug 1621415 +async function runTest13() { + await compareFiles("test_shadow_root_adopted_styles.html", "test_shadow_root_adopted_styles_ref.html"); + requestAnimationFrame(function() { setTimeout(runTest14); } ); +} + +// bug 1622322 +async function runTest14() { + await compareFiles("test_shared_adopted_styles.html", "test_shared_adopted_styles_ref.html"); + requestAnimationFrame(function() { setTimeout(runTest15); } ); +} + +// Crash test for bug 1615261 +async function runTest15() { + frameElts[0].contentDocument.body.innerHTML = + '<style>div { width: 100px; height: 100px; background-image: url("animated.gif"); } </style>' + + '<div>Firefox will crash if you try and print this page</div>'; + + // XXX Is there a more reliable way to wait for the background-image to load? + await new Promise(resolve => setTimeout(resolve, 500)); + + await printpreview(); + await exitprintpreview(); + + requestAnimationFrame(function() { setTimeout(runTest16); } ); +} + +// Various image tests. +async function runTest16() { + // fuzzy: SVG image in the test pixel-snaps different than <div> in the ref. + // (And on WebRender, the pixel-snapping seems to shift some pixels over a + // bit such that they're fully white vs. fully blue; hence 255 as the allowed + // color-channel difference.) + // XXXdholbert We should revisit this and adjust these thresholds (hopefully + // lower) after bug 1602410 lands. + await compareFiles("printpreview_images.html", "printpreview_images_ref.html", { maxDifferent: 118, maxDifference: 255 }); + requestAnimationFrame(function() { setTimeout(runTest17); } ); +} + +async function runTest17() { + // fuzzy: SVG image in the test pixel-snaps different than <div> in the ref. + // (And on WebRender, the pixel-snapping seems to shift some pixels over a + // bit such that they're fully white vs. fully blue; hence 255 as the allowed + // color-channel difference.) + // XXXdholbert We should revisit this and adjust these thresholds (hopefully + // lower) after bug 1602410 lands. + await compareFiles("printpreview_images_sw.html", "printpreview_images_sw_ref.html", { waitForMessage: true, maxDifferent: 118, maxDifference: 255 }); + requestAnimationFrame(() => setTimeout(runTest18)); +} + +async function runTest18() { + await compareFiles("printpreview_quirks.html", "printpreview_quirks_ref.html", { + settings: { + marginTop: 22, + marginBottom: 22, + marginLeft: 22, + marginRight: 22, + }, + }); + + requestAnimationFrame(() => setTimeout(runTest19)); +} + +async function runTest19() { + await compareFiles("color_adjust.html", "color_adjust_ref.html", { + test: { + settings: { + printBGColors: false, + printBGImages: false, + }, + }, + ref: { + settings: { + printBGColors: true, + printBGImages: true, + }, + }, + }); + + requestAnimationFrame(() => setTimeout(runTest20)); +} + +async function runTest20() { + frameElts[0].contentDocument.body.innerHTML = + '<style>div { page-break-after: always; }</style>' + + '<div>1</div>' + + '<div>2</div>' + + '<div>3</div>'; + await printpreview(); + + is(gWbp.printPreviewCurrentPageNumber, 1, + "The initial current page number should be 1"); + + // Scroll to the second page. + gWbp.printPreviewScrollToPage(Ci.nsIWebBrowserPrint.PRINTPREVIEW_GOTO_PAGENUM, 2); + + is(gWbp.printPreviewCurrentPageNumber, 2, + "The current page number should be 2"); + + // Scroll to the last page. + gWbp.printPreviewScrollToPage(Ci.nsIWebBrowserPrint.PRINTPREVIEW_END, 0); + + is(gWbp.printPreviewCurrentPageNumber, 3, + "The current page number should be 3"); + + exitprintpreview(); + + requestAnimationFrame(() => setTimeout(runTest21)); +} + +async function runTest21() { + await compareFiles("data:text/html,<audio controls>", "data:text/html,<audio controls >"); // Shouldn't crash. + requestAnimationFrame(() => setTimeout(runTest22)); +} + +async function runTest22() { + // Similar to above runtTest20 but more specific for the logic to choose + // the current page in the new print preview UI so this test works only + // in the new print preview. + frameElts[0].contentDocument.body.innerHTML = + '<style>div { page-break-after: always; max-height: 2in; }</style>' + + '<div>1</div>' + + '<div>2</div>' + + '<div>3</div>' + + '<div>4</div>' + + '<div>5</div>' + + '<div>6</div>' + + '<div>7</div>' + + '<div>8</div>' + + '<div>9</div>' + + '<div>10</div>'; + + await printpreview({ settings: { paperHeight: 3 } }); + + const initialCurrentPageNumber = gWbp.printPreviewCurrentPageNumber; + + // NOTE: In the cases the page hight is less than the half height of the + // print preview scroll port height, the initial current page number will + // not be 1. + ok(initialCurrentPageNumber >= 1, + "The initial current page number should be equal to or greater than 1"); + + const totalPageNumber = gWbp.printPreviewNumPages; + for (let n = initialCurrentPageNumber; + n <= totalPageNumber - initialCurrentPageNumber; + n++) { + // Scroll to the given page number and check the current page number. + gWbp.printPreviewScrollToPage( + Ci.nsIWebBrowserPrint.PRINTPREVIEW_GOTO_PAGENUM, n); + is(gWbp.printPreviewCurrentPageNumber, n, + `The current page number should be ${n}`); + } + + // Scroll to the end of the scroll region. + gWbp.printPreviewScrollToPage(Ci.nsIWebBrowserPrint.PRINTPREVIEW_END, 0); + + // Same as the initial current page number case, the last page might not + // be the current page if the page height is less than the half of the scroll + // port. + is(gWbp.printPreviewCurrentPageNumber, + totalPageNumber + 1 - initialCurrentPageNumber, + `The current page number should be ${totalPageNumber + 1 - initialCurrentPageNumber}`); + + exitprintpreview(); + + requestAnimationFrame(() => setTimeout(runTest23)); +} + +async function runTest23() { + await compareFiles("printpreview_prettyprint.xml", "printpreview_prettyprint_ref.xhtml"); + requestAnimationFrame(() => setTimeout(runTest24)); +} +async function runTest24() { + await compareFiles("printpreview_mask.html", "data:text/html,", { + settings: { + printBGColors: false, + printBGImages: false, + }, + expectDifference: true, + }); + requestAnimationFrame(() => setTimeout(runTest25)); +} + +async function runTest25() { + await compareFiles("printpreview_downloadable_font.html", "printpreview_downloadable_font_ref.html"); + requestAnimationFrame(() => setTimeout(runTest26)); +} + +async function runTest26() { + await compareFiles("printpreview_downloadable_font_in_iframe.html", "printpreview_downloadable_font_in_iframe_ref.html"); + requestAnimationFrame(() => setTimeout(runTest27)); +} + +async function runTest27() { + await compareFiles("data:text/html,<style>:root { background-color: red; background-image: linear-gradient(red, red) }</style>", "data:text/html,", { + settings: { + printBGColors: false, + printBGImages: false, + } + }); + requestAnimationFrame(() => setTimeout(runTest28)); +} + +async function runTest28() { + await compareFiles("data:text/html,<style>@page { margin: 0 }</style>Foo", "data:text/html,Foo", { + settings: { + honorPageRuleMargins: false, + marginTop: 1, + } + }); + + requestAnimationFrame(() => setTimeout(runTest29)); +} + +async function runTest29() { + await compareFiles("data:text/html,<style>@page { margin: 0 }</style>Foo", "data:text/html,Foo", { + settings: { + honorPageRuleMargins: true, + marginTop: 1, + }, + expectDifference: true, + }); + + requestAnimationFrame(() => setTimeout(runTest30)); +} + +// Helper function to test trivial/unsupported pages-per-sheet values which we +// just treat as 1 page-per-sheet (as if the attribute were unset.) +// NOTE: The second data-URI's explicit "<body>" tag is not meant to affect the +// rendering -- it's just a hack to ensure that the URIs themselves are +// different, so that compareFiles() sees the two URIs as different and gets +// the "load" notification that it depends on after switching between them. +// We also include numPages in the tested URL/content here, so that if we get +// a test-failure, it's easy to figure out which call to this function had the +// failure. +async function checkTrivialPagesPerSheetValue(numPages) { + let stringToDisplay = "TrivialPagesPerSheetVal" + numPages; + await compareFiles("data:text/html," + stringToDisplay, + "data:text/html,<body>" + stringToDisplay, { + test: { + settings: { + numPagesPerSheet: numPages, + }, + }, + ref: { settings: {} }, + }); +} + +async function runTest30() { + await checkTrivialPagesPerSheetValue(1); + await checkTrivialPagesPerSheetValue(0); + await checkTrivialPagesPerSheetValue(-5); + await checkTrivialPagesPerSheetValue(7); + await checkTrivialPagesPerSheetValue(500); + + requestAnimationFrame(() => setTimeout(runTest31)); +} + +// Helper function to test supported pages-per-sheet values that actually do +// tiling (i.e. values greater than 1). We render the testcase and reference +// case with zero page-margins and zero unwritable margins. (This makes it +// tractable to create a reference case without having to account for margins +// that are outside of the content area.) +async function checkSupportedPagesPerSheetValue(src1, src2, numPages, fuzz) { + await compareFiles(src1, src2, { + maxDifferent: fuzz.maxDifferent, + maxDifference: fuzz.maxDifference, + test: { + settings: { + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0, + unwriteableMarginRight: 0, + unwriteableMarginBottom: 0, + unwriteableMarginLeft: 0, + numPagesPerSheet: numPages, + }, + }, + ref: { + settings: { + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0, + unwriteableMarginRight: 0, + unwriteableMarginBottom: 0, + unwriteableMarginLeft: 0, + }, + }, + }); +} + +// Pages-per-sheet: test the supported values. +// First we test the perfect-square values: 4, 9, 16. +// Then we test the other values, 2 and 6. (They require some extra bespoke +// configuration to mock up their page-rotation, so their runTest functions are +// a bit more verbose.) +async function runTest31() { + // XXXdholbert On windows, our zero-margin settings aren't reliably respected + // for some reason; see bug 1680838. For now, we just account for that with a + // hefty amount of fuzz, guarded behind a platform-specific check so that we + // can keep this strict on other platforms. + let fuzz = navigator.platform.includes("Win") ? + { maxDifferent: 101278, maxDifference: 255 } : + { maxDifferent: 0, maxDifference: 0 }; + + await checkSupportedPagesPerSheetValue("printpreview_pps4.html", + "printpreview_pps4_ref.html", 4, fuzz); + + requestAnimationFrame(() => setTimeout(runTest32)); +} +async function runTest32() { + let fuzz = navigator.platform.includes("Win") ? + { maxDifferent: 130170, maxDifference: 255 } : + { maxDifferent: 0, maxDifference: 0 }; + + await checkSupportedPagesPerSheetValue("printpreview_pps9.html", + "printpreview_pps9_ref.html", 9, fuzz); + + requestAnimationFrame(() => setTimeout(runTest33)); +} +async function runTest33() { + let fuzz = navigator.platform.includes("Win") ? + { maxDifferent: 145706, maxDifference: 255 } : + { maxDifferent: 0, maxDifference: 0 }; + + await checkSupportedPagesPerSheetValue("printpreview_pps16.html", + "printpreview_pps16_ref.html", 16, + fuzz); + + requestAnimationFrame(() => setTimeout(runTest34)); +} + +async function runTest34() { + let fuzz = navigator.platform.includes("Win") ? // Workaround for bug 1680838 + { maxDifferent: 44256, maxDifference: 255 } : + { maxDifferent: 0, maxDifference: 0 }; + + let test = "printpreview_pps2.html"; + let ref = "printpreview_pps2_ref.html"; + await compareFiles(test, ref, { + maxDifferent: fuzz.maxDifferent, + maxDifference: fuzz.maxDifference, + test: { + settings: { + paperWidth: 8, + paperHeight: 10, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0, + unwriteableMarginRight: 0, + unwriteableMarginBottom: 0, + unwriteableMarginLeft: 0, + numPagesPerSheet: 2, + }, + }, + ref: { + settings: { + paperWidth: 8, + paperHeight: 10, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0, + unwriteableMarginRight: 0, + unwriteableMarginBottom: 0, + unwriteableMarginLeft: 0, + orientation: 1, /* Landscape mode */ + }, + }, + }); + + requestAnimationFrame(() => setTimeout(runTest35)); +} + +async function runTest35() { + let fuzz = navigator.platform.includes("Win") ? // Workaround for bug 1680838 + { maxDifferent: 88751, maxDifference: 255 } : + { maxDifferent: 0, maxDifference: 0 }; + + let test = "printpreview_pps6.html"; + let ref = "printpreview_pps6_ref.html"; + await compareFiles(test, ref, { + maxDifferent: fuzz.maxDifferent, + maxDifference: fuzz.maxDifference, + test: { + settings: { + paperWidth: 5, + paperHeight: 6, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0, + unwriteableMarginRight: 0, + unwriteableMarginBottom: 0, + unwriteableMarginLeft: 0, + numPagesPerSheet: 6, + orientation: 1, /* Landscape mode */ + }, + }, + ref: { + settings: { + paperWidth: 5, + paperHeight: 6, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0, + unwriteableMarginRight: 0, + unwriteableMarginBottom: 0, + unwriteableMarginLeft: 0, + }, + }, + }); + + requestAnimationFrame(() => setTimeout(runTest36)); +} + +// Testcases for pages-per-sheet with nonzero unwriteable margin values: +// --------------------------------------------------------------------- + +// In this subtest, the vertical scale-factor is more-severe and hence ends up +// "winning", and we have a bit of extra space in the horizontal axis which we +// distribute equally on either side (see the _ref.html file used below for +// more details). +async function runTest36() { + let fuzz = navigator.platform.includes("Win") ? + { maxDifferent: 139464, maxDifference: 255 } : + { maxDifferent: 0, maxDifference: 0 }; + + let test = "printpreview_pps_uw4.html"; + let ref = "printpreview_pps_uw4_ref.html"; + await compareFiles(test, ref, { + maxDifferent: fuzz.maxDifferent, + maxDifference: fuzz.maxDifference, + test: { + settings: { + paperWidth: 4, + paperHeight: 5, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0.6, + unwriteableMarginRight: 0.1, + unwriteableMarginBottom: 0.4, + unwriteableMarginLeft: 0.3, + numPagesPerSheet: 4, + }, + }, + ref: { + settings: { + paperWidth: 4, + paperHeight: 5, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0, + unwriteableMarginRight: 0, + unwriteableMarginBottom: 0, + unwriteableMarginLeft: 0, + }, + }, + }); + + requestAnimationFrame(() => setTimeout(runTest37)); +} + +// In this subtest, the horizontal scale-factor is more-severe and hence ends +// up "winning", and we have a bit of extra space in the vertical axis which we +// distribute equally on either side (see the _ref.html file used below for +// more details). +async function runTest37() { + let fuzz = navigator.platform.includes("Win") ? + { maxDifferent: 152268, maxDifference: 255 } : + { maxDifferent: 0, maxDifference: 0 }; + + let test = "printpreview_pps_uw9.html"; + let ref = "printpreview_pps_uw9_ref.html"; + await compareFiles(test, ref, { + maxDifferent: fuzz.maxDifferent, + maxDifference: fuzz.maxDifference, + test: { + settings: { + paperWidth: 5, + paperHeight: 10, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0.2, + unwriteableMarginRight: 0.8, + unwriteableMarginBottom: 0.4, + unwriteableMarginLeft: 1.2, + numPagesPerSheet: 9, + }, + }, + ref: { + settings: { + paperWidth: 5, + paperHeight: 10, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0, + unwriteableMarginRight: 0, + unwriteableMarginBottom: 0, + unwriteableMarginLeft: 0, + }, + }, + }); + + requestAnimationFrame(() => setTimeout(runTest38)); +} + +async function runTest38() { + let fuzz = navigator.platform.includes("Win") ? // Workaround for bug 1680838 + { maxDifferent: 117744, maxDifference: 255 } : + { maxDifferent: 0, maxDifference: 0 }; + + let test = "printpreview_pps_uw2.html"; + let ref = "printpreview_pps_uw2_ref.html"; + await compareFiles(test, ref, { + maxDifferent: fuzz.maxDifferent, + maxDifference: fuzz.maxDifference, + test: { + settings: { + paperWidth: 8, + paperHeight: 10, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0.8, + unwriteableMarginRight: 0.6, + unwriteableMarginBottom: 1.2, + unwriteableMarginLeft: 0.4, + numPagesPerSheet: 2, + }, + }, + ref: { + settings: { + paperWidth: 8, + paperHeight: 10, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + /* Note: These are the same values we used for 'test' above, except + that here we've rotated the margins counterclockwise through the + sides, to account for the fact that we're specifying these margins + for a landscape-orientation page here vs. portrait-mode above.*/ + unwriteableMarginTop: 0.6, + unwriteableMarginRight: 1.2, + unwriteableMarginBottom: 0.4, + unwriteableMarginLeft: 0.8, + orientation: 1, /* Landscape mode */ + }, + }, + }); + + requestAnimationFrame(() => setTimeout(runTest39)); +} + +// In this subtest, the vertical unwriteable margins exactly consume the full +// pageHeight, so we don't have any space available for printing and we just +// print a blank sheet. (This is mostly a stress test to be sure we don't +// crash, hang, divide-by-zero, etc. in this edge case.) +async function runTest39() { + let fuzz = navigator.platform.includes("Win") ? + { maxDifferent: 254, maxDifference: 255 } : + { maxDifferent: 0, maxDifference: 0 }; + + let test = "data:text/html,Unwriteable-Margins-Too-Tall-To-See-This"; + let ref = "data:text/html,<!-- runTest39 -->"; + await compareFiles(test, ref, { + maxDifferent: fuzz.maxDifferent, + maxDifference: fuzz.maxDifference, + test: { + settings: { + paperWidth: 4, + paperHeight: 5, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + unwriteableMarginTop: 3, + unwriteableMarginBottom: 2, + numPagesPerSheet: 4, + }, + }, + ref: { + settings: { + paperWidth: 4, + paperHeight: 5, + }, + }, + }); + + requestAnimationFrame(() => setTimeout(runTest40)); +} + +// In this subtest, the horizontal unwriteable margins consume more than the +// full pageWidth, so we don't have any space available for printing and we +// just print a blank sheet. (This is mostly a stress test to be sure we don't +// crash, hang, divide-by-zero, etc. in this edge case.) +async function runTest40() { + let fuzz = navigator.platform.includes("Win") ? + { maxDifferent: 172, maxDifference: 255 } : + { maxDifferent: 0, maxDifference: 0 }; + + let test = "data:text/html,Unwriteable-Margins-Too-Wide-To-See-This"; + let ref = "data:text/html,<!-- runTest40 -->"; + await compareFiles(test, ref, { + maxDifferent: fuzz.maxDifferent, + maxDifference: fuzz.maxDifference, + test: { + settings: { + paperWidth: 4, + paperHeight: 5, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + unwriteableMarginRight: 3, + unwriteableMarginLeft: 4, + numPagesPerSheet: 9, + }, + }, + ref: { + settings: { + paperWidth: 4, + paperHeight: 5, + }, + }, + }); + + requestAnimationFrame(() => setTimeout(runTest41)); +} + +// Drawing headers/footers with very large unwriteable margins. The specific +// bug occurs when combined unwriteable are larger than half of the page's +// dimensions. +async function runTest41() { + // This test compares a rendered page to the headers/footers that print code + // generates. On Windows, workaround bug 1680838. On OS X, the headers/ + // footers are sometimes slightly offset. See bug 1714217. + // It's not too big a deal to have a higher fuzz factor, since when + // bug 1713404 occurs no headers/footers at all are rendered. These higher + // fuzz factors will still catch this worst case on OS X. + if (navigator.platform.includes("Win")) { + var fuzz = { maxDifferent: 133, maxDifference: 255 }; // Bug 1680838 + } + else if (navigator.platform.includes("Mac")) { + var fuzz = { maxDifferent: 60, maxDifference: 200 }; // Bug 1714217 + } + else { + var fuzz = { maxDifferent: 14, maxDifference: 16 }; + } + + let test = "data:text/html,<!-- runTest41 -->"; + let ref = "printpreview_bug1713404_ref.html"; + await compareFiles(test, ref, { + maxDifferent: fuzz.maxDifferent, + maxDifference: fuzz.maxDifference, + test: { + settings: { + paperWidth: 5, + paperHeight: 5, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + unwriteableMarginLeft: 2, + unwriteableMarginRight: 2, + unwriteableMarginTop: 2, + unwriteableMarginBottom: 2, + headerStrLeft: "|", + headerStrRight: "||", + footerStrLeft: "|||", + footerStrRight: "||||", + }, + }, + ref: { + settings: { + paperWidth: 5, + paperHeight: 5, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + unwriteableMarginLeft: 0, + unwriteableMarginRight: 0, + unwriteableMarginTop: 0, + unwriteableMarginBottom: 0, + }, + }, + }); + + requestAnimationFrame(() => setTimeout(runTest42)); +} + +// Test that @page{ size: ... } works correctly with a smaller specified +// @page{ size: ... } than the paper we are printing to. The test and ref use +// varying margin and size properties to place elements in the same location. +// This depends on Firefox's current behavior of putting undersized pages into +// the upper left corner, rather than scaling or centering the page. +async function runTest42() { + if (navigator.platform.includes("Mac")) { + var fuzz = { maxDifferent: 15, maxDifference: 8 }; + } + let test = "print_page_size1.html"; + let ref = "print_page_size1_ref.html"; + await compareFiles(test, ref, fuzz); + + requestAnimationFrame(() => setTimeout(runTest43)); +} + +// Test that @page{ size: ... } works correctly with a larger specified +// @page{ size: ... } than the paper we are printing to. This specifically +// tests scaling when only one page edge is too large. +// This depends on Firefox's current behavior of scaling down any oversized +// pages to fit onto a single physical page, and putting this aligned to the +// upper left corner rather than centering the page. +async function runTest43() { + if (navigator.platform.includes("Mac")) { + var fuzz = { maxDifferent: 15, maxDifference: 8 }; + } + let test = "print_page_size2.html"; + let ref = "print_page_size2_ref.html"; + await compareFiles(test, ref, fuzz); + + requestAnimationFrame(() => setTimeout(runTest44)); +} + +// Test that @page{ size: ... } works correctly with a smaller specified +// @page{ size: ... } than the paper we are printing to. The test case uses +// only the size property and the ref case uses only absolute positioning. +// This depends on Firefox's current behavior of putting undersized pages into +// the upper left corner, rather than scaling or centering the page. +async function runTest44() { + if (navigator.platform.includes("Mac")) { + var fuzz = { maxDifferent: 15, maxDifference: 8 }; + } + let test = "print_page_size3.html"; + let ref = "print_page_size3_ref.html"; + await compareFiles(test, ref, fuzz); + requestAnimationFrame(() => setTimeout(runTest45)); +} + +// Test that @page{ size: ... } results in scaling down the contents to fit on +// a smaller paper size. +// This depends on Firefox's current behavior of scaling oversized pages down +// to fit onto the paper size. +async function runTest45() { + if (navigator.platform.includes("Mac")) { + var fuzz = { maxDifferent: 15, maxDifference: 8 }; + } + let test = "print_page_size4.html"; + let ref = "print_page_size4_ref.html"; + await compareFiles(test, ref, fuzz); + requestAnimationFrame(() => setTimeout(runTest46)); +} + +// Test that small elements don't get clipped from the bottom of the page when +// using a < 1.0 scaling factor. +async function runTest46() { + var fuzz = { maxDifferent: 0, maxDifference: 0 }; + let test = "bug1722890.html"; + let ref = "bug1722890_ref.html"; + await compareFiles(test, ref, { + maxDifferent: fuzz.maxDifferent, + maxDifference: fuzz.maxDifference, + test: { + settings: { + scaling: 0.5, + shrinkToFit: false + } + }, + ref: { + settings: { + scaling: 1.0, + shrinkToFit: false + } + } + }); + requestAnimationFrame(() => setTimeout(runTest47)); +} + +// Test for header/footer text clipping when printing with scaling factor. +async function runTest47() { + // This test compares a rendered page to the headers/footers that print code + // generates. On Windows, workaround bug 1680838. On OS X, the headers/ + // footers are sometimes slightly offset. See bug 1714217. + // It's not too big a deal to have a higher fuzz factor, since when + // bug 1730091 occurs most of the headers/footers are not rendered at all, + // and these fuzz factors will still catch that. + if (navigator.platform.includes("Win")) { + var fuzz = { maxDifferent: 200, maxDifference: 255 }; // Bug 1680838 + } + else if (navigator.platform.includes("Mac")) { + var fuzz = { maxDifferent: 180, maxDifference: 255 }; // Bug 1714217 + } + else { + var fuzz = { maxDifferent: 6, maxDifference: 16 }; + } + + let test = "data:text/html,<!-- runTest47 -->"; + let ref = "printpreview_bug1730091_ref.html"; + await compareFiles(test, ref, { + maxDifferent: fuzz.maxDifferent, + maxDifference: fuzz.maxDifference, + test: { + settings: { + scaling: 1.3, + shrinkToFit: false, + paperWidth: 5, + paperHeight: 5, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + unwriteableMarginLeft: 0, + unwriteableMarginRight: 0, + unwriteableMarginTop: 0, + unwriteableMarginBottom: 0, + headerStrLeft: "||||", + headerStrRight: "||||", + footerStrLeft: "||||", + footerStrRight: "||||", + }, + }, + ref: { + settings: { + paperWidth: 5, + paperHeight: 5, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + unwriteableMarginLeft: 0, + unwriteableMarginRight: 0, + unwriteableMarginTop: 0, + unwriteableMarginBottom: 0, + }, + }, + }); + requestAnimationFrame(() => setTimeout(runTest48)); +} + +// Test that even when downscaling happens due to CSS page-size, the +// unwriteable margins are in units applicable to the resulting page as it is +// actually printed. +// https://bugzilla.mozilla.org/1769161 +async function runTest48() { + if (navigator.platform.includes("Win")) { + var fuzz = { maxDifferent: 816, maxDifference: 255 }; // Bug 1680838 + } else { + var fuzz = { maxDifferent: 16, maxDifference: 255 }; + } + let test = "bug1769161_1.html"; + let ref = "bug1769161_1_ref.html"; + await compareFiles(test, ref, { + maxDifferent: fuzz.maxDifferent, + maxDifference: fuzz.maxDifference, + settings: { + paperWidth: 5, + paperHeight: 5, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + unwriteableMarginLeft: 1, + unwriteableMarginRight: 1, + unwriteableMarginTop: 1, + unwriteableMarginBottom: 1, + }, + }); + requestAnimationFrame(() => setTimeout(runTest49)); +} + +// Same as runTest48, but uses different scaling factors. +async function runTest49() { + if (navigator.platform.includes("Win")) { + var fuzz = { maxDifferent: 6472, maxDifference: 255 }; // Bug 1680838 + } else { + var fuzz = { maxDifferent: 24, maxDifference: 255 }; + } + let test = "bug1769161_2.html"; + let ref = "bug1769161_2_ref.html"; + await compareFiles(test, ref, { + maxDifferent: fuzz.maxDifferent, + maxDifference: fuzz.maxDifference, + settings: { + paperWidth: 5, + paperHeight: 5, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + unwriteableMarginLeft: 1, + unwriteableMarginRight: 1, + unwriteableMarginTop: 1, + unwriteableMarginBottom: 1, + }, + }); + requestAnimationFrame(() => setTimeout(runTest50)); +} + +// Test that when downscaling happens due to CSS page-size, the unwriteable +// margins are equivalent to the @page margins after those margins are scaled. +// https://bugzilla.mozilla.org/1769161 +async function runTest50() { + if (navigator.platform.includes("Win")) { + var fuzz = { maxDifferent: 816, maxDifference: 255 }; // Bug 1680838 + } else { + var fuzz = { maxDifferent: 16, maxDifference: 255 }; + } + let test = "bug1769161_3.html"; + let ref = "bug1769161_3_ref.html"; + await compareFiles(test, ref, { + maxDifferent: fuzz.maxDifferent, + maxDifference: fuzz.maxDifference, + test: { + settings: { + paperWidth: 5, + paperHeight: 5, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + unwriteableMarginLeft: 1, + unwriteableMarginRight: 1, + unwriteableMarginTop: 1, + unwriteableMarginBottom: 1, + }, + }, + ref: { + settings: { + paperWidth: 5, + paperHeight: 5, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + unwriteableMarginLeft: 0, + unwriteableMarginRight: 0, + unwriteableMarginTop: 0, + unwriteableMarginBottom: 0, + }, + }, + }); + requestAnimationFrame(() => setTimeout(runTest51)); +} + +// Same as runTest50, but uses different scaling factors. +async function runTest51() { + if (navigator.platform.includes("Win")) { + var fuzz = { maxDifferent: 11764, maxDifference: 255 }; // Bug 1680838 + } else { + var fuzz = { maxDifferent: 24, maxDifference: 255 }; + } + let test = "bug1769161_4.html"; + let ref = "bug1769161_4_ref.html"; + await compareFiles(test, ref, { + maxDifferent: fuzz.maxDifferent, + maxDifference: fuzz.maxDifference, + test: { + settings: { + paperWidth: 5, + paperHeight: 5, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + unwriteableMarginLeft: 1, + unwriteableMarginRight: 1, + unwriteableMarginTop: 1, + unwriteableMarginBottom: 1, + }, + }, + ref: { + settings: { + paperWidth: 5, + paperHeight: 5, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + unwriteableMarginLeft: 0, + unwriteableMarginRight: 0, + unwriteableMarginTop: 0, + unwriteableMarginBottom: 0, + }, + }, + }); + requestAnimationFrame(() => setTimeout(runTest52)); +} + +async function runTest52() { + // Unwriteable margins can be ignored by setting the appropriate flag. + // Slightly different to avoid hang. + await compareFiles("data:text/html,Foo", "data:text/html,<div>Foo", { + maxDifferent: 0, + maxDifference: 0, + test: { + settings: { + paperWidth: 8, + paperHeight: 10, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 1, + unwriteableMarginRight: 1, + unwriteableMarginBottom: 1, + unwriteableMarginLeft: 1, + ignoreUnwriteableMargins: true, + }, + }, + ref: { + settings: { + paperWidth: 8, + paperHeight: 10, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0, + unwriteableMarginRight: 0, + unwriteableMarginBottom: 0, + unwriteableMarginLeft: 0, + }, + }, + }); + + requestAnimationFrame(() => setTimeout(runTest53)); +} + +async function runTest53() { + // Ensure that even when unwriteable margins are set to be taken into + // account, page rule margins can override it. + await compareFiles( + "data:text/html,<style>@page { margin: 0 }</style>Foo", + "data:text/html,<div>Foo", + { + maxDifferent: 0, + maxDifference: 0, + test: { + settings: { + paperWidth: 8, + paperHeight: 10, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 1, + unwriteableMarginRight: 1, + unwriteableMarginBottom: 1, + unwriteableMarginLeft: 1, + ignoreUnwriteableMargins: false, + honorPageRuleMargins: true, + }, + }, + ref: { + settings: { + paperWidth: 8, + paperHeight: 10, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0, + unwriteableMarginRight: 0, + unwriteableMarginBottom: 0, + unwriteableMarginLeft: 0, + }, + }, + }); + + requestAnimationFrame(() => setTimeout(runTest54)); +} + +async function runTest54() { + // `ignoreUnwriteableMargins` lets author-specified margins ignore + // unwriteable margins as well. Without this flag, the unwriteable + // margin is ignored iff `Margins: Default` is set (i.e. + // `honorPageRuleMargins` set) and the author specified CSS page + // margin is zero. + // Note: At least currently, both `ignoreUnwriteableMargins` + // and `honorPageRuleMargins` cannot be set through the printing UI. + // TODO: If this behaviour is desired is up for debate. + await compareFiles( + "data:text/html,<style>@page { margin: 0.1in }</style>Foo", + "data:text/html,<div>Foo", + { + maxDifferent: 0, + maxDifference: 0, + test: { + settings: { + paperWidth: 8, + paperHeight: 10, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 1, + unwriteableMarginRight: 1, + unwriteableMarginBottom: 1, + unwriteableMarginLeft: 1, + ignoreUnwriteableMargins: true, + honorPageRuleMargins: true, + }, + }, + ref: { + settings: { + paperWidth: 8, + paperHeight: 10, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0.1, + marginRight: 0.1, + marginBottom: 0.1, + marginLeft: 0.1, + unwriteableMarginTop: 0, + unwriteableMarginRight: 0, + unwriteableMarginBottom: 0, + unwriteableMarginLeft: 0, + }, + }, + }); + + requestAnimationFrame(() => setTimeout(runTest55)); +} + +async function runTest55() { + let test = "printpreview_pps_uw2.html"; + let ref = "printpreview_pps_uw2_no_margin_ref.html"; + let fuzz = navigator.platform.includes("Win") ? // Workaround for bug 1680838 + { maxDifferent: 12870, maxDifference: 255 } : + { maxDifferent: 0, maxDifference: 0 }; + + // Unwriteable margins are successfully ignored, if requested, + // for pages-per-sheet. + await compareFiles(test, ref, { + maxDifferent: fuzz.maxDifferent, + maxDifference: fuzz.maxDifference, + test: { + settings: { + paperWidth: 8, + paperHeight: 10, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0.8, + unwriteableMarginRight: 0.6, + unwriteableMarginBottom: 1.2, + unwriteableMarginLeft: 0.4, + numPagesPerSheet: 2, + ignoreUnwriteableMargins: true, + }, + }, + ref: { + settings: { + paperWidth: 8, + paperHeight: 10, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0, + unwriteableMarginRight: 0, + unwriteableMarginBottom: 0, + unwriteableMarginLeft: 0, + orientation: 1, /* Landscape mode */ + }, + }, + }); + + requestAnimationFrame(() => setTimeout(runTest56)); +} + +async function runTest56() { + await compareFiles("printpreview_image_select.html", "printpreview_image_select_ref.html"); + requestAnimationFrame(() => setTimeout(runTest57)); +} + +// Tests that printing with mixed page sizes doesn't crash. +// These tests can't actually compare any pages after the first, so this only +// verifies that we don't crash reflowing. +async function runTest57() { + let test = "printpreview_mixed_page_size_001.html"; + // The params are just to give the file unique URLs. + await compareFiles(test + "?test", test + "?ref"); + requestAnimationFrame(() => setTimeout(runTest58)); +} + +// As with runTest57, this is only testing for crashes. +// This includes fixed-position content, as this is the only way to get content +// within the same chain of continuations onto pages with different sizes. +async function runTest58() { + let test = "printpreview_mixed_page_size_002.html"; + // The params are just to give the file unique URLs. + await compareFiles(test + "?test", test + "?ref"); + finish(); +} + +]]></script> +<table style="border: 1px solid black;" xmlns="http://www.w3.org/1999/xhtml"> +<tr><th>Print preview canvas 1</th><th>Print preview canvas 2</th></tr> +<tr> +<td><canvas height="800" width="800"></canvas></td> +<td><canvas height="800" width="800"></canvas></td> +</tr></table> +</window> diff --git a/layout/base/tests/chrome/printpreview_image_select.html b/layout/base/tests/chrome/printpreview_image_select.html new file mode 100644 index 0000000000..b61a40774d --- /dev/null +++ b/layout/base/tests/chrome/printpreview_image_select.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<body> + <picture> + <source width="200" srcset="red.png 1w, green.png 200w"> + <img> + </picture> +</body> diff --git a/layout/base/tests/chrome/printpreview_image_select_ref.html b/layout/base/tests/chrome/printpreview_image_select_ref.html new file mode 100644 index 0000000000..7189a57642 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_image_select_ref.html @@ -0,0 +1,4 @@ +<!DOCTYPE html> +<body> + <div style="width: 200px; height: 200px; background-color: green;"></div> +</body> diff --git a/layout/base/tests/chrome/printpreview_images.html b/layout/base/tests/chrome/printpreview_images.html new file mode 100644 index 0000000000..6919002354 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_images.html @@ -0,0 +1,25 @@ +<!doctype html> +<style> + img, object, svg, input { display: block } + div { + content: url(blue-32x32.png); + width: 32px; + height: 32px; + } +</style> +<div></div> +<picture> + <source srcset="blue-32x32.png"> + <img width=32 height=32> +</picture> +<picture> + <source srcset="blue-32x32.png" media="print"> + <source srcset="animated.gif" media="not print"> + <img width=32 height=32> +</picture> +<img src="blue-32x32.png" width=32 height=32> +<object data="blue-32x32.png" width=32 height=32></object> +<svg width="32" height="32"> + <image x=0 y=0 href="blue-32x32.png" width=32 height=32></image> +</svg> +<input type="image" src="blue-32x32.png" width=32 height=32> diff --git a/layout/base/tests/chrome/printpreview_images_ref.html b/layout/base/tests/chrome/printpreview_images_ref.html new file mode 100644 index 0000000000..65a0df066c --- /dev/null +++ b/layout/base/tests/chrome/printpreview_images_ref.html @@ -0,0 +1,15 @@ +<!doctype html> +<style> + div { + width: 32px; + height: 32px; + background-color: blue; + } +</style> +<div></div> +<div></div> +<div></div> +<div></div> +<div></div> +<div></div> +<div></div> diff --git a/layout/base/tests/chrome/printpreview_images_sw.html b/layout/base/tests/chrome/printpreview_images_sw.html new file mode 100644 index 0000000000..78b8a0dd88 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_images_sw.html @@ -0,0 +1,46 @@ +<!doctype html> +<style> + img, object, svg, input { display: block } + div { + content: url(nonexistent.png?1); + width: 32px; + height: 32px; + } +</style> +<script> +const WORKER = "printpreview_images_sw.js"; +if (location.href.includes("registered")) { + console.log("REGISTERED"); + onload = function() { + postMessage("ready", "*"); + } + onbeforeunload = function() { + navigator.serviceWorker.getRegistrations().then(function(registrations) { + for(let registration of registrations) { + registration.unregister() + } + }) + navigator.serviceWorker.unregister(WORKER); + } +} else { + navigator.serviceWorker.oncontrollerchange = function() { + location.href = location.href + "?registered"; + }; + navigator.serviceWorker.register(WORKER); +} +</script> +<div></div> +<picture> + <source srcset="nonexistent.png?2"> + <img width=32 height=32> +</picture> +<picture> + <source srcset="nonexistent.png?3" media="print"> + <source srcset="animated.gif" media="not print"> + <img width=32 height=32> +</picture> +<img src="nonexistent.png?4" width=32 height=32> +<svg width="32" height="32"> + <image x=0 y=0 href="nonexistent.png?7" width=32 height=32></image> +</svg> +<input type="image" src="nonexistent.png?6" width=32 height=32> diff --git a/layout/base/tests/chrome/printpreview_images_sw.js b/layout/base/tests/chrome/printpreview_images_sw.js new file mode 100644 index 0000000000..bb0ab60b1f --- /dev/null +++ b/layout/base/tests/chrome/printpreview_images_sw.js @@ -0,0 +1,11 @@ +self.addEventListener("fetch", event => { + if (event.request.url.includes("nonexistent.png")) { + event.respondWith( + fetch(event.request.url.replace("nonexistent.png", "blue-32x32.png")) + ); + } +}); + +self.addEventListener("activate", event => { + event.waitUntil(clients.claim()); +}); diff --git a/layout/base/tests/chrome/printpreview_images_sw_ref.html b/layout/base/tests/chrome/printpreview_images_sw_ref.html new file mode 100644 index 0000000000..2efb9e9199 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_images_sw_ref.html @@ -0,0 +1,14 @@ +<!doctype html> +<style> + div { + width: 32px; + height: 32px; + background-color: blue; + } +</style> +<div></div> +<div></div> +<div></div> +<div></div> +<div></div> +<div></div> diff --git a/layout/base/tests/chrome/printpreview_mask.html b/layout/base/tests/chrome/printpreview_mask.html new file mode 100644 index 0000000000..f1ea3af255 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_mask.html @@ -0,0 +1,16 @@ +<!doctype html> +<style> +div { + background: black; + color: white; + -webkit-mask-image: linear-gradient(180deg,#000 60%,transparent); + mask-image: linear-gradient(180deg,#000 60%,transparent); +} +</style> +<div> + Here's some text<br> + Here's some text<br> + Here's some text<br> + Here's some text<br> + Here's some text<br> +</div> diff --git a/layout/base/tests/chrome/printpreview_mixed_page_size_001.html b/layout/base/tests/chrome/printpreview_mixed_page_size_001.html new file mode 100644 index 0000000000..a611299527 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_mixed_page_size_001.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<style> +@page a { + size: 10in 5in; +} +@page b { + size: 6in 9in; +} +</style> +<div style="page: a">a</div> +<div style="page: b">b</div> diff --git a/layout/base/tests/chrome/printpreview_mixed_page_size_002.html b/layout/base/tests/chrome/printpreview_mixed_page_size_002.html new file mode 100644 index 0000000000..f55efef3e6 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_mixed_page_size_002.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<style> +@page a { + size: 10in 5in; +} +@page b { + size: 6in 9in; +} +</style> +<div style="display: flex; position: fixed;"> + <div>static 1</div> + <div>static 2</div> +</div> +<div style="page: a">block a</div> +<div style="page: b">block b</div> diff --git a/layout/base/tests/chrome/printpreview_pps16.html b/layout/base/tests/chrome/printpreview_pps16.html new file mode 100644 index 0000000000..fc94819340 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_pps16.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<!-- This is a testcase for a "16-pages-per-sheet" scenario. + There are 16 full-page color-swatches. --> +<style> +html, body { margin: 0; height: 100%; } +.swatch { + box-sizing: border-box; + border: 120px solid; + height: 100%; +} +.swatch:nth-child(1) { border-color: cyan; } +.swatch:nth-child(2) { border-color: yellow; } +.swatch:nth-child(3) { border-color: pink; } +.swatch:nth-child(4) { border-color: orange; } +.swatch:nth-child(5) { border-color: purple; } +.swatch:nth-child(6) { border-color: olive; } +.swatch:nth-child(7) { border-color: blue; } +.swatch:nth-child(8) { border-color: tan; } +.swatch:nth-child(9) { border-color: fuchsia; } +.swatch:nth-child(10) { border-color: salmon; } +.swatch:nth-child(11) { border-color: lightgreen; } +.swatch:nth-child(12) { border-color: navy; } +.swatch:nth-child(13) { border-color: brown; } +.swatch:nth-child(14) { border-color: orchid; } +.swatch:nth-child(15) { border-color: goldenrod; } +.swatch:nth-child(16) { border-color: seagreen; } +</style> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> diff --git a/layout/base/tests/chrome/printpreview_pps16_ref.html b/layout/base/tests/chrome/printpreview_pps16_ref.html new file mode 100644 index 0000000000..5807cc44ec --- /dev/null +++ b/layout/base/tests/chrome/printpreview_pps16_ref.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<!-- This is a reference case for a "16-pages-per-sheet" scenario. The width + and height of each "swatch" is 1/4 the width and height of the page. --> +<style> +html, body { margin: 0; height: 100%; } +body { + display: flex; + flex-flow: row wrap; +} +.swatch { + box-sizing: border-box; + border: 30px solid; + /* The height will be automatically set to the flex container's row height, + via default 'align-self' behavior (which ends up as 'stretch') */ + flex: 1 25%; +} +.swatch:nth-child(1) { border-color: cyan; } +.swatch:nth-child(2) { border-color: yellow; } +.swatch:nth-child(3) { border-color: pink; } +.swatch:nth-child(4) { border-color: orange; } +.swatch:nth-child(5) { border-color: purple; } +.swatch:nth-child(6) { border-color: olive; } +.swatch:nth-child(7) { border-color: blue; } +.swatch:nth-child(8) { border-color: tan; } +.swatch:nth-child(9) { border-color: fuchsia; } +.swatch:nth-child(10) { border-color: salmon; } +.swatch:nth-child(11) { border-color: lightgreen; } +.swatch:nth-child(12) { border-color: navy; } +.swatch:nth-child(13) { border-color: brown; } +.swatch:nth-child(14) { border-color: orchid; } +.swatch:nth-child(15) { border-color: goldenrod; } +.swatch:nth-child(16) { border-color: seagreen; } +</style> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> diff --git a/layout/base/tests/chrome/printpreview_pps2.html b/layout/base/tests/chrome/printpreview_pps2.html new file mode 100644 index 0000000000..a7f9fddae3 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_pps2.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<!-- This is a testcase for a "2-pages-per-sheet" scenario. + There are 2 full-page "swatches" with large colorful borders. --> +<style> +html, body { margin: 0; height: 100%; } +.swatch { + box-sizing: border-box; + border: 240px solid; + height: 100%; +} +.swatch:nth-child(1) { border-color: cyan; } +.swatch:nth-child(2) { border-color: pink; } +</style> +<div class="swatch"></div> +<div class="swatch"></div> diff --git a/layout/base/tests/chrome/printpreview_pps2_ref.html b/layout/base/tests/chrome/printpreview_pps2_ref.html new file mode 100644 index 0000000000..b1e8033c87 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_pps2_ref.html @@ -0,0 +1,40 @@ +<!DOCTYPE html> +<!-- This is a reference case for a "2-pages-per-sheet" scenario. The width and + height of each "swatch" is 0.625 the width and height of the page. That + 0.625 scale-factor comes from the fact that, when rendering the testcase, + we'll need to scale the page-width (8in) down enough to fit side-by-side + into half of the page height (10in/2 = 5in), on a rotated sheet. So we've + got to scale 8in to fit into 5in, which is a scale factor of 0.625. --> +<style> +html { height: 100%; } +body { + height: 100%; + margin: 0; + box-sizing: border-box; + + /* The testcase (rendered at 2-pages-per-sheet) will have 1.75in of extra + space in the vertical axis, which will be distributed equally with 0.875in + on the top and the bottom of the page grid. We mock that up as padding + here: */ + padding: 0.875in 0; + + /* We lay out the body as a row-oriented flex container, with two + side-by-side children which correspond to the two pages per sheet: */ + display: flex; +} +.swatch { + box-sizing: border-box; + + /* This represents the 240px border in the testcase, scaled down 0.625x: */ + border: 150px solid; + + /* Share the width equally among the swatches. (The height will be + automatically set to the flex container's row height, via default + 'align-self' behavior.) */ + flex: 1; +} +.swatch:nth-child(1) { border-color: cyan; } +.swatch:nth-child(2) { border-color: pink; } +</style> +<div class="swatch"></div> +<div class="swatch"></div> diff --git a/layout/base/tests/chrome/printpreview_pps4.html b/layout/base/tests/chrome/printpreview_pps4.html new file mode 100644 index 0000000000..6e3d030c6d --- /dev/null +++ b/layout/base/tests/chrome/printpreview_pps4.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<!-- This is a testcase for a "4-pages-per-sheet" scenario. + There are 4 full-page "swatches" with large colorful borders. --> +<style> +html, body { margin: 0; height: 100%; } +.swatch { + box-sizing: border-box; + border: 120px solid; + height: 100%; +} +.swatch:nth-child(1) { border-color: cyan; } +.swatch:nth-child(2) { border-color: yellow; } +.swatch:nth-child(3) { border-color: pink; } +.swatch:nth-child(4) { border-color: orange; } +</style> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> diff --git a/layout/base/tests/chrome/printpreview_pps4_ref.html b/layout/base/tests/chrome/printpreview_pps4_ref.html new file mode 100644 index 0000000000..4ffbec505f --- /dev/null +++ b/layout/base/tests/chrome/printpreview_pps4_ref.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<!-- This is a reference case for a "4-pages-per-sheet" scenario. The width + and height of each "swatch" is 1/2 the width and height of the page. --> +<style> +html, body { margin: 0; height: 100%; } +body { + display: flex; + flex-flow: row wrap; +} +.swatch { + box-sizing: border-box; + border: 60px solid; + /* The height will be automatically set to the flex container's row height, + via default 'align-self' behavior (which ends up as 'stretch') */ + flex: 1 50%; +} +.swatch:nth-child(1) { border-color: cyan; } +.swatch:nth-child(2) { border-color: yellow; } +.swatch:nth-child(3) { border-color: pink; } +.swatch:nth-child(4) { border-color: orange; } +</style> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> diff --git a/layout/base/tests/chrome/printpreview_pps6.html b/layout/base/tests/chrome/printpreview_pps6.html new file mode 100644 index 0000000000..68722afba9 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_pps6.html @@ -0,0 +1,40 @@ +<!DOCTYPE html> +<!-- This is a testcase for a "6-pages-per-sheet" scenario. + There are 12 full-page color-swatches, which should be layed out over 2 + sheets. + + This test is specifically given more pages than fit on a sheet so that + at least one of our tests checks the case where we have more than one + sheet. --> +<style> +html, body { margin: 0; height: 100%; } +.swatch { + box-sizing: border-box; + border: 120px solid; + height: 100%; +} +.swatch:nth-child(1) { border-color: cyan; } +.swatch:nth-child(2) { border-color: yellow; } +.swatch:nth-child(3) { border-color: pink; } +.swatch:nth-child(4) { border-color: orange; } +.swatch:nth-child(5) { border-color: purple; } +.swatch:nth-child(6) { border-color: olive; } +.swatch:nth-child(7) { border-color: blue; } +.swatch:nth-child(8) { border-color: tan; } +.swatch:nth-child(9) { border-color: fuchsia; } +.swatch:nth-child(10) { border-color: salmon; } +.swatch:nth-child(11) { border-color: lightgreen; } +.swatch:nth-child(12) { border-color: navy; } +</style> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> diff --git a/layout/base/tests/chrome/printpreview_pps6_ref.html b/layout/base/tests/chrome/printpreview_pps6_ref.html new file mode 100644 index 0000000000..3af174e0fa --- /dev/null +++ b/layout/base/tests/chrome/printpreview_pps6_ref.html @@ -0,0 +1,90 @@ +<!DOCTYPE html> +<!-- This is a reference case for a "6-pages-per-sheet" scenario. This file is + a mockup of a sheet with 6 pages, followed by a sheet with another 6 pages, + with the pages all having a 0.4x scale factor applied. --> +<style> +html { height: 100%; } +body { + height: 100%; + margin: 0; + box-sizing: border-box; +} + +.sheet { + height: 100%; + + /* We lay out the body as a column-oriented flex container (whose children, + in turn, are rows). */ + display: flex; + flex-direction: column; +} + +.row { + /* Give each row an equal share of the available height: */ + flex: 1; + + /* ...and render them as row-oriented (by default) flex containers: */ + display: flex; +} + +.swatch { + box-sizing: border-box; + + /* This represents the 120px border in the testcase, scaled down 0.4x: */ + border: 48px solid; + + /* Share the width equally among the swatches. (The height will be + automatically set to the flex container's row height, via default + 'align-self' behavior.) */ + flex: 1; + + /* The testcase (rendered at 6-pages-per-sheet) will have 0.2in of extra + space in the horizontal axis, which will be distributed equally with + 0.05in to the left and right of each page in the grid. We mock that up as + margin here: */ + margin: 0 0.05in; +} + +.sheet:nth-child(1) > .row:nth-child(1) > .swatch:nth-child(1) { border-color: cyan; } +.sheet:nth-child(1) > .row:nth-child(1) > .swatch:nth-child(2) { border-color: yellow; } +.sheet:nth-child(1) > .row:nth-child(2) > .swatch:nth-child(1) { border-color: pink; } +.sheet:nth-child(1) > .row:nth-child(2) > .swatch:nth-child(2) { border-color: orange; } +.sheet:nth-child(1) > .row:nth-child(3) > .swatch:nth-child(1) { border-color: purple; } +.sheet:nth-child(1) > .row:nth-child(3) > .swatch:nth-child(2) { border-color: olive; } + +.sheet:nth-child(2) { break-before: always; } +.sheet:nth-child(2) > .row:nth-child(1) > .swatch:nth-child(1) { border-color: blue; } +.sheet:nth-child(2) > .row:nth-child(1) > .swatch:nth-child(2) { border-color: tan; } +.sheet:nth-child(2) > .row:nth-child(2) > .swatch:nth-child(1) { border-color: fuchsia; } +.sheet:nth-child(2) > .row:nth-child(2) > .swatch:nth-child(2) { border-color: salmon; } +.sheet:nth-child(2) > .row:nth-child(3) > .swatch:nth-child(1) { border-color: lightgreen; } +.sheet:nth-child(2) > .row:nth-child(3) > .swatch:nth-child(2) { border-color: navy; } +</style> +<div class="sheet"> +<div class="row"> + <div class="swatch"></div> + <div class="swatch"></div> +</div> +<div class="row"> + <div class="swatch"></div> + <div class="swatch"></div> +</div> +<div class="row"> + <div class="swatch"></div> + <div class="swatch"></div> +</div> +</div> +<div class="sheet"> +<div class="row"> + <div class="swatch"></div> + <div class="swatch"></div> +</div> +<div class="row"> + <div class="swatch"></div> + <div class="swatch"></div> +</div> +<div class="row"> + <div class="swatch"></div> + <div class="swatch"></div> +</div> +</div> diff --git a/layout/base/tests/chrome/printpreview_pps9.html b/layout/base/tests/chrome/printpreview_pps9.html new file mode 100644 index 0000000000..341e5fdf81 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_pps9.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<!-- This is a testcase for a "9-pages-per-sheet" scenario. + There are 9 full-page color-swatches. --> +<style> +html, body { margin: 0; height: 100%; } +.swatch { + box-sizing: border-box; + border: 120px solid; + height: 100%; +} +.swatch:nth-child(1) { border-color: cyan; } +.swatch:nth-child(2) { border-color: yellow; } +.swatch:nth-child(3) { border-color: pink; } +.swatch:nth-child(4) { border-color: orange; } +.swatch:nth-child(5) { border-color: purple; } +.swatch:nth-child(6) { border-color: olive; } +.swatch:nth-child(7) { border-color: blue; } +.swatch:nth-child(8) { border-color: tan; } +.swatch:nth-child(9) { border-color: fuchsia; } +</style> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> diff --git a/layout/base/tests/chrome/printpreview_pps9_ref.html b/layout/base/tests/chrome/printpreview_pps9_ref.html new file mode 100644 index 0000000000..ab90c837aa --- /dev/null +++ b/layout/base/tests/chrome/printpreview_pps9_ref.html @@ -0,0 +1,40 @@ +<!DOCTYPE html> +<!-- This is a reference case for a "9-pages-per-sheet" scenario. The width + and height of each "swatch" is 1/3 the width and height of the page. --> +<style> +html, body { margin: 0; height: 100%; } +body { + display: flex; + flex-flow: row wrap; +} +.swatch { + box-sizing: border-box; + border: 40px solid; + /* The height will be automatically set to the flex container's row height, + via default 'align-self' behavior (which ends up as 'stretch') */ + /* Note: it's OK that the flex-basis isn't exactly 1/3 here. + Flexbox layout will give each flex item 33% of the width, + and then divide up the remaining amount equally. This + results in exactly 3 items fitting per row and each one + getting 1/3 of a row, which is all we're going for. */ + flex: 1 33%; +} +.swatch:nth-child(1) { border-color: cyan; } +.swatch:nth-child(2) { border-color: yellow; } +.swatch:nth-child(3) { border-color: pink; } +.swatch:nth-child(4) { border-color: orange; } +.swatch:nth-child(5) { border-color: purple; } +.swatch:nth-child(6) { border-color: olive; } +.swatch:nth-child(7) { border-color: blue; } +.swatch:nth-child(8) { border-color: tan; } +.swatch:nth-child(9) { border-color: fuchsia; } +</style> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> diff --git a/layout/base/tests/chrome/printpreview_pps_uw2.html b/layout/base/tests/chrome/printpreview_pps_uw2.html new file mode 100644 index 0000000000..34d3af49de --- /dev/null +++ b/layout/base/tests/chrome/printpreview_pps_uw2.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<!-- This is a testcase for a "2-pages-per-sheet" scenario with nonzero + unwriteable margins. There are 2 full-page "swatches" with large colorful + borders. --> +<style> +html, body { margin: 0; height: 100%; } +.swatch { + box-sizing: border-box; + border: 240px solid; + height: 100%; +} +.swatch:nth-child(1) { border-color: cyan; } +.swatch:nth-child(2) { border-color: pink; } +</style> +<div class="swatch"></div> +<div class="swatch"></div> diff --git a/layout/base/tests/chrome/printpreview_pps_uw2_no_margin_ref.html b/layout/base/tests/chrome/printpreview_pps_uw2_no_margin_ref.html new file mode 100644 index 0000000000..223aab8d55 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_pps_uw2_no_margin_ref.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<!-- This is a reference case for a "2-pages-per-sheet" scenario zero + unwriteable margins. We're scaling down 8in width to fit 2 in 10in, + so the scale factor is (10 / 2) / 8 = 0.625x. --> +<style> +html { height: 100%; } +body { + height: 100%; + margin: 0; + box-sizing: border-box; + + /* The testcase (rendered at 2-pages-per-sheet) will have 8 - (10in * 0.625) + * = 1.75in of extra vertical space. */ + padding: 0.875in 0; + + /* We lay out the body as a row-oriented flex container, with two + side-by-side children which correspond to the two pages per sheet: */ + display: flex; +} +.swatch { + box-sizing: border-box; + + /* This represents the 240px border in the testcase, scaled down 0.5x: */ + border: 150px solid; + + /* Share the width equally among the swatches. (The height will be + automatically set to the flex container's row height, via default + 'align-self' behavior.) */ + flex: 1; + margin: 0; +} +.swatch:nth-child(1) { border-color: cyan; } +.swatch:nth-child(2) { border-color: pink; } +</style> +<div class="swatch"></div> +<div class="swatch"></div> diff --git a/layout/base/tests/chrome/printpreview_pps_uw2_ref.html b/layout/base/tests/chrome/printpreview_pps_uw2_ref.html new file mode 100644 index 0000000000..d923901096 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_pps_uw2_ref.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<!-- This is a reference case for a "2-pages-per-sheet" scenario with nonzero + unwriteable margins. We expect the pages to have a 0.5x scale-down + factor. That 0.5 scale-factor comes from the fact that, when rendering the + testcase, we'll need to scale the page-width (8in) down enough to fit + side-by-side into half of the sheet's available width (with the sheet + having been rotated to landscape mode), with the sheet's unwritable margin + having already been subtracted out. The sheet's width (in landscape mode) + is 10in, and its unwriteable margin in that axis is 2in, so it's got 8in + of available width to hold two side-by-side pages, i.e. 4in per page. + Since the page width was 8in, that makes for a 0.5x scale. --> +<style> +html { height: 100%; } +body { + height: 100%; + margin: 0; + box-sizing: border-box; + + /* The testcase (rendered at 2-pages-per-sheet) will have 2in of extra space + in the vertical axis, which will be distributed equally with 1in on the + top and the bottom of the page grid (separately from the sheet's + unwriteable margin). We mock that up as padding here: */ + padding: 1in 0; + + /* We lay out the body as a row-oriented flex container, with two + side-by-side children which correspond to the two pages per sheet: */ + display: flex; +} +.swatch { + box-sizing: border-box; + + /* This represents the 240px border in the testcase, scaled down 0.5x: */ + border: 120px solid; + + /* Share the width equally among the swatches. (The height will be + automatically set to the flex container's row height, via default + 'align-self' behavior.) */ + flex: 1; + + /* This margin is meant to mock up the unwriteable margin for each page on + our sheet; it's exactly 0.5x the unwriteableMargin values specified for + the testcase in printpreview_helper.xhtml. */ + margin: 0.4in 0.3in 0.6in 0.2in; +} +.swatch:nth-child(1) { border-color: cyan; } +.swatch:nth-child(2) { border-color: pink; } +</style> +<div class="swatch"></div> +<div class="swatch"></div> diff --git a/layout/base/tests/chrome/printpreview_pps_uw4.html b/layout/base/tests/chrome/printpreview_pps_uw4.html new file mode 100644 index 0000000000..6e3d030c6d --- /dev/null +++ b/layout/base/tests/chrome/printpreview_pps_uw4.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<!-- This is a testcase for a "4-pages-per-sheet" scenario. + There are 4 full-page "swatches" with large colorful borders. --> +<style> +html, body { margin: 0; height: 100%; } +.swatch { + box-sizing: border-box; + border: 120px solid; + height: 100%; +} +.swatch:nth-child(1) { border-color: cyan; } +.swatch:nth-child(2) { border-color: yellow; } +.swatch:nth-child(3) { border-color: pink; } +.swatch:nth-child(4) { border-color: orange; } +</style> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> diff --git a/layout/base/tests/chrome/printpreview_pps_uw4_ref.html b/layout/base/tests/chrome/printpreview_pps_uw4_ref.html new file mode 100644 index 0000000000..a603ff2be9 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_pps_uw4_ref.html @@ -0,0 +1,70 @@ +<!DOCTYPE html> +<!-- This is a reference case for a "4-pages-per-sheet" scenario. This file is + a mockup of a sheet with 4 pages, with the pages all having a 0.4x scale + scale factor applied. (We end up with that scale factor by subtracting the + requested unwriteable margins from the sheet, and dividing up the + remaining space equally among the "virtual pages".) --> +<style> +html { + display: flex; + height: 100%; + margin: 0; +} +body { + /* As a flex item (a child of the html element), fill the available area. */ + flex: 1; + + /* We lay out the body as a column-oriented flex container (whose children, + in turn, are rows). */ + display: flex; + flex-direction: column; + + /* These values come directly from the unwriteableMargin values in the + testcase's configuration code in printpreview_helper.xhtml. */ + margin-top: 0.6in; + margin-right: 0.1in; + margin-bottom: 0.4in; + margin-left: 0.3in; +} + +.row { + /* Give each row an equal share of the available height: */ + flex: 1; + + /* ...and render them as row-oriented (by default) flex containers: */ + display: flex; +} + +.swatch { + box-sizing: border-box; + + /* These represent the 120px borders in the testcase, scaled down 0.4x: */ + border: 48px solid; + + /* Share the width equally among the swatches. (The height will be + automatically set to the flex container's row height, via default + 'align-self' behavior.) */ + flex: 1; + + /* These values come directly from the unwriteableMargin values in the + testcase's configuration code in printpreview_helper.xhtml, with + each measurement scaled down by exactly 0.4x. The extra 0.1in accounts + for the centering of each page in its grid cell. */ + margin-top: 0.24in; + margin-right: calc(0.04in + 0.1in); + margin-bottom: 0.16in; + margin-left: calc(0.12in + 0.1in); +} +.row:nth-child(1) > .swatch:nth-child(1) { border-color: cyan; } +.row:nth-child(1) > .swatch:nth-child(2) { border-color: yellow; } +.row:nth-child(2) > .swatch:nth-child(1) { border-color: pink; } +.row:nth-child(2) > .swatch:nth-child(2) { border-color: orange; } +</style> +<div class="row"> + <div class="swatch"></div> + <div class="swatch"></div> +</div> +<div class="row"> + <div class="swatch"></div> + <div class="swatch"></div> +</div> diff --git a/layout/base/tests/chrome/printpreview_pps_uw9.html b/layout/base/tests/chrome/printpreview_pps_uw9.html new file mode 100644 index 0000000000..9bd0e1f5a4 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_pps_uw9.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<!-- This is a testcase for a "9-pages-per-sheet" scenario. + There are 9 full-page "swatches" with large colorful borders. --> +<style> +html, body { margin: 0; height: 100%; } +.swatch { + box-sizing: border-box; + border: 120px solid; + height: 100%; +} +.swatch:nth-child(1) { border-color: cyan; } +.swatch:nth-child(2) { border-color: yellow; } +.swatch:nth-child(3) { border-color: pink; } +.swatch:nth-child(4) { border-color: orange; } +.swatch:nth-child(5) { border-color: purple; } +.swatch:nth-child(6) { border-color: olive; } +.swatch:nth-child(7) { border-color: blue; } +.swatch:nth-child(8) { border-color: tan; } +.swatch:nth-child(9) { border-color: fuchsia; } +</style> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> +<div class="swatch"></div> diff --git a/layout/base/tests/chrome/printpreview_pps_uw9_ref.html b/layout/base/tests/chrome/printpreview_pps_uw9_ref.html new file mode 100644 index 0000000000..de3cb1e08b --- /dev/null +++ b/layout/base/tests/chrome/printpreview_pps_uw9_ref.html @@ -0,0 +1,82 @@ +<!DOCTYPE html> +<!-- This is a reference case for a "9-pages-per-sheet" scenario. This file is + a mockup of a sheet with 9 pages, with the pages all having a 0.2x scale + scale factor applied. (We end up with that scale factor by subtracting the + requested unwriteable margins from the sheet, and dividing up the + remaining space equally among the "virtual pages".) --> +<style> +html { + display: flex; + height: 100%; + margin: 0; +} +body { + /* As a flex item (a child of the html element), fill the available area. */ + flex: 1; + + /* We lay out the body as a column-oriented flex container (whose children, + in turn, are rows). */ + display: flex; + flex-direction: column; + + /* These values come directly from the unwriteableMargin values in the + testcase's configuration code in printpreview_helper.xhtml. */ + margin-top: 0.2in; + margin-right: 0.8in; + margin-bottom: 0.4in; + margin-left: 1.2in; +} + +.row { + /* Give each row an equal share of the available height: */ + flex: 1; + + /* ...and render them as row-oriented (by default) flex containers: */ + display: flex; +} + +.swatch { + box-sizing: border-box; + + /* These represent the 120px borders in the testcase, scaled down 0.2x: */ + border: 24px solid; + + /* Share the width equally among the swatches. (The height will be + automatically set to the flex container's row height, via default + 'align-self' behavior.) */ + flex: 1; + + /* These values come directly from the unwriteableMargin values in the + testcase's configuration code in printpreview_helper.xhtml, with + each measurement scaled down by exactly 0.2x. The extra 0.5667in accounts + for the centering of each page in its grid cell. */ + margin-top: calc(0.04in + 0.5667in); + margin-right: 0.16in; + margin-bottom: calc(0.08in + 0.5667in); + margin-left: 0.24in; +} +.row:nth-child(1) > .swatch:nth-child(1) { border-color: cyan; } +.row:nth-child(1) > .swatch:nth-child(2) { border-color: yellow; } +.row:nth-child(1) > .swatch:nth-child(3) { border-color: pink; } +.row:nth-child(2) > .swatch:nth-child(1) { border-color: orange; } +.row:nth-child(2) > .swatch:nth-child(2) { border-color: purple; } +.row:nth-child(2) > .swatch:nth-child(3) { border-color: olive; } +.row:nth-child(3) > .swatch:nth-child(1) { border-color: blue; } +.row:nth-child(3) > .swatch:nth-child(2) { border-color: tan; } +.row:nth-child(3) > .swatch:nth-child(3) { border-color: fuchsia; } +</style> +<div class="row"> + <div class="swatch"></div> + <div class="swatch"></div> + <div class="swatch"></div> +</div> +<div class="row"> + <div class="swatch"></div> + <div class="swatch"></div> + <div class="swatch"></div> +</div> +<div class="row"> + <div class="swatch"></div> + <div class="swatch"></div> + <div class="swatch"></div> +</div> diff --git a/layout/base/tests/chrome/printpreview_prettyprint.xml b/layout/base/tests/chrome/printpreview_prettyprint.xml new file mode 100644 index 0000000000..759d5066cf --- /dev/null +++ b/layout/base/tests/chrome/printpreview_prettyprint.xml @@ -0,0 +1 @@ +<out>Here be sea hags</out> diff --git a/layout/base/tests/chrome/printpreview_prettyprint_ref.xhtml b/layout/base/tests/chrome/printpreview_prettyprint_ref.xhtml new file mode 100644 index 0000000000..7309425fb4 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_prettyprint_ref.xhtml @@ -0,0 +1,3 @@ +<out><div id="top" xmlns="http://www.w3.org/1999/xhtml"><link href="chrome://global/content/xml/XMLPrettyPrint.css" type="text/css" rel="stylesheet"/><div id="header"><p> + This XML file does not appear to have any style information associated with it. The document tree is shown below. + </p></div><main id="tree" class="highlight"><div><<span class="start-tag">out</span>><span class="text">Here be sea hags</span></<span class="end-tag">out</span>></div></main></div></out> diff --git a/layout/base/tests/chrome/printpreview_quirks.html b/layout/base/tests/chrome/printpreview_quirks.html new file mode 100644 index 0000000000..fa8714a0f7 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_quirks.html @@ -0,0 +1,8 @@ +<!doctype html> +<meta charset="utf-8"> +<style> + .HiDdEn { display: none } +</style> +<body class="hidden"> + Some content that I should be able to print. +</body> diff --git a/layout/base/tests/chrome/printpreview_quirks_ref.html b/layout/base/tests/chrome/printpreview_quirks_ref.html new file mode 100644 index 0000000000..4c6fcce1f6 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_quirks_ref.html @@ -0,0 +1,5 @@ +<!doctype html> +<meta charset="utf-8"> +<body> + Some content that I should be able to print. +</body> diff --git a/layout/base/tests/chrome/red.png b/layout/base/tests/chrome/red.png Binary files differnew file mode 100644 index 0000000000..57bf3ddc52 --- /dev/null +++ b/layout/base/tests/chrome/red.png diff --git a/layout/base/tests/chrome/test_bug1018265.xhtml b/layout/base/tests/chrome/test_bug1018265.xhtml new file mode 100644 index 0000000000..53862b0e5e --- /dev/null +++ b/layout/base/tests/chrome/test_bug1018265.xhtml @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1018265 +--> +<window title="Mozilla Bug 1018265" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="run()"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for Bug 1018265 **/ + + SimpleTest.waitForExplicitFinish(); + + function run() { + window.openDialog("file_bug1018265.xhtml", "contentViewerTest", "chrome,width=100,height=100,noopener", window); + } + + function done() { + ok(true, "done"); + setTimeout(function() { SimpleTest.finish(); }, 0); + } + ]]> + </script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1018265" + target="_blank">Mozilla Bug 1018265</a> + </body> +</window> diff --git a/layout/base/tests/chrome/test_bug1041200.xhtml b/layout/base/tests/chrome/test_bug1041200.xhtml new file mode 100644 index 0000000000..365ecf2825 --- /dev/null +++ b/layout/base/tests/chrome/test_bug1041200.xhtml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + SimpleTest.waitForExplicitFinish(); + // Run the test in a separate window so that the test runs as a chrome + // window + window.openDialog("bug1041200_window.html", "bug1041200", + "chrome,width=800,height=800,noopener", window); + ]]> + </script> +</window> diff --git a/layout/base/tests/chrome/test_bug396367-1.html b/layout/base/tests/chrome/test_bug396367-1.html new file mode 100644 index 0000000000..63b33d335d --- /dev/null +++ b/layout/base/tests/chrome/test_bug396367-1.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=396367 +--> +<head> + <title>Test for Bug 396367</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <script> + SimpleTest.waitForExplicitFinish(); + + function finish() { + ok(true, "didn't crash"); + top.docShell.browsingContext.textZoom = 1; + SimpleTest.finish(); + } + </script> +</head> +<body> + +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=396367">Mozilla Bug 396367</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> + +<input> +<script>document.body.setAttribute('style', 'display: -moz-box; overflow: scroll;');</script> +<script> +top.docShell.browsingContext.textZoom = Math.floor(10 * Math.random()) / 4 + 0.2; +document.documentElement.offsetHeight; +setTimeout(finish, 0); +</script> + + +</pre> +</body> +</html> diff --git a/layout/base/tests/chrome/test_bug396367-2.html b/layout/base/tests/chrome/test_bug396367-2.html new file mode 100644 index 0000000000..2a751cd8be --- /dev/null +++ b/layout/base/tests/chrome/test_bug396367-2.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=396367 +--> +<head> + <title>Test for Bug 396367</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <style>select::after { content:"m"; }</style> + <script> + SimpleTest.waitForExplicitFinish(); + + function finish() { + ok(true, "didn't crash"); + top.docShell.browsingContext.textZoom = 1; + SimpleTest.finish(); + } + </script> +</head> +<body> + +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=396367">Mozilla Bug 396367</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> + +<div style="overflow: scroll; float: left;"> + +<select></select> + +<li style="display: table-cell;"> + +<script> +top.docShell.browsingContext.textZoom = Math.floor(10 * Math.random()) / 4 + 0.2; +document.documentElement.offsetHeight; +setTimeout(finish, 0); +</script> +</li> +</div> + + +</pre> +</body> +</html> diff --git a/layout/base/tests/chrome/test_bug420499.xhtml b/layout/base/tests/chrome/test_bug420499.xhtml new file mode 100644 index 0000000000..22fefd7987 --- /dev/null +++ b/layout/base/tests/chrome/test_bug420499.xhtml @@ -0,0 +1,126 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=420499 +--> +<window title="Mozilla Bug 420499" onload="setTimeout(focusInput, 500);" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> + + + + <menu id="menu" label="Menu"> + <menupopup id="file-popup"> + <!-- <input xmlns="http://www.w3.org/1999/xhtml" id="some-text" maxlength="10" value="some text"/> --> + <menu label="submenu"> + <menupopup id="file-popup-inner"> + + <menuitem label="Item1"/> + <menuitem label="Item2"/> + <input xmlns="http://www.w3.org/1999/xhtml" id="some-text" maxlength="10" value="some more text"/> + </menupopup> + </menu> + <menuitem label="Item3"/> + <menuitem label="Item4"/> + </menupopup> + </menu> + + <popupset> + <menupopup id="contextmenu"> + <menuitem label="Cut"/> + <menuitem label="Copy"/> + <menuitem label="Paste"/> + </menupopup> + <tooltip id="tooltip" orient="vertical"> + <description value="This is a tooltip"/> + </tooltip> + </popupset> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml" bgcolor="white"> + + <p id="par1">Paragraph 1</p> + <p id="par2">Paragraph 2</p> + <p id="par3">Paragraph 3</p> + <p id="par4">Paragraph 4</p> + <p id="par5">Paragraph 5</p> + + <input type="text" id="text-input" maxlength="10" value="some more text"/> <br /> + + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=420499" + target="_blank">Mozilla Bug 420499</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 420499 **/ + SimpleTest.waitForExplicitFinish(); + + function getSelectionController() { + return window.docShell + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsISelectionDisplay) + .QueryInterface(Ci.nsISelectionController); + } + + function isCaretVisible() { + var docShell = window.docShell; + var selCon = docShell.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsISelectionDisplay) + .QueryInterface(Ci.nsISelectionController); + return selCon.caretVisible; + } + + function focusInput() { + ok(!isCaretVisible(), "Caret shouldn't be visible"); + $("text-input").focus(); + ok(isCaretVisible(), "Caret should be visible when input focused"); + window.addEventListener("popupshown", popupMenuShownHandler); + $("menu").open = true; + } + + function popupMenuShownHandler() { + window.removeEventListener("popupshown", popupMenuShownHandler); + ok(!isCaretVisible(), "Caret shouldn't be visible when menu open"); + window.addEventListener("popuphidden", ensureParagraphFocused); + $("menu").open = false; + } + + function ensureParagraphFocused() { + window.removeEventListener("popuphidden", ensureParagraphFocused); + ok(isCaretVisible(), "Caret should have returned to previous focus"); + window.addEventListener("popupshown", popupMenuShownHandler2); + $("contextmenu").openPopup($('text-input'), "topleft" , -1 , -1 , true, true); + } + + function popupMenuShownHandler2() { + window.removeEventListener("popupshown", popupMenuShownHandler2); + ok(isCaretVisible(), "Caret should be visible when context menu open"); + window.addEventListener("popuphidden", ensureParagraphFocused2); + document.getElementById("contextmenu").hidePopup(); + } + + function ensureParagraphFocused2() { + window.removeEventListener("popuphidden", ensureParagraphFocused2); + ok(isCaretVisible(), "Caret should still be visible"); + window.addEventListener("popupshown", tooltipShownHandler); + $("tooltip").openPopup($('text-input'), "topleft" , -1 , -1 , false, true); + } + + function tooltipShownHandler() { + window.removeEventListener("popupshown", tooltipShownHandler); + ok(isCaretVisible(), "Caret should be visible when tooltip is visible"); + window.addEventListener("popuphidden", ensureParagraphFocused3); + document.getElementById("tooltip").hidePopup(); + } + + function ensureParagraphFocused3() { + window.removeEventListener("popuphidden", ensureParagraphFocused2); + ok(isCaretVisible(), "Caret should still be visible"); + SimpleTest.finish(); + } + ]]></script> +</window> diff --git a/layout/base/tests/chrome/test_bug458898.html b/layout/base/tests/chrome/test_bug458898.html new file mode 100644 index 0000000000..a7913f9a2a --- /dev/null +++ b/layout/base/tests/chrome/test_bug458898.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=458898 +--> +<head> + <title>Test for Bug 458898</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=458898">Mozilla Bug 458898</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); +var win = window.browsingContext.topChromeWindow.openDialog("file_bug458898.html"); + +function loaded() { + var disableWindowResizePref = "dom.disable_window_move_resize"; + SpecialPowers.pushPrefEnv({"set":[[disableWindowResizePref, false]]}, function() { + win.sizeToContent(); + ok(win.innerWidth >= 100, "innerWidth: " + win.innerWidth + " >= 100 ?"); + ok(win.innerHeight >= 200, "innerHeight: " + win.innerHeight + " >= 200 ?"); + win.close(); + SimpleTest.finish(); + }); +} + +win.addEventListener("load", loaded); + +</script> +</pre> +</body> +</html> diff --git a/layout/base/tests/chrome/test_bug465448.xhtml b/layout/base/tests/chrome/test_bug465448.xhtml new file mode 100644 index 0000000000..fa9d1589a2 --- /dev/null +++ b/layout/base/tests/chrome/test_bug465448.xhtml @@ -0,0 +1,45 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> + +<window title="Bug 465448" + onload="loaded()" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> + +<script><![CDATA[ +SimpleTest.waitForExplicitFinish(); +var loadedCalled = false; +var win = window.open("file_bug465448.html", "_blank", "width=600,height=600"); + +function loaded() { + if (!loadedCalled) { + loadedCalled = true; + return; + } + win.sizeToContent(); + win.sizeToContent(); + win.sizeToContent(); + win.sizeToContent(); + win.sizeToContent(); + win.sizeToContent(); + ok(win.innerWidth >= 100, "innerWidth"); + ok(win.innerHeight >= 200, "innerHeight"); + win.close(); + SimpleTest.finish(); +} +]]></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<p id="display"> +</p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +</pre> +</body> + +</window> diff --git a/layout/base/tests/chrome/test_bug514660.xhtml b/layout/base/tests/chrome/test_bug514660.xhtml new file mode 100644 index 0000000000..a7c03a054d --- /dev/null +++ b/layout/base/tests/chrome/test_bug514660.xhtml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=514660 +--> +<window title="Mozilla Bug 504311" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="doTest()"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<body xmlns="http://www.w3.org/1999/xhtml"> +<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=514660" + target="_blank">Mozilla Bug 514660</a> +<textarea></textarea> +</body> + <!-- test code goes here --> +<script type="application/javascript"> +<![CDATA[ +SimpleTest.waitForExplicitFinish(); + +function doTest() +{ + var viewer = window.docShell.contentViewer; + viewer.authorStyleDisabled = true; + + document.documentElement.getBoundingClientRect(); + ok(true, "Didn't crash"); + + viewer.authorStyleDisabled = false; + + SimpleTest.finish(); +} +]]></script> +</window> diff --git a/layout/base/tests/chrome/test_bug533845.xhtml b/layout/base/tests/chrome/test_bug533845.xhtml new file mode 100644 index 0000000000..3ea21cb9b7 --- /dev/null +++ b/layout/base/tests/chrome/test_bug533845.xhtml @@ -0,0 +1,49 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=533845 +--> +<window title="Mozilla Bug 533845" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="doTest()"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<panel id="panel" style="width: 500px; height: 500px"> + <iframe type="content" id="contentFrame" src="data:text/html,<html><body onclick='document.body.textContent=1'>This is a panel!</body></html>" width="500" height="500"/> +</panel> +<body xmlns="http://www.w3.org/1999/xhtml"> +<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=533845" + target="_blank">Mozilla Bug 533845</a> +</body> + <!-- test code goes here --> +<script type="application/javascript"> +<![CDATA[ +SimpleTest.waitForExplicitFinish(); + +function doTest() { + let panel = document.getElementById("panel"); + panel.addEventListener("popupshown", function onpopupshown() { + continueTest(); + panel.addEventListener("popuphidden", function onpopuphidden() { + SimpleTest.finish(); + }, { once: true }); + panel.hidePopup(); + }, { once: true }); + panel.openPopup(); +} + +function continueTest() { + var ifrwindow = document.getElementById("contentFrame").contentWindow; + ifrwindow.focus(); + var utils = ifrwindow.windowUtils; + var rect = ifrwindow.document.body.getBoundingClientRect(); + var x = rect.left + (rect.width/2); + var y = rect.top + (rect.height/2); + utils.sendMouseEvent("mousedown", x, y, 0, 1, 0); + utils.sendMouseEvent("mouseup", x, y, 0, 1, 0); + is(ifrwindow.document.body.textContent, "1", "Should have got a click event!"); +} + +]]></script> +</window> diff --git a/layout/base/tests/chrome/test_bug551434.html b/layout/base/tests/chrome/test_bug551434.html new file mode 100644 index 0000000000..5e21cf6408 --- /dev/null +++ b/layout/base/tests/chrome/test_bug551434.html @@ -0,0 +1,95 @@ +<html> +<head> + <title>Test for Bug 551434</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" /> +</head> +<body> +</div> +<pre id="test"> +<input id="i1" onkeydown="gKeyDown1++; $('i2').focus();" onkeypress="gKeyPress1++;" onkeyup="gKeyUp1++;"/> +<input id="i2" onkeydown="gKeyDown2++;" onkeypress="gKeyPress2++;" onkeyup="gKeyUp2++;"/> + +<input id="i3" onkeydown="gKeyDown3++; frames[0].document.getElementById('i4').focus();" + onkeypress="gKeyPress3++;" onkeyup="gKeyUp3++;"/> +<iframe id="iframe" src="http://example.org/chrome/layout/base/tests/chrome/bug551434_childframe.html"></iframe> + +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var gKeyDown1 = 0, gKeyPress1 = 0, gKeyUp1 = 0; +var gKeyDown2 = 0, gKeyPress2 = 0, gKeyUp2 = 0; +var gKeyDown3 = 0, gKeyPress3 = 0, gKeyUp3 = 0; + +function runTest() +{ + $("i1").focus(); + + // key events should not be retargeted when the focus changes to an + // element in the same document. + synthesizeKey("a", {type: "keydown"}); + is(document.activeElement, $("i2"), "input 2 in focused"); + + synthesizeKey("a", {type: "keyup"}); + + is(gKeyDown1, 1, "keydown on input 1"); + is(gKeyPress1, 0, "keypress on input 1"); + is(gKeyUp1, 0, "keyup on input 1"); + is(gKeyDown2, 0, "keydown on input 2"); + is(gKeyPress2, 1, "keypress on input 2"); + is(gKeyUp2, 1, "keyup on input 2"); + + is($("i1").value, "", "input 1 value"); + is($("i2").value, "a", "input 2 value"); + + // key events should however be retargeted when the focus changes to an + // element in the a content document from a chrome document. + $("i3").focus(); + + var childWinObj = frames[0].wrappedJSObject; + + sendString("b"); + is(gKeyDown3, 1, "keydown on input 3"); + is(gKeyPress3, 1, "keypress on input 3"); + is(gKeyUp3, 1, "keyup on input 3"); + is(childWinObj.gKeyDownChild, 0, "keydown on input 4"); + is(childWinObj.gKeyPressChild, 0, "keypress on input 4"); + is(childWinObj.gKeyUpChild, 0, "keyup on input 4"); + + var i4 = frames[0].document.getElementById("i4"); + is($("i3").value, "b", "input 3 value"); + is(i4.value, "", "input 4 value"); + + is(document.activeElement, $("iframe"), "parent focus"); + is(frames[0].document.activeElement, i4, "child focus"); + + // key events should also be retargeted when the focus changes to an + // element in a chrome document from a content document. + i4.addEventListener("keydown", () => $("i3").focus()); + + sendString("c"); + + is(gKeyDown3, 1, "keydown on input 3"); + is(gKeyPress3, 1, "keypress on input 3"); + is(gKeyUp3, 1, "keyup on input 3"); + is(childWinObj.gKeyDownChild, 1, "keydown on input 4"); + is(childWinObj.gKeyPressChild, 1, "keypress on input 4"); + is(childWinObj.gKeyUpChild, 1, "keyup on input 4"); + + is($("i3").value, "b", "input 3 value"); + is(i4.value, "c", "input 4 value"); + + is(document.activeElement, $("i3"), "parent focus"); + + SimpleTest.finish(); +} + +SimpleTest.waitForFocus(runTest); + +</script> +</pre> +</body> +</html> + diff --git a/layout/base/tests/chrome/test_bug708062.html b/layout/base/tests/chrome/test_bug708062.html new file mode 100644 index 0000000000..ee7df7d37d --- /dev/null +++ b/layout/base/tests/chrome/test_bug708062.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=708062 +--> +<head> + <title>Test for Bug 708062</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> +</head> +<body onload="doTest()"> + +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=708062">Mozilla Bug 708062</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<iframe id="f" style="width:100px;" + src="data:text/html,A<div id='d' style='position:fixed;width:170px;top:0;right:0;height:1px;background:yellow;'>"></iframe> +<pre id="test"> + +<script> +function isBoundingClientRect(e, r, msg) { + var BCR = e.getBoundingClientRect(); + is([BCR.left, BCR.top, BCR.right, BCR.bottom].join(','), r, msg); +} + +function doTest() { + var f = document.getElementById('f'); + + var d = f.contentDocument.getElementById('d'); + + isBoundingClientRect(d, "-70,0,100,1", "initial rect"); + SpecialPowers.setFullZoom(f.contentWindow, 2); + isBoundingClientRect(d, "-120,0,50,1", "after zooming in"); + SpecialPowers.setFullZoom(f.contentWindow, 1); + isBoundingClientRect(d, "-70,0,100,1", "after zooming back out"); + SimpleTest.finish(); +} +</script> +</pre> +</body> +</html> diff --git a/layout/base/tests/chrome/test_bug812817.xhtml b/layout/base/tests/chrome/test_bug812817.xhtml new file mode 100644 index 0000000000..c5eb747ea6 --- /dev/null +++ b/layout/base/tests/chrome/test_bug812817.xhtml @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=812817 +--> +<window title="Mozilla Bug 812817" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="doTest()"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<panel id="panel" width="200" height="200" onpopupshown="continueTest()"> +</panel> +<body xmlns="http://www.w3.org/1999/xhtml"> +<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=812817" + target="_blank">Mozilla Bug 812817</a> +</body> + <!-- test code goes here --> +<script type="application/javascript"> +<![CDATA[ +SimpleTest.waitForExplicitFinish(); + +var panel = document.getElementById('panel'); +function doTest() { + panel.openPopup(null, '', 500, 500, false, false, null); +} + +function continueTest() { + panel.style.background = "url(blue-32x32.png)"; + setTimeout(function() { + ok(true, "Didn't crash"); + SimpleTest.finish(); + }, 50); +} + +]]></script> +</window> diff --git a/layout/base/tests/chrome/test_chrome_content_integration.xhtml b/layout/base/tests/chrome/test_chrome_content_integration.xhtml new file mode 100644 index 0000000000..6e6be4761a --- /dev/null +++ b/layout/base/tests/chrome/test_chrome_content_integration.xhtml @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/chrome-harness.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + SimpleTest.waitForExplicitFinish(); + // Run the test in a separate window so that the test runs as a chrome + // window + var root = getRootDirectory(window.location.href); + window.openDialog(root + "chrome_content_integration_window.xhtml", "chrome_content_integration", + "chrome,width=200,height=300,noopener", window); + ]]> + </script> +</window> diff --git a/layout/base/tests/chrome/test_color_scheme_browser.xhtml b/layout/base/tests/chrome/test_color_scheme_browser.xhtml new file mode 100644 index 0000000000..15a6ac2282 --- /dev/null +++ b/layout/base/tests/chrome/test_color_scheme_browser.xhtml @@ -0,0 +1,114 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <head> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/chrome-harness.js"></script> + <style> + #light { color-scheme: light } + #dark { color-scheme: dark } + </style> + </head> + <body> + <div id="dynamic-test"> + <xul:browser type="content" remote="true" nodefaultsrc="true" class="remote" /> + <xul:browser type="content" src="about:blank" class="nonremote" /> + </div> + <div id="light"> + <xul:browser type="content" remote="true" nodefaultsrc="true" class="remote" /> + <xul:browser type="content" src="about:blank" class="nonremote" /> + </div> + <div id="dark"> + <xul:browser type="content" remote="true" nodefaultsrc="true" class="remote" /> + <xul:browser type="content" src="about:blank" class="nonremote" /> + </div> + <script><![CDATA[ + // FIXME: This shouldn't be needed if remote browsers would block the load event. + add_task(async function ensureBrowsersLoaded() { + const triggeringPrincipal = document.nodePrincipal; + for (let b of document.querySelectorAll("browser[remote=true]")) { + let loaded = new Promise(resolve => { + b.addProgressListener({ + onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) { + info(`Got state change for ${b.parentNode.id}: ${aStateFlags}, ${aStatus}`); + if ( + aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW && + aStateFlags & Ci.nsIWebProgressListener.STATE_STOP + ) { + resolve(); + b.removeProgressListener(this); + } + }, + QueryInterface: ChromeUtils.generateQI([ + "nsIWebProgressListener", + "nsISupportsWeakReference", + ]), + }); + }); + b.loadURI(null /*blank*/, { triggeringPrincipal }); + await loaded; + } + }); + async function getBrowserColorScheme(browser) { + return SpecialPowers.spawn(browser, [], () => { + return content.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; + }); + } + async function tick() { + return new Promise(resolve => { + requestAnimationFrame(() => requestAnimationFrame(resolve)); + }); + } + async function testElement(id, expectedIfTop, expectedIfNonTop) { + let element = document.getElementById(id); + for (let browser of element.querySelectorAll("browser")) { + let scheme = await getBrowserColorScheme(browser); + let expected = browser.browsingContext.top == browser.browsingContext ? expectedIfTop : expectedIfNonTop; + is(scheme, expected, `${id}: ${browser.className} should be ${expected}`); + } + } + add_task(async function test_browser_color_scheme() { + let current = matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; + for (let id of ["dynamic-test", "light", "dark"]) { + let expected = id == "dynamic-test" ? current : id; + await testElement(id, expected, expected); + } + }); + + add_task(async function test_browser_color_scheme_dynamic_style() { + let current = matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; + let dynamicTest = document.getElementById("dynamic-test"); + for (let value of ["light", "dark"]) { + await tick(); + dynamicTest.style.colorScheme = value; + await testElement("dynamic-test", value, value); + } + dynamicTest.style.colorScheme = ""; + await tick(); + }); + + add_task(async function test_browser_color_scheme_dynamic_system() { + const ACTIVE_THEME_ID = Services.prefs.getCharPref("extensions.activeThemeID"); + const DEFAULT_THEME_ID = "default-theme@mozilla.org"; + if (ACTIVE_THEME_ID != DEFAULT_THEME_ID) { + info(`skipping test_browser_color_scheme_dynamic_system because the active theme is ${ACTIVE_THEME_ID} instead of ${DEFAULT_THEME_ID}`); + return; + } + for (let dark of [true, false]) { + await SpecialPowers.pushPrefEnv({ + set: [ + ["layout.css.prefers-color-scheme.content-override", 2], + ["ui.systemUsesDarkTheme", dark ? 1 : 0], + ] + }); + await tick(); + let expected = dark ? "dark" : "light"; + await testElement("dynamic-test", expected, expected); + await SpecialPowers.popPrefEnv(); + } + }); + ]]></script> + </body> +</html> + diff --git a/layout/base/tests/chrome/test_css_visibility_propagation.xhtml b/layout/base/tests/chrome/test_css_visibility_propagation.xhtml new file mode 100644 index 0000000000..7b1b082064 --- /dev/null +++ b/layout/base/tests/chrome/test_css_visibility_propagation.xhtml @@ -0,0 +1,209 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> +<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> +<body xmlns="http://www.w3.org/1999/xhtml"></body> +<script> +<![CDATA[ +const baseURL = "chrome://mochitests/content/chrome/layout/base/tests/chrome/"; + +function checkHiddenEmbeddederState(window1, window2, expected1, expected2) +{ + ok(!window1.browsingContext.isUnderHiddenEmbedderElement, "window1 visible state"); + ok(!window2.browsingContext.isUnderHiddenEmbedderElement, "window2 visible state"); + is(window1.document.querySelector("browser").contentWindow.browsingContext.isUnderHiddenEmbedderElement, !expected1, + "window1 child visible state"); + is(window2.document.querySelector("browser").contentWindow.browsingContext.isUnderHiddenEmbedderElement, !expected2, + "window2 child visible state"); +} + +// Tests that browser visibility is updated when it's swapped. +add_task(async () => { + // Open two new windows to swap iframes. + const window1 = window.browsingContext.topChromeWindow.open( + baseURL + "window_css_visibility_propagation-1.xhtml", + "_blank", "chrome"); + const window2 = window.browsingContext.topChromeWindow.open( + baseURL + "window_css_visibility_propagation-2.xhtml", + "_blank", "chrome"); + + const loadWindow1 = + new Promise(resolve => window1.addEventListener("load", resolve)); + const loadWindow2 = + new Promise(resolve => window2.addEventListener("load", resolve)); + + await Promise.all([ loadWindow1, loadWindow2 ]); + + checkHiddenEmbeddederState(window1, window2, true, true); + + // Hide the parent of browser2. + let parent = window2.document.getElementById("parent"); + parent.style.visibility = "hidden"; + parent.getBoundingClientRect(); + + checkHiddenEmbeddederState(window1, window2, true, false); + + const browser2 = window2.document.querySelector("browser"); + let target = browser2.contentDocument.getElementById("button"); + target.focus(); + + // browser2 is now in a visibility:hidden element in window2, + // so that Element.focus() shouldn't work. + isnot(browser2.contentDocument.activeElement, target, + "Element.focus() shouldn't work in invisible browser"); + + // Make the parent visible. + parent.style.visibility = ""; + parent.getBoundingClientRect(); + + checkHiddenEmbeddederState(window1, window2, true, true); + + target.focus(); + + // browser2 is visible now, so focus() should work. + is(browser2.contentDocument.activeElement, target, + "Element.focus() should work in visible browser"); + + target.blur(); + isnot(browser2.contentDocument.activeElement, target, + "The target element shouldn't be activeElement"); + + // Swap the content in browser1 for the content in browser2. + const browser1 = window1.document.querySelector("browser"); + browser1.swapFrameLoaders(browser2); + await new Promise(resolve => setTimeout(resolve, 0)); + + target = browser1.contentDocument.getElementById("button"); + target.focus(); + + // browser1 is in a visibility:hidden element in window1, + // so that Element.focus() shouldn't work. + isnot(browser1.contentDocument.activeElement, target, + "Element.focus() shouldn't work in invisible browser"); + + checkHiddenEmbeddederState(window1, window2, false, true); + + parent = window1.document.getElementById("parent"); + parent.style.visibility = "visible"; + parent.getBoundingClientRect(); + + checkHiddenEmbeddederState(window1, window2, true, true); + + target.focus(); + + // Now browser1 is in a visibility:visible element, so that + // Element.focus() should just work. + is(browser1.contentDocument.activeElement, target, + "Element.focus() should work in visible browser"); + + window1.close(); + window2.close(); +}); + +// Tests that ancestor's visibility change doesn't clobber child +// iframe's visibility if the child iframe is hidden by an +// element in the ancestor document. +add_task(async () => { + const tabReady = new Promise(resolve => { + window.addEventListener("message", event => { + if (event.data == "ready") { + resolve(); + } + }, { once: true }); + }); + const tabWindow = + window.open(baseURL + "window_css_visibility_propagation-3.html"); + await tabReady; + + const childIFrame = tabWindow.document.querySelector("iframe"); + + const grandChildBrowser = + childIFrame.contentDocument.querySelector("browser"); + let target = grandChildBrowser.contentDocument.getElementById("button"); + target.focus(); + + ok(!tabWindow.browsingContext.isUnderHiddenEmbedderElement, "tab window is visible"); + ok(!childIFrame.browsingContext.isUnderHiddenEmbedderElement, "iframe is visible"); + ok(!grandChildBrowser.browsingContext.isUnderHiddenEmbedderElement, "grandchild is visible"); + + is(grandChildBrowser.contentDocument.activeElement, target, + "Element.focus() should work in visible browser"); + target.blur(); + + // Hide the parent element of the grand child browser. + let parent = childIFrame.contentDocument.getElementById("parent"); + parent.style.visibility = "hidden"; + parent.getBoundingClientRect(); + + ok(!tabWindow.browsingContext.isUnderHiddenEmbedderElement, "tab window is visible"); + ok(!childIFrame.browsingContext.isUnderHiddenEmbedderElement, "iframe is visible"); + ok(grandChildBrowser.browsingContext.isUnderHiddenEmbedderElement, "grandchild is not visible"); + + target.focus(); + + isnot(grandChildBrowser.contentDocument.activeElement, target, + "Element.focus() shouldn't work in invisible browser"); + + // Hide the parent element of the child iframe. + parent = tabWindow.document.getElementById("parent"); + parent.style.visibility = "hidden"; + parent.getBoundingClientRect(); + + target.focus(); + + ok(!tabWindow.browsingContext.isUnderHiddenEmbedderElement, "tab window is visible"); + ok(childIFrame.browsingContext.isUnderHiddenEmbedderElement, "iframe is not visible"); + ok(grandChildBrowser.browsingContext.isUnderHiddenEmbedderElement, "grandchild is not visible"); + + isnot(grandChildBrowser.contentDocument.activeElement, target, + "Element.focus() shouldn't work in invisible iframe"); + + // Make the parent element of the child iframe visible. + parent.style.visibility = "visible"; + parent.getBoundingClientRect(); + + ok(!tabWindow.browsingContext.isUnderHiddenEmbedderElement, "tab window is visible"); + ok(!childIFrame.browsingContext.isUnderHiddenEmbedderElement, "iframe is visible"); + ok(grandChildBrowser.browsingContext.isUnderHiddenEmbedderElement, "grandchild is not visible"); + + target.focus(); + + // Even if the child iframe is visible, but still the grand child is + // hidden by the parent element of the grand child browser so that + // we can't focus to the element in the grand child browser. + isnot(grandChildBrowser.contentDocument.activeElement, target, + "Element.focus() shouldn't work in invisible browser"); + + tabWindow.close(); +}); + +// Tests that an iframe is initially hidden by a visibility:hidden element in +// the parent document. +add_task(async () => { + const tabReady = new Promise(resolve => { + window.addEventListener("message", event => { + if (event.data == "ready") { + resolve(); + } + }, { once: true }); + }); + const tabWindow = + window.open(baseURL + "window_css_visibility_propagation-4.html"); + await tabReady; + + const iframe = tabWindow.document.querySelector("iframe"); + let target = iframe.contentDocument.getElementById("button"); + target.focus(); + + ok(!tabWindow.browsingContext.isUnderHiddenEmbedderElement, "tab window is visible"); + ok(iframe.browsingContext.isUnderHiddenEmbedderElement, "iframe is not visible"); + + isnot(iframe.contentDocument.activeElement, target, + "Element.focus() shouldn't work in invisible iframe"); + + tabWindow.close(); +}); +]]> +</script> +</window> diff --git a/layout/base/tests/chrome/test_default_background.xhtml b/layout/base/tests/chrome/test_default_background.xhtml new file mode 100644 index 0000000000..26e28c574e --- /dev/null +++ b/layout/base/tests/chrome/test_default_background.xhtml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + SimpleTest.waitForExplicitFinish(); + // Run the test in a separate window so that the test runs as a chrome + // window + window.openDialog("default_background_window.xhtml", "default_background", + "chrome,width=200,height=300,noopener", window); + ]]> + </script> +</window> diff --git a/layout/base/tests/chrome/test_dialog_with_positioning.html b/layout/base/tests/chrome/test_dialog_with_positioning.html new file mode 100644 index 0000000000..db08a3d9b4 --- /dev/null +++ b/layout/base/tests/chrome/test_dialog_with_positioning.html @@ -0,0 +1,20 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test positioning of fixed-pos/abs-pos elements in a XUL dialog</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/chrome-harness.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> +</head> +<body> +<pre id="test"> +<script type="application/javascript"> +SimpleTest.waitForExplicitFinish(); + +var root = getRootDirectory(window.location.href); +window.openDialog(root + "dialog_with_positioning_window.xhtml", "dialog_with_positioning", + "dialog,chrome,noopener", window); +</script> +</pre> +</body> +</html> diff --git a/layout/base/tests/chrome/test_document_adopted_styles.html b/layout/base/tests/chrome/test_document_adopted_styles.html new file mode 100644 index 0000000000..f2784bd60b --- /dev/null +++ b/layout/base/tests/chrome/test_document_adopted_styles.html @@ -0,0 +1,8 @@ +<!doctype html> +<meta charset="utf-8"> +<div class="target"></div> +<script> + const sheet = new CSSStyleSheet(); + document.adoptedStyleSheets = [sheet]; + sheet.replaceSync(".target { width: 100px; height: 100px; border-style: solid; border-color: blue; }"); +</script> diff --git a/layout/base/tests/chrome/test_document_adopted_styles_ref.html b/layout/base/tests/chrome/test_document_adopted_styles_ref.html new file mode 100644 index 0000000000..0b592207f3 --- /dev/null +++ b/layout/base/tests/chrome/test_document_adopted_styles_ref.html @@ -0,0 +1,6 @@ +<!doctype html> +<meta charset="utf-8"> +<body> + <div class="target"></div> + <style> .target { width: 100px; height: 100px; border-style: solid; border-color: blue; } </style> +</body> diff --git a/layout/base/tests/chrome/test_fixed_bg_scrolling_repaints.html b/layout/base/tests/chrome/test_fixed_bg_scrolling_repaints.html new file mode 100644 index 0000000000..9543340d6b --- /dev/null +++ b/layout/base/tests/chrome/test_fixed_bg_scrolling_repaints.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test that we don't get unnecessary repaints with fixed backgrounds</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/paint_listener.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> +</head> +<!-- Need a timeout here to allow paint unsuppression before we start the test --> +<body onload="setTimeout(startTest,0)" style="background:url(blue-32x32.png) top left no-repeat fixed; background-size: 100px 2000px; overflow:hidden;"> +<div style="height: 2048px"></div> + +<pre id="test"> +<script type="application/javascript"> +SimpleTest.waitForExplicitFinish(); + +var utils = window.windowUtils; + +function startTest() { + // Do a scroll to ensure we trigger activity heuristics. + document.documentElement.scrollTop = 1; + waitForAllPaintsFlushed(function () { + document.documentElement.scrollTop = 0; + waitForAllPaintsFlushed(function () { + // Clear paint state and scroll down + utils.checkAndClearPaintedState(document.documentElement); + document.documentElement.scrollTop = 100; + waitForAllPaintsFlushed(function () { + // Make sure nothing painted + var painted = utils.checkAndClearPaintedState(document.documentElement); + is(painted, false, "Fixed background should not have been painted when scrolled"); + SimpleTest.finish(); + }); + }); + }); +} +</script> +</pre> +</body> +</html> diff --git a/layout/base/tests/chrome/test_getClientRectsAndTexts.html b/layout/base/tests/chrome/test_getClientRectsAndTexts.html new file mode 100644 index 0000000000..d2fdde2197 --- /dev/null +++ b/layout/base/tests/chrome/test_getClientRectsAndTexts.html @@ -0,0 +1,80 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> +</head> +<body> + +<div id="div1" style="width:200px">Here is some text that <a href="#">will wrap</a> in <a href="#">this small</a>-ish container.</div> +<div id="div2">Into another <a href="#">container</a></div> +<div id="div3">A very <span>deep <span>deep <span>deep</span></span></span> bit of text.</div> + +<script> +if (typeof(is) == "undefined") { + var is = function(a, b, m) { + if(a != b) { + window.console.log("Expected '" + b + "' but got '" + a + "': " + m); + } + }; +} + +if (typeof(todo_is) == "undefined") { + var todo_is = is; +} + +function testRangeTexts(startNode, startOffset, endNode, endOffset, expectedText, todo) { + let r = new Range(); + r.setStart(startNode, startOffset); + r.setEnd(endNode, endOffset); + + let texts = r.getClientRectsAndTexts().textList; + let concatText = ""; + for (let i = 0; i < texts.length; i++) { + concatText += texts[i]; + } + + if (todo) { + todo_is(concatText, expectedText, "Text matches."); + } else { + is(concatText, expectedText, "Text matches."); + } +} + +let d1c1 = div1.firstChild; +let d1c2 = d1c1.nextSibling; +let d1c3 = d1c2.nextSibling; +let d1c4 = d1c3.nextSibling; +let d1c5 = d1c4.nextSibling; + +let link1 = d1c2.firstChild; +let link2 = d1c4.firstChild; + +let d2c1 = div2.firstChild; +let d2c2 = d2c1.nextSibling; + +let link3 = d2c2.firstChild; + +let d3c1 = div3.firstChild; +let d3c2 = d3c1.nextSibling; +let d3c3 = d3c2.nextSibling; + +let data = [ + [d1c1, 0, d1c1, 0, ""], + [d1c1, 0, d1c1, 4, "Here"], + [d1c1, 4, d1c1, 7, " is"], + [d1c1, 22, link1, 0, " "], + [d1c1, 22, link1, 1, " w"], + [d1c1, 22, d1c3, 1, " will wrap "], + [link1, 2, link2, 3, "ll wrap in thi"], + [link2, 5, link3, 3, "small-ish container.Into another con"], + [d3c1, 3, d3c3, 4, "ery deep deep deep bit"], +]; + +data.forEach(function (d) { testRangeTexts.apply(null, d); }); + +</script> + +</body> +</html> diff --git a/layout/base/tests/chrome/test_get_printer_basic_attributes.html b/layout/base/tests/chrome/test_get_printer_basic_attributes.html new file mode 100644 index 0000000000..26a04e09d5 --- /dev/null +++ b/layout/base/tests/chrome/test_get_printer_basic_attributes.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<head> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +</head> +<body onload="run()"> +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +async function run() { + try { + let printerList = Cc["@mozilla.org/gfx/printerlist;1"].getService( + Ci.nsIPrinterList + ); + + let printers = await printerList.printers; + for (let printer of printers) { + printer.QueryInterface(Ci.nsIPrinter); + info(`Listing basic attributes for ${printer.name}:`); + let [supportsDuplex, supportsColor] = await Promise.all([printer.supportsDuplex, printer.supportsColor]); + info(`* supportsDuplex: ${supportsDuplex}`); + info(`* supportsColor: ${supportsColor}`); + } + + ok(true, "Retrieved printer basic attributes successfully."); + } catch (e) { + ok(false, `Error thrown while retrieving printer basic attributes: ${e}.`); + console.error(e); + } + SimpleTest.finish(); +} + +</script> +</body> +</html> diff --git a/layout/base/tests/chrome/test_get_printer_orientation.html b/layout/base/tests/chrome/test_get_printer_orientation.html new file mode 100644 index 0000000000..1bb50eef65 --- /dev/null +++ b/layout/base/tests/chrome/test_get_printer_orientation.html @@ -0,0 +1,50 @@ +<!DOCTYPE HTML> +<html> +<head> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +</head> +<body onload="run()"> +<script> + +SimpleTest.waitForExplicitFinish(); + +async function run() { + try { + let printerList = Cc["@mozilla.org/gfx/printerlist;1"].getService( + Ci.nsIPrinterList + ); + var settingsSvc = Cc["@mozilla.org/gfx/printsettings-service;1"].getService( + Ci.nsIPrintSettingsService + ); + + let printers = await printerList.printers; + for (let printer of printers) { + printer.QueryInterface(Ci.nsIPrinter); + let printerInfo = await printer.printerInfo; + + // Look up the printer's defaultSettings: + let defaultSettings = printerInfo.defaultSettings; + + // Let the printer impose its defaults onto a fresh settings object: + let freshSettings = settingsSvc.createNewPrintSettings(); + printerList.initPrintSettingsFromPrinter(printer.name, freshSettings); + + // Make sure they agree on the default orientation: + is(freshSettings.orientation, defaultSettings.orientation, + "initPrintSettingsFromPrinter should produce the same orientation " + + "as the printer's defaultSettings"); + } + + // This ok() just lets us avoid failure-due-to-no-tests-being-run, on + // devices that have no printers available & hence skip the loop above: + ok(true, "Finished traversing printers."); + } catch (e) { + ok(false, `Error thrown while retrieving printer info: ${e}.`); + console.error(e); + } + SimpleTest.finish(); +} + +</script> +</body> +</html> diff --git a/layout/base/tests/chrome/test_get_printer_paper_sizes.html b/layout/base/tests/chrome/test_get_printer_paper_sizes.html new file mode 100644 index 0000000000..4ebe462ac6 --- /dev/null +++ b/layout/base/tests/chrome/test_get_printer_paper_sizes.html @@ -0,0 +1,69 @@ +<!DOCTYPE HTML> +<html> +<head> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +</head> +<body onload="run()"> +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +async function run() { + try { + let printerList = Cc["@mozilla.org/gfx/printerlist;1"].getService( + Ci.nsIPrinterList + ); + let printers = await printerList.printers; + if (printers.length == 0) { + ok(true, "There were no printers to iterate through."); + } + + for (let printer of printers) { + printer.QueryInterface(Ci.nsIPrinter); + is(typeof(printer.name), 'string', "Printer name should be a string."); + isnot(printer.name, "", "Printer name should never be empty."); + + info(printer.name); + info("duplex(" + printer.supportsDuplex + ")"); + + let printerInfo = await printer.printerInfo; + for (let paper of printerInfo.paperList) { + paper.QueryInterface(Ci.nsIPaper); + + info(`${paper.name}: ${paper.width}x${paper.height}`); + + is(typeof(paper.name), 'string', "Paper name should be a string."); + isnot(paper.name, "", "Paper name should never be empty."); + + is(typeof(paper.width), 'number', "Paper width should be a number."); + ok(paper.width > 0.0, "Paper width should be greater than zero."); + + is(typeof(paper.height), 'number', "Paper height should be a number."); + ok(paper.height > 0.0, "Paper height should be greater than zero."); + + let margin = await paper.unwriteableMargin; + margin.QueryInterface(Ci.nsIPaperMargin); + + info(`with margin: ${margin.top} ${margin.right} ${margin.bottom} ${margin.left}`); + + is(typeof(margin.top), 'number', "Paper unwriteable margin top should be a number."); + is(typeof(margin.right), 'number', "Paper unwriteable margin right should be a number."); + is(typeof(margin.bottom), 'number', "Paper unwriteable margin bottom should be a number."); + is(typeof(margin.left), 'number', "Paper unwriteable margin left should be a number."); + + ok(margin.top >= 0.0, "Paper unwriteable margin top should be greater than or equal to zero."); + ok(margin.right >= 0.0, "Paper unwriteable margin right should be greater than or equal to zero."); + ok(margin.bottom >= 0.0, "Paper unwriteable bottom right should be greater than or equal to zero."); + ok(margin.left >= 0.0, "Paper unwriteable margin left should be greater than or equal to zero."); + } + } + } catch (e) { + ok(false, `Shouldn't throw: ${e}`); + console.error(e); + } + SimpleTest.finish(); +} + +</script> +</body> +</html> diff --git a/layout/base/tests/chrome/test_prerendered_transforms.html b/layout/base/tests/chrome/test_prerendered_transforms.html new file mode 100644 index 0000000000..3151d32413 --- /dev/null +++ b/layout/base/tests/chrome/test_prerendered_transforms.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test that active transformed elements coming into view are prerendered so we don't have to redraw constantly</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="chrome://mochikit/content/tests/SimpleTest/paint_listener.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+</head>
+<body onload="startTest()">
+<div>
+<div id="t" style="position:absolute; left:0; top:500px; -moz-transform: translatex(-100px); width:200px; height:100px; background:yellow;">
+ <div style="text-align:right">Hello</div>
+ <div style="text-align:left">Kitty</div>
+</div>
+</div>
+<pre id="test">
+<script type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+
+var t = document.getElementById("t");
+var utils = window.windowUtils;
+
+function startTest() {
+ // Do a couple of transform changes to ensure we've triggered activity heuristics
+ waitForAllPaintsFlushed(function () {
+ t.style.MozTransform = "translatex(-75px)";
+ waitForAllPaintsFlushed(function () {
+ t.style.MozTransform = "translatex(-50px)";
+ waitForAllPaintsFlushed(function () {
+ // Clear paint state now and move again.
+ utils.checkAndClearPaintedState(t);
+ // Don't move to 0 since that might trigger some special case that turns off transforms.
+ t.style.MozTransform = "translatex(-1px)";
+ waitForAllPaintsFlushed(function () {
+ var painted = utils.checkAndClearPaintedState(t);
+ is(painted, false, "Transformed element should not have been painted");
+ SimpleTest.finish();
+ });
+ });
+ });
+ });
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/base/tests/chrome/test_printer_default_settings.html b/layout/base/tests/chrome/test_printer_default_settings.html new file mode 100644 index 0000000000..8fb6f98a4e --- /dev/null +++ b/layout/base/tests/chrome/test_printer_default_settings.html @@ -0,0 +1,63 @@ +<!DOCTYPE HTML> +<html> +<head> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +</head> +<body onload="run()"> +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +async function run() { + try { + let printerList = Cc["@mozilla.org/gfx/printerlist;1"].getService( + Ci.nsIPrinterList + ); + let printers = await printerList.printers; + if (printers.length == 0) { + ok(true, "There were no printers to iterate through."); + } + + for (let printer of printers) { + printer.QueryInterface(Ci.nsIPrinter); + info(printer.name); + info("duplex(" + await printer.supportsDuplex + ")"); + + const printerInfo = await printer.printerInfo; + const settings = printerInfo.defaultSettings; + settings.QueryInterface(Ci.nsIPrintSettings); + + is(typeof settings.printerName, "string", "Printer name should be a string."); + is(settings.printerName, printer.name, "Print settings' printer should match the printer that created them."); + + is(typeof settings.paperId, "string", "Paper ID should never be null."); + is(typeof settings.paperWidth, "number", "Paper width should never be null."); + is(typeof settings.paperHeight, "number", "Paper height should never be null."); + + if (settings.paperId != "") { + info(`Paper: ${settings.paperId}`); + info(`Size: (${settings.paperWidth} x ${settings.paperHeight})`); + ok(settings.paperWidth > 0.0, "Paper width should be greater than zero."); + ok(settings.paperHeight > 0.0, "Paper height should be greater than zero."); + } + + ok(settings.marginTop >= 0.0, "Paper margins should be greater than or equal to zero."); + ok(settings.marginRight >= 0.0, "Paper margins should be greater than or equal to zero."); + ok(settings.marginBottom >= 0.0, "Paper margins should be greater than or equal to zero."); + ok(settings.marginLeft >= 0.0, "Paper margins should be greater than or equal to zero."); + + is(settings.printInColor, await printer.supportsColor, "Print settings' color mode should match the printer's color support."); + + ok(settings.isInitializedFromPrinter, "Print settings were initialized from printer"); + ok(!settings.isInitializedFromPrefs); + } + } catch (e) { + ok(false, `Shouldn't throw: ${e}`); + console.error(e); + } + SimpleTest.finish(); +} + +</script> +</body> +</html> diff --git a/layout/base/tests/chrome/test_printpreview.xhtml b/layout/base/tests/chrome/test_printpreview.xhtml new file mode 100644 index 0000000000..c63d7a62d1 --- /dev/null +++ b/layout/base/tests/chrome/test_printpreview.xhtml @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<body xmlns="http://www.w3.org/1999/xhtml"> +</body> + <!-- test code goes here --> +<script type="application/javascript"> +<![CDATA[ +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestLongerTimeout(3); +window.openDialog("printpreview_helper.xhtml", "printpreview", "chrome,width=100,height=100,noopener", window); +]]></script> +</window> diff --git a/layout/base/tests/chrome/test_printpreview_bug396024.xhtml b/layout/base/tests/chrome/test_printpreview_bug396024.xhtml new file mode 100644 index 0000000000..4b839f3b2b --- /dev/null +++ b/layout/base/tests/chrome/test_printpreview_bug396024.xhtml @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=396024 +--> +<window title="Mozilla Bug 369024" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<body xmlns="http://www.w3.org/1999/xhtml"> +<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=396024" + target="_blank">Mozilla Bug 396024</a> +</body> + <!-- test code goes here --> +<script type="application/javascript"> +<![CDATA[ +SimpleTest.waitForExplicitFinish(); +window.openDialog("printpreview_bug396024_helper.xhtml", "bug396024", "chrome,width=100,height=100,noopener", window); +]]></script> +</window> diff --git a/layout/base/tests/chrome/test_printpreview_bug482976.xhtml b/layout/base/tests/chrome/test_printpreview_bug482976.xhtml new file mode 100644 index 0000000000..8dd4c65337 --- /dev/null +++ b/layout/base/tests/chrome/test_printpreview_bug482976.xhtml @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=482976 +--> +<window title="Mozilla Bug 482976" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<body xmlns="http://www.w3.org/1999/xhtml"> +<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=482976" + target="_blank">Mozilla Bug 482976</a> +</body> + <!-- test code goes here --> +<script type="application/javascript"> +<![CDATA[ +SimpleTest.waitForExplicitFinish(); +window.openDialog("printpreview_bug482976_helper.xhtml", "bug482976", "chrome,width=100,height=100,noopener", window); +]]></script> +</window> diff --git a/layout/base/tests/chrome/test_scrolling_repaints.html b/layout/base/tests/chrome/test_scrolling_repaints.html new file mode 100644 index 0000000000..605e598c52 --- /dev/null +++ b/layout/base/tests/chrome/test_scrolling_repaints.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test that we don't get unnecessary repaints due to subpixel shifts</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/paint_listener.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> +</head> +<!-- Need a timeout here to allow paint unsuppression before we start the test --> +<body onload="setTimeout(startTest,0)"> +<div id="t" style="width:400px; height:100px; background:yellow; overflow:hidden"> + <div style="height:40px;"></div> + <div id="e" style="height:30px; background:lime"></div> + <div style="height:60.4px; background:pink"></div> +</div> +<pre id="test"> +<script type="application/javascript"> +SimpleTest.waitForExplicitFinish(); + +var t = document.getElementById("t"); +var e = document.getElementById("e"); +var utils = window.windowUtils; + +function startTest() { + // Do a scroll to ensure we trigger activity heuristics. + waitForAllPaintsFlushed(function () { + t.scrollTop = 5; + // Scroll down as far as we can, to put our rendering layer at a subpixel offset within the layer + waitForAllPaintsFlushed(function () { + t.scrollTop = 1000; + waitForAllPaintsFlushed(function () { + // Clear paint state now and scroll again. + utils.checkAndClearPaintedState(e); + // scroll up a little bit. This should not cause anything to be repainted. + t.scrollTop = t.scrollTop - 10; + waitForAllPaintsFlushed(function () { + var painted = utils.checkAndClearPaintedState(e); + is(painted, false, "Fully-visible scrolled element should not have been painted"); + SimpleTest.finish(); + }); + }); + }); + }); +} +</script> +</pre> +</body> +</html> diff --git a/layout/base/tests/chrome/test_shadow_root_adopted_styles.html b/layout/base/tests/chrome/test_shadow_root_adopted_styles.html new file mode 100644 index 0000000000..d6701f3089 --- /dev/null +++ b/layout/base/tests/chrome/test_shadow_root_adopted_styles.html @@ -0,0 +1,11 @@ +<!doctype html> +<meta charset="utf-8"> +<body> +<script> + document.body.attachShadow({mode: "open"}).innerHTML = ` + <div class="target"></div> + `; + const sheet = new CSSStyleSheet(); + document.body.shadowRoot.adoptedStyleSheets = [sheet]; + sheet.replaceSync(".target { width: 100px; height: 100px; border-style: solid; border-color: blue; }"); +</script> diff --git a/layout/base/tests/chrome/test_shadow_root_adopted_styles_ref.html b/layout/base/tests/chrome/test_shadow_root_adopted_styles_ref.html new file mode 100644 index 0000000000..fae4a54f21 --- /dev/null +++ b/layout/base/tests/chrome/test_shadow_root_adopted_styles_ref.html @@ -0,0 +1,11 @@ +<!doctype html> +<meta charset="utf-8"> +<body> +<script> + document.body.attachShadow({mode: "open"}).innerHTML = ` + <div class="target"></div> + <style> + .target { width: 100px; height: 100px; border-style: solid; border-color: blue; } + </style> + `; +</script> diff --git a/layout/base/tests/chrome/test_shared_adopted_styles.html b/layout/base/tests/chrome/test_shared_adopted_styles.html new file mode 100644 index 0000000000..f5b232bce6 --- /dev/null +++ b/layout/base/tests/chrome/test_shared_adopted_styles.html @@ -0,0 +1,19 @@ +<!doctype html> +<meta charset="utf-8"> +<body> + <div class="target"></div> + <span id="shadowHostA"></span> + <span id="shadowHostB"></span> +</body> +<script> + const sheet = new CSSStyleSheet(); + sheet.replaceSync(".target { width: 100px; height: 100px; border-style: solid; border-color: blue; }"); + + const innerHTMLText = `<div class="target"></div>` + shadowHostA.attachShadow({mode: "open"}).innerHTML = innerHTMLText; + shadowHostB.attachShadow({mode: "open"}).innerHTML = innerHTMLText; + + document.adoptedStyleSheets = [sheet]; + shadowHostA.shadowRoot.adoptedStyleSheets = [sheet]; + shadowHostB.shadowRoot.adoptedStyleSheets = [sheet]; +</script> diff --git a/layout/base/tests/chrome/test_shared_adopted_styles_ref.html b/layout/base/tests/chrome/test_shared_adopted_styles_ref.html new file mode 100644 index 0000000000..b12cb5fd99 --- /dev/null +++ b/layout/base/tests/chrome/test_shared_adopted_styles_ref.html @@ -0,0 +1,16 @@ +<!doctype html> +<meta charset="utf-8"> +<body> + <div class="target"></div> + <span id="shadowHostA"></span> + <span id="shadowHostB"></span> + <style> .target { width: 100px; height: 100px; border-style: solid; border-color: blue; } </style> +</body> +<script> + const innerHTMLText = ` + <div class="target"></div> + <style> .target { width: 100px; height: 100px; border-style: solid; border-color: blue; } </style> + `; + shadowHostA.attachShadow({mode: "open"}).innerHTML = innerHTMLText; + shadowHostB.attachShadow({mode: "open"}).innerHTML = innerHTMLText; +</script> diff --git a/layout/base/tests/chrome/test_will_change.html b/layout/base/tests/chrome/test_will_change.html new file mode 100644 index 0000000000..fd34dc50f6 --- /dev/null +++ b/layout/base/tests/chrome/test_will_change.html @@ -0,0 +1,140 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Tests for MozAfterPaint</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/paint_listener.js"></script> + <style> + div { + width: 100px; + height: 100px; + background: radial-gradient(ellipse at center, #87e0fd 0%,#53cbf1 40%,#05abe0 100%); + } + </style> +</head> +<body> +</body> +<script> + +var utils = window.windowUtils; + +function waitForPaints() { + return new Promise(function(resolve, reject) { + waitForAllPaintsFlushed(resolve); + }); +} + +add_task(async () => { + var element = document.createElement("div"); + document.body.appendChild(element); + + await waitForPaints(); + + utils.checkAndClearPaintedState(element); + element.style.opacity = "0.5"; + + await waitForPaints(); + + var painted = utils.checkAndClearPaintedState(element); + // *** We check that this repaints because the test is relying + // on this property. If this is broken then this test wont + // be reliable check for will-change. + is(painted, true, "element should have been painted"); + + element.remove(); +}); + +add_task(async () => { + var element = document.createElement("div"); + document.body.appendChild(element); + + element.style.willChange = "opacity"; + + await waitForPaints(); + + utils.checkAndClearPaintedState(element); + element.style.opacity = "0.5"; + + await waitForPaints(); + + var painted = utils.checkAndClearPaintedState(element); + // BasicLayers' heuristics are so that even with will-change:opacity, + // we can still have repaints. + if (utils.layerManagerType != "Basic") { + is(painted, false, "will-change:opacity element should not have been painted"); + } + + element.remove(); +}); + +add_task(async () => { + var element = document.createElement("div"); + document.body.appendChild(element); + + element.style.willChange = "transform"; + + await waitForPaints(); + + utils.checkAndClearPaintedState(element); + element.style.transform = "translateY(-5px)"; + + await waitForPaints(); + + var painted = utils.checkAndClearPaintedState(element); + // BasicLayers' heuristics are so that even with will-change:transform, + // we can still have repaints. + if (utils.layerManagerType != "Basic") { + is(painted, false, "will-change:transform element should not have been painted"); + } + + element.remove(); +}); + +add_task(async () => { + var element = document.createElement("div"); + document.body.appendChild(element); + + element.style.willChange = "translate"; + + await waitForPaints(); + + utils.checkAndClearPaintedState(element); + element.style.translate = "5px"; + + await waitForPaints(); + + var painted = utils.checkAndClearPaintedState(element); + // BasicLayers' heuristics are so that even with will-change:translate, + // we can still have repaints. + if (utils.layerManagerType != "Basic") { + is(painted, false, "will-change:translate element should not have been painted"); + } + + element.remove(); +}); + +add_task(async () => { + var element = document.createElement("div"); + document.body.appendChild(element); + + element.style.willChange = "offset-path"; + + await waitForPaints(); + + utils.checkAndClearPaintedState(element); + element.style.offsetPath = "path('M55 50 h1')"; + + await waitForPaints(); + + var painted = utils.checkAndClearPaintedState(element); + // BasicLayers' heuristics are so that even with will-change:offset-path, + // we can still have repaints. + if (utils.layerManagerType != "Basic") { + is(painted, false, "will-change:offset-path element should not have been painted"); + } + + element.remove(); +}); + +</script> +</html> diff --git a/layout/base/tests/chrome/window_css_visibility_propagation-1.xhtml b/layout/base/tests/chrome/window_css_visibility_propagation-1.xhtml new file mode 100644 index 0000000000..ac9c63ec14 --- /dev/null +++ b/layout/base/tests/chrome/window_css_visibility_propagation-1.xhtml @@ -0,0 +1,6 @@ +<?xml version="1.0"?> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> +<div id="parent" style="visibility:hidden"> + <browser type="content" src="about:mozilla"></browser> +</div> +</window> diff --git a/layout/base/tests/chrome/window_css_visibility_propagation-2.xhtml b/layout/base/tests/chrome/window_css_visibility_propagation-2.xhtml new file mode 100644 index 0000000000..9b9e42c2d1 --- /dev/null +++ b/layout/base/tests/chrome/window_css_visibility_propagation-2.xhtml @@ -0,0 +1,6 @@ +<?xml version="1.0"?> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> +<div id="parent"> + <browser type="content" src="frame_css_visibility_propagation.html"></browser> +</div> +</window> diff --git a/layout/base/tests/chrome/window_css_visibility_propagation-3.html b/layout/base/tests/chrome/window_css_visibility_propagation-3.html new file mode 100644 index 0000000000..91a2230ee1 --- /dev/null +++ b/layout/base/tests/chrome/window_css_visibility_propagation-3.html @@ -0,0 +1,3 @@ +<div id="parent"> + <iframe onload="opener.postMessage('ready');" src="window_css_visibility_propagation-2.xhtml"/> +</div> diff --git a/layout/base/tests/chrome/window_css_visibility_propagation-4.html b/layout/base/tests/chrome/window_css_visibility_propagation-4.html new file mode 100644 index 0000000000..98de74059c --- /dev/null +++ b/layout/base/tests/chrome/window_css_visibility_propagation-4.html @@ -0,0 +1,3 @@ +<div id="parent" style="visibility:hidden"> + <iframe onload="opener.postMessage('ready');" src="frame_css_visibility_propagation.html"/> +</div> |