insertedIntoDocument and insertedIntoTree should be unitifed.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 17 Apr 2012 06:40:55 +0000 (06:40 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 17 Apr 2012 06:40:55 +0000 (06:40 +0000)
https://bugs.webkit.org/show_bug.cgi?id=82701

Patch by Hajime Morrita <morrita@chromium.org> on 2012-04-16
Reviewed by Ryosuke Niwa.

Both Node::insertedIntoTree() and Node::insertedIntoDocument() are
served as lifecycle callbacks which are invoked when a node is
inserted into its new parent. There are also removedFromTree()
and removedFromDocument() respectively. Considering that this pair
of virtual functions are laid onto the hot path, it's worth
merging them into one, to gain some speedup. Such
unification could clarify the semantics as well.

This change makes following change to merge these functions.

- pulling the tree traversal out from ContainerNode to ChildNodeInsertionNotifier.
- letting new Node::insertInto() do the job for its own, but not
  for its children and
- Pass the parent of each insertion root as a parameter of insertedInto().
  This root node can tell inserted node where it is inserted,
  specifically whetehr the insertion is to the document or not.

Same pattern is also applied to Node::removedFromDocument() and
Node::removedFromTree(), which are factored to Node::removedFrom()
and ChildNodeRemovalNotifier respectively.

Speed up on Dromaeo/dom-modify.html is about 2%.
Further speed-up by de-virtulization would be possible.

Caveat:

There is possible situation where a node need to invoke
insertedInto() after its children is nofitied, instead of before
that.  It was represented naturally with previous
traversal-by-ContainerNode pattern, but is no longer simple with
this new external traversal. To support this scenario, we
introduced the InsertionNotificationRequest as a return value of insertedInto()
and a supplemental hook Node::didNotifyDescendantInseretions(). See for
example HTMLFormElement.cpp to learn how it works.

No new tests. Covered by existing tests.

* CMakeLists.txt:
* GNUmakefile.list.am:
* Target.pri:
* WebCore.gypi:
* WebCore.xcodeproj/project.pbxproj:
* dom/ContainerNode.cpp:
(WebCore::ContainerNode::parserInsertBefore):
(WebCore::ContainerNode::removeChild):
(WebCore::ContainerNode::parserRemoveChild):
(WebCore::ContainerNode::removeChildren):
(WebCore::ContainerNode::parserAddChild):
(WebCore::updateTreeAfterInsertion):
* dom/ContainerNode.h:
(ContainerNode):
(WebCore::Node::highestAncestor):
(WebCore):
* dom/ContainerNodeAlgorithms.cpp: Added.
(WebCore):
(WebCore::ChildNodeInsertionNotifier::notifyDescendantInsertedIntoDocument):
(WebCore::ChildNodeInsertionNotifier::notifyDescendantInsertedIntoTree):
(WebCore::ChildNodeRemovalNotifier::notifyDescendantRemovedFromDocument):
(WebCore::ChildNodeRemovalNotifier::notifyDescendantRemovedFromTree):
* dom/ContainerNodeAlgorithms.h:
(ChildNodeInsertionNotifier):
(WebCore::ChildNodeInsertionNotifier::ChildNodeInsertionNotifier):
(WebCore):
(ChildNodeRemovalNotifier):
(WebCore::ChildNodeRemovalNotifier::ChildNodeRemovalNotifier):
(WebCore::removeAllChildrenInContainer):
(WebCore::appendChildToContainer):
(Private):
(WebCore::ChildNodeInsertionNotifier::notifyNodeInsertedIntoDocument):
(WebCore::ChildNodeInsertionNotifier::notifyNodeInsertedIntoTree):
(WebCore::ChildNodeInsertionNotifier::notifyInsertedIntoDocument):
(WebCore::ChildNodeInsertionNotifier::notify):
(WebCore::ChildNodeRemovalNotifier::notifyNodeRemovedFromDocument):
(WebCore::ChildNodeRemovalNotifier::notifyNodeRemovedFromTree):
(WebCore::ChildNodeRemovalNotifier::notify):
* dom/DOMAllInOne.cpp:
* dom/DocumentType.cpp:
(WebCore::DocumentType::insertedInto):
(WebCore::DocumentType::removedFrom):
* dom/DocumentType.h:
(DocumentType):
* dom/Element.cpp:
(WebCore::Element::insertedInto):
(WebCore::Element::removedFrom):
* dom/Element.h:
(Element):
* dom/Node.cpp:
(WebCore::Node::insertedInto):
(WebCore::Node::removedFrom):
* dom/Node.h:
(Node):
(WebCore::Node::didNotifyDescendantInseretions):
* dom/ProcessingInstruction.cpp:
(WebCore::ProcessingInstruction::insertedInto):
(WebCore::ProcessingInstruction::removedFrom):
* dom/ProcessingInstruction.h:
(ProcessingInstruction):
* dom/ScriptElement.cpp:
(WebCore::ScriptElement::insertedInto):
* dom/ScriptElement.h:
(WebCore):
(ScriptElement):
* dom/ShadowTree.cpp:
(WebCore::ShadowTree::addShadowRoot):
(WebCore::ShadowTree::removeAllShadowRoots):
* dom/ShadowTree.h:
(ShadowTree):
(ShadowRootVector):
(WebCore::ShadowRootVector::ShadowRootVector):
(WebCore):
* html/FormAssociatedElement.cpp:
(WebCore::FormAssociatedElement::insertedInto):
(WebCore::FormAssociatedElement::removedFrom):
(WebCore::FormAssociatedElement::formRemovedFromTree):
* html/FormAssociatedElement.h:
(FormAssociatedElement):
* html/HTMLBaseElement.cpp:
(WebCore::HTMLBaseElement::insertedInto):
(WebCore::HTMLBaseElement::removedFrom):
* html/HTMLBaseElement.h:
(HTMLBaseElement):
* html/HTMLBodyElement.cpp:
(WebCore::HTMLBodyElement::insertedInto):
(WebCore::HTMLBodyElement::didNotifyDescendantInseretions):
* html/HTMLBodyElement.h:
(HTMLBodyElement):
* html/HTMLFormControlElement.cpp:
(WebCore::HTMLFormControlElement::insertedInto):
(WebCore::HTMLFormControlElement::removedFrom):
* html/HTMLFormControlElement.h:
(HTMLFormControlElement):
* html/HTMLFormElement.cpp:
(WebCore::HTMLFormElement::insertedInto):
(WebCore::HTMLFormElement::didNotifyDescendantInseretions):
(WebCore::HTMLFormElement::removedFrom):
* html/HTMLFormElement.h:
(HTMLFormElement):
* html/HTMLFrameElementBase.cpp:
(WebCore::HTMLFrameElementBase::insertedInto):
(WebCore):
(WebCore::HTMLFrameElementBase::didNotifyDescendantInseretions):
* html/HTMLFrameElementBase.h:
(HTMLFrameElementBase):
* html/HTMLFrameSetElement.cpp:
(WebCore::HTMLFrameSetElement::insertedInto):
(WebCore::HTMLFrameSetElement::removedFrom):
* html/HTMLFrameSetElement.h:
(HTMLFrameSetElement):
* html/HTMLIFrameElement.cpp:
(WebCore::HTMLIFrameElement::insertedInto):
(WebCore::HTMLIFrameElement::removedFrom):
* html/HTMLIFrameElement.h:
(HTMLIFrameElement):
* html/HTMLImageElement.cpp:
(WebCore::HTMLImageElement::insertedInto):
(WebCore::HTMLImageElement::removedFrom):
* html/HTMLImageElement.h:
(HTMLImageElement):
* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::insertedInto):
(WebCore::HTMLInputElement::removedFrom):
* html/HTMLInputElement.h:
* html/HTMLLinkElement.cpp:
(WebCore::HTMLLinkElement::insertedInto):
(WebCore::HTMLLinkElement::removedFrom):
* html/HTMLLinkElement.h:
(HTMLLinkElement):
* html/HTMLMapElement.cpp:
(WebCore::HTMLMapElement::insertedInto):
(WebCore::HTMLMapElement::removedFrom):
* html/HTMLMapElement.h:
(HTMLMapElement):
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::insertedInto):
(WebCore::HTMLMediaElement::removedFrom):
* html/HTMLMediaElement.h:
(HTMLMediaElement):
* html/HTMLMetaElement.cpp:
(WebCore::HTMLMetaElement::insertedInto):
* html/HTMLMetaElement.h:
(HTMLMetaElement):
* html/HTMLObjectElement.cpp:
(WebCore::HTMLObjectElement::insertedInto):
(WebCore::HTMLObjectElement::removedFrom):
* html/HTMLObjectElement.h:
(HTMLObjectElement):
* html/HTMLOptionElement.cpp:
(WebCore::HTMLOptionElement::insertedInto):
* html/HTMLOptionElement.h:
(HTMLOptionElement):
* html/HTMLQuoteElement.cpp:
(WebCore::HTMLQuoteElement::insertedInto):
* html/HTMLQuoteElement.h:
(HTMLQuoteElement):
* html/HTMLScriptElement.cpp:
(WebCore::HTMLScriptElement::insertedInto):
* html/HTMLScriptElement.h:
(HTMLScriptElement):
* html/HTMLSelectElement.cpp:
(WebCore::HTMLSelectElement::insertedInto):
* html/HTMLSelectElement.h:
* html/HTMLSourceElement.cpp:
(WebCore::HTMLSourceElement::insertedInto):
* html/HTMLSourceElement.h:
(HTMLSourceElement):
* html/HTMLStyleElement.cpp:
(WebCore::HTMLStyleElement::insertedInto):
(WebCore::HTMLStyleElement::removedFrom):
* html/HTMLStyleElement.h:
(HTMLStyleElement):
* html/HTMLTextFormControlElement.cpp:
(WebCore::HTMLTextFormControlElement::insertedInto):
* html/HTMLTextFormControlElement.h:
* html/HTMLTitleElement.cpp:
(WebCore::HTMLTitleElement::insertedInto):
(WebCore::HTMLTitleElement::removedFrom):
* html/HTMLTitleElement.h:
(HTMLTitleElement):
* html/HTMLTrackElement.cpp:
(WebCore::HTMLTrackElement::insertedInto):
* html/HTMLTrackElement.h:
(HTMLTrackElement):
* mathml/MathMLMathElement.cpp:
(WebCore::MathMLMathElement::insertedInto):
* mathml/MathMLMathElement.h:
(MathMLMathElement):
* svg/SVGElement.cpp:
(WebCore::SVGElement::removedFrom):
* svg/SVGElement.h:
(SVGElement):
* svg/SVGFEImageElement.cpp:
(WebCore::SVGFEImageElement::insertedInto):
(WebCore::SVGFEImageElement::removedFrom):
* svg/SVGFEImageElement.h:
(SVGFEImageElement):
* svg/SVGFontFaceElement.cpp:
(WebCore::SVGFontFaceElement::insertedInto):
(WebCore::SVGFontFaceElement::removedFrom):
* svg/SVGFontFaceElement.h:
(SVGFontFaceElement):
* svg/SVGFontFaceUriElement.cpp:
(WebCore::SVGFontFaceUriElement::insertedInto):
* svg/SVGFontFaceUriElement.h:
(SVGFontFaceUriElement):
* svg/SVGGlyphElement.cpp:
(WebCore::SVGGlyphElement::insertedInto):
(WebCore::SVGGlyphElement::removedFrom):
* svg/SVGGlyphElement.h:
(SVGGlyphElement):
* svg/SVGHKernElement.cpp:
(WebCore::SVGHKernElement::insertedInto):
(WebCore::SVGHKernElement::removedFrom):
* svg/SVGHKernElement.h:
(SVGHKernElement):
* svg/SVGImageElement.cpp:
(WebCore::SVGImageElement::insertedInto):
* svg/SVGImageElement.h:
(SVGImageElement):
* svg/SVGSVGElement.cpp:
(WebCore::SVGSVGElement::insertedInto):
(WebCore::SVGSVGElement::removedFrom):
* svg/SVGSVGElement.h:
(SVGSVGElement):
* svg/SVGScriptElement.cpp:
(WebCore::SVGScriptElement::insertedInto):
* svg/SVGScriptElement.h:
(SVGScriptElement):
* svg/SVGStyleElement.cpp:
(WebCore::SVGStyleElement::insertedInto):
(WebCore::SVGStyleElement::removedFrom):
* svg/SVGStyleElement.h:
(SVGStyleElement):
* svg/SVGStyledElement.cpp:
(WebCore::SVGStyledElement::insertedInto):
(WebCore::SVGStyledElement::removedFrom):
(WebCore::SVGStyledElement::updateRelativeLengthsInformation):
* svg/SVGStyledElement.h:
(SVGStyledElement):
* svg/SVGTRefElement.cpp:
(WebCore::SVGTRefElement::buildPendingResource):
(WebCore::SVGTRefElement::insertedInto):
(WebCore::SVGTRefElement::removedFrom):
* svg/SVGTRefElement.h:
(SVGTRefElement):
* svg/SVGTextPathElement.cpp:
(WebCore::SVGTextPathElement::insertedInto):
* svg/SVGTextPathElement.h:
* svg/SVGTitleElement.cpp:
(WebCore::SVGTitleElement::insertedInto):
(WebCore::SVGTitleElement::removedFrom):
* svg/SVGTitleElement.h:
(SVGTitleElement):
* svg/SVGUseElement.cpp:
(WebCore::SVGUseElement::insertedInto):
(WebCore::SVGUseElement::removedFrom):
* svg/SVGUseElement.h:
(SVGUseElement):
* svg/SVGVKernElement.cpp:
(WebCore::SVGVKernElement::insertedInto):
(WebCore::SVGVKernElement::removedFrom):
* svg/SVGVKernElement.h:
(SVGVKernElement):
* svg/animation/SVGSMILElement.cpp:
(WebCore::SVGSMILElement::insertedInto):
(WebCore::SVGSMILElement::removedFrom):
* svg/animation/SVGSMILElement.h:
(SVGSMILElement):

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

107 files changed:
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/Target.pri
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/ContainerNode.cpp
Source/WebCore/dom/ContainerNode.h
Source/WebCore/dom/ContainerNodeAlgorithms.cpp [new file with mode: 0644]
Source/WebCore/dom/ContainerNodeAlgorithms.h
Source/WebCore/dom/DOMAllInOne.cpp
Source/WebCore/dom/DocumentType.cpp
Source/WebCore/dom/DocumentType.h
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/Element.h
Source/WebCore/dom/Node.cpp
Source/WebCore/dom/Node.h
Source/WebCore/dom/ProcessingInstruction.cpp
Source/WebCore/dom/ProcessingInstruction.h
Source/WebCore/dom/ScriptElement.cpp
Source/WebCore/dom/ScriptElement.h
Source/WebCore/dom/ShadowTree.cpp
Source/WebCore/dom/ShadowTree.h
Source/WebCore/html/FormAssociatedElement.cpp
Source/WebCore/html/FormAssociatedElement.h
Source/WebCore/html/HTMLBaseElement.cpp
Source/WebCore/html/HTMLBaseElement.h
Source/WebCore/html/HTMLBodyElement.cpp
Source/WebCore/html/HTMLBodyElement.h
Source/WebCore/html/HTMLFormControlElement.cpp
Source/WebCore/html/HTMLFormControlElement.h
Source/WebCore/html/HTMLFormElement.cpp
Source/WebCore/html/HTMLFormElement.h
Source/WebCore/html/HTMLFrameElementBase.cpp
Source/WebCore/html/HTMLFrameElementBase.h
Source/WebCore/html/HTMLFrameSetElement.cpp
Source/WebCore/html/HTMLFrameSetElement.h
Source/WebCore/html/HTMLIFrameElement.cpp
Source/WebCore/html/HTMLIFrameElement.h
Source/WebCore/html/HTMLImageElement.cpp
Source/WebCore/html/HTMLImageElement.h
Source/WebCore/html/HTMLInputElement.cpp
Source/WebCore/html/HTMLInputElement.h
Source/WebCore/html/HTMLLinkElement.cpp
Source/WebCore/html/HTMLLinkElement.h
Source/WebCore/html/HTMLMapElement.cpp
Source/WebCore/html/HTMLMapElement.h
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/html/HTMLMetaElement.cpp
Source/WebCore/html/HTMLMetaElement.h
Source/WebCore/html/HTMLObjectElement.cpp
Source/WebCore/html/HTMLObjectElement.h
Source/WebCore/html/HTMLOptionElement.cpp
Source/WebCore/html/HTMLOptionElement.h
Source/WebCore/html/HTMLQuoteElement.cpp
Source/WebCore/html/HTMLQuoteElement.h
Source/WebCore/html/HTMLScriptElement.cpp
Source/WebCore/html/HTMLScriptElement.h
Source/WebCore/html/HTMLSelectElement.cpp
Source/WebCore/html/HTMLSelectElement.h
Source/WebCore/html/HTMLSourceElement.cpp
Source/WebCore/html/HTMLSourceElement.h
Source/WebCore/html/HTMLStyleElement.cpp
Source/WebCore/html/HTMLStyleElement.h
Source/WebCore/html/HTMLTextFormControlElement.cpp
Source/WebCore/html/HTMLTextFormControlElement.h
Source/WebCore/html/HTMLTitleElement.cpp
Source/WebCore/html/HTMLTitleElement.h
Source/WebCore/html/HTMLTrackElement.cpp
Source/WebCore/html/HTMLTrackElement.h
Source/WebCore/mathml/MathMLMathElement.cpp
Source/WebCore/mathml/MathMLMathElement.h
Source/WebCore/svg/SVGElement.cpp
Source/WebCore/svg/SVGElement.h
Source/WebCore/svg/SVGFEImageElement.cpp
Source/WebCore/svg/SVGFEImageElement.h
Source/WebCore/svg/SVGFontFaceElement.cpp
Source/WebCore/svg/SVGFontFaceElement.h
Source/WebCore/svg/SVGFontFaceUriElement.cpp
Source/WebCore/svg/SVGFontFaceUriElement.h
Source/WebCore/svg/SVGGlyphElement.cpp
Source/WebCore/svg/SVGGlyphElement.h
Source/WebCore/svg/SVGHKernElement.cpp
Source/WebCore/svg/SVGHKernElement.h
Source/WebCore/svg/SVGImageElement.cpp
Source/WebCore/svg/SVGImageElement.h
Source/WebCore/svg/SVGSVGElement.cpp
Source/WebCore/svg/SVGSVGElement.h
Source/WebCore/svg/SVGScriptElement.cpp
Source/WebCore/svg/SVGScriptElement.h
Source/WebCore/svg/SVGStyleElement.cpp
Source/WebCore/svg/SVGStyleElement.h
Source/WebCore/svg/SVGStyledElement.cpp
Source/WebCore/svg/SVGStyledElement.h
Source/WebCore/svg/SVGTRefElement.cpp
Source/WebCore/svg/SVGTRefElement.h
Source/WebCore/svg/SVGTextPathElement.cpp
Source/WebCore/svg/SVGTextPathElement.h
Source/WebCore/svg/SVGTitleElement.cpp
Source/WebCore/svg/SVGTitleElement.h
Source/WebCore/svg/SVGUseElement.cpp
Source/WebCore/svg/SVGUseElement.h
Source/WebCore/svg/SVGVKernElement.cpp
Source/WebCore/svg/SVGVKernElement.h
Source/WebCore/svg/animation/SVGSMILElement.cpp
Source/WebCore/svg/animation/SVGSMILElement.h

