Switch to new PseudoElement based :before and :after
authordpranke@chromium.org <dpranke@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 11 Dec 2012 18:53:19 +0000 (18:53 +0000)
committerdpranke@chromium.org <dpranke@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 11 Dec 2012 18:53:19 +0000 (18:53 +0000)
https://bugs.webkit.org/show_bug.cgi?id=104462

Patch by Elliott Sprehn <esprehn@chromium.org> on 2012-12-11
Reviewed by Antti Koivisto.

Source/WebCore:

Switch to the new PseudoElement based generated content implementation
that moves :before and :after into the DOM. This also switches to using
the ComposedShadowTreeWalker for determining the siblings of PseudoElement's
making the new generated content implementation support adding :before
and :after into <input> elements.

Tests: fast/css-generated-content/block-inside-inline.html
       fast/css-generated-content/box-orient.html

* dom/ComposedShadowTreeWalker.cpp:
(WebCore::ComposedShadowTreeWalker::pseudoAwareNextSibling):
(WebCore):
(WebCore::ComposedShadowTreeWalker::pseudoAwarePreviousSibling):
(WebCore::ComposedShadowTreeWalker::traverseParent):
* dom/ComposedShadowTreeWalker.h:
(ComposedShadowTreeWalker):
* dom/Element.cpp:
(WebCore::Element::attach):
(WebCore::Element::recalcStyle):
* dom/Node.cpp:
* dom/Node.h:
(Node):
* dom/NodeRenderingContext.cpp:
(WebCore::NodeRenderingContext::nextRenderer):
(WebCore::NodeRenderingContext::previousRenderer):
(WebCore::NodeRenderingContext::createRendererForElementIfNeeded):
* dom/Position.cpp:
(WebCore::Position::Position):
(WebCore::Position::hasRenderedNonAnonymousDescendantsWithHeight):
* editing/visible_units.cpp:
(WebCore::logicallyPreviousBox):
(WebCore::logicallyNextBox):
(WebCore::startPositionForLine):
(WebCore::endPositionForLine):
* html/HTMLTextFormControlElement.cpp:
(WebCore::HTMLTextFormControlElement::childShouldCreateRenderer):
* page/DragController.cpp:
(WebCore::DragController::draggableNode):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::styleDidChange):
(WebCore::RenderBlock::splitBlocks):
(WebCore::RenderBlock::addChildIgnoringAnonymousColumnBlocks):
(WebCore::RenderBlock::createReplacementRunIn):
(WebCore::RenderBlock::isSelectionRoot):
* rendering/RenderBlock.h:
(RenderBlock):
* rendering/RenderButton.cpp:
* rendering/RenderButton.h:
(RenderButton):
* rendering/RenderInline.cpp:
(WebCore::RenderInline::styleDidChange):
(WebCore::RenderInline::addChildIgnoringContinuation):
(WebCore::RenderInline::splitInlines):
* rendering/RenderListItem.cpp:
(WebCore::RenderListItem::updateMarkerLocation):
* rendering/RenderObject.cpp:
(WebCore::RenderObject::createVisiblePosition):
* rendering/RenderObject.h:
(WebCore::RenderObject::nonPseudoNode):
(RenderObject):
(WebCore::RenderObject::clearNode):
(WebCore::RenderObject::generatingNode):
* rendering/RenderObjectChildList.cpp:
* rendering/RenderObjectChildList.h:
(RenderObjectChildList):
* rendering/RenderRubyText.cpp:
* rendering/RenderRubyText.h:
(RenderRubyText):
* rendering/RenderTableRow.cpp:
(WebCore::RenderTableRow::styleDidChange):
* rendering/RenderTableRow.h:
* rendering/RenderTableSection.cpp:
(WebCore::RenderTableSection::addChild):
* rendering/RenderWidget.cpp:
(WebCore::RenderWidget::destroy):

LayoutTests:

Add test for block generated content inside inlines which is now supported
properly, and also for using box-orient and reordering.

before-content-continuation.html's expectations change because we now
support block content properly.

I skipped fast/css-generated-content/table-row-group-to-inline.html
which needs a rebaseline after this this lands. Unfortunately the test
output is still wrong because we leave an anonymous RenderTable in the
tree, but that bug has always been there.

I also skipped fast/css/empty-generated-content.html which needs rebaselines
as we no longer create extra anonymous blocks, though the reason is not clear
to me.

* fast/css-generated-content/before-content-continuation-chain-expected.txt:
* fast/css-generated-content/block-inside-inline-expected.html: Added.
* fast/css-generated-content/block-inside-inline.html: Added.
* fast/css-generated-content/box-orient-expected.html: Added.
* fast/css-generated-content/box-orient.html: Added.
* platform/chromium/TestExpectations:
* platform/mac/TestExpectations:

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

35 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/css-generated-content/before-content-continuation-chain-expected.txt
LayoutTests/fast/css-generated-content/block-inside-inline-expected.html [new file with mode: 0644]
LayoutTests/fast/css-generated-content/block-inside-inline.html [new file with mode: 0644]
LayoutTests/fast/css-generated-content/box-orient-expected.html [new file with mode: 0644]
LayoutTests/fast/css-generated-content/box-orient.html [new file with mode: 0644]
LayoutTests/platform/chromium/TestExpectations
LayoutTests/platform/mac/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/dom/ComposedShadowTreeWalker.cpp
Source/WebCore/dom/ComposedShadowTreeWalker.h
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/Node.cpp
Source/WebCore/dom/Node.h
Source/WebCore/dom/NodeRenderingContext.cpp
Source/WebCore/dom/Position.cpp
Source/WebCore/editing/visible_units.cpp
Source/WebCore/html/HTMLTextFormControlElement.cpp
Source/WebCore/page/DragController.cpp
Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderBlock.h
Source/WebCore/rendering/RenderButton.cpp
Source/WebCore/rendering/RenderButton.h
Source/WebCore/rendering/RenderInline.cpp
Source/WebCore/rendering/RenderListItem.cpp
Source/WebCore/rendering/RenderObject.cpp
Source/WebCore/rendering/RenderObject.h
Source/WebCore/rendering/RenderObjectChildList.cpp
Source/WebCore/rendering/RenderObjectChildList.h
Source/WebCore/rendering/RenderRubyText.cpp
Source/WebCore/rendering/RenderRubyText.h
Source/WebCore/rendering/RenderTableRow.cpp
Source/WebCore/rendering/RenderTableRow.h
Source/WebCore/rendering/RenderTableSection.cpp
Source/WebCore/rendering/RenderWidget.cpp

index 70f084d..106b216 100644 (file)
@@ -1,3 +1,33 @@
+2012-12-11  Elliott Sprehn  <esprehn@chromium.org>
+
+        Switch to new PseudoElement based :before and :after
+        https://bugs.webkit.org/show_bug.cgi?id=104462
+
+        Reviewed by Antti Koivisto.
+
+        Add test for block generated content inside inlines which is now supported
+        properly, and also for using box-orient and reordering.
+
+        before-content-continuation.html's expectations change because we now
+        support block content properly.
+
+        I skipped fast/css-generated-content/table-row-group-to-inline.html
+        which needs a rebaseline after this this lands. Unfortunately the test
+        output is still wrong because we leave an anonymous RenderTable in the
+        tree, but that bug has always been there.
+
+        I also skipped fast/css/empty-generated-content.html which needs rebaselines
+        as we no longer create extra anonymous blocks, though the reason is not clear
+        to me.
+
+        * fast/css-generated-content/before-content-continuation-chain-expected.txt:
+        * fast/css-generated-content/block-inside-inline-expected.html: Added.
+        * fast/css-generated-content/block-inside-inline.html: Added.
+        * fast/css-generated-content/box-orient-expected.html: Added.
+        * fast/css-generated-content/box-orient.html: Added.
+        * platform/chromium/TestExpectations:
+        * platform/mac/TestExpectations:
+
 2012-12-11  Nate Chapin  <japhet@chromium.org>
 
         Route main resource loads through the memory cache.
