| OLD | NEW |
| (Empty) |
| 1 <!DOCTYPE html> | |
| 2 <html> | |
| 3 <head> | |
| 4 <title>Testing Widows and Orphans</title> | |
| 5 <style> | |
| 6 body.hide-containers .container { | |
| 7 display: none; | |
| 8 } | |
| 9 | |
| 10 .container { | |
| 11 width: 600px; | |
| 12 height: 200px; | |
| 13 -webkit-columns: 3; | |
| 14 columns: 3; | |
| 15 column-fill: auto; | |
| 16 line-height: 20px; /* 10 lines per page */ | |
| 17 font-size: 16px; | |
| 18 margin: 0 0 20px 0; | |
| 19 padding: 0; | |
| 20 overflow: hidden; | |
| 21 } | |
| 22 | |
| 23 .block { | |
| 24 margin: 0 0 15px 0; | |
| 25 padding: 0; | |
| 26 } | |
| 27 | |
| 28 .top { | |
| 29 color: red; | |
| 30 } | |
| 31 | |
| 32 .bottom { | |
| 33 color: green; | |
| 34 } | |
| 35 </style> | |
| 36 <script> | |
| 37 var results; | |
| 38 | |
| 39 function createTestContainer(id, description, blocks) | |
| 40 { | |
| 41 var label = document.createElement("h3"); | |
| 42 label.textContent = id + " - " + description; | |
| 43 document.body.appendChild(label); | |
| 44 var element = document.createElement("div"); | |
| 45 element.className = "container"; | |
| 46 element.id = id; | |
| 47 | |
| 48 for (var i = 1; i <= blocks.length; i++) { | |
| 49 var block = document.createElement("div"); | |
| 50 block.className = "block"; | |
| 51 var numLines = blocks[i-1]; | |
| 52 for (var j = 1; j <= numLines; j++) { | |
| 53 var line = document.createElement("span"); | |
| 54 line.id = id + "-block-" + i + "-line-" + j; | |
| 55 line.textContent = "Block " + i + " Line " + j; | |
| 56 block.appendChild(line); | |
| 57 block.appendChild(document.createElement("br")); | |
| 58 } | |
| 59 element.appendChild(block); | |
| 60 } | |
| 61 document.body.appendChild(element); | |
| 62 return element; | |
| 63 } | |
| 64 | |
| 65 function markTopLine(containerId, blockNumber, lineNumber) | |
| 66 { | |
| 67 var element = document.getElementById(containerId + "-block-" + blockNumber
+ "-line-" + lineNumber); | |
| 68 element.className = "top"; | |
| 69 } | |
| 70 | |
| 71 function markBottomLine(containerId, blockNumber, lineNumber) | |
| 72 { | |
| 73 var element = document.getElementById(containerId + "-block-" + blockNumber
+ "-line-" + lineNumber); | |
| 74 element.className = "bottom"; | |
| 75 } | |
| 76 | |
| 77 function logPass(msg) { | |
| 78 log("PASS: " + msg); | |
| 79 } | |
| 80 | |
| 81 function logFail(msg) { | |
| 82 log("FAIL: " + msg); | |
| 83 } | |
| 84 | |
| 85 function log(msg) { | |
| 86 if (!results) | |
| 87 results = document.createElement("div"); | |
| 88 | |
| 89 var output = document.createElement("p"); | |
| 90 output.textContent = msg; | |
| 91 results.appendChild(output); | |
| 92 } | |
| 93 | |
| 94 function testIsFirstInColumn(containerId, blockNumber, lineNumber) | |
| 95 { | |
| 96 // Get the upper bounds of the container and line. | |
| 97 var topOfContainer = document.getElementById(containerId).getBoundingClientR
ect().top; | |
| 98 var topOfLine = document.getElementById(containerId + "-block-" + blockNumbe
r + "-line-" + lineNumber).getBoundingClientRect().top; | |
| 99 | |
| 100 if (Math.abs(topOfContainer - topOfLine) < 5) // Give 5 pixels to account fo
r subpixel layout. | |
| 101 logPass(containerId + " Block " + blockNumber + " Line " + lineNumber +
" is correct."); | |
| 102 else | |
| 103 logFail(containerId + " Block " + blockNumber + " Line " + lineNumber +
" wasn't at the top of the column."); | |
| 104 } | |
| 105 | |
| 106 function runTest() | |
| 107 { | |
| 108 var container; | |
| 109 | |
| 110 createTestContainer("test1", "Normal breaking", [5, 6, 5, 5]); | |
| 111 | |
| 112 markTopLine("test1", 1, 1); | |
| 113 markBottomLine("test1", 2, 4); | |
| 114 markTopLine("test1", 2, 5); | |
| 115 markBottomLine("test1", 4, 1); | |
| 116 markTopLine("test1", 4, 2); | |
| 117 | |
| 118 testIsFirstInColumn("test1", 1, 1); | |
| 119 testIsFirstInColumn("test1", 2, 5); | |
| 120 testIsFirstInColumn("test1", 4, 2); | |
| 121 | |
| 122 container = createTestContainer("test2", "Basic Orphan", [8, 6]); | |
| 123 container.style.orphans = 2; | |
| 124 | |
| 125 markTopLine("test2", 1, 1); | |
| 126 markBottomLine("test2", 1, 8); // Orphan break happens here. | |
| 127 markTopLine("test2", 2, 1); | |
| 128 | |
| 129 testIsFirstInColumn("test2", 1, 1); | |
| 130 testIsFirstInColumn("test2", 2, 1); | |
| 131 | |
| 132 container = createTestContainer("test3", "Basic Widow", [4, 6, 3]); | |
| 133 container.style.widows = 2; | |
| 134 | |
| 135 markTopLine("test3", 1, 1); | |
| 136 markBottomLine("test3", 2, 4); // Widow break happens here. | |
| 137 markTopLine("test3", 2, 5); | |
| 138 | |
| 139 testIsFirstInColumn("test3", 1, 1); | |
| 140 testIsFirstInColumn("test3", 2, 5); | |
| 141 | |
| 142 container = createTestContainer("test4", "Orphans causing Widows", [8, 6, 4,
4]); | |
| 143 container.style.orphans = 2; | |
| 144 container.style.widows = 2; | |
| 145 | |
| 146 markTopLine("test4", 1, 1); | |
| 147 markBottomLine("test4", 1, 8); // Orphan break happens here. | |
| 148 markTopLine("test4", 2, 1); | |
| 149 markBottomLine("test4", 3, 2); // And that creates a widow forcing a break h
ere. | |
| 150 markTopLine("test4", 3, 3); | |
| 151 | |
| 152 testIsFirstInColumn("test4", 1, 1); | |
| 153 testIsFirstInColumn("test4", 2, 1); | |
| 154 testIsFirstInColumn("test4", 3, 3); | |
| 155 | |
| 156 container = createTestContainer("test5", "Widows blocked by Orphan rule", [7
, 3, 4]); | |
| 157 container.style.orphans = 2; | |
| 158 container.style.widows = 2; | |
| 159 | |
| 160 markTopLine("test5", 1, 1); | |
| 161 markBottomLine("test5", 2, 2); // This line should not move - protected by o
rphaning. | |
| 162 markTopLine("test5", 2, 3); // This line won't be un-widowed - blocked by or
phaning. | |
| 163 | |
| 164 testIsFirstInColumn("test5", 1, 1); | |
| 165 testIsFirstInColumn("test5", 2, 3); | |
| 166 | |
| 167 container = createTestContainer("test6", "Ridiculous values", [7, 7, 7, 7]); | |
| 168 container.style.orphans = 100; | |
| 169 container.style.widows = 100; | |
| 170 | |
| 171 markTopLine("test6", 1, 1); | |
| 172 markBottomLine("test6", 1, 7); // Orphan break happens here. | |
| 173 markTopLine("test6", 2, 1); // Adopted. | |
| 174 markBottomLine("test6", 2, 7); // Orphan break. | |
| 175 markTopLine("test6", 3, 1); // Adopted. | |
| 176 | |
| 177 testIsFirstInColumn("test6", 1, 1); | |
| 178 testIsFirstInColumn("test6", 2, 1); | |
| 179 testIsFirstInColumn("test6", 3, 1); | |
| 180 | |
| 181 if (results) | |
| 182 document.body.appendChild(results); | |
| 183 | |
| 184 if (window.testRunner) { | |
| 185 // Hide all the containers and leave just the test results for text outp
ut. | |
| 186 document.body.className = "hide-containers"; | |
| 187 testRunner.notifyDone(); | |
| 188 } | |
| 189 } | |
| 190 | |
| 191 if (window.testRunner) { | |
| 192 testRunner.dumpAsText(); | |
| 193 testRunner.waitUntilDone(); | |
| 194 } | |
| 195 | |
| 196 window.addEventListener("load", runTest, false); | |
| 197 </script> | |
| 198 </head> | |
| 199 <body> | |
| 200 <p> | |
| 201 Testing widows and orphans. Any green lines | |
| 202 should be at the bottom of pages/columns, and any red lines | |
| 203 should be at the top of pages/columns. | |
| 204 </p> | |
| 205 </body> | |
| 206 </html> | |
| OLD | NEW |