index 977518c..4be25ff 100644 (file)
@@ -539,6 +539,7 @@ SET(WebCore_SOURCES
     dom/ComposedShadowTreeWalker.cpp
     dom/CompositionEvent.cpp
     dom/ContainerNode.cpp
+    dom/ContainerNodeAlgorithms.cpp
     dom/ContextDestructionObserver.cpp
     dom/CustomEvent.cpp
     dom/DatasetDOMStringMap.cpp
index a893bc6..fb2e235 100644 (file)
@@ -1,3 +1,318 @@
+2012-04-16  Hajime Morrita  <morrita@chromium.org>
+
+        insertedIntoDocument and insertedIntoTree should be unitifed.
+        https://bugs.webkit.org/show_bug.cgi?id=82701
+
+        Reviewed by Ryosuke Niwa.
+
+        Both Node::insertedIntoTree() and Node::insertedIntoDocument() are
+        served as lifecycle callbacks which are invoked when a node is
+        inserted into its new parent. There are also removedFromTree()
+        and removedFromDocument() respectively. Considering that this pair
+        of virtual functions are laid onto the hot path, it's worth
+        merging them into one, to gain some speedup. Such
+        unification could clarify the semantics as well.
+
+        This change makes following change to merge these functions.
+
+        - pulling the tree traversal out from ContainerNode to ChildNodeInsertionNotifier.
+        - letting new Node::insertInto() do the job for its own, but not
+          for its children and
+        - Pass the parent of each insertion root as a parameter of insertedInto().
+          This root node can tell inserted node where it is inserted,
+          specifically whetehr the insertion is to the document or not.
+
+        Same pattern is also applied to Node::removedFromDocument() and
+        Node::removedFromTree(), which are factored to Node::removedFrom()
+        and ChildNodeRemovalNotifier respectively.
+
+        Speed up on Dromaeo/dom-modify.html is about 2%.
+        Further speed-up by de-virtulization would be possible.
+
+        Caveat:
+
+        There is possible situation where a node need to invoke
+        insertedInto() after its children is nofitied, instead of before
+        that.  It was represented naturally with previous
+        traversal-by-ContainerNode pattern, but is no longer simple with
+        this new external traversal. To support this scenario, we
+        introduced the InsertionNotificationRequest as a return value of insertedInto()
+        and a supplemental hook Node::didNotifyDescendantInseretions(). See for
+        example HTMLFormElement.cpp to learn how it works.
+
+        No new tests. Covered by existing tests.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * Target.pri:
+        * WebCore.gypi:
+        * WebCore.xcodeproj/project.pbxproj:
+        * dom/ContainerNode.cpp:
+        (WebCore::ContainerNode::parserInsertBefore):
+        (WebCore::ContainerNode::removeChild):
+        (WebCore::ContainerNode::parserRemoveChild):
+        (WebCore::ContainerNode::removeChildren):
+        (WebCore::ContainerNode::parserAddChild):
+        (WebCore::updateTreeAfterInsertion):
+        * dom/ContainerNode.h:
+        (ContainerNode):
+        (WebCore::Node::highestAncestor):
+        (WebCore):
+        * dom/ContainerNodeAlgorithms.cpp: Added.
+        (WebCore):
+        (WebCore::ChildNodeInsertionNotifier::notifyDescendantInsertedIntoDocument):
+        (WebCore::ChildNodeInsertionNotifier::notifyDescendantInsertedIntoTree):
+        (WebCore::ChildNodeRemovalNotifier::notifyDescendantRemovedFromDocument):
+        (WebCore::ChildNodeRemovalNotifier::notifyDescendantRemovedFromTree):
+        * dom/ContainerNodeAlgorithms.h:
+        (ChildNodeInsertionNotifier):
+        (WebCore::ChildNodeInsertionNotifier::ChildNodeInsertionNotifier):
+        (WebCore):
+        (ChildNodeRemovalNotifier):
+        (WebCore::ChildNodeRemovalNotifier::ChildNodeRemovalNotifier):
+        (WebCore::removeAllChildrenInContainer):
+        (WebCore::appendChildToContainer):
+        (Private):
+        (WebCore::ChildNodeInsertionNotifier::notifyNodeInsertedIntoDocument):
+        (WebCore::ChildNodeInsertionNotifier::notifyNodeInsertedIntoTree):
+        (WebCore::ChildNodeInsertionNotifier::notifyInsertedIntoDocument):
+        (WebCore::ChildNodeInsertionNotifier::notify):
+        (WebCore::ChildNodeRemovalNotifier::notifyNodeRemovedFromDocument):
+        (WebCore::ChildNodeRemovalNotifier::notifyNodeRemovedFromTree):
+        (WebCore::ChildNodeRemovalNotifier::notify):
+        * dom/DOMAllInOne.cpp:
+        * dom/DocumentType.cpp:
+        (WebCore::DocumentType::insertedInto):
+        (WebCore::DocumentType::removedFrom):
+        * dom/DocumentType.h:
+        (DocumentType):
+        * dom/Element.cpp:
+        (WebCore::Element::insertedInto):
+        (WebCore::Element::removedFrom):
+        * dom/Element.h:
+        (Element):
+        * dom/Node.cpp:
+        (WebCore::Node::insertedInto):
+        (WebCore::Node::removedFrom):
+        * dom/Node.h:
+        (Node):
+        (WebCore::Node::didNotifyDescendantInseretions):
+        * dom/ProcessingInstruction.cpp:
+        (WebCore::ProcessingInstruction::insertedInto):
+        (WebCore::ProcessingInstruction::removedFrom):
+        * dom/ProcessingInstruction.h:
+        (ProcessingInstruction):
+        * dom/ScriptElement.cpp:
+        (WebCore::ScriptElement::insertedInto):
+        * dom/ScriptElement.h:
+        (WebCore):
+        (ScriptElement):
+        * dom/ShadowTree.cpp:
+        (WebCore::ShadowTree::addShadowRoot):
+        (WebCore::ShadowTree::removeAllShadowRoots):
+        * dom/ShadowTree.h:
+        (ShadowTree):
+        (ShadowRootVector):
+        (WebCore::ShadowRootVector::ShadowRootVector):
+        (WebCore):
+        * html/FormAssociatedElement.cpp:
+        (WebCore::FormAssociatedElement::insertedInto):
+        (WebCore::FormAssociatedElement::removedFrom):
+        (WebCore::FormAssociatedElement::formRemovedFromTree):
+        * html/FormAssociatedElement.h:
+        (FormAssociatedElement):
+        * html/HTMLBaseElement.cpp:
+        (WebCore::HTMLBaseElement::insertedInto):
+        (WebCore::HTMLBaseElement::removedFrom):
+        * html/HTMLBaseElement.h:
+        (HTMLBaseElement):
+        * html/HTMLBodyElement.cpp:
+        (WebCore::HTMLBodyElement::insertedInto):
+        (WebCore::HTMLBodyElement::didNotifyDescendantInseretions):
+        * html/HTMLBodyElement.h:
+        (HTMLBodyElement):
+        * html/HTMLFormControlElement.cpp:
+        (WebCore::HTMLFormControlElement::insertedInto):
+        (WebCore::HTMLFormControlElement::removedFrom):
+        * html/HTMLFormControlElement.h:
+        (HTMLFormControlElement):
+        * html/HTMLFormElement.cpp:
+        (WebCore::HTMLFormElement::insertedInto):
+        (WebCore::HTMLFormElement::didNotifyDescendantInseretions):
+        (WebCore::HTMLFormElement::removedFrom):
+        * html/HTMLFormElement.h:
+        (HTMLFormElement):
+        * html/HTMLFrameElementBase.cpp:
+        (WebCore::HTMLFrameElementBase::insertedInto):
+        (WebCore):
+        (WebCore::HTMLFrameElementBase::didNotifyDescendantInseretions):
+        * html/HTMLFrameElementBase.h:
+        (HTMLFrameElementBase):
+        * html/HTMLFrameSetElement.cpp:
+        (WebCore::HTMLFrameSetElement::insertedInto):
+        (WebCore::HTMLFrameSetElement::removedFrom):
+        * html/HTMLFrameSetElement.h:
+        (HTMLFrameSetElement):
+        * html/HTMLIFrameElement.cpp:
+        (WebCore::HTMLIFrameElement::insertedInto):
+        (WebCore::HTMLIFrameElement::removedFrom):
+        * html/HTMLIFrameElement.h:
+        (HTMLIFrameElement):
+        * html/HTMLImageElement.cpp:
+        (WebCore::HTMLImageElement::insertedInto):
+        (WebCore::HTMLImageElement::removedFrom):
+        * html/HTMLImageElement.h:
+        (HTMLImageElement):
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::insertedInto):
+        (WebCore::HTMLInputElement::removedFrom):
+        * html/HTMLInputElement.h:
+        * html/HTMLLinkElement.cpp:
+        (WebCore::HTMLLinkElement::insertedInto):
+        (WebCore::HTMLLinkElement::removedFrom):
+        * html/HTMLLinkElement.h:
+        (HTMLLinkElement):
+        * html/HTMLMapElement.cpp:
+        (WebCore::HTMLMapElement::insertedInto):
+        (WebCore::HTMLMapElement::removedFrom):
+        * html/HTMLMapElement.h:
+        (HTMLMapElement):
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::insertedInto):
+        (WebCore::HTMLMediaElement::removedFrom):
+        * html/HTMLMediaElement.h:
+        (HTMLMediaElement):
+        * html/HTMLMetaElement.cpp:
+        (WebCore::HTMLMetaElement::insertedInto):
+        * html/HTMLMetaElement.h:
+        (HTMLMetaElement):
+        * html/HTMLObjectElement.cpp:
+        (WebCore::HTMLObjectElement::insertedInto):
+        (WebCore::HTMLObjectElement::removedFrom):
+        * html/HTMLObjectElement.h:
+        (HTMLObjectElement):
+        * html/HTMLOptionElement.cpp:
+        (WebCore::HTMLOptionElement::insertedInto):
+        * html/HTMLOptionElement.h:
+        (HTMLOptionElement):
+        * html/HTMLQuoteElement.cpp:
+        (WebCore::HTMLQuoteElement::insertedInto):
+        * html/HTMLQuoteElement.h:
+        (HTMLQuoteElement):
+        * html/HTMLScriptElement.cpp:
+        (WebCore::HTMLScriptElement::insertedInto):
+        * html/HTMLScriptElement.h:
+        (HTMLScriptElement):
+        * html/HTMLSelectElement.cpp:
+        (WebCore::HTMLSelectElement::insertedInto):
+        * html/HTMLSelectElement.h:
+        * html/HTMLSourceElement.cpp:
+        (WebCore::HTMLSourceElement::insertedInto):
+        * html/HTMLSourceElement.h:
+        (HTMLSourceElement):
+        * html/HTMLStyleElement.cpp:
+        (WebCore::HTMLStyleElement::insertedInto):
+        (WebCore::HTMLStyleElement::removedFrom):
+        * html/HTMLStyleElement.h:
+        (HTMLStyleElement):
+        * html/HTMLTextFormControlElement.cpp:
+        (WebCore::HTMLTextFormControlElement::insertedInto):
+        * html/HTMLTextFormControlElement.h:
+        * html/HTMLTitleElement.cpp:
+        (WebCore::HTMLTitleElement::insertedInto):
+        (WebCore::HTMLTitleElement::removedFrom):
+        * html/HTMLTitleElement.h:
+        (HTMLTitleElement):
+        * html/HTMLTrackElement.cpp:
+        (WebCore::HTMLTrackElement::insertedInto):
+        * html/HTMLTrackElement.h:
+        (HTMLTrackElement):
+        * mathml/MathMLMathElement.cpp:
+        (WebCore::MathMLMathElement::insertedInto):
+        * mathml/MathMLMathElement.h:
+        (MathMLMathElement):
+        * svg/SVGElement.cpp:
+        (WebCore::SVGElement::removedFrom):
+        * svg/SVGElement.h:
+        (SVGElement):
+        * svg/SVGFEImageElement.cpp:
+        (WebCore::SVGFEImageElement::insertedInto):
+        (WebCore::SVGFEImageElement::removedFrom):
+        * svg/SVGFEImageElement.h:
+        (SVGFEImageElement):
+        * svg/SVGFontFaceElement.cpp:
+        (WebCore::SVGFontFaceElement::insertedInto):
+        (WebCore::SVGFontFaceElement::removedFrom):
+        * svg/SVGFontFaceElement.h:
+        (SVGFontFaceElement):
+        * svg/SVGFontFaceUriElement.cpp:
+        (WebCore::SVGFontFaceUriElement::insertedInto):
+        * svg/SVGFontFaceUriElement.h:
+        (SVGFontFaceUriElement):
+        * svg/SVGGlyphElement.cpp:
+        (WebCore::SVGGlyphElement::insertedInto):
+        (WebCore::SVGGlyphElement::removedFrom):
+        * svg/SVGGlyphElement.h:
+        (SVGGlyphElement):
+        * svg/SVGHKernElement.cpp:
+        (WebCore::SVGHKernElement::insertedInto):
+        (WebCore::SVGHKernElement::removedFrom):
+        * svg/SVGHKernElement.h:
+        (SVGHKernElement):
+        * svg/SVGImageElement.cpp:
+        (WebCore::SVGImageElement::insertedInto):
+        * svg/SVGImageElement.h:
+        (SVGImageElement):
+        * svg/SVGSVGElement.cpp:
+        (WebCore::SVGSVGElement::insertedInto):
+        (WebCore::SVGSVGElement::removedFrom):
+        * svg/SVGSVGElement.h:
+        (SVGSVGElement):
+        * svg/SVGScriptElement.cpp:
+        (WebCore::SVGScriptElement::insertedInto):
+        * svg/SVGScriptElement.h:
+        (SVGScriptElement):
+        * svg/SVGStyleElement.cpp:
+        (WebCore::SVGStyleElement::insertedInto):
+        (WebCore::SVGStyleElement::removedFrom):
+        * svg/SVGStyleElement.h:
+        (SVGStyleElement):
+        * svg/SVGStyledElement.cpp:
+        (WebCore::SVGStyledElement::insertedInto):
+        (WebCore::SVGStyledElement::removedFrom):
+        (WebCore::SVGStyledElement::updateRelativeLengthsInformation):
+        * svg/SVGStyledElement.h:
+        (SVGStyledElement):
+        * svg/SVGTRefElement.cpp:
+        (WebCore::SVGTRefElement::buildPendingResource):
+        (WebCore::SVGTRefElement::insertedInto):
+        (WebCore::SVGTRefElement::removedFrom):
+        * svg/SVGTRefElement.h:
+        (SVGTRefElement):
+        * svg/SVGTextPathElement.cpp:
+        (WebCore::SVGTextPathElement::insertedInto):
+        * svg/SVGTextPathElement.h:
+        * svg/SVGTitleElement.cpp:
+        (WebCore::SVGTitleElement::insertedInto):
+        (WebCore::SVGTitleElement::removedFrom):
+        * svg/SVGTitleElement.h:
+        (SVGTitleElement):
+        * svg/SVGUseElement.cpp:
+        (WebCore::SVGUseElement::insertedInto):
+        (WebCore::SVGUseElement::removedFrom):
+        * svg/SVGUseElement.h:
+        (SVGUseElement):
+        * svg/SVGVKernElement.cpp:
+        (WebCore::SVGVKernElement::insertedInto):
+        (WebCore::SVGVKernElement::removedFrom):
+        * svg/SVGVKernElement.h:
+        (SVGVKernElement):
+        * svg/animation/SVGSMILElement.cpp:
+        (WebCore::SVGSMILElement::insertedInto):
+        (WebCore::SVGSMILElement::removedFrom):
+        * svg/animation/SVGSMILElement.h:
+        (SVGSMILElement):
+
 2012-04-16  David Barr  <davidbarr@chromium.org>
 
         Stack overflow in CSS parser caused by recursive stylesheet import
