Adding a ShadowRoot to image-backed element causes a crash
authormorrita@google.com <morrita@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 24 Feb 2012 09:59:07 +0000 (09:59 +0000)
committermorrita@google.com <morrita@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 24 Feb 2012 09:59:07 +0000 (09:59 +0000)
https://bugs.webkit.org/show_bug.cgi?id=78878

Reviewed by Dimitri Glazkov.

Source/WebCore:

The crash happened because NodeRenderingContext tried to append a
child to a renderer regardless one isn't capable of holding any
children if it appears in the shadow attaching phase. RenderImage
is one of such renderer classes which aren't capable.

NodeRenderingContext decide whether the contextual node as a child
can create its renderer based on RenderObject::canHaveChildren()
and Node::childShouldCreateRenderer(). But the responsibility
between these two methods are getting confused. which results this
unfortuante crash path.

This change re-aligns the responsibility:

- Now canHaveChildren() purely declares the ability of the
  renderer. If the renderer is capable of having children, it
  return true regardless of HTML semantics.

- On the other hand, childShouldCreateRenderer() cares about the
  semantics. If the element doesn't allow children to be rendered,
  this returns false.

- Note that these decision on elements are contextual. Each element
  needs to know which role it is playing in the tree composition
  algorithm of Shadow DOM. That's why the method parameter is changed
  from Node* to NodeRenderingContext.

- Fixed updateFirstLetter() which relied on this confused assumption.
  This change introduces RenderDeprecatedFlexibleBox::buttonText()
  to refine the relying assumption.

With this change, some decision points are moved from a renderer to an
element. Following renderers no longer stop reject having children:

- RenderButton, RenderListBox, RenderMenuList, RenderMeter,
  RenderProgress, RenderTextControl.

Corresponding element for such a render (HTMLProgressElement of
RenderProgress for exaple) now cares about that.

Reviewed by Dimitri Glazkov.

Tests: fast/dom/shadow/shadow-on-image-expected.html
       fast/dom/shadow/shadow-on-image.html

* dom/Element.cpp:
(WebCore::Element::childShouldCreateRenderer):
* dom/Element.h:
(Element):
* dom/Node.h:
(WebCore::Node::childShouldCreateRenderer):
* dom/NodeRenderingContext.cpp:
(WebCore::NodeRenderingContext::shouldCreateRenderer):
* dom/NodeRenderingContext.h:
(NodeRenderingContext):
(WebCore::NodeRenderingContext::isOnEncapsulationBoundary):
(WebCore):
* html/HTMLDetailsElement.cpp:
(WebCore::HTMLDetailsElement::childShouldCreateRenderer):
* html/HTMLDetailsElement.h:
(HTMLDetailsElement):
* html/HTMLMediaElement.cpp:
(WebCore):
(WebCore::HTMLMediaElement::childShouldCreateRenderer):
* html/HTMLMediaElement.h:
(HTMLMediaElement):
* html/HTMLMeterElement.cpp:
(WebCore::HTMLMeterElement::childShouldCreateRenderer):
(WebCore):
* html/HTMLMeterElement.h:
(HTMLMeterElement):
* html/HTMLProgressElement.cpp:
(WebCore::HTMLProgressElement::childShouldCreateRenderer):
(WebCore):
* html/HTMLProgressElement.h:
(HTMLProgressElement):
* html/HTMLSelectElement.cpp:
(WebCore::HTMLSelectElement::childShouldCreateRenderer):
(WebCore):
* html/HTMLSelectElement.h:
(HTMLSelectElement):
* html/HTMLSummaryElement.cpp:
(WebCore::HTMLSummaryElement::childShouldCreateRenderer):
(WebCore):
* html/HTMLSummaryElement.h:
(HTMLSummaryElement):
* html/HTMLTextFormControlElement.cpp:
(WebCore::HTMLTextFormControlElement::childShouldCreateRenderer):
(WebCore):
* html/HTMLTextFormControlElement.h:
(HTMLTextFormControlElement):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::updateFirstLetter):
* rendering/RenderButton.cpp:
* rendering/RenderButton.h:
(RenderButton):
* rendering/RenderDeprecatedFlexibleBox.h:
(WebCore::RenderDeprecatedFlexibleBox::buttonText):
* rendering/RenderListBox.h:
(RenderListBox):
* rendering/RenderMedia.h:
(WebCore::RenderMedia::canHaveChildren):
* rendering/RenderMenuList.h:
(RenderMenuList):
(WebCore::RenderMenuList::hasControlClip):
* rendering/RenderMeter.h:
* rendering/RenderProgress.h:
* rendering/RenderTextControl.h:
* rendering/svg/RenderSVGRoot.h:
(WebCore::RenderSVGRoot::canHaveChildren):
* svg/SVGAElement.cpp:
(WebCore::SVGAElement::childShouldCreateRenderer):
* svg/SVGAElement.h:
(SVGAElement):
* svg/SVGAltGlyphElement.cpp:
(WebCore::SVGAltGlyphElement::childShouldCreateRenderer):
* svg/SVGAltGlyphElement.h:
(SVGAltGlyphElement):
* svg/SVGDocument.cpp:
(WebCore::SVGDocument::childShouldCreateRenderer):
* svg/SVGDocument.h:
(SVGDocument):
* svg/SVGElement.cpp:
(WebCore::SVGElement::childShouldCreateRenderer):
* svg/SVGElement.h:
(SVGElement):
* svg/SVGForeignObjectElement.cpp:
(WebCore::SVGForeignObjectElement::childShouldCreateRenderer):
* svg/SVGForeignObjectElement.h:
(SVGForeignObjectElement):
* svg/SVGSwitchElement.cpp:
(WebCore::SVGSwitchElement::childShouldCreateRenderer):
* svg/SVGSwitchElement.h:
(SVGSwitchElement):
* svg/SVGTRefElement.cpp:
(WebCore::SVGTRefElement::childShouldCreateRenderer):
* svg/SVGTRefElement.h:
(SVGTRefElement):
* svg/SVGTSpanElement.cpp:
(WebCore::SVGTSpanElement::childShouldCreateRenderer):
* svg/SVGTSpanElement.h:
(SVGTSpanElement):
* svg/SVGTextElement.cpp:
(WebCore::SVGTextElement::childShouldCreateRenderer):
* svg/SVGTextElement.h:
(SVGTextElement):
* svg/SVGTextPathElement.cpp:
(WebCore::SVGTextPathElement::childShouldCreateRenderer):
* svg/SVGTextPathElement.h:

LayoutTests:

* fast/dom/shadow/shadow-on-image-expected.html: Added.
* fast/dom/shadow/shadow-on-image.html: Added.

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

