De-virtualize recalcStyle()
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 2 Sep 2011 11:19:35 +0000 (11:19 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 2 Sep 2011 11:19:35 +0000 (11:19 +0000)
https://bugs.webkit.org/show_bug.cgi?id=67378

Reviewed by Dimitri Glazkov.

Element::recalcStyle() does not need to be virtual, there are very few legit overrides. This will
also make it possible to de-recursify it later.

Added willRecalcStyle()/didRecalcStyle() virtual function for subclasses that need custom style recalc.
These are only invoked if hasCustomWillOrDidRecalcStyle() bit is set.

* dom/Document.cpp:
(WebCore::Document::recalcStyle):
* dom/Document.h:
* dom/Element.cpp:
(WebCore::Element::recalcStyle):
* dom/Element.h:
(WebCore::Element::willRecalcStyle):
(WebCore::Element::didRecalcStyle):
* dom/Node.h:
(WebCore::Node::hasCustomWillOrDidRecalcStyle):
(WebCore::Node::setHasCustomWillOrDidRecalcStyle):
* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::recalcShadowTreeStyle):
* dom/ShadowRoot.h:
* dom/Text.cpp:
(WebCore::Text::recalcTextStyle):
* dom/Text.h:
* html/HTMLFormControlElement.cpp:
(WebCore::HTMLFormControlElement::HTMLFormControlElement):
(WebCore::HTMLFormControlElement::didRecalcStyle):
* html/HTMLFormControlElement.h:
* html/HTMLFrameSetElement.cpp:
(WebCore::HTMLFrameSetElement::HTMLFrameSetElement):
(WebCore::HTMLFrameSetElement::willRecalcStyle):
* html/HTMLFrameSetElement.h:
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::HTMLMediaElement):
(WebCore::HTMLMediaElement::didRecalcStyle):
* html/HTMLMediaElement.h:
* html/HTMLNoScriptElement.cpp:
(WebCore::HTMLNoScriptElement::HTMLNoScriptElement):
(WebCore::HTMLNoScriptElement::willRecalcStyle):
* html/HTMLNoScriptElement.h:
* html/HTMLPlugInImageElement.cpp:
(WebCore::HTMLPlugInImageElement::HTMLPlugInImageElement):
(WebCore::HTMLPlugInImageElement::willRecalcStyle):
* html/HTMLPlugInImageElement.h:
* html/HTMLSelectElement.cpp:
* html/HTMLSelectElement.h:
* svg/SVGTRefElement.cpp:
(WebCore::SVGTRefElement::SVGTRefElement):
(WebCore::SVGShadowText::willRecalcStyle):
* svg/SVGUseElement.cpp:
(WebCore::SVGUseElement::SVGUseElement):
(WebCore::SVGUseElement::willRecalcStyle):
(WebCore::SVGUseElement::didRecalcStyle):
* svg/SVGUseElement.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@94406 268f45cc-cd09-0410-ab3c-d52691b4dbfc

25 files changed:
Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/Element.h
Source/WebCore/dom/Node.h
Source/WebCore/dom/ShadowRoot.cpp
Source/WebCore/dom/ShadowRoot.h
Source/WebCore/dom/Text.cpp
Source/WebCore/dom/Text.h
Source/WebCore/html/HTMLFormControlElement.cpp
Source/WebCore/html/HTMLFormControlElement.h
Source/WebCore/html/HTMLFrameSetElement.cpp
Source/WebCore/html/HTMLFrameSetElement.h
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/html/HTMLNoScriptElement.cpp
Source/WebCore/html/HTMLNoScriptElement.h
Source/WebCore/html/HTMLPlugInImageElement.cpp
Source/WebCore/html/HTMLPlugInImageElement.h
Source/WebCore/html/HTMLSelectElement.cpp
Source/WebCore/html/HTMLSelectElement.h
Source/WebCore/svg/SVGTRefElement.cpp
Source/WebCore/svg/SVGUseElement.cpp
Source/WebCore/svg/SVGUseElement.h