index 4bd5dfd..952d583 100644 (file)
@@ -1759,6 +1759,7 @@ webcore_sources += \
        Source/WebCore/dom/CompositionEvent.cpp \
        Source/WebCore/dom/CompositionEvent.h \
        Source/WebCore/dom/ContainerNodeAlgorithms.h \
+       Source/WebCore/dom/ContainerNodeAlgorithms.cpp \
        Source/WebCore/dom/ContainerNode.cpp \
        Source/WebCore/dom/ContainerNode.h \
        Source/WebCore/dom/ContextDestructionObserver.cpp \
index e567a3d..b0e8e22 100644 (file)
@@ -518,6 +518,7 @@ SOURCES += \
     dom/ComposedShadowTreeWalker.cpp \
     dom/CompositionEvent.cpp \
     dom/ContainerNode.cpp \
+    dom/ContainerNodeAlgorithms.cpp \
     dom/ContextDestructionObserver.cpp \
     dom/CustomEvent.cpp \
     dom/DecodedDataDocumentParser.cpp \
@@ -1669,6 +1670,7 @@ HEADERS += \
     dom/Comment.h \
     dom/ComposedShadowTreeWalker.h \
     dom/ContainerNode.h \
+    dom/ContainerNodeAlgorithms.h \
     dom/CustomEvent.h \
     dom/default/PlatformMessagePortChannel.h \
     dom/DeviceMotionClient.h \
index 6843028..65b4b17 100644 (file)
             'dom/CompositionEvent.h',
             'dom/ContainerNode.cpp',
             'dom/ContainerNodeAlgorithms.h',
+            'dom/ContainerNodeAlgorithms.cpp',
             'dom/ContextDestructionObserver.cpp',
             'dom/CrossThreadTask.h',
             'dom/CustomEvent.cpp',
index f26bf1e..072081e 100644 (file)
                A78FE13C12366B1000ACE8D0 /* SpellChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = A78FE13A12366B1000ACE8D0 /* SpellChecker.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A795463E0B5C4C80007B438F /* DragDataMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = A795463D0B5C4C80007B438F /* DragDataMac.mm */; };
                A79546430B5C4CB4007B438F /* DragData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A79546420B5C4CB4007B438F /* DragData.cpp */; };
+               A7A78CD51532BA62006C21E4 /* ContainerNodeAlgorithms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7A78CD41532BA62006C21E4 /* ContainerNodeAlgorithms.cpp */; };
                A7AD2F870EC89D07008AB002 /* LinkHash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7AD2F850EC89D07008AB002 /* LinkHash.cpp */; };
                A7AD2F880EC89D07008AB002 /* LinkHash.h in Headers */ = {isa = PBXBuildFile; fileRef = A7AD2F860EC89D07008AB002 /* LinkHash.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A7B070D2130A409C00A3763C /* FrameActionScheduler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7B070D0130A409C00A3763C /* FrameActionScheduler.cpp */; };
                A78FE13A12366B1000ACE8D0 /* SpellChecker.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = SpellChecker.h; sourceTree = "<group>"; };
                A795463D0B5C4C80007B438F /* DragDataMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = DragDataMac.mm; sourceTree = "<group>"; };
                A79546420B5C4CB4007B438F /* DragData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DragData.cpp; sourceTree = "<group>"; };
+               A7A78CD41532BA62006C21E4 /* ContainerNodeAlgorithms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ContainerNodeAlgorithms.cpp; sourceTree = "<group>"; };
                A7AD2F850EC89D07008AB002 /* LinkHash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LinkHash.cpp; sourceTree = "<group>"; };
                A7AD2F860EC89D07008AB002 /* LinkHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinkHash.h; sourceTree = "<group>"; };
                A7B070D0130A409C00A3763C /* FrameActionScheduler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FrameActionScheduler.cpp; sourceTree = "<group>"; };
                                79F2F5A01091939A000D87CB /* CompositionEvent.idl */,
                                A81872140977D3C0005826D9 /* ContainerNode.cpp */,
                                A81872110977D3C0005826D9 /* ContainerNode.h */,
+                               A7A78CD41532BA62006C21E4 /* ContainerNodeAlgorithms.cpp */,
                                E1A1470711102B1500EEC0F3 /* ContainerNodeAlgorithms.h */,
                                97627B8B14FB3CEE002CDCA1 /* ContextDestructionObserver.cpp */,
                                97627B8C14FB3CEE002CDCA1 /* ContextDestructionObserver.h */,
                                BC0B36A40CD3C67C00AC7EB5 /* Console.cpp in Sources */,
                                41F0618F0F5F069800A07EAC /* ConsoleMessage.cpp in Sources */,
                                A818721F0977D3C0005826D9 /* ContainerNode.cpp in Sources */,
+                               A7A78CD51532BA62006C21E4 /* ContainerNodeAlgorithms.cpp in Sources */,
                                BC5EB9800E82072500B25965 /* ContentData.cpp in Sources */,
                                59102FBB14327D3B003C9D04 /* ContentSearchUtils.cpp in Sources */,
                                97C471DB12F925BD0086354B /* ContentSecurityPolicy.cpp in Sources */,
index 1be9cdf..8a68385 100644 (file)
@@ -47,7 +47,6 @@ using namespace std;
 
 namespace WebCore {
 
-static void notifyChildInserted(Node*);
 static void dispatchChildInsertionEvents(Node*);
 static void dispatchChildRemovalEvents(Node*);
 static void updateTreeAfterInsertion(ContainerNode*, Node*, bool shouldLazyAttach);
@@ -230,7 +229,7 @@ void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node* nextChil
         insertBeforeCommon(next.get(), child);
 
         childrenChanged(true, nextChildPreviousSibling.get(), nextChild, 1);
-        notifyChildInserted(child);
+        ChildNodeInsertionNotifier(this).notify(child);
     }
 }
 
@@ -406,11 +405,7 @@ bool ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec)
 
     childrenChanged(false, prev, next, -1);
 
-    if (child->inDocument())
-        child->removedFromDocument();
-    else if (child->isContainerNode())
-        toContainerNode(child.get())->removedFromTree(true);
-
+    ChildNodeRemovalNotifier(this).notify(child.get());
     dispatchSubtreeModifiedEvent();
 
     return child;
@@ -456,10 +451,7 @@ void ContainerNode::parserRemoveChild(Node* oldChild)
     removeBetween(prev, next, oldChild);
 
     childrenChanged(true, prev, next, -1);
-    if (oldChild->inDocument())
-        oldChild->removedFromDocument();
-    else if (oldChild->isContainerNode())
-        toContainerNode(oldChild)->removedFromTree(true);
+    ChildNodeRemovalNotifier(this).notify(oldChild);
 }
 
 // this differs from other remove functions because it forcibly removes all the children,
@@ -520,13 +512,8 @@ void ContainerNode::removeChildren()
 
     childrenChanged(false, 0, 0, -static_cast<int>(removedChildrenCount));
 
-    for (i = 0; i < removedChildrenCount; ++i) {
-        Node* removedChild = removedChildren[i].get();
-        if (removedChild->inDocument())
-            removedChild->removedFromDocument();
-        else if (removedChild->isContainerNode())
-            toContainerNode(removedChild)->removedFromTree(true);
-    }
+    for (i = 0; i < removedChildrenCount; ++i)
+        ChildNodeRemovalNotifier(this).notify(removedChildren[i].get());
 
     allowEventDispatch();
     dispatchSubtreeModifiedEvent();
@@ -603,9 +590,9 @@ void ContainerNode::parserAddChild(PassRefPtr<Node> newChild)
     
     allowEventDispatch();
 
-    // FIXME: Why doesn't this use notifyChildInserted(newChild) instead?
+    // FIXME: Why doesn't this use notify(newChild.get()) instead?
     if (inDocument())
-        newChild->insertedIntoDocument();
+        ChildNodeInsertionNotifier(this).notifyInsertedIntoDocument(newChild.get());
     childrenChanged(true, last, 0, 1);
 }
 
@@ -696,72 +683,6 @@ void ContainerNode::detach()
     Node::detach();
 }
 
-void ContainerNode::insertedIntoDocument()
-{
-    RefPtr<Node> protect(this);
-
-    Node::insertedIntoDocument();
-    insertedIntoTree(false);
-
-    NodeVector children;
-    getChildNodes(this, children);
-    for (size_t i = 0; i < children.size(); ++i) {
-        // If we have been removed from the document during this loop, then
-        // we don't want to tell the rest of our children that they've been
-        // inserted into the document because they haven't.
-        if (!inDocument())
-            break;
-        if (children[i]->parentNode() != this)
-            continue;
-        children[i]->insertedIntoDocument();
-    }
-}
-
-void ContainerNode::removedFromDocument()
-{
-    Node::removedFromDocument();
-    if (document()->cssTarget() == this) 
-        document()->setCSSTarget(0); 
-    removedFromTree(false);
-
-    NodeVector children;
-    getChildNodes(this, children);
-    for (size_t i = 0; i < children.size(); ++i) {
-        // If we have been added to the document during this loop, then we
-        // don't want to tell the rest of our children that they've been
-        // removed from the document because they haven't.
-        if (inDocument())
-            break;
-        if (children[i]->parentNode() != this)
-            continue;
-        children[i]->removedFromDocument();
-    }
-}
-
-void ContainerNode::insertedIntoTree(bool deep)
-{
-    if (!deep)
-        return;
-    forbidEventDispatch();
-    for (Node* child = m_firstChild; child; child = child->nextSibling()) {
-        if (child->isContainerNode())
-            toContainerNode(child)->insertedIntoTree(true);
-    }
-    allowEventDispatch();
-}
-
-void ContainerNode::removedFromTree(bool deep)
-{
-    if (!deep)
-        return;
-    forbidEventDispatch();
-    for (Node* child = m_firstChild; child; child = child->nextSibling()) {
-        if (child->isContainerNode())
-            toContainerNode(child)->removedFromTree(true);
-    }
-    allowEventDispatch();
-}
-
 void ContainerNode::childrenChanged(bool changedByParser, Node*, Node*, int childCountDelta)
 {
     document()->incDOMTreeVersion();
@@ -1007,23 +928,6 @@ Node *ContainerNode::childNode(unsigned index) const
     return n;
 }
 
