[LayoutReloaded] Remove left/right width/height setters from Layout.Box
[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.InitialBlockContainer(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
62             box = new Layout.Box(node, id);
63
64         if (box)
65             box.setRendererName(name);
66
67         let parentBox = this._findBox(initialBlockContainer, parentId);
68         // WebKit does not construct anonymous inline container for text if the text
69         // is a direct child of a block container.
70         if (text && !parentBox.isInlineContainer) {
71             box = new Layout.InlineBox(null, -1);
72             box.setIsAnonymous();
73             box.setText(text);
74         }
75         this._appendChild(parentBox, box);
76         return box;
77     }
78
79     _appendChild(parent, child) {
80         child.setParent(parent);
81         let firstChild = parent.firstChild();
82         if (!firstChild) {
83             parent.setFirstChild(child);
84             parent.setLastChild(child);
85             return;
86         }
87         let lastChild = parent.lastChild();
88         lastChild.setNextSibling(child);
89         child.setPreviousSibling(lastChild);
90         parent.setLastChild(child);
91     }
92
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
108     _findNode(node, boxId) {
109         // Super inefficient but this is all temporary anyway.
110         for (let currentNode = node.firstChild; currentNode; currentNode = currentNode.nextSibling) {
111             if (currentNode.rendererId == boxId)
112                 return currentNode;
113             let candidate = this._findNode(currentNode, boxId);
114             if (candidate)
115                 return candidate;
116         }
117     }
118 }