index 84dbfe9..ecd2a3f 100644 (file)
@@ -1,3 +1,64 @@
+2011-09-02  Antti Koivisto  <antti@apple.com>
+
+        De-virtualize recalcStyle()
+        https://bugs.webkit.org/show_bug.cgi?id=67378
+
+        Reviewed by Dimitri Glazkov.
+
+        Element::recalcStyle() does not need to be virtual, there are very few legit overrides. This will
+        also make it possible to de-recursify it later.
+        
+        Added willRecalcStyle()/didRecalcStyle() virtual function for subclasses that need custom style recalc.
+        These are only invoked if hasCustomWillOrDidRecalcStyle() bit is set.
+
+        * dom/Document.cpp:
+        (WebCore::Document::recalcStyle):
+        * dom/Document.h:
+        * dom/Element.cpp:
+        (WebCore::Element::recalcStyle):
+        * dom/Element.h:
+        (WebCore::Element::willRecalcStyle):
+        (WebCore::Element::didRecalcStyle):
+        * dom/Node.h:
+        (WebCore::Node::hasCustomWillOrDidRecalcStyle):
+        (WebCore::Node::setHasCustomWillOrDidRecalcStyle):
+        * dom/ShadowRoot.cpp:
+        (WebCore::ShadowRoot::recalcShadowTreeStyle):
+        * dom/ShadowRoot.h:
+        * dom/Text.cpp:
+        (WebCore::Text::recalcTextStyle):
+        * dom/Text.h:
+        * html/HTMLFormControlElement.cpp:
+        (WebCore::HTMLFormControlElement::HTMLFormControlElement):
+        (WebCore::HTMLFormControlElement::didRecalcStyle):
+        * html/HTMLFormControlElement.h:
+        * html/HTMLFrameSetElement.cpp:
+        (WebCore::HTMLFrameSetElement::HTMLFrameSetElement):
+        (WebCore::HTMLFrameSetElement::willRecalcStyle):
+        * html/HTMLFrameSetElement.h:
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::HTMLMediaElement):
+        (WebCore::HTMLMediaElement::didRecalcStyle):
+        * html/HTMLMediaElement.h:
+        * html/HTMLNoScriptElement.cpp:
+        (WebCore::HTMLNoScriptElement::HTMLNoScriptElement):
+        (WebCore::HTMLNoScriptElement::willRecalcStyle):
+        * html/HTMLNoScriptElement.h:
+        * html/HTMLPlugInImageElement.cpp:
+        (WebCore::HTMLPlugInImageElement::HTMLPlugInImageElement):
+        (WebCore::HTMLPlugInImageElement::willRecalcStyle):
+        * html/HTMLPlugInImageElement.h:
+        * html/HTMLSelectElement.cpp:
+        * html/HTMLSelectElement.h:
+        * svg/SVGTRefElement.cpp:
+        (WebCore::SVGTRefElement::SVGTRefElement):
+        (WebCore::SVGShadowText::willRecalcStyle):
+        * svg/SVGUseElement.cpp:
+        (WebCore::SVGUseElement::SVGUseElement):
+        (WebCore::SVGUseElement::willRecalcStyle):
+        (WebCore::SVGUseElement::didRecalcStyle):
+        * svg/SVGUseElement.h:
+
 2011-09-02  Yuta Kitamura  <yutak@chromium.org>
 
         WebSocket: Send Blob as WebSocket binary message
 
         * page/DOMWindow.idl:
 
->>>>>>> .r94382
 2011-09-01  Mark Rowe  <mrowe@apple.com>
 
         <rdar://problem/10063411> WebScriptObject.h declares an Objective-C method without a return type.
index 836ad60..571a53a 100644 (file)
@@ -1529,9 +1529,13 @@ void Document::recalcStyle(StyleChange change)
             renderer()->setStyle(documentStyle.release());
     }
 
