Changeset 179807 in webkit
- Timestamp:
- Feb 8, 2015, 3:22:24 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 9 added
- 50 deleted
- 9 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/platform/efl/svg/W3C-SVG-1.2-Tiny (deleted)
-
LayoutTests/platform/efl/svg/hixie/error/017-expected.png (deleted)
-
LayoutTests/platform/gtk/svg/W3C-SVG-1.2-Tiny (deleted)
-
LayoutTests/platform/gtk/svg/custom/use-on-disallowed-foreign-object-3-expected.png (deleted)
-
LayoutTests/platform/gtk/svg/custom/use-on-disallowed-foreign-object-3-expected.txt (deleted)
-
LayoutTests/platform/gtk/svg/custom/use-recursion-1-expected.png (deleted)
-
LayoutTests/platform/gtk/svg/custom/use-recursion-1-expected.txt (deleted)
-
LayoutTests/platform/gtk/svg/custom/use-recursion-2-expected.png (deleted)
-
LayoutTests/platform/gtk/svg/custom/use-recursion-2-expected.txt (deleted)
-
LayoutTests/platform/gtk/svg/custom/use-recursion-3-expected.png (deleted)
-
LayoutTests/platform/gtk/svg/custom/use-recursion-3-expected.txt (deleted)
-
LayoutTests/platform/gtk/svg/custom/use-recursion-4-expected.png (deleted)
-
LayoutTests/platform/gtk/svg/custom/use-recursion-4-expected.txt (deleted)
-
LayoutTests/platform/gtk/svg/hixie/error/017-expected.png (deleted)
-
LayoutTests/platform/ios-sim-deprecated/svg/W3C-SVG-1.2-Tiny (deleted)
-
LayoutTests/platform/ios-sim-deprecated/svg/custom/use-on-disallowed-foreign-object-3-expected.txt (deleted)
-
LayoutTests/platform/ios-sim-deprecated/svg/custom/use-recursion-1-expected.txt (deleted)
-
LayoutTests/platform/ios-sim-deprecated/svg/custom/use-recursion-2-expected.txt (deleted)
-
LayoutTests/platform/ios-sim-deprecated/svg/custom/use-recursion-3-expected.txt (deleted)
-
LayoutTests/platform/ios-sim-deprecated/svg/custom/use-recursion-4-expected.txt (deleted)
-
LayoutTests/platform/ios-sim-deprecated/svg/hixie/error/017-expected.txt (deleted)
-
LayoutTests/platform/ios-simulator/svg/custom/use-on-disallowed-foreign-object-3-expected.txt (deleted)
-
LayoutTests/platform/ios-simulator/svg/custom/use-recursion-1-expected.txt (deleted)
-
LayoutTests/platform/ios-simulator/svg/custom/use-recursion-2-expected.txt (deleted)
-
LayoutTests/platform/ios-simulator/svg/custom/use-recursion-3-expected.txt (deleted)
-
LayoutTests/platform/ios-simulator/svg/custom/use-recursion-4-expected.txt (deleted)
-
LayoutTests/platform/mac-mountainlion/svg/W3C-SVG-1.2-Tiny (deleted)
-
LayoutTests/platform/mac-mountainlion/svg/custom/use-on-disallowed-foreign-object-3-expected.txt (deleted)
-
LayoutTests/platform/mac-mountainlion/svg/custom/use-recursion-1-expected.txt (deleted)
-
LayoutTests/platform/mac-mountainlion/svg/custom/use-recursion-2-expected.txt (deleted)
-
LayoutTests/platform/mac-mountainlion/svg/custom/use-recursion-3-expected.txt (deleted)
-
LayoutTests/platform/mac-mountainlion/svg/custom/use-recursion-4-expected.txt (deleted)
-
LayoutTests/platform/mac-mountainlion/svg/hixie/error/017-expected.txt (deleted)
-
LayoutTests/platform/mac/svg/W3C-SVG-1.2-Tiny (deleted)
-
LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-3-expected.png (deleted)
-
LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-3-expected.txt (deleted)
-
LayoutTests/platform/mac/svg/custom/use-recursion-1-expected.png (deleted)
-
LayoutTests/platform/mac/svg/custom/use-recursion-1-expected.txt (deleted)
-
LayoutTests/platform/mac/svg/custom/use-recursion-2-expected.png (deleted)
-
LayoutTests/platform/mac/svg/custom/use-recursion-2-expected.txt (deleted)
-
LayoutTests/platform/mac/svg/custom/use-recursion-3-expected.png (deleted)
-
LayoutTests/platform/mac/svg/custom/use-recursion-3-expected.txt (deleted)
-
LayoutTests/platform/mac/svg/custom/use-recursion-4-expected.png (deleted)
-
LayoutTests/platform/mac/svg/custom/use-recursion-4-expected.txt (deleted)
-
LayoutTests/platform/mac/svg/hixie/error/017-expected.png (deleted)
-
LayoutTests/platform/mac/svg/hixie/error/017-expected.txt (deleted)
-
LayoutTests/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-01-t-expected.svg (added)
-
LayoutTests/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-01-t-expected.txt (deleted)
-
LayoutTests/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-02-t-expected.svg (added)
-
LayoutTests/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-02-t-expected.txt (deleted)
-
LayoutTests/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-03-t-expected.svg (added)
-
LayoutTests/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-03-t-expected.txt (deleted)
-
LayoutTests/svg/custom/use-on-disallowed-foreign-object-3-expected.svg (added)
-
LayoutTests/svg/custom/use-recursion-1-expected.svg (added)
-
LayoutTests/svg/custom/use-recursion-2-expected.svg (added)
-
LayoutTests/svg/custom/use-recursion-3-expected.svg (added)
-
LayoutTests/svg/custom/use-recursion-4-expected.svg (added)
-
LayoutTests/svg/hixie/error/017-expected.txt (deleted)
-
LayoutTests/svg/hixie/error/017-expected.xml (added)
-
LayoutTests/svg/in-html/defs-after-use.html (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/dom/ElementIterator.h (modified) (3 diffs)
-
Source/WebCore/dom/TypedElementDescendantIterator.h (modified) (4 diffs)
-
Source/WebCore/svg/SVGElement.cpp (modified) (2 diffs)
-
Source/WebCore/svg/SVGElement.h (modified) (1 diff)
-
Source/WebCore/svg/SVGUseElement.cpp (modified) (12 diffs)
-
Source/WebCore/svg/SVGUseElement.h (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r179806 r179807 1 2015-02-08 Darin Adler <darin@apple.com> 2 3 Make SVGUseElement work without creating any SVGElementInstance objects 4 https://bugs.webkit.org/show_bug.cgi?id=141374 5 6 Reviewed by Sam Weinig. 7 8 Results changed on some tests that expected the old "remove all content if a cycle is detected" 9 behavior from the <use> element. The new behavior is to inhibit cycles, but render everything 10 else, which is much easier to implement correctly and also makes logical sense. Changed all 11 those tests to be reference tests, which makes sense since they are focusing on what gets 12 rendered in these complex cases, and the expected results are a lot easier to understand in 13 SVG form than they were in txt/png form. This also means we can remove a lot of platform-specific 14 results since reference tests aren't sensitive to small platform differences in rendering. 15 16 * platform/efl/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-01-t-expected.png: Removed. 17 * platform/efl/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-02-t-expected.png: Removed. 18 * platform/efl/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-03-t-expected.png: Removed. 19 * platform/efl/svg/hixie/error/017-expected.png: Removed. 20 * platform/gtk/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-01-t-expected.png: Removed. 21 * platform/gtk/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-02-t-expected.png: Removed. 22 * platform/gtk/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-03-t-expected.png: Removed. 23 * platform/gtk/svg/custom/use-on-disallowed-foreign-object-3-expected.png: Removed. 24 * platform/gtk/svg/custom/use-on-disallowed-foreign-object-3-expected.txt: Removed. 25 * platform/gtk/svg/custom/use-recursion-1-expected.png: Removed. 26 * platform/gtk/svg/custom/use-recursion-1-expected.txt: Removed. 27 * platform/gtk/svg/custom/use-recursion-2-expected.png: Removed. 28 * platform/gtk/svg/custom/use-recursion-2-expected.txt: Removed. 29 * platform/gtk/svg/custom/use-recursion-3-expected.png: Removed. 30 * platform/gtk/svg/custom/use-recursion-3-expected.txt: Removed. 31 * platform/gtk/svg/custom/use-recursion-4-expected.png: Removed. 32 * platform/gtk/svg/custom/use-recursion-4-expected.txt: Removed. 33 * platform/gtk/svg/hixie/error/017-expected.png: Removed. 34 * platform/ios-sim-deprecated/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-01-t-expected.txt: Removed. 35 * platform/ios-sim-deprecated/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-02-t-expected.txt: Removed. 36 * platform/ios-sim-deprecated/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-03-t-expected.txt: Removed. 37 * platform/ios-sim-deprecated/svg/custom/use-on-disallowed-foreign-object-3-expected.txt: Removed. 38 * platform/ios-sim-deprecated/svg/custom/use-recursion-1-expected.txt: Removed. 39 * platform/ios-sim-deprecated/svg/custom/use-recursion-2-expected.txt: Removed. 40 * platform/ios-sim-deprecated/svg/custom/use-recursion-3-expected.txt: Removed. 41 * platform/ios-sim-deprecated/svg/custom/use-recursion-4-expected.txt: Removed. 42 * platform/ios-sim-deprecated/svg/hixie/error/017-expected.txt: Removed. 43 * platform/ios-simulator/svg/custom/use-on-disallowed-foreign-object-3-expected.txt: Removed. 44 * platform/ios-simulator/svg/custom/use-recursion-1-expected.txt: Removed. 45 * platform/ios-simulator/svg/custom/use-recursion-2-expected.txt: Removed. 46 * platform/ios-simulator/svg/custom/use-recursion-3-expected.txt: Removed. 47 * platform/ios-simulator/svg/custom/use-recursion-4-expected.txt: Removed. 48 * platform/mac-mountainlion/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-01-t-expected.txt: Removed. 49 * platform/mac-mountainlion/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-02-t-expected.txt: Removed. 50 * platform/mac-mountainlion/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-03-t-expected.txt: Removed. 51 * platform/mac-mountainlion/svg/custom/use-on-disallowed-foreign-object-3-expected.txt: Removed. 52 * platform/mac-mountainlion/svg/custom/use-recursion-1-expected.txt: Removed. 53 * platform/mac-mountainlion/svg/custom/use-recursion-2-expected.txt: Removed. 54 * platform/mac-mountainlion/svg/custom/use-recursion-3-expected.txt: Removed. 55 * platform/mac-mountainlion/svg/custom/use-recursion-4-expected.txt: Removed. 56 * platform/mac-mountainlion/svg/hixie/error/017-expected.txt: Removed. 57 * platform/mac/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-01-t-expected.png: Removed. 58 * platform/mac/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-01-t-expected.txt: Removed. 59 * platform/mac/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-02-t-expected.png: Removed. 60 * platform/mac/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-02-t-expected.txt: Removed. 61 * platform/mac/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-03-t-expected.png: Removed. 62 * platform/mac/svg/W3C-SVG-1.2-Tiny/struct-use-recursion-03-t-expected.txt: Removed. 63 * platform/mac/svg/custom/use-on-disallowed-foreign-object-3-expected.png: Removed. 64 * platform/mac/svg/custom/use-on-disallowed-foreign-object-3-expected.txt: Removed. 65 * platform/mac/svg/custom/use-recursion-1-expected.png: Removed. 66 * platform/mac/svg/custom/use-recursion-1-expected.txt: Removed. 67 * platform/mac/svg/custom/use-recursion-2-expected.png: Removed. 68 * platform/mac/svg/custom/use-recursion-2-expected.txt: Removed. 69 * platform/mac/svg/custom/use-recursion-3-expected.png: Removed. 70 * platform/mac/svg/custom/use-recursion-3-expected.txt: Removed. 71 * platform/mac/svg/custom/use-recursion-4-expected.png: Removed. 72 * platform/mac/svg/custom/use-recursion-4-expected.txt: Removed. 73 * platform/mac/svg/hixie/error/017-expected.png: Removed. 74 * platform/mac/svg/hixie/error/017-expected.txt: Removed. 75 76 * svg/W3C-SVG-1.2-Tiny/struct-use-recursion-01-t-expected.svg: Added. Made this be a reference test, 77 and made it expect more of the recursion to work. 78 * svg/W3C-SVG-1.2-Tiny/struct-use-recursion-01-t-expected.txt: Removed. 79 * svg/W3C-SVG-1.2-Tiny/struct-use-recursion-02-t-expected.svg: Added. More of the same. 80 * svg/W3C-SVG-1.2-Tiny/struct-use-recursion-02-t-expected.txt: Removed. 81 * svg/W3C-SVG-1.2-Tiny/struct-use-recursion-03-t-expected.svg: Added. More of the same. 82 * svg/W3C-SVG-1.2-Tiny/struct-use-recursion-03-t-expected.txt: Removed. 83 * svg/custom/use-on-disallowed-foreign-object-3-expected.svg: Added. More of the same. 84 * svg/custom/use-recursion-1-expected.svg: Added. More of the same. 85 * svg/custom/use-recursion-2-expected.svg: Added. More of the same. 86 * svg/custom/use-recursion-3-expected.svg: Added. More of the same. 87 * svg/custom/use-recursion-4-expected.svg: Added. More of the same. 88 * svg/hixie/error/017-expected.txt: Removed. 89 * svg/hixie/error/017-expected.xml: Added. More of the same. 90 91 * svg/in-html/defs-after-use.html: Updated incorrect bug number in this test. 92 1 93 2015-02-08 David Kilzer <ddkilzer@apple.com> 2 94 -
trunk/LayoutTests/svg/in-html/defs-after-use.html
r177576 r179807 6 6 tree as well. 7 7 8 https://bugs.webkit.org/show_bug.cgi?id=1394 698 https://bugs.webkit.org/show_bug.cgi?id=139451 9 9 --> 10 10 <html> -
trunk/Source/WebCore/ChangeLog
r179804 r179807 1 2015-02-08 Darin Adler <darin@apple.com> 2 3 Make SVGUseElement work without creating any SVGElementInstance objects 4 https://bugs.webkit.org/show_bug.cgi?id=141374 5 6 Reviewed by Sam Weinig. 7 8 * dom/ElementIterator.h: Changed the * and -> operators to be const. 9 There is no need for the iterator itself to be modified just to dereference it. 10 11 * dom/TypedElementDescendantIterator.h: Added DoubleTypedElementDescendantIterator. 12 This allows callers to call descendantsOfType on two elements, as long as the caller 13 can guarantee that both have the same number of descendants of that type. It's handy 14 for walking a tree of cloned elements to set up something between each original and 15 its clone. In the future we might instead change the cloning machinery so it can do 16 this work as we clone, and if so, we could consider deleting this. 17 18 * svg/SVGElement.cpp: 19 (WebCore::SVGElement::correspondingElement): Made this const. 20 (WebCore::SVGElement::invalidateInstances): Got rid of the rule that said "this can 21 only be done for an element in a document", since it's useful to do this on an element 22 that has just been removed from a document. Removed the "updateStyleIfNeeded" call 23 here now that the other changes make it no longer needed. Removed an unimportant 24 assertion that we only invalidate use elements that are in a document; that's not 25 a necessary restriction. Streamlined the logic a bit. 26 27 * svg/SVGElement.h: Made correspondingElement const. 28 29 * svg/SVGUseElement.cpp: 30 (WebCore::SVGUseElement::insertedInto): Removed an assertion about 31 m_targetElementInstance since that's gone now. 32 (WebCore::SVGUseElement::svgAttributeChanged): Changed code that transfers 33 size attributes to the shadow tree to use shadowTreeTargetClone instead of 34 m_targetElementInstance. 35 (WebCore::SVGUseElement::clearResourceReferences): Removed code to detach 36 m_targetElementInstance, and also the call to removeAllTargetReferencesForElement, 37 because we no longer use those. 38 (WebCore::SVGUseElement::buildPendingResource): Moved the code to build the 39 shadow tree in here and deleted the buildShadowAndInstanceTree function. 40 Also changed logic so that we use a pending resource any time the target is not 41 a valid one. That helps us correctly handle cases where we initially have an 42 invalid target, but later get a value one 43 (WebCore::SVGUseElement::buildShadowAndInstanceTree): Deleted. The code here 44 was greatly simplified and moved into buildPendingResource. 45 (WebCore::SVGUseElement::buildInstanceTree): Deleted. 46 (WebCore::SVGUseElement::hasCycleUseReferencing): Deleted. Cycles are now 47 detected by the new isValidTarget function and so there's no need for a 48 separate explicit check for a cycle. 49 (WebCore::associateClonesWithOriginals): Added. Helper that makes 50 functions that build the shadow tree simpler and easier to read. 51 (WebCore::associateReplacementCloneWithOriginal): Added. Helper to 52 make associateReplacementClonesWithOriginals simple. 53 (WebCore::associateReplacementClonesWithOriginals): Added. Helper that 54 makes functions that build the shadow tree simpler and easier to read. 55 (WebCore::SVGUseElement::buildShadowTree): Call associateClonesWithOriginals 56 since associateInstancesWithShadowTreeElements no longer does this. 57 (WebCore::SVGUseElement::isValidTarget): Added. Covers all the different 58 reasons a target might not be valid: type of element, reference cycles, and 59 also "not in document" (refactored in here; not sure when that can happen 60 in practice, might be possible to remove it later). 61 (WebCore::SVGUseElement::expandUseElementsInShadowTree): Add checks for 62 documents that are still loading; this used to be checked when building the 63 instance tree. Added calls to associateReplacementClonesWithOriginals and 64 associateClonesWithOriginals; that used to be done by later in the 65 associateInstancesWithShadowTreeElements function. Use isValidTarget so 66 we handle cycles as well as invalid target types. 67 (WebCore::SVGUseElement::expandSymbolElementsInShadowTree): Added a call to 68 associateReplacementClonesWithOriginals, since we can no longer do that in 69 associateInstancesWithShadowTreeElements. 70 (WebCore::SVGUseElement::associateInstancesWithShadowTreeElements): Deleted. 71 (WebCore::SVGUseElement::instanceForShadowTreeElement): Deleted. 72 (WebCore::SVGUseElement::invalidateDependentShadowTrees): Removed a comment 73 that simply restated the name of the function. 74 75 * svg/SVGUseElement.h: Removed instanceForShadowTreeElement, 76 buildShadowAndInstanceTree, detachInstance, buildInstanceTree, 77 hasCycleUseReferencing, associateInstancesWithShadowTreeElements, 78 instanceForShadowTreeElement, and m_targetElementInstance. Added isValidTarget. 79 1 80 2015-02-08 Chris Dumez <cdumez@apple.com> 2 81 -
trunk/Source/WebCore/dom/ElementIterator.h
r179143 r179807 41 41 ElementIterator(const ContainerNode* root, ElementType* current); 42 42 43 ElementType& operator*() ;44 ElementType* operator->() ;43 ElementType& operator*() const; 44 ElementType* operator->() const; 45 45 46 46 bool operator==(const ElementIterator& other) const; … … 212 212 213 213 template <typename ElementType> 214 inline ElementType& ElementIterator<ElementType>::operator*() 214 inline ElementType& ElementIterator<ElementType>::operator*() const 215 215 { 216 216 ASSERT(m_current); … … 220 220 221 221 template <typename ElementType> 222 inline ElementType* ElementIterator<ElementType>::operator->() 222 inline ElementType* ElementIterator<ElementType>::operator->() const 223 223 { 224 224 ASSERT(m_current); -
trunk/Source/WebCore/dom/TypedElementDescendantIterator.h
r179143 r179807 31 31 namespace WebCore { 32 32 33 template<typename ElementType> class DoubleTypedElementDescendantIterator; 34 33 35 template <typename ElementType> 34 36 class TypedElementDescendantIterator : public ElementIterator<ElementType> { … … 79 81 }; 80 82 83 template<typename ElementType> class DoubleTypedElementDescendantIteratorAdapter { 84 public: 85 typedef TypedElementDescendantIteratorAdapter<ElementType> SingleAdapter; 86 typedef DoubleTypedElementDescendantIterator<ElementType> Iterator; 87 88 DoubleTypedElementDescendantIteratorAdapter(SingleAdapter&&, SingleAdapter&&); 89 Iterator begin(); 90 Iterator end(); 91 92 private: 93 std::pair<SingleAdapter, SingleAdapter> m_pair; 94 }; 95 96 template<typename ElementType> class DoubleTypedElementDescendantIterator { 97 public: 98 typedef TypedElementDescendantIterator<ElementType> SingleIterator; 99 typedef std::pair<ElementType&, ElementType&> ReferenceProxy; 100 101 DoubleTypedElementDescendantIterator(SingleIterator&&, SingleIterator&&); 102 ReferenceProxy operator*() const; 103 bool operator==(const DoubleTypedElementDescendantIterator&) const; 104 bool operator!=(const DoubleTypedElementDescendantIterator&) const; 105 DoubleTypedElementDescendantIterator& operator++(); 106 107 private: 108 std::pair<SingleIterator, SingleIterator> m_pair; 109 }; 110 81 111 template <typename ElementType> TypedElementDescendantIteratorAdapter<ElementType> descendantsOfType(ContainerNode&); 82 112 template <typename ElementType> TypedElementDescendantConstIteratorAdapter<ElementType> descendantsOfType(const ContainerNode&); 113 114 // This must only be used when both sets of descendants are known to be the same length. 115 // If they are different lengths, this will stop when the shorter one reaches the end, but also an assertion will fail. 116 template<typename ElementType> DoubleTypedElementDescendantIteratorAdapter<ElementType> descendantsOfType(ContainerNode& firstRoot, ContainerNode& secondRoot); 83 117 84 118 // TypedElementDescendantIterator … … 221 255 } 222 256 257 // DoubleTypedElementDescendantIteratorAdapter 258 259 template<typename ElementType> inline DoubleTypedElementDescendantIteratorAdapter<ElementType>::DoubleTypedElementDescendantIteratorAdapter(SingleAdapter&& first, SingleAdapter&& second) 260 : m_pair(WTF::move(first), WTF::move(second)) 261 { 262 } 263 264 template<typename ElementType> inline auto DoubleTypedElementDescendantIteratorAdapter<ElementType>::begin() -> Iterator 265 { 266 return { m_pair.first.begin(), m_pair.second.begin() }; 267 } 268 269 template<typename ElementType> inline auto DoubleTypedElementDescendantIteratorAdapter<ElementType>::end() -> Iterator 270 { 271 return { m_pair.first.end(), m_pair.second.end() }; 272 } 273 274 // DoubleTypedElementDescendantIterator 275 276 template<typename ElementType> inline DoubleTypedElementDescendantIterator<ElementType>::DoubleTypedElementDescendantIterator(SingleIterator&& first, SingleIterator&& second) 277 : m_pair(WTF::move(first), WTF::move(second)) 278 { 279 } 280 281 template<typename ElementType> inline auto DoubleTypedElementDescendantIterator<ElementType>::operator*() const -> ReferenceProxy 282 { 283 return { *m_pair.first, *m_pair.second }; 284 } 285 286 template<typename ElementType> inline bool DoubleTypedElementDescendantIterator<ElementType>::operator==(const DoubleTypedElementDescendantIterator& other) const 287 { 288 ASSERT((m_pair.first == other.m_pair.first) == (m_pair.second == other.m_pair.second)); 289 return m_pair.first == other.m_pair.first || m_pair.second == other.m_pair.second; 290 } 291 292 template<typename ElementType> inline bool DoubleTypedElementDescendantIterator<ElementType>::operator!=(const DoubleTypedElementDescendantIterator& other) const 293 { 294 return !(*this == other); 295 } 296 297 template<typename ElementType> inline DoubleTypedElementDescendantIterator<ElementType>& DoubleTypedElementDescendantIterator<ElementType>::operator++() 298 { 299 ++m_pair.first; 300 ++m_pair.second; 301 return *this; 302 } 303 223 304 // Standalone functions 224 305 … … 235 316 } 236 317 318 template<typename ElementType> inline DoubleTypedElementDescendantIteratorAdapter<ElementType> descendantsOfType(ContainerNode& firstRoot, ContainerNode& secondRoot) 319 { 320 return { descendantsOfType<ElementType>(firstRoot), descendantsOfType<ElementType>(secondRoot) }; 321 } 322 237 323 } 238 324 -
trunk/Source/WebCore/svg/SVGElement.cpp
r179695 r179807 476 476 } 477 477 478 SVGElement* SVGElement::correspondingElement() 478 SVGElement* SVGElement::correspondingElement() const 479 479 { 480 480 ASSERT(!m_svgRareData || !m_svgRareData->correspondingElement() || correspondingUseElement()); … … 1208 1208 void SVGElement::invalidateInstances() 1209 1209 { 1210 if (!inDocument())1211 return;1212 1213 1210 if (instanceUpdatesBlocked()) 1214 1211 return; 1215 1212 1216 1213 auto& instances = this->instances(); 1217 if (instances.isEmpty()) 1218 return; 1219 1220 // Mark all use elements referencing 'element' for rebuilding 1221 do { 1214 while (!instances.isEmpty()) { 1222 1215 SVGElement* instance = *instances.begin(); 1223 if (SVGUseElement* element = instance->correspondingUseElement()) { 1224 ASSERT(element->inDocument()); 1225 element->invalidateShadowTree(); 1226 } 1216 if (SVGUseElement* useElement = instance->correspondingUseElement()) 1217 useElement->invalidateShadowTree(); 1227 1218 instance->setCorrespondingElement(nullptr); 1228 1219 } while (!instances.isEmpty()); 1229 1230 // FIXME: Why is this needed? 1231 document().updateStyleIfNeeded(); 1232 } 1233 1234 } 1220 } 1221 1222 } -
trunk/Source/WebCore/svg/SVGElement.h
r179695 r179807 114 114 void cursorImageValueRemoved(); 115 115 116 SVGElement* correspondingElement() ;116 SVGElement* correspondingElement() const; 117 117 SVGUseElement* correspondingUseElement() const; 118 118 -
trunk/Source/WebCore/svg/SVGUseElement.cpp
r179695 r179807 158 158 if (!rootParent.inDocument()) 159 159 return InsertionDone; 160 ASSERT(!m_targetElementInstance || !isWellFormedDocument(document()));161 160 ASSERT(!hasPendingResources() || !isWellFormedDocument(document())); 162 161 SVGExternalResourcesRequired::insertedIntoDocument(this); … … 228 227 if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr) { 229 228 updateRelativeLengthsInformation(); 230 if ( m_targetElementInstance) {229 if (SVGElement* shadowTreeTargetClone = this->shadowTreeTargetClone()) { 231 230 // FIXME: It's unnecessarily inefficient to do this work any time we change "x" or "y". 232 231 // FIXME: It's unnecessarily inefficient to update both width and height each time either is changed. 233 ASSERT(m_targetElementInstance->shadowTreeElement()); 234 transferSizeAttributesToShadowTreeTargetClone(*m_targetElementInstance->shadowTreeElement()); 232 transferSizeAttributesToShadowTreeTargetClone(*shadowTreeTargetClone); 235 233 } 236 234 if (auto* renderer = this->renderer()) … … 314 312 void SVGUseElement::clearResourceReferences() 315 313 { 316 // FIXME: We should try to optimize this, to at least allow partial reclones.314 // FIXME: It's expensive to re-clone the entire tree every time. We should find a more efficient way to handle this. 317 315 if (ShadowRoot* root = userAgentShadowRoot()) 318 316 root->removeChildren(); 319 320 if (m_targetElementInstance) {321 m_targetElementInstance->detach();322 m_targetElementInstance = 0;323 }324 325 317 m_needsShadowTreeRecreation = false; 326 327 document().accessSVGExtensions().removeAllTargetReferencesForElement(this);328 318 } 329 319 330 320 void SVGUseElement::buildPendingResource() 331 321 { 332 if (!referencedDocument() || isInShadowTree()) 322 if (isInShadowTree()) 323 return; 324 if (!referencedDocument()) 333 325 return; 334 326 clearResourceReferences(); … … 338 330 String id; 339 331 Element* target = SVGURIReference::targetElementFromIRIString(href(), document(), &id, externalDocument()); 340 if (! target || !target->inDocument()) {341 // If we can't find the target of an external element, just give up.342 // We can't observe if the target somewhen enters the external document, nor should we do it.343 if (externalDocument())332 if (!isValidTarget(target)) { 333 if (externalDocument()) { 334 // We can't find the target in an external document, so just give up and don't try to do it again. 335 // We should not attempt to observe if an element with ID shows up in the external document later. 344 336 return; 345 if (id.isEmpty()) 346 return; 347 337 } 348 338 referencedDocument()->accessSVGExtensions().addPendingResource(id, this); 349 ASSERT(hasPendingResources()); 350 return; 351 } 352 353 if (target->isSVGElement()) { 354 buildShadowAndInstanceTree(downcast<SVGElement>(*target)); 355 invalidateDependentShadowTrees(); 356 } 357 339 return; 340 } 341 342 buildShadowTree(downcast<SVGElement>(*target)); 343 expandUseElementsInShadowTree(); 344 expandSymbolElementsInShadowTree(); 345 transferSizeAttributesToShadowTreeTargetClone(*shadowTreeTargetClone()); 346 transferEventListenersToShadowTree(); 347 updateRelativeLengthsInformation(); 348 349 // When we invalidate the other shadow trees, it's important that we don't 350 // follow any cycles and invalidate ourselves. To avoid that, we temporarily 351 // set m_needsShadowTreeRecreation to true so invalidateShadowTree will 352 // quickly return and do nothing. 358 353 ASSERT(!m_needsShadowTreeRecreation); 354 m_needsShadowTreeRecreation = true; 355 invalidateDependentShadowTrees(); 356 m_needsShadowTreeRecreation = false; 359 357 } 360 358 … … 365 363 return nullptr; 366 364 return downcast<SVGElement>(root->firstChild()); 367 }368 369 void SVGUseElement::buildShadowAndInstanceTree(SVGElement& target)370 {371 ASSERT(!m_targetElementInstance);372 373 // Do not build the shadow/instance tree for <use> elements living in a shadow tree.374 // The will be expanded soon anyway - see expandUseElementsInShadowTree().375 if (isInShadowTree())376 return;377 378 // Do not allow self-referencing.379 if (&target == this)380 return;381 382 // Build instance tree.383 // Spec: If the 'use' element references a simple graphics element such as a 'rect', then there is only a384 // single SVGElementInstance object, and the correspondingElement attribute on this SVGElementInstance object385 // is the SVGRectElement that corresponds to the referenced 'rect' element.386 m_targetElementInstance = SVGElementInstance::create(this, this, &target);387 388 // Eventually enter recursion to build SVGElementInstance objects for the sub-tree children389 bool foundProblem = false;390 buildInstanceTree(&target, m_targetElementInstance.get(), foundProblem, false);391 392 if (instanceTreeIsLoading(m_targetElementInstance.get()))393 return;394 395 // SVG specification does not say a word about <use> and cycles. My view on this is: just ignore it!396 // Non-appearing <use> content is easier to debug, then half-appearing content.397 if (foundProblem) {398 clearResourceReferences();399 return;400 }401 402 // Assure instance tree building was successful.403 ASSERT(m_targetElementInstance);404 ASSERT(!m_targetElementInstance->shadowTreeElement());405 ASSERT(m_targetElementInstance->correspondingUseElement() == this);406 ASSERT(m_targetElementInstance->directUseElement() == this);407 ASSERT(m_targetElementInstance->correspondingElement() == &target);408 409 if (isDisallowedElement(target)) {410 clearResourceReferences();411 return;412 }413 414 buildShadowTree(target);415 expandUseElementsInShadowTree();416 expandSymbolElementsInShadowTree();417 418 ASSERT(shadowTreeTargetClone());419 SVGElement& shadowTreeTargetClone = *this->shadowTreeTargetClone();420 associateInstancesWithShadowTreeElements(&shadowTreeTargetClone, m_targetElementInstance.get());421 422 transferSizeAttributesToShadowTreeTargetClone(shadowTreeTargetClone);423 424 transferEventListenersToShadowTree();425 updateRelativeLengthsInformation();426 365 } 427 366 … … 471 410 } 472 411 473 void SVGUseElement::buildInstanceTree(SVGElement* target, SVGElementInstance* targetInstance, bool& foundProblem, bool foundUse)474 {475 ASSERT(target);476 ASSERT(targetInstance);477 478 // Spec: If the referenced object is itself a 'use', or if there are 'use' subelements within the referenced479 // object, the instance tree will contain recursive expansion of the indirect references to form a complete tree.480 bool targetHasUseTag = target->hasTagName(SVGNames::useTag);481 SVGElement* newTarget = nullptr;482 if (targetHasUseTag) {483 foundProblem = hasCycleUseReferencing(downcast<SVGUseElement>(target), targetInstance, newTarget);484 if (foundProblem)485 return;486 487 // We only need to track first degree <use> dependencies. Indirect references are handled488 // as the invalidation bubbles up the dependency chain.489 if (!foundUse) {490 document().accessSVGExtensions().addElementReferencingTarget(this, target);491 foundUse = true;492 }493 } else if (isDisallowedElement(*target)) {494 foundProblem = true;495 return;496 }497 498 // A general description from the SVG spec, describing what buildInstanceTree() actually does.499 //500 // Spec: If the 'use' element references a 'g' which contains two 'rect' elements, then the instance tree501 // contains three SVGElementInstance objects, a root SVGElementInstance object whose correspondingElement502 // is the SVGGElement object for the 'g', and then two child SVGElementInstance objects, each of which has503 // its correspondingElement that is an SVGRectElement object.504 505 for (auto& element : childrenOfType<SVGElement>(*target)) {506 // Skip any non-svg nodes or any disallowed element.507 if (isDisallowedElement(element))508 continue;509 510 // Create SVGElementInstance object, for both container/non-container nodes.511 RefPtr<SVGElementInstance> instance = SVGElementInstance::create(this, 0, &element);512 SVGElementInstance* instancePtr = instance.get();513 targetInstance->appendChild(instance.release());514 515 // Enter recursion, appending new instance tree nodes to the "instance" object.516 buildInstanceTree(&element, instancePtr, foundProblem, foundUse);517 if (foundProblem)518 return;519 }520 521 if (!targetHasUseTag || !newTarget)522 return;523 524 RefPtr<SVGElementInstance> newInstance = SVGElementInstance::create(this, downcast<SVGUseElement>(target), newTarget);525 SVGElementInstance* newInstancePtr = newInstance.get();526 targetInstance->appendChild(newInstance.release());527 buildInstanceTree(newTarget, newInstancePtr, foundProblem, foundUse);528 }529 530 bool SVGUseElement::hasCycleUseReferencing(SVGUseElement* use, SVGElementInstance* targetInstance, SVGElement*& newTarget)531 {532 ASSERT(referencedDocument());533 Element* targetElement = SVGURIReference::targetElementFromIRIString(use->href(), *referencedDocument());534 newTarget = nullptr;535 if (targetElement && targetElement->isSVGElement())536 newTarget = downcast<SVGElement>(targetElement);537 538 if (!newTarget)539 return false;540 541 // Shortcut for self-references542 if (newTarget == this)543 return true;544 545 AtomicString targetId = newTarget->getIdAttribute();546 SVGElementInstance* instance = targetInstance->parentNode();547 while (instance) {548 SVGElement* element = instance->correspondingElement();549 550 if (element->hasID() && element->getIdAttribute() == targetId && &element->document() == &newTarget->document())551 return true;552 553 instance = instance->parentNode();554 }555 return false;556 }557 558 412 static void removeDisallowedElementsFromSubtree(SVGElement& subtree) 559 413 { … … 581 435 } 582 436 437 static void associateClonesWithOriginals(SVGElement& clone, SVGElement& original) 438 { 439 // This assertion checks that we don't call this with the arguments backwards. 440 // The clone is new and so it's not installed in a parent yet. 441 ASSERT(!clone.parentNode()); 442 443 // The loop below works because we are associating these clones immediately, before 444 // doing transformations like removing disallowed elements or expanding elements. 445 clone.setCorrespondingElement(&original); 446 for (auto pair : descendantsOfType<SVGElement>(clone, original)) 447 pair.first.setCorrespondingElement(&pair.second); 448 } 449 450 static void associateReplacementCloneWithOriginal(SVGElement& replacementClone, SVGElement& originalClone) 451 { 452 SVGElement* correspondingElement = originalClone.correspondingElement(); 453 ASSERT(correspondingElement); 454 originalClone.setCorrespondingElement(nullptr); 455 replacementClone.setCorrespondingElement(correspondingElement); 456 } 457 458 static void associateReplacementClonesWithOriginals(SVGElement& replacementClone, SVGElement& originalClone) 459 { 460 // This assertion checks that we don't call this with the arguments backwards. 461 // The replacement clone is new and so it's not installed in a parent yet. 462 ASSERT(!replacementClone.parentNode()); 463 464 // The loop below works because we are associating these clones immediately, before 465 // doing transformations like removing disallowed elements or expanding elements. 466 associateReplacementCloneWithOriginal(replacementClone, originalClone); 467 for (auto pair : descendantsOfType<SVGElement>(replacementClone, originalClone)) 468 associateReplacementCloneWithOriginal(pair.first, pair.second); 469 } 470 583 471 void SVGUseElement::buildShadowTree(SVGElement& target) 584 472 { 585 473 Ref<SVGElement> clonedTarget = static_pointer_cast<SVGElement>(target.cloneElementWithChildren(document())).releaseNonNull(); 474 associateClonesWithOriginals(clonedTarget.get(), target); 586 475 removeDisallowedElementsFromSubtree(clonedTarget.get()); 587 476 ensureUserAgentShadowRoot().appendChild(WTF::move(clonedTarget)); 588 477 } 589 478 479 bool SVGUseElement::isValidTarget(Element* target) const 480 { 481 if (!is<SVGElement>(target)) 482 return false; 483 if (!target->inDocument()) 484 return false; 485 SVGElement& castedTarget = downcast<SVGElement>(*target); 486 if (&castedTarget == this) 487 return false; 488 if (isDisallowedElement(castedTarget)) 489 return false; 490 // Reject any target that would create a cycle. 491 for (auto& ancestor : lineageOfType<SVGElement>(*this)) { 492 if (ancestor.correspondingElement() == &castedTarget) 493 return false; 494 } 495 return true; 496 } 497 590 498 void SVGUseElement::expandUseElementsInShadowTree() 591 499 { 592 // Why expand the <use> elements in the shadow tree here, and not just593 // do this directly in buildShadowTree, as we encounter each <use> element? 594 // Because we might miss expanding some elements if we did it then. If a <symbol>595 // contained <use> elements, we'd miss those.500 // FIXME: Combine this with buildShadowTree. 501 502 if (cachedDocumentIsStillLoading()) 503 return; 596 504 597 505 auto descendants = descendantsOfType<SVGUseElement>(*userAgentShadowRoot()); … … 601 509 it = end; // Efficiently quiets assertions due to the outstanding iterator. 602 510 603 ASSERT(!original->cachedDocumentIsStillLoading()); 511 if (original->cachedDocumentIsStillLoading()) 512 return; 604 513 605 514 // Spec: In the generated content, the 'use' will be replaced by 'g', where all attributes from the … … 611 520 ASSERT(referencedDocument()); 612 521 auto replacement = SVGGElement::create(SVGNames::gTag, *referencedDocument()); 613 614 522 original->transferAttributesToShadowTreeReplacement(replacement.get()); 615 523 original->cloneChildNodes(replacement.ptr()); 524 associateReplacementClonesWithOriginals(replacement.get(), original.get()); 616 525 617 526 RefPtr<SVGElement> clonedTarget; 618 527 Element* targetCandidate = SVGURIReference::targetElementFromIRIString(original->href(), *referencedDocument()); 619 if ( is<SVGElement>(targetCandidate) && !isDisallowedElement(downcast<SVGElement>(*targetCandidate))) {528 if (original->isValidTarget(targetCandidate)) { 620 529 SVGElement& originalTarget = downcast<SVGElement>(*targetCandidate); 621 530 clonedTarget = static_pointer_cast<SVGElement>(originalTarget.cloneElementWithChildren(document())); 622 // Set the corresponding element here so transferSizeAttributesToShadowTreeTargetClone 623 // can use it. It will be set again later in associateInstancesWithShadowTreeElements, 624 // but it does no harm to set it twice. 625 clonedTarget->setCorrespondingElement(&originalTarget); 531 associateClonesWithOriginals(*clonedTarget, originalTarget); 626 532 replacement->appendChild(clonedTarget); 627 533 } … … 664 570 replacement->cloneDataFromElement(original); 665 571 original.cloneChildNodes(replacement.ptr()); 572 associateReplacementClonesWithOriginals(replacement.get(), original); 573 666 574 removeDisallowedElementsFromSubtree(replacement.get()); 667 575 … … 684 592 } 685 593 686 void SVGUseElement::associateInstancesWithShadowTreeElements(Node* target, SVGElementInstance* targetInstance)687 {688 if (!target || !targetInstance)689 return;690 691 SVGElement* originalElement = targetInstance->correspondingElement();692 693 if (originalElement->hasTagName(SVGNames::useTag)) {694 // <use> gets replaced by <g>695 ASSERT(target->nodeName() == SVGNames::gTag);696 } else if (originalElement->hasTagName(SVGNames::symbolTag)) {697 // <symbol> gets replaced by <svg>698 ASSERT(target->nodeName() == SVGNames::svgTag);699 } else700 ASSERT(target->nodeName() == originalElement->nodeName());701 702 SVGElement* element = nullptr;703 if (target->isSVGElement())704 element = downcast<SVGElement>(target);705 706 ASSERT(!targetInstance->shadowTreeElement());707 targetInstance->setShadowTreeElement(element);708 element->setCorrespondingElement(originalElement);709 710 Node* node = target->firstChild();711 for (SVGElementInstance* instance = targetInstance->firstChild(); node && instance; instance = instance->nextSibling()) {712 // Skip any non-svg elements in shadow tree713 while (node && !node->isSVGElement())714 node = node->nextSibling();715 716 if (!node)717 break;718 719 associateInstancesWithShadowTreeElements(node, instance);720 node = node->nextSibling();721 }722 }723 724 SVGElementInstance* SVGUseElement::instanceForShadowTreeElement(Node* element) const725 {726 if (!m_targetElementInstance) {727 ASSERT(!inDocument());728 return 0;729 }730 731 return instanceForShadowTreeElement(element, m_targetElementInstance.get());732 }733 734 SVGElementInstance* SVGUseElement::instanceForShadowTreeElement(Node* element, SVGElementInstance* instance) const735 {736 ASSERT(element);737 ASSERT(instance);738 739 // We're dispatching a mutation event during shadow tree construction740 // this instance hasn't yet been associated to a shadowTree element.741 if (!instance->shadowTreeElement())742 return 0;743 744 if (element == instance->shadowTreeElement())745 return instance;746 747 for (SVGElementInstance* current = instance->firstChild(); current; current = current->nextSibling()) {748 if (SVGElementInstance* search = instanceForShadowTreeElement(element, current))749 return search;750 }751 752 return 0;753 }754 755 594 void SVGUseElement::invalidateShadowTree() 756 595 { … … 764 603 void SVGUseElement::invalidateDependentShadowTrees() 765 604 { 766 // Recursively invalidate dependent <use> shadow trees767 605 for (auto* instance : instances()) { 768 606 if (SVGUseElement* element = instance->correspondingUseElement()) { -
trunk/Source/WebCore/svg/SVGUseElement.h
r179391 r179807 35 35 36 36 class CachedSVGDocument; 37 class SVGElementInstance;38 37 class SVGGElement; 39 38 … … 46 45 virtual ~SVGUseElement(); 47 46 48 SVGElementInstance* instanceForShadowTreeElement(Node*) const;49 47 void invalidateShadowTree(); 50 48 void invalidateDependentShadowTrees(); … … 74 72 75 73 void clearResourceReferences(); 76 void buildShadowAndInstanceTree(SVGElement& target);77 void detachInstance();78 74 79 75 virtual bool haveLoadedRequiredResources() override { return SVGExternalResourcesRequired::haveLoadedRequiredResources(); } … … 81 77 virtual void finishParsingChildren() override; 82 78 virtual bool selfHasRelativeLengths() const override; 83 84 // Instance tree handling85 void buildInstanceTree(SVGElement* target, SVGElementInstance* targetInstance, bool& foundCycle, bool foundUse);86 bool hasCycleUseReferencing(SVGUseElement*, SVGElementInstance* targetInstance, SVGElement*& newTarget);87 79 88 80 // Shadow tree handling. … … 94 86 void transferAttributesToShadowTreeReplacement(SVGGElement&) const; 95 87 void transferSizeAttributesToShadowTreeTargetClone(SVGElement&) const; 96 97 // "Tree connector" 98 void associateInstancesWithShadowTreeElements(Node* target, SVGElementInstance* targetInstance); 99 SVGElementInstance* instanceForShadowTreeElement(Node* element, SVGElementInstance* instance) const; 88 bool isValidTarget(Element*) const; 100 89 101 90 BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGUseElement) … … 124 113 bool m_haveFiredLoadEvent; 125 114 bool m_needsShadowTreeRecreation; 126 RefPtr<SVGElementInstance> m_targetElementInstance;127 115 CachedResourceHandle<CachedSVGDocument> m_cachedDocument; 128 116 Timer m_svgLoadEventTimer;
Note:
See TracChangeset
for help on using the changeset viewer.