| 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 { | 525 { |
| 526 // This function is provided for use by SVGAnimatedProperty to avoid | 526 // This function is provided for use by SVGAnimatedProperty to avoid |
| 527 // global inclusion of core/dom/Document.h in SVG code. | 527 // global inclusion of core/dom/Document.h in SVG code. |
| 528 return document().accessSVGExtensions(); | 528 return document().accessSVGExtensions(); |
| 529 } | 529 } |
| 530 | 530 |
| 531 void SVGElement::mapInstanceToElement(SVGElementInstance* instance) | 531 void SVGElement::mapInstanceToElement(SVGElementInstance* instance) |
| 532 { | 532 { |
| 533 ASSERT(instance); | 533 ASSERT(instance); |
| 534 | 534 |
| 535 HashSet<SVGElementInstance*>& instances = ensureSVGRareData()->elementInstan
ces(); | 535 HashSet<SVGElement*>& instances = ensureSVGRareData()->elementInstances(); |
| 536 ASSERT(!instances.contains(instance)); | 536 ASSERT(!instances.contains(instance->shadowTreeElement())); |
| 537 | 537 |
| 538 instances.add(instance); | 538 instances.add(instance->shadowTreeElement()); |
| 539 } | 539 } |
| 540 | 540 |
| 541 void SVGElement::removeInstanceMapping(SVGElementInstance* instance) | 541 void SVGElement::removeInstanceMapping(SVGElementInstance* instance) |
| 542 { | 542 { |
| 543 ASSERT(instance); | 543 ASSERT(instance); |
| 544 ASSERT(hasSVGRareData()); | 544 ASSERT(hasSVGRareData()); |
| 545 | 545 |
| 546 HashSet<SVGElementInstance*>& instances = svgRareData()->elementInstances(); | 546 if (!instance->shadowTreeElement()) |
| 547 ASSERT(instances.contains(instance)); | 547 return; |
| 548 | 548 |
| 549 instances.remove(instance); | 549 HashSet<SVGElement*>& instances = svgRareData()->elementInstances(); |
| 550 ASSERT(instances.contains(instance->shadowTreeElement())); |
| 551 |
| 552 instances.remove(instance->shadowTreeElement()); |
| 550 } | 553 } |
| 551 | 554 |
| 552 const HashSet<SVGElementInstance*>& SVGElement::instancesForElement() const | 555 const HashSet<SVGElement*>& SVGElement::instancesForElement() const |
| 553 { | 556 { |
| 554 if (!hasSVGRareData()) { | 557 if (!hasSVGRareData()) { |
| 555 DEFINE_STATIC_LOCAL(HashSet<SVGElementInstance*>, emptyInstances, ()); | 558 DEFINE_STATIC_LOCAL(HashSet<SVGElement*>, emptyInstances, ()); |
| 556 return emptyInstances; | 559 return emptyInstances; |
| 557 } | 560 } |
| 558 return svgRareData()->elementInstances(); | 561 return svgRareData()->elementInstances(); |
| 559 } | 562 } |
| 560 | 563 |
| 561 bool SVGElement::getBoundingBox(FloatRect& rect) | 564 bool SVGElement::getBoundingBox(FloatRect& rect) |
| 562 { | 565 { |
| 563 if (!isSVGGraphicsElement()) | 566 if (!isSVGGraphicsElement()) |
| 564 return false; | 567 return false; |
| 565 | 568 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 606 svgRareData()->setCursorImageValue(0); | 609 svgRareData()->setCursorImageValue(0); |
| 607 } | 610 } |
| 608 #endif | 611 #endif |
| 609 | 612 |
| 610 SVGElement* SVGElement::correspondingElement() | 613 SVGElement* SVGElement::correspondingElement() |
| 611 { | 614 { |
| 612 ASSERT(!hasSVGRareData() || !svgRareData()->correspondingElement() || contai
ningShadowRoot()); | 615 ASSERT(!hasSVGRareData() || !svgRareData()->correspondingElement() || contai
ningShadowRoot()); |
| 613 return hasSVGRareData() ? svgRareData()->correspondingElement() : 0; | 616 return hasSVGRareData() ? svgRareData()->correspondingElement() : 0; |
| 614 } | 617 } |
| 615 | 618 |
| 619 SVGUseElement* SVGElement::correspondingUseElement() const |
| 620 { |
| 621 if (ShadowRoot* root = containingShadowRoot()) { |
| 622 if (isSVGUseElement(root->host()) && (root->type() == ShadowRoot::UserAg
entShadowRoot)) |
| 623 return toSVGUseElement(root->host()); |
| 624 } |
| 625 return 0; |
| 626 } |
| 627 |
| 616 void SVGElement::setCorrespondingElement(SVGElement* correspondingElement) | 628 void SVGElement::setCorrespondingElement(SVGElement* correspondingElement) |
| 617 { | 629 { |
| 618 ensureSVGRareData()->setCorrespondingElement(correspondingElement); | 630 ensureSVGRareData()->setCorrespondingElement(correspondingElement); |
| 619 } | 631 } |
| 620 | 632 |
| 621 bool SVGElement::inUseShadowTree() const | 633 bool SVGElement::inUseShadowTree() const |
| 622 { | 634 { |
| 623 if (ShadowRoot* root = containingShadowRoot()) | 635 return correspondingUseElement(); |
| 624 return isSVGUseElement(root->host()) && (root->type() == ShadowRoot::Use
rAgentShadowRoot); | |
| 625 return false; | |
| 626 } | 636 } |
| 627 | 637 |
| 628 bool SVGElement::supportsSpatialNavigationFocus() const | 638 bool SVGElement::supportsSpatialNavigationFocus() const |
| 629 { | 639 { |
| 630 // This function checks whether the element satisfies the extended criteria | 640 // This function checks whether the element satisfies the extended criteria |
| 631 // for the element to be focusable, introduced by spatial navigation feature
, | 641 // for the element to be focusable, introduced by spatial navigation feature
, |
| 632 // i.e. checks if click or keyboard event handler is specified. | 642 // i.e. checks if click or keyboard event handler is specified. |
| 633 // This is the way to make it possible to navigate to (focus) elements | 643 // This is the way to make it possible to navigate to (focus) elements |
| 634 // which web designer meant for being active (made them respond to click eve
nts). | 644 // which web designer meant for being active (made them respond to click eve
nts). |
| 635 | 645 |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 768 | 778 |
| 769 bool SVGElement::haveLoadedRequiredResources() | 779 bool SVGElement::haveLoadedRequiredResources() |
| 770 { | 780 { |
| 771 for (SVGElement* child = Traversal<SVGElement>::firstChild(*this); child; ch
ild = Traversal<SVGElement>::nextSibling(*child)) { | 781 for (SVGElement* child = Traversal<SVGElement>::firstChild(*this); child; ch
ild = Traversal<SVGElement>::nextSibling(*child)) { |
| 772 if (!child->haveLoadedRequiredResources()) | 782 if (!child->haveLoadedRequiredResources()) |
| 773 return false; | 783 return false; |
| 774 } | 784 } |
| 775 return true; | 785 return true; |
| 776 } | 786 } |
| 777 | 787 |
| 778 static inline void collectInstancesForSVGElement(SVGElement* element, HashSet<SV
GElementInstance*>& instances) | 788 static inline void collectInstancesForSVGElement(SVGElement* element, HashSet<SV
GElement*>& instances) |
| 779 { | 789 { |
| 780 ASSERT(element); | 790 ASSERT(element); |
| 781 if (element->containingShadowRoot()) | 791 if (element->containingShadowRoot()) |
| 782 return; | 792 return; |
| 783 | 793 |
| 784 ASSERT(!element->instanceUpdatesBlocked()); | 794 ASSERT(!element->instanceUpdatesBlocked()); |
| 785 | 795 |
| 786 instances = element->instancesForElement(); | 796 instances = element->instancesForElement(); |
| 787 } | 797 } |
| 788 | 798 |
| 789 bool SVGElement::addEventListener(const AtomicString& eventType, PassRefPtr<Even
tListener> prpListener, bool useCapture) | 799 bool SVGElement::addEventListener(const AtomicString& eventType, PassRefPtr<Even
tListener> prpListener, bool useCapture) |
| 790 { | 800 { |
| 791 RefPtr<EventListener> listener = prpListener; | 801 RefPtr<EventListener> listener = prpListener; |
| 792 | 802 |
| 793 // Add event listener to regular DOM element | 803 // Add event listener to regular DOM element |
| 794 if (!Node::addEventListener(eventType, listener, useCapture)) | 804 if (!Node::addEventListener(eventType, listener, useCapture)) |
| 795 return false; | 805 return false; |
| 796 | 806 |
| 797 // Add event listener to all shadow tree DOM element instances | 807 // Add event listener to all shadow tree DOM element instances |
| 798 HashSet<SVGElementInstance*> instances; | 808 HashSet<SVGElement*> instances; |
| 799 collectInstancesForSVGElement(this, instances); | 809 collectInstancesForSVGElement(this, instances); |
| 800 const HashSet<SVGElementInstance*>::const_iterator end = instances.end(); | 810 const HashSet<SVGElement*>::const_iterator end = instances.end(); |
| 801 for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it
!= end; ++it) { | 811 for (HashSet<SVGElement*>::const_iterator it = instances.begin(); it != end;
++it) { |
| 802 ASSERT((*it)->shadowTreeElement()); | 812 bool result = (*it)->Node::addEventListener(eventType, listener, useCapt
ure); |
| 803 ASSERT((*it)->correspondingElement() == this); | |
| 804 | |
| 805 bool result = (*it)->shadowTreeElement()->Node::addEventListener(eventTy
pe, listener, useCapture); | |
| 806 ASSERT_UNUSED(result, result); | 813 ASSERT_UNUSED(result, result); |
| 807 } | 814 } |
| 808 | 815 |
| 809 return true; | 816 return true; |
| 810 } | 817 } |
| 811 | 818 |
| 812 bool SVGElement::removeEventListener(const AtomicString& eventType, EventListene
r* listener, bool useCapture) | 819 bool SVGElement::removeEventListener(const AtomicString& eventType, EventListene
r* listener, bool useCapture) |
| 813 { | 820 { |
| 814 HashSet<SVGElementInstance*> instances; | 821 HashSet<SVGElement*> instances; |
| 815 collectInstancesForSVGElement(this, instances); | 822 collectInstancesForSVGElement(this, instances); |
| 816 if (instances.isEmpty()) | 823 if (instances.isEmpty()) |
| 817 return Node::removeEventListener(eventType, listener, useCapture); | 824 return Node::removeEventListener(eventType, listener, useCapture); |
| 818 | 825 |
| 819 // EventTarget::removeEventListener creates a PassRefPtr around the given Ev
entListener | 826 // EventTarget::removeEventListener creates a PassRefPtr around the given Ev
entListener |
| 820 // object when creating a temporary RegisteredEventListener object used to l
ook up the | 827 // object when creating a temporary RegisteredEventListener object used to l
ook up the |
| 821 // event listener in a cache. If we want to be able to call removeEventListe
ner() multiple | 828 // event listener in a cache. If we want to be able to call removeEventListe
ner() multiple |
| 822 // times on different nodes, we have to delay its immediate destruction, whi
ch would happen | 829 // times on different nodes, we have to delay its immediate destruction, whi
ch would happen |
| 823 // after the first call below. | 830 // after the first call below. |
| 824 RefPtr<EventListener> protector(listener); | 831 RefPtr<EventListener> protector(listener); |
| 825 | 832 |
| 826 // Remove event listener from regular DOM element | 833 // Remove event listener from regular DOM element |
| 827 if (!Node::removeEventListener(eventType, listener, useCapture)) | 834 if (!Node::removeEventListener(eventType, listener, useCapture)) |
| 828 return false; | 835 return false; |
| 829 | 836 |
| 830 // Remove event listener from all shadow tree DOM element instances | 837 // Remove event listener from all shadow tree DOM element instances |
| 831 const HashSet<SVGElementInstance*>::const_iterator end = instances.end(); | 838 const HashSet<SVGElement*>::const_iterator end = instances.end(); |
| 832 for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it
!= end; ++it) { | 839 for (HashSet<SVGElement*>::const_iterator it = instances.begin(); it != end;
++it) { |
| 833 ASSERT((*it)->correspondingElement() == this); | 840 SVGElement* shadowTreeElement = *it; |
| 834 | |
| 835 SVGElement* shadowTreeElement = (*it)->shadowTreeElement(); | |
| 836 ASSERT(shadowTreeElement); | 841 ASSERT(shadowTreeElement); |
| 837 | 842 |
| 838 if (shadowTreeElement->Node::removeEventListener(eventType, listener, us
eCapture)) | 843 if (shadowTreeElement->Node::removeEventListener(eventType, listener, us
eCapture)) |
| 839 continue; | 844 continue; |
| 840 | 845 |
| 841 // This case can only be hit for event listeners created from markup | 846 // This case can only be hit for event listeners created from markup |
| 842 ASSERT(listener->wasCreatedFromMarkup()); | 847 ASSERT(listener->wasCreatedFromMarkup()); |
| 843 | 848 |
| 844 // If the event listener 'listener' has been created from markup and has
been fired before | 849 // If the event listener 'listener' has been created from markup and has
been fired before |
| 845 // then JSLazyEventListener::parseCode() has been called and m_jsFunctio
n of that listener | 850 // then JSLazyEventListener::parseCode() has been called and m_jsFunctio
n of that listener |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1142 animatableAttributes.add(SVGNames::zAttr); | 1147 animatableAttributes.add(SVGNames::zAttr); |
| 1143 } | 1148 } |
| 1144 | 1149 |
| 1145 if (name == classAttr) | 1150 if (name == classAttr) |
| 1146 return true; | 1151 return true; |
| 1147 | 1152 |
| 1148 return animatableAttributes.contains(name); | 1153 return animatableAttributes.contains(name); |
| 1149 } | 1154 } |
| 1150 #endif | 1155 #endif |
| 1151 } | 1156 } |
| OLD | NEW |