-    for (Node* n = firstChild(); n; n = n->nextSibling())
-        if (change >= Inherit || n->childNeedsStyleRecalc() || n->needsStyleRecalc())
-            n->recalcStyle(change);
+    for (Node* n = firstChild(); n; n = n->nextSibling()) {
+        if (!n->isElementNode())
+            continue;
+        Element* element = static_cast<Element*>(n);
+        if (change >= Inherit || element->childNeedsStyleRecalc() || element->needsStyleRecalc())
+            element->recalcStyle(change);
+    }
 
 #if USE(ACCELERATED_COMPOSITING)
     if (view()) {
index aad686e..20d82ba 100644 (file)
@@ -539,7 +539,7 @@ public:
     PassRefPtr<CSSStyleDeclaration> createCSSStyleDeclaration();
     PassRefPtr<EditingText> createEditingTextNode(const String&);
 
-    virtual void recalcStyle(StyleChange = NoChange);
+    void recalcStyle(StyleChange = NoChange);
     bool childNeedsAndNotInStyleRecalc();
     virtual void updateStyleIfNeeded();
     void updateLayout();
index 7168e12..6745774 100644 (file)
@@ -57,6 +57,7 @@
 #include "RenderWidget.h"
 #include "Settings.h"
 #include "ShadowRoot.h"
+#include "Text.h"
 #include "TextIterator.h"
 #include "WebKitAnimationList.h"
 #include "XMLNames.h"
@@ -1095,6 +1096,11 @@ bool Element::pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderS
 
 void Element::recalcStyle(StyleChange change)
 {
+    if (hasCustomWillOrDidRecalcStyle()) {
+        if (!willRecalcStyle(change))
+            return;
+    }
+
     // Ref currentStyle in case it would otherwise be deleted when setRenderStyle() is called.
     RefPtr<RenderStyle> currentStyle(renderStyle());
     bool hasParentStyle = parentNodeForRenderingAndStyle() ? static_cast<bool>(parentNodeForRenderingAndStyle()->renderStyle()) : false;
@@ -1114,9 +1120,12 @@ void Element::recalcStyle(StyleChange change)
         if (ch == Detach || !currentStyle) {
             // FIXME: The style gets computed twice by calling attach. We could do better if we passed the style along.
             reattach();
-            // attach recalulates the style for all children. No need to do it twice.
+            // attach recalculates the style for all children. No need to do it twice.
             clearNeedsStyleRecalc();
             clearChildNeedsStyleRecalc();
+
+            if (hasCustomWillOrDidRecalcStyle())
+                didRecalcStyle(change);
             return;
         }
 
@@ -1171,28 +1180,37 @@ void Element::recalcStyle(StyleChange change)
     bool forceCheckOfNextElementSibling = false;
     bool forceCheckOfAnyElementSibling = false;
     for (Node *n = firstChild(); n; n = n->nextSibling()) {
-        bool childRulesChanged = n->needsStyleRecalc() && n->styleChangeType() == FullStyleChange;
-        if ((forceCheckOfNextElementSibling || forceCheckOfAnyElementSibling) && n->isElementNode())
-            n->setNeedsStyleRecalc();
-        if (change >= Inherit || n->isTextNode() || n->childNeedsStyleRecalc() || n->needsStyleRecalc()) {
+        if (n->isTextNode()) {
             parentPusher.push();
-            n->recalcStyle(change);
-        }
-        if (n->isElementNode()) {
-            forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules;
-            forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
+            static_cast<Text*>(n)->recalcTextStyle(change);
+            continue;
+        } 
+        if (!n->isElementNode()) 
+            continue;
+        Element* element = static_cast<Element*>(n);
+        bool childRulesChanged = element->needsStyleRecalc() && element->styleChangeType() == FullStyleChange;
+        if ((forceCheckOfNextElementSibling || forceCheckOfAnyElementSibling))
+            element->setNeedsStyleRecalc();
+        if (change >= Inherit || element->childNeedsStyleRecalc() || element->needsStyleRecalc()) {
+            parentPusher.push();
+            element->recalcStyle(change);
         }
+        forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules;
+        forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
     }
     // FIXME: This does not care about sibling combinators. Will be necessary in XBL2 world.
     if (ShadowRoot* shadow = shadowRoot()) {
         if (change >= Inherit || shadow->childNeedsStyleRecalc() || shadow->needsStyleRecalc()) {
             parentPusher.push();
-            shadow->recalcStyle(change);
+            shadow->recalcShadowTreeStyle(change);
         }
     }
 
     clearNeedsStyleRecalc();
     clearChildNeedsStyleRecalc();
+    
+    if (hasCustomWillOrDidRecalcStyle())
+        didRecalcStyle(change);
 }
 
 ShadowRoot* Element::shadowRoot() const
index 1923b06..b070c62 100644 (file)
@@ -229,7 +229,7 @@ public:
     virtual void attach();
     virtual void detach();
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
-    virtual void recalcStyle(StyleChange = NoChange);
+    void recalcStyle(StyleChange = NoChange);
 
     ShadowRoot* shadowRoot() const;
     void setShadowRoot(PassRefPtr<ShadowRoot>, ExceptionCode&);
@@ -380,6 +380,8 @@ protected:
     virtual void insertedIntoTree(bool);
     virtual void removedFromTree(bool);
     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+    virtual bool willRecalcStyle(StyleChange) { return true; }
+    virtual void didRecalcStyle(StyleChange) { }
 
     // The implementation of Element::attributeChanged() calls the following two functions.
     // They are separated to allow a different flow of control in StyledElement::attributeChanged().
index 5ba059c..f66a041 100644 (file)
@@ -352,8 +352,6 @@ public:
     // Note: This method only works properly after layout has occurred.
     bool hasNonEmptyBoundingBox() const;
 
-    virtual void recalcStyle(StyleChange = NoChange) { }
-
     unsigned nodeIndex() const;
 
     // Returns the DOM ownerDocument attribute. This method never returns NULL, except in the case 
@@ -617,6 +615,7 @@ private:
         StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1),
 
         SelfOrAncestorHasDirAutoFlag = 1 << 27,
+        HasCustomWillOrDidRecalcStyle = 1 << 28,
 
 #if ENABLE(SVG)
         DefaultNodeFlags = IsParsingChildrenFinishedFlag | IsStyleAttributeValidFlag | AreSVGAttributesValidFlag
@@ -625,7 +624,7 @@ private:
 #endif
     };
 
