Diff
Modified: trunk/Tools/ChangeLog (230621 => 230622)
--- trunk/Tools/ChangeLog 2018-04-13 03:09:03 UTC (rev 230621)
+++ trunk/Tools/ChangeLog 2018-04-13 05:27:52 UTC (rev 230622)
@@ -1,5 +1,26 @@
2018-04-12 Zalan Bujtas <za...@apple.com>
+ [LayoutReloaded] Add support for incremental layout
+ https://bugs.webkit.org/show_bug.cgi?id=184578
+
+ Reviewed by Antti Koivisto.
+
+ * LayoutReloaded/Layout.js:
+ (layout):
+ * LayoutReloaded/LayoutState.js:
+ (LayoutState.prototype.rootContainer):
+ (LayoutState.prototype.setNeedsLayoutById):
+ * LayoutReloaded/Utils.js:
+ (Utils.layoutTreeDump):
+ * LayoutReloaded/test/TestHarness.js:
+ (verifyLayout):
+ (runLayout):
+ (verifyLayoutTreeDump): Deleted.
+ * LayoutReloaded/test/index.html:
+ * LayoutReloaded/test/simple-incremental-layout-with-static-content.html: Added.
+
+2018-04-12 Zalan Bujtas <za...@apple.com>
+
[LayoutReloaded] Move root container ownership to layout state
https://bugs.webkit.org/show_bug.cgi?id=184575
Modified: trunk/Tools/LayoutReloaded/Layout.js (230621 => 230622)
--- trunk/Tools/LayoutReloaded/Layout.js 2018-04-13 03:09:03 UTC (rev 230621)
+++ trunk/Tools/LayoutReloaded/Layout.js 2018-04-13 05:27:52 UTC (rev 230622)
@@ -23,12 +23,18 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-function layout(window, viewportSize) {
- let treeBuilder = new TreeBuilder();
- let initialContainingBlock = treeBuilder.createTree(window.document, window.renderTreeStructure);
- let displayBox = new Display.Box();
- displayBox.setSize(viewportSize);
- let layoutState = new LayoutState(initialContainingBlock, displayBox);
- layoutState.formattingContext(initialContainingBlock).layout();
- return Utils.layoutTreeDump(initialContainingBlock, layoutState);
+function layout(window, viewportSize, layoutState) {
+ let rootContainer = null;
+ if (layoutState)
+ rootContainer = layoutState.rootContainer();
+ else {
+ // This is top level layout (initial containing block, etc).
+ let treeBuilder = new TreeBuilder();
+ rootContainer = treeBuilder.createTree(window.document, window.renderTreeStructure);
+ let displayBox = new Display.Box();
+ displayBox.setSize(viewportSize);
+ layoutState = new LayoutState(rootContainer, displayBox);
+ }
+ layoutState.formattingContext(rootContainer).layout();
+ return layoutState;
}
Modified: trunk/Tools/LayoutReloaded/LayoutState.js (230621 => 230622)
--- trunk/Tools/LayoutReloaded/LayoutState.js 2018-04-13 03:09:03 UTC (rev 230621)
+++ trunk/Tools/LayoutReloaded/LayoutState.js 2018-04-13 05:27:52 UTC (rev 230622)
@@ -36,6 +36,10 @@
return this._formattingContext(this.establishedFormattingState(formattingRoot));
}
+ rootContainer() {
+ return this.m_rootContainer;
+ }
+
establishedFormattingState(formattingRoot) {
ASSERT(formattingRoot.establishesFormattingContext());
let formattingState = this.m_formattingStates.get(formattingRoot);
@@ -57,6 +61,10 @@
return null;
}
+ // This is for testing only.
+ setNeedsLayoutById(layoutBoxId) {
+ }
+
setNeedsLayout(layoutBox) {
let formattingState = this.formattingStateForBox(layoutBox);
// Newly created formatting state will obviously mark all the boxes dirty.
Modified: trunk/Tools/LayoutReloaded/Utils.js (230621 => 230622)
--- trunk/Tools/LayoutReloaded/Utils.js 2018-04-13 03:09:03 UTC (rev 230621)
+++ trunk/Tools/LayoutReloaded/Utils.js 2018-04-13 05:27:52 UTC (rev 230622)
@@ -549,8 +549,8 @@
}
// "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";
- static layoutTreeDump(initialContainingBlock, layoutState) {
- return this._dumpBox(layoutState, initialContainingBlock, 1) + this._dumpTree(layoutState, initialContainingBlock, 2);
+ static layoutTreeDump(layoutState) {
+ return this._dumpBox(layoutState, layoutState.rootContainer(), 1) + this._dumpTree(layoutState, layoutState.rootContainer(), 2);
}
static _dumpBox(layoutState, box, level) {
Modified: trunk/Tools/LayoutReloaded/test/TestHarness.js (230621 => 230622)
--- trunk/Tools/LayoutReloaded/test/TestHarness.js 2018-04-13 03:09:03 UTC (rev 230621)
+++ trunk/Tools/LayoutReloaded/test/TestHarness.js 2018-04-13 05:27:52 UTC (rev 230622)
@@ -23,8 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-function verifyLayoutTreeDump(renderTreeDump, layoutTreeDump)
+function verifyLayout(renderTreeDump)
{
+ let layoutTreeDump = Utils.layoutTreeDump(layoutState);
console.log("WebKit:\n" + renderTreeDump + renderTreeDump.length);
console.log("Reloaded:\n" + layoutTreeDump + layoutTreeDump.length);
if (renderTreeDump == layoutTreeDump)
@@ -32,9 +33,8 @@
return false;
}
-function runLayout(testWindow) {
+function runLayout(testWindow, layoutState) {
testWindow.document.body.offsetHeight;
let viewportSize = new LayoutSize(parseFloat(testWindow.innerWidth), parseFloat(testWindow.innerHeight));
- let layoutTreeDump = layout(testWindow, viewportSize);
- return verifyLayoutTreeDump(testWindow.simplifiedRenderTree, layoutTreeDump);
+ return layout(testWindow, viewportSize, layoutState);
}
Modified: trunk/Tools/LayoutReloaded/test/index.html (230621 => 230622)
--- trunk/Tools/LayoutReloaded/test/index.html 2018-04-13 03:09:03 UTC (rev 230621)
+++ trunk/Tools/LayoutReloaded/test/index.html 2018-04-13 05:27:52 UTC (rev 230622)
@@ -8,6 +8,7 @@
</style>
<script>
let testFiles = [
+ "simple-incremental-layout-with-static-content.html",
"relative-simple.html",
"relative-bottom.html",
"relative-right.html",
@@ -116,45 +117,116 @@
addJS("../FormattingContext/InlineFormatting/InlineFormattingContext.js");
addJS("../FormattingContext/InlineFormatting/Line.js");
-let failedTests = [];
+let failedTests = new Array();
-function printResult(files, currentTestIndex) {
- let resultContent = currentTestIndex != null ? ("Testing..." + currentTestIndex + " out of " + files.length) : ("Number of tests: " + files.length) ;
- resultContent += "<br><br>Passed: " + ((currentTestIndex != null ? currentTestIndex : files.length) - failedTests.length) + "<br>Failed: " + failedTests.length;
+let isRunningAsyncTest = false;
+let tests;
+let currentTestIndex = 0;
+let subTests = 0;
+let layoutState = null;
+
+function collectRenderersWithNeedsLayout() {
+ // TODO: implement it in WebKit.
+ return null;
+}
+
+function runAndVerifyLayout(window) {
+ layoutState = runLayout(window, layoutState);
+ return verifyLayout(window.simplifiedRenderTree);
+}
+
+class TestRunner {
+ waitUntilDone() {
+ isRunningAsyncTest = true;
+ }
+
+ notifyDone() {
+ let testFrame = document.getElementById("testFrame");
+ let passed = runAndVerifyLayout(testFrame.contentWindow);
+ finishAndMoveToNextTest(passed);
+ }
+
+ forceLayout() {
+ let testFrame = document.getElementById("testFrame");
+ let needsLayoutRenderers = collectRenderersWithNeedsLayout(); //testFrame.contentWindow.collectRenderersWithNeedsLayout();
+ testFrame.contentWindow.document.body.offsetWidth;
+ if (layoutState) {
+ for (let rendererId of needsLayoutRenderers)
+ layoutState.setNeedsLayoutById(rendererId);
+ }
+ let passed = runAndVerifyLayout(testFrame.contentWindow);
+ ++subTests;
+ if (!passed && failedTests.indexOf(currentTestIndex) == -1)
+ failedTests.push(currentTestIndex);
+ printIntermediateResult();
+ }
+
+}
+
+function printFinalResult() {
+ let resultContent = "Number of tests: " + tests.length;
+ resultContent += "<br><br>Passed: " + (tests.length - failedTests.length) + "<br>Failed: " + failedTests.length;
if (failedTests.length > 0) {
resultContent += "<br><br>Failed cases:"
failedTests.forEach(function(item) {
- resultContent += "<br><a href="" + files[item] + "\">" + files[item] + "</a>";
+ resultContent += "<br><a href="" + tests[item] + "\">" + tests[item] + "</a>";
});
}
result.innerHTML = resultContent;
}
-function runTest(files, currentTestIndex) {
- printResult(files, currentTestIndex);
+function printIntermediateResult() {
+ let resultContent = "Testing..." + currentTestIndex + (subTests > 0 ? "(" + subTests + ")" : "") + " out of " + tests.length;
+ resultContent += "<br><br>Passed: " + (currentTestIndex - failedTests.length) + "<br>Failed: " + failedTests.length;
+ if (failedTests.length > 0) {
+ resultContent += "<br><br>Failed cases:"
+ failedTests.forEach(function(item) {
+ resultContent += "<br><a href="" + tests[item] + "\">" + tests[item] + "</a>";
+ });
+ }
+ result.innerHTML = resultContent;
+}
+
+function finishAndMoveToNextTest(passed) {
+ let testFrame = document.getElementById("testFrame");
+ testFrame.remove();
+ initialContainingBlock = null;
+ layoutState = null;
+ subTests = 0;
+ isRunningAsyncTest = false;
+ if (!passed)
+ failedTests.push(currentTestIndex);
+ setTimeout(function() {
+ if (currentTestIndex < tests.length - 1) {
+ printIntermediateResult();
+ ++currentTestIndex;
+ runTest(tests);
+ return;
+ }
+ printFinalResult();
+ }, 0);
+}
+
+function runTest() {
let iframe = document.createElement("iframe");
- iframe.src = ""
+ iframe.src = ""
iframe.id = "testFrame";
iframe.width = window.innerWidth;
iframe.height = window.innerHeight;
iframe._onload_ = function() {
+ if (isRunningAsyncTest)
+ return;
let testFrame = document.getElementById("testFrame");
- let passed = runLayout(testFrame.contentWindow);
- testFrame.remove();
- if (!passed)
- failedTests.push(currentTestIndex);
- setTimeout(function() {
- if (currentTestIndex < files.length - 1)
- runTest(files, ++currentTestIndex);
- else
- printResult(files);
- }, 0);
+ let passed = runAndVerifyLayout(testFrame.contentWindow);
+ finishAndMoveToNextTest(passed, tests);
};
document.body.appendChild(iframe);
+ iframe.contentWindow.testRunner = new TestRunner();
}
function runTests() {
- runTest(debugThis.length ? debugThis : testFiles, 0);
+ tests = debugThis.length ? debugThis : testFiles;
+ runTest();
}
</script>
</head>
Added: trunk/Tools/LayoutReloaded/test/simple-incremental-layout-with-static-content.html (0 => 230622)
--- trunk/Tools/LayoutReloaded/test/simple-incremental-layout-with-static-content.html (rev 0)
+++ trunk/Tools/LayoutReloaded/test/simple-incremental-layout-with-static-content.html 2018-04-13 05:27:52 UTC (rev 230622)
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div style="width: 100px; height: 100px; border: 1px solid green"></div>
+<script>
+testRunner.waitUntilDone();
+setInterval(function() {
+ testRunner.forceLayout();
+}, 10);
+
+setTimeout(function() {
+ testRunner.notifyDone();
+}, 100);
+</script>
+</body>
+</html>