55 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/shadow/shadow-on-image-expected.html [new file with mode: 0644]
LayoutTests/fast/dom/shadow/shadow-on-image.html [new file with mode: 0644]
LayoutTests/platform/chromium/test_expectations.txt
Source/WebCore/ChangeLog
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/Element.h
Source/WebCore/dom/Node.h
Source/WebCore/dom/NodeRenderingContext.cpp
Source/WebCore/dom/NodeRenderingContext.h
Source/WebCore/html/HTMLDetailsElement.cpp
Source/WebCore/html/HTMLDetailsElement.h
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/html/HTMLMeterElement.cpp
Source/WebCore/html/HTMLMeterElement.h
Source/WebCore/html/HTMLProgressElement.cpp
Source/WebCore/html/HTMLProgressElement.h
Source/WebCore/html/HTMLSelectElement.cpp
Source/WebCore/html/HTMLSelectElement.h
Source/WebCore/html/HTMLSummaryElement.cpp
Source/WebCore/html/HTMLSummaryElement.h
Source/WebCore/html/HTMLTextFormControlElement.cpp
Source/WebCore/html/HTMLTextFormControlElement.h
Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderButton.cpp
Source/WebCore/rendering/RenderButton.h
Source/WebCore/rendering/RenderDeprecatedFlexibleBox.h
Source/WebCore/rendering/RenderListBox.h
Source/WebCore/rendering/RenderMedia.h
Source/WebCore/rendering/RenderMenuList.h
Source/WebCore/rendering/RenderMeter.h
Source/WebCore/rendering/RenderProgress.h
Source/WebCore/rendering/RenderTextControl.h
Source/WebCore/rendering/svg/RenderSVGRoot.h
Source/WebCore/svg/SVGAElement.cpp
Source/WebCore/svg/SVGAElement.h
Source/WebCore/svg/SVGAltGlyphElement.cpp
Source/WebCore/svg/SVGAltGlyphElement.h
Source/WebCore/svg/SVGDocument.cpp
Source/WebCore/svg/SVGDocument.h
Source/WebCore/svg/SVGElement.cpp
Source/WebCore/svg/SVGElement.h
Source/WebCore/svg/SVGForeignObjectElement.cpp
Source/WebCore/svg/SVGForeignObjectElement.h
Source/WebCore/svg/SVGSwitchElement.cpp
Source/WebCore/svg/SVGSwitchElement.h
Source/WebCore/svg/SVGTRefElement.cpp
Source/WebCore/svg/SVGTRefElement.h
Source/WebCore/svg/SVGTSpanElement.cpp
Source/WebCore/svg/SVGTSpanElement.h
Source/WebCore/svg/SVGTextElement.cpp
Source/WebCore/svg/SVGTextElement.h
Source/WebCore/svg/SVGTextPathElement.cpp
Source/WebCore/svg/SVGTextPathElement.h

index a6a3bfd..2081f6d 100644 (file)
@@ -1,3 +1,13 @@
+2012-02-23  MORITA Hajime  <morrita@google.com>
+
+        Adding a ShadowRoot to image-backed element causes a crash
+        https://bugs.webkit.org/show_bug.cgi?id=78878
+
+        Reviewed by Dimitri Glazkov.
+
+        * fast/dom/shadow/shadow-on-image-expected.html: Added.
+        * fast/dom/shadow/shadow-on-image.html: Added.
+
 2012-02-24  Kenichi Ishibashi  <bashi@chromium.org>
 
         [Qt] Unreviewed gardening.
diff --git a/LayoutTests/fast/dom/shadow/shadow-on-image-expected.html b/LayoutTests/fast/dom/shadow/shadow-on-image-expected.html
new file mode 100644 (file)
index 0000000..536b176
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.with-image {
+    content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAFklEQVQIHWPUFPzPgA0wYRMEiQ1OCQD4SAFJZaEkKQAAAABJRU5ErkJggg==);
+}
+</style>
+</head>
+<body>
+<div class="with-image"></div>
+<div class="with-image"></div>
+<div class="with-image"></div>
+</body>
+</html>
diff --git a/LayoutTests/fast/dom/shadow/shadow-on-image.html b/LayoutTests/fast/dom/shadow/shadow-on-image.html
new file mode 100644 (file)
index 0000000..93d7ab4
--- /dev/null
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+
+var imageContentStyle = "content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAFklEQVQIHWPUFPzPgA0wYRMEiQ1OCQD4SAFJZaEkKQAAAABJRU5ErkJggg==);"
+
+function createImageDivWithShadow() {
+  var imageDiv = document.createElement('div');
+  imageDiv.setAttribute("style", imageContentStyle);
+  var shadow = new WebKitShadowRoot(imageDiv); 
+  shadow.appendChild(document.createElement('div'));
+  return imageDiv;
+}
+
+function createImageDivWithContentShadow() {
+  var imageDiv = document.createElement('div');
+  imageDiv.setAttribute("style", imageContentStyle);
+  imageDiv.appendChild(document.createElement('div'));
+  var shadow = new WebKitShadowRoot(imageDiv); 
+  shadow.appendChild(document.createElement('div'));
+  shadow.appendChild(document.createElement('content'));
+  return imageDiv;
+}
+
+function createImageDivWithFallbackContentShadow() {
+  var imageDiv = document.createElement('div');
+  imageDiv.setAttribute("style", imageContentStyle);
+  var shadow = new WebKitShadowRoot(imageDiv); 
+  shadow.appendChild(document.createElement('div'));
+  var content = document.createElement('content');
+  content.innerHTML = "<div></div>";
+  shadow.appendChild(content);
+  return imageDiv;
+}
+
+function test() {
+    document.body.appendChild(createImageDivWithShadow());
+    document.body.appendChild(createImageDivWithContentShadow());
+    document.body.appendChild(createImageDivWithFallbackContentShadow());
+}
+</script>
+</head>
+<body onload="test()"></body>
+</html>
index c09c2e1..f322a1f 100644 (file)
@@ -4166,6 +4166,9 @@ BUGCR114777 MAC : compositing/culling/filter-occlusion-blur.html = PASS IMAGE
 BUGCR114777 WIN DEBUG : compositing/culling/filter-occlusion-blur-large.html = PASS IMAGE
 BUGCR114777 WIN DEBUG : compositing/culling/filter-occlusion-blur.html = PASS IMAGE
 
+// Needs rebaseline
+BUGWK78878 : media/audio-repaint.html = IMAGE
+
 // Needs new baselines.
 BUGWK65072 : svg/text/exs-display-none.svg = IMAGE IMAGE+TEXT
 BUGWK65072 : svg/text/ems-display-none.svg = IMAGE IMAGE+TEXT