-    // 4 bits remaining
+    // 3 bits remaining
 
     bool getFlag(NodeFlags mask) const { return m_nodeFlags & mask; }
     void setFlag(bool f, NodeFlags mask) const { m_nodeFlags = (m_nodeFlags & ~mask) | (-(int32_t)f & mask); } 
@@ -658,6 +657,9 @@ protected:
     NodeRareData* ensureRareData();
     void clearRareData();
 
+    bool hasCustomWillOrDidRecalcStyle() const { return getFlag(HasCustomWillOrDidRecalcStyle); }
+    void setHasCustomWillOrDidRecalcStyle() { setFlag(true, HasCustomWillOrDidRecalcStyle); }
+
 private:
     // Do not use this method to change the document of a node until after the node has been
     // removed from its previous document.
index 494823d..a6cc3c7 100644 (file)
@@ -32,6 +32,7 @@
 #include "NodeRareData.h"
 #include "ShadowContentElement.h"
 #include "ShadowInclusionSelector.h"
+#include "Text.h"
 
 namespace WebCore {
 
@@ -83,13 +84,17 @@ bool ShadowRoot::childTypeAllowed(NodeType type) const
     }
 }
 
-void ShadowRoot::recalcStyle(StyleChange change)
+void ShadowRoot::recalcShadowTreeStyle(StyleChange change)
 {
     if (hasContentElement())
         reattach();
     else {
-        for (Node* n = firstChild(); n; n = n->nextSibling())
-            n->recalcStyle(change);
+        for (Node* n = firstChild(); n; n = n->nextSibling()) {
+            if (n->isElementNode())
+                static_cast<Element*>(n)->recalcStyle(change);
+            else if (n->isTextNode())
+                static_cast<Text*>(n)->recalcTextStyle(change);
+        }
     }
 
     clearNeedsStyleRecalc();
index 6410c66..ebec872 100644 (file)
@@ -39,7 +39,7 @@ class ShadowRoot : public TreeScope {
 public:
     static PassRefPtr<ShadowRoot> create(Document*);
 
-    virtual void recalcStyle(StyleChange = NoChange);
+    void recalcShadowTreeStyle(StyleChange);
 
     ShadowContentElement* includerFor(Node*) const;
     void hostChildrenChanged();
index b88c829..1f5c15b 100644 (file)
@@ -254,7 +254,7 @@ void Text::attach()
     CharacterData::attach();
 }
 
-void Text::recalcStyle(StyleChange change)
+void Text::recalcTextStyle(StyleChange change)
 {
     if (change != NoChange && parentNode() && parentNode()->renderer()) {
         if (renderer())
index 24caae4..04bae91 100644 (file)
@@ -40,6 +40,8 @@ public:
 
     String wholeText() const;
     PassRefPtr<Text> replaceWholeText(const String&, ExceptionCode&);
+    
+    void recalcTextStyle(StyleChange);
 
     virtual void attach();
     
@@ -51,8 +53,6 @@ protected:
     {
     }
 
-    virtual void recalcStyle(StyleChange = NoChange);
-
 private:
     virtual String nodeName() const;
     virtual NodeType nodeType() const;
index ffafba5..000637b 100644 (file)
@@ -64,6 +64,8 @@ HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName, Doc
         setForm(findFormAncestor());
     if (this->form())
         this->form()->registerFormElement(this);
+
+    setHasCustomWillOrDidRecalcStyle();
 }
 
 HTMLFormControlElement::~HTMLFormControlElement()
@@ -262,10 +264,8 @@ static void updateFromElementCallback(Node* node, unsigned)
         renderer->updateFromElement();
 }
 
-void HTMLFormControlElement::recalcStyle(StyleChange change)
+void HTMLFormControlElement::didRecalcStyle(StyleChange)
 {
-    HTMLElement::recalcStyle(change);
-
     // updateFromElement() can cause the selection to change, and in turn
     // trigger synchronous layout, so it must not be called during style recalc.
     if (renderer())
index d94333f..33c39f0 100644 (file)
@@ -117,7 +117,7 @@ protected:
     virtual bool isKeyboardFocusable(KeyboardEvent*) const;
     virtual bool isMouseFocusable() const;
 
-    virtual void recalcStyle(StyleChange);
+    virtual void didRecalcStyle(StyleChange);
 
     virtual void dispatchBlurEvent(PassRefPtr<Node> newFocusedNode);
     virtual void detach();
index 753eb0f..978a72d 100644 (file)
@@ -55,6 +55,8 @@ HTMLFrameSetElement::HTMLFrameSetElement(const QualifiedName& tagName, Document*
     , m_noresize(false)
 {
     ASSERT(hasTagName(framesetTag));
+    
+    setHasCustomWillOrDidRecalcStyle();
 }
 
 PassRefPtr<HTMLFrameSetElement> HTMLFrameSetElement::create(const QualifiedName& tagName, Document* document)
@@ -198,13 +200,13 @@ void HTMLFrameSetElement::defaultEventHandler(Event* evt)
     HTMLElement::defaultEventHandler(evt);
 }
 
-void HTMLFrameSetElement::recalcStyle(StyleChange ch)
+bool HTMLFrameSetElement::willRecalcStyle(StyleChange)
 {
     if (needsStyleRecalc() && renderer()) {
         renderer()->setNeedsLayout(true);
         clearNeedsStyleRecalc();
     }
-    HTMLElement::recalcStyle(ch);
+    return true;
 }
 
 void HTMLFrameSetElement::insertedIntoDocument()
index 7fc445c..6988974 100644 (file)
@@ -76,7 +76,7 @@ private:
     
     virtual void defaultEventHandler(Event*);
 
-    virtual void recalcStyle(StyleChange);
+    virtual bool willRecalcStyle(StyleChange);
 
     virtual void insertedIntoDocument();
     virtual void removedFromDocument();
index 5e2cdec..d4e6521 100644 (file)
@@ -209,6 +209,8 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* docum
     m_mediaSourceURL.setProtocol(mediaSourceURLProtocol);
     m_mediaSourceURL.setPath(createCanonicalUUIDString());
 #endif
+
+    setHasCustomWillOrDidRecalcStyle();
 }
 
 HTMLMediaElement::~HTMLMediaElement()
@@ -407,10 +409,8 @@ void HTMLMediaElement::attach()
 #endif
 }
 