-static void notifyChildInserted(Node* child)
-{
-    ASSERT(!eventDispatchForbidden());
-
-#if ENABLE(INSPECTOR)
-    InspectorInstrumentation::didInsertDOMNode(child->document(), child);
-#endif
-
-    RefPtr<Node> c = child;
-    RefPtr<Document> document = child->document();
-
-    Node* parentOrHostNode = c->parentOrHostNode();
-    if (parentOrHostNode && parentOrHostNode->inDocument())
-        c->insertedIntoDocument();
-    else if (c->isContainerNode())
-        toContainerNode(c.get())->insertedIntoTree(true);
-}
 
 static void dispatchChildInsertionEvents(Node* child)
 {
@@ -1092,7 +996,7 @@ static void updateTreeAfterInsertion(ContainerNode* parent, Node* child, bool sh
 
     parent->childrenChanged(false, child->previousSibling(), child->nextSibling(), 1);
 
-    notifyChildInserted(child);
+    ChildNodeInsertionNotifier(parent).notify(child);
 
     // FIXME: Attachment should be the first operation in this function, but some code
     // (for example, HTMLFormControlElement's autofocus support) requires this ordering.
index 970836b..98fa705 100644 (file)
@@ -77,19 +77,11 @@ public:
     virtual void setFocus(bool = true) OVERRIDE;
     virtual void setActive(bool active = true, bool pause = false) OVERRIDE;
     virtual void setHovered(bool = true) OVERRIDE;
-    virtual void insertedIntoDocument() OVERRIDE;
-    virtual void removedFromDocument() OVERRIDE;
     virtual void scheduleSetNeedsStyleRecalc(StyleChangeType = FullStyleChange) OVERRIDE;
 
     // -----------------------------------------------------------------------------
     // Notification of document structure changes (see Node.h for more notification methods)
 
-    // These functions are called whenever you are connected or disconnected from a tree. That tree may be the main
-    // document tree, or it could be another disconnected tree. Override these functions to do any work that depends
-    // on connectedness to some ancestor (e.g., an ancestor <form>).
-    virtual void insertedIntoTree(bool deep);
-    virtual void removedFromTree(bool deep);
-
     // Notifies the node that it's list of children have changed (either by adding or removing child nodes), or a child
     // node that is of the type CDATA_SECTION_NODE, TEXT_NODE or COMMENT_NODE has changed its value.
     virtual void childrenChanged(bool createdByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
@@ -227,6 +219,15 @@ inline Node* Node::lastChild() const
     return toContainerNode(this)->lastChild();
 }
 
+inline Node* Node::highestAncestor() const
+{
+    Node* node = const_cast<Node*>(this);
+    Node* highest = node;
+    for (; node; node = node->parentNode())
+        highest = node;
+    return highest;
+}
+
 typedef Vector<RefPtr<Node>, 11> NodeVector;
 
 inline void getChildNodes(Node* node, NodeVector& nodes)
diff --git a/Source/WebCore/dom/ContainerNodeAlgorithms.cpp b/Source/WebCore/dom/ContainerNodeAlgorithms.cpp
new file mode 100644 (file)
index 0000000..edb84da
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ *           (C) 1999 Antti Koivisto (koivisto@kde.org)
+ *           (C) 2001 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "ContainerNodeAlgorithms.h"
+
+#include "Element.h"
+#include "ShadowTree.h"
+
+namespace WebCore {
+
+void ChildNodeInsertionNotifier::notifyDescendantInsertedIntoDocument(ContainerNode* node)
+{
+    NodeVector children;
+    getChildNodes(node, children);
+    for (size_t i = 0; i < children.size(); ++i) {
+        // If we have been removed from the document during this loop, then
+        // we don't want to tell the rest of our children that they've been
+        // inserted into the document because they haven't.
+        if (node->inDocument() && children[i]->parentNode() == node)
+            notifyNodeInsertedIntoDocument(children[i].get());
+    }
+        
+    if (!node->isElementNode())
+        return;
+
+    if (ShadowTree* tree = toElement(node)->shadowTree()) {
+        ShadowRootVector roots(tree);
+        for (size_t i = 0; i < roots.size(); ++i)
+            notifyNodeInsertedIntoDocument(roots[i].get());
+    }
+}
+
+void ChildNodeInsertionNotifier::notifyDescendantInsertedIntoTree(ContainerNode* node)
+{
+    for (Node* child = node->firstChild(); child; child = child->nextSibling()) {
+        if (child->isContainerNode())
+            notifyNodeInsertedIntoTree(toContainerNode(child));
+    }
+
+    if (!node->isElementNode())
+        return;
+
+    if (ShadowTree* tree = toElement(node)->shadowTree()) {
+        for (ShadowRoot* root = tree->youngestShadowRoot(); root; root = root->olderShadowRoot())
+            notifyNodeInsertedIntoTree(root);
+    }
+}
+
+void ChildNodeRemovalNotifier::notifyDescendantRemovedFromDocument(ContainerNode* node)
+{
+    NodeVector children;
+    getChildNodes(node, children);
+    for (size_t i = 0; i < children.size(); ++i) {
+        // If we have been added to the document during this loop, then we
+        // don't want to tell the rest of our children that they've been
+        // removed from the document because they haven't.
+        if (!node->inDocument() && children[i]->parentNode() == node)
+            notifyNodeRemovedFromDocument(children[i].get());
+    }
+
+    if (!node->isElementNode())
+        return;
+
+    if (node->document()->cssTarget() == node)
+        node->document()->setCSSTarget(0);
+
+    if (ShadowTree* tree = toElement(node)->shadowTree()) {
+        ShadowRootVector roots(tree);
+        for (size_t i = 0; i < roots.size(); ++i)
+            notifyNodeRemovedFromDocument(roots[i].get());
+    }
+}
+
+void ChildNodeRemovalNotifier::notifyDescendantRemovedFromTree(ContainerNode* node)
+{
+    for (Node* child = node->firstChild(); child; child = child->nextSibling()) {
+        if (child->isContainerNode())
+            notifyNodeRemovedFromTree(toContainerNode(child));
+    }
+
+    if (!node->isElementNode())
+        return;
+
+    if (ShadowTree* tree = toElement(node)->shadowTree()) {
+        ShadowRootVector roots(tree);
+        for (size_t i = 0; i < roots.size(); ++i)
+            notifyNodeRemovedFromTree(roots[i].get());
+    }
+}
+
+}
index b322289..5c11e8c 100644 (file)
 #ifndef ContainerNodeAlgorithms_h
 #define ContainerNodeAlgorithms_h
 
-#include <Document.h>
+#include "Document.h"
+#include "InspectorInstrumentation.h"
 #include <wtf/Assertions.h>
 
 namespace WebCore {
 
 class Node;
 
+class ChildNodeInsertionNotifier {
+public:
+    explicit ChildNodeInsertionNotifier(Node* insertionPoint)
+        : m_insertionPoint(insertionPoint)
+    { }
+
+    void notifyInsertedIntoDocument(Node*);
+    void notify(Node*);
+
+private:
+    void notifyDescendantInsertedIntoDocument(ContainerNode*);
+    void notifyDescendantInsertedIntoTree(ContainerNode*);
+    void notifyNodeInsertedIntoDocument(Node*);
+    void notifyNodeInsertedIntoTree(ContainerNode*);
+
+    Node* m_insertionPoint;
+};
+
+class ChildNodeRemovalNotifier {
+public:
+    explicit ChildNodeRemovalNotifier(Node* insertionPoint)
+        : m_insertionPoint(insertionPoint)
+    { }
+
+    void notify(Node*);
+
+private:
+    void notifyDescendantRemovedFromDocument(ContainerNode*);
+    void notifyDescendantRemovedFromTree(ContainerNode*);
+    void notifyNodeRemovedFromDocument(Node*);
+    void notifyNodeRemovedFromTree(ContainerNode*);
+
+    Node* m_insertionPoint;
+};
+
 namespace Private {
 
     template<class GenericNode, class GenericNodeContainer>
@@ -39,7 +75,7 @@ namespace Private {
 // Helper functions for TreeShared-derived classes, which have a 'Node' style interface
 // This applies to 'ContainerNode' and 'SVGElementInstance'
 template<class GenericNode, class GenericNodeContainer>
-void removeAllChildrenInContainer(GenericNodeContainer* container)
+inline void removeAllChildrenInContainer(GenericNodeContainer* container)
 {
     // List of nodes to be deleted.
     GenericNode* head = 0;
@@ -67,7 +103,7 @@ void removeAllChildrenInContainer(GenericNodeContainer* container)
 }
 
 template<class GenericNode, class GenericNodeContainer>
-void appendChildToContainer(GenericNode* child, GenericNodeContainer* container)
+inline void appendChildToContainer(GenericNode* child, GenericNodeContainer* container)
 {
     child->setParent(container);
 
@@ -100,7 +136,7 @@ namespace Private {
             if (Document* containerDocument = container->ownerDocument())
                 containerDocument->adoptIfNeeded(node);
             if (node->inDocument())
-                node->removedFromDocument();
+                ChildNodeRemovalNotifier(container).notify(node);
         }
     };
 
@@ -148,7 +184,86 @@ namespace Private {
         container->setFirstChild(0);
         container->setLastChild(0);
     }
-};
+
+} // namespace Private
+
+inline void ChildNodeInsertionNotifier::notifyNodeInsertedIntoDocument(Node* node)
+{
+    ASSERT(m_insertionPoint->inDocument());
+    RefPtr<Node> protect(node);
+    Node::InsertionNotificationRequest request = node->insertedInto(m_insertionPoint);
+
+    if (node->isContainerNode())
+        notifyDescendantInsertedIntoDocument(toContainerNode(node));
+
+    if (request == Node::InsertionShouldCallDidNotifyDescendantInseretions)
+        node->didNotifyDescendantInseretions(m_insertionPoint);
+}
+
+inline void ChildNodeInsertionNotifier::notifyNodeInsertedIntoTree(ContainerNode* node)
+{
+    ASSERT(!m_insertionPoint->inDocument());
+    forbidEventDispatch();
+
+    Node::InsertionNotificationRequest request = node->insertedInto(m_insertionPoint);
+
+    notifyDescendantInsertedIntoTree(node);
+    if (request == Node::InsertionShouldCallDidNotifyDescendantInseretions)
+        node->didNotifyDescendantInseretions(m_insertionPoint);
+
+    allowEventDispatch();
+}
+
+inline void ChildNodeInsertionNotifier::notifyInsertedIntoDocument(Node* node)
+{
+    notifyNodeInsertedIntoDocument(node);
+}
+
+inline void ChildNodeInsertionNotifier::notify(Node* node)
+{
+    ASSERT(!eventDispatchForbidden());
+
+#if ENABLE(INSPECTOR)
+    InspectorInstrumentation::didInsertDOMNode(node->document(), node);
+#endif
+
+    RefPtr<Document> protectDocument(node->document());
+    RefPtr<Node> protectNode(node);
+
+    if (m_insertionPoint->inDocument())
+        notifyNodeInsertedIntoDocument(node);
+    else if (node->isContainerNode())
+        notifyNodeInsertedIntoTree(toContainerNode(node));
+}
+
+
+inline void ChildNodeRemovalNotifier::notifyNodeRemovedFromDocument(Node* node)
+{
+    ASSERT(m_insertionPoint->inDocument());
+    node->removedFrom(m_insertionPoint);
+
+    if (node->isContainerNode())
+        notifyDescendantRemovedFromDocument(toContainerNode(node));
+}
+
+inline void ChildNodeRemovalNotifier::notifyNodeRemovedFromTree(ContainerNode* node)
+{
+    ASSERT(!m_insertionPoint->inDocument());
+    forbidEventDispatch();
+
+    node->removedFrom(m_insertionPoint);
+    notifyDescendantRemovedFromTree(node);
+
+    allowEventDispatch();
+}
+
+inline void ChildNodeRemovalNotifier::notify(Node* node)
+{
+    if (node->inDocument())
+        notifyNodeRemovedFromDocument(node);
+    else if (node->isContainerNode())
+        notifyNodeRemovedFromTree(toContainerNode(node));
+}
 
 } // namespace WebCore
 
index 929b281..3ec6604 100644 (file)
@@ -43,6 +43,7 @@
 #include "Comment.cpp"
 #include "CompositionEvent.cpp"
 #include "ContainerNode.cpp"
+#include "ContainerNodeAlgorithms.cpp"
 #include "ContextDestructionObserver.cpp"
 #include "CustomEvent.cpp"
 #include "DOMCoreException.cpp"
index ed4b96c..a67a6b5 100644 (file)
@@ -56,8 +56,12 @@ PassRefPtr<Node> DocumentType::cloneNode(bool /*deep*/)
     return create(document(), m_name, m_publicId, m_systemId);
 }
 
-void DocumentType::insertedIntoDocument()
+Node::InsertionNotificationRequest DocumentType::insertedInto(Node* insertionPoint)
 {
+    Node::insertedInto(insertionPoint);
+    if (!insertionPoint->inDocument())
+        return InsertionDone;
+
     // Our document node can be null if we were created by a DOMImplementation.  We use the parent() instead.
     ASSERT(parentNode() && parentNode()->isDocumentNode());
     if (parentNode() && parentNode()->isDocumentNode()) {
@@ -65,14 +69,15 @@ void DocumentType::insertedIntoDocument()
         if (!doc->doctype())
             doc->setDocType(this);
     }
-    Node::insertedIntoDocument();
+
+    return InsertionDone;
 }
 
-void DocumentType::removedFromDocument()
+void DocumentType::removedFrom(Node* insertionPoint)
 {
-    if (document() && document()->doctype() == this)
+    if (insertionPoint->inDocument() && document() && document()->doctype() == this)
         document()->setDocType(0);
-    Node::removedFromDocument();
+    Node::removedFrom(insertionPoint);
 }
 
 }
index fd6c891..e523efb 100644 (file)
@@ -54,8 +54,8 @@ private:
     virtual NodeType nodeType() const;
     virtual PassRefPtr<Node> cloneNode(bool deep);
 
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
 
     OwnPtr<NamedNodeMap> m_entities;
     OwnPtr<NamedNodeMap> m_notations;
index 69c74d5..d641b85 100644 (file)
@@ -881,13 +881,19 @@ void Element::willRemove()
     ContainerNode::willRemove();
 }
 
-void Element::insertedIntoDocument()
+Node::InsertionNotificationRequest Element::insertedInto(Node* insertionPoint)
 {
     // need to do superclass processing first so inDocument() is true
     // by the time we reach updateId
-    ContainerNode::insertedIntoDocument();
-    if (ShadowTree* tree = shadowTree())
-        tree->insertedIntoDocument();
+    ContainerNode::insertedInto(insertionPoint);
+
+#if ENABLE(FULLSCREEN_API)
+    if (containsFullScreenElement() && parentElement() && !parentElement()->containsFullScreenElement())
+        setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
+#endif
+
+    if (!insertionPoint->inDocument())
+        return InsertionDone;
 
     if (m_attributeData) {
         if (hasID()) {
@@ -901,51 +907,30 @@ void Element::insertedIntoDocument()
                 updateName(nullAtom, nameItem->value());
         }
     }
+
+    return InsertionDone;
 }
 
-void Element::removedFromDocument()
+void Element::removedFrom(Node* insertionPoint)
 {
     setSavedLayerScrollOffset(IntSize());
 
-    if (m_attributeData) {
-        if (hasID()) {
-            Attribute* idItem = getAttributeItem(document()->idAttributeName());
-            if (idItem && !idItem->isNull())
-                updateId(idItem->value(), nullAtom);
-        }
-        if (hasName()) {
-            Attribute* nameItem = getAttributeItem(HTMLNames::nameAttr);
-            if (nameItem && !nameItem->isNull())
-                updateName(nameItem->value(), nullAtom);
+    if (insertionPoint->inDocument()) {
+        if (m_attributeData) {
+            if (hasID()) {
+                Attribute* idItem = getAttributeItem(document()->idAttributeName());
+                if (idItem && !idItem->isNull())
+                    updateId(idItem->value(), nullAtom);
+            }
+            if (hasName()) {
+                Attribute* nameItem = getAttributeItem(HTMLNames::nameAttr);
+                if (nameItem && !nameItem->isNull())
+                    updateName(nameItem->value(), nullAtom);
+            }
         }
     }
 
-    ContainerNode::removedFromDocument();
-    if (ShadowTree* tree = shadowTree())
-        tree->removedFromDocument();
-}
-
-void Element::insertedIntoTree(bool deep)
-{
-    ContainerNode::insertedIntoTree(deep);
-    if (!deep)
-        return;
-    if (ShadowTree* tree = shadowTree())
-        tree->insertedIntoTree(true);
-
-#if ENABLE(FULLSCREEN_API)
-    if (containsFullScreenElement() && parentElement() && !parentElement()->containsFullScreenElement())
-        setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
-#endif
-}
-
-void Element::removedFromTree(bool deep)
-{
-    ContainerNode::removedFromTree(deep);
-    if (!deep)
-        return;
-    if (ShadowTree* tree = shadowTree())
-        tree->removedFromTree(true);
+    ContainerNode::removedFrom(insertionPoint);
 }
 
 void Element::attach()
index be26547..8db059c 100644 (file)
@@ -413,10 +413,8 @@ protected:
     }
 
     virtual void willRemove();
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
-    virtual void insertedIntoTree(bool);
-    virtual void removedFromTree(bool);
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
     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) { }
index 332522b..54606b8 100644 (file)
@@ -2385,14 +2385,19 @@ ScriptExecutionContext* Node::scriptExecutionContext() const
     return document();
 }
 
-void Node::insertedIntoDocument()
+Node::InsertionNotificationRequest Node::insertedInto(Node* insertionPoint)
 {
-    setFlag(InDocumentFlag);
+    ASSERT(insertionPoint->inDocument() || isContainerNode());
+    if (insertionPoint->inDocument())
+        setFlag(InDocumentFlag);
+    return InsertionDone;
 }
 
-void Node::removedFromDocument()
+void Node::removedFrom(Node* insertionPoint)
 {
-    clearFlag(InDocumentFlag);
+    ASSERT(insertionPoint->inDocument() || isContainerNode());
+    if (insertionPoint->inDocument())
+        clearFlag(InDocumentFlag);
 }
 
 void Node::didMoveToNewDocument(Document* oldDocument)
index 301c161..acae281 100644 (file)
@@ -225,6 +225,8 @@ public:
     // Node's parent, shadow tree host.
     ContainerNode* parentOrHostNode() const;
     Element* parentOrHostElement() const;
+    Node* highestAncestor() const;
+
     // Use when it's guaranteed to that shadowHost is 0.
     ContainerNode* parentNodeGuaranteedHostFree() const;
     // Returns the parent node, but 0 if the parent node is a ShadowRoot.
@@ -504,22 +506,34 @@ public:
 
     // -----------------------------------------------------------------------------
     // Notification of document structure changes (see ContainerNode.h for more notification methods)
-
-    // Notifies the node that it has been inserted into the document. This is called during document parsing, and also
-    // when a node is added through the DOM methods insertBefore(), appendChild() or replaceChild(). Note that this only
-    // happens when the node becomes part of the document tree, i.e. only when the document is actually an ancestor of
-    // the node. The call happens _after_ the node has been added to the tree.
     //
+    // At first, WebKit notifies the node that it has been inserted into the document. This is called during document parsing, and also
+    // when a node is added through the DOM methods insertBefore(), appendChild() or replaceChild(). The call happens _after_ the node has been added to the tree.
     // This is similar to the DOMNodeInsertedIntoDocument DOM event, but does not require the overhead of event
     // dispatching.
-    virtual void insertedIntoDocument();
+    //
+    // Webkit notifies this callback regardless if the subtree of the node is a document tree or a floating subtree.
+    // Implementation can determine the type of subtree by seeing insertionPoint->inDocument().
+    // For a performance reason, notifications are delivered only to ContainerNode subclasses if the insertionPoint is out of document.
+    //
+    // There are another callback named didNotifyDescendantInseretions(), which is called after all the descendant is notified.
+    // Only a few subclasses actually need this. To utilize this, the node should return InsertionShouldCallDidNotifyDescendantInseretions
+    // from insrtedInto().
+    //
+    enum InsertionNotificationRequest {
+        InsertionDone,
+        InsertionShouldCallDidNotifyDescendantInseretions
+    };
 
-    // Notifies the node that it is no longer part of the document tree, i.e. when the document is no longer an ancestor
-    // node.
+    virtual InsertionNotificationRequest insertedInto(Node* insertionPoint);
+    virtual void didNotifyDescendantInseretions(Node*) { }
+
+    // Notifies the node that it is no longer part of the tree.
     //
-    // This is similar to the DOMNodeRemovedFromDocument DOM event, but does not require the overhead of event
+    // This is a dual of insertedInto(), and is similar to the DOMNodeRemovedFromDocument DOM event, but does not require the overhead of event
     // dispatching, and is called _after_ the node is removed from the tree.
-    virtual void removedFromDocument();
+    //
+    virtual void removedFrom(Node* insertionPoint);
 
 #ifndef NDEBUG
     virtual void formatForDebugger(char* buffer, unsigned length) const;
index 6d201cb..b8a7c2f 100644 (file)
@@ -282,17 +282,22 @@ void ProcessingInstruction::addSubresourceAttributeURLs(ListHashSet<KURL>& urls)
     addSubresourceURL(urls, sheet()->baseURL());
 }
 
-void ProcessingInstruction::insertedIntoDocument()
+Node::InsertionNotificationRequest ProcessingInstruction::insertedInto(Node* insertionPoint)
 {
-    Node::insertedIntoDocument();
+    Node::insertedInto(insertionPoint);
+    if (!insertionPoint->inDocument())
+        return InsertionDone;
     document()->addStyleSheetCandidateNode(this, m_createdByParser);
     checkStyleSheet();
+    return InsertionDone;
 }
 
-void ProcessingInstruction::removedFromDocument()
+void ProcessingInstruction::removedFrom(Node* insertionPoint)
 {
-    Node::removedFromDocument();
-
+    Node::removedFrom(insertionPoint);
+    if (!insertionPoint->inDocument())
+        return;
+    
     document()->removeStyleSheetCandidateNode(this);
 
     if (m_sheet) {
index 2a619ad..04accd5 100644 (file)
@@ -64,8 +64,8 @@ private:
     virtual bool offsetInCharacters() const;
     virtual int maxCharacterOffset() const;
 
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
 
     void checkStyleSheet();
     virtual void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet*);
index b1129ac..bdc1fcd 100644 (file)
@@ -77,9 +77,9 @@ ScriptElement::~ScriptElement()
     stopLoadRequest();
 }
 
-void ScriptElement::insertedIntoDocument()
+void ScriptElement::insertedInto(Node* insertionPoint)
 {
-    if (!m_parserInserted)
+    if (insertionPoint->inDocument() && !m_parserInserted)
         prepareScript(); // FIXME: Provide a real starting line number here.
 }
 
