Changeset 136744 in webkit


Ignore:
Timestamp:
Dec 5, 2012 1:00:54 PM (11 years ago)
Author:
commit-queue@webkit.org
Message:

Add infrastructure for :before and :after in DOM
https://bugs.webkit.org/show_bug.cgi?id=103705

Patch by Elliott Sprehn <esprehn@chromium.org> on 2012-12-05
Reviewed by Eric Seidel.

Add all infrastructure for reimplementing generated content :before and
:after as DOM Elements. Now ElementRareData has two pointers to PseudoElements
for the generated content and Node has methods for traversing the tree
including generated content.

This will allow the generated content to be treated as real nodes instead
of anonymous and take part in the usual recalcStyle and attach flow which
fixes many bugs and vastly simplifies the ifecycle of generated content.

Instead of attempting to land both the infrastructure and enable it at
the same time which has proven problematic due to how drastic this change
is, this patch contains only the support code so a much smaller future
patch can be used to switch it on.

No new behavior, this is just the infrastructure.

  • CMakeLists.txt:
  • GNUmakefile.list.am:
  • Target.pri:
  • WebCore.gypi:
  • WebCore.vcproj/WebCore.vcproj:
  • WebCore.xcodeproj/project.pbxproj:
  • dom/DOMAllInOne.cpp:
  • dom/Element.cpp:

(WebCore::Element::~Element):
(WebCore::Element::detach):
(WebCore::Element::updatePseudoElement):
(WebCore::Element::createPseudoElementIfNeeded):
(WebCore::Element::beforePseudoElement):
(WebCore::Element::afterPseudoElement):

  • dom/Element.h:

(Element):

  • dom/ElementRareData.h:

(ElementRareData):
(WebCore::ElementRareData::ElementRareData):
(WebCore::ElementRareData::~ElementRareData):
(WebCore::ElementRareData::setPseudoElement):
(WebCore::ElementRareData::pseudoElement):
(WebCore::ElementRareData::releasePseudoElement):

  • dom/Node.cpp:

(WebCore::Node::pseudoAwarePreviousSibling):
(WebCore::Node::pseudoAwareNextSibling):
(WebCore::Node::rendererIsEditable):
(WebCore::checkAcceptChild):

  • dom/Node.h:

(Node):
(WebCore::Node::isPseudoElement):
(WebCore::Node::isBeforePseudoElement):
(WebCore::Node::isAfterPseudoElement):
(WebCore::Node::pseudoId):
(WebCore::Node::customPseudoId):

  • dom/NodeRenderingContext.cpp:

(WebCore::NodeRenderingContext::nextRenderer):
(WebCore::NodeRenderingContext::previousRenderer):

  • dom/Position.cpp:

(WebCore::Position::hasRenderedNonAnonymousDescendantsWithHeight):

  • dom/PseudoElement.cpp: Added.

(WebCore::pseudoElementTagName):
(WebCore::PseudoElement::PseudoElement):
(WebCore::PseudoElement::customStyleForRenderer):
(WebCore::PseudoElement::attach):
(WebCore::PseudoElement::rendererIsNeeded):
(WebCore::PseudoElement::updateChildStyle):
(WebCore::PseudoElement::didRecalcStyle):

  • dom/PseudoElement.h: Added.

(PseudoElement):
(WebCore::PseudoElement::create):
(WebCore::pseudoElementIsNeeded):

  • editing/visible_units.cpp:

(WebCore::logicallyPreviousBox):
(WebCore::logicallyNextBox):
(WebCore::startPositionForLine):
(WebCore::endPositionForLine):

  • page/animation/AnimationController.cpp:

(WebCore::AnimationController::updateAnimations):

  • rendering/HitTestResult.cpp:

(WebCore::HitTestResult::setInnerNode):
(WebCore::HitTestResult::setInnerNonSharedNode):

  • rendering/RenderBlock.cpp:

(WebCore::RenderBlock::isSelectionRoot):
(WebCore::RenderBlock::renderName):

  • rendering/RenderCounter.cpp:

(WebCore::RenderCounter::originalText):

  • rendering/RenderDeprecatedFlexibleBox.cpp:

(WebCore::RenderDeprecatedFlexibleBox::renderName):

  • rendering/RenderInline.cpp:

(WebCore::RenderInline::renderName):

  • rendering/RenderMultiColumnBlock.cpp:

(WebCore::RenderMultiColumnBlock::renderName):

  • rendering/RenderObject.cpp:

(WebCore::RenderObject::createObject):
(WebCore::RenderObject::setPseudoStyle):
(WebCore::RenderObject::createVisiblePosition):

  • rendering/RenderObject.h:

(WebCore::RenderObject::isPseudoElement):
(RenderObject):
(WebCore::RenderObject::generatingNode):

  • rendering/RenderTableCell.h:

(WebCore::RenderTableCell::renderName):

  • rendering/RenderTableRow.h:

(WebCore::RenderTableRow::renderName):

  • rendering/RenderTableSection.h:

(WebCore::RenderTableSection::renderName):

  • rendering/RenderTreeAsText.cpp:

(WebCore::RenderTreeAsText::writeRenderObject):

  • rendering/style/ContentData.cpp:

(WebCore::ImageContentData::createRenderer):
(WebCore::TextContentData::createRenderer):
(WebCore::CounterContentData::createRenderer):
(WebCore::QuoteContentData::createRenderer):