-void HTMLMediaElement::recalcStyle(StyleChange change)
+void HTMLMediaElement::didRecalcStyle(StyleChange)
 {
-    HTMLElement::recalcStyle(change);
-
     if (renderer())
         renderer()->updateFromElement();
 }
index 342383b..56a522d 100644 (file)
@@ -253,7 +253,7 @@ private:
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
     virtual void insertedIntoDocument();
     virtual void removedFromDocument();
-    virtual void recalcStyle(StyleChange);
+    virtual void didRecalcStyle(StyleChange);
     
     virtual void defaultEventHandler(Event*);
 
index 5bba16f..aa4764e 100644 (file)
@@ -35,6 +35,8 @@ inline HTMLNoScriptElement::HTMLNoScriptElement(const QualifiedName& tagName, Do
     : HTMLElement(tagName, document)
 {
     ASSERT(hasTagName(noscriptTag));
+
+    setHasCustomWillOrDidRecalcStyle();
 }
 
 PassRefPtr<HTMLNoScriptElement> HTMLNoScriptElement::create(const QualifiedName& tagName, Document* document)
@@ -54,10 +56,10 @@ void HTMLNoScriptElement::attach()
     }
 }
 
-void HTMLNoScriptElement::recalcStyle(StyleChange change)
+bool HTMLNoScriptElement::willRecalcStyle(StyleChange)
 {
     if (!document()->shouldProcessNoscriptElement() || !renderer() || !renderer()->style())
-        return;
+        return false;
 
     // If <noscript> needs processing, we make it visiable here, including its visible children
     RefPtr<RenderStyle> style = renderer()->style();
@@ -71,6 +73,7 @@ void HTMLNoScriptElement::recalcStyle(StyleChange change)
                     n->createRendererIfNeeded();
         }
     }
