[RenderTreeBuilder] Move RenderButton::addChild() tree mutation to RenderTreeBuilder
[WebKit-https.git] / Source / WebCore / rendering / updating / RenderTreeBuilder.cpp
1 /*
2  * Copyright (C) 2017 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. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "RenderTreeBuilder.h"
28
29 #include "RenderButton.h"
30 #include "RenderElement.h"
31 #include "RenderRuby.h"
32 #include "RenderRubyBase.h"
33 #include "RenderRubyRun.h"
34 #include "RenderTableRow.h"
35 #include "RenderText.h"
36 #include "RenderTreeBuilderFirstLetter.h"
37 #include "RenderTreeBuilderList.h"
38 #include "RenderTreeBuilderMultiColumn.h"
39 #include "RenderTreeBuilderRuby.h"
40 #include "RenderTreeBuilderTable.h"
41
42 namespace WebCore {
43
44 RenderTreeBuilder* RenderTreeBuilder::s_current;
45
46 RenderTreeBuilder::RenderTreeBuilder(RenderView& view)
47     : m_view(view)
48     , m_firstLetterBuilder(std::make_unique<FirstLetter>(*this))
49     , m_listBuilder(std::make_unique<List>(*this))
50     , m_multiColumnBuilder(std::make_unique<MultiColumn>(*this))
51     , m_tableBuilder(std::make_unique<Table>(*this))
52     , m_rubyBuilder(std::make_unique<Ruby>(*this))
53 {
54     RELEASE_ASSERT(!s_current || &m_view != &s_current->m_view);
55     m_previous = s_current;
56     s_current = this;
57 }
58
59 RenderTreeBuilder::~RenderTreeBuilder()
60 {
61     s_current = m_previous;
62 }
63
64 static RenderBlock& createInnerRendererForButtonIfNeeded(RenderButton& button, RenderTreeBuilder& builder)
65 {
66     auto* innerRenderer = button.innerRenderer();
67     if (innerRenderer)
68         return *innerRenderer;
69     auto wrapper = button.createAnonymousBlock(button.style().display());
70     innerRenderer = wrapper.get();
71     button.updateAnonymousChildStyle(wrapper->mutableStyle());
72     button.RenderFlexibleBox::addChild(builder, WTFMove(wrapper));
73     button.setInnerRenderer(*innerRenderer);
74     return *innerRenderer;
75 }
76
77 void RenderTreeBuilder::insertChild(RenderElement& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild)
78 {
79     auto insertRecursiveIfNeeded = [&](RenderElement& parentCandidate) {
80         if (&parent == &parentCandidate) {
81             parent.addChild(*this, WTFMove(child), beforeChild);
82             return;
83         }
84         insertChild(parentCandidate, WTFMove(child), beforeChild);
85     };
86
87     ASSERT(&parent.view() == &m_view);
88
89     if (is<RenderText>(beforeChild)) {
90         if (auto* wrapperInline = downcast<RenderText>(*beforeChild).inlineWrapperForDisplayContents())
91             beforeChild = wrapperInline;
92     }
93
94     if (is<RenderTableRow>(parent)) {
95         insertRecursiveIfNeeded(tableBuilder().findOrCreateParentForChild(downcast<RenderTableRow>(parent), *child, beforeChild));
96         return;
97     }
98
99     if (is<RenderTableSection>(parent)) {
100         insertRecursiveIfNeeded(tableBuilder().findOrCreateParentForChild(downcast<RenderTableSection>(parent), *child, beforeChild));
101         return;
102     }
103
104     if (is<RenderTable>(parent)) {
105         insertRecursiveIfNeeded(tableBuilder().findOrCreateParentForChild(downcast<RenderTable>(parent), *child, beforeChild));
106         return;
107     }
108
109     if (is<RenderRubyAsBlock>(parent)) {
110         insertRecursiveIfNeeded(rubyBuilder().findOrCreateParentForChild(downcast<RenderRubyAsBlock>(parent), *child, beforeChild));
111         return;
112     }
113
114     if (is<RenderRubyAsInline>(parent)) {
115         insertRecursiveIfNeeded(rubyBuilder().findOrCreateParentForChild(downcast<RenderRubyAsInline>(parent), *child, beforeChild));
116         return;
117     }
118
119     if (is<RenderRubyRun>(parent)) {
120         rubyBuilder().insertChild(downcast<RenderRubyRun>(parent), WTFMove(child), beforeChild);
121         return;
122     }
123
124     if (is<RenderButton>(parent)) {
125         insertRecursiveIfNeeded(createInnerRendererForButtonIfNeeded(downcast<RenderButton>(parent), *this));
126         return;
127     }
128     parent.addChild(*this, WTFMove(child), beforeChild);
129 }
130
131 void RenderTreeBuilder::insertChild(RenderTreePosition& position, RenderPtr<RenderObject> child)
132 {
133     insertChild(position.parent(), WTFMove(child), position.nextSibling());
134 }
135
136 void RenderTreeBuilder::updateAfterDescendants(RenderElement& renderer)
137 {
138     if (is<RenderBlock>(renderer))
139         firstLetterBuilder().updateAfterDescendants(downcast<RenderBlock>(renderer));
140     if (is<RenderListItem>(renderer))
141         listBuilder().updateItemMarker(downcast<RenderListItem>(renderer));
142     if (is<RenderBlockFlow>(renderer))
143         multiColumnBuilder().updateAfterDescendants(downcast<RenderBlockFlow>(renderer));
144 }
145
146 }