index d04d1ed..2874b8a 100644 (file)
@@ -1,3 +1,159 @@
+2012-02-23  MORITA Hajime  <morrita@google.com>
+
+        Adding a ShadowRoot to image-backed element causes a crash
+        https://bugs.webkit.org/show_bug.cgi?id=78878
+
+        Reviewed by Dimitri Glazkov.
+
+        The crash happened because NodeRenderingContext tried to append a
+        child to a renderer regardless one isn't capable of holding any
+        children if it appears in the shadow attaching phase. RenderImage
+        is one of such renderer classes which aren't capable.
+
+        NodeRenderingContext decide whether the contextual node as a child
+        can create its renderer based on RenderObject::canHaveChildren()
+        and Node::childShouldCreateRenderer(). But the responsibility
+        between these two methods are getting confused. which results this
+        unfortuante crash path.
+
+        This change re-aligns the responsibility:
+
+        - Now canHaveChildren() purely declares the ability of the
+          renderer. If the renderer is capable of having children, it
+          return true regardless of HTML semantics.
+
+        - On the other hand, childShouldCreateRenderer() cares about the
+          semantics. If the element doesn't allow children to be rendered,
+          this returns false.
+
+        - Note that these decision on elements are contextual. Each element
+          needs to know which role it is playing in the tree composition
+          algorithm of Shadow DOM. That's why the method parameter is changed
+          from Node* to NodeRenderingContext.
+
+        - Fixed updateFirstLetter() which relied on this confused assumption.
+          This change introduces RenderDeprecatedFlexibleBox::buttonText()
+          to refine the relying assumption.
+
+        With this change, some decision points are moved from a renderer to an
+        element. Following renderers no longer stop reject having children:
+
+        - RenderButton, RenderListBox, RenderMenuList, RenderMeter,
+          RenderProgress, RenderTextControl.
+
+        Corresponding element for such a render (HTMLProgressElement of
+        RenderProgress for exaple) now cares about that.
+
+        Reviewed by Dimitri Glazkov.
+
+        Tests: fast/dom/shadow/shadow-on-image-expected.html
+               fast/dom/shadow/shadow-on-image.html
+
+        * dom/Element.cpp:
+        (WebCore::Element::childShouldCreateRenderer):
+        * dom/Element.h:
+        (Element):
+        * dom/Node.h:
+        (WebCore::Node::childShouldCreateRenderer):
+        * dom/NodeRenderingContext.cpp:
+        (WebCore::NodeRenderingContext::shouldCreateRenderer):
+        * dom/NodeRenderingContext.h:
+        (NodeRenderingContext):
+        (WebCore::NodeRenderingContext::isOnEncapsulationBoundary):
+        (WebCore):
+        * html/HTMLDetailsElement.cpp:
+        (WebCore::HTMLDetailsElement::childShouldCreateRenderer):
+        * html/HTMLDetailsElement.h:
+        (HTMLDetailsElement):
+        * html/HTMLMediaElement.cpp:
+        (WebCore):
+        (WebCore::HTMLMediaElement::childShouldCreateRenderer):
+        * html/HTMLMediaElement.h:
+        (HTMLMediaElement):
+        * html/HTMLMeterElement.cpp:
+        (WebCore::HTMLMeterElement::childShouldCreateRenderer):
+        (WebCore):
+        * html/HTMLMeterElement.h:
+        (HTMLMeterElement):
+        * html/HTMLProgressElement.cpp:
+        (WebCore::HTMLProgressElement::childShouldCreateRenderer):
+        (WebCore):
+        * html/HTMLProgressElement.h:
+        (HTMLProgressElement):
+        * html/HTMLSelectElement.cpp:
+        (WebCore::HTMLSelectElement::childShouldCreateRenderer):
+        (WebCore):
+        * html/HTMLSelectElement.h:
+        (HTMLSelectElement):
+        * html/HTMLSummaryElement.cpp:
+        (WebCore::HTMLSummaryElement::childShouldCreateRenderer):
+        (WebCore):
+        * html/HTMLSummaryElement.h:
+        (HTMLSummaryElement):
+        * html/HTMLTextFormControlElement.cpp:
+        (WebCore::HTMLTextFormControlElement::childShouldCreateRenderer):
+        (WebCore):
+        * html/HTMLTextFormControlElement.h:
+        (HTMLTextFormControlElement):
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::updateFirstLetter):
+        * rendering/RenderButton.cpp:
+        * rendering/RenderButton.h:
+        (RenderButton):
+        * rendering/RenderDeprecatedFlexibleBox.h:
+        (WebCore::RenderDeprecatedFlexibleBox::buttonText):
+        * rendering/RenderListBox.h:
+        (RenderListBox):
+        * rendering/RenderMedia.h:
+        (WebCore::RenderMedia::canHaveChildren):
+        * rendering/RenderMenuList.h:
+        (RenderMenuList):
+        (WebCore::RenderMenuList::hasControlClip):
+        * rendering/RenderMeter.h:
+        * rendering/RenderProgress.h:
+        * rendering/RenderTextControl.h:
+        * rendering/svg/RenderSVGRoot.h:
+        (WebCore::RenderSVGRoot::canHaveChildren):
+        * svg/SVGAElement.cpp:
+        (WebCore::SVGAElement::childShouldCreateRenderer):
+        * svg/SVGAElement.h:
+        (SVGAElement):
+        * svg/SVGAltGlyphElement.cpp:
+        (WebCore::SVGAltGlyphElement::childShouldCreateRenderer):
+        * svg/SVGAltGlyphElement.h:
+        (SVGAltGlyphElement):
+        * svg/SVGDocument.cpp:
+        (WebCore::SVGDocument::childShouldCreateRenderer):
+        * svg/SVGDocument.h:
+        (SVGDocument):
+        * svg/SVGElement.cpp:
+        (WebCore::SVGElement::childShouldCreateRenderer):
+        * svg/SVGElement.h:
+        (SVGElement):
+        * svg/SVGForeignObjectElement.cpp:
+        (WebCore::SVGForeignObjectElement::childShouldCreateRenderer):
+        * svg/SVGForeignObjectElement.h:
+        (SVGForeignObjectElement):
+        * svg/SVGSwitchElement.cpp:
+        (WebCore::SVGSwitchElement::childShouldCreateRenderer):
+        * svg/SVGSwitchElement.h:
+        (SVGSwitchElement):
+        * svg/SVGTRefElement.cpp:
+        (WebCore::SVGTRefElement::childShouldCreateRenderer):
+        * svg/SVGTRefElement.h:
+        (SVGTRefElement):
+        * svg/SVGTSpanElement.cpp:
+        (WebCore::SVGTSpanElement::childShouldCreateRenderer):
+        * svg/SVGTSpanElement.h:
+        (SVGTSpanElement):
+        * svg/SVGTextElement.cpp:
+        (WebCore::SVGTextElement::childShouldCreateRenderer):
+        * svg/SVGTextElement.h:
+        (SVGTextElement):
+        * svg/SVGTextPathElement.cpp:
+        (WebCore::SVGTextPathElement::childShouldCreateRenderer):
+        * svg/SVGTextPathElement.h:
+
 2012-02-24  Kentaro Hara  <haraken@chromium.org>
 
         Support [Supplemental] on static methods
         (WebCore::RenderFrameSet::positionFramesWithFlattening):
         * rendering/RenderImage.cpp:
         (WebCore::RenderImage::paintReplaced):
-                * rendering/RenderLayer.cpp:
+        * rendering/RenderLayer.cpp:
         (WebCore::RenderLayer::scrollRectToVisible):
         (WebCore::RenderLayer::positionOverflowControls):
         (WebCore::RenderLayer::calculateRects):
         (WebCore::RenderFrameSet::positionFramesWithFlattening):
         * rendering/RenderImage.cpp:
         (WebCore::RenderImage::paintReplaced):
