Changeset 131004 in webkit
- Timestamp:
- Oct 10, 2012 8:17:42 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 43 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r131000 r131004 1 2012-10-10 Elliott Sprehn <esprehn@chromium.org> 2 3 Move :before and :after into the DOM 4 https://bugs.webkit.org/show_bug.cgi?id=95117 5 6 Reviewed by Eric Seidel. 7 8 Regenerated some baselines for tests given the new generated content architecture and disabled 9 tests that are testing generated content on inputs which were wrong. 10 11 * fast/css-generated-content/before-content-continuation-chain-expected.txt: 12 * platform/chromium-mac/fast/css-generated-content/table-row-group-to-inline-expected.png: 13 * platform/chromium/TestExpectations: Disable the tests for generated content on inputs. A follow up CL with remove these tests. 14 * platform/mac/fast/css-generated-content/table-row-group-to-inline-expected.png: 15 * platform/mac/fast/css-generated-content/table-row-group-to-inline-expected.txt: 16 This test always produced wrong output because we leave an anonymous RenderTable in the tree, 17 and now that generated content is handled like DOM nodes this test renders differently since the 18 content ends up after the left over RenderTable. Both outputs are wrong until Bug 86261 is fixed. 19 1 20 2012-10-10 Levi Weintraub <leviw@chromium.org> 2 21 -
trunk/LayoutTests/fast/css-generated-content/before-content-continuation-chain-expected.txt
r108109 r131004 4 4 RenderBlock {HTML} at (0,0) size 800x416 5 5 RenderBody {BODY} at (8,8) size 784x400 6 RenderBlock (anonymous) at (0,0) size 784x0 7 RenderInline {SPAN} at (0,0) size 0x0 [color=#008000] 6 8 RenderBlock (anonymous) at (0,0) size 784x200 7 RenderInline {SPAN} at (0,0) size 200x200 [color=#008000] 8 RenderInline (generated) at (0,0) size 200x200 [color=#0000FF] 9 RenderText at (0,0) size 200x200 10 text run at (0,0) width 200: "A" 11 RenderBlock (anonymous) at (0,200) size 784x0 12 RenderBlock {DIV} at (0,0) size 784x0 [color=#008000] 9 RenderBlock (generated) at (0,0) size 784x200 [color=#0000FF] 10 RenderText at (0,0) size 200x200 11 text run at (0,0) width 200: "A" 12 RenderBlock {DIV} at (0,200) size 784x0 [color=#008000] 13 13 RenderBlock (anonymous) at (0,200) size 784x200 14 14 RenderInline {SPAN} at (0,0) size 200x200 [color=#008000] -
trunk/LayoutTests/platform/chromium/TestExpectations
r131000 r131004 3615 3615 webkit.org/b/97325 css3/masking/clip-path-circle-relative-overflow.html [ ImageOnlyFailure Pass ] 3616 3616 3617 # Needs rebaseline after bug 95117 is fixed 3618 webkit.org/b/98687 fast/css-generated-content/table-row-group-to-inline.html [ Failure Pass ] 3619 3620 # Should not be testing for generated content in inputs yet. 3621 webkit.org/b/98836 fast/forms/time-multiple-fields/time-multiple-fields-appearance-pseudo-elements.html [ Skip ] 3622 webkit.org/b/98836 fast/forms/month-multiple-fields/month-multiple-fields-appearance-pseudo-elements.html [ Skip ] 3623 webkit.org/b/98836 fast/forms/week-multiple-fields/week-multiple-fields-appearance-pseudo-elements.html [ Skip ] 3624 webkit.org/b/98836 fast/forms/date-multiple-fields/date-multiple-fields-appearance-pseudo-elements.html [ Skip ] 3625 3617 3626 webkit.org/b/91544 media/media-continues-playing-after-replace-source.html [ Pass Timeout ] 3618 3627 -
trunk/LayoutTests/platform/mac/fast/css-generated-content/table-row-group-to-inline-expected.txt
r35318 r131004 15 15 RenderBlock (anonymous) at (0,0) size 744x18 16 16 RenderListMarker at (-17,0) size 7x18: bullet 17 RenderTable at (0,18) size 0x0 18 RenderBlock (anonymous) at (0,18) size 744x18 17 19 RenderInline (generated) at (0,0) size 31x18 18 20 RenderText at (0,0) size 31x18 19 21 text run at (0,0) width 31: "hello" 20 RenderTable at (0,18) size 0x0 21 RenderBlock (anonymous) at (0,18) size 744x18 22 RenderText {#text} at (0,0) size 21x18 23 text run at (0,0) width 21: "test" 22 RenderText {#text} at (31,0) size 21x18 23 text run at (31,0) width 21: "test" -
trunk/Source/WebCore/CMakeLists.txt
r130962 r131004 1197 1197 dom/ProgressEvent.cpp 1198 1198 dom/PropertyNodeList.cpp 1199 dom/PseudoElement.cpp 1199 1200 dom/QualifiedName.cpp 1200 1201 dom/Range.cpp -
trunk/Source/WebCore/ChangeLog
r131003 r131004 1 2012-10-10 Elliott Sprehn <esprehn@chromium.org> 2 3 Move :before and :after into the DOM 4 https://bugs.webkit.org/show_bug.cgi?id=95117 5 6 Reviewed by Eric Seidel. 7 8 Reimplement generated content :before and :after as DOM Elements. Now ElementRareData has 9 two RefPtrs to PseudoElements for the generated content and Node has methods for traversing 10 the tree including generated content. 11 12 This allows the generated content to be treated as real nodes instead of anonymous and take 13 part in the usual recalcStyle and attach flow which fixes many bugs and vastly simplifies the 14 lifecycle of generated content. 15 16 No new tests needed for now. 17 18 * CMakeLists.txt: 19 * GNUmakefile.list.am: 20 * Target.pri: 21 * WebCore.gypi: 22 * WebCore.vcproj/WebCore.vcproj: 23 * WebCore.xcodeproj/project.pbxproj: 24 * dom/DOMAllInOne.cpp: 25 * dom/Element.cpp: 26 (WebCore::Element::attach): Add generated content if needed. 27 (WebCore::Element::detach): Remove all child generated content. 28 (WebCore::Element::recalcStyle): Add or remove generated content based on the new style. 29 (WebCore::Element::updatePseudoElement): Updates pseudo content based on a pseudoId. 30 (WebCore): 31 (WebCore::Element::createPseudoElementIfNeeded): 32 (WebCore::Element::beforePseudoElement): 33 (WebCore::Element::afterPseudoElement): 34 * dom/Element.h: 35 (WebCore): 36 (Element): 37 * dom/ElementRareData.h: 38 (ElementRareData): 39 (WebCore::ElementRareData::setPseudoElement): 40 (WebCore): 41 (WebCore::ElementRareData::pseudoElement): 42 * dom/Node.cpp: 43 (WebCore::Node::pseudoAwarePreviousSibling): 44 (WebCore): 45 (WebCore::Node::pseudoAwareNextSibling): 46 (WebCore::checkAcceptChild): Forbid moving PseudoElements for sanity. The code never does this. 47 * dom/Node.h: 48 (Node): 49 (WebCore::Node::isPseudoElement): 50 (WebCore::Node::pseudoId): Fast path that only calls virtualPseudoId if the node has custom callbacks so isPseudoElement is fast. 51 (WebCore::Node::virtualPseudoId): 52 (WebCore::Node::isBeforePseudoElement): 53 (WebCore::Node::isAfterPseudoElement): 54 * dom/NodeRenderingContext.cpp: 55 (WebCore::NodeRenderingContext::nextRenderer): Changed to find the next sibling of pseudos for insertion. 56 * dom/PseudoElement.cpp: Added. 57 (WebCore): 58 (WebCore::pseudoElementName): 59 (WebCore::PseudoElement::PseudoElement): 60 (WebCore::PseudoElement::pseudoRendererIsNeeded): 61 (WebCore::PseudoElement::customStyleForRenderer): 62 (WebCore::PseudoElement::attach): 63 (WebCore::PseudoElement::rendererIsNeeded): 64 (WebCore::PseudoElement::updateChildStyle): Propagates the style downward into the anonymous renderers for the content. 65 (WebCore::PseudoElement::didRecalcStyle): 66 (WebCore::PseudoElement::createRendererForContent): Refactored from RenderObjectChildList. 67 * dom/PseudoElement.h: Added. 68 (WebCore): 69 (PseudoElement): 70 (WebCore::PseudoElement::create): 71 (WebCore::toPseudoElement): 72 * rendering/HitTestResult.cpp: 73 (WebCore::HitTestResult::setInnerNode): Hit testing a PseudoElement should really hit the parent. 74 (WebCore::HitTestResult::setInnerNonSharedNode): Same as above. 75 * rendering/RenderBlock.cpp: 76 (WebCore::RenderBlock::styleDidChange): Remove old generated content code, same for below. 77 (WebCore::RenderBlock::splitBlocks): 78 (WebCore::RenderBlock::addChildIgnoringAnonymousColumnBlocks): 79 (WebCore::RenderBlock::createReplacementRunIn): 80 (WebCore::RenderBlock::renderName): 81 * rendering/RenderBlock.h: 82 (RenderBlock): 83 * rendering/RenderButton.cpp: 84 * rendering/RenderButton.h: 85 (RenderButton): 86 * rendering/RenderCounter.cpp: 87 (WebCore::RenderCounter::originalText): 88 * rendering/RenderDeprecatedFlexibleBox.cpp: 89 (WebCore::RenderDeprecatedFlexibleBox::renderName): 90 * rendering/RenderGrid.cpp: 91 (WebCore::RenderGrid::renderName): 92 * rendering/RenderInline.cpp: 93 (WebCore::RenderInline::styleDidChange): 94 (WebCore::RenderInline::addChildIgnoringContinuation): 95 (WebCore::RenderInline::splitInlines): 96 (WebCore::RenderInline::renderName): 97 * rendering/RenderListItem.cpp: 98 (WebCore::RenderListItem::updateMarkerLocation): 99 * rendering/RenderMultiColumnBlock.cpp: 100 (WebCore::RenderMultiColumnBlock::renderName): 101 * rendering/RenderObject.cpp: 102 (WebCore::RenderObject::createObject): 103 * rendering/RenderObject.h: 104 (WebCore::RenderObject::isPseudoElement): 105 (RenderObject): 106 (WebCore::RenderObject::generatingNode): 107 * rendering/RenderObjectChildList.cpp: 108 * rendering/RenderObjectChildList.h: 109 (RenderObjectChildList): 110 * rendering/RenderRubyText.cpp: 111 * rendering/RenderRubyText.h: 112 (RenderRubyText): 113 * rendering/RenderTableCell.h: 114 (WebCore::RenderTableCell::renderName): 115 * rendering/RenderTableRow.cpp: 116 (WebCore::RenderTableRow::styleDidChange): 117 * rendering/RenderTableRow.h: 118 (WebCore::RenderTableRow::renderName): 119 * rendering/RenderTableSection.cpp: 120 (WebCore::RenderTableSection::addChild): 121 * rendering/RenderTableSection.h: 122 (WebCore::RenderTableSection::renderName): 123 * rendering/RenderTreeAsText.cpp: 124 (WebCore::RenderTreeAsText::writeRenderObject): 125 1 126 2012-10-10 Sam Weinig <sam@webkit.org> 2 127 -
trunk/Source/WebCore/GNUmakefile.list.am
r130947 r131004 2891 2891 Source/WebCore/dom/PropertyNodeList.cpp \ 2892 2892 Source/WebCore/dom/PropertyNodeList.h \ 2893 Source/WebCore/dom/PseudoElement.cpp \ 2894 Source/WebCore/dom/PseudoElement.h \ 2893 2895 Source/WebCore/dom/QualifiedName.cpp \ 2894 2896 Source/WebCore/dom/QualifiedName.h \ -
trunk/Source/WebCore/Target.pri
r130947 r131004 439 439 dom/ProgressEvent.cpp \ 440 440 dom/PropertyNodeList.cpp \ 441 dom/PseudoElement.cpp \ 441 442 dom/QualifiedName.cpp \ 442 443 dom/Range.cpp \ … … 1599 1600 dom/ProgressEvent.h \ 1600 1601 dom/PropertyNodeList.h \ 1602 dom/PseudoElement.h \ 1601 1603 dom/QualifiedName.h \ 1602 1604 dom/Range.h \ -
trunk/Source/WebCore/WebCore.gypi
r130947 r131004 682 682 'dom/PendingScript.h', 683 683 'dom/Position.h', 684 'dom/PseudoElement.h', 684 685 'dom/QualifiedName.h', 685 686 'dom/Range.h', … … 3924 3925 'dom/PropertyNodeList.cpp', 3925 3926 'dom/PropertyNodeList.h', 3927 'dom/PseudoElement.cpp', 3926 3928 'dom/QualifiedName.cpp', 3927 3929 'dom/Range.cpp', -
trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj
r130962 r131004 53560 53560 </File> 53561 53561 <File 53562 RelativePath="..\dom\PseudoElement.h" 53563 > 53564 </File> 53565 <File 53566 RelativePath="..\dom\PseudoElement.cpp" 53567 > 53568 <FileConfiguration 53569 Name="Debug|Win32" 53570 ExcludedFromBuild="true" 53571 > 53572 <Tool 53573 Name="VCCLCompilerTool" 53574 /> 53575 </FileConfiguration> 53576 <FileConfiguration 53577 Name="Release|Win32" 53578 ExcludedFromBuild="true" 53579 > 53580 <Tool 53581 Name="VCCLCompilerTool" 53582 /> 53583 </FileConfiguration> 53584 <FileConfiguration 53585 Name="Debug_Cairo_CFLite|Win32" 53586 ExcludedFromBuild="true" 53587 > 53588 <Tool 53589 Name="VCCLCompilerTool" 53590 /> 53591 </FileConfiguration> 53592 <FileConfiguration 53593 Name="Release_Cairo_CFLite|Win32" 53594 ExcludedFromBuild="true" 53595 > 53596 <Tool 53597 Name="VCCLCompilerTool" 53598 /> 53599 </FileConfiguration> 53600 <FileConfiguration 53601 Name="Debug_All|Win32" 53602 ExcludedFromBuild="true" 53603 > 53604 <Tool 53605 Name="VCCLCompilerTool" 53606 /> 53607 </FileConfiguration> 53608 <FileConfiguration 53609 Name="Production|Win32" 53610 ExcludedFromBuild="true" 53611 > 53612 <Tool 53613 Name="VCCLCompilerTool" 53614 /> 53615 </FileConfiguration> 53616 </File> 53617 <File 53562 53618 RelativePath="..\dom\PropertyNodeList.h" 53563 53619 > -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r130962 r131004 6567 6567 FE80DA710E9C472F000D6F75 /* JSPositionError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE80DA6D0E9C472F000D6F75 /* JSPositionError.cpp */; }; 6568 6568 FE80DA720E9C472F000D6F75 /* JSPositionError.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80DA6E0E9C472F000D6F75 /* JSPositionError.h */; }; 6569 FF945ECB161F7F3600971BC8 /* PseudoElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FF945EC9161F7F3600971BC8 /* PseudoElement.cpp */; }; 6570 FF945ECC161F7F3600971BC8 /* PseudoElement.h in Headers */ = {isa = PBXBuildFile; fileRef = FF945ECA161F7F3600971BC8 /* PseudoElement.h */; }; 6569 6571 FFD5B97A135CC97800D5E92A /* PageVisibilityState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FFD5B977135CC97800D5E92A /* PageVisibilityState.cpp */; }; 6570 6572 FFD5B97B135CC97800D5E92A /* PageVisibilityState.h in Headers */ = {isa = PBXBuildFile; fileRef = FFD5B978135CC97800D5E92A /* PageVisibilityState.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 14019 14021 FE80DA6D0E9C472F000D6F75 /* JSPositionError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPositionError.cpp; sourceTree = "<group>"; }; 14020 14022 FE80DA6E0E9C472F000D6F75 /* JSPositionError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPositionError.h; sourceTree = "<group>"; }; 14023 FF945EC9161F7F3600971BC8 /* PseudoElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PseudoElement.cpp; sourceTree = "<group>"; }; 14024 FF945ECA161F7F3600971BC8 /* PseudoElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PseudoElement.h; sourceTree = "<group>"; }; 14021 14025 FFD5B977135CC97800D5E92A /* PageVisibilityState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageVisibilityState.cpp; sourceTree = "<group>"; }; 14022 14026 FFD5B978135CC97800D5E92A /* PageVisibilityState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageVisibilityState.h; sourceTree = "<group>"; }; … … 21853 21857 1059459815B42AA0004D37FD /* PropertyNodeList.h */, 21854 21858 1059459A15B42AC0004D37FD /* PropertyNodeList.idl */, 21859 FF945EC9161F7F3600971BC8 /* PseudoElement.cpp */, 21860 FF945ECA161F7F3600971BC8 /* PseudoElement.h */, 21855 21861 550A0BC7085F6039007353D6 /* QualifiedName.cpp */, 21856 21862 550A0BC8085F6039007353D6 /* QualifiedName.h */, … … 24646 24652 51A052561058874000CC9E95 /* ProtectionSpaceHash.h in Headers */, 24647 24653 1AF8E11A1256592600230FF7 /* ProxyServer.h in Headers */, 24654 FF945ECC161F7F3600971BC8 /* PseudoElement.h in Headers */, 24648 24655 10FB084B14E15C7E00A3DB98 /* PublicURLManager.h in Headers */, 24649 24656 E4D687790ED7AE4F006EA978 /* PurgeableBuffer.h in Headers */, … … 27912 27919 1AF8E13312565A4400230FF7 /* ProxyServer.cpp in Sources */, 27913 27920 1AF8E1C3125673E000230FF7 /* ProxyServerCFNet.cpp in Sources */, 27921 FF945ECB161F7F3600971BC8 /* PseudoElement.cpp in Sources */, 27914 27922 E4D687770ED7AE3D006EA978 /* PurgeableBufferMac.cpp in Sources */, 27915 27923 550A0BC9085F6039007353D6 /* QualifiedName.cpp in Sources */, -
trunk/Source/WebCore/dom/DOMAllInOne.cpp
r126627 r131004 115 115 #include "ProcessingInstruction.cpp" 116 116 #include "ProgressEvent.cpp" 117 #include "PseudoElement.cpp" 117 118 #include "Range.cpp" 118 119 #include "RangeException.cpp" -
trunk/Source/WebCore/dom/Element.cpp
r130354 r131004 62 62 #include "Page.h" 63 63 #include "PointerLockController.h" 64 #include "PseudoElement.h" 64 65 #include "RenderRegion.h" 65 66 #include "RenderView.h" … … 1017 1018 if (firstChild()) 1018 1019 parentPusher.push(); 1020 updatePseudoElement(BEFORE); 1019 1021 ContainerNode::attach(); 1022 updatePseudoElement(AFTER); 1020 1023 } 1021 1024 … … 1047 1050 if (hasRareData()) { 1048 1051 ElementRareData* data = elementRareData(); 1052 data->setPseudoElement(BEFORE, 0); 1053 data->setPseudoElement(AFTER, 0); 1049 1054 data->setIsInCanvasSubtree(false); 1050 1055 data->resetComputedStyle(); … … 1198 1203 } 1199 1204 1205 updatePseudoElement(BEFORE, change); 1206 1200 1207 // FIXME: This check is good enough for :hover + foo, but it is not good enough for :hover + foo + bar. 1201 1208 // For now we will just worry about the common case, since it's a lot trickier to get the second case right … … 1222 1229 } 1223 1230 1231 updatePseudoElement(AFTER, change); 1232 1224 1233 clearNeedsStyleRecalc(); 1225 1234 clearChildNeedsStyleRecalc(); … … 1804 1813 } 1805 1814 1815 void Element::updatePseudoElement(PseudoId pseudoId, StyleChange change) 1816 { 1817 PseudoElement* existing = hasRareData() ? elementRareData()->pseudoElement(pseudoId) : 0; 1818 if (existing) { 1819 // PseudoElement styles hang off the parent element's style so we need to manually tell 1820 // the pseudo element it's style has changed (or we could pass Force). 1821 existing->setNeedsStyleRecalc(); 1822 existing->recalcStyle(change); 1823 if (!existing->renderer()) 1824 elementRareData()->setPseudoElement(pseudoId, 0); 1825 } else if (RefPtr<PseudoElement> element = createPseudoElementIfNeeded(pseudoId)) { 1826 element->attach(); 1827 ensureElementRareData()->setPseudoElement(pseudoId, element); 1828 } 1829 } 1830 1831 PassRefPtr<PseudoElement> Element::createPseudoElementIfNeeded(PseudoId pseudoId) 1832 { 1833 if (!document()->styleSheetCollection()->usesBeforeAfterRules()) 1834 return 0; 1835 1836 if (isPseudoElement() || !renderer() || !renderer()->canHaveGeneratedChildren()) 1837 return 0; 1838 1839 RenderStyle* style = renderer()->getCachedPseudoStyle(pseudoId); 1840 if (!style || !PseudoElement::pseudoRendererIsNeeded(style)) 1841 return 0; 1842 1843 return PseudoElement::create(this, pseudoId); 1844 } 1845 1846 PseudoElement* Element::beforePseudoElement() const 1847 { 1848 return hasRareData() ? elementRareData()->pseudoElement(BEFORE) : 0; 1849 } 1850 1851 PseudoElement* Element::afterPseudoElement() const 1852 { 1853 return hasRareData() ? elementRareData()->pseudoElement(AFTER) : 0; 1854 } 1855 1806 1856 // ElementTraversal API 1807 1857 Element* Element::firstElementChild() const -
trunk/Source/WebCore/dom/Element.h
r129903 r131004 44 44 class IntSize; 45 45 class Localizer; 46 class PseudoElement; 46 47 class RenderRegion; 47 48 class ShadowRoot; … … 346 347 virtual void beginParsingChildren(); 347 348 349 PseudoElement* beforePseudoElement() const; 350 PseudoElement* afterPseudoElement() const; 351 348 352 // ElementTraversal API 349 353 Element* firstElementChild() const; … … 476 480 477 481 private: 482 void updatePseudoElement(PseudoId, StyleChange = NoChange); 483 PassRefPtr<PseudoElement> createPseudoElementIfNeeded(PseudoId); 484 478 485 void updateInvalidAttributes() const; 479 486 -
trunk/Source/WebCore/dom/ElementRareData.h
r130278 r131004 30 30 #include "NamedNodeMap.h" 31 31 #include "NodeRareData.h" 32 #include "PseudoElement.h" 32 33 #include "StyleInheritedData.h" 33 34 #include <wtf/OwnPtr.h> … … 41 42 ElementRareData(); 42 43 virtual ~ElementRareData(); 44 45 void setPseudoElement(PseudoId, PassRefPtr<PseudoElement>); 46 PseudoElement* pseudoElement(PseudoId) const; 43 47 44 48 void resetComputedStyle(); … … 120 124 OwnPtr<NamedNodeMap> m_attributeMap; 121 125 126 RefPtr<PseudoElement> m_generatedBefore; 127 RefPtr<PseudoElement> m_generatedAfter; 128 122 129 IntSize m_savedLayerScrollOffset; 123 130 }; … … 138 145 } 139 146 147 inline void ElementRareData::setPseudoElement(PseudoId pseudoId, PassRefPtr<PseudoElement> element) 148 { 149 switch (pseudoId) { 150 case BEFORE: 151 m_generatedBefore = element; 152 break; 153 case AFTER: 154 m_generatedAfter = element; 155 break; 156 default: 157 ASSERT_NOT_REACHED(); 158 } 159 } 160 161 inline PseudoElement* ElementRareData::pseudoElement(PseudoId pseudoId) const 162 { 163 switch (pseudoId) { 164 case BEFORE: 165 return m_generatedBefore.get(); 166 case AFTER: 167 return m_generatedAfter.get(); 168 default: 169 ASSERT_NOT_REACHED(); 170 return 0; 171 } 172 } 173 140 174 inline void ElementRareData::resetComputedStyle() 141 175 { -
trunk/Source/WebCore/dom/Node.cpp
r130824 r131004 467 467 } 468 468 469 Node* Node::pseudoAwarePreviousSibling() const 470 { 471 if (isElementNode() && !previousSibling()) { 472 Element* parent = parentOrHostElement(); 473 if (!parent) 474 return 0; 475 if (isAfterPseudoElement() && parent->lastChild()) 476 return parent->lastChild(); 477 if (!isBeforePseudoElement()) 478 return parent->beforePseudoElement(); 479 } 480 return previousSibling(); 481 } 482 483 Node* Node::pseudoAwareNextSibling() const 484 { 485 if (isElementNode() && !nextSibling()) { 486 Element* parent = parentOrHostElement(); 487 if (!parent) 488 return 0; 489 if (isBeforePseudoElement() && parent->firstChild()) 490 return parent->firstChild(); 491 if (!isAfterPseudoElement()) 492 return parent->afterPseudoElement(); 493 } 494 return nextSibling(); 495 } 496 469 497 NodeRareData* Node::rareData() const 470 498 { … … 1184 1212 return; 1185 1213 } 1186 1214 1215 // Assert because this should never happen, but also protect non-debug builds 1216 // from tree corruption. 1217 ASSERT(!newChild->isPseudoElement()); 1218 if (newChild->isPseudoElement()) { 1219 ec = HIERARCHY_REQUEST_ERR; 1220 return; 1221 } 1222 1187 1223 if (newParent->isReadOnlyNode()) { 1188 1224 ec = NO_MODIFICATION_ALLOWED_ERR; -
trunk/Source/WebCore/dom/Node.h
r130266 r131004 173 173 NamedNodeMap* attributes() const; 174 174 175 Node* pseudoAwarePreviousSibling() const; 176 Node* pseudoAwareNextSibling() const; 177 175 178 virtual KURL baseURI() const; 176 179 … … 217 220 bool isSVGElement() const { return getFlag(IsSVGFlag); } 218 221 222 bool isPseudoElement() const 223 { 224 return pseudoId() != NOPSEUDO; 225 } 226 227 PseudoId pseudoId() const 228 { 229 return (isElementNode() && hasCustomCallbacks()) ? virtualPseudoId() : NOPSEUDO; 230 } 231 232 virtual PseudoId virtualPseudoId() const { return NOPSEUDO; } 233 bool isBeforePseudoElement() const { return pseudoId() == BEFORE; } 234 bool isAfterPseudoElement() const { return pseudoId() == AFTER; } 219 235 virtual bool isMediaControlElement() const { return false; } 220 236 virtual bool isMediaControls() const { return false; } -
trunk/Source/WebCore/dom/NodeRenderingContext.cpp
r126359 r131004 36 36 #include "HTMLShadowElement.h" 37 37 #include "Node.h" 38 #include "PseudoElement.h" 38 39 #include "RenderFullScreen.h" 39 40 #include "RenderNamedFlowThread.h" … … 93 94 if (m_parentDetails.node() && !m_parentDetails.node()->attached()) 94 95 return 0; 96 97 // FIXME: This is wrong when the next sibling was actually moved around by shadow insertion points. 98 if (m_node->isPseudoElement()) { 99 Node* sibling = m_node->pseudoAwareNextSibling(); 100 while (sibling && !sibling->renderer()) 101 sibling = sibling->pseudoAwareNextSibling(); 102 return sibling ? sibling->renderer() : 0; 103 } 95 104 96 105 ComposedShadowTreeWalker walker(m_node); -
trunk/Source/WebCore/rendering/HitTestResult.cpp
r128677 r131004 262 262 void HitTestResult::setInnerNode(Node* n) 263 263 { 264 if (n && n->isPseudoElement()) 265 n = n->parentOrHostNode(); 264 266 m_innerNode = n; 265 267 } … … 267 269 void HitTestResult::setInnerNonSharedNode(Node* n) 268 270 { 271 if (n && n->isPseudoElement()) 272 n = n->parentOrHostNode(); 269 273 m_innerNonSharedNode = n; 270 274 } -
trunk/Source/WebCore/rendering/RenderBlock.cpp
r130824 r131004 347 347 m_lineHeight = -1; 348 348 349 // Update pseudos for :before and :after now.350 if (!isAnonymous() && document()->styleSheetCollection()->usesBeforeAfterRules() && canHaveGeneratedChildren()) {351 updateBeforeAfterContent(BEFORE);352 updateBeforeAfterContent(AFTER);353 }354 355 349 // After our style changed, if we lose our ability to propagate floats into next sibling 356 350 // blocks, then we need to find the top most parent containing that overhanging float and … … 382 376 parentBlock->markSiblingsWithFloatsForLayout(); 383 377 } 384 }385 386 void RenderBlock::updateBeforeAfterContent(PseudoId pseudoId)387 {388 // If this is an anonymous wrapper, then the parent applies its own pseudo-element style to it.389 if (parent() && parent()->createsAnonymousWrapper())390 return;391 children()->updateBeforeAfterContent(this, pseudoId);392 378 } 393 379 … … 603 589 RenderBoxModelObject* currChild = this; 604 590 RenderObject* currChildNextSibling = currChild->nextSibling(); 605 bool documentUsesBeforeAfterRules = document()->styleSheetCollection()->usesBeforeAfterRules(); 606 607 // Note: |this| can be destroyed inside this loop if it is an empty anonymous 608 // block and we try to call updateBeforeAfterContent inside which removes the 609 // generated content and additionally cleans up |this| empty anonymous block. 610 // See RenderBlock::removeChild(). DO NOT reference any local variables to |this| 611 // after this point. 591 612 592 while (curr && curr != fromBlock) { 613 593 ASSERT(curr->isRenderBlock()); … … 631 611 cloneBlock->setContinuation(oldCont); 632 612 } 633 634 // Someone may have indirectly caused a <q> to split. When this happens, the :after content635 // has to move into the inline continuation. Call updateBeforeAfterContent to ensure that the inline's :after636 // content gets properly destroyed.637 bool isLastChild = (currChildNextSibling == blockCurr->lastChild());638 if (documentUsesBeforeAfterRules)639 blockCurr->children()->updateBeforeAfterContent(blockCurr, AFTER);640 if (isLastChild && currChildNextSibling != blockCurr->lastChild())641 currChildNextSibling = 0; // We destroyed the last child, so now we need to update642 // the value of currChildNextSibling.643 613 644 614 // Now we need to take all of the children starting from the first child … … 872 842 if (!isAnonymousBlock()) 873 843 setContinuation(newBox); 874 875 // Someone may have put a <p> inside a <q>, causing a split. When this happens, the :after content876 // has to move into the inline continuation. Call updateBeforeAfterContent to ensure that our :after877 // content gets properly destroyed.878 bool isFirstChild = (beforeChild == firstChild());879 bool isLastChild = (beforeChild == lastChild());880 if (document()->styleSheetCollection()->usesBeforeAfterRules())881 children()->updateBeforeAfterContent(this, AFTER);882 if (isLastChild && beforeChild != lastChild()) {883 // We destroyed the last child, so now we need to update our insertion884 // point to be 0. It's just a straight append now.885 beforeChild = 0;886 } else if (isFirstChild && beforeChild != firstChild()) {887 // If beforeChild was the last anonymous block that collapsed,888 // then we need to update its value.889 beforeChild = firstChild();890 }891 844 892 845 splitFlow(beforeChild, newBox, newChild, oldContinuation); … … 1866 1819 ASSERT(runIn->isRunIn()); 1867 1820 1868 // First we destroy any :before/:after content. It will be regenerated by the new run-in.1869 // Exception is if the run-in itself is generated.1870 if (runIn->style()->styleType() != BEFORE && runIn->style()->styleType() != AFTER) {1871 RenderObject* generatedContent;1872 if (runIn->getCachedPseudoStyle(BEFORE) && (generatedContent = runIn->beforePseudoElementRenderer()))1873 generatedContent->destroy();1874 if (runIn->getCachedPseudoStyle(AFTER) && (generatedContent = runIn->afterPseudoElementRenderer()))1875 generatedContent->destroy();1876 }1877 1878 1821 bool newRunInShouldBeBlock = !runIn->isRenderBlock(); 1879 1822 Node* runInNode = runIn->node(); … … 7430 7373 if (isAnonymousBlock()) 7431 7374 return "RenderBlock (anonymous)"; 7432 else if (isAnonymous()) 7375 if (isAnonymous()) 7376 return "RenderBlock (generated)"; 7377 // FIXME: Temporary hack while the new generated content system is being implemented. 7378 if (isPseudoElement()) 7433 7379 return "RenderBlock (generated)"; 7434 7380 if (isRelPositioned()) -
trunk/Source/WebCore/rendering/RenderBlock.h
r130851 r131004 543 543 544 544 virtual void borderFitAdjust(LayoutRect&) const; // Shrink the box in which the border paints if border-fit is set. 545 546 virtual void updateBeforeAfterContent(PseudoId);547 545 548 546 virtual RootInlineBox* createRootInlineBox(); // Subclassed by SVG and Ruby. -
trunk/Source/WebCore/rendering/RenderButton.cpp
r129204 r131004 150 150 } 151 151 152 void RenderButton::updateBeforeAfterContent(PseudoId type)153 {154 if (m_inner)155 m_inner->children()->updateBeforeAfterContent(m_inner, type, this);156 else157 children()->updateBeforeAfterContent(this, type);158 }159 160 152 LayoutRect RenderButton::controlClipRect(const LayoutPoint& additionalOffset) const 161 153 { -
trunk/Source/WebCore/rendering/RenderButton.h
r129204 r131004 51 51 virtual void updateFromElement(); 52 52 53 virtual void updateBeforeAfterContent(PseudoId);54 55 53 virtual bool canHaveGeneratedChildren() const OVERRIDE; 56 54 virtual bool hasControlClip() const { return true; } -
trunk/Source/WebCore/rendering/RenderCounter.cpp
r130612 r131004 502 502 if (!beforeAfterContainer) 503 503 return 0; 504 if (!beforeAfterContainer->isAnonymous() )504 if (!beforeAfterContainer->isAnonymous() && !beforeAfterContainer->isPseudoElement()) 505 505 return 0; // RenderCounters are restricted to before and after pseudo elements 506 506 PseudoId containerStyle = beforeAfterContainer->style()->styleType(); -
trunk/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp
r130549 r131004 1086 1086 const char *RenderDeprecatedFlexibleBox::renderName() const 1087 1087 { 1088 // FIXME: Temporary hack while the new generated content system is being implemented. 1089 if (isPseudoElement()) 1090 return "RenderDeprecatedFlexibleBox (generated)"; 1091 1088 1092 if (isFloating()) 1089 1093 return "RenderDeprecatedFlexibleBox (floating)"; -
trunk/Source/WebCore/rendering/RenderGrid.cpp
r128786 r131004 204 204 const char* RenderGrid::renderName() const 205 205 { 206 // FIXME: Temporary hack while the new generated content system is being implemented. 207 if (isPseudoElement()) 208 return "RenderGrid (generated)"; 209 206 210 if (isFloating()) 207 211 return "RenderGrid (floating)"; -
trunk/Source/WebCore/rendering/RenderInline.cpp
r130829 r131004 41 41 #include "VisiblePosition.h" 42 42 43 #include <wtf/TemporaryChange.h>44 45 43 #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) 46 44 #include "Frame.h" … … 170 168 RenderStyle* newStyle = style(); 171 169 RenderInline* continuation = inlineElementContinuation(); 172 { 173 TemporaryChange<bool> enableAfter(RenderObjectChildList::s_enableUpdateBeforeAfterContent, false); 174 RenderInline* nextInlineElementCont = 0; 175 for (RenderInline* currCont = continuation; currCont; currCont = nextInlineElementCont) { 176 nextInlineElementCont = currCont->inlineElementContinuation(); 177 // We need to update :after content for the last continuation in the chain. 178 RenderObjectChildList::s_enableUpdateBeforeAfterContent = !nextInlineElementCont; 179 RenderBoxModelObject* nextCont = currCont->continuation(); 180 currCont->setContinuation(0); 181 currCont->setStyle(newStyle); 182 currCont->setContinuation(nextCont); 183 } 170 for (RenderInline* currCont = continuation; currCont; currCont = currCont->inlineElementContinuation()) { 171 RenderBoxModelObject* nextCont = currCont->continuation(); 172 currCont->setContinuation(0); 173 currCont->setStyle(newStyle); 174 currCont->setContinuation(nextCont); 184 175 } 185 176 … … 201 192 } 202 193 m_alwaysCreateLineBoxes = alwaysCreateLineBoxes; 203 }204 205 // Update pseudos for :before and :after now.206 if (!isAnonymous() && document()->styleSheetCollection()->usesBeforeAfterRules()) {207 children()->updateBeforeAfterContent(this, BEFORE);208 children()->updateBeforeAfterContent(this, AFTER);209 194 } 210 195 } … … 329 314 RenderBoxModelObject* oldContinuation = continuation(); 330 315 setContinuation(newBox); 331 332 // Someone may have put a <p> inside a <q>, causing a split. When this happens, the :after content333 // has to move into the inline continuation. Call updateBeforeAfterContent to ensure that our :after334 // content gets properly destroyed.335 bool isLastChild = (beforeChild == lastChild());336 if (document()->styleSheetCollection()->usesBeforeAfterRules())337 children()->updateBeforeAfterContent(this, AFTER);338 if (isLastChild && beforeChild != lastChild())339 beforeChild = 0; // We destroyed the last child, so now we need to update our insertion340 // point to be 0. It's just a straight append now.341 316 342 317 splitFlow(beforeChild, newBox, newChild, oldContinuation); … … 405 380 inlineCurr->setContinuation(cloneInline); 406 381 cloneInline->setContinuation(oldCont); 407 408 // Someone may have indirectly caused a <q> to split. When this happens, the :after content409 // has to move into the inline continuation. Call updateBeforeAfterContent to ensure that the inline's :after410 // content gets properly destroyed.411 if (document()->styleSheetCollection()->usesBeforeAfterRules())412 inlineCurr->children()->updateBeforeAfterContent(inlineCurr, AFTER);413 382 414 383 // Now we need to take all of the children starting from the first child … … 764 733 if (isAnonymous()) 765 734 return "RenderInline (generated)"; 735 // FIXME: Temporary hack while the new generated content system is being implemented. 736 if (isPseudoElement()) 737 return "RenderInline (generated)"; 766 738 if (isRunIn()) 767 739 return "RenderInline (run-in)"; -
trunk/Source/WebCore/rendering/RenderListItem.cpp
r126359 r131004 269 269 m_marker->computePreferredLogicalWidths(); 270 270 // If markerPar is an anonymous block that has lost all its children, destroy it. 271 // Extraneous anonymous blocks can cause problems for RenderBlock::updateBeforeAfterContent.272 271 if (markerPar && markerPar->isAnonymousBlock() && !markerPar->firstChild() && !toRenderBlock(markerPar)->continuation()) 273 272 markerPar->destroy(); -
trunk/Source/WebCore/rendering/RenderMultiColumnBlock.cpp
r128201 r131004 147 147 const char* RenderMultiColumnBlock::renderName() const 148 148 { 149 // FIXME: Temporary hack while the new generated content system is being implemented. 150 if (isPseudoElement()) 151 return "RenderMultiColumnBlock (generated)"; 152 149 153 if (isFloating()) 150 154 return "RenderMultiColumnBlock (floating)"; -
trunk/Source/WebCore/rendering/RenderObject.cpp
r130829 r131004 131 131 // Otherwise acts as if we didn't support this feature. 132 132 const ContentData* contentData = style->contentData(); 133 if (contentData && !contentData->next() && contentData->isImage() && doc != node ) {133 if (contentData && !contentData->next() && contentData->isImage() && doc != node && !node->isPseudoElement()) { 134 134 RenderImage* image = new (arena) RenderImage(node); 135 135 // RenderImageResourceStyleImage requires a style being present on the image but we don't want to -
trunk/Source/WebCore/rendering/RenderObject.h
r130829 r131004 318 318 RenderArena* renderArena() const { return document()->renderArena(); } 319 319 320 bool isPseudoElement() const { return node() && node()->isPseudoElement(); } 321 320 322 virtual bool isBR() const { return false; } 321 323 virtual bool isBlockFlow() const { return false; } … … 610 612 // This is the same as node() except for renderers of :before and :after 611 613 // pseudo elements for which their parent node is returned. 612 Node* generatingNode() const { return m_node == document() ? 0 : m_node; } 614 Node* generatingNode() const 615 { 616 // FIXME: Fix the DOM traversals in RenderCounter and remove the use of generatingNode(). 617 Node* node = m_node == document() ? 0 : m_node; 618 if (node && node->isPseudoElement()) 619 return node->parentOrHostNode(); 620 return node; 621 } 613 622 void setNode(Node* node) { m_node = node; } 614 623 -
trunk/Source/WebCore/rendering/RenderObjectChildList.cpp
r130555 r131004 46 46 namespace WebCore { 47 47 48 bool RenderObjectChildList::s_enableUpdateBeforeAfterContent = true;49 50 48 void RenderObjectChildList::destroyLeftoverChildren() 51 49 { … … 198 196 } 199 197 200 static RenderObject* findBeforeAfterParent(RenderObject* object)201 {202 // Only table parts and flex-boxes need to search for the :before or :after parent203 // FIXME: We could likely get away without this check and always look for the right parent.204 if (!(object->isTable() || object->isTableSection() || object->isTableRow() || object->isFlexibleBoxIncludingDeprecated()))205 return object;206 207 // If there is a :first-letter style applied on the :before or :after content,208 // then we want the parent of the first-letter block209 RenderObject* beforeAfterParent = object;210 while (beforeAfterParent && !(beforeAfterParent->isText() || beforeAfterParent->isImage())211 && (beforeAfterParent->style()->styleType() != FIRST_LETTER))212 beforeAfterParent = beforeAfterParent->firstChild();213 214 return beforeAfterParent ? beforeAfterParent->parent() : 0;215 }216 217 198 RenderObject* RenderObjectChildList::beforePseudoElementRenderer(const RenderObject* owner) const 218 199 { … … 261 242 } 262 243 263 void RenderObjectChildList::updateBeforeAfterStyle(RenderObject* child, PseudoId type, RenderStyle* pseudoElementStyle)264 {265 if (!child || child->style()->styleType() != type)266 return;267 268 // We have generated content present still. We want to walk this content and update our269 // style information with the new pseudo-element style.270 child->setStyle(pseudoElementStyle);271 272 RenderObject* beforeAfterParent = findBeforeAfterParent(child);273 if (!beforeAfterParent)274 return;275 276 // When beforeAfterParent is not equal to child (e.g. in tables),277 // we need to create new styles inheriting from pseudoElementStyle278 // on all the intermediate parents (leaving their display same).279 if (beforeAfterParent != child) {280 RenderObject* curr = beforeAfterParent;281 while (curr && curr != child) {282 ASSERT(curr->isAnonymous());283 RefPtr<RenderStyle> newStyle = RenderStyle::create();284 newStyle->inheritFrom(pseudoElementStyle);285 newStyle->setDisplay(curr->style()->display());286 newStyle->setStyleType(curr->style()->styleType());287 curr->setStyle(newStyle);288 curr = curr->parent();289 }290 }291 292 // Note that if we ever support additional types of generated content (which should be way off293 // in the future), this code will need to be patched.294 for (RenderObject* genChild = beforeAfterParent->firstChild(); genChild; genChild = genChild->nextSibling()) {295 if (genChild->isText())296 // Generated text content is a child whose style also needs to be set to the pseudo-element style.297 genChild->setStyle(pseudoElementStyle);298 else if (genChild->isImage()) {299 // Images get an empty style that inherits from the pseudo.300 RefPtr<RenderStyle> style = RenderStyle::create();301 style->inheritFrom(pseudoElementStyle);302 genChild->setStyle(style.release());303 } else {304 // RenderListItem may insert a list marker here. We do not need to care about this case.305 // Otherwise, genChild must be a first-letter container. updateFirstLetter() will take care of it.306 ASSERT(genChild->isListMarker() || genChild->style()->styleType() == FIRST_LETTER);307 }308 }309 }310 311 static RenderObject* createRendererForBeforeAfterContent(RenderObject* owner, const ContentData* content, RenderStyle* pseudoElementStyle)312 {313 RenderObject* renderer = 0;314 switch (content->type()) {315 case CONTENT_NONE:316 break;317 case CONTENT_TEXT:318 renderer = new (owner->renderArena()) RenderTextFragment(owner->document() /* anonymous object */, static_cast<const TextContentData*>(content)->text().impl());319 renderer->setStyle(pseudoElementStyle);320 break;321 case CONTENT_OBJECT: {322 RenderImage* image = new (owner->renderArena()) RenderImage(owner->document()); // anonymous object323 RefPtr<RenderStyle> style = RenderStyle::create();324 style->inheritFrom(pseudoElementStyle);325 image->setStyle(style.release());326 if (const StyleImage* styleImage = static_cast<const ImageContentData*>(content)->image())327 image->setImageResource(RenderImageResourceStyleImage::create(const_cast<StyleImage*>(styleImage)));328 else329 image->setImageResource(RenderImageResource::create());330 renderer = image;331 break;332 }333 case CONTENT_COUNTER:334 renderer = new (owner->renderArena()) RenderCounter(owner->document(), *static_cast<const CounterContentData*>(content)->counter());335 renderer->setStyle(pseudoElementStyle);336 break;337 case CONTENT_QUOTE:338 renderer = new (owner->renderArena()) RenderQuote(owner->document(), static_cast<const QuoteContentData*>(content)->quote());339 renderer->setStyle(pseudoElementStyle);340 break;341 }342 return renderer;343 }344 345 static RenderObject* ensureBeforeAfterContainer(RenderObject* owner, PseudoId type, RenderStyle* pseudoElementStyle, Node* generatingNode, RenderObject* insertBefore)346 {347 // Make a generated box that might be any display type now that we are able to drill down into children348 // to find the original content properly.349 RenderObject* generatedContentContainer = RenderObject::createObject(owner->document(), pseudoElementStyle);350 ASSERT(generatingNode); // The styled object cannot be anonymous or else it could not have ':before' or ':after' pseudo elements.351 generatedContentContainer->setNode(generatingNode); // This allows access to the generatingNode.352 generatedContentContainer->setStyle(pseudoElementStyle);353 if (!owner->isChildAllowed(generatedContentContainer, pseudoElementStyle)) {354 // The generated content container is not allowed here -> abort.355 generatedContentContainer->destroy();356 return 0;357 }358 359 // When we don't have a first child and are part of a continuation chain,360 // insertBefore is incorrectly set to zero above, which causes the :before361 // child to end up at the end of continuation chain.362 // See https://bugs.webkit.org/show_bug.cgi?id=78380.363 if (!insertBefore && type == BEFORE && owner->virtualContinuation())364 owner->addChildIgnoringContinuation(generatedContentContainer, 0);365 else366 owner->addChild(generatedContentContainer, insertBefore);367 368 return generatedContentContainer;369 }370 371 void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, PseudoId type, const RenderObject* styledObject)372 {373 // Double check that the document did in fact use generated content rules. Otherwise we should not have been called.374 ASSERT(owner->document()->styleSheetCollection()->usesBeforeAfterRules());375 376 // In CSS2, before/after pseudo-content cannot nest. Check this first.377 if (owner->style()->styleType() == BEFORE || owner->style()->styleType() == AFTER)378 return;379 if (!s_enableUpdateBeforeAfterContent)380 return;381 382 if (!styledObject)383 styledObject = owner;384 385 RenderStyle* pseudoElementStyle = styledObject->getCachedPseudoStyle(type);386 RenderObject* child;387 switch (type) {388 case BEFORE:389 child = beforePseudoElementRenderer(owner);390 break;391 case AFTER:392 child = afterPseudoElementRenderer(owner);393 break;394 default:395 ASSERT_NOT_REACHED();396 return;397 }398 399 // Whether or not we currently have generated content attached.400 bool oldContentPresent = child;401 402 // Whether or not we now want generated content.403 bool newContentWanted = pseudoElementStyle && pseudoElementStyle->display() != NONE;404 405 // For <q><p/></q>, if this object is the inline continuation of the <q>, we only want to generate406 // :after content and not :before content.407 if (newContentWanted && type == BEFORE && owner->isElementContinuation())408 newContentWanted = false;409 410 // Similarly, if we're the beginning of a <q>, and there's an inline continuation for our object,411 // then we don't generate the :after content.412 if (newContentWanted && type == AFTER && owner->virtualContinuation())413 newContentWanted = false;414 415 // If we don't want generated content any longer, or if we have generated content, but it's no longer416 // identical to the new content data we want to build render objects for, then we nuke all417 // of the old generated content.418 if (oldContentPresent && (!newContentWanted || Node::diff(child->style(), pseudoElementStyle, owner->document()) == Node::Detach)) {419 // Nuke the child.420 if (child->style()->styleType() == type) {421 oldContentPresent = false;422 child->destroy();423 child = (type == BEFORE) ? owner->virtualChildren()->firstChild() : owner->virtualChildren()->lastChild();424 }425 }426 427 // If we have no pseudo-element style or if the pseudo-element style's display type is NONE, then we428 // have no generated content and can now return.429 if (!newContentWanted)430 return;431 432 if (owner->isRenderInline() && !pseudoElementStyle->isDisplayInlineType() && !pseudoElementStyle->isFloating() &&433 !pseudoElementStyle->hasOutOfFlowPosition())434 // According to the CSS2 spec (the end of section 12.1), the only allowed435 // display values for the pseudo style are NONE and INLINE for inline flows.436 // FIXME: CSS2.1 lifted this restriction, but block display types will crash.437 // For now we at least relax the restriction to allow all inline types like inline-block438 // and inline-table.439 pseudoElementStyle->setDisplay(INLINE);440 441 if (oldContentPresent) {442 updateBeforeAfterStyle(child, type, pseudoElementStyle);443 return; // We've updated the generated content. That's all we needed to do.444 }445 446 RenderObject* insertBefore = (type == BEFORE) ? owner->virtualChildren()->firstChild() : 0;447 if (insertBefore && insertBefore->isAnonymousBlock() && insertBefore->childrenInline() && !insertBefore->isEmpty()) {448 // We are going to add the "before" element. We have to check whether the "insertBefore" element449 // is an anonymous block with inline children. If it is, then we should insert the "before" element450 // before the first inline child of the anonymous block, otherwise we will end up with the "before"451 // element in a different block. We do this only when the anonymous block has children, otherwise452 // we end up with the before element in a wrong block.453 insertBefore = insertBefore->firstChild();454 }455 456 // Nothing goes before the intruded run-in, not even generated content.457 if (insertBefore && insertBefore->isRunIn() && owner->isRenderBlock()458 && toRenderBlock(owner)->runInIsPlacedIntoSiblingBlock(insertBefore))459 insertBefore = insertBefore->nextSibling();460 461 // Generated content consists of a single container that houses multiple children (specified462 // by the content property). This generated content container gets the pseudo-element style set on it.463 // For pseudo-elements that are regions, the container is the RenderRegion.464 RenderObject* generatedContentContainer = 0;465 466 if (!pseudoElementStyle->regionThread().isEmpty())467 generatedContentContainer = ensureBeforeAfterContainer(owner, type, pseudoElementStyle, styledObject->node(), insertBefore);468 else {469 // Walk our list of generated content and create render objects for each.470 for (const ContentData* content = pseudoElementStyle->contentData(); content; content = content->next()) {471 RenderObject* renderer = createRendererForBeforeAfterContent(owner, content, pseudoElementStyle);472 473 if (renderer) {474 if (!generatedContentContainer) {475 generatedContentContainer = ensureBeforeAfterContainer(owner, type, pseudoElementStyle, styledObject->node(), insertBefore);476 if (!generatedContentContainer) {477 renderer->destroy();478 return;479 }480 }481 if (generatedContentContainer->isChildAllowed(renderer, pseudoElementStyle))482 generatedContentContainer->addChild(renderer);483 else484 renderer->destroy();485 }486 }487 }488 489 if (!generatedContentContainer)490 return;491 492 // Handle placement of run-ins. We do the run-in placement at the end since generatedContentContainer can get destroyed.493 RenderObject* generatedContentContainerImmediateParent = generatedContentContainer->parent();494 if (generatedContentContainerImmediateParent->isRenderBlock())495 toRenderBlock(generatedContentContainerImmediateParent)->placeRunInIfNeeded(generatedContentContainer, PlaceGeneratedRunIn);496 }497 498 244 } // namespace WebCore -
trunk/Source/WebCore/rendering/RenderObjectChildList.h
r130555 r131004 57 57 void insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* before, bool notifyRenderer = true); 58 58 59 void updateBeforeAfterContent(RenderObject* owner, PseudoId type, const RenderObject* styledObject = 0);60 59 RenderObject* beforePseudoElementRenderer(const RenderObject* owner) const; 61 60 RenderObject* afterPseudoElementRenderer(const RenderObject* owner) const; 62 61 63 public:64 static bool s_enableUpdateBeforeAfterContent;65 66 62 private: 67 void updateBeforeAfterStyle(RenderObject* child, PseudoId type, RenderStyle* pseudoElementStyle);68 69 63 RenderObject* m_firstChild; 70 64 RenderObject* m_lastChild; -
trunk/Source/WebCore/rendering/RenderRubyText.cpp
r120495 r131004 89 89 } 90 90 91 void RenderRubyText::updateBeforeAfterContent(PseudoId pseudoId)92 {93 // RenderRubyText manages its own :before and :after content94 // and is not handled by its anonymous wrappers RenderRubyRun95 // and RenderRuby. This contrasts with other ruby children, which96 // are enclosed in RenderRubyBase and hence they are able to97 // update their :before, :after content (since RenderRubyBase98 // is not a anonymous wrapper).99 return children()->updateBeforeAfterContent(this, pseudoId);100 }101 102 91 } // namespace WebCore -
trunk/Source/WebCore/rendering/RenderRubyText.h
r95901 r131004 47 47 virtual bool isChildAllowed(RenderObject*, RenderStyle*) const; 48 48 49 virtual void updateBeforeAfterContent(PseudoId);50 51 49 private: 52 50 virtual bool avoidsFloats() const; -
trunk/Source/WebCore/rendering/RenderTableCell.h
r130710 r131004 210 210 211 211 private: 212 virtual const char* renderName() const { return isAnonymous() ? "RenderTableCell (anonymous)" : "RenderTableCell"; }212 virtual const char* renderName() const { return (isAnonymous() || isPseudoElement()) ? "RenderTableCell (anonymous)" : "RenderTableCell"; } 213 213 214 214 virtual bool isTableCell() const { return true; } -
trunk/Source/WebCore/rendering/RenderTableRow.cpp
r130081 r131004 54 54 } 55 55 56 void RenderTableRow::updateBeforeAndAfterContent()57 {58 if (!isAnonymous() && document()->styleSheetCollection()->usesBeforeAfterRules()) {59 children()->updateBeforeAfterContent(this, BEFORE);60 children()->updateBeforeAfterContent(this, AFTER);61 }62 }63 64 56 void RenderTableRow::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) 65 57 { … … 68 60 RenderBox::styleDidChange(diff, oldStyle); 69 61 propagateStyleToAnonymousChildren(); 70 71 if (parent())72 updateBeforeAndAfterContent();73 62 74 63 if (section() && oldStyle && style()->logicalHeight() != oldStyle->logicalHeight()) -
trunk/Source/WebCore/rendering/RenderTableRow.h
r130081 r131004 43 43 RenderTable* table() const { return toRenderTable(parent()->parent()); } 44 44 45 void updateBeforeAndAfterContent();46 45 void paintOutlineForRowIfNeeded(PaintInfo&, const LayoutPoint&); 47 46 … … 90 89 virtual const RenderObjectChildList* virtualChildren() const { return children(); } 91 90 92 virtual const char* renderName() const { return isAnonymous() ? "RenderTableRow (anonymous)" : "RenderTableRow"; }91 virtual const char* renderName() const { return (isAnonymous() || isPseudoElement()) ? "RenderTableRow (anonymous)" : "RenderTableRow"; } 93 92 94 93 virtual bool isTableRow() const { return true; } -
trunk/Source/WebCore/rendering/RenderTableSection.cpp
r130612 r131004 187 187 ASSERT(!beforeChild || beforeChild->isTableRow()); 188 188 RenderBox::addChild(child, beforeChild); 189 toRenderTableRow(child)->updateBeforeAndAfterContent();190 189 } 191 190 -
trunk/Source/WebCore/rendering/RenderTableSection.h
r130454 r131004 201 201 virtual const RenderObjectChildList* virtualChildren() const { return children(); } 202 202 203 virtual const char* renderName() const { return isAnonymous() ? "RenderTableSection (anonymous)" : "RenderTableSection"; }203 virtual const char* renderName() const { return (isAnonymous() || isPseudoElement()) ? "RenderTableSection (anonymous)" : "RenderTableSection"; } 204 204 205 205 virtual bool isTableSection() const { return true; } -
trunk/Source/WebCore/rendering/RenderTreeAsText.cpp
r130918 r131004 222 222 if (o.node()) { 223 223 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; 224 227 if (!tagName.isEmpty()) { 225 228 ts << " {" << tagName << "}";
Note: See TracChangeset
for help on using the changeset viewer.