Tools/ChangeLog

 12018-04-13 Zalan Bujtas <zalan@apple.com>
 2
 3 [LayoutReloaded] Add simple implementation for FormattingState::markNeedsLayout()
 4 https://bugs.webkit.org/show_bug.cgi?id=184621
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 This is just a simple, mark ancestors dirty implementation.
 9
 10 * LayoutReloaded/FormattingState/FormattingState.js:
 11 (FormattingState.prototype.markNeedsLayout):
 12 * LayoutReloaded/LayoutState.js:
 13 (LayoutState.prototype.markNeedsLayout):
 14 (LayoutState.prototype.setNeedsLayoutById): Deleted.
 15 (LayoutState.prototype.setNeedsLayout): Deleted.
 16 * LayoutReloaded/TreeBuilder.js:
 17 (TreeBuilder.prototype._createAndAttachBox):
 18 (TreeBuilder.prototype._findBox): Deleted.
 19 * LayoutReloaded/Utils.js:
 20 (Utils.layoutBoxById):
 21 * LayoutReloaded/test/index.html:
 22 * LayoutReloaded/test/simple-incremental-layout-with-static-content.html:
 23
1242018-04-13 Zalan Bujtas <zalan@apple.com>
225
326 Rebaseline LayoutReloaded patch file (collectRenderersWithNeedsLayout).

Tools/LayoutReloaded/FormattingState/FormattingState.js