-        * rendering/RenderLayer.cpp:
+                * rendering/RenderLayer.cpp:
         (WebCore::RenderLayer::scrollRectToVisible):
         (WebCore::RenderLayer::positionOverflowControls):
         (WebCore::RenderLayer::calculateRects):
index edc5a62..1b4d839 100644 (file)
@@ -1852,13 +1852,13 @@ void Element::setUnsignedIntegralAttribute(const QualifiedName& attributeName, u
 }
 
 #if ENABLE(SVG)
-bool Element::childShouldCreateRenderer(Node* child) const
+bool Element::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
 {
     // Only create renderers for SVG elements whose parents are SVG elements, or for proper <svg xmlns="svgNS"> subdocuments.
-    if (child->isSVGElement())
-        return child->hasTagName(SVGNames::svgTag) || isSVGElement();
+    if (childContext.node()->isSVGElement())
+        return childContext.node()->hasTagName(SVGNames::svgTag) || isSVGElement();
 
-    return Node::childShouldCreateRenderer(child);
+    return Node::childShouldCreateRenderer(childContext);
 }
 #endif
     
index 31da1ed..c9a1139 100644 (file)
@@ -372,7 +372,7 @@ public:
     virtual void dispatchFormControlChangeEvent() { }
 
 #if ENABLE(SVG)
-    virtual bool childShouldCreateRenderer(Node*) const; 
+    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const;
 #endif
     
 #if ENABLE(FULLSCREEN_API)
index e42ea50..9ca1264 100644 (file)
@@ -497,7 +497,7 @@ public:
     virtual void willRemove();
     void createRendererIfNeeded();
     virtual bool rendererIsNeeded(const NodeRenderingContext&);
-    virtual bool childShouldCreateRenderer(Node*) const { return true; }
+    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const { return true; }
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
     ContainerNode* parentNodeForRenderingAndStyle();
     
index 663d55f..cdcb102 100644 (file)
@@ -271,24 +271,13 @@ bool NodeRenderingContext::shouldCreateRenderer() const
 
     if (m_phase == AttachingNotInTree || m_phase == AttachingNotDistributed || m_phase == AttachingNotFallbacked)
         return false;
-
     RenderObject* parentRenderer = this->parentRenderer();
     if (!parentRenderer)
         return false;
-
-    if (m_phase == AttachingStraight) {
-        // FIXME: Ignoring canHaveChildren() in a case of shadow children might be wrong.
-        // See https://bugs.webkit.org/show_bug.cgi?id=52423
-        if (!parentRenderer->canHaveChildren())
-            return false;
-
-        if (m_visualParentShadowRootList)
-            return false;
-    }
-
-    if (!m_parentNodeForRenderingAndStyle->childShouldCreateRenderer(m_node))
+    if (!parentRenderer->canHaveChildren())
+        return false;
+    if (!m_parentNodeForRenderingAndStyle->childShouldCreateRenderer(*this))
         return false;
-
     return true;
 }
 
index 4373e2f..ca20d52 100644 (file)
@@ -62,6 +62,7 @@ public:
 
     void hostChildrenChanged();
 
+    bool isOnEncapsulationBoundary() const;
     bool hasFlowThreadParent() const { return m_parentFlowRenderer; }
     RenderFlowThread* parentFlowRenderer() const { return m_parentFlowRenderer; }
     void moveToFlowThreadIfNeeded();
@@ -109,6 +110,13 @@ inline InsertionPoint* NodeRenderingContext::insertionPoint() const
     return m_insertionPoint;
 }
 
+inline bool NodeRenderingContext::isOnEncapsulationBoundary() const
+{
+    return (m_phase == AttachingDistributed
+            || m_phase == AttachingShadowChild
+            || m_phase == AttachingFallbacked);
+}
+
 class NodeRendererFactory {
     WTF_MAKE_NONCOPYABLE(NodeRendererFactory);
     WTF_MAKE_FAST_ALLOCATED;
index aa264c2..d49daa4 100644 (file)
@@ -28,6 +28,7 @@
 #include "HTMLSummaryElement.h"
 #include "LocalizedStrings.h"
 #include "MouseEvent.h"
+#include "NodeRenderingContext.h"
 #include "RenderDetails.h"
 #include "ShadowRoot.h"
 #include "ShadowRootList.h"
@@ -137,15 +138,18 @@ void HTMLDetailsElement::parseAttribute(Attribute* attr)
         HTMLElement::parseAttribute(attr);
 }
 
-bool HTMLDetailsElement::childShouldCreateRenderer(Node* child) const
+bool HTMLDetailsElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
 {
+    if (!childContext.isOnEncapsulationBoundary())
+        return false;
+
     if (m_isOpen)
-        return true;
+        return HTMLElement::childShouldCreateRenderer(childContext);
 
-    if (!child->hasTagName(summaryTag))
+    if (!childContext.node()->hasTagName(summaryTag))
         return false;
 
-    return child == findMainSummary();
+    return childContext.node() == findMainSummary() && HTMLElement::childShouldCreateRenderer(childContext);
 }
 
 void HTMLDetailsElement::toggleOpen()
index a86a365..94e8833 100644 (file)
@@ -36,9 +36,8 @@ private:
     HTMLDetailsElement(const QualifiedName&, Document*);
 
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
-
+    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const OVERRIDE;
     virtual void parseAttribute(Attribute*) OVERRIDE;
-    bool childShouldCreateRenderer(Node*) const;
 
     void createShadowSubtree();
 
index 2eb2a9b..b956d66 100644 (file)
@@ -63,6 +63,7 @@
 #include "MediaQueryEvaluator.h"
 #include "MouseEvent.h"
 #include "MIMETypeRegistry.h"
+#include "NodeRenderingContext.h"
 #include "Page.h"
 #include "RenderVideo.h"
 #include "RenderView.h"
@@ -464,7 +465,12 @@ RenderObject* HTMLMediaElement::createRenderer(RenderArena* arena, RenderStyle*)
     return new (arena) RenderMedia(this);
 #endif
 }
+
+bool HTMLMediaElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
+{
+    return childContext.isOnEncapsulationBoundary() && HTMLElement::childShouldCreateRenderer(childContext);
+}
+
 void HTMLMediaElement::insertedIntoDocument()
 {
     LOG(Media, "HTMLMediaElement::insertedIntoDocument");
index 404b5a4..126b78f 100644 (file)
@@ -339,6 +339,7 @@ private:
     virtual bool isMouseFocusable() const;
     virtual bool rendererIsNeeded(const NodeRenderingContext&);
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const OVERRIDE;
     virtual void insertedIntoDocument();
     virtual void removedFromDocument();
     virtual void didRecalcStyle(StyleChange);
index 7c83994..3be84e3 100644 (file)
@@ -26,6 +26,7 @@
 #include "EventNames.h"
 #include "ExceptionCode.h"
 #include "FormDataList.h"
+#include "NodeRenderingContext.h"
 #include "HTMLFormElement.h"
 #include "HTMLNames.h"
 #include "HTMLParserIdioms.h"
@@ -60,6 +61,11 @@ RenderObject* HTMLMeterElement::createRenderer(RenderArena* arena, RenderStyle*)
     return new (arena) RenderMeter(this);
 }
 
