4 <title>Testing Widows and Orphans</title>
5 <script src="../../resources/js-test.js"></script>
7 body.hide-containers .container, body.hide-containers h3 {
13 -webkit-region-fragment: break;
14 display: inline-block;
32 line-height: 20px; /* 10 lines per page */
54 description("Testing widows and orphans. Any green lines should be at the bottom of regions, and any red lines should be at the top of regions.");
56 if (window.testRunner)
57 testRunner.dumpAsText();
59 function createRegions(id, container)
61 for (var i = 0; i < 3; ++i) {
62 var element = document.createElement("div");
63 element.className = "region region" + i;
64 element.style.webkitFlowFrom = id;
66 container.appendChild(element);
70 function createTestContainer(id, description, blocks)
72 var label = document.createElement("h3");
73 label.textContent = id + " - " + description;
74 document.body.appendChild(label);
75 var element = document.createElement("div");
76 element.className = "container";
79 createRegions(id, element);
81 for (var i = 1; i <= blocks.length; ++i) {
82 var block = document.createElement("div");
83 block.className = "block";
84 var numLines = blocks[i-1];
85 for (var j = 1; j <= numLines; ++j) {
86 var line = document.createElement("span");
87 line.id = id + "-block-" + i + "-line-" + j;
88 line.textContent = "Block " + i + " Line " + j;
89 block.appendChild(line);
90 block.appendChild(document.createElement("br"));
92 block.style.webkitFlowInto = id;
93 element.appendChild(block);
95 document.body.appendChild(element);
99 function markTopLine(containerId, blockNumber, lineNumber)
101 var element = document.getElementById(containerId + "-block-" + blockNumber + "-line-" + lineNumber);
102 element.className = "top";
105 function markBottomLine(containerId, blockNumber, lineNumber)
107 var element = document.getElementById(containerId + "-block-" + blockNumber + "-line-" + lineNumber);
108 element.className = "bottom";
111 function testIsFirstInRegion(containerId, blockNumber, lineNumber)
113 var topOfContainer = document.getElementById(containerId).getBoundingClientRect().top;
114 var topOfLine = document.getElementById(containerId + "-block-" + blockNumber + "-line-" + lineNumber).getBoundingClientRect().top;
116 if (Math.abs(topOfContainer - topOfLine) < 5) // Give 5 pixels to account for subpixel layout.
117 testPassed(containerId + " Block " + blockNumber + " Line " + lineNumber + " is correct.");
119 testFailed(containerId + " Block " + blockNumber + " Line " + lineNumber + " wasn't at the top of the region.");
126 createTestContainer("test1", "Normal breaking", [5, 6, 5, 5]);
128 markTopLine("test1", 1, 1);
129 markBottomLine("test1", 2, 4);
130 markTopLine("test1", 2, 5);
131 markBottomLine("test1", 4, 1);
132 markTopLine("test1", 4, 2);
134 testIsFirstInRegion("test1", 1, 1);
135 testIsFirstInRegion("test1", 2, 5);
136 testIsFirstInRegion("test1", 4, 2);
138 container = createTestContainer("test2", "Basic Orphan", [8, 6]);
139 container.style.orphans = 2;
141 markTopLine("test2", 1, 1);
142 markBottomLine("test2", 1, 8); // Orphan break happens here.
143 markTopLine("test2", 2, 1);
145 testIsFirstInRegion("test2", 1, 1);
146 testIsFirstInRegion("test2", 2, 1);
148 container = createTestContainer("test3", "Basic Widow", [4, 6, 3]);
149 container.style.widows = 2;
151 markTopLine("test3", 1, 1);
152 markBottomLine("test3", 2, 4); // Widow break happens here.
153 markTopLine("test3", 2, 5);
155 testIsFirstInRegion("test3", 1, 1);
156 testIsFirstInRegion("test3", 2, 5);
158 container = createTestContainer("test4", "Orphans causing Widows", [8, 6, 4, 4]);
159 container.style.orphans = 2;
160 container.style.widows = 2;
162 markTopLine("test4", 1, 1);
163 markBottomLine("test4", 1, 8); // Orphan break happens here.
164 markTopLine("test4", 2, 1);
165 markBottomLine("test4", 3, 2); // And that creates a widow forcing a break here.
166 markTopLine("test4", 3, 3);
168 testIsFirstInRegion("test4", 1, 1);
169 testIsFirstInRegion("test4", 2, 1);
170 testIsFirstInRegion("test4", 3, 3);
172 container = createTestContainer("test5", "Widows blocked by Orphan rule", [7, 3, 4]);
173 container.style.orphans = 2;
174 container.style.widows = 2;
176 markTopLine("test5", 1, 1);
177 markBottomLine("test5", 2, 2); // This line should not move - protected by orphaning.
178 markTopLine("test5", 2, 3); // This line won't be un-widowed - blocked by orphaning.
180 testIsFirstInRegion("test5", 1, 1);
181 testIsFirstInRegion("test5", 2, 3);
183 container = createTestContainer("test6", "Ridiculous values", [7, 7, 7, 7]);
184 container.style.orphans = 100;
185 container.style.widows = 100;
187 markTopLine("test6", 1, 1);
188 markBottomLine("test6", 1, 7); // Orphan break happens here.
189 markTopLine("test6", 2, 1); // Adopted.
190 markBottomLine("test6", 2, 7); // Orphan break.
191 markTopLine("test6", 3, 1); // Adopted.
193 testIsFirstInRegion("test6", 1, 1);
194 testIsFirstInRegion("test6", 2, 1);
195 testIsFirstInRegion("test6", 3, 1);
197 if (window.testRunner) {
198 // Hide all the containers and leave just the test results for text output.
199 document.body.className = "hide-containers";
202 isSuccessfullyParsed();
205 window.addEventListener("load", runTest, false);