@@class FormattingState {
8080 }
8181
8282 markNeedsLayout(layoutBox) {
 83 // Never mark the formatting root dirty. It belongs to the parent formatting context (or none if ICB).
 84 ASSERT(layoutBox != this.formattingRoot());
8385 this.m_needsLayoutBoxList.set(layoutBox);
 86 // FIXME: Let's just mark all the ancestors dirty in this formatting scope.
 87 let containingBlock = layoutBox.containingBlock();
 88 if (!containingBlock || containingBlock == this.formattingRoot())
 89 return;
 90 if (!FormattingContext.isInFormattingContext(containingBlock, this.formattingRoot()))
 91 return;
 92 if (this.needsLayout(containingBlock))
 93 return;
 94
 95 this.markNeedsLayout(containingBlock);
8496 }
8597
8698 clearNeedsLayout(layoutBox) {

Tools/LayoutReloaded/LayoutState.js

@@class LayoutState {
6161 return null;
6262 }
6363
64  // This is for testing only.
65  setNeedsLayoutById(layoutBoxId) {
66  }
67 
68  setNeedsLayout(layoutBox) {
 64 markNeedsLayout(layoutBox) {
6965 let formattingState = this.formattingStateForBox(layoutBox);
7066 // Newly created formatting state will obviously mark all the boxes dirty.
7167 if (!formattingState)
7268 return;
73  formattingState.setNeedsLayout(layoutBox);
 69 formattingState.markNeedsLayout(layoutBox);
7470 }
7571
7672 needsLayout() {

Tools/LayoutReloaded/TreeBuilder.js

@@class TreeBuilder {
6464 if (box)
6565 box.setRendererName(name);
6666
67  let parentBox = this._findBox(initialBlockContainer, parentId);
 67 let parentBox = Utils.layoutBoxById(parentId, initialBlockContainer);
6868 // WebKit does not construct anonymous inline container for text if the text
6969 // is a direct child of a block container.
7070 if (text) {

@@class TreeBuilder {
9090 parent.setLastChild(child);
9191 }
9292
93  _findBox(root, boxId) {
94  if (root.id() == boxId)
95  return root;
96  // Super inefficient but this is all temporary anyway.
97  for (let box = root.firstChild(); box; box = box.nextSibling()) {
98  if (box.id() == boxId)
99  return box;
100  if (box.isContainer() && box.hasChild()) {
101  let candidate = this._findBox(box, boxId);
102  if (candidate)
103  return candidate;
104  }
105  }
106  }
107 
10893 _findNode(node, boxId) {
10994 // Super inefficient but this is all temporary anyway.
11095 for (let currentNode = node.firstChild; currentNode; currentNode = currentNode.nextSibling) {

Tools/LayoutReloaded/Utils.js

@@class Utils {
548548 return textBox.text().node().textHeight();
549549 }
550550
 551 static layoutBoxById(layoutBoxId, box) {
 552 if (box.id() == layoutBoxId)
 553 return box;
 554 if (!box.isContainer())
 555 return null;
 556 // Super inefficient but this is all temporary anyway.
 557 for (let child = box.firstChild(); child; child = child.nextSibling()) {
 558 if (child.id() == layoutBoxId)
 559 return child;
 560 let foundIt = Utils.layoutBoxById(layoutBoxId, child);
 561 if (foundIt)
 562 return foundIt;
 563 }
 564 return null;
 565 }
551566 // "RenderView at (0,0) size 1317x366\n HTML RenderBlock at (0,0) size 1317x116\n BODY RenderBody at (8,8) size 1301x100\n DIV RenderBlock at (0,0) size 100x100\n";
552567 static layoutTreeDump(layoutState) {
553568 return this._dumpBox(layoutState, layoutState.rootContainer(), 1) + this._dumpTree(layoutState, layoutState.rootContainer(), 2);

Tools/LayoutReloaded/test/index.html

@@let failedTests = new Array();
121121
122122let isRunningAsyncTest = false;
123123let tests;
 124let testsPassed = 0;
124125let currentTestIndex = 0;
125126let subTests = 0;
 127let subTestPassed = true;
126128let layoutState = null;
127129
128 function collectRenderersWithNeedsLayout() {
129  // TODO: implement it in WebKit.
130  return null;
131 }
132 
133130function runAndVerifyLayout(window) {
134131 layoutState = runLayout(window, layoutState);
135132 return verifyLayout(window.simplifiedRenderTree);

@@class TestRunner {
142139
143140 notifyDone() {
144141 let testFrame = document.getElementById("testFrame");
145  let passed = runAndVerifyLayout(testFrame.contentWindow);
146  finishAndMoveToNextTest(passed);
 142 ASSERT(subTests);
 143 finishAndMoveToNextTest(subTestPassed);
147144 }
148145
149146 forceLayout() {
150147 let testFrame = document.getElementById("testFrame");
151  let needsLayoutRenderers = collectRenderersWithNeedsLayout(); //testFrame.contentWindow.collectRenderersWithNeedsLayout();
 148 let needsLayoutRenderers = testFrame.contentWindow.collectRenderersWithNeedsLayout();
152149 testFrame.contentWindow.document.body.offsetWidth;
153150 if (layoutState) {
154  for (let rendererId of needsLayoutRenderers)
155  layoutState.setNeedsLayoutById(rendererId);
 151 // Finding box by id won't work unless this is ICB's layout state.
 152 ASSERT(!layoutState.rootContainer().parent());
 153 for (let rendererId of needsLayoutRenderers) {
 154 let layoutBox = Utils.layoutBoxById(rendererId, layoutState.rootContainer());
 155 layoutState.markNeedsLayout(layoutBox);
 156 }
156157 }
157158 let passed = runAndVerifyLayout(testFrame.contentWindow);
158159 ++subTests;
159  if (!passed && failedTests.indexOf(currentTestIndex) == -1)
160  failedTests.push(currentTestIndex);
 160 if (!passed) {
 161 subTestPassed = false;
 162 if (failedTests.indexOf(currentTestIndex) == -1)
 163 failedTests.push(currentTestIndex);
 164 }
161165 printIntermediateResult();
162166 }
163167

@@function printFinalResult() {
176180}
177181
178182function printIntermediateResult() {
179  let resultContent = "Testing..." + currentTestIndex + (subTests > 0 ? "(" + subTests + ")" : "") + " out of " + tests.length;
180  resultContent += "<br><br>Passed: " + (currentTestIndex - failedTests.length) + "<br>Failed: " + failedTests.length;
 183 let resultContent = "Testing..." + (currentTestIndex + 1) + (subTests > 0 ? "(" + subTests + ")" : "") + " out of " + tests.length;
 184 resultContent += "<br><br>Passed: " + testsPassed + "<br>Failed: " + failedTests.length;
181185 if (failedTests.length > 0) {
182186 resultContent += "<br><br>Failed cases:"
183187 failedTests.forEach(function(item) {

@@function finishAndMoveToNextTest(passed) {
194198 layoutState = null;
195199 subTests = 0;
196200 isRunningAsyncTest = false;
197  if (!passed)
 201 if (passed)
 202 ++testsPassed;
 203 else if (failedTests.indexOf(currentTestIndex) == -1)
198204 failedTests.push(currentTestIndex);
199205 setTimeout(function() {
200206 if (currentTestIndex < tests.length - 1) {

Tools/LayoutReloaded/test/simple-incremental-layout-with-static-content.html

11<!DOCTYPE html>
22<html>
33<body>
4 <div style="width: 100px; height: 100px; border: 1px solid green"></div>
 4<div id=foobar style="width: 100px; height: 100px;"></div>
55<script>
 6let foobarWidth = 200;
67testRunner.waitUntilDone();
 8testRunner.forceLayout();
 9
710setInterval(function() {
 11 foobar.style.width = foobarWidth + "px";
812 testRunner.forceLayout();
 13 foobarWidth += 50;
914}, 10);
1015
1116setTimeout(function() {
1217 testRunner.notifyDone();
13 }, 100);
 18}, 500);
1419</script>
1520</body>
1621</html>