+bool HTMLMeterElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
+{
+    return childContext.isOnEncapsulationBoundary() && HTMLElement::childShouldCreateRenderer(childContext);
+}
+
 const AtomicString& HTMLMeterElement::formControlType() const
 {
     DEFINE_STATIC_LOCAL(const AtomicString, meter, ("meter"));
index fb71bc9..dc5e7cc 100644 (file)
@@ -70,6 +70,7 @@ private:
     virtual bool recalcWillValidate() const { return false; }
     virtual const AtomicString& formControlType() const;
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const OVERRIDE;
     virtual void parseAttribute(Attribute*) OVERRIDE;
     virtual void attach();
 
index ed6950c..78bbde3 100644 (file)
@@ -26,6 +26,7 @@
 #include "EventNames.h"
 #include "ExceptionCode.h"
 #include "FormDataList.h"
+#include "NodeRenderingContext.h"
 #include "HTMLDivElement.h"
 #include "HTMLFormElement.h"
 #include "HTMLNames.h"
@@ -64,6 +65,11 @@ RenderObject* HTMLProgressElement::createRenderer(RenderArena* arena, RenderStyl
     return new (arena) RenderProgress(this);
 }
 
+bool HTMLProgressElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
+{
+    return childContext.isOnEncapsulationBoundary() && HTMLElement::childShouldCreateRenderer(childContext);
+}
+
 bool HTMLProgressElement::supportsFocus() const
 {
     return Node::supportsFocus() && !disabled();
index 731f80b..dfd0067 100644 (file)
@@ -58,6 +58,7 @@ private:
     virtual const AtomicString& formControlType() const;
 
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const OVERRIDE;
 
     virtual void parseAttribute(Attribute*) OVERRIDE;
 
index 715d682..a2c31dc 100644 (file)
@@ -42,6 +42,7 @@
 #include "HTMLOptionsCollection.h"
 #include "KeyboardEvent.h"
 #include "MouseEvent.h"
+#include "NodeRenderingContext.h"
 #include "Page.h"
 #include "RenderListBox.h"
 #include "RenderMenuList.h"
@@ -325,6 +326,11 @@ RenderObject* HTMLSelectElement::createRenderer(RenderArena* arena, RenderStyle*
     return new (arena) RenderListBox(this);
 }
 
+bool HTMLSelectElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
+{
+    return childContext.isOnEncapsulationBoundary() && HTMLFormControlElementWithState::childShouldCreateRenderer(childContext);
+}
+
 HTMLOptionsCollection* HTMLSelectElement::options()
 {
     if (!m_optionsCollection)
index 0467724..77c081e 100644 (file)
@@ -124,6 +124,7 @@ private:
     virtual void parseAttribute(Attribute*) OVERRIDE;
     virtual bool isPresentationAttribute(Attribute*) const OVERRIDE;
 
+    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const OVERRIDE;
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle *);
     virtual bool appendFormData(FormDataList&, bool);
 
index e2957b2..a3494af 100644 (file)
 #include "DetailsMarkerControl.h"
 #include "HTMLContentElement.h"
 #include "HTMLDetailsElement.h"
-#include "KeyboardEvent.h"
 #include "HTMLNames.h"
+#include "KeyboardEvent.h"
 #include "MouseEvent.h"
+#include "NodeRenderingContext.h"
 #include "PlatformMouseEvent.h"
 #include "RenderSummary.h"
 #include "ShadowRoot.h"
@@ -72,6 +73,11 @@ RenderObject* HTMLSummaryElement::createRenderer(RenderArena* arena, RenderStyle
     return new (arena) RenderSummary(this);
 }
 
+bool HTMLSummaryElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
+{
+    return childContext.isOnEncapsulationBoundary() && HTMLElement::childShouldCreateRenderer(childContext);
+}
+
 void HTMLSummaryElement::createShadowSubtree()
 {
     ASSERT(!hasShadowRoot());
index e64df07..49a2d0b 100644 (file)
@@ -36,6 +36,7 @@ private:
     HTMLSummaryElement(const QualifiedName&, Document*);
 
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const OVERRIDE;
     virtual void defaultEventHandler(Event*);
 
     void createShadowSubtree();
index fcfd967..f47e1f2 100644 (file)
@@ -37,6 +37,7 @@
 #include "HTMLFormElement.h"
 #include "HTMLInputElement.h"
 #include "HTMLNames.h"
+#include "NodeRenderingContext.h"
 #include "Page.h"
 #include "RenderBox.h"
 #include "RenderTextControl.h"
@@ -64,6 +65,11 @@ HTMLTextFormControlElement::~HTMLTextFormControlElement()
 {
 }
 
+bool HTMLTextFormControlElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
+{
+    return childContext.isOnEncapsulationBoundary() && HTMLFormControlElementWithState::childShouldCreateRenderer(childContext);
+}
+
 void HTMLTextFormControlElement::insertedIntoDocument()
 {
     HTMLFormControlElement::insertedIntoDocument();
index f810c5e..59cd741 100644 (file)
@@ -114,6 +114,7 @@ private:
 
     virtual void dispatchFocusEvent(PassRefPtr<Node> oldFocusedNode);
     virtual void dispatchBlurEvent(PassRefPtr<Node> newFocusedNode);
+    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const OVERRIDE;
 
     bool isPlaceholderEmpty() const;
 
index 969cf66..413c60e 100755 (executable)
@@ -5810,6 +5810,36 @@ static inline bool shouldSkipForFirstLetter(UChar c)
     return isSpaceOrNewline(c) || c == noBreakSpace || isPunctuationForFirstLetter(c);
 }
 
+// We only honor first-letter if 
+// - the firstLetterBlock can have children in the DOM and
+// - the block doesn't have any special assumption on its text children.
+// This correctly prevents form controls from honoring first-letter.
+static inline bool isSafeToCreateFirstLetterRendererOn(RenderObject* renderer)
+{
+    return (renderer->canHaveChildren()
+            && !(renderer->isDeprecatedFlexibleBox()
+                 && static_cast<RenderDeprecatedFlexibleBox*>(renderer)->buttonText()));
+}
+
+static inline RenderObject* findFirstLetterBlock(RenderBlock* start)
+{
+    RenderObject* firstLetterBlock = start;
+    while (true) {
+        bool canHaveFirstLetterRenderer = firstLetterBlock->style()->hasPseudoStyle(FIRST_LETTER)
+            && isSafeToCreateFirstLetterRendererOn(firstLetterBlock);
+        if (canHaveFirstLetterRenderer)
+            return firstLetterBlock;
+
+        RenderObject* parentBlock = firstLetterBlock->parent();
+        if (firstLetterBlock->isReplaced() || !parentBlock || parentBlock->firstChild() != firstLetterBlock || 
+            !parentBlock->isBlockFlow())
+            return 0;
+        firstLetterBlock = parentBlock;
+    } 
+
+    return 0;
+}
+   
 void RenderBlock::updateFirstLetter()
 {
     if (!document()->usesFirstLetterRules())
@@ -5820,23 +5850,8 @@ void RenderBlock::updateFirstLetter()
 
     // FIXME: We need to destroy the first-letter object if it is no longer the first child.  Need to find
     // an efficient way to check for that situation though before implementing anything.
-    RenderObject* firstLetterBlock = this;
-    bool hasPseudoStyle = false;
-    while (true) {
-        // We only honor first-letter if the firstLetterBlock can have children in the DOM. This correctly 
-        // prevents form controls from honoring first-letter.
-        hasPseudoStyle = firstLetterBlock->style()->hasPseudoStyle(FIRST_LETTER) 
-            && firstLetterBlock->canHaveChildren();
-        if (hasPseudoStyle)
-            break;
-        RenderObject* parentBlock = firstLetterBlock->parent();
-        if (firstLetterBlock->isReplaced() || !parentBlock || parentBlock->firstChild() != firstLetterBlock || 
-            !parentBlock->isBlockFlow())
-            break;
-        firstLetterBlock = parentBlock;
-    } 
-
-    if (!hasPseudoStyle) 
+    RenderObject* firstLetterBlock = findFirstLetterBlock(this);
+    if (!firstLetterBlock)
         return;
 
     // Drill into inlines looking for our first text child.
index e6d1920..dd23130 100644 (file)
@@ -118,14 +118,6 @@ void RenderButton::updateFromElement()
     }
 }
 
-bool RenderButton::canHaveChildren() const
-{
-    // Input elements can't have children, but button elements can.  We'll
-    // write the code assuming any other button types that might emerge in the future
-    // can also have children.
-    return !node()->hasTagName(inputTag);
-}
-
 void RenderButton::setText(const String& str)
 {
     if (str.isEmpty()) {
@@ -157,6 +149,11 @@ void RenderButton::updateBeforeAfterContent(PseudoId type)
         children()->updateBeforeAfterContent(this, type);
 }
 
+RenderText* RenderButton::buttonText() const
+{
+    return m_buttonText;
+}
+
 LayoutRect RenderButton::controlClipRect(const LayoutPoint& additionalOffset) const
 {
     // Clip to the padding box to at least give content the extra padding space.
index 24cecd2..c851abc 100644 (file)
@@ -50,14 +50,13 @@ public:
 
     virtual void updateBeforeAfterContent(PseudoId);
 
+    virtual RenderText* buttonText() const OVERRIDE;
     virtual bool hasControlClip() const { return true; }
     virtual LayoutRect controlClipRect(const LayoutPoint&) const;
 
     void setText(const String&);
     String text() const;
 
-    virtual bool canHaveChildren() const;
-
 private:
     virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
index 417ebac..101bedb 100644 (file)
@@ -49,6 +49,7 @@ public:
     virtual bool isDeprecatedFlexibleBox() const { return true; }
     virtual bool isFlexingChildren() const { return m_flexingChildren; }
     virtual bool isStretchingChildren() const { return m_stretchingChildren; }
+    virtual RenderText* buttonText() const { return 0; }
 
     void placeChild(RenderBox* child, const LayoutPoint& location);
 
index e63e003..407fa52 100644 (file)
@@ -62,8 +62,6 @@ private:
 
     virtual void updateFromElement();
 
-    virtual bool canHaveChildren() const { return false; }
-
     virtual bool hasControlClip() const { return true; }
     virtual void paintObject(PaintInfo&, const LayoutPoint&);
     virtual LayoutRect controlClipRect(const LayoutPoint&) const;
index 78e36c4..54e625a 100644 (file)
@@ -51,6 +51,7 @@ protected:
 private:
     virtual RenderObjectChildList* virtualChildren() { return children(); }
     virtual const RenderObjectChildList* virtualChildren() const { return children(); }
+    virtual bool canHaveChildren() const { return true; }
 
     virtual const char* renderName() const { return "RenderMedia"; }
     virtual bool isMedia() const { return true; }
index b6f4436..27872eb 100644 (file)
@@ -62,12 +62,12 @@ private:
     virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
     virtual void removeChild(RenderObject*);
     virtual bool createsAnonymousWrapper() const { return true; }
-    virtual bool canHaveChildren() const { return false; }
 
     virtual void updateFromElement();
 
-    virtual bool hasControlClip() const { return true; }
     virtual LayoutRect controlClipRect(const LayoutPoint&) const;
+    virtual bool hasControlClip() const { return true; }
+    virtual RenderText* buttonText() const OVERRIDE { return m_buttonText; }
 
     virtual const char* renderName() const { return "RenderMenuList"; }
 
index 6eb1717..c4deb12 100644 (file)
@@ -42,7 +42,6 @@ private:
     virtual const char* renderName() const { return "RenderMeter"; }
     virtual bool isMeter() const { return true; }
     virtual bool requiresForcedStyleRecalcPropagation() const { return true; }
-    virtual bool canHaveChildren() const { return false; }
     virtual void updateFromElement();
 
     double valueRatio() const;
index 62436fd..fa92bb2 100644 (file)
@@ -45,7 +45,6 @@ private:
     virtual const char* renderName() const { return "RenderProgress"; }
     virtual bool isProgress() const { return true; }
     virtual bool requiresForcedStyleRecalcPropagation() const { return true; }
-    virtual bool canHaveChildren() const { return false; }
     virtual void updateFromElement();
 
     void animationTimerFired(Timer<RenderProgress>*);
index 744878a..aa936e7 100644 (file)
@@ -70,7 +70,6 @@ private:
     virtual bool isTextControl() const { return true; }
     virtual void computePreferredLogicalWidths();
     virtual void removeLeftoverAnonymousBlock(RenderBlock*) { }
-    virtual bool canHaveChildren() const { return false; }
     virtual bool avoidsFloats() const { return true; }
     
     virtual void addFocusRingRects(Vector<LayoutRect>&, const LayoutPoint&);
index cb7a1b2..701137f 100644 (file)
@@ -56,7 +56,6 @@ public:
 private:
     virtual RenderObjectChildList* virtualChildren() { return children(); }
     virtual const RenderObjectChildList* virtualChildren() const { return children(); }
-    virtual bool canHaveChildren() const { return true; }
 
     virtual bool isSVGRoot() const { return true; }
     virtual const char* renderName() const { return "RenderSVGRoot"; }
@@ -87,6 +86,7 @@ private:
 
     virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&, bool* wasFixed = 0) const;
     virtual bool canBeSelectionLeaf() const { return false; }
+    virtual bool canHaveChildren() const { return true; }
 
     void updateCachedBoundaries();
     void buildLocalToBorderBoxTransform();
index b3e0f85..7ec617a 100644 (file)
@@ -37,6 +37,7 @@
 #include "HTMLParserIdioms.h"
 #include "KeyboardEvent.h"
 #include "MouseEvent.h"
+#include "NodeRenderingContext.h"
 #include "PlatformMouseEvent.h"
 #include "RenderSVGInline.h"
 #include "RenderSVGTransformableContainer.h"
@@ -224,16 +225,16 @@ bool SVGAElement::isKeyboardFocusable(KeyboardEvent* event) const
     return document()->frame()->eventHandler()->tabsToLinks(event);
 }
 
-bool SVGAElement::childShouldCreateRenderer(Node* child) const
+bool SVGAElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
 {
     // http://www.w3.org/2003/01/REC-SVG11-20030114-errata#linking-text-environment
     // The 'a' element may contain any element that its parent may contain, except itself.
-    if (child->hasTagName(SVGNames::aTag))
+    if (childContext.node()->hasTagName(SVGNames::aTag))
         return false;
     if (parentNode() && parentNode()->isSVGElement())
-        return parentNode()->childShouldCreateRenderer(child);
+        return parentNode()->childShouldCreateRenderer(childContext);
 
-    return SVGElement::childShouldCreateRenderer(child);
+    return SVGElement::childShouldCreateRenderer(childContext);
 }
 
 } // namespace WebCore
index f2af9a8..e3b8f28 100644 (file)
@@ -61,7 +61,7 @@ private:
     virtual bool isKeyboardFocusable(KeyboardEvent*) const;
     virtual bool isFocusable() const;
 
-    virtual bool childShouldCreateRenderer(Node*) const;
+    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const;
 
     BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGAElement)
         // This declaration used to define a non-virtual "String& target() const" method, that clashes with "virtual String Element::target() const".
