Changeset 154806 in webkit
- Timestamp:
- Aug 29, 2013 5:25:23 AM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r154802 r154806 1 2013-08-29 Antti Koivisto <antti@apple.com> 2 3 Move element renderer creation out of NodeRenderingContext 4 https://bugs.webkit.org/show_bug.cgi?id=120461 5 6 Reviewed by Andreas Kling. 7 8 Move NodeRenderingContext::createRendererIfNeeded() and the related utility functions to StyleResolveTree. 9 10 Tighten typing and constness. Refactor sligthly to be more understandable. 11 12 * dom/Element.cpp: 13 (WebCore::Element::shouldMoveToFlowThread): 14 * dom/Element.h: 15 * dom/NodeRenderingContext.cpp: 16 (WebCore::NodeRenderingContext::NodeRenderingContext): 17 (WebCore::NodeRenderingContext::nextRenderer): 18 (WebCore::NodeRenderingContext::previousRenderer): 19 (WebCore::NodeRenderingContext::parentRenderer): 20 * dom/NodeRenderingContext.h: 21 * dom/PseudoElement.h: 22 * style/StyleResolveTree.cpp: 23 (WebCore::Style::nextSiblingRenderer): 24 (WebCore::Style::shouldCreateRenderer): 25 (WebCore::Style::elementInsideRegionNeedsRenderer): 26 (WebCore::Style::moveToFlowThreadIfNeeded): 27 (WebCore::Style::createRendererIfNeeded): 28 (WebCore::Style::attachRenderTree): 29 * svg/SVGElement.cpp: 30 (WebCore::SVGElement::shouldMoveToFlowThread): 31 * svg/SVGElement.h: 32 1 33 2013-08-28 Chris Fleizach <cfleizach@apple.com> 2 34 -
trunk/Source/WebCore/dom/Element.cpp
r154686 r154806 2678 2678 #if ENABLE(CSS_REGIONS) 2679 2679 2680 bool Element::shouldMoveToFlowThread(RenderStyle* styleToUse) const 2681 { 2682 ASSERT(styleToUse); 2683 2680 bool Element::shouldMoveToFlowThread(const RenderStyle& styleToUse) const 2681 { 2684 2682 #if ENABLE(FULLSCREEN_API) 2685 2683 if (document()->webkitIsFullScreen() && document()->webkitCurrentFullScreenElement() == this) … … 2690 2688 return false; 2691 2689 2692 if (styleToUse ->flowThread().isEmpty())2690 if (styleToUse.flowThread().isEmpty()) 2693 2691 return false; 2694 2692 -
trunk/Source/WebCore/dom/Element.h
r154778 r154806 526 526 527 527 #if ENABLE(CSS_REGIONS) 528 virtual bool shouldMoveToFlowThread( RenderStyle*) const;528 virtual bool shouldMoveToFlowThread(const RenderStyle&) const; 529 529 530 530 const AtomicString& webkitRegionOverset() const; -
trunk/Source/WebCore/dom/NodeRenderingContext.cpp
r154738 r154806 55 55 NodeRenderingContext::NodeRenderingContext(Node* node) 56 56 : m_node(node) 57 , m_parentFlowRenderer(0)58 {59 m_renderingParent = NodeRenderingTraversal::parent(node);60 }61 62 NodeRenderingContext::NodeRenderingContext(Node* node, RenderStyle* style)63 : m_node(node)64 , m_renderingParent(0)65 , m_style(style)66 , m_parentFlowRenderer(0)67 {68 }69 70 NodeRenderingContext::NodeRenderingContext(Node* node, const Style::AttachContext& context)71 : m_node(node)72 , m_style(context.resolvedStyle)73 , m_parentFlowRenderer(0)74 57 { 75 58 m_renderingParent = NodeRenderingTraversal::parent(node); … … 112 95 #endif 113 96 114 if (m_parentFlowRenderer)115 return m_parentFlowRenderer->nextRendererForNode(m_node);116 117 97 // Avoid an O(N^2) problem with this function by not checking for 118 98 // nextRenderer() when the parent element hasn't attached yet. … … 140 120 ASSERT(!m_node->isElementNode() || !toElement(m_node)->isInTopLayer()); 141 121 #endif 142 143 if (m_parentFlowRenderer)144 return m_parentFlowRenderer->previousRendererForNode(m_node);145 122 146 123 // FIXME: We should have the same O(N^2) avoidance as nextRenderer does … … 174 151 #endif 175 152 176 if (m_parentFlowRenderer)177 return m_parentFlowRenderer;178 179 153 return m_renderingParent ? m_renderingParent->renderer() : 0; 180 }181 182 bool NodeRenderingContext::shouldCreateRenderer() const183 {184 if (!m_node->document()->shouldCreateRenderers())185 return false;186 if (!m_renderingParent)187 return false;188 RenderObject* parentRenderer = this->parentRenderer();189 if (!parentRenderer)190 return false;191 if (!parentRenderer->canHaveChildren() && !(m_node->isPseudoElement() && parentRenderer->canHaveGeneratedChildren()))192 return false;193 if (!m_renderingParent->childShouldCreateRenderer(m_node))194 return false;195 return true;196 }197 198 // Check the specific case of elements that are children of regions but are flowed into a flow thread themselves.199 bool NodeRenderingContext::elementInsideRegionNeedsRenderer()200 {201 bool elementInsideRegionNeedsRenderer = false;202 203 #if ENABLE(CSS_REGIONS)204 Element* element = toElement(m_node);205 RenderObject* parentRenderer = this->parentRenderer();206 if ((parentRenderer && !parentRenderer->canHaveChildren() && parentRenderer->isRenderRegion())207 || (!parentRenderer && element->parentElement() && element->parentElement()->isInsideRegion())) {208 209 if (!m_style)210 m_style = element->styleForRenderer();211 212 elementInsideRegionNeedsRenderer = element->shouldMoveToFlowThread(m_style.get());213 214 // Children of this element will only be allowed to be flowed into other flow-threads if display is NOT none.215 if (element->rendererIsNeeded(*m_style))216 element->setIsInsideRegion(true);217 }218 #endif219 220 return elementInsideRegionNeedsRenderer;221 }222 223 void NodeRenderingContext::moveToFlowThreadIfNeeded()224 {225 #if ENABLE(CSS_REGIONS)226 Element* element = toElement(m_node);227 228 if (!element->shouldMoveToFlowThread(m_style.get()))229 return;230 231 ASSERT(m_node->document()->renderView());232 FlowThreadController& flowThreadController = m_node->document()->renderView()->flowThreadController();233 m_parentFlowRenderer = &flowThreadController.ensureRenderFlowThreadWithName(m_style->flowThread());234 flowThreadController.registerNamedFlowContentNode(m_node, m_parentFlowRenderer);235 #endif236 }237 238 void NodeRenderingContext::createRendererForElementIfNeeded()239 {240 ASSERT(!m_node->renderer());241 242 Element* element = toElement(m_node);243 244 element->setIsInsideRegion(false);245 246 if (!shouldCreateRenderer() && !elementInsideRegionNeedsRenderer())247 return;248 249 if (!m_style)250 m_style = element->styleForRenderer();251 ASSERT(m_style);252 253 moveToFlowThreadIfNeeded();254 255 if (!element->rendererIsNeeded(*m_style))256 return;257 258 RenderObject* parentRenderer = this->parentRenderer();259 RenderObject* nextRenderer = this->nextRenderer();260 261 Document* document = element->document();262 RenderObject* newRenderer = element->createRenderer(document->renderArena(), m_style.get());263 if (!newRenderer)264 return;265 if (!parentRenderer->isChildAllowed(newRenderer, m_style.get())) {266 newRenderer->destroy();267 return;268 }269 270 // Make sure the RenderObject already knows it is going to be added to a RenderFlowThread before we set the style271 // for the first time. Otherwise code using inRenderFlowThread() in the styleWillChange and styleDidChange will fail.272 newRenderer->setFlowThreadState(parentRenderer->flowThreadState());273 274 element->setRenderer(newRenderer);275 newRenderer->setAnimatableStyle(m_style.release()); // setAnimatableStyle() can depend on renderer() already being set.276 277 #if ENABLE(FULLSCREEN_API)278 if (document->webkitIsFullScreen() && document->webkitCurrentFullScreenElement() == element) {279 newRenderer = RenderFullScreen::wrapRenderer(newRenderer, parentRenderer, document);280 if (!newRenderer)281 return;282 }283 #endif284 // Note: Adding newRenderer instead of renderer(). renderer() may be a child of newRenderer.285 parentRenderer->addChild(newRenderer, nextRenderer);286 154 } 287 155 -
trunk/Source/WebCore/dom/NodeRenderingContext.h
r154738 r154806 28 28 29 29 #include "NodeRenderingTraversal.h" 30 #include "StyleResolveTree.h"31 30 32 31 #include <wtf/Noncopyable.h> … … 37 36 38 37 class ContainerNode; 39 class Document;40 class InsertionPoint;41 38 class Node; 42 class RenderNamedFlowThread;43 39 class RenderObject; 44 class RenderStyle;45 40 46 41 class NodeRenderingContext { 47 42 public: 48 43 explicit NodeRenderingContext(Node*); 49 NodeRenderingContext(Node*, RenderStyle*);50 NodeRenderingContext(Node*, const Style::AttachContext&);51 44 ~NodeRenderingContext(); 52 53 void createRendererForElementIfNeeded();54 45 55 46 Node* node() const; … … 60 51 RenderObject* previousRenderer() const; 61 52 62 const RenderStyle* style() const;63 64 53 private: 65 bool shouldCreateRenderer() const;66 void moveToFlowThreadIfNeeded();67 bool elementInsideRegionNeedsRenderer();68 69 54 Node* m_node; 70 55 ContainerNode* m_renderingParent; 71 RefPtr<RenderStyle> m_style;72 RenderNamedFlowThread* m_parentFlowRenderer;73 56 }; 74 57 … … 83 66 } 84 67 85 inline const RenderStyle* NodeRenderingContext::style() const86 {87 return m_style.get();88 }89 90 68 } // namespace WebCore 91 69 -
trunk/Source/WebCore/dom/PseudoElement.h
r154358 r154806 53 53 // cannot be directly collected into a named flow. 54 54 #if ENABLE(CSS_REGIONS) 55 virtual bool shouldMoveToFlowThread( RenderStyle*) const OVERRIDE { return false; }55 virtual bool shouldMoveToFlowThread(const RenderStyle&) const OVERRIDE { return false; } 56 56 #endif 57 57 -
trunk/Source/WebCore/style/StyleResolveTree.cpp
r154746 r154806 31 31 #include "ElementRareData.h" 32 32 #include "ElementTraversal.h" 33 #include "FlowThreadController.h" 33 34 #include "NodeRenderStyle.h" 34 35 #include "NodeRenderingContext.h" 35 36 #include "NodeTraversal.h" 37 #include "RenderFullScreen.h" 38 #include "RenderNamedFlowThread.h" 36 39 #include "RenderObject.h" 37 40 #include "RenderText.h" … … 105 108 } 106 109 107 static void createRendererIfNeeded(Element* element, const AttachContext& context)108 {109 NodeRenderingContext(element, context).createRendererForElementIfNeeded();110 }111 112 110 static bool isRendererReparented(const RenderObject* renderer) 113 111 { … … 117 115 return true; 118 116 return false; 117 } 118 119 static RenderObject* nextSiblingRenderer(const Element& element, const ContainerNode* renderingParentNode) 120 { 121 // Avoid an O(N^2) problem with this function by not checking for 122 // nextRenderer() when the parent element hasn't attached yet. 123 // FIXME: Why would we get here anyway if parent is not attached? 124 if (renderingParentNode && !renderingParentNode->attached()) 125 return 0; 126 for (Node* sibling = NodeRenderingTraversal::nextSibling(&element); sibling; sibling = NodeRenderingTraversal::nextSibling(sibling)) { 127 RenderObject* renderer = sibling->renderer(); 128 if (renderer && !isRendererReparented(renderer)) 129 return renderer; 130 } 131 return 0; 132 } 133 134 static bool shouldCreateRenderer(const Element& element, const ContainerNode* renderingParent) 135 { 136 if (!element.document()->shouldCreateRenderers()) 137 return false; 138 if (!renderingParent) 139 return false; 140 RenderObject* parentRenderer = renderingParent->renderer(); 141 if (!parentRenderer) 142 return false; 143 if (!parentRenderer->canHaveChildren() && !(element.isPseudoElement() && parentRenderer->canHaveGeneratedChildren())) 144 return false; 145 if (!renderingParent->childShouldCreateRenderer(&element)) 146 return false; 147 return true; 148 } 149 150 // Check the specific case of elements that are children of regions but are flowed into a flow thread themselves. 151 static bool elementInsideRegionNeedsRenderer(Element& element, const ContainerNode* renderingParentNode, RefPtr<RenderStyle>& style) 152 { 153 #if ENABLE(CSS_REGIONS) 154 const RenderObject* parentRenderer = renderingParentNode ? renderingParentNode->renderer() : 0; 155 156 bool parentIsRegion = parentRenderer && !parentRenderer->canHaveChildren() && parentRenderer->isRenderRegion(); 157 bool parentIsNonRenderedInsideRegion = !parentRenderer && element.parentElement() && element.parentElement()->isInsideRegion(); 158 if (!parentIsRegion && !parentIsNonRenderedInsideRegion) 159 return false; 160 161 if (!style) 162 style = element.styleForRenderer(); 163 164 // Children of this element will only be allowed to be flowed into other flow-threads if display is NOT none. 165 if (element.rendererIsNeeded(*style)) 166 element.setIsInsideRegion(true); 167 168 if (element.shouldMoveToFlowThread(*style)) 169 return true; 170 #endif 171 return false; 172 } 173 174 static RenderNamedFlowThread* moveToFlowThreadIfNeeded(Element& element, const RenderStyle& style) 175 { 176 if (!element.shouldMoveToFlowThread(style)) 177 return 0; 178 FlowThreadController& flowThreadController = element.document()->renderView()->flowThreadController(); 179 RenderNamedFlowThread& parentFlowRenderer = flowThreadController.ensureRenderFlowThreadWithName(style.flowThread()); 180 flowThreadController.registerNamedFlowContentNode(&element, &parentFlowRenderer); 181 return &parentFlowRenderer; 182 } 183 184 static void createRendererIfNeeded(Element& element, const AttachContext& context) 185 { 186 ASSERT(!element.renderer()); 187 188 Document& document = *element.document(); 189 ContainerNode* renderingParentNode = NodeRenderingTraversal::parent(&element); 190 191 RefPtr<RenderStyle> style = context.resolvedStyle; 192 193 element.setIsInsideRegion(false); 194 195 if (!shouldCreateRenderer(element, renderingParentNode) && !elementInsideRegionNeedsRenderer(element, renderingParentNode, style)) 196 return; 197 198 if (!style) 199 style = element.styleForRenderer(); 200 201 RenderNamedFlowThread* parentFlowRenderer = 0; 202 #if ENABLE(CSS_REGIONS) 203 parentFlowRenderer = moveToFlowThreadIfNeeded(element, *style); 204 #endif 205 206 if (!element.rendererIsNeeded(*style)) 207 return; 208 209 RenderObject* parentRenderer; 210 RenderObject* nextRenderer; 211 if (parentFlowRenderer) { 212 parentRenderer = parentFlowRenderer; 213 nextRenderer = parentFlowRenderer->nextRendererForNode(&element); 214 } else { 215 parentRenderer = renderingParentNode->renderer(); 216 nextRenderer = nextSiblingRenderer(element, renderingParentNode); 217 } 218 219 RenderObject* newRenderer = element.createRenderer(document.renderArena(), style.get()); 220 if (!newRenderer) 221 return; 222 if (!parentRenderer->isChildAllowed(newRenderer, style.get())) { 223 newRenderer->destroy(); 224 return; 225 } 226 227 // Make sure the RenderObject already knows it is going to be added to a RenderFlowThread before we set the style 228 // for the first time. Otherwise code using inRenderFlowThread() in the styleWillChange and styleDidChange will fail. 229 newRenderer->setFlowThreadState(parentRenderer->flowThreadState()); 230 231 element.setRenderer(newRenderer); 232 newRenderer->setAnimatableStyle(style.release()); // setAnimatableStyle() can depend on renderer() already being set. 233 234 #if ENABLE(FULLSCREEN_API) 235 if (document.webkitIsFullScreen() && document.webkitCurrentFullScreenElement() == &element) { 236 newRenderer = RenderFullScreen::wrapRenderer(newRenderer, parentRenderer, &document); 237 if (!newRenderer) 238 return; 239 } 240 #endif 241 // Note: Adding newRenderer instead of renderer(). renderer() may be a child of newRenderer. 242 parentRenderer->addChild(newRenderer, nextRenderer); 119 243 } 120 244 … … 342 466 current->willAttachRenderers(); 343 467 344 createRendererIfNeeded( current, context);468 createRendererIfNeeded(*current, context); 345 469 346 470 if (current->parentElement() && current->parentElement()->isInCanvasSubtree()) -
trunk/Source/WebCore/svg/SVGElement.cpp
r154769 r154806 570 570 571 571 #if ENABLE(CSS_REGIONS) 572 bool SVGElement::shouldMoveToFlowThread( RenderStyle*styleToUse) const572 bool SVGElement::shouldMoveToFlowThread(const RenderStyle& styleToUse) const 573 573 { 574 574 // Allow only svg root elements to be directly collected by a render flow thread. -
trunk/Source/WebCore/svg/SVGElement.h
r154481 r154806 136 136 137 137 #if ENABLE(CSS_REGIONS) 138 virtual bool shouldMoveToFlowThread( RenderStyle*) const OVERRIDE;138 virtual bool shouldMoveToFlowThread(const RenderStyle&) const OVERRIDE; 139 139 #endif 140 140
Note: See TracChangeset
for help on using the changeset viewer.