Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(268)

Side by Side Diff: Source/core/dom/RenderTreeBuilder.cpp

Issue 699213003: RenderTreeBuilder => RenderTreeBuilderForElement and RenderTreeBuilderForText (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/dom/RenderTreeBuilder.h ('k') | Source/core/dom/Text.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r ights reserved. 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r ights reserved.
6 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) 6 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/)
7 * Copyright (C) 2011 Google Inc. All rights reserved. 7 * Copyright (C) 2011 Google Inc. All rights reserved.
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public 10 * modify it under the terms of the GNU Library General Public
(...skipping 25 matching lines...) Expand all
36 #include "core/dom/Text.h" 36 #include "core/dom/Text.h"
37 #include "core/rendering/RenderFullScreen.h" 37 #include "core/rendering/RenderFullScreen.h"
38 #include "core/rendering/RenderObject.h" 38 #include "core/rendering/RenderObject.h"
39 #include "core/rendering/RenderText.h" 39 #include "core/rendering/RenderText.h"
40 #include "core/rendering/RenderView.h" 40 #include "core/rendering/RenderView.h"
41 #include "core/svg/SVGElement.h" 41 #include "core/svg/SVGElement.h"
42 #include "platform/RuntimeEnabledFeatures.h" 42 #include "platform/RuntimeEnabledFeatures.h"
43 43
44 namespace blink { 44 namespace blink {
45 45
46 RenderTreeBuilder::RenderTreeBuilder(Node* node, RenderStyle* style) 46 RenderTreeBuilderForElement::RenderTreeBuilderForElement(Element* element, Rende rStyle* style)
47 : m_node(node) 47 : RenderTreeBuilder(element, nullptr)
48 , m_renderingParent(nullptr)
49 , m_style(style) 48 , m_style(style)
50 { 49 {
51 ASSERT(!node->renderer()); 50 if (element->isFirstLetterPseudoElement()) {
52 ASSERT(node->needsAttach());
53 ASSERT(node->document().inStyleRecalc());
54
55 // FIXME: We should be able to ASSERT(node->inActiveDocument()) but children Changed is called
56 // before ChildNodeInsertionNotifier in ContainerNode's methods and some imp lementations
57 // will trigger a layout inside childrenChanged.
58 // Mainly HTMLTextAreaElement::childrenChanged calls HTMLTextFormControlElem ent::setSelectionRange
59 // which does an updateLayoutIgnorePendingStylesheets.
60
61 Element* element = node->isElementNode() ? toElement(node) : 0;
62 if (element && element->isFirstLetterPseudoElement()) {
63 if (RenderObject* nextRenderer = FirstLetterPseudoElement::firstLetterTe xtRenderer(*element)) 51 if (RenderObject* nextRenderer = FirstLetterPseudoElement::firstLetterTe xtRenderer(*element))
64 m_renderingParent = nextRenderer->parent(); 52 m_renderingParent = nextRenderer->parent();
65 } else if (ContainerNode* containerNode = NodeRenderingTraversal::parent(nod e, &m_parentDetails)) { 53 } else if (ContainerNode* containerNode = NodeRenderingTraversal::parent(ele ment)) {
66 m_renderingParent = containerNode->renderer(); 54 m_renderingParent = containerNode->renderer();
67 } 55 }
68 } 56 }
69 57
70 RenderObject* RenderTreeBuilder::nextRenderer() const 58 RenderObject* RenderTreeBuilderForElement::nextRenderer() const
71 { 59 {
72 ASSERT(m_renderingParent); 60 ASSERT(m_renderingParent);
73 61
74 Element* element = m_node->isElementNode() ? toElement(m_node) : 0; 62 if (m_node->isInTopLayer())
63 return NodeRenderingTraversal::nextInTopLayer(m_node);
75 64
76 if (element && element->isInTopLayer()) 65 if (m_node->isFirstLetterPseudoElement())
77 return NodeRenderingTraversal::nextInTopLayer(element); 66 return FirstLetterPseudoElement::firstLetterTextRenderer(*m_node);
78 67
79 if (element && element->isFirstLetterPseudoElement()) 68 return RenderTreeBuilder::nextRenderer();
80 return FirstLetterPseudoElement::firstLetterTextRenderer(*element);
81
82 // Avoid an O(N^2) walk over the children when reattaching all children of a node.
83 if (m_renderingParent->node() && m_renderingParent->node()->needsAttach())
84 return 0;
85
86 return NodeRenderingTraversal::nextSiblingRenderer(m_node);
87 } 69 }
88 70
89 RenderObject* RenderTreeBuilder::parentRenderer() const 71 RenderObject* RenderTreeBuilderForElement::parentRenderer() const
90 { 72 {
91 ASSERT(m_renderingParent); 73 RenderObject* parentRenderer = RenderTreeBuilder::parentRenderer();
92 74
93 Element* element = m_node->isElementNode() ? toElement(m_node) : 0; 75 if (parentRenderer) {
94 76 // FIXME: Guarding this by parentRenderer isn't quite right as the spec for
95 if (element && m_renderingParent) {
96 // FIXME: Guarding this by m_renderingParent isn't quite right as the sp ec for
97 // top layer only talks about display: none ancestors so putting a <dial og> inside an 77 // top layer only talks about display: none ancestors so putting a <dial og> inside an
98 // <optgroup> seems like it should still work even though this check wil l prevent it. 78 // <optgroup> seems like it should still work even though this check wil l prevent it.
99 if (element->isInTopLayer()) 79 if (m_node->isInTopLayer())
100 return m_node->document().renderView(); 80 return m_node->document().renderView();
101 } 81 }
102 82
103 return m_renderingParent; 83 return parentRenderer;
104 } 84 }
105 85
106 bool RenderTreeBuilder::shouldCreateRenderer() const 86 bool RenderTreeBuilderForElement::shouldCreateRenderer() const
107 { 87 {
108 if (!m_renderingParent) 88 if (!m_renderingParent)
109 return false; 89 return false;
90
91 // FIXME: Should the following be in SVGElement::rendererIsNeeded()?
110 if (m_node->isSVGElement()) { 92 if (m_node->isSVGElement()) {
111 // SVG elements only render when inside <svg>, or if the element is an < svg> itself. 93 // SVG elements only render when inside <svg>, or if the element is an < svg> itself.
112 if (!isSVGSVGElement(*m_node) && (!m_renderingParent->node() || !m_rende ringParent->node()->isSVGElement())) 94 if (!isSVGSVGElement(*m_node) && (!m_renderingParent->node() || !m_rende ringParent->node()->isSVGElement()))
113 return false; 95 return false;
114 if (!toSVGElement(m_node)->isValid()) 96 if (!toSVGElement(m_node)->isValid())
115 return false; 97 return false;
116 } 98 }
117 99
118 RenderObject* parentRenderer = this->parentRenderer(); 100 RenderObject* parentRenderer = this->parentRenderer();
119 if (!parentRenderer) 101 if (!parentRenderer)
120 return false; 102 return false;
121 if (!parentRenderer->canHaveChildren()) 103 if (!parentRenderer->canHaveChildren())
122 return false; 104 return false;
123 return true; 105
106 return m_node->rendererIsNeeded(style());
124 } 107 }
125 108
126 RenderStyle& RenderTreeBuilder::style() const 109 RenderStyle& RenderTreeBuilderForElement::style() const
127 { 110 {
128 if (!m_style) 111 if (!m_style)
129 m_style = toElement(m_node)->styleForRenderer(); 112 m_style = m_node->styleForRenderer();
130 return *m_style; 113 return *m_style;
131 } 114 }
132 115
133 void RenderTreeBuilder::createRendererForElementIfNeeded() 116 void RenderTreeBuilderForElement::createRenderer()
134 { 117 {
135 ASSERT(!m_node->renderer());
136
137 if (!shouldCreateRenderer())
138 return;
139
140 Element* element = toElement(m_node);
141 RenderStyle& style = this->style(); 118 RenderStyle& style = this->style();
142 119
143 if (!element->rendererIsNeeded(style)) 120 RenderObject* newRenderer = m_node->createRenderer(&style);
144 return;
145
146 RenderObject* newRenderer = element->createRenderer(&style);
147 if (!newRenderer) 121 if (!newRenderer)
148 return; 122 return;
149 123
150 RenderObject* parentRenderer = this->parentRenderer(); 124 RenderObject* parentRenderer = this->parentRenderer();
151 125
152 if (!parentRenderer->isChildAllowed(newRenderer, &style)) { 126 if (!parentRenderer->isChildAllowed(newRenderer, &style)) {
153 newRenderer->destroy(); 127 newRenderer->destroy();
154 return; 128 return;
155 } 129 }
156 130
157 // Make sure the RenderObject already knows it is going to be added to a Ren derFlowThread before we set the style 131 // Make sure the RenderObject already knows it is going to be added to a Ren derFlowThread before we set the style
158 // for the first time. Otherwise code using inRenderFlowThread() in the styl eWillChange and styleDidChange will fail. 132 // for the first time. Otherwise code using inRenderFlowThread() in the styl eWillChange and styleDidChange will fail.
159 newRenderer->setFlowThreadState(parentRenderer->flowThreadState()); 133 newRenderer->setFlowThreadState(parentRenderer->flowThreadState());
160 134
161 RenderObject* nextRenderer = this->nextRenderer(); 135 RenderObject* nextRenderer = this->nextRenderer();
162 element->setRenderer(newRenderer); 136 m_node->setRenderer(newRenderer);
163 newRenderer->setStyle(&style); // setStyle() can depend on renderer() alread y being set. 137 newRenderer->setStyle(&style); // setStyle() can depend on renderer() alread y being set.
164 138
165 if (Fullscreen::isActiveFullScreenElement(*element)) { 139 if (Fullscreen::isActiveFullScreenElement(*m_node)) {
166 newRenderer = RenderFullScreen::wrapRenderer(newRenderer, parentRenderer , &element->document()); 140 newRenderer = RenderFullScreen::wrapRenderer(newRenderer, parentRenderer , &m_node->document());
167 if (!newRenderer) 141 if (!newRenderer)
168 return; 142 return;
169 } 143 }
170 144
171 // Note: Adding newRenderer instead of renderer(). renderer() may be a child of newRenderer. 145 // Note: Adding newRenderer instead of renderer(). renderer() may be a child of newRenderer.
172 parentRenderer->addChild(newRenderer, nextRenderer); 146 parentRenderer->addChild(newRenderer, nextRenderer);
173 } 147 }
174 148
175 void RenderTreeBuilder::createRendererForTextIfNeeded() 149 void RenderTreeBuilderForText::createRenderer()
176 { 150 {
177 ASSERT(!m_node->renderer()); 151 RenderObject* parentRenderer = this->parentRenderer();
152 RenderStyle* style = parentRenderer->style();
178 153
179 if (!shouldCreateRenderer()) 154 ASSERT(m_node->textRendererIsNeeded(*style, *parentRenderer));
180 return;
181 155
182 Text* textNode = toText(m_node); 156 RenderText* newRenderer = m_node->createTextRenderer(style);
183 RenderObject* parentRenderer = this->parentRenderer(); 157 if (!parentRenderer->isChildAllowed(newRenderer, style)) {
184
185 m_style = parentRenderer->style();
186
187 if (!textNode->textRendererIsNeeded(*m_style, *parentRenderer))
188 return;
189
190 RenderText* newRenderer = textNode->createTextRenderer(m_style.get());
191 if (!parentRenderer->isChildAllowed(newRenderer, m_style.get())) {
192 newRenderer->destroy(); 158 newRenderer->destroy();
193 return; 159 return;
194 } 160 }
195 161
196 // Make sure the RenderObject already knows it is going to be added to a Ren derFlowThread before we set the style 162 // Make sure the RenderObject already knows it is going to be added to a Ren derFlowThread before we set the style
197 // for the first time. Otherwise code using inRenderFlowThread() in the styl eWillChange and styleDidChange will fail. 163 // for the first time. Otherwise code using inRenderFlowThread() in the styl eWillChange and styleDidChange will fail.
198 newRenderer->setFlowThreadState(parentRenderer->flowThreadState()); 164 newRenderer->setFlowThreadState(parentRenderer->flowThreadState());
199 165
200 RenderObject* nextRenderer = this->nextRenderer(); 166 RenderObject* nextRenderer = this->nextRenderer();
201 textNode->setRenderer(newRenderer); 167 m_node->setRenderer(newRenderer);
202 // Parent takes care of the animations, no need to call setAnimatableStyle. 168 // Parent takes care of the animations, no need to call setAnimatableStyle.
203 newRenderer->setStyle(m_style.release()); 169 newRenderer->setStyle(style);
204 parentRenderer->addChild(newRenderer, nextRenderer); 170 parentRenderer->addChild(newRenderer, nextRenderer);
205 } 171 }
206 172
207 } 173 }
OLDNEW
« no previous file with comments | « Source/core/dom/RenderTreeBuilder.h ('k') | Source/core/dom/Text.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698