index 1baba84..f03d1ff 100644 (file)
@@ -26,6 +26,7 @@
 #include "SVGAltGlyphElement.h"
 
 #include "ExceptionCode.h"
+#include "NodeRenderingContext.h"
 #include "RenderInline.h"
 #include "RenderSVGTSpan.h"
 #include "SVGAltGlyphDefElement.h"
@@ -75,9 +76,9 @@ const AtomicString& SVGAltGlyphElement::format() const
     return fastGetAttribute(SVGNames::formatAttr);
 }
 
-bool SVGAltGlyphElement::childShouldCreateRenderer(Node* child) const
+bool SVGAltGlyphElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
 {
-    if (child->isTextNode())
+    if (childContext.node()->isTextNode())
         return true;
     return false;
 }
index 0ba229c..179ed77 100644 (file)
@@ -47,7 +47,7 @@ private:
     SVGAltGlyphElement(const QualifiedName&, Document*);
 
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
-    virtual bool childShouldCreateRenderer(Node*) const;
+    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const;
 
     BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGAltGlyphElement)
         DECLARE_ANIMATED_STRING(Href, href)
index f543948..c29ede3 100644 (file)
@@ -25,6 +25,7 @@
 #include "EventNames.h"
 #include "ExceptionCode.h"
 #include "FrameView.h"
