Changeset 154541 in webkit
- Timestamp:
- Aug 24, 2013, 4:09:26 AM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r154535 r154541 1 2013-08-24 Antti Koivisto <antti@apple.com> 2 3 Tighten before/after pseudo element accessors 4 https://bugs.webkit.org/show_bug.cgi?id=120204 5 6 Reviewed by Andreas Kling. 7 8 We have generic looking Element::pseudoElement(PseudoID) which only returns before/after pseudo elements. 9 10 Switch to Element::before/afterPseudoElement(), similarly for setters. 11 12 * WebCore.exp.in: 13 * css/CSSComputedStyleDeclaration.cpp: 14 (WebCore::ComputedStyleExtractor::styledNode): 15 * dom/Element.cpp: 16 (WebCore::Element::~Element): 17 (WebCore::beforeOrAfterPseudeoElement): 18 (WebCore::Element::computedStyle): 19 (WebCore::Element::updatePseudoElement): 20 (WebCore::Element::createPseudoElementIfNeeded): 21 (WebCore::Element::updateBeforePseudoElement): 22 (WebCore::Element::updateAfterPseudoElement): 23 (WebCore::Element::beforePseudoElement): 24 (WebCore::Element::afterPseudoElement): 25 (WebCore::Element::setBeforePseudoElement): 26 (WebCore::Element::setAfterPseudoElement): 27 (WebCore::disconnectPseudoElement): 28 (WebCore::Element::clearBeforePseudoElement): 29 (WebCore::Element::clearAfterPseudoElement): 30 (WebCore::Element::clearStyleDerivedDataBeforeDetachingRenderer): 31 * dom/Element.h: 32 * dom/ElementRareData.h: 33 (WebCore::ElementRareData::beforePseudoElement): 34 (WebCore::ElementRareData::afterPseudoElement): 35 (WebCore::ElementRareData::hasPseudoElements): 36 (WebCore::ElementRareData::~ElementRareData): 37 (WebCore::ElementRareData::clearBeforePseudoElement): 38 (WebCore::ElementRareData::clearAfterPseudoElement): 39 (WebCore::ElementRareData::setBeforePseudoElement): 40 (WebCore::ElementRareData::setAfterPseudoElement): 41 42 Move detach logic to Element. ElementRareData should not implement semantics. 43 44 * dom/Node.cpp: 45 (WebCore::Node::pseudoAwarePreviousSibling): 46 (WebCore::Node::pseudoAwareNextSibling): 47 (WebCore::Node::pseudoAwareFirstChild): 48 (WebCore::Node::pseudoAwareLastChild): 49 * dom/NodeRenderingTraversal.cpp: 50 (WebCore::NodeRenderingTraversal::nextSiblingSlow): 51 (WebCore::NodeRenderingTraversal::previousSiblingSlow): 52 * rendering/RenderTreeAsText.cpp: 53 (WebCore::writeCounterValuesFromChildren): 54 (WebCore::counterValueForElement): 55 * style/StyleResolveTree.cpp: 56 (WebCore::Style::attachRenderTree): 57 (WebCore::Style::resolveTree): 58 * testing/Internals.cpp: 59 (WebCore::Internals::pauseAnimationAtTimeOnPseudoElement): 60 (WebCore::Internals::pauseTransitionAtTimeOnPseudoElement): 61 1 62 2013-08-23 Simon Fraser <simon.fraser@apple.com> 2 63 -
trunk/Source/WebCore/WebCore.exp.in
r154528 r154541 1642 1642 __ZNK7WebCore7Element12getAttributeERKNS_13QualifiedNameE 1643 1643 __ZNK7WebCore7Element12hasAttributeERKN3WTF12AtomicStringE 1644 __ZNK7WebCore7Element13pseudoElementENS_8PseudoIdE 1644 __ZNK7WebCore7Element18afterPseudoElementEv 1645 __ZNK7WebCore7Element19beforePseudoElementEv 1645 1646 __ZNK7WebCore7IntRect10intersectsERKS0_ 1646 1647 __ZNK7WebCore7IntRect8containsERKS0_ -
trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp
r154401 r154541 1635 1635 if (!m_node) 1636 1636 return 0; 1637 if (m_node->isElementNode()) { 1638 if (PseudoElement* element = toElement(m_node.get())->pseudoElement(m_pseudoElementSpecifier)) 1639 return element; 1640 } 1641 return m_node.get(); 1637 if (!m_node->isElementNode()) 1638 return m_node.get(); 1639 Element* element = toElement(m_node.get()); 1640 PseudoElement* pseudoElement; 1641 if (m_pseudoElementSpecifier == BEFORE && (pseudoElement = element->beforePseudoElement())) 1642 return pseudoElement; 1643 if (m_pseudoElementSpecifier == AFTER && (pseudoElement = element->afterPseudoElement())) 1644 return pseudoElement; 1645 return element; 1642 1646 } 1643 1647 -
trunk/Source/WebCore/dom/Element.cpp
r154371 r154541 171 171 #endif 172 172 173 if (hasRareData()) { 174 ElementRareData* data = elementRareData(); 175 data->setPseudoElement(BEFORE, 0); 176 data->setPseudoElement(AFTER, 0); 177 removeShadowRoot(); 178 } 173 ASSERT(!beforePseudoElement()); 174 ASSERT(!afterPseudoElement()); 175 176 removeShadowRoot(); 179 177 180 178 if (hasSyntheticAttrChildNodes()) … … 2065 2063 } 2066 2064 2065 static PseudoElement* beforeOrAfterPseudoElement(Element* host, PseudoId pseudoElementSpecifier) 2066 { 2067 switch (pseudoElementSpecifier) { 2068 case BEFORE: 2069 return host->beforePseudoElement(); 2070 case AFTER: 2071 return host->afterPseudoElement(); 2072 default: 2073 return 0; 2074 } 2075 } 2076 2067 2077 RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier) 2068 2078 { 2069 if (PseudoElement* element = pseudoElement(pseudoElementSpecifier))2070 return element->computedStyle();2079 if (PseudoElement* pseudoElement = beforeOrAfterPseudoElement(this, pseudoElementSpecifier)) 2080 return pseudoElement->computedStyle(); 2071 2081 2072 2082 // FIXME: Find and use the renderer from the pseudo element instead of the actual element so that the 'length' … … 2303 2313 } 2304 2314 2305 void Element::updatePseudoElement(PseudoId pseudoId, Style::Change change) 2306 { 2307 PseudoElement* existing = pseudoElement(pseudoId); 2308 if (existing) { 2309 // PseudoElement styles hang off their parent element's style so if we needed 2310 // a style recalc we should Force one on the pseudo. 2311 Style::resolveTree(existing, needsStyleRecalc() ? Style::Force : change); 2312 2313 // Wait until our parent is not displayed or pseudoElementRendererIsNeeded 2314 // is false, otherwise we could continously create and destroy PseudoElements 2315 // when RenderObject::isChildAllowed on our parent returns false for the 2316 // PseudoElement's renderer for each style recalc. 2317 if (!renderer() || !pseudoElementRendererIsNeeded(renderer()->getCachedPseudoStyle(pseudoId))) 2318 setPseudoElement(pseudoId, 0); 2319 } else if (RefPtr<PseudoElement> element = createPseudoElementIfNeeded(pseudoId)) { 2320 Style::attachRenderTree(element.get()); 2321 setPseudoElement(pseudoId, element.release()); 2322 } 2315 bool Element::updateExistingPseudoElement(PseudoElement* existingPseudoElement, Style::Change change) 2316 { 2317 // PseudoElement styles hang off their parent element's style so if we needed 2318 // a style recalc we should Force one on the pseudo. 2319 Style::resolveTree(existingPseudoElement, needsStyleRecalc() ? Style::Force : change); 2320 2321 // FIXME: This is silly. 2322 // Wait until our parent is not displayed or pseudoElementRendererIsNeeded 2323 // is false, otherwise we could continously create and destroy PseudoElements 2324 // when RenderObject::isChildAllowed on our parent returns false for the 2325 // PseudoElement's renderer for each style recalc. 2326 return renderer() && pseudoElementRendererIsNeeded(existingPseudoElement->renderStyle()); 2323 2327 } 2324 2328 … … 2327 2331 if (!document()->styleSheetCollection()->usesBeforeAfterRules()) 2328 2332 return 0; 2329 2330 2333 if (!renderer() || !renderer()->canHaveGeneratedChildren()) 2331 2334 return 0; 2332 2333 2335 if (isPseudoElement()) 2334 2336 return 0; 2335 2336 2337 if (!pseudoElementRendererIsNeeded(renderer()->getCachedPseudoStyle(pseudoId))) 2337 2338 return 0; 2338 2339 return PseudoElement::create(this, pseudoId); 2340 } 2341 2342 bool Element::hasPseudoElements() const 2343 { 2344 return hasRareData() && elementRareData()->hasPseudoElements(); 2345 } 2346 2347 PseudoElement* Element::pseudoElement(PseudoId pseudoId) const 2348 { 2349 return hasRareData() ? elementRareData()->pseudoElement(pseudoId) : 0; 2350 } 2351 2352 void Element::setPseudoElement(PseudoId pseudoId, PassRefPtr<PseudoElement> element) 2353 { 2354 ensureElementRareData().setPseudoElement(pseudoId, element); 2339 RefPtr<PseudoElement> pseudoElement = PseudoElement::create(this, pseudoId); 2340 Style::attachRenderTree(pseudoElement.get()); 2341 return pseudoElement.release(); 2342 } 2343 2344 void Element::updateBeforePseudoElement(Style::Change change) 2345 { 2346 if (PseudoElement* existingPseudoElement = beforePseudoElement()) { 2347 if (!updateExistingPseudoElement(existingPseudoElement, change)) 2348 clearBeforePseudoElement(); 2349 return; 2350 } 2351 if (RefPtr<PseudoElement> pseudo = createPseudoElementIfNeeded(BEFORE)) 2352 setBeforePseudoElement(pseudo.release()); 2353 } 2354 2355 void Element::updateAfterPseudoElement(Style::Change change) 2356 { 2357 if (PseudoElement* existingPseudoElement = afterPseudoElement()) { 2358 if (!updateExistingPseudoElement(existingPseudoElement, change)) 2359 clearAfterPseudoElement(); 2360 return; 2361 } 2362 if (RefPtr<PseudoElement> pseudo = createPseudoElementIfNeeded(AFTER)) 2363 setAfterPseudoElement(pseudo.release()); 2364 } 2365 2366 PseudoElement* Element::beforePseudoElement() const 2367 { 2368 return hasRareData() ? elementRareData()->beforePseudoElement() : 0; 2369 } 2370 2371 PseudoElement* Element::afterPseudoElement() const 2372 { 2373 return hasRareData() ? elementRareData()->afterPseudoElement() : 0; 2374 } 2375 2376 void Element::setBeforePseudoElement(PassRefPtr<PseudoElement> element) 2377 { 2378 ensureElementRareData().setBeforePseudoElement(element); 2355 2379 resetNeedsShadowTreeWalker(); 2356 2380 } 2357 2381 2358 RenderObject* Element::pseudoElementRenderer(PseudoId pseudoId) const 2359 { 2360 if (PseudoElement* element = pseudoElement(pseudoId)) 2361 return element->renderer(); 2362 return 0; 2382 void Element::setAfterPseudoElement(PassRefPtr<PseudoElement> element) 2383 { 2384 ensureElementRareData().setAfterPseudoElement(element); 2385 resetNeedsShadowTreeWalker(); 2386 } 2387 2388 static void disconnectPseudoElement(PseudoElement* pseudoElement) 2389 { 2390 if (!pseudoElement) 2391 return; 2392 if (pseudoElement->attached()) 2393 Style::detachRenderTree(pseudoElement); 2394 ASSERT(pseudoElement->hostElement()); 2395 pseudoElement->clearHostElement(); 2396 } 2397 2398 void Element::clearBeforePseudoElement() 2399 { 2400 if (!hasRareData()) 2401 return; 2402 disconnectPseudoElement(elementRareData()->beforePseudoElement()); 2403 elementRareData()->setBeforePseudoElement(nullptr); 2404 } 2405 2406 void Element::clearAfterPseudoElement() 2407 { 2408 if (!hasRareData()) 2409 return; 2410 disconnectPseudoElement(elementRareData()->afterPseudoElement()); 2411 elementRareData()->setAfterPseudoElement(nullptr); 2363 2412 } 2364 2413 … … 2957 3006 unregisterNamedFlowContentNode(); 2958 3007 cancelFocusAppearanceUpdate(); 3008 clearBeforePseudoElement(); 3009 clearAfterPseudoElement(); 2959 3010 if (!hasRareData()) 2960 3011 return; 2961 3012 ElementRareData* data = elementRareData(); 2962 data->setPseudoElement(BEFORE, 0);2963 data->setPseudoElement(AFTER, 0);2964 3013 data->setIsInCanvasSubtree(false); 2965 3014 data->resetComputedStyle(); -
trunk/Source/WebCore/dom/Element.h
r154481 r154541 423 423 virtual void beginParsingChildren() OVERRIDE FINAL; 424 424 425 bool hasPseudoElements() const; 426 PseudoElement* pseudoElement(PseudoId) const; 427 RenderObject* pseudoElementRenderer(PseudoId) const; 425 PseudoElement* beforePseudoElement() const; 426 PseudoElement* afterPseudoElement() const; 428 427 bool childNeedsShadowWalker() const; 429 428 void didShadowTreeAwareChildrenChange(); … … 552 551 virtual void didDetachRenderers(); 553 552 554 void updatePseudoElement(PseudoId, Style::Change = Style::NoChange); 553 void updateBeforePseudoElement(Style::Change); 554 void updateAfterPseudoElement(Style::Change); 555 555 void resetComputedStyle(); 556 556 void clearStyleDerivedDataBeforeDetachingRenderer(); … … 591 591 592 592 PassRefPtr<PseudoElement> createPseudoElementIfNeeded(PseudoId); 593 void setPseudoElement(PseudoId, PassRefPtr<PseudoElement>); 593 bool updateExistingPseudoElement(PseudoElement* existing, Style::Change); 594 595 void setBeforePseudoElement(PassRefPtr<PseudoElement>); 596 void setAfterPseudoElement(PassRefPtr<PseudoElement>); 597 void clearBeforePseudoElement(); 598 void clearAfterPseudoElement(); 594 599 595 600 virtual bool areAuthorShadowsAllowed() const { return true; } -
trunk/Source/WebCore/dom/ElementRareData.h
r154257 r154541 40 40 ~ElementRareData(); 41 41 42 void setPseudoElement(PseudoId, PassRefPtr<PseudoElement>); 43 PseudoElement* pseudoElement(PseudoId) const; 44 bool hasPseudoElements() const { return m_generatedBefore || m_generatedAfter; } 42 void setBeforePseudoElement(PassRefPtr<PseudoElement>); 43 void setAfterPseudoElement(PassRefPtr<PseudoElement>); 44 45 PseudoElement* beforePseudoElement() const { return m_beforePseudoElement.get(); } 46 PseudoElement* afterPseudoElement() const { return m_afterPseudoElement.get(); } 45 47 46 48 void resetComputedStyle(); … … 170 172 OwnPtr<NamedNodeMap> m_attributeMap; 171 173 172 RefPtr<PseudoElement> m_ generatedBefore;173 RefPtr<PseudoElement> m_ generatedAfter;174 RefPtr<PseudoElement> m_beforePseudoElement; 175 RefPtr<PseudoElement> m_afterPseudoElement; 174 176 175 177 ElementRareData(RenderObject*); … … 216 218 { 217 219 ASSERT(!m_shadowRoot); 218 ASSERT(!m_generatedBefore); 219 ASSERT(!m_generatedAfter); 220 } 221 222 inline void ElementRareData::setPseudoElement(PseudoId pseudoId, PassRefPtr<PseudoElement> element) 223 { 224 switch (pseudoId) { 225 case BEFORE: 226 releasePseudoElement(m_generatedBefore.get()); 227 m_generatedBefore = element; 228 break; 229 case AFTER: 230 releasePseudoElement(m_generatedAfter.get()); 231 m_generatedAfter = element; 232 break; 233 default: 234 ASSERT_NOT_REACHED(); 235 } 236 } 237 238 inline PseudoElement* ElementRareData::pseudoElement(PseudoId pseudoId) const 239 { 240 switch (pseudoId) { 241 case BEFORE: 242 return m_generatedBefore.get(); 243 case AFTER: 244 return m_generatedAfter.get(); 245 default: 246 return 0; 247 } 248 } 249 250 inline void ElementRareData::releasePseudoElement(PseudoElement* element) 251 { 252 if (!element) 253 return; 254 if (element->attached()) 255 Style::detachRenderTree(element); 256 element->clearHostElement(); 257 258 ASSERT(!element->nextSibling()); 259 ASSERT(!element->previousSibling()); 260 ASSERT(!element->parentNode()); 220 ASSERT(!m_beforePseudoElement); 221 ASSERT(!m_afterPseudoElement); 222 } 223 224 inline void ElementRareData::setBeforePseudoElement(PassRefPtr<PseudoElement> pseudoElement) 225 { 226 ASSERT(!m_beforePseudoElement || !pseudoElement); 227 m_beforePseudoElement = pseudoElement; 228 } 229 230 inline void ElementRareData::setAfterPseudoElement(PassRefPtr<PseudoElement> pseudoElement) 231 { 232 ASSERT(!m_afterPseudoElement || !pseudoElement); 233 m_afterPseudoElement = pseudoElement; 261 234 } 262 235 -
trunk/Source/WebCore/dom/Node.cpp
r154481 r154541 896 896 return parentOrHost->lastChild(); 897 897 if (!isBeforePseudoElement()) 898 return parentOrHost-> pseudoElement(BEFORE);898 return parentOrHost->beforePseudoElement(); 899 899 } 900 900 return previousSibling(); … … 908 908 return parentOrHost->firstChild(); 909 909 if (!isAfterPseudoElement()) 910 return parentOrHost-> pseudoElement(AFTER);910 return parentOrHost->afterPseudoElement(); 911 911 } 912 912 return nextSibling(); … … 917 917 if (isElementNode()) { 918 918 const Element* currentElement = toElement(this); 919 Node* first = currentElement-> pseudoElement(BEFORE);919 Node* first = currentElement->beforePseudoElement(); 920 920 if (first) 921 921 return first; 922 922 first = currentElement->firstChild(); 923 923 if (!first) 924 first = currentElement-> pseudoElement(AFTER);924 first = currentElement->afterPseudoElement(); 925 925 return first; 926 926 } … … 932 932 if (isElementNode()) { 933 933 const Element* currentElement = toElement(this); 934 Node* last = currentElement-> pseudoElement(AFTER);934 Node* last = currentElement->afterPseudoElement(); 935 935 if (last) 936 936 return last; 937 937 last = currentElement->lastChild(); 938 938 if (!last) 939 last = currentElement-> pseudoElement(BEFORE);939 last = currentElement->beforePseudoElement(); 940 940 return last; 941 941 } … … 1064 1064 bool Node::needsShadowTreeWalkerSlow() const 1065 1065 { 1066 return (isShadowRoot() || (isElementNode() && (isInsertionPoint() || isPseudoElement() || toElement(this)->hasPseudoElements() || toElement(this)->shadowRoot()))); 1066 if (isShadowRoot()) 1067 return true; 1068 if (!isElementNode()) 1069 return false; 1070 const Element* asElement = toElement(this); 1071 if (asElement->isPseudoElement() || asElement->beforePseudoElement() || asElement->afterPseudoElement()) 1072 return true; 1073 return asElement->isInsertionPoint() || asElement->shadowRoot(); 1067 1074 } 1068 1075 -
trunk/Source/WebCore/dom/NodeRenderingTraversal.cpp
r154327 r154541 55 55 Node* parent = walker.traverseParent(node); 56 56 if (parent && parent->isElementNode()) 57 return toElement(parent)-> pseudoElement(AFTER);57 return toElement(parent)->afterPseudoElement(); 58 58 59 59 return 0; … … 74 74 Node* parent = walker.traverseParent(node); 75 75 if (parent && parent->isElementNode()) 76 return toElement(parent)-> pseudoElement(BEFORE);76 return toElement(parent)->beforePseudoElement(); 77 77 78 78 return 0; -
trunk/Source/WebCore/rendering/RenderTreeAsText.cpp
r154286 r154541 36 36 #include "InlineTextBox.h" 37 37 #include "PrintContext.h" 38 #include "PseudoElement.h" 38 39 #include "RenderBR.h" 39 40 #include "RenderDetailsMarker.h" … … 903 904 static void writeCounterValuesFromChildren(TextStream& stream, RenderObject* parent, bool& isFirstCounter) 904 905 { 906 if (!parent) 907 return; 905 908 for (RenderObject* child = parent->firstChild(); child; child = child->nextSibling()) { 906 909 if (child->isCounter()) { … … 922 925 bool isFirstCounter = true; 923 926 // The counter renderers should be children of :before or :after pseudo-elements. 924 if ( RenderObject* before = element->pseudoElementRenderer(BEFORE))925 writeCounterValuesFromChildren(stream, before , isFirstCounter);926 if ( RenderObject* after = element->pseudoElementRenderer(AFTER))927 writeCounterValuesFromChildren(stream, after , isFirstCounter);927 if (PseudoElement* before = element->beforePseudoElement()) 928 writeCounterValuesFromChildren(stream, before->renderer(), isFirstCounter); 929 if (PseudoElement* after = element->afterPseudoElement()) 930 writeCounterValuesFromChildren(stream, after->renderer(), isFirstCounter); 928 931 return stream.release(); 929 932 } -
trunk/Source/WebCore/style/StyleResolveTree.cpp
r154257 r154541 177 177 current->setIsInCanvasSubtree(true); 178 178 179 current->update PseudoElement(BEFORE);179 current->updateBeforePseudoElement(NoChange); 180 180 181 181 StyleResolverParentPusher parentPusher(current); … … 202 202 } 203 203 204 current->update PseudoElement(AFTER);204 current->updateAfterPseudoElement(NoChange); 205 205 206 206 current->updateFocusAppearanceAfterAttachIfNeeded(); … … 430 430 } 431 431 432 current->update PseudoElement(BEFORE,change);432 current->updateBeforePseudoElement(change); 433 433 434 434 // FIXME: This check is good enough for :hover + foo, but it is not good enough for :hover + foo + bar. … … 456 456 } 457 457 458 current->update PseudoElement(AFTER,change);458 current->updateAfterPseudoElement(change); 459 459 } 460 460 -
trunk/Source/WebCore/testing/Internals.cpp
r154458 r154541 458 458 } 459 459 460 PseudoElement* pseudoElement = element->pseudoElement(pseudoId == "before" ? BEFORE : AFTER);460 PseudoElement* pseudoElement = pseudoId == "before" ? element->beforePseudoElement() : element->afterPseudoElement(); 461 461 if (!pseudoElement) { 462 462 ec = INVALID_ACCESS_ERR; … … 488 488 } 489 489 490 PseudoElement* pseudoElement = element->pseudoElement(pseudoId == "before" ? BEFORE : AFTER);490 PseudoElement* pseudoElement = pseudoId == "before" ? element->beforePseudoElement() : element->afterPseudoElement(); 491 491 if (!pseudoElement) { 492 492 ec = INVALID_ACCESS_ERR;
Note:
See TracChangeset
for help on using the changeset viewer.