+    return false;
 }
 
 bool HTMLNoScriptElement::childShouldCreateRenderer(Node*) const
index 09de203..acc1499 100644 (file)
@@ -35,7 +35,7 @@ private:
     HTMLNoScriptElement(const QualifiedName&, Document*);
 
     virtual void attach();
-    virtual void recalcStyle(StyleChange);
+    virtual bool willRecalcStyle(StyleChange);
     virtual bool childShouldCreateRenderer(Node*) const;
     virtual bool rendererIsNeeded(const NodeRenderingContext&) {  return true; }
 };
index 760149d..8753442 100644 (file)
@@ -42,6 +42,7 @@ HTMLPlugInImageElement::HTMLPlugInImageElement(const QualifiedName& tagName, Doc
     , m_needsWidgetUpdate(!createdByParser)
     , m_shouldPreferPlugInsForImages(preferPlugInsForImagesOption == ShouldPreferPlugInsForImages)
 {
+    setHasCustomWillOrDidRecalcStyle();
 }
 
 RenderEmbeddedObject* HTMLPlugInImageElement::renderEmbeddedObject() const
@@ -121,12 +122,12 @@ RenderObject* HTMLPlugInImageElement::createRenderer(RenderArena* arena, RenderS
     return new (arena) RenderEmbeddedObject(this);
 }
 
-void HTMLPlugInImageElement::recalcStyle(StyleChange ch)
+bool HTMLPlugInImageElement::willRecalcStyle(StyleChange)
 {
     // FIXME: Why is this necessary?  Manual re-attach is almost always wrong.
     if (!useFallbackContent() && needsWidgetUpdate() && renderer() && !isImageType())
         reattach();
-    HTMLPlugInElement::recalcStyle(ch);
+    return true;
 }
 
 void HTMLPlugInImageElement::attach()
index 08090ba..eb2d17e 100644 (file)
@@ -73,7 +73,7 @@ protected:
 
 private:
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
-    virtual void recalcStyle(StyleChange);
+    virtual bool willRecalcStyle(StyleChange);
     
     virtual void finishParsingChildren();
 
index e7a4dbe..1679fab 100644 (file)
@@ -58,11 +58,6 @@ PassRefPtr<HTMLSelectElement> HTMLSelectElement::create(const QualifiedName& tag
     return adoptRef(new HTMLSelectElement(tagName, document, form));
 }
 
-void HTMLSelectElement::recalcStyle(StyleChange change)
-{
-    HTMLFormControlElementWithState::recalcStyle(change);
-}
-
 const AtomicString& HTMLSelectElement::formControlType() const
 {
     DEFINE_STATIC_LOCAL(const AtomicString, selectMultiple, ("select-multiple"));
index a0c4a9d..648ef64 100644 (file)
@@ -101,8 +101,6 @@ private:
     virtual bool isKeyboardFocusable(KeyboardEvent*) const;
     virtual bool isMouseFocusable() const;
 
-    virtual void recalcStyle(StyleChange);
-
     virtual void dispatchFocusEvent(PassRefPtr<Node> oldFocusedNode);
     virtual void dispatchBlurEvent(PassRefPtr<Node> newFocusedNode);
     
index 6c7bbb3..a2ba104 100644 (file)
@@ -52,6 +52,8 @@ inline SVGTRefElement::SVGTRefElement(const QualifiedName& tagName, Document* do
 {
     ASSERT(hasTagName(SVGNames::trefTag));
     registerAnimatedPropertiesForSVGTRefElement();
+    
+    setHasCustomWillOrDidRecalcStyle();
 }
 
 PassRefPtr<SVGTRefElement> SVGTRefElement::create(const QualifiedName& tagName, Document* document)
@@ -119,7 +121,7 @@ private:
     {
     }
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
-    virtual void recalcStyle(StyleChange);
+    virtual bool willRecalcStyle(StyleChange);
 };
 
 RenderObject* SVGShadowText::createRenderer(RenderArena* arena, RenderStyle*)
@@ -127,13 +129,13 @@ RenderObject* SVGShadowText::createRenderer(RenderArena* arena, RenderStyle*)
     return new (arena) RenderSVGInlineText(this, dataImpl());
 }
 
-void SVGShadowText::recalcStyle(StyleChange change)
+bool SVGShadowText::willRecalcStyle(StyleChange change)
 {
     if (change != NoChange && parentNode()->shadowHost()) {
         if (renderer())
             renderer()->setStyle(parentNode()->shadowHost()->renderer()->style());
     }
-    Text::recalcStyle(change);
+    return true;
 }
 
 void SVGTRefElement::updateReferencedText()
index 1459065..1892724 100644 (file)
@@ -86,6 +86,8 @@ inline SVGUseElement::SVGUseElement(const QualifiedName& tagName, Document* docu
 {
     ASSERT(hasTagName(SVGNames::useTag));
     registerAnimatedPropertiesForSVGUseElement();
+    
+    setHasCustomWillOrDidRecalcStyle();
 }
 
 PassRefPtr<SVGUseElement> SVGUseElement::create(const QualifiedName& tagName, Document* document)
@@ -343,16 +345,18 @@ void SVGUseElement::updateContainerOffsets()
         RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
 }
 
-void SVGUseElement::recalcStyle(StyleChange change)
+bool SVGUseElement::willRecalcStyle(StyleChange change)
 {
     // Eventually mark shadow root element needing style recalc
     if ((change >= Inherit || needsStyleRecalc() || childNeedsStyleRecalc()) && m_targetElementInstance && !m_updatesBlocked) {
         if (SVGElement* shadowRoot = m_targetElementInstance->shadowTreeElement())
             shadowRoot->setNeedsStyleRecalc();
     }
+    return true;
+}
 
-    SVGStyledTransformableElement::recalcStyle(change);
-
+void SVGUseElement::didRecalcStyle(StyleChange change)
+{
     // Assure that the shadow tree has not been marked for recreation, while we're building it.
     if (m_updatesBlocked)
         ASSERT(!m_needsShadowTreeRecreation);
index b65ca4e..961ece9 100644 (file)
@@ -64,7 +64,9 @@ private:
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
 
-    virtual void recalcStyle(StyleChange = NoChange);
+    virtual bool willRecalcStyle(StyleChange);
+    virtual void didRecalcStyle(StyleChange);
+
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
     virtual void attach();
     virtual void detach();