+#include "NodeRenderingContext.h"
 #include "RenderView.h"
 #include "SVGElement.h"
 #include "SVGNames.h"
@@ -95,10 +96,10 @@ void SVGDocument::updatePan(const FloatPoint& pos) const
     }
 }
 
-bool SVGDocument::childShouldCreateRenderer(Node* node) const
+bool SVGDocument::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
 {
-    if (node->hasTagName(SVGNames::svgTag))
-        return static_cast<SVGSVGElement*>(node)->isValid();
+    if (childContext.node()->hasTagName(SVGNames::svgTag))
+        return static_cast<SVGSVGElement*>(childContext.node())->isValid();
     return true;
 }
 
index b934145..a637872 100644 (file)
@@ -53,7 +53,7 @@ private:
 
     virtual bool isSVGDocument() const { return true; }
 
-    virtual bool childShouldCreateRenderer(Node*) const;
+    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const;
 
     FloatPoint m_translate;
 };
index f3d5874..24adcf7 100644 (file)
@@ -36,6 +36,7 @@
 #include "EventNames.h"
 #include "FrameView.h"
 #include "HTMLNames.h"
+#include "NodeRenderingContext.h"
 #include "RegisteredEventListener.h"
 #include "RenderObject.h"
 #include "SVGCursorElement.h"
@@ -386,10 +387,10 @@ void SVGElement::finishParsingChildren()
     sendSVGLoadEventIfPossible();
 }
 
-bool SVGElement::childShouldCreateRenderer(Node* child) const
+bool SVGElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
 {
-    if (child->isSVGElement())
-        return static_cast<SVGElement*>(child)->isValid();
+    if (childContext.node()->isSVGElement())
+        return static_cast<SVGElement*>(childContext.node())->isValid();
     return false;
 }
 
index c5c5ac5..4735690 100644 (file)
@@ -114,7 +114,7 @@ protected:
 
     virtual void finishParsingChildren();
     virtual void attributeChanged(Attribute*) OVERRIDE;
-    virtual bool childShouldCreateRenderer(Node*) const;
+    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const;
     
     virtual void removedFromDocument();
 
index d792c47..1d74079 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "Attribute.h"
 #include "CSSPropertyNames.h"
+#include "NodeRenderingContext.h"
 #include "RenderSVGForeignObject.h"
 #include "RenderSVGResource.h"
 #include "SVGElementInstance.h"
@@ -137,14 +138,14 @@ RenderObject* SVGForeignObjectElement::createRenderer(RenderArena* arena, Render
     return new (arena) RenderSVGForeignObject(this);
 }
 
-bool SVGForeignObjectElement::childShouldCreateRenderer(Node* child) const
+bool SVGForeignObjectElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
 {
     // Disallow arbitary SVG content. Only allow proper <svg xmlns="svgNS"> subdocuments.
-    if (child->isSVGElement())
-        return child->hasTagName(SVGNames::svgTag);
+    if (childContext.node()->isSVGElement())
+        return childContext.node()->hasTagName(SVGNames::svgTag);
 
     // Skip over SVG rules which disallow non-SVG kids
-    return StyledElement::childShouldCreateRenderer(child);
+    return StyledElement::childShouldCreateRenderer(childContext);
 }
 
 bool SVGForeignObjectElement::selfHasRelativeLengths() const
index 67266d5..057ba05 100644 (file)
@@ -46,7 +46,7 @@ private:
     virtual void parseAttribute(Attribute*) OVERRIDE;
     virtual void svgAttributeChanged(const QualifiedName&);
 
-    virtual bool childShouldCreateRenderer(Node*) const;
+    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const;
     virtual RenderObject* createRenderer(RenderArena* arena, RenderStyle* style);
 
     virtual bool selfHasRelativeLengths() const;
index 79a00ac..7b976b2 100644 (file)
@@ -23,6 +23,7 @@
 #if ENABLE(SVG)
 #include "SVGSwitchElement.h"
 
+#include "NodeRenderingContext.h"
 #include "RenderSVGTransformableContainer.h"
 #include "SVGNames.h"
 
@@ -49,7 +50,7 @@ PassRefPtr<SVGSwitchElement> SVGSwitchElement::create(const QualifiedName& tagNa
     return adoptRef(new SVGSwitchElement(tagName, document));
 }
 
