Changeset 165465 in webkit
- Timestamp:
- Mar 12, 2014, 3:18:47 AM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r165464 r165465 1 2014-03-12 Antti Koivisto <antti@apple.com> 2 3 Don't use NodeRenderingTraversal for pseudo elements 4 https://bugs.webkit.org/show_bug.cgi?id=130091 5 6 Reviewed by Andreas Kling. 7 8 Make traversing during style resolve more comprehensible by handling before/after pseudo elements explicitly. 9 10 With this patch NodeRenderingTraversal is only needed for InsertionPoints (which are nothing but an implementation 11 detail of the <details> element at this point). 12 13 * dom/Element.cpp: 14 (WebCore::shouldUseNodeRenderingTraversalSlowPath): 15 16 PseudoElements don't need the slow path anymore. 17 18 (WebCore::Element::setBeforePseudoElement): 19 (WebCore::Element::setAfterPseudoElement): 20 (WebCore::Element::clearBeforePseudoElement): 21 (WebCore::Element::clearAfterPseudoElement): 22 * dom/NodeRenderingTraversal.cpp: 23 (WebCore::NodeRenderingTraversal::traverseParent): 24 (WebCore::NodeRenderingTraversal::firstChildSlow): 25 (WebCore::NodeRenderingTraversal::nextSiblingSlow): 26 (WebCore::NodeRenderingTraversal::previousSiblingSlow): 27 * dom/NodeRenderingTraversal.h: 28 (WebCore::NodeRenderingTraversal::firstChild): 29 * style/StyleResolveTree.cpp: 30 (WebCore::Style::nextSiblingRenderer): 31 32 Add ::before/::after pseudo element handling here. 33 34 (WebCore::Style::shouldCreateRenderer): 35 (WebCore::Style::elementInsideRegionNeedsRenderer): 36 (WebCore::Style::createRendererIfNeeded): 37 (WebCore::Style::previousSiblingRenderer): 38 39 Add ::before pseudo element handling here (text node can't be ::after). 40 41 (WebCore::Style::reattachTextRenderersForWhitespaceOnlySiblingsAfterAttachIfNeeded): 42 (WebCore::Style::textRendererIsNeeded): 43 (WebCore::Style::createTextRendererIfNeeded): 44 (WebCore::Style::attachTextRenderer): 45 (WebCore::Style::updateTextRendererAfterContentChange): 46 (WebCore::Style::attachChildren): 47 (WebCore::Style::attachDistributedChildren): 48 49 Handle InsertionPoints in one place. 50 51 (WebCore::Style::attachShadowRoot): 52 (WebCore::Style::attachBeforeOrAfterPseudoElementIfNeeded): 53 (WebCore::Style::attachRenderTree): 54 (WebCore::Style::resolveLocal): 55 (WebCore::Style::updateTextStyle): 56 (WebCore::Style::resolveShadowTree): 57 (WebCore::Style::updateBeforeOrAfterPseudoElement): 58 (WebCore::Style::resolveTree): 59 60 Pass the rendering parent around to various functions instead of determining it repeatedly by calling 61 NodeRenderingTraversal::parent. It is always the same for all direct children being resolved and generally just 62 the parent element. 63 1 64 2014-03-12 Frédéric Wang <fred.wang@free.fr> 2 65 -
trunk/Source/WebCore/css/StyleResolver.cpp
r164869 r165465 93 93 #include "PageRuleCollector.h" 94 94 #include "Pair.h" 95 #include "PseudoElement.h" 95 96 #include "QuotesData.h" 96 97 #include "Rect.h" … … 411 412 412 413 if (e) { 413 m_parentNode = NodeRenderingTraversal::parent(e);414 m_parentNode = e->isPseudoElement() ? toPseudoElement(e)->hostElement() : NodeRenderingTraversal::parent(e); 414 415 bool resetStyleInheritance = hasShadowRootParent(*e) && toShadowRoot(e->parentNode())->resetStyleInheritance(); 415 416 m_parentStyle = resetStyleInheritance ? 0 : -
trunk/Source/WebCore/dom/Element.cpp
r165185 r165465 1411 1411 if (element.isShadowRoot()) 1412 1412 return true; 1413 if (element.isPseudoElement() || element.beforePseudoElement() || element.afterPseudoElement())1414 return true;1415 1413 return element.isInsertionPoint() || element.shadowRoot(); 1416 1414 } … … 2251 2249 { 2252 2250 ensureElementRareData().setBeforePseudoElement(element); 2253 resetNeedsNodeRenderingTraversalSlowPath();2254 2251 } 2255 2252 … … 2257 2254 { 2258 2255 ensureElementRareData().setAfterPseudoElement(element); 2259 resetNeedsNodeRenderingTraversalSlowPath();2260 2256 } 2261 2257 … … 2276 2272 disconnectPseudoElement(elementRareData()->beforePseudoElement()); 2277 2273 elementRareData()->setBeforePseudoElement(nullptr); 2278 resetNeedsNodeRenderingTraversalSlowPath();2279 2274 } 2280 2275 … … 2285 2280 disconnectPseudoElement(elementRareData()->afterPseudoElement()); 2286 2281 elementRareData()->setAfterPseudoElement(nullptr); 2287 resetNeedsNodeRenderingTraversalSlowPath();2288 2282 } 2289 2283 -
trunk/Source/WebCore/dom/NodeRenderingTraversal.cpp
r155292 r165465 30 30 31 31 #include "InsertionPoint.h" 32 #include "PseudoElement.h"33 32 #include "ShadowRoot.h" 34 33 … … 122 121 static ContainerNode* traverseParent(const Node* node, ShadowRootCrossing shadowRootCrossing) 123 122 { 124 if (node->isPseudoElement())125 return toPseudoElement(node)->hostElement();126 127 123 if (shadowRootCrossing == DontCrossShadowRoot && node->isShadowRoot()) 128 124 return 0; … … 223 219 } 224 220 221 Node* firstChildSlow(const Node* node) 222 { 223 ASSERT(!node->isShadowRoot()); 224 225 return traverseFirstChild(node, DontCrossShadowRoot); 226 } 227 225 228 Node* nextSiblingSlow(const Node* node) 226 229 { 227 230 ASSERT(!node->isShadowRoot()); 228 231 229 // FIXME: Why do these functions deal with before/after when other code here doesn't? 230 Node* nextSibling = 0; 231 if (node->isBeforePseudoElement()) { 232 nextSibling = traverseParent(node, CrossShadowRoot); 233 nextSibling = traverseFirstChild(nextSibling, CrossShadowRoot); 234 } else 235 nextSibling = traverseNextSibling(node); 236 237 if (nextSibling || node->isAfterPseudoElement()) 238 return nextSibling; 239 240 Node* parent = traverseParent(node, CrossShadowRoot); 241 if (parent && parent->isElementNode()) 242 return toElement(parent)->afterPseudoElement(); 243 244 return 0; 232 return traverseNextSibling(node); 245 233 } 246 234 … … 249 237 ASSERT(!node->isShadowRoot()); 250 238 251 Node* previousSibling = 0; 252 if (node->isAfterPseudoElement()) { 253 ContainerNode* parent = traverseParent(node, CrossShadowRoot); 254 previousSibling = traverseLastChild(parent, CrossShadowRoot); 255 } else 256 previousSibling = traversePreviousSibling(node); 257 258 if (previousSibling || node->isBeforePseudoElement()) 259 return previousSibling; 260 261 ContainerNode* parent = traverseParent(node, CrossShadowRoot); 262 if (parent && parent->isElementNode()) 263 return toElement(parent)->beforePseudoElement(); 264 265 return 0; 239 return traversePreviousSibling(node); 266 240 } 267 241 -
trunk/Source/WebCore/dom/NodeRenderingTraversal.h
r155303 r165465 36 36 37 37 ContainerNode* parent(const Node*); 38 Node* firstChild(const Node*); 38 39 Node* nextSibling(const Node*); 39 40 Node* previousSibling(const Node*); … … 45 46 46 47 ContainerNode* parentSlow(const Node*); 48 Node* firstChildSlow(const Node*); 47 49 Node* nextSiblingSlow(const Node*); 48 50 Node* previousSiblingSlow(const Node*); … … 50 52 inline ContainerNode* parent(const Node* node) 51 53 { 54 ASSERT(!node->isPseudoElement()); 52 55 if (node->needsNodeRenderingTraversalSlowPath()) 53 56 return parentSlow(node); … … 57 60 } 58 61 62 inline Node* firstChild(const Node* node) 63 { 64 ASSERT(!node->isPseudoElement()); 65 if (node->needsNodeRenderingTraversalSlowPath()) 66 return firstChildSlow(node); 67 68 ASSERT(nextSiblingSlow(node) == node->nextSibling()); 69 return node->firstChild(); 70 } 71 59 72 inline Node* nextSibling(const Node* node) 60 73 { 74 ASSERT(!node->isPseudoElement()); 61 75 if (node->needsNodeRenderingTraversalSlowPath()) 62 76 return nextSiblingSlow(node); … … 68 82 inline Node* previousSibling(const Node* node) 69 83 { 84 ASSERT(!node->isPseudoElement()); 70 85 if (node->needsNodeRenderingTraversalSlowPath()) 71 86 return previousSiblingSlow(node); -
trunk/Source/WebCore/style/StyleResolveTree.cpp
r163969 r165465 61 61 enum DetachType { NormalDetach, ReattachDetach }; 62 62 63 static void attachRenderTree(Element&, PassRefPtr<RenderStyle>);64 static void attachTextRenderer(Text& );63 static void attachRenderTree(Element&, ContainerNode& renderingParentNode, PassRefPtr<RenderStyle>); 64 static void attachTextRenderer(Text&, ContainerNode& renderingParentNode); 65 65 static void detachRenderTree(Element&, DetachType); 66 static void resolveTree(Element&, C hange);66 static void resolveTree(Element&, ContainerNode& renderingParentNode, Change); 67 67 68 68 Change determineChange(const RenderStyle* s1, const RenderStyle* s2) … … 127 127 } 128 128 129 static RenderObject* nextSiblingRenderer(const Element& element, const ContainerNode* renderingParentNode) 130 { 129 static RenderObject* nextSiblingRenderer(const Node& node, const ContainerNode& renderingParentNode) 130 { 131 if (!renderingParentNode.isElementNode()) 132 return nullptr; 133 const Element& renderingParentElement = toElement(renderingParentNode); 131 134 // Avoid an O(N^2) problem with this function by not checking for 132 135 // nextRenderer() when the parent element hasn't attached yet. 133 136 // FIXME: Why would we get here anyway if parent is not attached? 134 if ( renderingParentNode && !renderingParentNode->renderer())137 if (!renderingParentElement.renderer()) 135 138 return nullptr; 136 for (Node* sibling = NodeRenderingTraversal::nextSibling(&element); sibling; sibling = NodeRenderingTraversal::nextSibling(sibling)) { 139 if (node.isAfterPseudoElement()) 140 return nullptr; 141 Node* sibling = node.isBeforePseudoElement() ? NodeRenderingTraversal::firstChild(&renderingParentNode) : NodeRenderingTraversal::nextSibling(&node); 142 for (; sibling; sibling = NodeRenderingTraversal::nextSibling(sibling)) { 137 143 RenderObject* renderer = sibling->renderer(); 138 144 if (renderer && !isRendererReparented(renderer)) 139 145 return renderer; 140 146 } 147 if (PseudoElement* after = renderingParentElement.afterPseudoElement()) 148 return after->renderer(); 141 149 return nullptr; 142 150 } 143 151 144 static bool shouldCreateRenderer(const Element& element, const ContainerNode *renderingParent)152 static bool shouldCreateRenderer(const Element& element, const ContainerNode& renderingParent) 145 153 { 146 154 if (!element.document().shouldCreateRenderers()) 147 155 return false; 148 if (!renderingParent) 149 return false; 150 RenderObject* parentRenderer = renderingParent->renderer(); 156 RenderObject* parentRenderer = renderingParent.renderer(); 151 157 if (!parentRenderer) 152 158 return false; 153 159 if (!parentRenderer->canHaveChildren() && !(element.isPseudoElement() && parentRenderer->canHaveGeneratedChildren())) 154 160 return false; 155 if (!renderingParent ->childShouldCreateRenderer(element))161 if (!renderingParent.childShouldCreateRenderer(element)) 156 162 return false; 157 163 return true; … … 159 165 160 166 // Check the specific case of elements that are children of regions but are flowed into a flow thread themselves. 161 static bool elementInsideRegionNeedsRenderer(Element& element, const ContainerNode *renderingParentNode, RefPtr<RenderStyle>& style)167 static bool elementInsideRegionNeedsRenderer(Element& element, const ContainerNode& renderingParentNode, RefPtr<RenderStyle>& style) 162 168 { 163 169 #if ENABLE(CSS_REGIONS) 164 170 // The parent of a region should always be an element. 165 const RenderElement* parentRenderer = renderingParentNode ? renderingParentNode->renderer() : 0;171 const RenderElement* parentRenderer = renderingParentNode.renderer(); 166 172 167 173 bool parentIsRegion = parentRenderer && !parentRenderer->canHaveChildren() && parentRenderer->isRenderNamedFlowFragmentContainer(); … … 199 205 #endif 200 206 201 static void createRendererIfNeeded(Element& element, PassRefPtr<RenderStyle> resolvedStyle)207 static void createRendererIfNeeded(Element& element, ContainerNode& renderingParentNode, PassRefPtr<RenderStyle> resolvedStyle) 202 208 { 203 209 ASSERT(!element.renderer()); 204 205 ContainerNode* renderingParentNode = NodeRenderingTraversal::parent(&element);206 210 207 211 RefPtr<RenderStyle> style = resolvedStyle; … … 230 234 } else { 231 235 // FIXME: Make this path Element only, handle the root special case separately. 232 parentRenderer = renderingParentNode ->renderer();236 parentRenderer = renderingParentNode.renderer(); 233 237 nextRenderer = nextSiblingRenderer(element, renderingParentNode); 234 238 } … … 276 280 return renderer; 277 281 } 278 return 0; 279 } 280 281 static RenderObject* nextSiblingRenderer(const Text& textNode) 282 { 283 if (textNode.renderer()) 284 return textNode.renderer()->nextSibling(); 285 for (Node* sibling = NodeRenderingTraversal::nextSibling(&textNode); sibling; sibling = NodeRenderingTraversal::nextSibling(sibling)) { 286 RenderObject* renderer = sibling->renderer(); 287 if (renderer && !isRendererReparented(renderer)) 288 return renderer; 289 } 290 return 0; 291 } 292 293 static void reattachTextRenderersForWhitespaceOnlySiblingsAfterAttachIfNeeded(Node& current) 282 if (PseudoElement* before = textNode.parentElement()->beforePseudoElement()) 283 return before->renderer(); 284 return nullptr; 285 } 286 287 static void reattachTextRenderersForWhitespaceOnlySiblingsAfterAttachIfNeeded(Node& current, ContainerNode& renderingParentNode) 294 288 { 295 289 if (isInsertionPoint(current)) … … 297 291 // This function finds sibling text renderers where the results of textRendererIsNeeded may have changed as a result of 298 292 // the current node gaining or losing the renderer. This can only affect white space text nodes. 299 for (Node* sibling = NodeRenderingTraversal::nextSibling(¤t); sibling; sibling = NodeRenderingTraversal::nextSibling(sibling)) {293 for (Node* sibling = current.nextSibling(); sibling; sibling = sibling->nextSibling()) { 300 294 // Siblings haven't been attached yet. They will be handled normally when they are. 301 295 if (sibling->styleChangeType() == ReconstructRenderTree) … … 315 309 bool hadRenderer = whitespaceTextSibling.renderer(); 316 310 detachTextRenderer(whitespaceTextSibling); 317 attachTextRenderer(whitespaceTextSibling );311 attachTextRenderer(whitespaceTextSibling, renderingParentNode); 318 312 // No changes, futher renderers can't be affected. 319 313 if (hadRenderer == !!whitespaceTextSibling.renderer()) … … 353 347 while (first && first->isFloatingOrOutOfFlowPositioned()) 354 348 first = first->nextSibling(); 355 RenderObject* nextRenderer = nextSiblingRenderer(textNode );349 RenderObject* nextRenderer = nextSiblingRenderer(textNode, *textNode.parentNode()); 356 350 if (!first || nextRenderer == first) { 357 351 // Whitespace at the start of a block just goes away. Don't even make a render object for this text. … … 362 356 } 363 357 364 static void createTextRendererIfNeeded(Text& textNode )358 static void createTextRendererIfNeeded(Text& textNode, ContainerNode& renderingParentNode) 365 359 { 366 360 ASSERT(!textNode.renderer()); 367 361 368 ContainerNode* renderingParentNode = NodeRenderingTraversal::parent(&textNode); 369 if (!renderingParentNode) 370 return; 371 RenderElement* parentRenderer = renderingParentNode->renderer(); 362 RenderElement* parentRenderer = renderingParentNode.renderer(); 372 363 if (!parentRenderer || !parentRenderer->canHaveChildren()) 373 364 return; 374 if (!renderingParentNode ->childShouldCreateRenderer(textNode))365 if (!renderingParentNode.childShouldCreateRenderer(textNode)) 375 366 return; 376 367 … … 390 381 newRenderer->setFlowThreadState(parentRenderer->flowThreadState()); 391 382 392 RenderObject* nextRenderer = nextSiblingRenderer(textNode );383 RenderObject* nextRenderer = nextSiblingRenderer(textNode, renderingParentNode); 393 384 textNode.setRenderer(newRenderer.get()); 394 385 // Parent takes care of the animations, no need to call setAnimatableStyle. … … 396 387 } 397 388 398 void attachTextRenderer(Text& textNode )399 { 400 createTextRendererIfNeeded(textNode );389 void attachTextRenderer(Text& textNode, ContainerNode& renderingParent) 390 { 391 createTextRendererIfNeeded(textNode, renderingParent); 401 392 402 393 textNode.clearNeedsStyleRecalc(); … … 413 404 { 414 405 RenderText* textRenderer = textNode.renderer(); 406 ContainerNode* renderingParentNode = NodeRenderingTraversal::parent(&textNode); 407 if (!renderingParentNode) 408 return; 415 409 if (!textRenderer) { 416 attachTextRenderer(textNode); 417 reattachTextRenderersForWhitespaceOnlySiblingsAfterAttachIfNeeded(textNode); 418 return; 419 } 420 RenderObject* parentRenderer = NodeRenderingTraversal::parent(&textNode)->renderer(); 421 if (!textRendererIsNeeded(textNode, *parentRenderer, textRenderer->style())) { 410 attachTextRenderer(textNode, *renderingParentNode); 411 reattachTextRenderersForWhitespaceOnlySiblingsAfterAttachIfNeeded(textNode, *renderingParentNode); 412 return; 413 } 414 if (!textRendererIsNeeded(textNode, *renderingParentNode->renderer(), textRenderer->style())) { 422 415 detachTextRenderer(textNode); 423 attachTextRenderer(textNode );424 reattachTextRenderersForWhitespaceOnlySiblingsAfterAttachIfNeeded(textNode );416 attachTextRenderer(textNode, *renderingParentNode); 417 reattachTextRenderersForWhitespaceOnlySiblingsAfterAttachIfNeeded(textNode, *renderingParentNode); 425 418 return; 426 419 } … … 428 421 } 429 422 430 static void attachDistributedChildren(InsertionPoint& insertionPoint) 423 static void attachChildren(ContainerNode& current, ContainerNode& renderingParentNode) 424 { 425 for (Node* child = current.firstChild(); child; child = child->nextSibling()) { 426 ASSERT((!child->renderer() || child->inNamedFlow()) || current.shadowRoot()); 427 if (child->renderer()) 428 continue; 429 if (child->isTextNode()) { 430 attachTextRenderer(*toText(child), renderingParentNode); 431 continue; 432 } 433 if (child->isElementNode()) 434 attachRenderTree(*toElement(child), renderingParentNode, nullptr); 435 } 436 } 437 438 static void attachDistributedChildren(InsertionPoint& insertionPoint, ContainerNode& renderingParentNode) 431 439 { 432 440 if (ShadowRoot* shadowRoot = insertionPoint.containingShadowRoot()) 433 441 ContentDistributor::ensureDistribution(shadowRoot); 442 434 443 for (Node* current = insertionPoint.firstDistributed(); current; current = insertionPoint.nextDistributedTo(current)) { 435 444 if (current->isTextNode()) { 436 445 if (current->renderer()) 437 446 continue; 438 attachTextRenderer(*toText(current) );447 attachTextRenderer(*toText(current), renderingParentNode); 439 448 continue; 440 449 } 441 450 if (current->isElementNode()) { 442 if (current->renderer()) 443 detachRenderTree(*toElement(current)); 444 attachRenderTree(*toElement(current), nullptr); 445 } 446 } 447 } 448 449 static void attachChildren(ContainerNode& current) 450 { 451 if (isInsertionPoint(current)) 452 attachDistributedChildren(toInsertionPoint(current)); 453 454 for (Node* child = current.firstChild(); child; child = child->nextSibling()) { 455 ASSERT((!child->renderer() || child->inNamedFlow()) || current.shadowRoot() || isInsertionPoint(current)); 456 if (child->renderer()) 457 continue; 458 if (child->isTextNode()) { 459 attachTextRenderer(*toText(child)); 460 continue; 461 } 462 if (child->isElementNode()) 463 attachRenderTree(*toElement(child), nullptr); 464 } 451 Element& currentElement = toElement(*current); 452 if (currentElement.renderer()) 453 detachRenderTree(currentElement); 454 attachRenderTree(currentElement, renderingParentNode, nullptr); 455 } 456 } 457 // Use actual children as fallback content. 458 if (!insertionPoint.hasDistribution()) 459 attachChildren(insertionPoint, renderingParentNode); 465 460 } 466 461 467 462 static void attachShadowRoot(ShadowRoot& shadowRoot) 468 463 { 469 attachChildren(shadowRoot );464 attachChildren(shadowRoot, *shadowRoot.hostElement()); 470 465 471 466 shadowRoot.clearNeedsStyleRecalc(); … … 520 515 RefPtr<PseudoElement> pseudoElement = PseudoElement::create(current, pseudoId); 521 516 setBeforeOrAfterPseudoElement(current, pseudoElement, pseudoId); 522 attachRenderTree(*pseudoElement, nullptr);523 } 524 525 static void attachRenderTree(Element& current, PassRefPtr<RenderStyle> resolvedStyle)517 attachRenderTree(*pseudoElement, current, nullptr); 518 } 519 520 static void attachRenderTree(Element& current, ContainerNode& renderingParentNode, PassRefPtr<RenderStyle> resolvedStyle) 526 521 { 527 522 PostAttachCallbackDisabler callbackDisabler(current.document()); … … 531 526 current.willAttachRenderers(); 532 527 533 createRendererIfNeeded(current, re solvedStyle);528 createRendererIfNeeded(current, renderingParentNode, resolvedStyle); 534 529 535 530 if (current.parentElement() && current.parentElement()->isInCanvasSubtree()) … … 540 535 StyleResolverParentPusher parentPusher(¤t); 541 536 542 // When a shadow root exists, it does the work of attaching the children.543 537 if (ShadowRoot* shadowRoot = current.shadowRoot()) { 544 538 parentPusher.push(); … … 547 541 parentPusher.push(); 548 542 549 attachChildren(current); 543 if (isInsertionPoint(current)) 544 attachDistributedChildren(toInsertionPoint(current), renderingParentNode); 545 else 546 attachChildren(current, current); 550 547 551 548 current.clearNeedsStyleRecalc(); … … 657 654 } 658 655 659 static Change resolveLocal(Element& current, C hange inheritedChange)656 static Change resolveLocal(Element& current, ContainerNode& renderingParentNode, Change inheritedChange) 660 657 { 661 658 Change localChange = Detach; … … 671 668 if (current.renderer() || current.inNamedFlow()) 672 669 detachRenderTree(current, ReattachDetach); 673 attachRenderTree(current, newStyle.release());674 reattachTextRenderersForWhitespaceOnlySiblingsAfterAttachIfNeeded(current );670 attachRenderTree(current, renderingParentNode, newStyle.release()); 671 reattachTextRenderersForWhitespaceOnlySiblingsAfterAttachIfNeeded(current, renderingParentNode); 675 672 676 673 return Detach; … … 703 700 } 704 701 705 static void updateTextStyle(Text& text )702 static void updateTextStyle(Text& text, ContainerNode& renderingParentNode) 706 703 { 707 704 RenderText* renderer = text.renderer(); … … 712 709 renderer->setText(text.dataImpl()); 713 710 else { 714 attachTextRenderer(text );715 reattachTextRenderersForWhitespaceOnlySiblingsAfterAttachIfNeeded(text );711 attachTextRenderer(text, renderingParentNode); 712 reattachTextRenderersForWhitespaceOnlySiblingsAfterAttachIfNeeded(text, renderingParentNode); 716 713 } 717 714 text.clearNeedsStyleRecalc(); 718 715 } 719 716 720 static void resolveShadowTree(ShadowRoot* shadowRoot, Style::Change change) 721 { 722 if (!shadowRoot) 723 return; 724 725 for (Node* child = shadowRoot->firstChild(); child; child = child->nextSibling()) { 717 static void resolveShadowTree(ShadowRoot& shadowRoot, Style::Change change) 718 { 719 for (Node* child = shadowRoot.firstChild(); child; child = child->nextSibling()) { 726 720 if (child->isTextNode()) { 727 updateTextStyle(*toText(child) );721 updateTextStyle(*toText(child), *shadowRoot.hostElement()); 728 722 continue; 729 723 } 730 724 if (child->isElementNode()) 731 resolveTree(*toElement(child), change);732 } 733 734 shadowRoot ->clearNeedsStyleRecalc();735 shadowRoot ->clearChildNeedsStyleRecalc();725 resolveTree(*toElement(child), *shadowRoot.hostElement(), change); 726 } 727 728 shadowRoot.clearNeedsStyleRecalc(); 729 shadowRoot.clearChildNeedsStyleRecalc(); 736 730 } 737 731 … … 740 734 if (PseudoElement* existingPseudoElement = beforeOrAfterPseudoElement(current, pseudoId)) { 741 735 if (needsPseudeElement(current, pseudoId)) 742 resolveTree(*existingPseudoElement, current .needsStyleRecalc() ? Force : change);736 resolveTree(*existingPseudoElement, current, current.needsStyleRecalc() ? Force : change); 743 737 else 744 738 clearBeforeOrAfterPseudoElement(current, pseudoId); … … 800 794 #endif // PLATFORM(IOS) 801 795 802 void resolveTree(Element& current, C hange change)796 void resolveTree(Element& current, ContainerNode& renderingParentNode, Change change) 803 797 { 804 798 ASSERT(change != Detach); … … 809 803 } 810 804 811 ContainerNode* renderingParentNode = NodeRenderingTraversal::parent(¤t); 812 bool hasParentStyle = renderingParentNode && renderingParentNode->renderStyle(); 805 bool hasParentStyle = renderingParentNode.renderStyle(); 813 806 bool hasDirectAdjacentRules = current.childrenAffectedByDirectAdjacentRules(); 814 807 bool hasIndirectAdjacentRules = current.childrenAffectedByForwardPositionalRules(); … … 822 815 823 816 if (hasParentStyle && (change >= Inherit || current.needsStyleRecalc())) 824 change = resolveLocal(current, change);817 change = resolveLocal(current, renderingParentNode, change); 825 818 826 819 if (change != Detach) { … … 830 823 if (change >= Inherit || shadowRoot->childNeedsStyleRecalc() || shadowRoot->needsStyleRecalc()) { 831 824 parentPusher.push(); 832 resolveShadowTree( shadowRoot, change);825 resolveShadowTree(*shadowRoot, change); 833 826 } 834 827 } … … 843 836 for (Node* child = current.firstChild(); child; child = child->nextSibling()) { 844 837 if (child->isTextNode()) { 845 updateTextStyle(*toText(child) );838 updateTextStyle(*toText(child), current); 846 839 continue; 847 840 } … … 854 847 if (change >= Inherit || childElement->childNeedsStyleRecalc() || childElement->needsStyleRecalc()) { 855 848 parentPusher.push(); 856 resolveTree(*childElement, c hange);849 resolveTree(*childElement, current, change); 857 850 } 858 851 forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules; … … 895 888 if (change < Inherit && !documentElement->childNeedsStyleRecalc() && !documentElement->needsStyleRecalc()) 896 889 return; 897 resolveTree(*documentElement, change);890 resolveTree(*documentElement, document, change); 898 891 } 899 892
Note:
See TracChangeset
for help on using the changeset viewer.