test_pseudoelement_state.html (10130B)
1 <!DOCTYPE html> 2 <title>Test for Bug 922669</title> 3 <script src="/tests/SimpleTest/SimpleTest.js"></script> 4 <script src="/tests/SimpleTest/EventUtils.js"></script> 5 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"> 6 7 <iframe srcdoc="<!DOCTYPE html><style></style><div></div>"></iframe> 8 9 <script> 10 var gIsAndroid = navigator.appVersion.includes("Android"); 11 12 var gTests = [ 13 // Interact with the ::-moz-progress-bar. 14 { markup: '<progress value="75" max="100"></progress>', 15 pseudoelement: '::-moz-progress-bar', 16 common_style: 'progress { -moz-appearance: none; } progress::-moz-progress-bar { background: black; }', 17 hover_test_style: 'progress::-moz-progress-bar:hover { background: green; }', 18 hover_reference_style: 'progress::-moz-progress-bar { background: green; }', 19 active_test_style: 'progress::-moz-progress-bar:active { background: lime; }', 20 active_reference_style: 'progress::-moz-progress-bar { background: lime; }' }, 21 22 // Interact with the part of the <progress> not covered by the ::-moz-progress-bar. 23 { markup: '<progress value="25" max="100"></progress>', 24 pseudoelement: '::-moz-progress-bar', 25 common_style: 'progress { -moz-appearance: none; } progress::-moz-progress-bar { background: black; }', 26 hover_test_style: 'progress::-moz-progress-bar { background: green; } progress::-moz-progress-bar:hover { background: red; }', 27 hover_reference_style: 'progress::-moz-progress-bar { background: green; }', 28 active_test_style: 'progress::-moz-progress-bar { background: lime; } progress::-moz-progress-bar:active { background: red; }', 29 active_reference_style: 'progress::-moz-progress-bar { background: lime; }' }, 30 31 // Interact with the ::-moz-range-thumb. 32 { markup: '<input type="range" value="50" min="0" max="100">', 33 pseudoelement: '::-moz-range-thumb', 34 common_style: 'input { -moz-appearance: none; } input::-moz-range-thumb { background: black; }', 35 hover_test_style: 'input::-moz-range-thumb:hover { background: green; }', 36 hover_reference_style: 'input::-moz-range-thumb { background: green; }', 37 active_test_style: 'input::-moz-range-thumb:active { background: lime; }', 38 active_reference_style: 'input::-moz-range-thumb { background: lime; }' }, 39 40 // Interact with the part of the <input type="range"> not covered by the ::-moz-range-thumb. 41 { markup: '<input type="range" value="25" min="0" max="100">', 42 pseudoelement: '::-moz-range-thumb', 43 common_style: 'input { -moz-appearance: none; } input::-moz-range-thumb { background: black; }', 44 hover_test_style: 'input::-moz-range-thumb { background: green; } input::-moz-range-thumb:hover { background: red; }', 45 hover_reference_style: 'input::-moz-range-thumb { background: green; }', 46 active_test_style: 'input::-moz-range-thumb { background: lime; } input::-moz-range-thumb:active { background: red; }', 47 active_reference_style: 'input::-moz-range-thumb { background: lime; }' }, 48 49 // Interact with the ::-moz-meter-bar. 50 { markup: '<meter value="75" min="0" max="100"></meter>', 51 pseudoelement: '::-moz-meter-bar', 52 common_style: 'meter { -moz-appearance: none; } meter::-moz-meter-bar { background: black; }', 53 hover_test_style: 'meter::-moz-meter-bar:hover { background: green; }', 54 hover_reference_style: 'meter::-moz-meter-bar { background: green; }', 55 active_test_style: 'meter::-moz-meter-bar:active { background: lime; }', 56 active_reference_style: 'meter::-moz-meter-bar { background: lime; }' }, 57 58 // Interact with the part of the <meter> not covered by the ::-moz-meter-bar. 59 { markup: '<meter value="25" min="0" max="100"></meter>', 60 pseudoelement: '::-moz-meter-bar', 61 common_style: 'meter { -moz-appearance: none; } meter::-moz-meter-bar { background: black; }', 62 hover_test_style: 'meter::-moz-meter-bar { background: green; } meter::-moz-meter-bar:hover { background: red; }', 63 hover_reference_style: 'meter::-moz-meter-bar { background: green; }', 64 active_test_style: 'meter::-moz-meter-bar { background: lime; } meter::-moz-meter-bar:active { background: red; }', 65 active_reference_style: 'meter::-moz-meter-bar { background: lime; }' }, 66 67 // Do the same as the "Interact with the ::-moz-range-thumb" subtest above, 68 // but with selectors that include descendant operators. 69 { markup: '<input type="range" value="50" min="0" max="100">', 70 pseudoelement: '::-moz-range-thumb', 71 common_style: 'body input { -moz-appearance: none; } input::-moz-range-thumb { background: black; }', 72 hover_test_style: 'body input::-moz-range-thumb:hover { background: green; }', 73 hover_reference_style: 'body input::-moz-range-thumb { background: green; }', 74 active_test_style: 'body input::-moz-range-thumb:active { background: lime; }', 75 active_reference_style: 'body input::-moz-range-thumb { background: lime; }' }, 76 77 // Do the same as above, but using :is instead. 78 { markup: '<input type="range" value="50" min="0" max="100">', 79 pseudoelement: '::-moz-range-thumb', 80 common_style: 'body input { -moz-appearance: none; } input::-moz-range-thumb { background: black; }', 81 hover_test_style: 'body input::-moz-range-thumb:is(:hover) { background: green; }', 82 hover_reference_style: 'body input::-moz-range-thumb { background: green; }', 83 active_test_style: 'body input::-moz-range-thumb:is(:active) { background: lime; }', 84 active_reference_style: 'body input::-moz-range-thumb { background: lime; }' }, 85 86 // Do the same as above, but using :not instead. 87 { markup: '<input type="range" value="50" min="0" max="100">', 88 pseudoelement: '::-moz-range-thumb', 89 common_style: 'input { -moz-appearance: none; } input::-moz-range-thumb { background: green } input::-moz-range-thumb:not(:hover) { background: black; }', 90 hover_test_style: '', 91 hover_reference_style: 'input::-moz-range-thumb { background: green !important; }', 92 active_test_style: 'input::-moz-range-thumb:active { background: lime !important; }', 93 active_reference_style: 'input::-moz-range-thumb { background: lime !important; }' }, 94 95 // ::placeholder can't be tested, since the UA style sheet sets it to 96 // be pointer-events:none. 97 ]; 98 99 function countPixelDifferences(aCanvas1, aCanvas2) { 100 var ctx1 = aCanvas1.getContext("2d"); 101 var ctx2 = aCanvas2.getContext("2d"); 102 var data1 = ctx1.getImageData(0, 0, aCanvas1.width, aCanvas1.height); 103 var data2 = ctx2.getImageData(0, 0, aCanvas2.width, aCanvas2.height); 104 var n = 0; 105 for (var i = 0; i < data1.width * data2.height * 4; i += 4) { 106 if (data1.data[i] != data2.data[i] || 107 data1.data[i + 1] != data2.data[i + 1] || 108 data1.data[i + 2] != data2.data[i + 2] || 109 data1.data[i + 3] != data2.data[i + 3]) { 110 n++; 111 } 112 } 113 return n; 114 } 115 116 function runTests() { 117 var iframe = document.querySelector("iframe"); 118 var style = iframe.contentDocument.querySelector("style"); 119 var div = iframe.contentDocument.querySelector("div"); 120 var canvas1, canvas2; 121 122 function runTestPart1(aIndex) { 123 var test = gTests[aIndex]; 124 div.innerHTML = test.markup; 125 style.textContent = test.common_style; 126 is(getComputedStyle(div.firstChild, test.pseudoelement).backgroundColor, "rgb(0, 0, 0)", "subtest #" + aIndex + ", computed style"); 127 style.textContent += test.hover_test_style; 128 synthesizeMouseAtCenter(div.lastChild, { type: 'mouseover' }, iframe.contentWindow); 129 } 130 131 function runTestPart2(aIndex) { 132 var test = gTests[aIndex]; 133 canvas1 = SpecialPowers.snapshotWindow(iframe.contentWindow, false); 134 style.textContent = test.common_style + test.hover_reference_style; 135 } 136 137 function runTestPart3(aIndex) { 138 var test = gTests[aIndex]; 139 canvas2 = SpecialPowers.snapshotWindow(iframe.contentWindow, false); 140 ok(canvas1.width == canvas2.width && canvas1.height == canvas2.height, "hover subtest #" + aIndex + ", canvas sizes equal"); 141 is(countPixelDifferences(canvas1, canvas2), 0, "hover subtest #" + aIndex + ", number of different pixels"); 142 is(getComputedStyle(div.firstChild, test.pseudoelement).backgroundColor, "rgb(0, 128, 0)", "hover subtest #" + aIndex + ", computed style"); 143 144 if (!gIsAndroid) { 145 style.textContent = test.common_style + test.active_test_style; 146 synthesizeMouseAtCenter(div.lastChild, { type: 'mousedown' }, iframe.contentWindow); 147 } 148 } 149 150 function runTestPart4(aIndex) { 151 if (!gIsAndroid) { 152 var test = gTests[aIndex]; 153 canvas1 = SpecialPowers.snapshotWindow(iframe.contentWindow, false); 154 synthesizeMouseAtCenter(div.lastChild, { type: 'mouseup' }, iframe.contentWindow); 155 style.textContent = test.common_style + test.active_reference_style; 156 } 157 } 158 159 function runTestPart5(aIndex) { 160 if (!gIsAndroid) { 161 var test = gTests[aIndex]; 162 canvas2 = SpecialPowers.snapshotWindow(iframe.contentWindow, false); 163 ok(canvas1.width == canvas2.width && canvas1.height == canvas2.height, "active subtest #" + aIndex + ", canvas sizes equal"); 164 is(countPixelDifferences(canvas1, canvas2), 0, "active subtest #" + aIndex + ", number of different pixels"); 165 is(getComputedStyle(div.firstChild, test.pseudoelement).backgroundColor, "rgb(0, 255, 0)", "active subtest #" + aIndex + ", computed style"); 166 } 167 } 168 169 for (var i = 0; i < gTests.length; i++) { 170 setTimeout(runTestPart1, 0, i); 171 setTimeout(runTestPart2, 0, i); 172 setTimeout(runTestPart3, 0, i); 173 setTimeout(runTestPart4, 0, i); 174 setTimeout(runTestPart5, 0, i); 175 } 176 setTimeout(function() { SimpleTest.finish(); }, 0); 177 } 178 179 SimpleTest.waitForExplicitFinish(); 180 window.addEventListener("load", async function() { 181 await SpecialPowers.contentTransformsReceived(window); 182 runTests(); 183 }); 184 </script>