-bool SVGSwitchElement::childShouldCreateRenderer(Node* child) const
+bool SVGSwitchElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
 {
     // FIXME: This function does not do what the comment below implies it does.
     // It will create a renderer for any valid SVG element children, not just the first one.
@@ -61,7 +62,7 @@ bool SVGSwitchElement::childShouldCreateRenderer(Node* child) const
         if (!element || !element->isValid())
             continue;
 
-        return node == child; // Only allow this child if it's the first valid child
+        return node == childContext.node(); // Only allow this child if it's the first valid child
     }
 
     return false;
index 073a038..1bf7e6c 100644 (file)
@@ -43,7 +43,7 @@ private:
     virtual bool isValid() const { return SVGTests::isValid(); }
     virtual bool supportsFocus() const { return true; }
 
-    virtual bool childShouldCreateRenderer(Node*) const;
+    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const;
 
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
 
index 1570f4a..90b2d99 100644 (file)
@@ -27,6 +27,7 @@
 #include "EventListener.h"
 #include "EventNames.h"
 #include "MutationEvent.h"
+#include "NodeRenderingContext.h"
 #include "RenderSVGInline.h"
 #include "RenderSVGInlineText.h"
 #include "RenderSVGResource.h"
@@ -237,9 +238,9 @@ RenderObject* SVGTRefElement::createRenderer(RenderArena* arena, RenderStyle*)
     return new (arena) RenderSVGInline(this);
 }
 
-bool SVGTRefElement::childShouldCreateRenderer(Node* child) const
+bool SVGTRefElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
 {
-    return child->isInShadowTree();
+    return childContext.node()->isInShadowTree();
 }
 
 bool SVGTRefElement::rendererIsNeeded(const NodeRenderingContext& context)
index f36447d..18cbded 100644 (file)
@@ -47,7 +47,7 @@ private:
     virtual void svgAttributeChanged(const QualifiedName&);
 
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
-    virtual bool childShouldCreateRenderer(Node*) const;
+    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const;
     virtual bool rendererIsNeeded(const NodeRenderingContext&);
 
     virtual void insertedIntoDocument();
index 3219e65..d13120d 100644 (file)
@@ -23,6 +23,7 @@
 #if ENABLE(SVG)
 #include "SVGTSpanElement.h"
 
+#include "NodeRenderingContext.h"
 #include "RenderInline.h"
 #include "RenderSVGTSpan.h"
 #include "SVGNames.h"
@@ -45,15 +46,15 @@ RenderObject* SVGTSpanElement::createRenderer(RenderArena* arena, RenderStyle*)
     return new (arena) RenderSVGTSpan(this);
 }
 
-bool SVGTSpanElement::childShouldCreateRenderer(Node* child) const
+bool SVGTSpanElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
 {
-    if (child->isTextNode()
-        || child->hasTagName(SVGNames::aTag)
+    if (childContext.node()->isTextNode()
+        || childContext.node()->hasTagName(SVGNames::aTag)
 #if ENABLE(SVG_FONTS)
-        || child->hasTagName(SVGNames::altGlyphTag)
+        || childContext.node()->hasTagName(SVGNames::altGlyphTag)
 #endif
-        || child->hasTagName(SVGNames::trefTag)
-        || child->hasTagName(SVGNames::tspanTag))
+        || childContext.node()->hasTagName(SVGNames::trefTag)
+        || childContext.node()->hasTagName(SVGNames::tspanTag))
         return true;
 
     return false;
index 287cab4..5ebab44 100644 (file)
@@ -34,7 +34,7 @@ private:
     SVGTSpanElement(const QualifiedName&, Document*);
             
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
-    virtual bool childShouldCreateRenderer(Node*) const;
+    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const;
     virtual bool rendererIsNeeded(const NodeRenderingContext&);
 };
 
index 5d46d82..54a64a5 100644 (file)
@@ -26,6 +26,7 @@
 #include "AffineTransform.h"
 #include "Attribute.h"
 #include "FloatRect.h"
+#include "NodeRenderingContext.h"
 #include "RenderSVGResource.h"
 #include "RenderSVGText.h"
 #include "SVGElementInstance.h"
@@ -141,16 +142,16 @@ RenderObject* SVGTextElement::createRenderer(RenderArena* arena, RenderStyle*)
     return new (arena) RenderSVGText(this);
 }
 
-bool SVGTextElement::childShouldCreateRenderer(Node* child) const
+bool SVGTextElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
 {
-    if (child->isTextNode()
-        || child->hasTagName(SVGNames::aTag)
+    if (childContext.node()->isTextNode()
+        || childContext.node()->hasTagName(SVGNames::aTag)
 #if ENABLE(SVG_FONTS)
-        || child->hasTagName(SVGNames::altGlyphTag)
+        || childContext.node()->hasTagName(SVGNames::altGlyphTag)
 #endif
-        || child->hasTagName(SVGNames::textPathTag)
-        || child->hasTagName(SVGNames::trefTag)
-        || child->hasTagName(SVGNames::tspanTag))
+        || childContext.node()->hasTagName(SVGNames::textPathTag)
+        || childContext.node()->hasTagName(SVGNames::trefTag)
+        || childContext.node()->hasTagName(SVGNames::tspanTag))
         return true;
 
     return false;
index e8a4193..32118f5 100644 (file)
@@ -53,7 +53,7 @@ private:
     virtual AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope mode) const { return SVGTransformable::localCoordinateSpaceTransform(mode); }
 
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
-    virtual bool childShouldCreateRenderer(Node*) const;
+    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const;
             
     virtual void svgAttributeChanged(const QualifiedName&);
 
index 84c9a72..c8cfdd2 100644 (file)
@@ -24,6 +24,7 @@
 #include "SVGTextPathElement.h"
 
 #include "Attribute.h"
+#include "NodeRenderingContext.h"
 #include "RenderSVGResource.h"
 #include "RenderSVGTextPath.h"
 #include "SVGElementInstance.h"
@@ -117,12 +118,12 @@ RenderObject* SVGTextPathElement::createRenderer(RenderArena* arena, RenderStyle
     return new (arena) RenderSVGTextPath(this);
 }
 
-bool SVGTextPathElement::childShouldCreateRenderer(Node* child) const
+bool SVGTextPathElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
 {
-    if (child->isTextNode()
-        || child->hasTagName(SVGNames::aTag)
-        || child->hasTagName(SVGNames::trefTag)
-        || child->hasTagName(SVGNames::tspanTag))
+    if (childContext.node()->isTextNode()
+        || childContext.node()->hasTagName(SVGNames::aTag)
+        || childContext.node()->hasTagName(SVGNames::trefTag)
+        || childContext.node()->hasTagName(SVGNames::tspanTag))
         return true;
 
     return false;
index 499c80d..99bf622 100644 (file)
@@ -122,7 +122,7 @@ private:
     virtual void svgAttributeChanged(const QualifiedName&);
 
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
-    virtual bool childShouldCreateRenderer(Node*) const;
+    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const;
     virtual bool rendererIsNeeded(const NodeRenderingContext&);
 
     virtual bool selfHasRelativeLengths() const;