/*
* Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2011 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef SVGElementInstance_h
#define SVGElementInstance_h
#if ENABLE(SVG)
#include "EventTarget.h"
#include "SVGElement.h"
#include "TreeShared.h"
namespace WebCore {
namespace Private {
template<class GenericNode, class GenericNodeContainer>
void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer* container);
};
class SVGUseElement;
class SVGElementInstanceList;
// SVGElementInstance mimics Node, but without providing all its functionality
class SVGElementInstance : public TreeShared<SVGElementInstance>,
public EventTarget {
public:
static PassRefPtr<SVGElementInstance> create(SVGUseElement* correspondingUseElement, SVGUseElement* directUseElement, PassRefPtr<SVGElement> originalElement)
{
return adoptRef(new SVGElementInstance(correspondingUseElement, directUseElement, originalElement));
}
virtual ~SVGElementInstance();
virtual ScriptExecutionContext* scriptExecutionContext() const;
virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
virtual void removeAllEventListeners();
using EventTarget::dispatchEvent;
virtual bool dispatchEvent(PassRefPtr<Event>);
SVGElement* correspondingElement() const { return m_element.get(); }
SVGUseElement* correspondingUseElement() const { return m_correspondingUseElement; }
SVGUseElement* directUseElement() const { return m_directUseElement; }
SVGElement* shadowTreeElement() const { return m_shadowTreeElement.get(); }
void clearUseElements()
{
m_directUseElement = 0;
m_correspondingUseElement = 0;
}
SVGElementInstance* parentNode() const { return parent(); }
PassRefPtr<SVGElementInstanceList> childNodes();
SVGElementInstance* previousSibling() const { return m_previousSibling; }
SVGElementInstance* nextSibling() const { return m_nextSibling; }
SVGElementInstance* firstChild() const { return m_firstChild; }
SVGElementInstance* lastChild() const { return m_lastChild; }
Document* ownerDocument() const { return m_element ? m_element->ownerDocument() : 0; }
static void invalidateAllInstancesOfElement(SVGElement*);
using TreeShared<SVGElementInstance>::ref;
using TreeShared<SVGElementInstance>::deref;
// EventTarget API
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), abort);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), blur);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), change);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), click);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), contextmenu);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dblclick);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), error);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), focus);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), input);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keydown);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keypress);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keyup);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), load);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousedown);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousemove);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseout);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseover);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseup);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousewheel);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforecut);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), cut);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforecopy);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), copy);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforepaste);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), paste);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragenter);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragover);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragleave);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), drop);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragstart);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), drag);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragend);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), reset);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), resize);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), scroll);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), search);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), select);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), selectstart);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), submit);
DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), unload);
private:
friend class SVGUseElement;
SVGElementInstance(SVGUseElement*, SVGUseElement*, PassRefPtr<SVGElement> originalElement);
virtual Node* toNode() { return shadowTreeElement(); }
virtual SVGElementInstance* toSVGElementInstance() { return this; }
void appendChild(PassRefPtr<SVGElementInstance> child);
void setShadowTreeElement(SVGElement*);
template<class GenericNode, class GenericNodeContainer>
friend void appendChildToContainer(GenericNode* child, GenericNodeContainer* container);
template<class GenericNode, class GenericNodeContainer>
friend void removeAllChildrenInContainer(GenericNodeContainer* container);
template<class GenericNode, class GenericNodeContainer>
friend void Private::addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer* container);
bool hasChildNodes() const { return m_firstChild; }
void setFirstChild(SVGElementInstance* child) { m_firstChild = child; }
void setLastChild(SVGElementInstance* child) { m_lastChild = child; }
void setNextSibling(SVGElementInstance* sibling) { m_nextSibling = sibling; }
void setPreviousSibling(SVGElementInstance* sibling) { m_previousSibling = sibling; }
virtual void refEventTarget() { ref(); }
virtual void derefEventTarget() { deref(); }
virtual EventTargetData* eventTargetData();
virtual EventTargetData* ensureEventTargetData();
SVGUseElement* m_correspondingUseElement;
SVGUseElement* m_directUseElement;
RefPtr<SVGElement> m_element;
RefPtr<SVGElement> m_shadowTreeElement;
SVGElementInstance* m_previousSibling;
SVGElementInstance* m_nextSibling;
SVGElementInstance* m_firstChild;
SVGElementInstance* m_lastChild;
};
} // namespace WebCore
#endif // ENABLE(SVG)
#endif