[LFC] Use the used margin values in outOfFlowReplacedVerticalGeometry consistently
[WebKit-https.git] / Tools / LayoutReloaded / TreeBuilder.js
1 /*
2  * Copyright (C) 2018 Apple Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 // 1()RenderView|2(1)RenderBlock|3(2)RenderBody|4(3)RenderBlock|5(3)AnonymousRenderBlock|
27 class TreeBuilder {
28
29     createTree(document, renderTreeDump) {
30         // Root.
31         let initialBlockContainer = new Layout.BlockContainer(document, parseInt(renderTreeDump.substring(0, renderTreeDump.indexOf("("))));
32         initialBlockContainer.setRendererName("RenderView");
33         renderTreeDump = renderTreeDump.substring(renderTreeDump.indexOf("|") + 1);
34
35         while (true) {
36             let endOfId = renderTreeDump.indexOf("(");
37             let boxId = parseInt(renderTreeDump.substring(0, endOfId));
38             let endOfParentId = renderTreeDump.indexOf(")");
39             let parentId = parseInt(renderTreeDump.substring(endOfId + 1, endOfParentId));
40             let endOfName = renderTreeDump.indexOf("|");
41             let name = renderTreeDump.substring(endOfParentId + 1, endOfName);
42
43             this._createAndAttachBox(initialBlockContainer, boxId, name, parentId);
44             if (endOfName == renderTreeDump.length - 1)
45                 break;
46             renderTreeDump = renderTreeDump.substring(endOfName + 1);
47         }
48         return initialBlockContainer;
49     }
50
51     _createAndAttachBox(initialBlockContainer, id, name, parentId) {
52         let box = null;
53         let text = null;
54         let node = this._findNode(initialBlockContainer.node(), id, name);
55         if (name == "RenderBlock" || name == "RenderBody")
56             box = new Layout.BlockContainer(node, id);
57         else if (name == "RenderInline")
58             box = new Layout.InlineContainer(node, id);
59         else if (name == "RenderText")
60             text = new Text(node, id);
61         else if (name == "RenderImage")
62             box = new Layout.InlineBox(node, id);
63         else
64             box = new Layout.Box(node, id);
65
66         if (box)
67             box.setRendererName(name);
68
69         let parentBox = Utils.layoutBoxById(parentId, initialBlockContainer);
70         // WebKit does not construct anonymous inline container for text if the text
71         // is a direct child of a block container.
72         if (text) {
73             box = new Layout.InlineBox(null, -1);
74             box.setIsAnonymous();
75             box.setText(text);
76         }
77         this._appendChild(parentBox, box);
78         return box;
79     }
80
81     _appendChild(parent, child) {
82         child.setParent(parent);
83         let firstChild = parent.firstChild();
84         if (!firstChild) {
85             parent.setFirstChild(child);
86             parent.setLastChild(child);
87             return;
88         }
89         let lastChild = parent.lastChild();
90         lastChild.setNextSibling(child);
91         child.setPreviousSibling(lastChild);
92         parent.setLastChild(child);
93     }
94
95     _findNode(node, boxId) {
96         // Super inefficient but this is all temporary anyway.
97         for (let currentNode = node.firstChild; currentNode; currentNode = currentNode.nextSibling) {
98             if (currentNode.rendererId == boxId)
99                 return currentNode;
100             let candidate = this._findNode(currentNode, boxId);
101             if (candidate)
102                 return candidate;
103         }
104     }
105 }