4 <title>Testing Widows and Orphans
</title>
6 body.hide-containers .container {
16 line-height:
20px; /*
10 lines per page */
39 function createTestContainer(id
, description
, blocks
)
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";
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"));
59 element
.appendChild(block
);
61 document
.body
.appendChild(element
);
65 function markTopLine(containerId
, blockNumber
, lineNumber
)
67 var element
= document
.getElementById(containerId
+ "-block-" + blockNumber
+ "-line-" + lineNumber
);
68 element
.className
= "top";
71 function markBottomLine(containerId
, blockNumber
, lineNumber
)
73 var element
= document
.getElementById(containerId
+ "-block-" + blockNumber
+ "-line-" + lineNumber
);
74 element
.className
= "bottom";
77 function logPass(msg
) {
81 function logFail(msg
) {
87 results
= document
.createElement("div");
89 var output
= document
.createElement("p");
90 output
.textContent
= msg
;
91 results
.appendChild(output
);
94 function testIsFirstInColumn(containerId
, blockNumber
, lineNumber
)
96 // Get the upper bounds of the container and line.
97 var topOfContainer
= document
.getElementById(containerId
).getBoundingClientRect().top
;
98 var topOfLine
= document
.getElementById(containerId
+ "-block-" + blockNumber
+ "-line-" + lineNumber
).getBoundingClientRect().top
;
100 if (Math
.abs(topOfContainer
- topOfLine
) < 5) // Give 5 pixels to account for subpixel layout.
101 logPass(containerId
+ " Block " + blockNumber
+ " Line " + lineNumber
+ " is correct.");
103 logFail(containerId
+ " Block " + blockNumber
+ " Line " + lineNumber
+ " wasn't at the top of the column.");
110 createTestContainer("test1", "Normal breaking", [5, 6, 5, 5]);
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);
118 testIsFirstInColumn("test1", 1, 1);
119 testIsFirstInColumn("test1", 2, 5);
120 testIsFirstInColumn("test1", 4, 2);
122 container
= createTestContainer("test2", "Basic Orphan", [8, 6]);
123 container
.style
.orphans
= 2;
125 markTopLine("test2", 1, 1);
126 markBottomLine("test2", 1, 8); // Orphan break happens here.
127 markTopLine("test2", 2, 1);
129 testIsFirstInColumn("test2", 1, 1);
130 testIsFirstInColumn("test2", 2, 1);
132 container
= createTestContainer("test3", "Basic Widow", [4, 6, 3]);
133 container
.style
.widows
= 2;
135 markTopLine("test3", 1, 1);
136 markBottomLine("test3", 2, 4); // Widow break happens here.
137 markTopLine("test3", 2, 5);
139 testIsFirstInColumn("test3", 1, 1);
140 testIsFirstInColumn("test3", 2, 5);
142 container
= createTestContainer("test4", "Orphans causing Widows", [8, 6, 4, 4]);
143 container
.style
.orphans
= 2;
144 container
.style
.widows
= 2;
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 here.
150 markTopLine("test4", 3, 3);
152 testIsFirstInColumn("test4", 1, 1);
153 testIsFirstInColumn("test4", 2, 1);
154 testIsFirstInColumn("test4", 3, 3);
156 container
= createTestContainer("test5", "Widows blocked by Orphan rule", [7, 3, 4]);
157 container
.style
.orphans
= 2;
158 container
.style
.widows
= 2;
160 markTopLine("test5", 1, 1);
161 markBottomLine("test5", 2, 2); // This line should not move - protected by orphaning.
162 markTopLine("test5", 2, 3); // This line won't be un-widowed - blocked by orphaning.
164 testIsFirstInColumn("test5", 1, 1);
165 testIsFirstInColumn("test5", 2, 3);
167 container
= createTestContainer("test6", "Ridiculous values", [7, 7, 7, 7]);
168 container
.style
.orphans
= 100;
169 container
.style
.widows
= 100;
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.
177 testIsFirstInColumn("test6", 1, 1);
178 testIsFirstInColumn("test6", 2, 1);
179 testIsFirstInColumn("test6", 3, 1);
182 document
.body
.appendChild(results
);
184 if (window
.testRunner
) {
185 // Hide all the containers and leave just the test results for text output.
186 document
.body
.className
= "hide-containers";
187 testRunner
.notifyDone();
191 if (window
.testRunner
) {
192 testRunner
.dumpAsText();
193 testRunner
.waitUntilDone();
196 window
.addEventListener("load", runTest
, false);
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.