index dbe6bbc..6c08258 100644 (file)
@@ -29,6 +29,7 @@ namespace WebCore {
 
 class CachedScript;
 class Element;
+class Node;
 class ScriptElement;
 class ScriptSourceCode;
 
@@ -66,7 +67,7 @@ protected:
     bool forceAsync() const { return m_forceAsync; }
 
     // Helper functions used by our parent classes.
-    void insertedIntoDocument();
+    void insertedInto(Node*);
     void childrenChanged();
     void handleSourceAttribute(const String& sourceUrl);
     void handleAsyncAttribute();
index 6fbe729..171cddb 100644 (file)
@@ -28,6 +28,7 @@
 #include "ShadowTree.h"
 
 #include "CSSStyleSelector.h"
+#include "ContainerNodeAlgorithms.h"
 #include "Document.h"
 #include "Element.h"
 #include "HTMLShadowElement.h"
 
 namespace WebCore {
 
-class ShadowRootVector : public Vector<RefPtr<ShadowRoot> > {
-public:
-    explicit ShadowRootVector(ShadowTree* tree)
-    {
-        for (ShadowRoot* root = tree->youngestShadowRoot(); root; root = root->olderShadowRoot())
-            append(root);
-    }
-};
-
 ShadowTree::ShadowTree()
     : m_needsRecalculateContent(false)
 {
@@ -85,9 +77,8 @@ void ShadowTree::addShadowRoot(Element* shadowHost, PassRefPtr<ShadowRoot> shado
         return;
 
     shadowRoot->setShadowHost(shadowHost);
+    ChildNodeInsertionNotifier(shadowHost).notify(shadowRoot.get());
 
-    if (shadowHost->inDocument())
-        shadowRoot->insertedIntoDocument();
     if (shadowHost->attached()) {
         shadowRoot->lazyAttach();
         detach();
@@ -117,44 +108,13 @@ void ShadowTree::removeAllShadowRoots()
         oldRoot->setPrev(0);
         oldRoot->setNext(0);
         shadowHost->document()->adoptIfNeeded(oldRoot.get());
-        if (oldRoot->inDocument())
-            oldRoot->removedFromDocument();
-        else
-            oldRoot->removedFromTree(true);
+        ChildNodeRemovalNotifier(shadowHost).notify(oldRoot.get());
     }
 
     if (shadowHost->attached())
         shadowHost->attachChildrenLazily();
 }
 
-void ShadowTree::insertedIntoDocument()
-{
-    ShadowRootVector roots(this);
-    for (size_t i = 0; i < roots.size(); ++i)
-        roots[i]->insertedIntoDocument();
-}
-
-void ShadowTree::removedFromDocument()
-{
-    ShadowRootVector roots(this);
-    for (size_t i = 0; i < roots.size(); ++i)
-        roots[i]->removedFromDocument();
-}
-
-void ShadowTree::insertedIntoTree(bool deep)
-{
-    ShadowRootVector roots(this);
-    for (size_t i = 0; i < roots.size(); ++i)
-        roots[i]->insertedIntoTree(deep);
-}
-
-void ShadowTree::removedFromTree(bool deep)
-{
-    ShadowRootVector roots(this);
-    for (size_t i = 0; i < roots.size(); ++i)
-        roots[i]->removedFromTree(deep);
-}
-
 void ShadowTree::willRemove()
 {
     ShadowRootVector roots(this);
index e9c2cca..3ba086d 100644 (file)
@@ -34,6 +34,7 @@
 #include <wtf/Noncopyable.h>
 #include <wtf/OwnPtr.h>
 #include <wtf/PassRefPtr.h>
+#include <wtf/Vector.h>
 
 namespace WebCore {
 
@@ -57,10 +58,6 @@ public:
     void addShadowRoot(Element* shadowHost, PassRefPtr<ShadowRoot>, ExceptionCode&);
     void removeAllShadowRoots();
 
-    void insertedIntoDocument();
-    void removedFromDocument();
-    void insertedIntoTree(bool deep);
-    void removedFromTree(bool deep);
     void willRemove();
 
     void setParentTreeScope(TreeScope*);
@@ -130,6 +127,15 @@ inline Element* ShadowTree::host() const
     return youngestShadowRoot()->host();
 }
 
+class ShadowRootVector : public Vector<RefPtr<ShadowRoot> > {
+public:
+    explicit ShadowRootVector(ShadowTree* tree)
+    {
+        for (ShadowRoot* root = tree->youngestShadowRoot(); root; root = root->olderShadowRoot())
+            append(root);
+    }
+};
+
 } // namespace
 
 #endif
index df8937b..665efa7 100644 (file)
@@ -60,18 +60,26 @@ void FormAssociatedElement::didMoveToNewDocument(Document* oldDocument)
         oldDocument->unregisterFormElementWithFormAttribute(this);
 }
 
-void FormAssociatedElement::insertedIntoDocument()
+void FormAssociatedElement::insertedInto(Node* insertionPoint)
 {
+    resetFormOwner();
+    if (!insertionPoint->inDocument())
+        return;
+
     HTMLElement* element = toHTMLElement(this);
     if (element->fastHasAttribute(formAttr))
         element->document()->registerFormElementWithFormAttribute(this);
 }
 
-void FormAssociatedElement::removedFromDocument()
+void FormAssociatedElement::removedFrom(Node* insertionPoint)
 {
     HTMLElement* element = toHTMLElement(this);
-    if (element->fastHasAttribute(formAttr))
+    if (insertionPoint->inDocument() && element->fastHasAttribute(formAttr))
         element->document()->unregisterFormElementWithFormAttribute(this);
+    // If the form and element are both in the same tree, preserve the connection to the form.
+    // Otherwise, null out our form and remove ourselves from the form's list of elements.
+    if (m_form && element->highestAncestor() != m_form->highestAncestor())
+        setForm(0);
 }
 
 HTMLFormElement* FormAssociatedElement::findAssociatedForm(const HTMLElement* element, HTMLFormElement* currentAssociatedForm)
@@ -95,33 +103,10 @@ HTMLFormElement* FormAssociatedElement::findAssociatedForm(const HTMLElement* el
     return currentAssociatedForm;
 }
 
-void FormAssociatedElement::insertedIntoTree()
-{
-    resetFormOwner();
-}
-
-static inline Node* findRoot(Node* n)
-{
-    Node* root = n;
-    for (; n; n = n->parentNode())
-        root = n;
-    return root;
-}
-
-void FormAssociatedElement::removedFromTree()
-{
-    HTMLElement* element = toHTMLElement(this);
-
-    // If the form and element are both in the same tree, preserve the connection to the form.
-    // Otherwise, null out our form and remove ourselves from the form's list of elements.
-    if (m_form && findRoot(element) != findRoot(m_form))
-        setForm(0);
-}
-
 void FormAssociatedElement::formRemovedFromTree(const Node* formRoot)
 {
     ASSERT(m_form);
-    if (findRoot(toHTMLElement(this)) != formRoot)
+    if (toHTMLElement(this)->highestAncestor() != formRoot)
         setForm(0);
 }
 
index 6a27323..284e298 100644 (file)
@@ -63,10 +63,8 @@ public:
 protected:
     FormAssociatedElement();
 
-    void insertedIntoTree();
-    void removedFromTree();
-    void insertedIntoDocument();
-    void removedFromDocument();
+    void insertedInto(Node*);
+    void removedFrom(Node*);
     void didMoveToNewDocument(Document* oldDocument);
 
     void setForm(HTMLFormElement*);
index b3da89a..3c1c3f3 100644 (file)
@@ -50,16 +50,19 @@ void HTMLBaseElement::parseAttribute(Attribute* attribute)
         HTMLElement::parseAttribute(attribute);
 }
 
-void HTMLBaseElement::insertedIntoDocument()
+Node::InsertionNotificationRequest HTMLBaseElement::insertedInto(Node* insertionPoint)
 {
-    HTMLElement::insertedIntoDocument();
-    document()->processBaseElement();
+    HTMLElement::insertedInto(insertionPoint);
+    if (insertionPoint->inDocument())
+        document()->processBaseElement();
+    return InsertionDone;
 }
 
-void HTMLBaseElement::removedFromDocument()
+void HTMLBaseElement::removedFrom(Node* insertionPoint)
 {
-    HTMLElement::removedFromDocument();
-    document()->processBaseElement();
+    HTMLElement::removedFrom(insertionPoint);
+    if (insertionPoint->inDocument())
+        document()->processBaseElement();
 }
 
 bool HTMLBaseElement::isURLAttribute(Attribute* attribute) const
index 5f526a6..2334d7e 100644 (file)
@@ -37,8 +37,8 @@ private:
     virtual String target() const;
     virtual bool isURLAttribute(Attribute*) const;
     virtual void parseAttribute(Attribute*) OVERRIDE;
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
 };
 
 } // namespace
index a6b5b21..28325b2 100644 (file)
@@ -152,10 +152,17 @@ void HTMLBodyElement::parseAttribute(Attribute* attr)
         HTMLElement::parseAttribute(attr);
 }
 
-void HTMLBodyElement::insertedIntoDocument()
+Node::InsertionNotificationRequest HTMLBodyElement::insertedInto(Node* insertionPoint)
 {
-    HTMLElement::insertedIntoDocument();
+    HTMLElement::insertedInto(insertionPoint);
+    if (insertionPoint->inDocument())
+        return InsertionShouldCallDidNotifyDescendantInseretions;
+    return InsertionDone;
+}
 
+void HTMLBodyElement::didNotifyDescendantInseretions(Node* insertionPoint)
+{
+    ASSERT_UNUSED(insertionPoint, insertionPoint->inDocument());
     ASSERT(document());
 
     // FIXME: Perhaps this code should be in attach() instead of here.
index a0dce1f..b18bd6d 100644 (file)
@@ -74,7 +74,8 @@ private:
     virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
     virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
 
-    virtual void insertedIntoDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void didNotifyDescendantInseretions(Node*) OVERRIDE;
     
     virtual bool isURLAttribute(Attribute*) const;
     
index 221f0ce..371c2dc 100644 (file)
@@ -221,29 +221,18 @@ void HTMLFormControlElement::didMoveToNewDocument(Document* oldDocument)
     HTMLElement::didMoveToNewDocument(oldDocument);
 }
 
-void HTMLFormControlElement::insertedIntoTree(bool deep)
+Node::InsertionNotificationRequest HTMLFormControlElement::insertedInto(Node* insertionPoint)
 {
-    FormAssociatedElement::insertedIntoTree();
-    HTMLElement::insertedIntoTree(deep);
+    HTMLElement::insertedInto(insertionPoint);
+    FormAssociatedElement::insertedInto(insertionPoint);
+    return InsertionDone;
 }
 
-void HTMLFormControlElement::removedFromTree(bool deep)
+void HTMLFormControlElement::removedFrom(Node* insertionPoint)
 {
     m_fieldSetAncestorValid = false;
-    FormAssociatedElement::removedFromTree();
-    HTMLElement::removedFromTree(deep);
-}
-
-void HTMLFormControlElement::insertedIntoDocument()
-{
-    HTMLElement::insertedIntoDocument();
-    FormAssociatedElement::insertedIntoDocument();
-}
-
-void HTMLFormControlElement::removedFromDocument()
-{
-    HTMLElement::removedFromDocument();
-    FormAssociatedElement::removedFromDocument();
+    HTMLElement::removedFrom(insertionPoint);
+    FormAssociatedElement::removedFrom(insertionPoint);
 }
 
 const AtomicString& HTMLFormControlElement::formControlName() const
index fbaf527..39bb588 100644 (file)
@@ -120,10 +120,8 @@ protected:
     virtual void requiredAttributeChanged();
     virtual void disabledAttributeChanged();
     virtual void attach();
-    virtual void insertedIntoTree(bool deep);
-    virtual void removedFromTree(bool deep);
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
     virtual void didMoveToNewDocument(Document* oldDocument) OVERRIDE;
 
     virtual bool supportsFocus() const;
index 031bb6b..1179699 100644 (file)
@@ -130,18 +130,18 @@ bool HTMLFormElement::rendererIsNeeded(const NodeRenderingContext& context)
     return formIsTablePart;
 }
 
-void HTMLFormElement::insertedIntoDocument()
+Node::InsertionNotificationRequest HTMLFormElement::insertedInto(Node* insertionPoint)
 {
-    HTMLElement::insertedIntoDocument();
-
-    if (hasID())
-        document()->resetFormElementsOwner();
+    HTMLElement::insertedInto(insertionPoint);
+    if (insertionPoint->inDocument())
+        return InsertionShouldCallDidNotifyDescendantInseretions;
+    return InsertionDone;
 }
 
-void HTMLFormElement::removedFromDocument()
+void HTMLFormElement::didNotifyDescendantInseretions(Node* insertionPoint)
 {
-    HTMLElement::removedFromDocument();
-
+    ASSERT(insertionPoint->inDocument());
+    HTMLElement::didNotifyDescendantInseretions(insertionPoint);
     if (hasID())
         document()->resetFormElementsOwner();
 }
@@ -154,13 +154,15 @@ static inline Node* findRoot(Node* n)
     return root;
 }
 
-void HTMLFormElement::removedFromTree(bool deep)
+void HTMLFormElement::removedFrom(Node* insertionPoint)
 {
     Node* root = findRoot(this);
     Vector<FormAssociatedElement*> associatedElements(m_associatedElements);
     for (unsigned i = 0; i < associatedElements.size(); ++i)
         associatedElements[i]->formRemovedFromTree(root);
-    HTMLElement::removedFromTree(deep);
+    HTMLElement::removedFrom(insertionPoint);
+    if (insertionPoint->inDocument() && hasID())
+        document()->resetFormElementsOwner();
 }
 
 void HTMLFormElement::handleLocalEvents(Event* event)
index 3b2abd7..8091148 100644 (file)
@@ -115,9 +115,9 @@ private:
     HTMLFormElement(const QualifiedName&, Document*);
 
     virtual bool rendererIsNeeded(const NodeRenderingContext&);
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
-    virtual void removedFromTree(bool deep) OVERRIDE;
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void didNotifyDescendantInseretions(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
 
     virtual void handleLocalEvents(Event*);
 
index 861c267..c34ddeb 100644 (file)
@@ -153,9 +153,17 @@ void HTMLFrameElementBase::setNameAndOpenURL()
     openURL();
 }
 
-void HTMLFrameElementBase::insertedIntoDocument()
+Node::InsertionNotificationRequest HTMLFrameElementBase::insertedInto(Node* insertionPoint)
 {
-    HTMLFrameOwnerElement::insertedIntoDocument();
+    HTMLFrameOwnerElement::insertedInto(insertionPoint);
+    if (insertionPoint->inDocument())
+        return InsertionShouldCallDidNotifyDescendantInseretions;
+    return InsertionDone;
+}
+
+void HTMLFrameElementBase::didNotifyDescendantInseretions(Node* insertionPoint)
+{
+    ASSERT_UNUSED(insertionPoint, insertionPoint->inDocument());
 
     // DocumentFragments don't kick of any loads.
     if (!document()->frame())
@@ -165,7 +173,7 @@ void HTMLFrameElementBase::insertedIntoDocument()
     // during attribute parsing *before* the normal parser machinery would
     // attach the element. To support this, we lazyAttach here, but only
     // if we don't already have a renderer (if we're inserted
-    // as part of a DocumentFragment, insertedIntoDocument from an earlier element
+    // as part of a DocumentFragment, insertedInto from an earlier element
     // could have forced a style resolve and already attached us).
     if (!renderer())
         lazyAttach(DoNotSetAttached);
index be68330..54891a4 100644 (file)
@@ -54,7 +54,8 @@ protected:
     bool isURLAllowed() const;
 
     virtual void parseAttribute(Attribute*) OVERRIDE;
-    virtual void insertedIntoDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void didNotifyDescendantInseretions(Node*) OVERRIDE;
     virtual void attach();
 
 private:
index 803a1b9..8b36dbf 100644 (file)
@@ -210,18 +210,24 @@ bool HTMLFrameSetElement::willRecalcStyle(StyleChange)
     return true;
 }
 
-void HTMLFrameSetElement::insertedIntoDocument()
+Node::InsertionNotificationRequest HTMLFrameSetElement::insertedInto(Node* insertionPoint)
 {
-    HTMLElement::insertedIntoDocument();
-    if (Frame* frame = document()->frame())
-        frame->loader()->client()->dispatchDidBecomeFrameset(document()->isFrameSet());
+    HTMLElement::insertedInto(insertionPoint);
+    if (insertionPoint->inDocument()) {
+        if (Frame* frame = document()->frame())
+            frame->loader()->client()->dispatchDidBecomeFrameset(document()->isFrameSet());
+    }
+
+    return InsertionDone;
 }
 
-void HTMLFrameSetElement::removedFromDocument()
+void HTMLFrameSetElement::removedFrom(Node* insertionPoint)
 {
-    HTMLElement::removedFromDocument();
-    if (Frame* frame = document()->frame())
-        frame->loader()->client()->dispatchDidBecomeFrameset(document()->isFrameSet());
+    HTMLElement::removedFrom(insertionPoint);
+    if (insertionPoint->inDocument()) {
+        if (Frame* frame = document()->frame())
+            frame->loader()->client()->dispatchDidBecomeFrameset(document()->isFrameSet());
+    }
 }
 
 } // namespace WebCore
index 69c6162..2f15949 100644 (file)
@@ -79,8 +79,8 @@ private:
 
     virtual bool willRecalcStyle(StyleChange);
 
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
 
     OwnArrayPtr<Length> m_rowLengths;
     OwnArrayPtr<Length> m_colLengths;
index 2969cf9..d6b5fe0 100644 (file)
@@ -100,20 +100,19 @@ RenderObject* HTMLIFrameElement::createRenderer(RenderArena* arena, RenderStyle*
     return new (arena) RenderIFrame(this);
 }
 
-void HTMLIFrameElement::insertedIntoDocument()
+Node::InsertionNotificationRequest HTMLIFrameElement::insertedInto(Node* insertionPoint)
 {
-    if (document()->isHTMLDocument())
+    InsertionNotificationRequest result = HTMLFrameElementBase::insertedInto(insertionPoint);
+    if (insertionPoint->inDocument() && document()->isHTMLDocument())
         static_cast<HTMLDocument*>(document())->addExtraNamedItem(m_name);
-
-    HTMLFrameElementBase::insertedIntoDocument();
+    return result;
 }
 