index 0493aa1..baa8293 100644 (file)
@@ -3,13 +3,13 @@ layer at (0,0) size 800x600
 layer at (0,0) size 800x416
   RenderBlock {HTML} at (0,0) size 800x416
     RenderBody {BODY} at (8,8) size 784x400
+      RenderBlock (anonymous) at (0,0) size 784x0
+        RenderInline {SPAN} at (0,0) size 0x0 [color=#008000]
       RenderBlock (anonymous) at (0,0) size 784x200
-        RenderInline {SPAN} at (0,0) size 200x200 [color=#008000]
-          RenderInline (generated) at (0,0) size 200x200 [color=#0000FF]
-            RenderText at (0,0) size 200x200
-              text run at (0,0) width 200: "A"
-      RenderBlock (anonymous) at (0,200) size 784x0
-        RenderBlock {DIV} at (0,0) size 784x0 [color=#008000]
+        RenderBlock (generated) at (0,0) size 784x200 [color=#0000FF]
+          RenderText at (0,0) size 200x200
+            text run at (0,0) width 200: "A"
+        RenderBlock {DIV} at (0,200) size 784x0 [color=#008000]
       RenderBlock (anonymous) at (0,200) size 784x200
         RenderInline {SPAN} at (0,0) size 200x200 [color=#008000]
           RenderText {#text} at (0,0) size 200x200
diff --git a/LayoutTests/fast/css-generated-content/block-inside-inline-expected.html b/LayoutTests/fast/css-generated-content/block-inside-inline-expected.html
new file mode 100644 (file)
index 0000000..f5bbbd5
--- /dev/null
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+
+<span>
+    <div>Should be on it's own line, </div>
+    and this too.
+</span>
diff --git a/LayoutTests/fast/css-generated-content/block-inside-inline.html b/LayoutTests/fast/css-generated-content/block-inside-inline.html
new file mode 100644 (file)
index 0000000..540a16a
--- /dev/null
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+
+<style>
+span:before {
+  display: block;
+  content: "Should be on it's own line, ";
+}
+</style>
+
+<span>and this too.</span>
diff --git a/LayoutTests/fast/css-generated-content/box-orient-expected.html b/LayoutTests/fast/css-generated-content/box-orient-expected.html
new file mode 100644 (file)
index 0000000..0103cfc
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+
+<style>
+.before {
+  background:red;
+}
+</style>
+
+<h1>Normal</h1>
+<div>
+  <div class="before">Before content</div>
+  <div>1st in code - 1nd in order</div>
+  <div>2nd in code - 2nd in order</div>
+</div>
+
+<h1>Reordered</h1>
+<div>
+  <div class="before">Before content</div>
+  <div>2nd in code - 1st in order</div>
+  <div>1st in code - 2nd in order</div>
+</div>
diff --git a/LayoutTests/fast/css-generated-content/box-orient.html b/LayoutTests/fast/css-generated-content/box-orient.html
new file mode 100644 (file)
index 0000000..5755e0f
--- /dev/null
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+
+<style>
+.container {
+  display: box;
+  display: -moz-box;
+  display: -webkit-box;
+  box-orient: vertical;
+  -moz-box-orient: vertical;
+  -webkit-box-orient: vertical;
+}
+
+.container:before {
+  display: block;
+  content: "Before content";
+  background:red;
+}
+
+.c1o2 {
+    -moz-box-ordinal-group: 2;
+    -webkit-box-ordinal-group: 2; 
+    box-ordinal-group: 2;
+}
+
+.c2o1 {
+    -moz-box-ordinal-group: 1;
+    -webkit-box-ordinal-group: 1; 
+    box-ordinal-group: 1;
+}
+</style>
+
+<h1>Normal</h1>
+<div class="container">
+  <div>1st in code - 1nd in order</div>
+  <div>2nd in code - 2nd in order</div>
+</div>
+
+<h1>Reordered</h1>
+<div class="container">
+  <div class="c1o2">1st in code - 2nd in order</div>
+  <div class="c2o1">2nd in code - 1st in order</div>
+</div>
index 5b56221..0a9644b 100644 (file)
@@ -3901,6 +3901,10 @@ webkit.org/b/11645 [ Mac Android ] fast/table/025.html [ Failure ]
 webkit.org/b/101177 svg/dynamic-updates/SVGUseElement-dom-requiredFeatures.html [ ImageOnlyFailure Pass ]
 webkit.org/b/101177 svg/repaint/inner-svg-change-viewBox.svg [ ImageOnlyFailure Pass ]
 
+# Needs rebaseline after bug https://bugs.webkit.org/show_bug.cgi?id=104462
+webkit.org/b/98687 fast/css-generated-content/table-row-group-to-inline.html [ Failure ]
+webkit.org/b/104595 fast/css/empty-generated-content.html [ Failure ]
+
 # These are real failues due to 95121.
 # This is spilling caused by LANCZOS3 scaling algorithm that samples outside the source rect.
 webkit.org/b/95121 [ Win Mac Android ] fast/images/pixel-crack-image-background-webkit-transform-scale.html [ ImageOnlyFailure ]
index c322fc0..87b2944 100644 (file)
@@ -1153,6 +1153,10 @@ webkit.org/b/90951 fast/text/shaping
 webkit.org/b/101177 svg/dynamic-updates/SVGUseElement-dom-requiredFeatures.html [ ImageOnlyFailure Pass ]
 webkit.org/b/101177 svg/repaint/inner-svg-change-viewBox.svg [ ImageOnlyFailure Pass ]
 
+# Needs rebaseline after bug https://bugs.webkit.org/show_bug.cgi?id=104462
+webkit.org/b/98687 fast/css-generated-content/table-row-group-to-inline.html [ Failure ]
+webkit.org/b/104595 fast/css/empty-generated-content.html [ Failure ]
+
 webkit.org/b/93247 [ Debug ] fast/lists/list-marker-remove-crash.html [ Crash ]
 
 # (r124484) inspector/device-orientation-success.html failing on Mac ports
index 18ae33b..157864e 100644 (file)
@@ -1,3 +1,86 @@
+2012-12-11  Elliott Sprehn  <esprehn@chromium.org>
+
+        Switch to new PseudoElement based :before and :after
+        https://bugs.webkit.org/show_bug.cgi?id=104462
+
+        Reviewed by Antti Koivisto.
+
+        Switch to the new PseudoElement based generated content implementation
+        that moves :before and :after into the DOM. This also switches to using
+        the ComposedShadowTreeWalker for determining the siblings of PseudoElement's
+        making the new generated content implementation support adding :before
+        and :after into <input> elements.
+
+        Tests: fast/css-generated-content/block-inside-inline.html
+               fast/css-generated-content/box-orient.html
+
+        * dom/ComposedShadowTreeWalker.cpp:
+        (WebCore::ComposedShadowTreeWalker::pseudoAwareNextSibling):
+        (WebCore):
+        (WebCore::ComposedShadowTreeWalker::pseudoAwarePreviousSibling):
+        (WebCore::ComposedShadowTreeWalker::traverseParent):
+        * dom/ComposedShadowTreeWalker.h:
+        (ComposedShadowTreeWalker):
+        * dom/Element.cpp:
+        (WebCore::Element::attach):
+        (WebCore::Element::recalcStyle):
+        * dom/Node.cpp:
+        * dom/Node.h:
+        (Node):
+        * dom/NodeRenderingContext.cpp:
+        (WebCore::NodeRenderingContext::nextRenderer):
+        (WebCore::NodeRenderingContext::previousRenderer):
+        (WebCore::NodeRenderingContext::createRendererForElementIfNeeded):
+        * dom/Position.cpp:
+        (WebCore::Position::Position):
+        (WebCore::Position::hasRenderedNonAnonymousDescendantsWithHeight):
+        * editing/visible_units.cpp:
+        (WebCore::logicallyPreviousBox):
+        (WebCore::logicallyNextBox):
+        (WebCore::startPositionForLine):
+        (WebCore::endPositionForLine):
+        * html/HTMLTextFormControlElement.cpp:
+        (WebCore::HTMLTextFormControlElement::childShouldCreateRenderer):
+        * page/DragController.cpp:
+        (WebCore::DragController::draggableNode):
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::styleDidChange):
+        (WebCore::RenderBlock::splitBlocks):
+        (WebCore::RenderBlock::addChildIgnoringAnonymousColumnBlocks):
+        (WebCore::RenderBlock::createReplacementRunIn):
+        (WebCore::RenderBlock::isSelectionRoot):
+        * rendering/RenderBlock.h:
+        (RenderBlock):
+        * rendering/RenderButton.cpp:
+        * rendering/RenderButton.h:
+        (RenderButton):
+        * rendering/RenderInline.cpp:
+        (WebCore::RenderInline::styleDidChange):
+        (WebCore::RenderInline::addChildIgnoringContinuation):
+        (WebCore::RenderInline::splitInlines):
+        * rendering/RenderListItem.cpp:
+        (WebCore::RenderListItem::updateMarkerLocation):
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::createVisiblePosition):
+        * rendering/RenderObject.h:
+        (WebCore::RenderObject::nonPseudoNode):
+        (RenderObject):
+        (WebCore::RenderObject::clearNode):
+        (WebCore::RenderObject::generatingNode):
+        * rendering/RenderObjectChildList.cpp:
+        * rendering/RenderObjectChildList.h:
+        (RenderObjectChildList):
+        * rendering/RenderRubyText.cpp:
+        * rendering/RenderRubyText.h:
+        (RenderRubyText):
+        * rendering/RenderTableRow.cpp:
+        (WebCore::RenderTableRow::styleDidChange):
+        * rendering/RenderTableRow.h:
+        * rendering/RenderTableSection.cpp:
+        (WebCore::RenderTableSection::addChild):
+        * rendering/RenderWidget.cpp:
+        (WebCore::RenderWidget::destroy):
+
 2012-12-11  Jacky Jiang  <zhajiang@rim.com>
 
         [BlackBerry] Clean up unused defaultViewportArguments in RenderThemeBlackBerry.cpp
index a9be953..12486a9 100644 (file)
@@ -33,6 +33,7 @@
 #include "HTMLContentElement.h"
 #include "HTMLShadowElement.h"
 #include "InsertionPoint.h"
+#include "PseudoElement.h"
 
 namespace WebCore {
 
@@ -180,6 +181,46 @@ void ComposedShadowTreeWalker::previousSibling()
     assertPostcondition();
 }
 
+void ComposedShadowTreeWalker::pseudoAwareNextSibling()
+{
+    assertPrecondition();
+
+    const Node* node = m_node;
+
+    if (node->isBeforePseudoElement())
+        m_node = traverseFirstChild(traverseParent(node));
+    else
+        m_node = traverseSiblingOrBackToInsertionPoint(node, TraversalDirectionForward);
+
+    if (!m_node && !node->isAfterPseudoElement()) {
+        Node* parent = traverseParent(node);
+        if (parent && parent->isElementNode())
+            m_node = toElement(parent)->afterPseudoElement();
+    }
+
+    assertPostcondition();
+}
+
+void ComposedShadowTreeWalker::pseudoAwarePreviousSibling()
+{
+    assertPrecondition();
+
+    const Node* node = m_node;
+
+    if (node->isAfterPseudoElement())
+        m_node = traverseLastChild(traverseParent(node));
+    else
+        m_node = traverseSiblingOrBackToInsertionPoint(node, TraversalDirectionBackward);
+
+    if (!m_node && !node->isBeforePseudoElement()) {
+        Node* parent = traverseParent(node);
+        if (parent && parent->isElementNode())
+            m_node = toElement(parent)->beforePseudoElement();
+    }
+
+    assertPostcondition();
+}
+
 Node* ComposedShadowTreeWalker::traverseDistributedNodes(const Node* node, const InsertionPoint* insertionPoint, TraversalDirection direction)
 {
     for (const Node* next = node; next; next = (direction == TraversalDirectionForward ? insertionPoint->nextTo(next) : insertionPoint->previousTo(next))) {
@@ -258,6 +299,9 @@ void ComposedShadowTreeWalker::parent()
 // https://bugs.webkit.org/show_bug.cgi?id=90415
 Node* ComposedShadowTreeWalker::traverseParent(const Node* node, ParentTraversalDetails* details) const
 {
+    if (node->isPseudoElement())
+        return node->parentOrHostNode();
+
     if (!canCrossUpperBoundary() && node->isShadowRoot()) {
         ASSERT(toShadowRoot(node)->isYoungest());
         return 0;
index 89769b1..4b6ff95 100644 (file)
@@ -90,6 +90,9 @@ public:
     void nextSibling();
     void previousSibling();
 
+    void pseudoAwareNextSibling();
+    void pseudoAwarePreviousSibling();
+
     void parent();
 
     void next();
index 2dbc74e..a585fc6 100644 (file)
@@ -1168,6 +1168,8 @@ void Element::attach()
     if (parentElement() && parentElement()->isInCanvasSubtree())
         setIsInCanvasSubtree(true);
 
+    updatePseudoElement(BEFORE);
+
     // When a shadow root exists, it does the work of attaching the children.
     if (ElementShadow* shadow = this->shadow()) {
         parentPusher.push();
@@ -1177,6 +1179,8 @@ void Element::attach()
 
     ContainerNode::attach();
 
+    updatePseudoElement(AFTER);
+
     if (hasRareData()) {   
         ElementRareData* data = elementRareData();
         if (data->needsFocusAppearanceUpdateSoonAfterAttach()) {
@@ -1329,6 +1333,8 @@ void Element::recalcStyle(StyleChange change)
         }
     }
 
+    updatePseudoElement(BEFORE, change);
+
     // FIXME: This check is good enough for :hover + foo, but it is not good enough for :hover + foo + bar.
     // For now we will just worry about the common case, since it's a lot trickier to get the second case right
     // without doing way too much re-resolution.
@@ -1353,6 +1359,8 @@ void Element::recalcStyle(StyleChange change)
         forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
     }
 
+    updatePseudoElement(AFTER, change);
+
     clearNeedsStyleRecalc();
     clearChildNeedsStyleRecalc();
     
index 654c102..765302a 100644 (file)
@@ -40,6 +40,7 @@
 #include "CSSStyleSheet.h"
 #include "ChildNodeList.h"
 #include "ClassNodeList.h"
+#include "ComposedShadowTreeWalker.h"
 #include "ContainerNodeAlgorithms.h"
 #include "ContextMenuController.h"
 #include "DOMImplementation.h"
@@ -449,34 +450,6 @@ void Node::setTreeScope(TreeScope* scope)
     ensureRareData()->setTreeScope(scope);
 }
 
-Node* Node::pseudoAwarePreviousSibling() const
-{
-    if (isElementNode() && !previousSibling()) {
-        Element* parent = parentOrHostElement();
-        if (!parent)
-            return 0;
-        if (isAfterPseudoElement() && parent->lastChild())
-            return parent->lastChild();
-        if (!isBeforePseudoElement())
-            return parent->beforePseudoElement();
-    }
-    return previousSibling();
-}
-
-Node* Node::pseudoAwareNextSibling() const
-{
-    if (isElementNode() && !nextSibling()) {
-        Element* parent = parentOrHostElement();
-        if (!parent)
-            return 0;
-        if (isBeforePseudoElement() && parent->firstChild())
-            return parent->firstChild();
-        if (!isAfterPseudoElement())
-            return parent->afterPseudoElement();
-    }
-    return nextSibling();
-}
-
 NodeRareData* Node::rareData() const
 {
     ASSERT(hasRareData());
index b28dec1..50539bb 100644 (file)
@@ -190,9 +190,6 @@ public:
     bool hasAttributes() const;
     NamedNodeMap* attributes() const;
 
-    Node* pseudoAwarePreviousSibling() const;
-    Node* pseudoAwareNextSibling() const;
-
     virtual KURL baseURI() const;
     
     void getSubresourceURLs(ListHashSet<KURL>&) const;
index 4646cd8..2c89a88 100644 (file)
 #include "ElementShadow.h"
 #include "FlowThreadController.h"
 #include "HTMLContentElement.h"
+#include "HTMLInputElement.h"
 #include "HTMLNames.h"
 #include "HTMLShadowElement.h"
 #include "Node.h"
+#include "PseudoElement.h"
 #include "RenderFullScreen.h"
 #include "RenderNamedFlowThread.h"
 #include "RenderObject.h"
@@ -83,17 +85,8 @@ RenderObject* NodeRenderingContext::nextRenderer() const
     if (m_parentDetails.node() && !m_parentDetails.node()->attached())
         return 0;
 
-    // FIXME: This is wrong when the next sibling was actually moved around by shadow insertion points.
-    if (m_node->isPseudoElement()) {
-        for (Node* sibling = m_node->pseudoAwareNextSibling(); sibling; sibling = sibling->pseudoAwareNextSibling()) {
-            if (RenderObject* renderer = sibling->renderer())
-                return renderer;
-        }
-        return 0;
-    }
-
     ComposedShadowTreeWalker walker(m_node);
-    for (walker.nextSibling(); walker.get(); walker.nextSibling()) {
+    for (walker.pseudoAwareNextSibling(); walker.get(); walker.pseudoAwareNextSibling()) {
         if (RenderObject* renderer = walker.get()->renderer()) {
             // Renderers for elements attached to a flow thread should be skipped because they are parented differently.
             if (renderer->node()->isElementNode() && renderer->style() && !renderer->style()->flowThread().isEmpty())
@@ -110,10 +103,6 @@ RenderObject* NodeRenderingContext::previousRenderer() const
     if (RenderObject* renderer = m_node->renderer())
         return renderer->previousSibling();
 
-    // FIXME: This method doesn't support pseudo elements since nothing needs
-    // previousRenderer() support for them yet.
-    ASSERT(!m_node->isPseudoElement());
-
     if (m_parentFlowRenderer)
         return m_parentFlowRenderer->previousRendererForNode(m_node);
 
@@ -121,7 +110,7 @@ RenderObject* NodeRenderingContext::previousRenderer() const
     // however, when I tried adding it, several tests failed.
 
     ComposedShadowTreeWalker walker(m_node);
-    for (walker.previousSibling(); walker.get(); walker.previousSibling()) {
+    for (walker.pseudoAwarePreviousSibling(); walker.get(); walker.pseudoAwarePreviousSibling()) {
         if (RenderObject* renderer = walker.get()->renderer()) {
             // Renderers for elements attached to a flow thread should be skipped because they are parented differently.
             if (renderer->node()->isElementNode() && renderer->style() && !renderer->style()->flowThread().isEmpty())
@@ -235,7 +224,7 @@ void NodeRenderingContext::createRendererForElementIfNeeded()
 
     RenderObject* parentRenderer = this->parentRenderer();
     RenderObject* nextRenderer = this->nextRenderer();
-
+    
 #if ENABLE(DIALOG_ELEMENT)
     if (element->isInTopLayer())
         adjustInsertionPointForTopLayerElement(element, parentRenderer, nextRenderer);
index a1c0b01..0581a88 100644 (file)
@@ -87,6 +87,7 @@ Position::Position(PassRefPtr<Node> anchorNode, LegacyEditingOffset offset)
 #else
     ASSERT(!m_anchorNode || !m_anchorNode->isShadowRoot());
 #endif
+    ASSERT(!m_anchorNode || !m_anchorNode->isPseudoElement());
 }
 
 Position::Position(PassRefPtr<Node> anchorNode, AnchorType anchorType)
@@ -102,6 +103,8 @@ Position::Position(PassRefPtr<Node> anchorNode, AnchorType anchorType)
     ASSERT(!m_anchorNode || !m_anchorNode->isShadowRoot());
 #endif
 
+    ASSERT(!m_anchorNode || !m_anchorNode->isPseudoElement());
+
     ASSERT(anchorType != PositionIsOffsetInAnchor);
     ASSERT(!((anchorType == PositionIsBeforeChildren || anchorType == PositionIsAfterChildren)
         && (m_anchorNode->isTextNode() || editingIgnoresContent(m_anchorNode.get()))));
@@ -120,6 +123,8 @@ Position::Position(PassRefPtr<Node> anchorNode, int offset, AnchorType anchorTyp
     ASSERT(!m_anchorNode || !editingIgnoresContent(m_anchorNode.get()) || !m_anchorNode->isShadowRoot());
 #endif
 
+    ASSERT(!m_anchorNode || !m_anchorNode->isPseudoElement());
+
     ASSERT(anchorType == PositionIsOffsetInAnchor);
 }
 
@@ -840,7 +845,7 @@ bool Position::hasRenderedNonAnonymousDescendantsWithHeight(RenderObject* render
 {
     RenderObject* stop = renderer->nextInPreOrderAfterChildren();
     for (RenderObject *o = renderer->firstChild(); o && o != stop; o = o->nextInPreOrder())
-        if (o->node() && !o->node()->isPseudoElement()) {
+        if (o->nonPseudoNode()) {
             if ((o->isText() && toRenderText(o)->linesBoundingBox().height()) ||
                 (o->isBox() && toRenderBox(o)->borderBoundingBox().height()))
                 return true;
index b441acb..4553050 100644 (file)
@@ -215,8 +215,8 @@ static const InlineTextBox* logicallyPreviousBox(const VisiblePosition& visibleP
         return previousBox;
 
     while (1) {
-        Node* startNode = startBox->renderer() ? startBox->renderer()->node() : 0;
-        if (!startNode || startNode->isPseudoElement())
+        Node* startNode = startBox->renderer() ? startBox->renderer()->nonPseudoNode() : 0;
+        if (!startNode)
             break;
 
         Position position = previousRootInlineBoxCandidatePosition(startNode, visiblePosition, ContentIsEditable);
@@ -256,8 +256,8 @@ static const InlineTextBox* logicallyNextBox(const VisiblePosition& visiblePosit
         return nextBox;
 
     while (1) {
-        Node* startNode = startBox->renderer() ? startBox->renderer()->node() : 0;
-        if (!startNode || startNode->isPseudoElement())
+        Node* startNode = startBox->renderer() ? startBox->renderer()->nonPseudoNode() : 0;
+        if (!startNode)
             break;
 
         Position position = nextRootInlineBoxCandidatePosition(startNode, visiblePosition, ContentIsEditable);
@@ -744,8 +744,8 @@ static VisiblePosition startPositionForLine(const VisiblePosition& c, LineEndpoi
             if (!startRenderer)
                 return VisiblePosition();
 
-            startNode = startRenderer->node();
-            if (startNode && !startNode->isPseudoElement())
+            startNode = startRenderer->nonPseudoNode();
+            if (startNode)
                 break;
 
             startBox = startBox->nextLeafChild();
@@ -816,8 +816,8 @@ static VisiblePosition endPositionForLine(const VisiblePosition& c, LineEndpoint
             if (!endRenderer)
                 return VisiblePosition();
 
-            endNode = endRenderer->node();
-            if (endNode && !endNode->isPseudoElement())
+            endNode = endRenderer->nonPseudoNode();
+            if (endNode)
                 break;
             
             endBox = endBox->prevLeafChild();
index 80f1ee7..586c57b 100644 (file)
@@ -66,6 +66,10 @@ HTMLTextFormControlElement::~HTMLTextFormControlElement()
 
 bool HTMLTextFormControlElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
 {
+    // FIXME: We shouldn't force the pseudo elements down into the shadow, but
+    // this perserves the current behavior of WebKit.
+    if (childContext.node()->isPseudoElement())
+        return HTMLFormControlElementWithState::childShouldCreateRenderer(childContext);
     return childContext.isOnEncapsulationBoundary() && HTMLFormControlElementWithState::childShouldCreateRenderer(childContext);
 }
 
index 3a0dd16..6e13e4e 100644 (file)
@@ -625,7 +625,7 @@ Node* DragController::draggableNode(const Frame* src, Node* startNode, const Int
     state.m_dragType = (src->selection()->contains(dragOrigin)) ? DragSourceActionSelection : DragSourceActionNone;
 
     for (const RenderObject* renderer = startNode->renderer(); renderer; renderer = renderer->parent()) {
-        Node* node = renderer->node();
+        Node* node = renderer->nonPseudoNode();
         if (!node)
             // Anonymous render blocks don't correspond to actual DOM nodes, so we skip over them
             // for the purposes of finding a draggable node.
index 7a444f9..cd6d88f 100644 (file)
@@ -344,12 +344,6 @@ void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldSty
     propagateStyleToAnonymousChildren(true);    
     m_lineHeight = -1;
 
-    // Update pseudos for :before and :after now.
-    if (!isAnonymous() && document()->styleSheetCollection()->usesBeforeAfterRules() && canHaveGeneratedChildren()) {
-        updateBeforeAfterContent(BEFORE);
-        updateBeforeAfterContent(AFTER);
-    }
-
     // After our style changed, if we lose our ability to propagate floats into next sibling
     // blocks, then we need to find the top most parent containing that overhanging float and
     // then mark its descendants with floats for layout and clear all floats from its next
@@ -381,14 +375,6 @@ void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldSty
     }
 }
 
-void RenderBlock::updateBeforeAfterContent(PseudoId pseudoId)
-{
-    // If this is an anonymous wrapper, then the parent applies its own pseudo-element style to it.
-    if (parent() && parent()->createsAnonymousWrapper())
-        return;
-    children()->updateBeforeAfterContent(this, pseudoId);
-}
-
 RenderBlock* RenderBlock::continuationBefore(RenderObject* beforeChild)
 {
     if (beforeChild && beforeChild->parent() == this)
@@ -603,13 +589,7 @@ void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
     RenderBoxModelObject* curr = toRenderBoxModelObject(parent());
     RenderBoxModelObject* currChild = this;
     RenderObject* currChildNextSibling = currChild->nextSibling();
-    bool documentUsesBeforeAfterRules = document()->styleSheetCollection()->usesBeforeAfterRules();
 
-    // Note: |this| can be destroyed inside this loop if it is an empty anonymous
-    // block and we try to call updateBeforeAfterContent inside which removes the
-    // generated content and additionally cleans up |this| empty anonymous block.
-    // See RenderBlock::removeChild(). DO NOT reference any local variables to |this|
-    // after this point.
     while (curr && curr != fromBlock) {
         ASSERT(curr->isRenderBlock());
         
@@ -632,16 +612,6 @@ void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
             cloneBlock->setContinuation(oldCont);
         }
 
-        // Someone may have indirectly caused a <q> to split.  When this happens, the :after content
-        // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that the inline's :after
-        // content gets properly destroyed.
-        bool isLastChild = (currChildNextSibling == blockCurr->lastChild());
-        if (documentUsesBeforeAfterRules)
-            blockCurr->children()->updateBeforeAfterContent(blockCurr, AFTER);
-        if (isLastChild && currChildNextSibling != blockCurr->lastChild())
-            currChildNextSibling = 0; // We destroyed the last child, so now we need to update
-                                      // the value of currChildNextSibling.
-
         // Now we need to take all of the children starting from the first child
         // *after* currChild and append them all to the clone.
         blockCurr->moveChildrenTo(cloneBlock, currChildNextSibling, 0, true);
@@ -874,23 +844,6 @@ void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild,
             if (!isAnonymousBlock())
                 setContinuation(newBox);
 
-            // Someone may have put a <p> inside a <q>, causing a split.  When this happens, the :after content
-            // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that our :after
-            // content gets properly destroyed.
-            bool isFirstChild = (beforeChild == firstChild());
-            bool isLastChild = (beforeChild == lastChild());
-            if (document()->styleSheetCollection()->usesBeforeAfterRules())
-                children()->updateBeforeAfterContent(this, AFTER);
-            if (isLastChild && beforeChild != lastChild()) {
-                // We destroyed the last child, so now we need to update our insertion
-                // point to be 0. It's just a straight append now.
-                beforeChild = 0;
-            } else if (isFirstChild && beforeChild != firstChild()) {
-                // If beforeChild was the last anonymous block that collapsed,
-                // then we need to update its value.
-                beforeChild = firstChild();
-            }
-
             splitFlow(beforeChild, newBox, newChild, oldContinuation);
             return;
         }
@@ -1878,16 +1831,6 @@ RenderBoxModelObject* RenderBlock::createReplacementRunIn(RenderBoxModelObject*
 {
     ASSERT(runIn->isRunIn());
 
-    // First we destroy any :before/:after content. It will be regenerated by the new run-in.
-    // Exception is if the run-in itself is generated.
-    if (runIn->style()->styleType() != BEFORE && runIn->style()->styleType() != AFTER) {
-        RenderObject* generatedContent;
-        if (runIn->getCachedPseudoStyle(BEFORE) && (generatedContent = runIn->beforePseudoElementRenderer()))
-            generatedContent->destroy();
-        if (runIn->getCachedPseudoStyle(AFTER) && (generatedContent = runIn->afterPseudoElementRenderer()))
-            generatedContent->destroy();
-    }
-
     bool newRunInShouldBeBlock = !runIn->isRenderBlock();
     Node* runInNode = runIn->node();
     RenderBoxModelObject* newRunIn = 0;
@@ -3236,7 +3179,7 @@ bool RenderBlock::shouldPaintSelectionGaps() const
 
 bool RenderBlock::isSelectionRoot() const
 {
-    if (!node() || isPseudoElement())
+    if (!nonPseudoNode())
         return false;
         
     // FIXME: Eventually tables should have to learn how to fill gaps between cells, at least in simple non-spanning cases.
index ad14a01..3f6af1a 100644 (file)
@@ -572,8 +572,6 @@ private:
 
     virtual void borderFitAdjust(LayoutRect&) const; // Shrink the box in which the border paints if border-fit is set.
 
-    virtual void updateBeforeAfterContent(PseudoId);
-    
     virtual RootInlineBox* createRootInlineBox(); // Subclassed by SVG and Ruby.
 
     // Called to lay out the legend for a fieldset or the ruby text of a ruby run.
index 69cef29..257fe1f 100644 (file)
@@ -153,14 +153,6 @@ bool RenderButton::canHaveGeneratedChildren() const
     return !node()->hasTagName(inputTag);
 }
 
-void RenderButton::updateBeforeAfterContent(PseudoId type)
-{
-    if (m_inner)
-        m_inner->children()->updateBeforeAfterContent(m_inner, type, this);
-    else
-        children()->updateBeforeAfterContent(this, type);
-}
-
 LayoutRect RenderButton::controlClipRect(const LayoutPoint& additionalOffset) const
 {
     // Clip to the padding box to at least give content the extra padding space.
index 5be62b0..a7afb5d 100644 (file)
@@ -50,8 +50,6 @@ public:
     void setupInnerStyle(RenderStyle*);
     virtual void updateFromElement();
 
-    virtual void updateBeforeAfterContent(PseudoId);
-
     virtual bool canHaveGeneratedChildren() const OVERRIDE;
     virtual bool hasControlClip() const { return true; }
     virtual LayoutRect controlClipRect(const LayoutPoint&) const;
index 5a8fa27..a612ca5 100644 (file)
@@ -41,8 +41,6 @@
 #include "VisiblePosition.h"
 #include "WebCoreMemoryInstrumentation.h"
 
-#include <wtf/TemporaryChange.h>
-
 #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(DRAGGABLE_REGION)
 #include "Frame.h"
 #endif
@@ -170,18 +168,11 @@ void RenderInline::styleDidChange(StyleDifference diff, const RenderStyle* oldSt
     // need to pass its style on to anyone else.
     RenderStyle* newStyle = style();
     RenderInline* continuation = inlineElementContinuation();
-    {
-        TemporaryChange<bool> enableAfter(RenderObjectChildList::s_enableUpdateBeforeAfterContent, false);
-        RenderInline* nextInlineElementCont = 0;
-        for (RenderInline* currCont = continuation; currCont; currCont = nextInlineElementCont) {
-            nextInlineElementCont = currCont->inlineElementContinuation();
-            // We need to update :after content for the last continuation in the chain.
-            RenderObjectChildList::s_enableUpdateBeforeAfterContent = !nextInlineElementCont;
-            RenderBoxModelObject* nextCont = currCont->continuation();
-            currCont->setContinuation(0);
-            currCont->setStyle(newStyle);
-            currCont->setContinuation(nextCont);
-        }
+    for (RenderInline* currCont = continuation; currCont; currCont = currCont->inlineElementContinuation()) {
+        RenderBoxModelObject* nextCont = currCont->continuation();
+        currCont->setContinuation(0);
+        currCont->setStyle(newStyle);
+        currCont->setContinuation(nextCont);
     }
 
     // If an inline's in-flow positioning has changed then any descendant blocks will need to change their in-flow positioning accordingly.
@@ -202,12 +193,6 @@ void RenderInline::styleDidChange(StyleDifference diff, const RenderStyle* oldSt
         }
         m_alwaysCreateLineBoxes = alwaysCreateLineBoxes;
     }
-
-    // Update pseudos for :before and :after now.
-    if (!isAnonymous() && document()->styleSheetCollection()->usesBeforeAfterRules()) {
-        children()->updateBeforeAfterContent(this, BEFORE);
-        children()->updateBeforeAfterContent(this, AFTER);
-    }
 }
 
 void RenderInline::updateAlwaysCreateLineBoxes(bool fullLayout)
@@ -330,16 +315,6 @@ void RenderInline::addChildIgnoringContinuation(RenderObject* newChild, RenderOb
         RenderBoxModelObject* oldContinuation = continuation();
         setContinuation(newBox);
 
-        // Someone may have put a <p> inside a <q>, causing a split.  When this happens, the :after content
-        // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that our :after
-        // content gets properly destroyed.
-        bool isLastChild = (beforeChild == lastChild());
-        if (document()->styleSheetCollection()->usesBeforeAfterRules())
-            children()->updateBeforeAfterContent(this, AFTER);
-        if (isLastChild && beforeChild != lastChild())
-            beforeChild = 0; // We destroyed the last child, so now we need to update our insertion
-                             // point to be 0.  It's just a straight append now.
-
         splitFlow(beforeChild, newBox, newChild, oldContinuation);
         return;
     }
@@ -406,12 +381,6 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
             inlineCurr->setContinuation(cloneInline);
             cloneInline->setContinuation(oldCont);
 
-            // Someone may have indirectly caused a <q> to split.  When this happens, the :after content
-            // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that the inline's :after
-            // content gets properly destroyed.
-            if (document()->styleSheetCollection()->usesBeforeAfterRules())
-                inlineCurr->children()->updateBeforeAfterContent(inlineCurr, AFTER);
-
             // Now we need to take all of the children starting from the first child
             // *after* currChild and append them all to the clone.
             o = currChild->nextSibling();
index 84a5794..d0b3b95 100644 (file)
@@ -268,7 +268,6 @@ void RenderListItem::updateMarkerLocation()
             if (m_marker->preferredLogicalWidthsDirty())
                 m_marker->computePreferredLogicalWidths();
             // If markerPar is an anonymous block that has lost all its children, destroy it.
-            // Extraneous anonymous blocks can cause problems for RenderBlock::updateBeforeAfterContent.
             if (markerPar && markerPar->isAnonymousBlock() && !markerPar->firstChild() && !toRenderBlock(markerPar)->continuation())
                 markerPar->destroy();
         }
index 20a1916..9703b15 100644 (file)
@@ -2995,8 +2995,7 @@ RenderBoxModelObject* RenderObject::offsetParent() const
 VisiblePosition RenderObject::createVisiblePosition(int offset, EAffinity affinity)
 {
     // If this is a non-anonymous renderer in an editable area, then it's simple.
-    if (node() && !isPseudoElement()) {
-        Node* node = this->node();
+    if (Node* node = nonPseudoNode()) {
         if (!node->rendererIsEditable()) {
             // If it can be found, we prefer a visually equivalent position that is editable. 
             Position position = createLegacyEditingPosition(node, offset);
@@ -3022,8 +3021,8 @@ VisiblePosition RenderObject::createVisiblePosition(int offset, EAffinity affini
         // Find non-anonymous content after.
         RenderObject* renderer = child;
         while ((renderer = renderer->nextInPreOrder(parent))) {
-            if (renderer->node() && !renderer->isPseudoElement())
-                return VisiblePosition(firstPositionInOrBeforeNode(renderer->node()), DOWNSTREAM);
+            if (Node* node = renderer->nonPseudoNode())
+                return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
         }
 
         // Find non-anonymous content before.
@@ -3031,13 +3030,13 @@ VisiblePosition RenderObject::createVisiblePosition(int offset, EAffinity affini
         while ((renderer = renderer->previousInPreOrder())) {
             if (renderer == parent)
                 break;
-            if (renderer->node() && !renderer->isPseudoElement())
-                return VisiblePosition(lastPositionInOrAfterNode(renderer->node()), DOWNSTREAM);
+            if (Node* node = renderer->nonPseudoNode())
+                return VisiblePosition(lastPositionInOrAfterNode(node), DOWNSTREAM);
         }
 
         // Use the parent itself unless it too is anonymous.
-        if (parent->node() && !isPseudoElement())
-            return VisiblePosition(firstPositionInOrBeforeNode(parent->node()), DOWNSTREAM);
+        if (Node* node = parent->nonPseudoNode())
+            return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
 
         // Repeat at the next level up.
         child = parent;
index ce4122e..8a786f7 100644 (file)
@@ -623,17 +623,15 @@ public:
     bool isRooted(RenderView** = 0) const;
 
     Node* node() const { return isAnonymous() ? 0 : m_node; }
+    Node* nonPseudoNode() const { return isPseudoElement() ? 0 : node(); }
+
+    // FIXME: Why does RenderWidget need this?
+    void clearNode() { m_node = 0; }
 
     // Returns the styled node that caused the generation of this renderer.
     // This is the same as node() except for renderers of :before and :after
     // pseudo elements for which their parent node is returned.
-    Node* generatingNode() const
-    {
-        if (isPseudoElement())
-            return node()->parentOrHostNode();
-        return m_node == document() ? 0 : m_node;
-    }
-    void setNode(Node* node) { m_node = node; }
+    Node* generatingNode() const { return isPseudoElement() ? node()->parentOrHostNode() : node(); }
 
     Document* document() const { return m_node->document(); }
     Frame* frame() const { return document()->frame(); }
index 202cc36..e2724bf 100644 (file)
@@ -40,8 +40,6 @@
 
 namespace WebCore {
 
-bool RenderObjectChildList::s_enableUpdateBeforeAfterContent = true;
-
 void RenderObjectChildList::destroyLeftoverChildren()
 {
     while (firstChild()) {
@@ -187,23 +185,6 @@ void RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* c
         owner->document()->axObjectCache()->childrenChanged(owner);
 }
 
-static RenderObject* findBeforeAfterParent(RenderObject* object)
-{
-    // Only table parts and flex-boxes need to search for the :before or :after parent
-    // FIXME: We could likely get away without this check and always look for the right parent.
-    if (!(object->isTable() || object->isTableSection() || object->isTableRow() || object->isFlexibleBoxIncludingDeprecated()))
-        return object;
-
-    // If there is a :first-letter style applied on the :before or :after content,
-    // then we want the parent of the first-letter block
-    RenderObject* beforeAfterParent = object;
-    while (beforeAfterParent && !(beforeAfterParent->isText() || beforeAfterParent->isImage())
-        && (beforeAfterParent->style()->styleType() != FIRST_LETTER))
-        beforeAfterParent = beforeAfterParent->firstChild();
-
-    return beforeAfterParent ? beforeAfterParent->parent() : 0;
-}
-
 RenderObject* RenderObjectChildList::beforePseudoElementRenderer(const RenderObject* owner) const
 {
     // An anonymous (generated) inline run-in that has PseudoId BEFORE must come from a grandparent.
@@ -250,203 +231,4 @@ RenderObject* RenderObjectChildList::afterPseudoElementRenderer(const RenderObje
     return last;
 }
 
-void RenderObjectChildList::updateBeforeAfterStyle(RenderObject* child, PseudoId type, RenderStyle* pseudoElementStyle)
-{
-    if (!child || child->style()->styleType() != type)
-        return;
-
-    // We have generated content present still. We want to walk this content and update our
-    // style information with the new pseudo-element style.
-    child->setStyle(pseudoElementStyle);
-
-    RenderObject* beforeAfterParent = findBeforeAfterParent(child);
-    if (!beforeAfterParent)
-        return;
-
-    // When beforeAfterParent is not equal to child (e.g. in tables),
-    // we need to create new styles inheriting from pseudoElementStyle
-    // on all the intermediate parents (leaving their display same).
-    if (beforeAfterParent != child) {
-        RenderObject* curr = beforeAfterParent;
-        while (curr && curr != child) {
-            ASSERT(curr->isAnonymous());
-            RefPtr<RenderStyle> newStyle = RenderStyle::create();
-            newStyle->inheritFrom(pseudoElementStyle);
-            newStyle->setDisplay(curr->style()->display());
-            newStyle->setStyleType(curr->style()->styleType());
-            curr->setStyle(newStyle);
-            curr = curr->parent();
-        }
-    }
-
-    // Note that if we ever support additional types of generated content (which should be way off
-    // in the future), this code will need to be patched.
-    for (RenderObject* genChild = beforeAfterParent->firstChild(); genChild; genChild = genChild->nextSibling()) {
-        if (genChild->isText())
-            // Generated text content is a child whose style also needs to be set to the pseudo-element style.
-            genChild->setStyle(pseudoElementStyle);
-        else if (genChild->isImage()) {
-            // Images get an empty style that inherits from the pseudo.
-            RefPtr<RenderStyle> style = RenderStyle::create();
-            style->inheritFrom(pseudoElementStyle);
-            genChild->setStyle(style.release());
-        } else {
-            // RenderListItem may insert a list marker here. We do not need to care about this case.
-            // Otherwise, genChild must be a first-letter container. updateFirstLetter() will take care of it.
-            ASSERT(genChild->isListMarker() || genChild->style()->styleType() == FIRST_LETTER);
-        }
-    }
-}
-
-static RenderObject* ensureBeforeAfterContainer(RenderObject* owner, PseudoId type, RenderStyle* pseudoElementStyle, Node* generatingNode, RenderObject* insertBefore)
-{
-    // Make a generated box that might be any display type now that we are able to drill down into children
-    // to find the original content properly.
-    RenderObject* generatedContentContainer = RenderObject::createObject(owner->document(), pseudoElementStyle);
-    ASSERT(generatingNode); // The styled object cannot be anonymous or else it could not have ':before' or ':after' pseudo elements.
-    generatedContentContainer->setNode(generatingNode); // This allows access to the generatingNode.
-    generatedContentContainer->setStyle(pseudoElementStyle);
-    if (!owner->isChildAllowed(generatedContentContainer, pseudoElementStyle)) {
-        // The generated content container is not allowed here -> abort.
-        generatedContentContainer->destroy();
-        return 0;
-    }
-
-    // When we don't have a first child and are part of a continuation chain,
-    // insertBefore is incorrectly set to zero above, which causes the :before
-    // child to end up at the end of continuation chain.
-    // See https://bugs.webkit.org/show_bug.cgi?id=78380.
-    if (!insertBefore && type == BEFORE && owner->virtualContinuation())
-        owner->addChildIgnoringContinuation(generatedContentContainer, 0);
-    else
-        owner->addChild(generatedContentContainer, insertBefore);
-
-    return generatedContentContainer;
-}
-
-void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, PseudoId type, const RenderObject* styledObject)
-{
-    // Double check that the document did in fact use generated content rules.  Otherwise we should not have been called.
-    ASSERT(owner->document()->styleSheetCollection()->usesBeforeAfterRules());
-
-    // In CSS2, before/after pseudo-content cannot nest.  Check this first.
-    if (owner->style()->styleType() == BEFORE || owner->style()->styleType() == AFTER)
-        return;
-    if (!s_enableUpdateBeforeAfterContent)
-        return;
-    
-    if (!styledObject)
-        styledObject = owner;
-
-    RenderStyle* pseudoElementStyle = styledObject->getCachedPseudoStyle(type);
-    RenderObject* child;
-    switch (type) {
-    case BEFORE:
-        child = beforePseudoElementRenderer(owner);
-        break;
-    case AFTER:
-        child = afterPseudoElementRenderer(owner);
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-        return;
-    }
-
-    // Whether or not we currently have generated content attached.
-    bool oldContentPresent = child;
-
-    // Whether or not we now want generated content.
-    bool newContentWanted = pseudoElementStyle && pseudoElementStyle->display() != NONE;
-
-    // For <q><p/></q>, if this object is the inline continuation of the <q>, we only want to generate
-    // :after content and not :before content.
-    if (newContentWanted && type == BEFORE && owner->isElementContinuation())
-        newContentWanted = false;
-
-    // Similarly, if we're the beginning of a <q>, and there's an inline continuation for our object,
-    // then we don't generate the :after content.
-    if (newContentWanted && type == AFTER && owner->virtualContinuation())
-        newContentWanted = false;
-    
-    // If we don't want generated content any longer, or if we have generated content, but it's no longer
-    // identical to the new content data we want to build render objects for, then we nuke all
-    // of the old generated content.
-    if (oldContentPresent && (!newContentWanted || Node::diff(child->style(), pseudoElementStyle, owner->document()) == Node::Detach)) {
-        // Nuke the child. 
-        if (child->style()->styleType() == type) {
-            oldContentPresent = false;
-            child->destroy();
-            child = (type == BEFORE) ? owner->virtualChildren()->firstChild() : owner->virtualChildren()->lastChild();
-        }
-    }
-
-    // If we have no pseudo-element style or if the pseudo-element style's display type is NONE, then we
-    // have no generated content and can now return.
-    if (!newContentWanted)
-        return;
-
-    if (owner->isRenderInline() && !pseudoElementStyle->isDisplayInlineType() && !pseudoElementStyle->isFloating() &&
-        !pseudoElementStyle->hasOutOfFlowPosition())
-        // According to the CSS2 spec (the end of section 12.1), the only allowed
-        // display values for the pseudo style are NONE and INLINE for inline flows.
-        // FIXME: CSS2.1 lifted this restriction, but block display types will crash.
-        // For now we at least relax the restriction to allow all inline types like inline-block
-        // and inline-table.
-        pseudoElementStyle->setDisplay(INLINE);
-
-    if (oldContentPresent) {
-        updateBeforeAfterStyle(child, type, pseudoElementStyle);
-        return; // We've updated the generated content. That's all we needed to do.
-    }
-    
-    RenderObject* insertBefore = (type == BEFORE) ? owner->virtualChildren()->firstChild() : 0;
-    if (insertBefore && insertBefore->isAnonymousBlock() && insertBefore->childrenInline() && !insertBefore->isEmpty()) {
-        // We are going to add the "before" element. We have to check whether the "insertBefore" element
-        // is an anonymous block with inline children. If it is, then we should insert the "before" element
-        // before the first inline child of the anonymous block, otherwise we will end up with the "before"
-        // element in a different block. We do this only when the anonymous block has children, otherwise
-        // we end up with the before element in a wrong block.
-        insertBefore = insertBefore->firstChild();
-    }
-
-    // Nothing goes before the intruded run-in, not even generated content.
-    if (insertBefore && insertBefore->isRunIn() && owner->isRenderBlock()
-        && toRenderBlock(owner)->runInIsPlacedIntoSiblingBlock(insertBefore))
-        insertBefore = insertBefore->nextSibling();
-
-    // Generated content consists of a single container that houses multiple children (specified
-    // by the content property). This generated content container gets the pseudo-element style set on it.
-    // For pseudo-elements that are regions, the container is the RenderRegion.
-    RenderObject* generatedContentContainer = 0;
-
-    if (!pseudoElementStyle->regionThread().isEmpty())
-        generatedContentContainer = ensureBeforeAfterContainer(owner, type, pseudoElementStyle, styledObject->node(), insertBefore);
-    else {
-        // Walk our list of generated content and create render objects for each.
-        for (const ContentData* content = pseudoElementStyle->contentData(); content; content = content->next()) {
-            RenderObject* renderer = content->createRenderer(owner->document(), pseudoElementStyle);
-
-            if (!generatedContentContainer) {
-                generatedContentContainer = ensureBeforeAfterContainer(owner, type, pseudoElementStyle, styledObject->node(), insertBefore);
-                if (!generatedContentContainer) {
-                    renderer->destroy();
-                    return;
-                }
-            }
-            if (generatedContentContainer->isChildAllowed(renderer, pseudoElementStyle))
-                generatedContentContainer->addChild(renderer);
-            else
-                renderer->destroy();
-        }
-    }
-
-    if (!generatedContentContainer)
-        return;
-
-    // Handle placement of run-ins. We do the run-in placement at the end since generatedContentContainer can get destroyed.
-    RenderObject* generatedContentContainerImmediateParent = generatedContentContainer->parent();
-    if (generatedContentContainerImmediateParent->isRenderBlock())
-        toRenderBlock(generatedContentContainerImmediateParent)->placeRunInIfNeeded(generatedContentContainer, PlaceGeneratedRunIn);
-}
-
 } // namespace WebCore
index 3f606db..b63f242 100644 (file)
@@ -26,7 +26,6 @@
 #ifndef RenderObjectChildList_h
 #define RenderObjectChildList_h
 
-#include "RenderStyleConstants.h"
 #include <wtf/Forward.h>
 
 namespace WebCore {
@@ -56,16 +55,10 @@ public:
     void appendChildNode(RenderObject* owner, RenderObject*, bool notifyRenderer = true);
     void insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* before, bool notifyRenderer = true);
 
-    void updateBeforeAfterContent(RenderObject* owner, PseudoId type, const RenderObject* styledObject = 0);
     RenderObject* beforePseudoElementRenderer(const RenderObject* owner) const;
     RenderObject* afterPseudoElementRenderer(const RenderObject* owner) const;
 
-public:
-    static bool s_enableUpdateBeforeAfterContent;
-
 private:
-    void updateBeforeAfterStyle(RenderObject* child, PseudoId type, RenderStyle* pseudoElementStyle);
-
     RenderObject* m_firstChild;
     RenderObject* m_lastChild;
 };
index e9765f2..be8313b 100644 (file)
@@ -88,15 +88,4 @@ bool RenderRubyText::avoidsFloats() const
     return true;
 }
 
-void RenderRubyText::updateBeforeAfterContent(PseudoId pseudoId)
-{
-    // RenderRubyText manages its own :before and :after content
-    // and is not handled by its anonymous wrappers RenderRubyRun
-    // and RenderRuby. This contrasts with other ruby children, which
-    // are enclosed in RenderRubyBase and hence they are able to
-    // update their :before, :after content (since RenderRubyBase
-    // is not a anonymous wrapper).
-    return children()->updateBeforeAfterContent(this, pseudoId);
-}
-
 } // namespace WebCore
index f47304c..3a67926 100644 (file)
@@ -46,8 +46,6 @@ public:
 
     virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
 
-    virtual void updateBeforeAfterContent(PseudoId);
-
 private:
     virtual bool avoidsFloats() const;
 
index 44360ff..0a5aa29 100644 (file)
@@ -54,14 +54,6 @@ void RenderTableRow::willBeRemovedFromTree()
     section()->setNeedsCellRecalc();
 }
 
-void RenderTableRow::updateBeforeAndAfterContent()
-{
-    if (!isAnonymous() && document()->styleSheetCollection()->usesBeforeAfterRules()) {
-        children()->updateBeforeAfterContent(this, BEFORE);
-        children()->updateBeforeAfterContent(this, AFTER);
-    }
-}
-
 void RenderTableRow::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
 {
     ASSERT(style()->display() == TABLE_ROW);
@@ -69,9 +61,6 @@ void RenderTableRow::styleDidChange(StyleDifference diff, const RenderStyle* old
     RenderBox::styleDidChange(diff, oldStyle);
     propagateStyleToAnonymousChildren();
 
-    if (parent())
-        updateBeforeAndAfterContent();
-
     if (section() && oldStyle && style()->logicalHeight() != oldStyle->logicalHeight())
         section()->rowLogicalHeightChanged(rowIndex());
 
index 11de4f1..4405aa1 100644 (file)
@@ -45,7 +45,6 @@ public:
     RenderTableSection* section() const { return toRenderTableSection(parent()); }
     RenderTable* table() const { return toRenderTable(parent()->parent()); }
 
-    void updateBeforeAndAfterContent();
     void paintOutlineForRowIfNeeded(PaintInfo&, const LayoutPoint&);
 
     static RenderTableRow* createAnonymousWithParentRenderer(const RenderObject*);
index dd6f42f..107aff1 100644 (file)
@@ -190,7 +190,6 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild
 
     ASSERT(!beforeChild || beforeChild->isTableRow());
     RenderBox::addChild(child, beforeChild);
-    toRenderTableRow(child)->updateBeforeAndAfterContent();
 }
 
 void RenderTableSection::ensureRows(unsigned numRows)
index 977751a..588e963 100644 (file)
@@ -119,7 +119,7 @@ void RenderWidget::destroy()
     // Grab the arena from node()->document()->renderArena() before clearing the node pointer.
     // Clear the node before deref-ing, as this may be deleted when deref is called.
     RenderArena* arena = renderArena();
-    setNode(0);
+    clearNode();
     deref(arena);
 }