Changeset 19378 in webkit


Ignore:
Timestamp:
Feb 2, 2007 5:33:38 PM (17 years ago)
Author:
zimmermann
Message:

Reviewed by Eric & Maciej.

Fix serveral <use> issues:

  • When events are dispatch to a referenced element, the actual event.target

has to be set to the corresponding SVGElementInstance object

  • Node::shadowAncestorNode() should _not_ return the shadowParentNode for SVG elements

This is only needed for the HTML forms concept and breaks event dispatching for SVG shadow tree elements.

  • Add SVGElementInstance as possible EventTarget in bindings/js/kjs_dom.cpp

(Now event.target returns the actual SVGElementInstance object for a shadow tree element)

Fixes: http://bugs.webkit.org/show_bug.cgi?id=12502 (Reproducible crash when browsing SVG map.)
Fixes: http://bugs.webkit.org/show_bug.cgi?id=12511 (<use> has event dispatching issues)

Added test: svg/custom/use-event-handler-on-use-element.svg
Added test: svg/custom/use-event-handler-on-referenced-element.svg
Added test: svg/custom/use-elementInstance-event-target.svg
Added test: svg/custom/use-elementInstance-methods.svg

Location:
trunk
Files:
16 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r19362 r19378  
     12007-02-03  Nikolas Zimmermann  <zimmermann@kde.org>
     2
     3        Reviewed by Eric & Maciej.
     4
     5        Add new SVG <use> tests regarding JS scripting.
     6        The use-elementInstance-event-target.svg basically works, but shows
     7        a repainting issue, which has to be tackled later.
     8
     9        * svg/custom/use-elementInstance-event-target-expected.checksum: Added.
     10        * svg/custom/use-elementInstance-event-target-expected.png: Added.
     11        * svg/custom/use-elementInstance-event-target-expected.txt: Added.
     12        * svg/custom/use-elementInstance-event-target.svg: Added.
     13        * svg/custom/use-elementInstance-methods-expected.checksum: Added.
     14        * svg/custom/use-elementInstance-methods-expected.png: Added.
     15        * svg/custom/use-elementInstance-methods-expected.txt: Added.
     16        * svg/custom/use-elementInstance-methods.svg: Added.
     17        * svg/custom/use-event-handler-on-referenced-element-expected.checksum: Added.
     18        * svg/custom/use-event-handler-on-referenced-element-expected.png: Added.
     19        * svg/custom/use-event-handler-on-referenced-element-expected.txt: Added.
     20        * svg/custom/use-event-handler-on-referenced-element.svg: Added.
     21        * svg/custom/use-event-handler-on-use-element-expected.checksum: Added.
     22        * svg/custom/use-event-handler-on-use-element-expected.png: Added.
     23        * svg/custom/use-event-handler-on-use-element-expected.txt: Added.
     24        * svg/custom/use-event-handler-on-use-element.svg: Added.
     25
    1262007-02-02  Eric Seidel  <eric@webkit.org>
    227
  • trunk/WebCore/ChangeLog

    r19376 r19378  
     12007-02-03  Nikolas Zimmermann  <zimmermann@kde.org>
     2
     3        Reviewed by Eric & Maciej.
     4
     5        Fix serveral <use> issues:
     6        - When events are dispatch to a referenced element, the actual event.target
     7          has to be set to the corresponding SVGElementInstance object
     8
     9        - Node::shadowAncestorNode() should _not_ return the shadowParentNode for SVG elements
     10          This is only needed for the HTML forms concept and breaks event dispatching for SVG shadow tree elements.
     11
     12        - Add SVGElementInstance as possible EventTarget in bindings/js/kjs_dom.cpp
     13          (Now event.target returns the actual SVGElementInstance object for a shadow tree element)
     14
     15        Fixes: http://bugs.webkit.org/show_bug.cgi?id=12502 (Reproducible crash when browsing SVG map.)
     16        Fixes: http://bugs.webkit.org/show_bug.cgi?id=12511 (<use> has event dispatching issues)
     17
     18        Added test: svg/custom/use-event-handler-on-use-element.svg
     19        Added test: svg/custom/use-event-handler-on-referenced-element.svg
     20        Added test: svg/custom/use-elementInstance-event-target.svg
     21        Added test: svg/custom/use-elementInstance-methods.svg
     22
     23        * bindings/js/kjs_dom.cpp:
     24        (KJS::toJS):
     25        * dom/EventTarget.cpp:
     26        (WebCore::EventTarget::toSVGElementInstance):
     27        * dom/EventTarget.h:
     28        * dom/EventTargetNode.cpp:
     29        (WebCore::EventTargetNode::handleLocalEvents):
     30        (WebCore::EventTargetNode::dispatchGenericEvent):
     31        (WebCore::EventTargetNode::dispatchEvent):
     32        * dom/EventTargetNode.h:
     33        * dom/Node.cpp:
     34        (WebCore::Node::shadowAncestorNode):
     35        * ksvg2/svg/SVGElement.cpp:
     36        (WebCore::shadowTreeParentElementForShadowTreeElement):
     37        (WebCore::SVGElement::dispatchEvent):
     38        * ksvg2/svg/SVGElement.h:
     39        * ksvg2/svg/SVGElementInstance.cpp:
     40        (WebCore::SVGElementInstance::toSVGElementInstance):
     41        * ksvg2/svg/SVGElementInstance.h:
     42        * ksvg2/svg/SVGUseElement.cpp:
     43        (WebCore::SVGUseElement::notifyAttributeChange):
     44        (WebCore::SVGUseElement::instanceForShadowTreeElement):
     45        * ksvg2/svg/SVGUseElement.h:
     46
    1472007-02-02  Oliver Hunt  <oliver@apple.com>
    248
  • trunk/WebCore/bindings/js/kjs_dom.cpp

    r18912 r19378  
    6666#ifdef SVG_SUPPORT
    6767#include "JSSVGDocument.h"
     68#include "JSSVGElementInstance.h"
    6869#include "JSSVGElementWrapperFactory.h"
    6970#include "SVGDocument.h"
     
    10441045        return interp->getDOMObject(xhr);
    10451046    }
    1046    
     1047
     1048#ifdef SVG_SUPPORT
     1049    SVGElementInstance* instance = target->toSVGElementInstance();
     1050    if (instance)
     1051        return toJS(exec, instance);
     1052#endif
     1053
    10471054    // There are two kinds of EventTargets: EventTargetNode and XMLHttpRequest.
     1055    // If SVG support is enabled, there is also SVGElementInstance.
    10481056    ASSERT(0);
    10491057    return jsNull();
  • trunk/WebCore/dom/EventTarget.cpp

    r19271 r19378  
    4646}
    4747
     48#ifdef SVG_SUPPORT
     49SVGElementInstance* EventTarget::toSVGElementInstance()
     50{
     51    return 0;
     52}
     53#endif
     54
    4855} // end namespace
  • trunk/WebCore/dom/EventTarget.h

    r19271 r19378  
    3838    class EventListener;
    3939    class EventTargetNode;
     40    class SVGElementInstance;
    4041    class XMLHttpRequest;
    41    
     42
    4243    typedef int ExceptionCode;
    4344
     
    4647        virtual EventTargetNode* toNode();
    4748        virtual XMLHttpRequest* toXMLHttpRequest();
     49
     50#ifdef SVG_SUPPORT
     51        virtual SVGElementInstance* toSVGElementInstance();
     52#endif
    4853
    4954        virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) = 0;
  • trunk/WebCore/dom/EventTargetNode.cpp

    r19327 r19378  
    163163   
    164164    RegisteredEventListenerList listenersCopy = *m_regdListeners;
    165     RegisteredEventListenerList::Iterator end = listenersCopy.end();   
    166    
     165    RegisteredEventListenerList::Iterator end = listenersCopy.end();
     166
    167167    for (RegisteredEventListenerList::Iterator it = listenersCopy.begin(); it != end; ++it)
    168168        if ((*it)->eventType() == evt->type() && (*it)->useCapture() == useCapture && !(*it)->removed())
     
    180180    DeprecatedPtrList<Node> nodeChain;
    181181    Node *n;
    182     for (n = this; n; n = n->parentNode()) {
     182
     183    // For SVG we have to dispatch "beyond" shadow tree boundaries.
     184    for (n = this; n; n = n->isShadowNode() ? n->shadowParentNode() : n->parentNode()) {
    183185        n->ref();
    184186        nodeChain.prepend(n);
     
    285287bool EventTargetNode::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec, bool tempEvent)
    286288{
     289    return dispatchEvent(e, ec, tempEvent, this);
     290}
     291
     292bool EventTargetNode::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec, bool tempEvent, EventTarget* target)
     293{
    287294    RefPtr<Event> evt(e);
    288295    ASSERT(!eventDispatchForbidden());
     
    291298        return false;
    292299    }
    293     evt->setTarget(this);
     300
     301    evt->setTarget(target);
    294302   
    295303    RefPtr<FrameView> view = document()->view();
  • trunk/WebCore/dom/EventTargetNode.h

    r19271 r19378  
    9696    using Node::deref;
    9797
     98private:
     99    friend class SVGElement;
     100    bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&, bool tempEvent, EventTarget* target);
     101 
    98102protected:
    99103    typedef DeprecatedValueList<RefPtr<RegisteredEventListener> > RegisteredEventListenerList;
  • trunk/WebCore/dom/Node.cpp

    r19364 r19378  
    10021002Node* Node::shadowAncestorNode()
    10031003{
     1004#ifdef SVG_SUPPORT
     1005    // SVG elements living in a shadow tree only occour when <use> created them.
     1006    // For these cases we do NOT want to return the shadowParentNode() here
     1007    // but the actual shadow tree element - as main difference to the HTML forms
     1008    // shadow tree concept. (This function _could_ be made virtual - opinions?)
     1009    if (isSVGElement())
     1010        return this;
     1011#endif
     1012
    10041013    Node *n = this;   
    10051014    while (n) {
  • trunk/WebCore/ksvg2/svg/SVGElement.cpp

    r19254 r19378  
    11/*
    2     Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
     2    Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
    33                  2004, 2005, 2006 Rob Buis <buis@kde.org>
    44
     
    3434#include "PlatformString.h"
    3535#include "SVGDocumentExtensions.h"
     36#include "SVGElementInstance.h"
    3637#include "SVGNames.h"
    3738#include "SVGSVGElement.h"
    3839#include "SVGURIReference.h"
     40#include "SVGUseElement.h"
    3941#include "XMLNames.h"
    4042
     
    205207}
    206208
     209static Node* shadowTreeParentElementForShadowTreeElement(Node* node)
     210{
     211    for (Node* n = node; n; n = n->parentNode()) {
     212        if (n->isShadowNode())
     213            return n->shadowParentNode();
     214    }
     215
     216    return 0;
     217}
     218
     219bool SVGElement::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec, bool tempEvent)
     220{
     221    EventTarget* target = this;
     222    Node* useNode = shadowTreeParentElementForShadowTreeElement(this);
     223
     224    // If we are a hidden shadow tree element, the target must
     225    // point to our corresponding SVGElementInstance object
     226    if (useNode) {
     227        ASSERT(useNode->hasTagName(SVGNames::useTag));
     228        SVGUseElement* use = static_cast<SVGUseElement*>(useNode);
     229
     230        SVGElementInstance* instance = use->instanceForShadowTreeElement(this);
     231
     232        if (instance)
     233            target = instance;
     234    }
     235
     236    return EventTargetNode::dispatchEvent(e, ec, tempEvent, target);
     237}
     238
    207239}
    208240
  • trunk/WebCore/ksvg2/svg/SVGElement.h

    r19254 r19378  
    234234        ANIMATED_PROPERTY_EMPTY_DECLARATIONS(bool, false, ExternalResourcesRequired, externalResourcesRequired)
    235235
     236        virtual bool dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec, bool tempEvent = false);
     237
    236238    private:
    237239        void addSVGEventListener(const AtomicString& eventType, const Attribute*);
  • trunk/WebCore/ksvg2/svg/SVGElementInstance.cpp

    r19264 r19378  
    176176}
    177177
     178SVGElementInstance* SVGElementInstance::toSVGElementInstance()
     179{
     180    return this;
     181}
     182
    178183void SVGElementInstance::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool useCapture)
    179184{
  • trunk/WebCore/ksvg2/svg/SVGElementInstance.h

    r19254 r19378  
    6767        SVGElementInstance* parent() const { return m_parent; }
    6868
     69        virtual SVGElementInstance* toSVGElementInstance();
     70
    6971        virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
    7072        virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
  • trunk/WebCore/ksvg2/svg/SVGUseElement.cpp

    r19254 r19378  
    142142    // NOTE: A lot of room for improvments here. This is too slow.
    143143    // It has to be done correctly, by implementing attributeChanged().
    144     renderer()->setNeedsLayout(true);
    145144    const_cast<SVGUseElement*>(this)->buildPendingResource();
     145
     146    if (renderer())
     147        renderer()->setNeedsLayout(true);
    146148
    147149    SVGStyledElement::notifyAttributeChange();
     
    538540}
    539541
     542SVGElementInstance* SVGUseElement::instanceForShadowTreeElement(Node* element) const
     543{
     544    return instanceForShadowTreeElement(element, m_targetElementInstance.get());
     545}
     546
     547SVGElementInstance* SVGUseElement::instanceForShadowTreeElement(Node* element, SVGElementInstance* instance) const
     548{
     549    ASSERT(element);
     550    ASSERT(instance);
     551    ASSERT(instance->shadowTreeElement());
     552
     553    if (element == instance->shadowTreeElement())
     554        return instance;
     555
     556    for (SVGElementInstance* current = instance->firstChild(); current; current = current->nextSibling()) {
     557        SVGElementInstance* search = instanceForShadowTreeElement(element, current);
     558        if (search)
     559            return search;
     560    }
     561
     562    return 0;
     563}
     564
    540565void SVGUseElement::transferUseAttributesToReplacedElement(SVGElement* from, SVGElement* to) const
    541566{
  • trunk/WebCore/ksvg2/svg/SVGUseElement.h

    r19254 r19378  
    7878
    7979    private:
     80        friend class SVGElement;
     81        SVGElementInstance* instanceForShadowTreeElement(Node* element) const;
     82
     83    private:
    8084        // Instance tree handling
    8185        void buildInstanceTree(SVGElement* target, SVGElementInstance* targetInstance, bool& foundCycle);
     
    9094        void associateInstancesWithShadowTreeElements(Node* target, SVGElementInstance* targetInstance);
    9195
     96        SVGElementInstance* instanceForShadowTreeElement(Node* element, SVGElementInstance* instance) const;
    9297        void transferUseAttributesToReplacedElement(SVGElement* from, SVGElement* to) const;
    9398
Note: See TracChangeset for help on using the changeset viewer.