summaryrefslogtreecommitdiffstats
path: root/WebCore/svg/SVGElementInstance.cpp
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:30:52 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:30:52 -0800
commit8e35f3cfc7fba1d1c829dc557ebad6409cbe16a2 (patch)
tree11425ea0b299d6fb89c6d3618a22d97d5bf68d0f /WebCore/svg/SVGElementInstance.cpp
parent648161bb0edfc3d43db63caed5cc5213bc6cb78f (diff)
downloadexternal_webkit-8e35f3cfc7fba1d1c829dc557ebad6409cbe16a2.zip
external_webkit-8e35f3cfc7fba1d1c829dc557ebad6409cbe16a2.tar.gz
external_webkit-8e35f3cfc7fba1d1c829dc557ebad6409cbe16a2.tar.bz2
auto import from //depot/cupcake/@135843
Diffstat (limited to 'WebCore/svg/SVGElementInstance.cpp')
-rw-r--r--WebCore/svg/SVGElementInstance.cpp572
1 files changed, 572 insertions, 0 deletions
diff --git a/WebCore/svg/SVGElementInstance.cpp b/WebCore/svg/SVGElementInstance.cpp
new file mode 100644
index 0000000..e548900
--- /dev/null
+++ b/WebCore/svg/SVGElementInstance.cpp
@@ -0,0 +1,572 @@
+/*
+ Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
+
+ This file is part of the KDE project
+
+ 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.
+*/
+
+#include "config.h"
+
+#if ENABLE(SVG)
+#include "SVGElementInstance.h"
+
+#include "ContainerNodeAlgorithms.h"
+#include "Document.h"
+#include "Event.h"
+#include "EventException.h"
+#include "EventListener.h"
+#include "EventNames.h"
+#include "FrameView.h"
+#include "GCController.h"
+#include "SVGElementInstanceList.h"
+#include "SVGUseElement.h"
+
+#include <wtf/RefCountedLeakCounter.h>
+
+namespace WebCore {
+
+#ifndef NDEBUG
+static WTF::RefCountedLeakCounter instanceCounter("WebCoreSVGElementInstance");
+#endif
+
+SVGElementInstance::SVGElementInstance(SVGUseElement* useElement, SVGElement* originalElement)
+ : m_needsUpdate(false)
+ , m_useElement(useElement)
+ , m_element(originalElement)
+ , m_previousSibling(0)
+ , m_nextSibling(0)
+ , m_firstChild(0)
+ , m_lastChild(0)
+{
+ ASSERT(m_useElement);
+ ASSERT(m_element);
+
+ // Register as instance for passed element.
+ m_element->mapInstanceToElement(this);
+
+#ifndef NDEBUG
+ instanceCounter.increment();
+#endif
+}
+
+SVGElementInstance::~SVGElementInstance()
+{
+#ifndef NDEBUG
+ instanceCounter.decrement();
+#endif
+
+ // Deregister as instance for passed element.
+ m_element->removeInstanceMapping(this);
+
+ removeAllChildrenInContainer<SVGElementInstance, SVGElementInstance>(this);
+}
+
+PassRefPtr<SVGElementInstanceList> SVGElementInstance::childNodes()
+{
+ return SVGElementInstanceList::create(this);
+}
+
+void SVGElementInstance::setShadowTreeElement(SVGElement* element)
+{
+ ASSERT(element);
+ m_shadowTreeElement = element;
+}
+
+void SVGElementInstance::forgetWrapper()
+{
+ // FIXME: This is fragile, as discussed with Sam. Need to find a better solution.
+ // Think about the case where JS explicitely holds "var root = useElement.instanceRoot;".
+ // We still have to recreate this wrapper somehow. The gc collection below, won't catch it.
+
+ // If the use shadow tree has been rebuilt, just the JSSVGElementInstance objects
+ // are still holding RefPtrs of SVGElementInstance objects, which prevent us to
+ // be deleted (and the shadow tree is not destructed as well). Force JS GC.
+ gcController().garbageCollectNow();
+}
+
+void SVGElementInstance::appendChild(PassRefPtr<SVGElementInstance> child)
+{
+ appendChildToContainer<SVGElementInstance, SVGElementInstance>(child.get(), this);
+}
+
+void SVGElementInstance::invalidateAllInstancesOfElement(SVGElement* element)
+{
+ if (!element)
+ return;
+
+ HashSet<SVGElementInstance*> set = element->instancesForElement();
+ if (set.isEmpty())
+ return;
+
+ // Find all use elements referencing the instances - ask them _once_ to rebuild.
+ HashSet<SVGElementInstance*>::const_iterator it = set.begin();
+ const HashSet<SVGElementInstance*>::const_iterator end = set.end();
+
+ for (; it != end; ++it)
+ (*it)->setNeedsUpdate(true);
+}
+
+void SVGElementInstance::setNeedsUpdate(bool value)
+{
+ m_needsUpdate = value;
+
+ if (m_needsUpdate)
+ correspondingUseElement()->setChanged();
+}
+
+ScriptExecutionContext* SVGElementInstance::scriptExecutionContext() const
+{
+ if (SVGElement* element = correspondingElement())
+ return element->scriptExecutionContext();
+ return 0;
+}
+
+void SVGElementInstance::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
+{
+ if (SVGElement* element = correspondingElement())
+ element->addEventListener(eventType, listener, useCapture);
+}
+
+void SVGElementInstance::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
+{
+ if (SVGElement* element = correspondingElement())
+ element->removeEventListener(eventType, listener, useCapture);
+}
+
+bool SVGElementInstance::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec)
+{
+ RefPtr<Event> evt(e);
+ ASSERT(!eventDispatchForbidden());
+ if (!evt || evt->type().isEmpty()) {
+ ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
+ return false;
+ }
+
+ // The event has to be dispatched to the shadowTreeElement(), not the correspondingElement()!
+ SVGElement* element = shadowTreeElement();
+ if (!element)
+ return false;
+
+ evt->setTarget(this);
+
+ RefPtr<FrameView> view = element->document()->view();
+ return element->dispatchGenericEvent(evt.release(), ec);
+}
+
+EventListener* SVGElementInstance::onabort() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().abortEvent);
+}
+
+void SVGElementInstance::setOnabort(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().abortEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onblur() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().blurEvent);
+}
+
+void SVGElementInstance::setOnblur(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().blurEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onchange() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().changeEvent);
+}
+
+void SVGElementInstance::setOnchange(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().changeEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onclick() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().clickEvent);
+}
+
+void SVGElementInstance::setOnclick(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().clickEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::oncontextmenu() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().contextmenuEvent);
+}
+
+void SVGElementInstance::setOncontextmenu(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().contextmenuEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::ondblclick() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().dblclickEvent);
+}
+
+void SVGElementInstance::setOndblclick(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().dblclickEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onerror() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().errorEvent);
+}
+
+void SVGElementInstance::setOnerror(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().errorEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onfocus() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().focusEvent);
+}
+
+void SVGElementInstance::setOnfocus(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().focusEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::oninput() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().inputEvent);
+}
+
+void SVGElementInstance::setOninput(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().inputEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onkeydown() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().keydownEvent);
+}
+
+void SVGElementInstance::setOnkeydown(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().keydownEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onkeypress() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().keypressEvent);
+}
+
+void SVGElementInstance::setOnkeypress(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().keypressEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onkeyup() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().keyupEvent);
+}
+
+void SVGElementInstance::setOnkeyup(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().keyupEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onload() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().loadEvent);
+}
+
+void SVGElementInstance::setOnload(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().loadEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onmousedown() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().mousedownEvent);
+}
+
+void SVGElementInstance::setOnmousedown(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().mousedownEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onmousemove() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().mousemoveEvent);
+}
+
+void SVGElementInstance::setOnmousemove(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().mousemoveEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onmouseout() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().mouseoutEvent);
+}
+
+void SVGElementInstance::setOnmouseout(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().mouseoutEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onmouseover() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().mouseoverEvent);
+}
+
+void SVGElementInstance::setOnmouseover(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().mouseoverEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onmouseup() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().mouseupEvent);
+}
+
+void SVGElementInstance::setOnmouseup(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().mouseupEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onmousewheel() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().mousewheelEvent);
+}
+
+void SVGElementInstance::setOnmousewheel(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().mousewheelEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onbeforecut() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().beforecutEvent);
+}
+
+void SVGElementInstance::setOnbeforecut(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().beforecutEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::oncut() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().cutEvent);
+}
+
+void SVGElementInstance::setOncut(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().cutEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onbeforecopy() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().beforecopyEvent);
+}
+
+void SVGElementInstance::setOnbeforecopy(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().beforecopyEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::oncopy() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().copyEvent);
+}
+
+void SVGElementInstance::setOncopy(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().copyEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onbeforepaste() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().beforepasteEvent);
+}
+
+void SVGElementInstance::setOnbeforepaste(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().beforepasteEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onpaste() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().pasteEvent);
+}
+
+void SVGElementInstance::setOnpaste(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().pasteEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::ondragenter() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().dragenterEvent);
+}
+
+void SVGElementInstance::setOndragenter(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().dragenterEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::ondragover() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().dragoverEvent);
+}
+
+void SVGElementInstance::setOndragover(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().dragoverEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::ondragleave() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().dragleaveEvent);
+}
+
+void SVGElementInstance::setOndragleave(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().dragleaveEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::ondrop() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().dropEvent);
+}
+
+void SVGElementInstance::setOndrop(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().dropEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::ondragstart() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().dragstartEvent);
+}
+
+void SVGElementInstance::setOndragstart(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().dragstartEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::ondrag() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().dragEvent);
+}
+
+void SVGElementInstance::setOndrag(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().dragEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::ondragend() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().dragendEvent);
+}
+
+void SVGElementInstance::setOndragend(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().dragendEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onreset() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().resetEvent);
+}
+
+void SVGElementInstance::setOnreset(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().resetEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onresize() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().resizeEvent);
+}
+
+void SVGElementInstance::setOnresize(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().resizeEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onscroll() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().scrollEvent);
+}
+
+void SVGElementInstance::setOnscroll(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().scrollEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onsearch() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().searchEvent);
+}
+
+void SVGElementInstance::setOnsearch(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().searchEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onselect() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().selectEvent);
+}
+
+void SVGElementInstance::setOnselect(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().selectEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onselectstart() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().selectstartEvent);
+}
+
+void SVGElementInstance::setOnselectstart(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().selectstartEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onsubmit() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().submitEvent);
+}
+
+void SVGElementInstance::setOnsubmit(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().submitEvent, eventListener);
+}
+
+EventListener* SVGElementInstance::onunload() const
+{
+ return correspondingElement()->inlineEventListenerForType(eventNames().unloadEvent);
+}
+
+void SVGElementInstance::setOnunload(PassRefPtr<EventListener> eventListener)
+{
+ correspondingElement()->setInlineEventListenerForType(eventNames().unloadEvent, eventListener);
+}
+
+}
+
+#endif // ENABLE(SVG)