| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde
.org> | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde
.org> |
| 3 * Copyright (C) 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> | 3 * Copyright (C) 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> |
| 4 * Copyright (C) 2008 Apple Inc. All rights reserved. | 4 * Copyright (C) 2008 Apple Inc. All rights reserved. |
| 5 * Copyright (C) 2008 Alp Toker <alp@atoker.com> | 5 * Copyright (C) 2008 Alp Toker <alp@atoker.com> |
| 6 * Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au> | 6 * Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au> |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| (...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 525 // This function is provided for use by SVGAnimatedProperty to avoid | 525 // This function is provided for use by SVGAnimatedProperty to avoid |
| 526 // global inclusion of core/dom/Document.h in SVG code. | 526 // global inclusion of core/dom/Document.h in SVG code. |
| 527 return document().accessSVGExtensions(); | 527 return document().accessSVGExtensions(); |
| 528 } | 528 } |
| 529 | 529 |
| 530 void SVGElement::mapInstanceToElement(SVGElement* instance) | 530 void SVGElement::mapInstanceToElement(SVGElement* instance) |
| 531 { | 531 { |
| 532 ASSERT(instance); | 532 ASSERT(instance); |
| 533 ASSERT(instance->inUseShadowTree()); | 533 ASSERT(instance->inUseShadowTree()); |
| 534 | 534 |
| 535 HashSet<SVGElement*>& instances = ensureSVGRareData()->elementInstances(); | 535 WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instances = ensureSV
GRareData()->elementInstances(); |
| 536 ASSERT(!instances.contains(instance)); | 536 ASSERT(!instances.contains(instance)); |
| 537 | 537 |
| 538 instances.add(instance); | 538 instances.add(instance); |
| 539 } | 539 } |
| 540 | 540 |
| 541 void SVGElement::removeInstanceMapping(SVGElement* instance) | 541 void SVGElement::removeInstanceMapping(SVGElement* instance) |
| 542 { | 542 { |
| 543 ASSERT(instance); | 543 ASSERT(instance); |
| 544 ASSERT(instance->inUseShadowTree()); | 544 ASSERT(instance->inUseShadowTree()); |
| 545 ASSERT(hasSVGRareData()); | 545 ASSERT(hasSVGRareData()); |
| 546 | 546 |
| 547 HashSet<SVGElement*>& instances = svgRareData()->elementInstances(); | 547 WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instances = svgRareD
ata()->elementInstances(); |
| 548 ASSERT(instances.contains(instance)); | 548 ASSERT(instances.contains(instance)); |
| 549 | 549 |
| 550 instances.remove(instance); | 550 instances.remove(instance); |
| 551 } | 551 } |
| 552 | 552 |
| 553 const HashSet<SVGElement*>& SVGElement::instancesForElement() const | 553 static WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& emptyInstances() |
| 554 { | 554 { |
| 555 if (!hasSVGRareData()) { | 555 #if ENABLE(OILPAN) |
| 556 DEFINE_STATIC_LOCAL(HashSet<SVGElement*>, emptyInstances, ()); | 556 DEFINE_STATIC_LOCAL(Persistent<HeapHashSet<WeakMember<SVGElement> > >, empty
Instances, (new HeapHashSet<WeakMember<SVGElement> >)); |
| 557 return emptyInstances; | 557 return *emptyInstances; |
| 558 } | 558 #else |
| 559 DEFINE_STATIC_LOCAL(HashSet<RawPtr<SVGElement> >, emptyInstances, ()); |
| 560 return emptyInstances; |
| 561 #endif |
| 562 } |
| 563 |
| 564 const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& SVGElement::instan
cesForElement() const |
| 565 { |
| 566 if (!hasSVGRareData()) |
| 567 return emptyInstances(); |
| 559 return svgRareData()->elementInstances(); | 568 return svgRareData()->elementInstances(); |
| 560 } | 569 } |
| 561 | 570 |
| 562 bool SVGElement::getBoundingBox(FloatRect& rect) | 571 bool SVGElement::getBoundingBox(FloatRect& rect) |
| 563 { | 572 { |
| 564 if (!isSVGGraphicsElement()) | 573 if (!isSVGGraphicsElement()) |
| 565 return false; | 574 return false; |
| 566 | 575 |
| 567 rect = toSVGGraphicsElement(this)->getBBox(); | 576 rect = toSVGGraphicsElement(this)->getBBox(); |
| 568 return true; | 577 return true; |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 776 | 785 |
| 777 bool SVGElement::haveLoadedRequiredResources() | 786 bool SVGElement::haveLoadedRequiredResources() |
| 778 { | 787 { |
| 779 for (SVGElement* child = Traversal<SVGElement>::firstChild(*this); child; ch
ild = Traversal<SVGElement>::nextSibling(*child)) { | 788 for (SVGElement* child = Traversal<SVGElement>::firstChild(*this); child; ch
ild = Traversal<SVGElement>::nextSibling(*child)) { |
| 780 if (!child->haveLoadedRequiredResources()) | 789 if (!child->haveLoadedRequiredResources()) |
| 781 return false; | 790 return false; |
| 782 } | 791 } |
| 783 return true; | 792 return true; |
| 784 } | 793 } |
| 785 | 794 |
| 786 static inline void collectInstancesForSVGElement(SVGElement* element, HashSet<SV
GElement*>& instances) | 795 static inline void collectInstancesForSVGElement(SVGElement* element, WillBeHeap
HashSet<RawPtrWillBeWeakMember<SVGElement> >& instances) |
| 787 { | 796 { |
| 788 ASSERT(element); | 797 ASSERT(element); |
| 789 if (element->containingShadowRoot()) | 798 if (element->containingShadowRoot()) |
| 790 return; | 799 return; |
| 791 | 800 |
| 792 ASSERT(!element->instanceUpdatesBlocked()); | 801 ASSERT(!element->instanceUpdatesBlocked()); |
| 793 | 802 |
| 794 instances = element->instancesForElement(); | 803 instances = element->instancesForElement(); |
| 795 } | 804 } |
| 796 | 805 |
| 797 bool SVGElement::addEventListener(const AtomicString& eventType, PassRefPtr<Even
tListener> prpListener, bool useCapture) | 806 bool SVGElement::addEventListener(const AtomicString& eventType, PassRefPtr<Even
tListener> prpListener, bool useCapture) |
| 798 { | 807 { |
| 799 RefPtr<EventListener> listener = prpListener; | 808 RefPtr<EventListener> listener = prpListener; |
| 800 | 809 |
| 801 // Add event listener to regular DOM element | 810 // Add event listener to regular DOM element |
| 802 if (!Node::addEventListener(eventType, listener, useCapture)) | 811 if (!Node::addEventListener(eventType, listener, useCapture)) |
| 803 return false; | 812 return false; |
| 804 | 813 |
| 805 // Add event listener to all shadow tree DOM element instances | 814 // Add event listener to all shadow tree DOM element instances |
| 806 HashSet<SVGElement*> instances; | 815 WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> > instances; |
| 807 collectInstancesForSVGElement(this, instances); | 816 collectInstancesForSVGElement(this, instances); |
| 808 const HashSet<SVGElement*>::const_iterator end = instances.end(); | 817 const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator
end = instances.end(); |
| 809 for (HashSet<SVGElement*>::const_iterator it = instances.begin(); it != end;
++it) { | 818 for (WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator
it = instances.begin(); it != end; ++it) { |
| 810 bool result = (*it)->Node::addEventListener(eventType, listener, useCapt
ure); | 819 bool result = (*it)->Node::addEventListener(eventType, listener, useCapt
ure); |
| 811 ASSERT_UNUSED(result, result); | 820 ASSERT_UNUSED(result, result); |
| 812 } | 821 } |
| 813 | 822 |
| 814 return true; | 823 return true; |
| 815 } | 824 } |
| 816 | 825 |
| 817 bool SVGElement::removeEventListener(const AtomicString& eventType, EventListene
r* listener, bool useCapture) | 826 bool SVGElement::removeEventListener(const AtomicString& eventType, EventListene
r* listener, bool useCapture) |
| 818 { | 827 { |
| 819 HashSet<SVGElement*> instances; | 828 WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> > instances; |
| 820 collectInstancesForSVGElement(this, instances); | 829 collectInstancesForSVGElement(this, instances); |
| 821 if (instances.isEmpty()) | 830 if (instances.isEmpty()) |
| 822 return Node::removeEventListener(eventType, listener, useCapture); | 831 return Node::removeEventListener(eventType, listener, useCapture); |
| 823 | 832 |
| 824 // EventTarget::removeEventListener creates a PassRefPtr around the given Ev
entListener | 833 // EventTarget::removeEventListener creates a PassRefPtr around the given Ev
entListener |
| 825 // object when creating a temporary RegisteredEventListener object used to l
ook up the | 834 // object when creating a temporary RegisteredEventListener object used to l
ook up the |
| 826 // event listener in a cache. If we want to be able to call removeEventListe
ner() multiple | 835 // event listener in a cache. If we want to be able to call removeEventListe
ner() multiple |
| 827 // times on different nodes, we have to delay its immediate destruction, whi
ch would happen | 836 // times on different nodes, we have to delay its immediate destruction, whi
ch would happen |
| 828 // after the first call below. | 837 // after the first call below. |
| 829 RefPtr<EventListener> protector(listener); | 838 RefPtr<EventListener> protector(listener); |
| 830 | 839 |
| 831 // Remove event listener from regular DOM element | 840 // Remove event listener from regular DOM element |
| 832 if (!Node::removeEventListener(eventType, listener, useCapture)) | 841 if (!Node::removeEventListener(eventType, listener, useCapture)) |
| 833 return false; | 842 return false; |
| 834 | 843 |
| 835 // Remove event listener from all shadow tree DOM element instances | 844 // Remove event listener from all shadow tree DOM element instances |
| 836 const HashSet<SVGElement*>::const_iterator end = instances.end(); | 845 const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator
end = instances.end(); |
| 837 for (HashSet<SVGElement*>::const_iterator it = instances.begin(); it != end;
++it) { | 846 for (WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator
it = instances.begin(); it != end; ++it) { |
| 838 SVGElement* shadowTreeElement = *it; | 847 SVGElement* shadowTreeElement = *it; |
| 839 ASSERT(shadowTreeElement); | 848 ASSERT(shadowTreeElement); |
| 840 | 849 |
| 841 if (shadowTreeElement->Node::removeEventListener(eventType, listener, us
eCapture)) | 850 if (shadowTreeElement->Node::removeEventListener(eventType, listener, us
eCapture)) |
| 842 continue; | 851 continue; |
| 843 | 852 |
| 844 // This case can only be hit for event listeners created from markup | 853 // This case can only be hit for event listeners created from markup |
| 845 ASSERT(listener->wasCreatedFromMarkup()); | 854 ASSERT(listener->wasCreatedFromMarkup()); |
| 846 | 855 |
| 847 // If the event listener 'listener' has been created from markup and has
been fired before | 856 // If the event listener 'listener' has been created from markup and has
been fired before |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1032 } | 1041 } |
| 1033 | 1042 |
| 1034 void SVGElement::invalidateInstances() | 1043 void SVGElement::invalidateInstances() |
| 1035 { | 1044 { |
| 1036 if (!inDocument()) | 1045 if (!inDocument()) |
| 1037 return; | 1046 return; |
| 1038 | 1047 |
| 1039 if (instanceUpdatesBlocked()) | 1048 if (instanceUpdatesBlocked()) |
| 1040 return; | 1049 return; |
| 1041 | 1050 |
| 1042 const HashSet<SVGElement*>& set = instancesForElement(); | 1051 const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& set = instance
sForElement(); |
| 1043 if (set.isEmpty()) | 1052 if (set.isEmpty()) |
| 1044 return; | 1053 return; |
| 1045 | 1054 |
| 1046 // Mark all use elements referencing 'element' for rebuilding | 1055 // Mark all use elements referencing 'element' for rebuilding |
| 1047 const HashSet<SVGElement*>::const_iterator end = set.end(); | 1056 const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator
end = set.end(); |
| 1048 for (HashSet<SVGElement*>::const_iterator it = set.begin(); it != end; ++it)
{ | 1057 for (WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator
it = set.begin(); it != end; ++it) { |
| 1049 (*it)->setCorrespondingElement(0); | 1058 (*it)->setCorrespondingElement(0); |
| 1050 | 1059 |
| 1051 if (SVGUseElement* element = (*it)->correspondingUseElement()) { | 1060 if (SVGUseElement* element = (*it)->correspondingUseElement()) { |
| 1052 ASSERT(element->inDocument()); | 1061 ASSERT(element->inDocument()); |
| 1053 element->invalidateShadowTree(); | 1062 element->invalidateShadowTree(); |
| 1054 } | 1063 } |
| 1055 } | 1064 } |
| 1056 | 1065 |
| 1057 document().updateRenderTreeIfNeeded(); | 1066 document().updateRenderTreeIfNeeded(); |
| 1058 } | 1067 } |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1170 animatableAttributes.add(SVGNames::zAttr); | 1179 animatableAttributes.add(SVGNames::zAttr); |
| 1171 } | 1180 } |
| 1172 | 1181 |
| 1173 if (name == classAttr) | 1182 if (name == classAttr) |
| 1174 return true; | 1183 return true; |
| 1175 | 1184 |
| 1176 return animatableAttributes.contains(name); | 1185 return animatableAttributes.contains(name); |
| 1177 } | 1186 } |
| 1178 #endif | 1187 #endif |
| 1179 } | 1188 } |
| OLD | NEW |