-void HTMLIFrameElement::removedFromDocument()
+void HTMLIFrameElement::removedFrom(Node* insertionPoint)
 {
-    if (document()->isHTMLDocument())
+    HTMLFrameElementBase::removedFrom(insertionPoint);
+    if (insertionPoint->inDocument() && document()->isHTMLDocument())
         static_cast<HTMLDocument*>(document())->removeExtraNamedItem(m_name);
-
-    HTMLFrameElementBase::removedFromDocument();
 }
 
 #if ENABLE(MICRODATA)
index 1882acd..86cb717 100644 (file)
@@ -39,8 +39,8 @@ private:
     virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
     virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
 
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
     
     virtual bool rendererIsNeeded(const NodeRenderingContext&);
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
index 2afe96b..e08fb57 100644 (file)
@@ -168,17 +168,7 @@ void HTMLImageElement::attach()
     }
 }
 
-void HTMLImageElement::insertedIntoDocument()
-{
-    // If we have been inserted from a renderer-less document,
-    // our loader may have not fetched the image, so do it now.
-    if (!m_imageLoader.image())
-        m_imageLoader.updateFromElement();
-
-    HTMLElement::insertedIntoDocument();
-}
-
-void HTMLImageElement::insertedIntoTree(bool deep)
+Node::InsertionNotificationRequest HTMLImageElement::insertedInto(Node* insertionPoint)
 {
     if (!m_form) {
         // m_form can be non-null if it was set in constructor.
@@ -191,15 +181,20 @@ void HTMLImageElement::insertedIntoTree(bool deep)
         }
     }
 
-    HTMLElement::insertedIntoTree(deep);
+    // If we have been inserted from a renderer-less document,
+    // our loader may have not fetched the image, so do it now.
+    if (insertionPoint->inDocument() && !m_imageLoader.image())
+        m_imageLoader.updateFromElement();
+
+    return HTMLElement::insertedInto(insertionPoint);
 }
 
-void HTMLImageElement::removedFromTree(bool deep)
+void HTMLImageElement::removedFrom(Node* insertionPoint)
 {
     if (m_form)
         m_form->removeImgElement(this);
     m_form = 0;
-    HTMLElement::removedFromTree(deep);
+    HTMLElement::removedFrom(insertionPoint);
 }
 
 int HTMLImageElement::width(bool ignorePendingStylesheets)
index 6fbadd3..3ab95a3 100644 (file)
@@ -99,10 +99,8 @@ private:
 
     virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
 
-    virtual void insertedIntoDocument();
-    virtual void insertedIntoTree(bool deep);
-    virtual void removedFromTree(bool deep);
-
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
     virtual bool shouldRegisterAsNamedItem() const OVERRIDE { return true; }
     virtual bool shouldRegisterAsExtraNamedItem() const OVERRIDE { return true; }
 
index fa3c58f..09c52ad 100644 (file)
@@ -1454,18 +1454,21 @@ void HTMLInputElement::didChangeForm()
     addToRadioButtonGroup();
 }
 
-void HTMLInputElement::insertedIntoDocument()
+Node::InsertionNotificationRequest HTMLInputElement::insertedInto(Node* insertionPoint)
 {
-    HTMLTextFormControlElement::insertedIntoDocument();
+    HTMLTextFormControlElement::insertedInto(insertionPoint);
+    if (!insertionPoint->inDocument())
+        return InsertionDone;
     ASSERT(inDocument());
     addToRadioButtonGroup();
+    return InsertionDone;
 }
 
-void HTMLInputElement::removedFromDocument()
+void HTMLInputElement::removedFrom(Node* insertionPoint)
 {
-    ASSERT(inDocument());
-    removeFromRadioButtonGroup();
-    HTMLTextFormControlElement::removedFromDocument();
+    if (insertionPoint->inDocument())
+        removeFromRadioButtonGroup();
+    HTMLTextFormControlElement::removedFrom(insertionPoint);
 }
 
 void HTMLInputElement::didMoveToNewDocument(Document* oldDocument)
index c210914..170f973 100644 (file)
@@ -247,8 +247,8 @@ private:
 
     virtual void willChangeForm() OVERRIDE;
     virtual void didChangeForm() OVERRIDE;
-    virtual void insertedIntoDocument() OVERRIDE;
-    virtual void removedFromDocument() OVERRIDE;
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
     virtual void didMoveToNewDocument(Document* oldDocument) OVERRIDE;
 
     virtual bool isKeyboardFocusable(KeyboardEvent*) const;
index 10bd04d..461925e 100644 (file)
@@ -243,22 +243,27 @@ void HTMLLinkElement::clearSheet()
     m_sheet = 0;
 }
 
-void HTMLLinkElement::insertedIntoDocument()
+Node::InsertionNotificationRequest HTMLLinkElement::insertedInto(Node* insertionPoint)
 {
-    HTMLElement::insertedIntoDocument();
+    HTMLElement::insertedInto(insertionPoint);
+    if (!insertionPoint->inDocument())
+        return InsertionDone;
 
     m_isInShadowTree = isInShadowTree();
     if (m_isInShadowTree)
-        return;
+        return InsertionDone;
 
     document()->addStyleSheetCandidateNode(this, m_createdByParser);
 
     process();
+    return InsertionDone;
 }
 
-void HTMLLinkElement::removedFromDocument()
+void HTMLLinkElement::removedFrom(Node* insertionPoint)
 {
-    HTMLElement::removedFromDocument();
+    HTMLElement::removedFrom(insertionPoint);
+    if (!insertionPoint->inDocument())
+        return;
 
     if (m_isInShadowTree) {
         ASSERT(!m_sheet);
index 9411842..8cb9177 100644 (file)
@@ -75,8 +75,8 @@ private:
     static void processCallback(Node*);
     void clearSheet();
 
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
 
     // from CachedResourceClient
     virtual void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet* sheet);
index 2e46713..5dc0836 100644 (file)
@@ -131,16 +131,18 @@ HTMLCollection* HTMLMapElement::areas()
     return ensureCachedHTMLCollection(MapAreas);
 }
 
-void HTMLMapElement::insertedIntoDocument()
+Node::InsertionNotificationRequest HTMLMapElement::insertedInto(Node* insertionPoint)
 {
-    treeScope()->addImageMap(this);
-    HTMLElement::insertedIntoDocument();
+    if (insertionPoint->inDocument())
+        treeScope()->addImageMap(this);
+    return HTMLElement::insertedInto(insertionPoint);
 }
 
-void HTMLMapElement::removedFromDocument()
+void HTMLMapElement::removedFrom(Node* insertionPoint)
 {
-    treeScope()->removeImageMap(this);
-    HTMLElement::removedFromDocument();
+    if (insertionPoint->inDocument())
+        treeScope()->removeImageMap(this);
+    HTMLElement::removedFrom(insertionPoint);
 }
 
 }
index 8aad96f..a25baba 100644 (file)
@@ -48,8 +48,8 @@ private:
 
     virtual void parseAttribute(Attribute*) OVERRIDE;
 
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
 
     AtomicString m_name;
 };
index 182cded..9eb1c20 100644 (file)
@@ -491,24 +491,28 @@ bool HTMLMediaElement::childShouldCreateRenderer(const NodeRenderingContext& chi
     return childContext.isOnUpperEncapsulationBoundary() && HTMLElement::childShouldCreateRenderer(childContext);
 }
 
-void HTMLMediaElement::insertedIntoDocument()
+Node::InsertionNotificationRequest HTMLMediaElement::insertedInto(Node* insertionPoint)
 {
-    LOG(Media, "HTMLMediaElement::insertedIntoDocument");
-    HTMLElement::insertedIntoDocument();
-    if (!getAttribute(srcAttr).isEmpty() && m_networkState == NETWORK_EMPTY)
+    LOG(Media, "HTMLMediaElement::insertedInto");
+    HTMLElement::insertedInto(insertionPoint);
+    if (insertionPoint->inDocument() && !getAttribute(srcAttr).isEmpty() && m_networkState == NETWORK_EMPTY)
         scheduleLoad(MediaResource);
     configureMediaControls();
+    return InsertionDone;
 }
 
-void HTMLMediaElement::removedFromDocument()
+void HTMLMediaElement::removedFrom(Node* insertionPoint)
 {
-    LOG(Media, "HTMLMediaElement::removedFromDocument");
-    configureMediaControls();
-    if (m_networkState > NETWORK_EMPTY)
-        pause();
-    if (m_isFullscreen)
-        exitFullscreen();
-    HTMLElement::removedFromDocument();
+    if (insertionPoint->inDocument()) {
+        LOG(Media, "HTMLMediaElement::removedFromDocument");
+        configureMediaControls();
+        if (m_networkState > NETWORK_EMPTY)
+            pause();
+        if (m_isFullscreen)
+            exitFullscreen();
+    }
+
+    HTMLElement::removedFrom(insertionPoint);
 }
 
 void HTMLMediaElement::attach()
index 03ace28..1fe066a 100644 (file)
@@ -360,8 +360,8 @@ private:
     virtual bool rendererIsNeeded(const NodeRenderingContext&);
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
     virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const OVERRIDE;
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
     virtual void didRecalcStyle(StyleChange);
     
     virtual void defaultEventHandler(Event*);
index 820ad44..0aa6651 100644 (file)
@@ -54,10 +54,12 @@ void HTMLMetaElement::parseAttribute(Attribute* attr)
         HTMLElement::parseAttribute(attr);
 }
 
-void HTMLMetaElement::insertedIntoDocument()
+Node::InsertionNotificationRequest HTMLMetaElement::insertedInto(Node* insertionPoint)
 {
-    HTMLElement::insertedIntoDocument();
-    process();
+    HTMLElement::insertedInto(insertionPoint);
+    if (insertionPoint->inDocument())
+        process();
+    return InsertionDone;
 }
 
 void HTMLMetaElement::process()
index 7fe03ef..9956f55 100644 (file)
@@ -39,7 +39,7 @@ private:
     HTMLMetaElement(const QualifiedName&, Document*);
 
     virtual void parseAttribute(Attribute*) OVERRIDE;
-    virtual void insertedIntoDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
 
     void process();
 
index 635042f..a8d34b9 100644 (file)
@@ -328,16 +328,17 @@ bool HTMLObjectElement::rendererIsNeeded(const NodeRenderingContext& context)
     return HTMLPlugInImageElement::rendererIsNeeded(context);
 }
 
-void HTMLObjectElement::insertedIntoDocument()
+Node::InsertionNotificationRequest HTMLObjectElement::insertedInto(Node* insertionPoint)
 {
-    HTMLPlugInImageElement::insertedIntoDocument();
-    FormAssociatedElement::insertedIntoDocument();
+    HTMLPlugInImageElement::insertedInto(insertionPoint);
+    FormAssociatedElement::insertedInto(insertionPoint);
+    return InsertionDone;
 }
 
-void HTMLObjectElement::removedFromDocument()
+void HTMLObjectElement::removedFrom(Node* insertionPoint)
 {
-    HTMLPlugInImageElement::removedFromDocument();
-    FormAssociatedElement::removedFromDocument();
+    HTMLPlugInImageElement::removedFrom(insertionPoint);
+    FormAssociatedElement::removedFrom(insertionPoint);
 }
 
 void HTMLObjectElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
@@ -485,18 +486,6 @@ void HTMLObjectElement::didMoveToNewDocument(Document* oldDocument)
     HTMLPlugInImageElement::didMoveToNewDocument(oldDocument);
 }
 
-void HTMLObjectElement::insertedIntoTree(bool deep)
-{
-    FormAssociatedElement::insertedIntoTree();
-    HTMLPlugInImageElement::insertedIntoTree(deep);
-}
-
-void HTMLObjectElement::removedFromTree(bool deep)
-{
-    FormAssociatedElement::removedFromTree();
-    HTMLPlugInImageElement::removedFromTree(deep);
-}
-
 bool HTMLObjectElement::appendFormData(FormDataList& encoding, bool)
 {
     if (name().isEmpty())
index a1ab972..b50045d 100644 (file)
@@ -70,12 +70,10 @@ private:
     virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
     virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
 
-    virtual void insertedIntoTree(bool deep);
-    virtual void removedFromTree(bool deep);
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
 
     virtual bool rendererIsNeeded(const NodeRenderingContext&);
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
     virtual void didMoveToNewDocument(Document* oldDocument) OVERRIDE;
 
     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
index a9be7c0..95a7971 100644 (file)
@@ -306,7 +306,7 @@ bool HTMLOptionElement::disabled() const
     return ownElementDisabled() || (parentNode() && parentNode()->isHTMLElement() && static_cast<HTMLElement*>(parentNode())->disabled());
 }
 
-void HTMLOptionElement::insertedIntoTree(bool deep)
+Node::InsertionNotificationRequest HTMLOptionElement::insertedInto(Node* insertionPoint)
 {
     if (HTMLSelectElement* select = ownerSelectElement()) {
         select->setRecalcListItems();
@@ -319,7 +319,7 @@ void HTMLOptionElement::insertedIntoTree(bool deep)
         select->scrollToSelection();
     }
 
-    HTMLElement::insertedIntoTree(deep);
+    return HTMLElement::insertedInto(insertionPoint);
 }
 
 String HTMLOptionElement::collectOptionInnerText() const
index 1433a82..064845a 100644 (file)
@@ -75,7 +75,7 @@ private:
 
     virtual void parseAttribute(Attribute*) OVERRIDE;
 
-    virtual void insertedIntoTree(bool);
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
     virtual void accessKeyAction(bool);
 
     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
index dfc14cb..d629bc9 100644 (file)
@@ -41,12 +41,12 @@ PassRefPtr<HTMLQuoteElement> HTMLQuoteElement::create(const QualifiedName& tagNa
     return adoptRef(new HTMLQuoteElement(tagName, document));
 }
 
-void HTMLQuoteElement::insertedIntoDocument()
+Node::InsertionNotificationRequest HTMLQuoteElement::insertedInto(Node* insertionPoint)
 {
     if (hasTagName(qTag))
         document()->setUsesBeforeAfterRules(true);
 
-    HTMLElement::insertedIntoDocument();
+    return HTMLElement::insertedInto(insertionPoint);
 }
 
 bool HTMLQuoteElement::isURLAttribute(Attribute* attribute) const
index d378de4..21cf50d 100644 (file)
@@ -36,7 +36,7 @@ public:
 private:
     HTMLQuoteElement(const QualifiedName&, Document*);
     
-    virtual void insertedIntoDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
     virtual bool isURLAttribute(Attribute*) const;
 };
 
index a1e6c80..244fc4f 100644 (file)
@@ -74,10 +74,11 @@ void HTMLScriptElement::parseAttribute(Attribute* attr)
         HTMLElement::parseAttribute(attr);
 }
 
-void HTMLScriptElement::insertedIntoDocument()
+Node::InsertionNotificationRequest HTMLScriptElement::insertedInto(Node* insertionPoint)
 {
-    HTMLElement::insertedIntoDocument();
-    ScriptElement::insertedIntoDocument();
+    HTMLElement::insertedInto(insertionPoint);
+    ScriptElement::insertedInto(insertionPoint);
+    return InsertionDone;
 }
 
 void HTMLScriptElement::setText(const String &value)
index 07c89ab..2e3146e 100644 (file)
@@ -45,7 +45,7 @@ private:
     HTMLScriptElement(const QualifiedName&, Document*, bool wasInsertedByParser, bool alreadyStarted);
 
     virtual void parseAttribute(Attribute*) OVERRIDE;
-    virtual void insertedIntoDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
 
     virtual bool isURLAttribute(Attribute*) const;
index 72d3c07..c25b288 100644 (file)
@@ -1472,13 +1472,14 @@ void HTMLSelectElement::typeAheadFind(KeyboardEvent* event)
     }
 }
 
-void HTMLSelectElement::insertedIntoTree(bool deep)
+Node::InsertionNotificationRequest HTMLSelectElement::insertedInto(Node* insertionPoint)
 {
     // When the element is created during document parsing, it won't have any
     // items yet - but for innerHTML and related methods, this method is called
     // after the whole subtree is constructed.
     recalcListItems();
-    HTMLFormControlElementWithState::insertedIntoTree(deep);
+    HTMLFormControlElementWithState::insertedInto(insertionPoint);
+    return InsertionDone;
 }
 
 void HTMLSelectElement::accessKeySetSelectedIndex(int index)
index eb5a153..52665e1 100644 (file)
@@ -142,7 +142,7 @@ private:
     void typeAheadFind(KeyboardEvent*);
     void saveLastSelection();
 
-    virtual void insertedIntoTree(bool);
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
 
     virtual bool isOptionalFormControl() const { return !isRequiredFormControl(); }
     virtual bool isRequiredFormControl() const;
index df26057..c2f9362 100644 (file)
@@ -54,12 +54,13 @@ PassRefPtr<HTMLSourceElement> HTMLSourceElement::create(const QualifiedName& tag
     return adoptRef(new HTMLSourceElement(tagName, document));
 }
 
