| 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 |