Location:
trunk/Source/WebCore
Files:
2 added
31 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/CMakeLists.txt

    r136686 r136744  
    12061206    dom/ProgressEvent.cpp
    12071207    dom/PropertyNodeList.cpp
     1208    dom/PseudoElement.cpp
    12081209    dom/QualifiedName.cpp
    12091210    dom/Range.cpp
  • trunk/Source/WebCore/ChangeLog

    r136742 r136744  
     12012-12-05  Elliott Sprehn  <esprehn@chromium.org>
     2
     3        Add infrastructure for :before and :after in DOM
     4        https://bugs.webkit.org/show_bug.cgi?id=103705
     5
     6        Reviewed by Eric Seidel.
     7
     8        Add all infrastructure for reimplementing generated content :before and
     9        :after as DOM Elements. Now ElementRareData has two pointers to PseudoElements
     10        for the generated content and Node has methods for traversing the tree
     11        including generated content.
     12
     13        This will allow the generated content to be treated as real nodes instead
     14        of anonymous and take part in the usual recalcStyle and attach flow which
     15        fixes many bugs and vastly simplifies the ifecycle of generated content.
     16
     17        Instead of attempting to land both the infrastructure and enable it at
     18        the same time which has proven problematic due to how drastic this change
     19        is, this patch contains only the support code so a much smaller future
     20        patch can be used to switch it on.
     21
     22        No new behavior, this is just the infrastructure.
     23
     24        * CMakeLists.txt:
     25        * GNUmakefile.list.am:
     26        * Target.pri:
     27        * WebCore.gypi:
     28        * WebCore.vcproj/WebCore.vcproj:
     29        * WebCore.xcodeproj/project.pbxproj:
     30        * dom/DOMAllInOne.cpp:
     31        * dom/Element.cpp:
     32        (WebCore::Element::~Element):
     33        (WebCore::Element::detach):
     34        (WebCore::Element::updatePseudoElement):
     35        (WebCore::Element::createPseudoElementIfNeeded):
     36        (WebCore::Element::beforePseudoElement):
     37        (WebCore::Element::afterPseudoElement):
     38        * dom/Element.h:
     39        (Element):
     40        * dom/ElementRareData.h:
     41        (ElementRareData):
     42        (WebCore::ElementRareData::ElementRareData):
     43        (WebCore::ElementRareData::~ElementRareData):
     44        (WebCore::ElementRareData::setPseudoElement):
     45        (WebCore::ElementRareData::pseudoElement):
     46        (WebCore::ElementRareData::releasePseudoElement):
     47        * dom/Node.cpp:
     48        (WebCore::Node::pseudoAwarePreviousSibling):
     49        (WebCore::Node::pseudoAwareNextSibling):
     50        (WebCore::Node::rendererIsEditable):
     51        (WebCore::checkAcceptChild):
     52        * dom/Node.h:
     53        (Node):
     54        (WebCore::Node::isPseudoElement):
     55        (WebCore::Node::isBeforePseudoElement):
     56        (WebCore::Node::isAfterPseudoElement):
     57        (WebCore::Node::pseudoId):
     58        (WebCore::Node::customPseudoId):
     59        * dom/NodeRenderingContext.cpp:
     60        (WebCore::NodeRenderingContext::nextRenderer):
     61        (WebCore::NodeRenderingContext::previousRenderer):
     62        * dom/Position.cpp:
     63        (WebCore::Position::hasRenderedNonAnonymousDescendantsWithHeight):
     64        * dom/PseudoElement.cpp: Added.
     65        (WebCore::pseudoElementTagName):
     66        (WebCore::PseudoElement::PseudoElement):
     67        (WebCore::PseudoElement::customStyleForRenderer):
     68        (WebCore::PseudoElement::attach):
     69        (WebCore::PseudoElement::rendererIsNeeded):
     70        (WebCore::PseudoElement::updateChildStyle):
     71        (WebCore::PseudoElement::didRecalcStyle):
     72        * dom/PseudoElement.h: Added.
     73        (PseudoElement):
     74        (WebCore::PseudoElement::create):
     75        (WebCore::pseudoElementIsNeeded):
     76        * editing/visible_units.cpp:
     77        (WebCore::logicallyPreviousBox):
     78        (WebCore::logicallyNextBox):
     79        (WebCore::startPositionForLine):
     80        (WebCore::endPositionForLine):
     81        * page/animation/AnimationController.cpp:
     82        (WebCore::AnimationController::updateAnimations):
     83        * rendering/HitTestResult.cpp:
     84        (WebCore::HitTestResult::setInnerNode):
     85        (WebCore::HitTestResult::setInnerNonSharedNode):
     86        * rendering/RenderBlock.cpp:
     87        (WebCore::RenderBlock::isSelectionRoot):
     88        (WebCore::RenderBlock::renderName):
     89        * rendering/RenderCounter.cpp:
     90        (WebCore::RenderCounter::originalText):
     91        * rendering/RenderDeprecatedFlexibleBox.cpp:
     92        (WebCore::RenderDeprecatedFlexibleBox::renderName):
     93        * rendering/RenderInline.cpp:
     94        (WebCore::RenderInline::renderName):
     95        * rendering/RenderMultiColumnBlock.cpp:
     96        (WebCore::RenderMultiColumnBlock::renderName):
     97        * rendering/RenderObject.cpp:
     98        (WebCore::RenderObject::createObject):
     99        (WebCore::RenderObject::setPseudoStyle):
     100        (WebCore::RenderObject::createVisiblePosition):
     101        * rendering/RenderObject.h:
     102        (WebCore::RenderObject::isPseudoElement):
     103        (RenderObject):
     104        (WebCore::RenderObject::generatingNode):
     105        * rendering/RenderTableCell.h:
     106        (WebCore::RenderTableCell::renderName):
     107        * rendering/RenderTableRow.h:
     108        (WebCore::RenderTableRow::renderName):
     109        * rendering/RenderTableSection.h:
     110        (WebCore::RenderTableSection::renderName):
     111        * rendering/RenderTreeAsText.cpp:
     112        (WebCore::RenderTreeAsText::writeRenderObject):
     113        * rendering/style/ContentData.cpp:
     114        (WebCore::ImageContentData::createRenderer):
     115        (WebCore::TextContentData::createRenderer):
     116        (WebCore::CounterContentData::createRenderer):
     117        (WebCore::QuoteContentData::createRenderer):
     118
    11192012-12-05  Justin Novosad  <junov@google.com>
    2120
  • trunk/Source/WebCore/GNUmakefile.list.am

    r136686 r136744  
    29082908        Source/WebCore/dom/PropertyNodeList.cpp \
    29092909        Source/WebCore/dom/PropertyNodeList.h \
     2910        Source/WebCore/dom/PseudoElement.cpp \
     2911        Source/WebCore/dom/PseudoElement.h \
    29102912        Source/WebCore/dom/QualifiedName.cpp \
    29112913        Source/WebCore/dom/QualifiedName.h \
  • trunk/Source/WebCore/Target.pri

    r136613 r136744  
    442442    dom/ProgressEvent.cpp \
    443443    dom/PropertyNodeList.cpp \
     444    dom/PseudoElement.cpp \
    444445    dom/QualifiedName.cpp \
    445446    dom/Range.cpp \
     
    16191620    dom/ProgressEvent.h \
    16201621    dom/PropertyNodeList.h \
     1622    dom/PseudoElement.h \
    16211623    dom/QualifiedName.h \
    16221624    dom/Range.h \
  • trunk/Source/WebCore/WebCore.gypi

    r136640 r136744  
    685685            'dom/PendingScript.h',
    686686            'dom/Position.h',
     687            'dom/PseudoElement.h',
    687688            'dom/QualifiedName.h',
    688689            'dom/Range.h',
     
    39153916            'dom/PropertyNodeList.cpp',
    39163917            'dom/PropertyNodeList.h',
     3918            'dom/PseudoElement.cpp',
    39173919            'dom/QualifiedName.cpp',
    39183920            'dom/Range.cpp',
  • trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj

    r136613 r136744  
    5396353963                        </File>
    5396453964                        <File
     53965                                RelativePath="..\dom\PseudoElement.h"
     53966                                >
     53967                        </File>
     53968                        <File
     53969                                RelativePath="..\dom\PseudoElement.cpp"
     53970                                >
     53971                                <FileConfiguration
     53972                                        Name="Debug|Win32"
     53973                                        ExcludedFromBuild="true"
     53974                                        >
     53975                                        <Tool
     53976                                                Name="VCCLCompilerTool"
     53977                                        />
     53978                                </FileConfiguration>
     53979                                <FileConfiguration
     53980                                        Name="Release|Win32"
     53981                                        ExcludedFromBuild="true"
     53982                                        >
     53983                                        <Tool
     53984                                                Name="VCCLCompilerTool"
     53985                                        />
     53986                                </FileConfiguration>
     53987                                <FileConfiguration
     53988                                        Name="Debug_Cairo_CFLite|Win32"
     53989                                        ExcludedFromBuild="true"
     53990                                        >
     53991                                        <Tool
     53992                                                Name="VCCLCompilerTool"
     53993                                        />
     53994                                </FileConfiguration>
     53995                                <FileConfiguration
     53996                                        Name="Release_Cairo_CFLite|Win32"
     53997                                        ExcludedFromBuild="true"
     53998                                        >
     53999                                        <Tool
     54000                                                Name="VCCLCompilerTool"
     54001                                        />
     54002                                </FileConfiguration>
     54003                                <FileConfiguration
     54004                                        Name="Debug_All|Win32"
     54005                                        ExcludedFromBuild="true"
     54006                                        >
     54007                                        <Tool
     54008                                                Name="VCCLCompilerTool"
     54009                                        />
     54010                                </FileConfiguration>
     54011                                <FileConfiguration
     54012                                        Name="Production|Win32"
     54013                                        ExcludedFromBuild="true"
     54014                                        >
     54015                                        <Tool
     54016                                                Name="VCCLCompilerTool"
     54017                                        />
     54018                                </FileConfiguration>
     54019                        </File>
     54020                        <File
    5396554021                                RelativePath="..\dom\PropertyNodeList.h"
    5396654022                                >
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r136686 r136744  
    66446644                FE80DA710E9C472F000D6F75 /* JSPositionError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE80DA6D0E9C472F000D6F75 /* JSPositionError.cpp */; };
    66456645                FE80DA720E9C472F000D6F75 /* JSPositionError.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80DA6E0E9C472F000D6F75 /* JSPositionError.h */; };
     6646                FF945ECB161F7F3600971BC8 /* PseudoElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FF945EC9161F7F3600971BC8 /* PseudoElement.cpp */; };
     6647                FF945ECC161F7F3600971BC8 /* PseudoElement.h in Headers */ = {isa = PBXBuildFile; fileRef = FF945ECA161F7F3600971BC8 /* PseudoElement.h */; };
    66466648                FFD5B97A135CC97800D5E92A /* PageVisibilityState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FFD5B977135CC97800D5E92A /* PageVisibilityState.cpp */; };
    66476649                FFD5B97B135CC97800D5E92A /* PageVisibilityState.h in Headers */ = {isa = PBXBuildFile; fileRef = FFD5B978135CC97800D5E92A /* PageVisibilityState.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    1419014192                FE80DA6D0E9C472F000D6F75 /* JSPositionError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPositionError.cpp; sourceTree = "<group>"; };
    1419114193                FE80DA6E0E9C472F000D6F75 /* JSPositionError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPositionError.h; sourceTree = "<group>"; };
     14194                FF945EC9161F7F3600971BC8 /* PseudoElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PseudoElement.cpp; sourceTree = "<group>"; };
     14195                FF945ECA161F7F3600971BC8 /* PseudoElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PseudoElement.h; sourceTree = "<group>"; };
    1419214196                FFD5B977135CC97800D5E92A /* PageVisibilityState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageVisibilityState.cpp; sourceTree = "<group>"; };
    1419314197                FFD5B978135CC97800D5E92A /* PageVisibilityState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageVisibilityState.h; sourceTree = "<group>"; };
     
    2212122125                                1059459815B42AA0004D37FD /* PropertyNodeList.h */,
    2212222126                                1059459A15B42AC0004D37FD /* PropertyNodeList.idl */,
     22127                                FF945EC9161F7F3600971BC8 /* PseudoElement.cpp */,
     22128                                FF945ECA161F7F3600971BC8 /* PseudoElement.h */,
    2212322129                                550A0BC7085F6039007353D6 /* QualifiedName.cpp */,
    2212422130                                550A0BC8085F6039007353D6 /* QualifiedName.h */,
     
    2492924935                                51A052561058874000CC9E95 /* ProtectionSpaceHash.h in Headers */,
    2493024936                                1AF8E11A1256592600230FF7 /* ProxyServer.h in Headers */,
     24937                                FF945ECC161F7F3600971BC8 /* PseudoElement.h in Headers */,
    2493124938                                10FB084B14E15C7E00A3DB98 /* PublicURLManager.h in Headers */,
    2493224939                                E4D687790ED7AE4F006EA978 /* PurgeableBuffer.h in Headers */,
     
    2820428211                                1AF8E13312565A4400230FF7 /* ProxyServer.cpp in Sources */,
    2820528212                                1AF8E1C3125673E000230FF7 /* ProxyServerCFNet.cpp in Sources */,
     28213                                FF945ECB161F7F3600971BC8 /* PseudoElement.cpp in Sources */,
    2820628214                                E4D687770ED7AE3D006EA978 /* PurgeableBufferMac.cpp in Sources */,
    2820728215                                550A0BC9085F6039007353D6 /* QualifiedName.cpp in Sources */,
  • trunk/Source/WebCore/dom/ContainerNode.cpp

    r136717 r136744  
    143143        return NOT_FOUND_ERR;
    144144
    145     // Goes common casae fast path if possible.
     145    // Use common case fast path if possible.
    146146    if ((newChild->isElementNode() || newChild->isTextNode()) && newParent->isElementNode()) {
    147147        ASSERT(!newParent->isReadOnlyNode());
     
    152152        return 0;
    153153    }
     154
     155    // This should never happen, but also protect release builds from tree corruption.
     156    ASSERT(!newChild->isPseudoElement());
     157    if (newChild->isPseudoElement())
     158        return HIERARCHY_REQUEST_ERR;
    154159
    155160    if (newParent->isReadOnlyNode())
  • trunk/Source/WebCore/dom/DOMAllInOne.cpp

    r136334 r136744  
    115115#include "ProcessingInstruction.cpp"
    116116#include "ProgressEvent.cpp"
     117#include "PseudoElement.cpp"
    117118#include "Range.cpp"
    118119#include "RangeException.cpp"
  • trunk/Source/WebCore/dom/Element.cpp

    r136738 r136744  
    6565#include "Page.h"
    6666#include "PointerLockController.h"
     67#include "PseudoElement.h"
    6768#include "RenderRegion.h"
    6869#include "RenderView.h"
     
    189190#endif
    190191
     192    if (hasRareData()) {
     193        ElementRareData* data = elementRareData();
     194        data->setPseudoElement(BEFORE, 0);
     195        data->setPseudoElement(AFTER, 0);
     196    }
     197
    191198    if (ElementShadow* elementShadow = shadow()) {
    192199        elementShadow->removeAllShadowRoots();
     
    11851192    if (hasRareData()) {
    11861193        ElementRareData* data = elementRareData();
     1194        data->setPseudoElement(BEFORE, 0);
     1195        data->setPseudoElement(AFTER, 0);
    11871196        data->setIsInCanvasSubtree(false);
    11881197        data->resetComputedStyle();
     
    20582067}
    20592068
     2069void Element::updatePseudoElement(PseudoId pseudoId, StyleChange change)
     2070{
     2071    PseudoElement* existing = hasRareData() ? elementRareData()->pseudoElement(pseudoId) : 0;
     2072    if (existing) {
     2073        // PseudoElement styles hang off their parent element's style so if we needed
     2074        // a style recalc we should Force one on the pseudo.
     2075        existing->recalcStyle(needsStyleRecalc() ? Force : change);
     2076
     2077        // Wait until our parent is not displayed or pseudoElementRendererIsNeeded
     2078        // is false, otherwise we could continously create and destroy PseudoElements
     2079        // when RenderObject::isChildAllowed on our parent returns false for the
     2080        // PseudoElement's renderer for each style recalc.
     2081        if (!renderer() || !pseudoElementRendererIsNeeded(renderer()->getCachedPseudoStyle(pseudoId)))
     2082            elementRareData()->setPseudoElement(pseudoId, 0);
     2083    } else if (RefPtr<PseudoElement> element = createPseudoElementIfNeeded(pseudoId)) {
     2084        element->attach();
     2085        ensureElementRareData()->setPseudoElement(pseudoId, element.release());
     2086    }
     2087}
     2088
     2089PassRefPtr<PseudoElement> Element::createPseudoElementIfNeeded(PseudoId pseudoId)
     2090{
     2091    if (!document()->styleSheetCollection()->usesBeforeAfterRules())
     2092        return 0;
     2093
     2094    if (!renderer() || !renderer()->canHaveGeneratedChildren())
     2095        return 0;
     2096
     2097    if (isPseudoElement())
     2098        return 0;
     2099
     2100    if (!pseudoElementRendererIsNeeded(renderer()->getCachedPseudoStyle(pseudoId)))
     2101        return 0;
     2102
     2103    return PseudoElement::create(this, pseudoId);
     2104}
     2105
     2106PseudoElement* Element::beforePseudoElement() const
     2107{
     2108    return hasRareData() ? elementRareData()->pseudoElement(BEFORE) : 0;
     2109}
     2110
     2111PseudoElement* Element::afterPseudoElement() const
     2112{
     2113    return hasRareData() ? elementRareData()->pseudoElement(AFTER) : 0;
     2114}
     2115
    20602116// ElementTraversal API
    20612117Element* Element::firstElementChild() const
  • trunk/Source/WebCore/dom/Element.h

    r136575 r136744  
    4444class IntSize;
    4545class Locale;
     46class PseudoElement;
    4647class RenderRegion;
    4748class ShadowRoot;
     
    366367    virtual void beginParsingChildren();
    367368
     369    PseudoElement* beforePseudoElement() const;
     370    PseudoElement* afterPseudoElement() const;
     371
    368372    // ElementTraversal API
    369373    Element* firstElementChild() const;
     
    494498
    495499private:
     500    void updatePseudoElement(PseudoId, StyleChange = NoChange);
     501    PassRefPtr<PseudoElement> createPseudoElementIfNeeded(PseudoId);
     502
    496503    // FIXME: Remove the need for Attr to call willModifyAttribute/didModifyAttribute.
    497504    friend class Attr;
  • trunk/Source/WebCore/dom/ElementRareData.h

    r136738 r136744  
    2828#include "NamedNodeMap.h"
    2929#include "NodeRareData.h"
     30#include "PseudoElement.h"
    3031#include "StyleInheritedData.h"
    3132#include <wtf/OwnPtr.h>
     
    3738    ElementRareData(Document*);
    3839    virtual ~ElementRareData();
     40
     41    void setPseudoElement(PseudoId, PassRefPtr<PseudoElement>);
     42    PseudoElement* pseudoElement(PseudoId) const;
    3943
    4044    void resetComputedStyle();
     
    113117    OwnPtr<NamedNodeMap> m_attributeMap;
    114118
     119    RefPtr<PseudoElement> m_generatedBefore;
     120    RefPtr<PseudoElement> m_generatedAfter;
     121
    115122    IntSize m_savedLayerScrollOffset;
     123
     124private:
     125    void releasePseudoElement(PseudoElement*);
    116126};
    117127
     
    124134    : NodeRareData(document)
    125135    , m_minimumSizeForResizing(defaultMinimumSizeForResizing())
     136    , m_generatedBefore(0)
     137    , m_generatedAfter(0)
    126138{
    127139}
     
    130142{
    131143    ASSERT(!m_shadow);
     144    ASSERT(!m_generatedBefore);
     145    ASSERT(!m_generatedAfter);
     146}
     147
     148inline void ElementRareData::setPseudoElement(PseudoId pseudoId, PassRefPtr<PseudoElement> element)
     149{
     150    switch (pseudoId) {
     151    case BEFORE:
     152        releasePseudoElement(m_generatedBefore.get());
     153        m_generatedBefore = element;
     154        break;
     155    case AFTER:
     156        releasePseudoElement(m_generatedAfter.get());
     157        m_generatedAfter = element;
     158        break;
     159    default:
     160        ASSERT_NOT_REACHED();
     161    }
     162}
     163
     164inline PseudoElement* ElementRareData::pseudoElement(PseudoId pseudoId) const
     165{
     166    switch (pseudoId) {
     167    case BEFORE:
     168        return m_generatedBefore.get();
     169    case AFTER:
     170        return m_generatedAfter.get();
     171    default:
     172        ASSERT_NOT_REACHED();
     173        return 0;
     174    }
     175}
     176
     177inline void ElementRareData::releasePseudoElement(PseudoElement* element)
     178{
     179    if (!element)
     180        return;
     181
     182    if (element->attached())
     183        element->detach();
     184
     185    ASSERT(!element->nextSibling());
     186    ASSERT(!element->previousSibling());
     187
     188    element->setParentOrHostNode(0);
    132189}
    133190
  • trunk/Source/WebCore/dom/Node.cpp

    r136573 r136744  
    448448}
    449449
     450Node* Node::pseudoAwarePreviousSibling() const
     451{
     452    if (isElementNode() && !previousSibling()) {
     453        Element* parent = parentOrHostElement();
     454        if (!parent)
     455            return 0;
     456        if (isAfterPseudoElement() && parent->lastChild())
     457            return parent->lastChild();
     458        if (!isBeforePseudoElement())
     459            return parent->beforePseudoElement();
     460    }
     461    return previousSibling();
     462}
     463
     464Node* Node::pseudoAwareNextSibling() const
     465{
     466    if (isElementNode() && !nextSibling()) {
     467        Element* parent = parentOrHostElement();
     468        if (!parent)
     469            return 0;
     470        if (isBeforePseudoElement() && parent->firstChild())
     471            return parent->firstChild();
     472        if (!isAfterPseudoElement())
     473            return parent->afterPseudoElement();
     474    }
     475    return nextSibling();
     476}
     477
    450478NodeRareData* Node::rareData() const
    451479{
     
    705733    if (document()->frame() && document()->frame()->page() && document()->frame()->page()->isEditable() && !shadowRoot())
    706734        return true;
     735
     736    if (isPseudoElement())
     737        return false;
    707738
    708739    // Ideally we'd call ASSERT(!needsStyleRecalc()) here, but
  • trunk/Source/WebCore/dom/Node.h

    r136573 r136744  
    191191    NamedNodeMap* attributes() const;
    192192
     193    Node* pseudoAwarePreviousSibling() const;
     194    Node* pseudoAwareNextSibling() const;
     195
    193196    virtual KURL baseURI() const;
    194197   
     
    234237    bool isHTMLElement() const { return getFlag(IsHTMLFlag); }
    235238    bool isSVGElement() const { return getFlag(IsSVGFlag); }
     239
     240    bool isPseudoElement() const { return pseudoId() != NOPSEUDO; }
     241    bool isBeforePseudoElement() const { return pseudoId() == BEFORE; }
     242    bool isAfterPseudoElement() const { return pseudoId() == AFTER; }
     243    PseudoId pseudoId() const { return (isElementNode() && hasCustomCallbacks()) ? customPseudoId() : NOPSEUDO; }
    236244
    237245    virtual bool isMediaControlElement() const { return false; }
     
    743751        CreateContainer = DefaultNodeFlags | IsContainerFlag,
    744752        CreateElement = CreateContainer | IsElementFlag,
     753        CreatePseudoElement =  CreateElement | InDocumentFlag,
    745754        CreateShadowRoot = CreateContainer | IsDocumentFragmentFlag,
    746755        CreateDocumentFragment = CreateContainer | IsDocumentFragmentFlag,
     
    755764    Node(Document*, ConstructionType);
    756765
     766    virtual PseudoId customPseudoId() const
     767    {
     768        ASSERT(hasCustomCallbacks());
     769        return NOPSEUDO;
     770    }
     771
    757772    virtual void didMoveToNewDocument(Document* oldDocument);
    758773   
  • trunk/Source/WebCore/dom/NodeRenderingContext.cpp

    r136107 r136744  
    8484        return 0;
    8585
     86    // FIXME: This is wrong when the next sibling was actually moved around by shadow insertion points.
     87    if (m_node->isPseudoElement()) {
     88        for (Node* sibling = m_node->pseudoAwareNextSibling(); sibling; sibling = sibling->pseudoAwareNextSibling()) {
     89            if (RenderObject* renderer = sibling->renderer())
     90                return renderer;
     91        }
     92        return 0;
     93    }
     94
    8695    ComposedShadowTreeWalker walker(m_node);
    8796    for (walker.nextSibling(); walker.get(); walker.nextSibling()) {
     
    101110    if (RenderObject* renderer = m_node->renderer())
    102111        return renderer->previousSibling();
     112
     113    // FIXME: This method doesn't support pseudo elements since nothing needs
     114    // previousRenderer() support for them yet.
     115    ASSERT(!m_node->isPseudoElement());
    103116
    104117    if (m_parentFlowRenderer)
  • trunk/Source/WebCore/dom/Position.cpp

    r133904 r136744  
    841841    RenderObject* stop = renderer->nextInPreOrderAfterChildren();
    842842    for (RenderObject *o = renderer->firstChild(); o && o != stop; o = o->nextInPreOrder())
    843         if (o->node()) {
     843        if (o->node() && !o->node()->isPseudoElement()) {
    844844            if ((o->isText() && toRenderText(o)->linesBoundingBox().height()) ||
    845845                (o->isBox() && toRenderBox(o)->borderBoundingBox().height()))
  • trunk/Source/WebCore/editing/visible_units.cpp

    r135618 r136744  
    216216    while (1) {
    217217        Node* startNode = startBox->renderer() ? startBox->renderer()->node() : 0;
    218         if (!startNode)
     218        if (!startNode || startNode->isPseudoElement())
    219219            break;
    220220
     
    257257    while (1) {
    258258        Node* startNode = startBox->renderer() ? startBox->renderer()->node() : 0;
    259         if (!startNode)
     259        if (!startNode || startNode->isPseudoElement())
    260260            break;
    261261
     
    745745
    746746            startNode = startRenderer->node();
    747             if (startNode)
     747            if (startNode && !startNode->isPseudoElement())
    748748                break;
    749749
     
    817817
    818818            endNode = endRenderer->node();
    819             if (endNode)
     819            if (endNode && !endNode->isPseudoElement())
    820820                break;
    821821           
  • trunk/Source/WebCore/page/animation/AnimationController.cpp

    r136293 r136744  
    522522        return newStyle;
    523523
     524    // FIXME: We do not animate generated content yet.
     525    if (renderer->isPseudoElement())
     526        return newStyle;
     527
    524528    RenderStyle* oldStyle = renderer->style();
    525529
     
    535539    // have changed, we reset the animation.  We then do a blend to get new values and we return
    536540    // a new style.
    537     ASSERT(renderer->node()); // FIXME: We do not animate generated content yet.
     541    ASSERT(renderer->node() && !renderer->isPseudoElement()); // FIXME: We do not animate generated content yet.
    538542
    539543    RefPtr<CompositeAnimation> rendererAnimations = m_data->accessCompositeAnimation(renderer);
  • trunk/Source/WebCore/rendering/HitTestResult.cpp

    r135841 r136744  
    268268void HitTestResult::setInnerNode(Node* n)
    269269{
     270    if (n && n->isPseudoElement())
     271        n = n->parentOrHostNode();
    270272    m_innerNode = n;
    271273}
     
    273275void HitTestResult::setInnerNonSharedNode(Node* n)
    274276{
     277    if (n && n->isPseudoElement())
     278        n = n->parentOrHostNode();
    275279    m_innerNonSharedNode = n;
    276280}
  • trunk/Source/WebCore/rendering/RenderBlock.cpp

    r136729 r136744  
    32363236bool RenderBlock::isSelectionRoot() const
    32373237{
    3238     if (!node())
     3238    if (!node() || isPseudoElement())
    32393239        return false;
    32403240       
     
    74727472    if (isAnonymousBlock())
    74737473        return "RenderBlock (anonymous)";
    7474     else if (isAnonymous())
     7474    // FIXME: Temporary hack while the new generated content system is being implemented.
     7475    if (isPseudoElement())
     7476        return "RenderBlock (generated)";
     7477    if (isAnonymous())
    74757478        return "RenderBlock (generated)";
    74767479    if (isRelPositioned())
  • trunk/Source/WebCore/rendering/RenderCounter.cpp

    r131050 r136744  
    502502            if (!beforeAfterContainer)
    503503                return 0;
    504             if (!beforeAfterContainer->isAnonymous())
     504            if (!beforeAfterContainer->isAnonymous() && !beforeAfterContainer->isPseudoElement())
    505505                return 0; // RenderCounters are restricted to before and after pseudo elements
    506506            PseudoId containerStyle = beforeAfterContainer->style()->styleType();
  • trunk/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp

    r133779 r136744  
    10841084}
    10851085
    1086 const char *RenderDeprecatedFlexibleBox::renderName() const
     1086const char* RenderDeprecatedFlexibleBox::renderName() const
    10871087{
    10881088    if (isFloating())
     
    10901090    if (isOutOfFlowPositioned())
    10911091        return "RenderDeprecatedFlexibleBox (positioned)";
     1092    // FIXME: Temporary hack while the new generated content system is being implemented.
     1093    if (isPseudoElement())
     1094        return "RenderDeprecatedFlexibleBox (generated)";
    10921095    if (isAnonymous())
    10931096        return "RenderDeprecatedFlexibleBox (generated)";
  • trunk/Source/WebCore/rendering/RenderInline.cpp

    r136060 r136744  
    763763    if (isStickyPositioned())
    764764        return "RenderInline (sticky positioned)";
     765    // FIXME: Temporary hack while the new generated content system is being implemented.
     766    if (isPseudoElement())
     767        return "RenderInline (generated)";
    765768    if (isAnonymous())
    766769        return "RenderInline (generated)";
  • trunk/Source/WebCore/rendering/RenderMultiColumnBlock.cpp

    r133779 r136744  
    146146
    147147const char* RenderMultiColumnBlock::renderName() const
    148 {   
     148{
    149149    if (isFloating())
    150150        return "RenderMultiColumnBlock (floating)";
     
    153153    if (isAnonymousBlock())
    154154        return "RenderMultiColumnBlock (anonymous)";
     155    // FIXME: Temporary hack while the new generated content system is being implemented.
     156    if (isPseudoElement())
     157        return "RenderMultiColumnBlock (generated)";
    155158    if (isAnonymous())
    156159        return "RenderMultiColumnBlock (generated)";
  • trunk/Source/WebCore/rendering/RenderObject.cpp

    r136617 r136744  
    143143    // Otherwise acts as if we didn't support this feature.
    144144    const ContentData* contentData = style->contentData();
    145     if (contentData && !contentData->next() && contentData->isImage() && doc != node) {
     145    if (contentData && !contentData->next() && contentData->isImage() && doc != node && !node->isPseudoElement()) {
    146146        RenderImage* image = new (arena) RenderImage(node);
    147147        // RenderImageResourceStyleImage requires a style being present on the image but we don't want to
     
    17571757}
    17581758
     1759void RenderObject::setPseudoStyle(PassRefPtr<RenderStyle> pseudoStyle)
     1760{
     1761    ASSERT(pseudoStyle->styleType() == BEFORE || pseudoStyle->styleType() == AFTER);
     1762
     1763    // Images are special and must inherit the pseudoStyle so the width and height of
     1764    // the pseudo element doesn't change the size of the image. In all other cases we
     1765    // can just share the style.
     1766    if (isImage()) {
     1767        RefPtr<RenderStyle> style = RenderStyle::create();
     1768        style->inheritFrom(pseudoStyle.get());
     1769        setStyle(style.release());
     1770        return;
     1771    }
     1772
     1773    setStyle(pseudoStyle);
     1774}
     1775
    17591776void RenderObject::setStyle(PassRefPtr<RenderStyle> style)
    17601777{
     
    29732990{
    29742991    // If this is a non-anonymous renderer in an editable area, then it's simple.
    2975     if (Node* node = this->node()) {
     2992    if (node() && !isPseudoElement()) {
     2993        Node* node = this->node();
    29762994        if (!node->rendererIsEditable()) {
    29772995            // If it can be found, we prefer a visually equivalent position that is editable.
     
    29993017        RenderObject* renderer = child;
    30003018        while ((renderer = renderer->nextInPreOrder(parent))) {
    3001             if (Node* node = renderer->node())
    3002                 return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
     3019            if (renderer->node() && !renderer->isPseudoElement())
     3020                return VisiblePosition(firstPositionInOrBeforeNode(renderer->node()), DOWNSTREAM);
    30033021        }
    30043022
     
    30083026            if (renderer == parent)
    30093027                break;
    3010             if (Node* node = renderer->node())
    3011                 return VisiblePosition(lastPositionInOrAfterNode(node), DOWNSTREAM);
     3028            if (renderer->node() && !renderer->isPseudoElement())
     3029                return VisiblePosition(lastPositionInOrAfterNode(renderer->node()), DOWNSTREAM);
    30123030        }
    30133031
    30143032        // Use the parent itself unless it too is anonymous.
    3015         if (Node* node = parent->node())
    3016             return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
     3033        if (parent->node() && !isPseudoElement())
     3034            return VisiblePosition(firstPositionInOrBeforeNode(parent->node()), DOWNSTREAM);
    30173035
    30183036        // Repeat at the next level up.
  • trunk/Source/WebCore/rendering/RenderObject.h

    r136465 r136744  
    331331    RenderArena* renderArena() const { return document()->renderArena(); }
    332332
     333    bool isPseudoElement() const { return node() && node()->isPseudoElement(); }
     334
    333335    virtual bool isBR() const { return false; }
    334336    virtual bool isBlockFlow() const { return false; }
     
    624626    // This is the same as node() except for renderers of :before and :after
    625627    // pseudo elements for which their parent node is returned.
    626     Node* generatingNode() const { return m_node == document() ? 0 : m_node; }
     628    Node* generatingNode() const
     629    {
     630        if (isPseudoElement())
     631            return node()->parentOrHostNode();
     632        return m_node == document() ? 0 : m_node;
     633    }
    627634    void setNode(Node* node) { m_node = node; }
    628635
     
    713720    // Set the style of the object and update the state of the object accordingly.
    714721    virtual void setStyle(PassRefPtr<RenderStyle>);
     722
     723    // Set the style of the object if it's generated content.
     724    void setPseudoStyle(PassRefPtr<RenderStyle>);
    715725
    716726    // Updates only the local style ptr of the object.  Does not update the state of the object,
  • trunk/Source/WebCore/rendering/RenderTableCell.h

    r133845 r136744  
    210210
    211211private:
    212     virtual const char* renderName() const { return isAnonymous() ? "RenderTableCell (anonymous)" : "RenderTableCell"; }
     212    virtual const char* renderName() const { return (isAnonymous() || isPseudoElement()) ? "RenderTableCell (anonymous)" : "RenderTableCell"; }
    213213
    214214    virtual bool isTableCell() const { return true; }
  • trunk/Source/WebCore/rendering/RenderTableRow.h

    r133845 r136744  
    9393    virtual const RenderObjectChildList* virtualChildren() const { return children(); }
    9494
    95     virtual const char* renderName() const { return isAnonymous() ? "RenderTableRow (anonymous)" : "RenderTableRow"; }
     95    virtual const char* renderName() const { return (isAnonymous() || isPseudoElement()) ? "RenderTableRow (anonymous)" : "RenderTableRow"; }
    9696
    9797    virtual bool isTableRow() const { return true; }
  • trunk/Source/WebCore/rendering/RenderTableSection.h

    r132995 r136744  
    203203    virtual const RenderObjectChildList* virtualChildren() const { return children(); }
    204204
    205     virtual const char* renderName() const { return isAnonymous() ? "RenderTableSection (anonymous)" : "RenderTableSection"; }
     205    virtual const char* renderName() const { return (isAnonymous() || isPseudoElement()) ? "RenderTableSection (anonymous)" : "RenderTableSection"; }
    206206
    207207    virtual bool isTableSection() const { return true; }
  • trunk/Source/WebCore/rendering/RenderTreeAsText.cpp

    r135060 r136744  
    222222    if (o.node()) {
    223223        String tagName = getTagName(o.node());
     224        // FIXME: Temporary hack to make tests pass by simulating the old generated content output.
     225        if (o.isPseudoElement() || (o.parent() && o.parent()->isPseudoElement()))
     226            tagName = emptyAtom;
    224227        if (!tagName.isEmpty()) {
    225228            ts << " {" << tagName << "}";
  • trunk/Source/WebCore/rendering/style/ContentData.cpp

    r131666 r136744  
    7171{
    7272    RenderImage* image = new (doc->renderArena()) RenderImage(doc);
    73     // Images are special and must inherit the pseudoStyle so the width and height of
    74     // the pseudo element don't change the size of the image. In all other cases we
    75     // can just share the style.
    76     RefPtr<RenderStyle> style = RenderStyle::create();
    77     style->inheritFrom(pseudoStyle);
    78     image->setStyle(style.release());
     73    image->setPseudoStyle(pseudoStyle);
    7974    if (m_image)
    8075        image->setImageResource(RenderImageResourceStyleImage::create(m_image.get()));
     
    8782{
    8883    RenderObject* renderer = new (doc->renderArena()) RenderTextFragment(doc, m_text.impl());
    89     renderer->setStyle(pseudoStyle);
     84    renderer->setPseudoStyle(pseudoStyle);
    9085    return renderer;
    9186}
     
    9489{
    9590    RenderObject* renderer = new (doc->renderArena()) RenderCounter(doc, *m_counter);
    96     renderer->setStyle(pseudoStyle);
     91    renderer->setPseudoStyle(pseudoStyle);
    9792    return renderer;
    9893}
     
    10196{
    10297    RenderObject* renderer = new (doc->renderArena()) RenderQuote(doc, m_quote);
    103     renderer->setStyle(pseudoStyle);
     98    renderer->setPseudoStyle(pseudoStyle);
    10499    return renderer;
    105100}
Note: See TracChangeset for help on using the changeset viewer.