-void HTMLSourceElement::insertedIntoTree(bool deep)
+Node::InsertionNotificationRequest HTMLSourceElement::insertedInto(Node* insertionPoint)
 {
-    HTMLElement::insertedIntoTree(deep);
+    HTMLElement::insertedInto(insertionPoint);
     Element* parent = parentElement();
     if (parent && parent->isMediaElement())
         static_cast<HTMLMediaElement*>(parentNode())->sourceWasAdded(this);
+    return InsertionDone;
 }
 
 void HTMLSourceElement::willRemove()
index 431a66c..379183e 100644 (file)
@@ -49,7 +49,7 @@ public:
 private:
     HTMLSourceElement(const QualifiedName&, Document*);
     
-    virtual void insertedIntoTree(bool);
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
     virtual void willRemove();
     virtual bool isURLAttribute(Attribute*) const;
 
index b327b15..77d081f 100644 (file)
@@ -151,26 +151,31 @@ void HTMLStyleElement::unregisterWithScopingNode()
 }
 #endif
 
-void HTMLStyleElement::insertedIntoDocument()
+Node::InsertionNotificationRequest HTMLStyleElement::insertedInto(Node* insertionPoint)
 {
-    HTMLElement::insertedIntoDocument();
-    StyleElement::insertedIntoDocument(document(), this);
+    HTMLElement::insertedInto(insertionPoint);
+    if (insertionPoint->inDocument())
+        StyleElement::insertedIntoDocument(document(), this);
 #if ENABLE(STYLE_SCOPED)
     if (scoped() && !m_isRegisteredWithScopingNode)
         registerWithScopingNode();
 #endif
+    return InsertionDone;
 }
 
-void HTMLStyleElement::removedFromDocument()
+void HTMLStyleElement::removedFrom(Node* insertionPoint)
 {
+    HTMLElement::removedFrom(insertionPoint);
+
+    if (insertionPoint->inDocument()) {
 #if ENABLE(STYLE_SCOPED)
-    // In come cases on teardown willRemove is not called - test here for unregistering again
-    // FIXME: Do we need to bother?
-    if (m_isRegisteredWithScopingNode)
-        unregisterWithScopingNode();
+        // In come cases on teardown willRemove is not called - test here for unregistering again
+        // FIXME: Do we need to bother?
+        if (m_isRegisteredWithScopingNode)
+            unregisterWithScopingNode();
 #endif
-    HTMLElement::removedFromDocument();
-    StyleElement::removedFromDocument(document(), this);
+        StyleElement::removedFromDocument(document(), this);
+    }
 }
 
 
index 47f6ac6..2dc13d8 100644 (file)
@@ -60,8 +60,8 @@ private:
 
     // overload from HTMLElement
     virtual void parseAttribute(Attribute*) OVERRIDE;
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
 #if ENABLE(STYLE_SCOPED)
     virtual void willRemove();
 #endif
index f47e1f2..76c0abe 100644 (file)
@@ -70,11 +70,14 @@ bool HTMLTextFormControlElement::childShouldCreateRenderer(const NodeRenderingCo
     return childContext.isOnEncapsulationBoundary() && HTMLFormControlElementWithState::childShouldCreateRenderer(childContext);
 }
 
-void HTMLTextFormControlElement::insertedIntoDocument()
+Node::InsertionNotificationRequest HTMLTextFormControlElement::insertedInto(Node* insertionPoint)
 {
-    HTMLFormControlElement::insertedIntoDocument();
+    HTMLFormControlElement::insertedInto(insertionPoint);
+    if (!insertionPoint->inDocument())
+        return InsertionDone;
     String initialValue = value();
     setTextAsOfLastFormControlChangeEvent(initialValue.isNull() ? emptyString() : initialValue);
+    return InsertionDone;
 }
 
 void HTMLTextFormControlElement::dispatchFocusEvent(PassRefPtr<Node> oldFocusedNode)
index 59cd741..c283055 100644 (file)
@@ -45,7 +45,8 @@ public:
 
     void forwardEvent(Event*);
 
-    virtual void insertedIntoDocument();
+
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
 
     // The derived class should return true if placeholder processing is needed.
     virtual bool supportsPlaceholder() const = 0;
index f488917..0a73ad1 100644 (file)
@@ -44,16 +44,19 @@ PassRefPtr<HTMLTitleElement> HTMLTitleElement::create(const QualifiedName& tagNa
     return adoptRef(new HTMLTitleElement(tagName, document));
 }
 
-void HTMLTitleElement::insertedIntoDocument()
+Node::InsertionNotificationRequest HTMLTitleElement::insertedInto(Node* insertionPoint)
 {
-    HTMLElement::insertedIntoDocument();
-    document()->setTitleElement(m_title, this);
+    HTMLElement::insertedInto(insertionPoint);
+    if (insertionPoint->inDocument())
+        document()->setTitleElement(m_title, this);
+    return InsertionDone;
 }
 
-void HTMLTitleElement::removedFromDocument()
+void HTMLTitleElement::removedFrom(Node* insertionPoint)
 {
-    HTMLElement::removedFromDocument();
-    document()->removeTitle(this);
+    HTMLElement::removedFrom(insertionPoint);
+    if (insertionPoint->inDocument())
+        document()->removeTitle(this);
 }
 
 void HTMLTitleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
index 6920997..662f5d7 100644 (file)
@@ -39,8 +39,8 @@ public:
 private:
     HTMLTitleElement(const QualifiedName&, Document*);
 
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
 
     StringWithDirection m_title;
index f2308a7..afd1dc3 100644 (file)
@@ -72,12 +72,15 @@ PassRefPtr<HTMLTrackElement> HTMLTrackElement::create(const QualifiedName& tagNa
     return adoptRef(new HTMLTrackElement(tagName, document));
 }
 
-void HTMLTrackElement::insertedIntoDocument()
+Node::InsertionNotificationRequest HTMLTrackElement::insertedInto(Node* insertionPoint)
 {
-    HTMLElement::insertedIntoDocument();
+    HTMLElement::insertedInto(insertionPoint);
+    if (insertionPoint->inDocument()) {
+        if (HTMLMediaElement* parent = mediaElement())
+            parent->didAddTrack(this);
+    }
 
-    if (HTMLMediaElement* parent = mediaElement())
-        parent->didAddTrack(this);
+    return InsertionDone;
 }
 
 void HTMLTrackElement::willRemove()
index 1eab873..a85863d 100644 (file)
@@ -77,7 +77,7 @@ private:
 
     virtual void parseAttribute(Attribute*) OVERRIDE;
 
-    virtual void insertedIntoDocument() OVERRIDE;
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
     virtual void willRemove() OVERRIDE;
     virtual bool isURLAttribute(Attribute*) const;
 
index ae74b52..98e33cd 100644 (file)
@@ -29,7 +29,6 @@
 #if ENABLE(MATHML)
 
 #include "MathMLMathElement.h"
-
 #include "RenderMathMLMath.h"
 
 namespace WebCore {
@@ -44,12 +43,12 @@ PassRefPtr<MathMLMathElement> MathMLMathElement::create(const QualifiedName& tag
     return adoptRef(new MathMLMathElement(tagName, document));
 }
 
-void MathMLMathElement::insertedIntoDocument()
+Node::InsertionNotificationRequest MathMLMathElement::insertedInto(Node* insertionPoint)
 {
     // There are sibling rules in the MathML default style.
-    document()->setUsesSiblingRules(true);
-    
-    MathMLInlineContainerElement::insertedIntoDocument();
+    if (insertionPoint->inDocument())
+        document()->setUsesSiblingRules(true);
+    return MathMLInlineContainerElement::insertedInto(insertionPoint);
 }
 
 RenderObject* MathMLMathElement::createRenderer(RenderArena* arena, RenderStyle*)
index 81f161b..42ba75f 100644 (file)
@@ -39,7 +39,7 @@ public:
 private:
     MathMLMathElement(const QualifiedName& tagName, Document*);
 
-    virtual void insertedIntoDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
 };
     
index 1753ece..0b9d50c 100644 (file)
@@ -169,11 +169,14 @@ void SVGElement::setXmlbase(const String& value, ExceptionCode&)
     setAttribute(XMLNames::baseAttr, value);
 }
 
-void SVGElement::removedFromDocument()
+void SVGElement::removedFrom(Node* rootParent)
 {
-    document()->accessSVGExtensions()->removeAllAnimationElementsFromTarget(this);
-    document()->accessSVGExtensions()->removeAllElementReferencesForTarget(this);
-    StyledElement::removedFromDocument();
+    if (rootParent->inDocument()) {
+        document()->accessSVGExtensions()->removeAllAnimationElementsFromTarget(this);
+        document()->accessSVGExtensions()->removeAllElementReferencesForTarget(this);
+    }
+
+    StyledElement::removedFrom(rootParent);
 }
 
 SVGSVGElement* SVGElement::ownerSVGElement() const
index 5e20cd8..0105096 100644 (file)
@@ -121,7 +121,7 @@ protected:
     virtual void attributeChanged(Attribute*) OVERRIDE;
     virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const;
     
-    virtual void removedFromDocument();
+    virtual void removedFrom(Node*) OVERRIDE;
 
     SVGElementRareData* rareSVGData() const;
     SVGElementRareData* ensureRareSVGData();
index d209747..efa22ad 100644 (file)
@@ -175,16 +175,18 @@ void SVGFEImageElement::svgAttributeChanged(const QualifiedName& attrName)
     ASSERT_NOT_REACHED();
 }
 
-void SVGFEImageElement::insertedIntoDocument()
+Node::InsertionNotificationRequest SVGFEImageElement::insertedInto(Node* rootParent)
 {
-    SVGFilterPrimitiveStandardAttributes::insertedIntoDocument();
+    SVGFilterPrimitiveStandardAttributes::insertedInto(rootParent);
     buildPendingResource();
+    return InsertionDone;
 }
 
-void SVGFEImageElement::removedFromDocument()
+void SVGFEImageElement::removedFrom(Node* rootParent)
 {
-    SVGFilterPrimitiveStandardAttributes::removedFromDocument();
-    clearResourceReferences();
+    SVGFilterPrimitiveStandardAttributes::removedFrom(rootParent);
+    if (rootParent->inDocument())
+        clearResourceReferences();
 }
 
 void SVGFEImageElement::notifyFinished(CachedResource*)
index f438c6f..a2aa248 100644 (file)
@@ -60,8 +60,8 @@ private:
     void requestImageResource();
 
     virtual void buildPendingResource();
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
 
     BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEImageElement)
         DECLARE_ANIMATED_PRESERVEASPECTRATIO(PreserveAspectRatio, preserveAspectRatio)
index 5e43070..9119767 100644 (file)
@@ -315,23 +315,27 @@ void SVGFontFaceElement::rebuildFontFace()
     document()->styleSelectorChanged(DeferRecalcStyle);
 }
 
-void SVGFontFaceElement::insertedIntoDocument()
+Node::InsertionNotificationRequest SVGFontFaceElement::insertedInto(Node* rootParent)
 {
-    SVGElement::insertedIntoDocument();
-
+    SVGElement::insertedInto(rootParent);
+    if (!rootParent->inDocument())
+        return InsertionDone;
     document()->accessSVGExtensions()->registerSVGFontFaceElement(this);
 
     rebuildFontFace();
+    return InsertionDone;
 }
 
-void SVGFontFaceElement::removedFromDocument()
+void SVGFontFaceElement::removedFrom(Node* rootParent)
 {
-    SVGElement::removedFromDocument();
+    SVGElement::removedFrom(rootParent);
 
-    document()->accessSVGExtensions()->unregisterSVGFontFaceElement(this);
-    m_fontFaceRule->properties()->parseDeclaration(emptyString(), 0);
+    if (rootParent->inDocument()) {
+        document()->accessSVGExtensions()->unregisterSVGFontFaceElement(this);
+        m_fontFaceRule->properties()->parseDeclaration(emptyString(), 0);
 
-    document()->styleSelectorChanged(DeferRecalcStyle);
+        document()->styleSelectorChanged(DeferRecalcStyle);
+    }
 }
 
 void SVGFontFaceElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
index 75af8cd..7a21f33 100644 (file)
@@ -57,8 +57,8 @@ private:
     virtual void parseAttribute(Attribute*) OVERRIDE;
 
     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
 
     RefPtr<StyleRuleFontFace> m_fontFaceRule;
     RefPtr<SVGFontElement> m_fontElement;
index 005c643..0af98cc 100644 (file)
@@ -82,10 +82,10 @@ void SVGFontFaceUriElement::childrenChanged(bool changedByParser, Node* beforeCh
         static_cast<SVGFontFaceElement*>(grandparent)->rebuildFontFace();
 }
 
-void SVGFontFaceUriElement::insertedIntoDocument()
+Node::InsertionNotificationRequest SVGFontFaceUriElement::insertedInto(Node* rootParent)
 {
     loadFont();
-    SVGElement::insertedIntoDocument();
+    return SVGElement::insertedInto(rootParent);
 }
 
 void SVGFontFaceUriElement::loadFont()
index d999b3a..dd6f3aa 100644 (file)
@@ -42,7 +42,7 @@ private:
     
     virtual void parseAttribute(Attribute*) OVERRIDE;
     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
-    virtual void insertedIntoDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
 
     void loadFont();
 
index 3f3c8f5..36de3f1 100644 (file)
@@ -61,16 +61,17 @@ void SVGGlyphElement::parseAttribute(Attribute* attr)
         SVGStyledElement::parseAttribute(attr);
 }
 
-void SVGGlyphElement::insertedIntoDocument()
+Node::InsertionNotificationRequest SVGGlyphElement::insertedInto(Node* rootParent)
 {
     invalidateGlyphCache();
-    SVGStyledElement::insertedIntoDocument();
+    return SVGStyledElement::insertedInto(rootParent);
 }
 
-void SVGGlyphElement::removedFromDocument()
+void SVGGlyphElement::removedFrom(Node* rootParent)
 {
-    invalidateGlyphCache();
-    SVGStyledElement::removedFromDocument();
+    if (rootParent->inDocument())
+        invalidateGlyphCache();
+    SVGStyledElement::removedFrom(rootParent);
 }
 
 static inline SVGGlyph::ArabicForm parseArabicForm(const AtomicString& value)
index c7b99d9..8e2dd40 100644 (file)
@@ -49,8 +49,8 @@ private:
     // FIXME: svgAttributeChanged missing.
     virtual void parseAttribute(Attribute*) OVERRIDE;
 
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
 
     virtual bool rendererIsNeeded(const NodeRenderingContext&) { return false; }
 
index 8ba474a..43de067 100644 (file)
@@ -41,24 +41,26 @@ PassRefPtr<SVGHKernElement> SVGHKernElement::create(const QualifiedName& tagName
     return adoptRef(new SVGHKernElement(tagName, document));
 }
 
-void SVGHKernElement::insertedIntoDocument()
+Node::InsertionNotificationRequest SVGHKernElement::insertedInto(Node* rootParent)
 {
     ContainerNode* fontNode = parentNode();
     if (fontNode && fontNode->hasTagName(SVGNames::fontTag)) {
         if (SVGFontElement* element = static_cast<SVGFontElement*>(fontNode))
             element->invalidateGlyphCache();
     }
-    SVGElement::insertedIntoDocument();
+
+    return SVGElement::insertedInto(rootParent);
 }
 
-void SVGHKernElement::removedFromDocument()
+void SVGHKernElement::removedFrom(Node* rootParent)
 {
     ContainerNode* fontNode = parentNode();
     if (fontNode && fontNode->hasTagName(SVGNames::fontTag)) {
         if (SVGFontElement* element = static_cast<SVGFontElement*>(fontNode))
             element->invalidateGlyphCache();
     }
-    SVGElement::removedFromDocument();
+
+    SVGElement::removedFrom(rootParent);
 }
 
 void SVGHKernElement::buildHorizontalKerningPair(KerningPairVector& kerningPairs)
index bc7b4e8..6b60d26 100644 (file)
@@ -36,8 +36,8 @@ public:
 private:
     SVGHKernElement(const QualifiedName&, Document*);
 
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
 
     virtual bool rendererIsNeeded(const NodeRenderingContext&) { return false; }
 };
index 904a270..c73dcdb 100644 (file)
@@ -211,13 +211,15 @@ void SVGImageElement::attach()
     }
 }
 
-void SVGImageElement::insertedIntoDocument()
+Node::InsertionNotificationRequest SVGImageElement::insertedInto(Node* rootParent)
 {
-    SVGStyledTransformableElement::insertedIntoDocument();
-
+    SVGStyledTransformableElement::insertedInto(rootParent);
+    if (!rootParent->inDocument())
+        return InsertionDone;
     // Update image loader, as soon as we're living in the tree.
     // We can only resolve base URIs properly, after that!
     m_imageLoader.updateFromElement();
+    return InsertionDone;
 }
 
 const QualifiedName& SVGImageElement::imageSourceAttributeName() const
index 05be5cc..26f114c 100644 (file)
@@ -55,7 +55,7 @@ private:
     virtual void svgAttributeChanged(const QualifiedName&);
 
     virtual void attach();
-    virtual void insertedIntoDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
 
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
  
index 25d7adc..215c33e 100644 (file)
@@ -474,16 +474,18 @@ RenderObject* SVGSVGElement::createRenderer(RenderArena* arena, RenderStyle*)
     return new (arena) RenderSVGViewportContainer(this);
 }
 
