test_value_cloning.html (5621B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=375363 5 --> 6 <head> 7 <title>Test for cloning of CSS property values (including 'inherit', 'initial' and 'unset')</title> 8 <script src="/tests/SimpleTest/SimpleTest.js"></script> 9 <script type="text/javascript" src="property_database.js"></script> 10 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 11 </head> 12 <body> 13 <p id="display"><iframe id="iframe" src="about:blank"></iframe></p> 14 <pre id="test"> 15 <script class="testbody" type="text/javascript"> 16 17 /** Test for cloning of CSS property values (including 'inherit', 'initial' and 'unset') */ 18 var test_queue = []; 19 var iframe = document.getElementById("iframe"); 20 21 SimpleTest.waitForExplicitFinish(); 22 23 for (var prop in gCSSProperties) { 24 let info = gCSSProperties[prop]; 25 26 test_queue.push({ prop: prop, value: "inherit", 27 inherited_value: info.initial_values[0] }); 28 test_queue.push({ prop: prop, value: "inherit", 29 inherited_value: info.other_values[0] }); 30 test_queue.push({ prop: prop, value: "initial" }); 31 if (info.inherited) { 32 test_queue.push({ prop: prop, value: "unset", 33 inherited_value: info.initial_values[0] }); 34 test_queue.push({ prop: prop, value: "unset", 35 inherited_value: info.other_values[0] }); 36 } else { 37 test_queue.push({ prop: prop, value: "unset" }); 38 } 39 for (let idx in info.initial_values) { 40 test_queue.push({ prop: prop, value: info.initial_values[idx] }); 41 } 42 for (let idx in info.other_values) { 43 test_queue.push({ prop: prop, value: info.other_values[idx] }); 44 } 45 } 46 47 test_queue.reverse(); 48 49 doTest(); 50 51 function doTest() 52 { 53 var sheet_data = ""; 54 55 for (let idx = 0; idx < test_queue.length; ++idx) { 56 var current_item = test_queue[idx]; 57 58 let info = gCSSProperties[current_item.prop]; 59 60 sheet_data += "#parent"+idx+", #test"+idx+" { "; 61 for (var prereq in info.prereqs) { 62 sheet_data += prereq + ": " + info.prereqs[prereq] + ";"; 63 } 64 sheet_data += " }"; 65 66 sheet_data += "#parent"+idx+" { "; 67 if ("inherited_value" in current_item) { 68 sheet_data += current_item.prop + ": " + current_item.inherited_value; 69 } 70 sheet_data += "}"; 71 72 sheet_data += "#test"+idx+" { "; 73 sheet_data += current_item.prop + ": " + current_item.value; 74 sheet_data += "}"; 75 } 76 77 var sheet_url = "data:text/css," + escape(sheet_data); 78 79 var doc_data = 80 "<!DOCTYPE HTML>\n" + 81 "<link rel='stylesheet' type='text/css' href='" + sheet_url + "'>\n" + 82 "<link rel='stylesheet' type='text/css' href='" + sheet_url + "'>\n" + 83 "<body>\n"; 84 85 86 for (let idx = 0; idx < test_queue.length; ++idx) { 87 var current_item = test_queue[idx]; 88 89 if ("inherited_value" in current_item) { 90 doc_data += "<span id='parent"+idx+"'>"; 91 } 92 doc_data += "<span id='test"+idx+"'></span>"; 93 if ("inherited_value" in current_item) { 94 doc_data += "</span>"; 95 } 96 } 97 98 var doc_url = "data:text/html," + escape(doc_data); 99 iframe.onload = iframe_loaded; 100 iframe.src = doc_url; 101 } 102 103 function iframe_loaded(event) 104 { 105 if (event.target != iframe) 106 return; 107 108 var start_ser = []; 109 var start_compute = []; 110 var test_cs = []; 111 var wrappedFrame = SpecialPowers.wrap(iframe); 112 var ifdoc = wrappedFrame.contentDocument; 113 var ifwin = wrappedFrame.contentWindow; 114 115 for (let idx = 0; idx < test_queue.length; ++idx) { 116 var current_item = test_queue[idx]; 117 var info = gCSSProperties[current_item.prop]; 118 119 var test = ifdoc.getElementById("test" + idx); 120 var cur_cs = ifwin.getComputedStyle(test); 121 test_cs.push(cur_cs); 122 var cur_ser = ifdoc.styleSheets[0].cssRules[3*idx+2].style.getPropertyValue(current_item.prop); 123 if (cur_ser == "") { 124 isnot(cur_ser, "", 125 "serialization should be nonempty for " + 126 current_item.prop + ": " + current_item.value); 127 } 128 start_ser.push(cur_ser); 129 130 var cur_compute = get_computed_value(cur_cs, current_item.prop); 131 if (cur_compute == "") { 132 isnot(cur_compute, "", 133 "computed value should be nonempty for " + 134 current_item.prop + ": " + current_item.value); 135 } 136 start_compute.push(cur_compute); 137 } 138 139 // In case the above access didn't force a clone already (though it 140 // currently does), clone the second style sheet's inner and then 141 // remove the first. 142 ifdoc.styleSheets[1].insertRule("#nonexistent { color: red }", 0); 143 var firstlink = ifdoc.getElementsByTagName("link")[0]; 144 firstlink.remove(); 145 146 // Force a flush 147 ifdoc.body.style.display="none"; 148 var ow = ifdoc.body.offsetWidth; 149 ifdoc.body.style.display=""; 150 151 for (let idx = 0; idx < test_queue.length; ++idx) { 152 var current_item = test_queue[idx]; 153 var info = gCSSProperties[current_item.prop]; 154 155 var end_ser = 156 ifdoc.styleSheets[0].cssRules[3*idx+3].style.getPropertyValue(current_item.prop); 157 is(end_ser, start_ser[idx], 158 "serialization should match when cloning " + 159 current_item.prop + ": " + current_item.value); 160 161 var end_compute = get_computed_value(test_cs[idx], current_item.prop); 162 // Output computed values only when the test failed. 163 // Computed values may be very long. 164 if (end_compute == start_compute[idx]) { 165 ok(true, 166 "computed values should match when cloning " + 167 current_item.prop + ": " + current_item.value); 168 } else { 169 is(end_compute, start_compute[idx], 170 "computed values should match when cloning " + 171 current_item.prop + ": " + current_item.value); 172 } 173 } 174 175 SimpleTest.finish(); 176 } 177 178 </script> 179 </pre> 180 </body> 181 </html>