-void SVGSVGElement::insertedIntoDocument()
+Node::InsertionNotificationRequest SVGSVGElement::insertedInto(Node* rootParent)
 {
-    document()->accessSVGExtensions()->addTimeContainer(this);
-    SVGStyledLocatableElement::insertedIntoDocument();
+    if (rootParent->inDocument())
+        document()->accessSVGExtensions()->addTimeContainer(this);
+    return SVGStyledLocatableElement::insertedInto(rootParent);
 }
 
-void SVGSVGElement::removedFromDocument()
+void SVGSVGElement::removedFrom(Node* rootParent)
 {
-    document()->accessSVGExtensions()->removeTimeContainer(this);
-    SVGStyledLocatableElement::removedFromDocument();
+    if (rootParent->inDocument())
+        document()->accessSVGExtensions()->removeTimeContainer(this);
+    SVGStyledLocatableElement::removedFrom(rootParent);
 }
 
 void SVGSVGElement::pauseAnimations()
index 10c59c2..6ee8887 100644 (file)
@@ -145,8 +145,8 @@ private:
     virtual bool rendererIsNeeded(const NodeRenderingContext& context) { return StyledElement::rendererIsNeeded(context); }
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
 
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
 
     virtual void svgAttributeChanged(const QualifiedName&);
 
index 000d481..d43a137 100644 (file)
@@ -117,11 +117,13 @@ void SVGScriptElement::svgAttributeChanged(const QualifiedName& attrName)
     ASSERT_NOT_REACHED();
 }
 
-void SVGScriptElement::insertedIntoDocument()
+Node::InsertionNotificationRequest SVGScriptElement::insertedInto(Node* rootParent)
 {
-    SVGElement::insertedIntoDocument();
-    ScriptElement::insertedIntoDocument();
-    SVGExternalResourcesRequired::insertedIntoDocument(this);
+    SVGElement::insertedInto(rootParent);
+    ScriptElement::insertedInto(rootParent);
+    if (rootParent->inDocument())
+        SVGExternalResourcesRequired::insertedIntoDocument(this);
+    return InsertionDone;
 }
 
 void SVGScriptElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
index 8a8c260..eb16698 100644 (file)
@@ -46,7 +46,7 @@ private:
 
     bool isSupportedAttribute(const QualifiedName&);
     virtual void parseAttribute(Attribute*) OVERRIDE;
-    virtual void insertedIntoDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
 
     virtual void svgAttributeChanged(const QualifiedName&);
index 85d6df2..7dcd623 100644 (file)
@@ -134,16 +134,19 @@ void SVGStyleElement::finishParsingChildren()
     SVGElement::finishParsingChildren();
 }
 
-void SVGStyleElement::insertedIntoDocument()
+Node::InsertionNotificationRequest SVGStyleElement::insertedInto(Node* rootParent)
 {
-    SVGElement::insertedIntoDocument();
-    StyleElement::insertedIntoDocument(document(), this);
+    SVGElement::insertedInto(rootParent);
+    if (rootParent->inDocument())
+        StyleElement::insertedIntoDocument(document(), this);
+    return InsertionDone;
 }
 
-void SVGStyleElement::removedFromDocument()
+void SVGStyleElement::removedFrom(Node* rootParent)
 {
-    SVGElement::removedFromDocument();
-    StyleElement::removedFromDocument(document(), this);
+    SVGElement::removedFrom(rootParent);
+    if (rootParent->inDocument())
+        StyleElement::removedFromDocument(document(), this);
 }
 
 void SVGStyleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
index 0566501..1b036ff 100644 (file)
@@ -54,8 +54,8 @@ private:
 
     bool isSupportedAttribute(const QualifiedName&);
     virtual void parseAttribute(Attribute*) OVERRIDE;
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
 
     virtual void finishParsingChildren();
index 7f2c1c5..3531879 100644 (file)
@@ -357,11 +357,12 @@ void SVGStyledElement::attach()
         object->updateFromElement();
 }
 
-void SVGStyledElement::insertedIntoDocument()
+Node::InsertionNotificationRequest SVGStyledElement::insertedInto(Node* rootParent)
 {
-    SVGElement::insertedIntoDocument();
+    SVGElement::insertedInto(rootParent);
     updateRelativeLengthsInformation();
     buildPendingResourcesIfNeeded();
+    return InsertionDone;
 }
 
 void SVGStyledElement::buildPendingResourcesIfNeeded()
@@ -388,14 +389,14 @@ void SVGStyledElement::buildPendingResourcesIfNeeded()
     }
 }
 
-void SVGStyledElement::removedFromDocument()
+void SVGStyledElement::removedFrom(Node* rootParent)
 {
-    updateRelativeLengthsInformation(false, this);
-    SVGElement::removedFromDocument();
+    if (rootParent->inDocument())
+        updateRelativeLengthsInformation(false, this);
+    SVGElement::removedFrom(rootParent);
     SVGElementInstance::invalidateAllInstancesOfElement(this);
-
     Document* document = this->document();
-    if (!needsPendingResourceHandling() || !document)
+    if (!rootParent->inDocument() || !needsPendingResourceHandling() || !document)
         return;
 
     document->accessSVGExtensions()->removeElementFromPendingResources(this);
@@ -463,7 +464,7 @@ AffineTransform SVGStyledElement::localCoordinateSpaceTransform(SVGLocatable::CT
 
 void SVGStyledElement::updateRelativeLengthsInformation(bool hasRelativeLengths, SVGStyledElement* element)
 {
-    // If we're not yet in a document, this function will be called again from insertedIntoDocument(). Do nothing now.
+    // If we're not yet in a document, this function will be called again from insertedInto(). Do nothing now.
     if (!inDocument())
         return;
 
index fe3a8e7..551f1be 100644 (file)
@@ -72,8 +72,8 @@ protected:
     virtual void svgAttributeChanged(const QualifiedName&);
 
     virtual void attach();
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
 
     static CSSPropertyID cssPropertyIdForSVGAttributeName(const QualifiedName&);
index aed6e7e..86a737c 100644 (file)
@@ -263,7 +263,7 @@ void SVGTRefElement::buildPendingResource()
     // Remove any existing event listener.
     clearEventListener();
 
-    // If we're not yet in a document, this function will be called again from insertedIntoDocument().
+    // If we're not yet in a document, this function will be called again from insertedInto().
     if (!inDocument())
         return;
 
@@ -286,16 +286,19 @@ void SVGTRefElement::buildPendingResource()
     target->addEventListener(eventNames().DOMNodeRemovedFromDocumentEvent, m_eventListener.get(), false);
 }
 
-void SVGTRefElement::insertedIntoDocument()
+Node::InsertionNotificationRequest SVGTRefElement::insertedInto(Node* rootParent)
 {
-    SVGStyledElement::insertedIntoDocument();
-    buildPendingResource();
+    SVGStyledElement::insertedInto(rootParent);
+    if (rootParent->inDocument())
+        buildPendingResource();
+    return InsertionDone;
 }
 
-void SVGTRefElement::removedFromDocument()
+void SVGTRefElement::removedFrom(Node* rootParent)
 {
-    SVGStyledElement::removedFromDocument();
-    clearEventListener();
+    SVGStyledElement::removedFrom(rootParent);
+    if (rootParent->inDocument())
+        clearEventListener();
 }
 
 void SVGTRefElement::clearEventListener()
index 18cbded..2f209f1 100644 (file)
@@ -50,8 +50,8 @@ private:
     virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const;
     virtual bool rendererIsNeeded(const NodeRenderingContext&);
 
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
 
     void clearEventListener();
 
index 3febdd7..2b2f387 100644 (file)
@@ -139,21 +139,24 @@ bool SVGTextPathElement::rendererIsNeeded(const NodeRenderingContext& context)
     return false;
 }
 
-void SVGTextPathElement::insertedIntoDocument()
+Node::InsertionNotificationRequest SVGTextPathElement::insertedInto(Node* rootParent)
 {
-    SVGStyledElement::insertedIntoDocument();
+    SVGStyledElement::insertedInto(rootParent);
+    if (!rootParent->inDocument())
+        return InsertionDone;
 
     String id;
     Element* targetElement = SVGURIReference::targetElementFromIRIString(href(), document(), &id);
     if (!targetElement) {
         if (hasPendingResources() || id.isEmpty())
-            return;
+            return InsertionDone;
 
         ASSERT(!hasPendingResources());
         document()->accessSVGExtensions()->addPendingResource(id, this);
         ASSERT(hasPendingResources());
-        return;
     }
+
+    return InsertionDone;
 }
 
 bool SVGTextPathElement::selfHasRelativeLengths() const
index 8023b79..42cadad 100644 (file)
@@ -115,7 +115,7 @@ public:
 private:
     SVGTextPathElement(const QualifiedName&, Document*);
 
-    virtual void insertedIntoDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
 
     bool isSupportedAttribute(const QualifiedName&);
     virtual void parseAttribute(Attribute*) OVERRIDE;
index 24bfa4e..4ba90fa 100644 (file)
@@ -21,9 +21,9 @@
 #include "config.h"
 #if ENABLE(SVG)
 #include "SVGTitleElement.h"
-#include "SVGNames.h"
 
 #include "Document.h"
+#include "SVGNames.h"
 
 namespace WebCore {
 
@@ -38,18 +38,22 @@ PassRefPtr<SVGTitleElement> SVGTitleElement::create(const QualifiedName& tagName
     return adoptRef(new SVGTitleElement(tagName, document));
 }
 
-void SVGTitleElement::insertedIntoDocument()
+Node::InsertionNotificationRequest SVGTitleElement::insertedInto(Node* rootParent)
 {
-    SVGStyledElement::insertedIntoDocument();
+    SVGStyledElement::insertedInto(rootParent);
+    if (!rootParent->inDocument())
+        return InsertionDone;
     if (firstChild())
         // FIXME: does SVG have a title text direction?
         document()->setTitleElement(StringWithDirection(textContent(), LTR), this);
+    return InsertionDone;
 }
 
-void SVGTitleElement::removedFromDocument()
+void SVGTitleElement::removedFrom(Node* rootParent)
 {
-    SVGElement::removedFromDocument();
-    document()->removeTitle(this);
+    SVGElement::removedFrom(rootParent);
+    if (rootParent->inDocument())
+        document()->removeTitle(this);
 }
 
 void SVGTitleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
index 643e52a..b8ef265 100644 (file)
@@ -35,8 +35,8 @@ public:
 private:
     SVGTitleElement(const QualifiedName&, Document*);
 
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
 
     virtual bool rendererIsNeeded(const NodeRenderingContext&) { return false; }
index 99c2293..ff622ab 100755 (executable)
@@ -175,21 +175,25 @@ static inline bool isWellFormedDocument(Document* document)
     return true;
 }
 
-void SVGUseElement::insertedIntoDocument()
+Node::InsertionNotificationRequest SVGUseElement::insertedInto(Node* rootParent)
 {
     // This functions exists to assure assumptions made in the code regarding SVGElementInstance creation/destruction are satisfied.
-    SVGStyledTransformableElement::insertedIntoDocument();
+    SVGStyledTransformableElement::insertedInto(rootParent);
+    if (!rootParent->inDocument())
+        return InsertionDone;
     ASSERT(!m_targetElementInstance || !isWellFormedDocument(document()));
     ASSERT(!hasPendingResources() || !isWellFormedDocument(document()));
     if (!m_wasInsertedByParser)
         buildPendingResource();
     SVGExternalResourcesRequired::insertedIntoDocument(this);
+    return InsertionDone;
 }
 
-void SVGUseElement::removedFromDocument()
+void SVGUseElement::removedFrom(Node* rootParent)
 {
-    SVGStyledTransformableElement::removedFromDocument();
-    clearResourceReferences();
+    SVGStyledTransformableElement::removedFrom(rootParent);
+    if (rootParent->inDocument())
+        clearResourceReferences();
 }
 
 Document* SVGUseElement::referencedDocument() const
index dd6533c..3faea90 100755 (executable)
@@ -59,8 +59,8 @@ private:
     virtual bool isValid() const { return SVGTests::isValid(); }
     virtual bool supportsFocus() const { return true; }
 
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
     virtual void buildPendingResource();
 
     bool isSupportedAttribute(const QualifiedName&);
index 29238ca..6ed8d49 100644 (file)
@@ -39,24 +39,27 @@ PassRefPtr<SVGVKernElement> SVGVKernElement::create(const QualifiedName& tagName
     return adoptRef(new SVGVKernElement(tagName, document));
 }
 
-void SVGVKernElement::insertedIntoDocument()
+Node::InsertionNotificationRequest SVGVKernElement::insertedInto(Node* rootParent)
 {
-    ContainerNode* fontNode = parentNode();
-    if (fontNode && fontNode->hasTagName(SVGNames::fontTag)) {
-        if (SVGFontElement* element = static_cast<SVGFontElement*>(fontNode))
-            element->invalidateGlyphCache();
+    if (rootParent->inDocument()) {
+        ContainerNode* fontNode = parentNode();
+        if (fontNode && fontNode->hasTagName(SVGNames::fontTag)) {
+            if (SVGFontElement* element = static_cast<SVGFontElement*>(fontNode))
+                element->invalidateGlyphCache();
+        }
     }
-    SVGElement::insertedIntoDocument();
+
+    return SVGElement::insertedInto(rootParent);
 }
 
-void SVGVKernElement::removedFromDocument()
+void SVGVKernElement::removedFrom(Node* rootParent)
 {
     ContainerNode* fontNode = parentNode();
     if (fontNode && fontNode->hasTagName(SVGNames::fontTag)) {
         if (SVGFontElement* element = static_cast<SVGFontElement*>(fontNode))
             element->invalidateGlyphCache();
     }
-    SVGElement::removedFromDocument();
+    SVGElement::removedFrom(rootParent);
 }
 
 void SVGVKernElement::buildVerticalKerningPair(KerningPairVector& kerningPairs)
index 01f0670..d331974 100644 (file)
@@ -39,8 +39,8 @@ public:
 private:
     SVGVKernElement(const QualifiedName&, Document*);
 
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
 
     virtual bool rendererIsNeeded(const NodeRenderingContext&) { return false; }
 };
index b32beab..78c7937 100644 (file)
@@ -189,9 +189,11 @@ void SVGSMILElement::reset()
     resolveFirstInterval();
 }
 
-void SVGSMILElement::insertedIntoDocument()
+Node::InsertionNotificationRequest SVGSMILElement::insertedInto(Node* rootParent)
 {
-    SVGElement::insertedIntoDocument();
+    SVGElement::insertedInto(rootParent);
+    if (!rootParent->inDocument())
+        return InsertionDone;
 
     // Verify we are not in <use> instance tree.
     ASSERT(!isInShadowTree());
@@ -199,7 +201,7 @@ void SVGSMILElement::insertedIntoDocument()
     m_attributeName = constructQualifiedName(this, fastGetAttribute(SVGNames::attributeNameAttr));
     SVGSVGElement* owner = ownerSVGElement();
     if (!owner)
-        return;
+        return InsertionDone;
     m_timeContainer = owner->timeContainer();
     ASSERT(m_timeContainer);
     m_timeContainer->setDocumentOrderIndexesDirty();
@@ -212,28 +214,33 @@ void SVGSMILElement::insertedIntoDocument()
         resolveFirstInterval();
         reschedule();
     }
+
+    return InsertionDone;
 }
 
-void SVGSMILElement::removedFromDocument()
+void SVGSMILElement::removedFrom(Node* rootParent)
 {
-    if (m_timeContainer) {
-        m_timeContainer->unschedule(this);
-        m_timeContainer = 0;
-    }
-    // Calling disconnectConditions() may kill us if there are syncbase conditions.
-    // OK, but we don't want to die inside the call.
-    RefPtr<SVGSMILElement> keepAlive(this);
-    disconnectConditions();
+    if (rootParent->inDocument()) {
+        if (m_timeContainer) {
+            m_timeContainer->unschedule(this);
+            m_timeContainer = 0;
+        }
+        // Calling disconnectConditions() may kill us if there are syncbase conditions.
+        // OK, but we don't want to die inside the call.
+        RefPtr<SVGSMILElement> keepAlive(this);
+        disconnectConditions();
 
-    // Clear target now, because disconnectConditions calls targetElement() which will recreate the target if we removed it sooner. 
-    if (m_targetElement) {
-        document()->accessSVGExtensions()->removeAnimationElementFromTarget(this, m_targetElement);
-        targetElementWillChange(m_targetElement, 0);
-        m_targetElement = 0;
+        // Clear target now, because disconnectConditions calls targetElement() which will recreate the target if we removed it sooner. 
+        if (m_targetElement) {
+            document()->accessSVGExtensions()->removeAnimationElementFromTarget(this, m_targetElement);
+            targetElementWillChange(m_targetElement, 0);
+            m_targetElement = 0;
+        }
+
+        m_attributeName = anyQName();
     }
 
-    m_attributeName = anyQName();
-    SVGElement::removedFromDocument();
+    SVGElement::removedFrom(rootParent);
 }
    
 SMILTime SVGSMILElement::parseOffsetValue(const String& data)
index eb16396..1a1f47e 100644 (file)
@@ -47,8 +47,8 @@ public:
     bool isSupportedAttribute(const QualifiedName&);
     virtual void parseAttribute(Attribute*) OVERRIDE;
     virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
-    virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
+    virtual InsertionNotificationRequest insertedInto(Node*) OVERRIDE;
+    virtual void removedFrom(Node*) OVERRIDE;
     
     virtual bool hasValidAttributeType() = 0;
     virtual void animationAttributeChanged() = 0;