18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2001 Peter Kelly (pmk@post.com) 38f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Copyright (C) 2003, 2008, 2009 Apple Inc. All rights reserved. 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Lesser General Public 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version. 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful, 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Lesser General Public License for more details. 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Lesser General Public 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License along with this library; if not, write to the Free Software 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef JSEventListener_h 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define JSEventListener_h 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "EventListener.h" 245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "JSDOMWindow.h" 252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include <heap/Weak.h> 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project class JSDOMGlobalObject; 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian class JSEventListener : public EventListener { 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project public: 338a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block static PassRefPtr<JSEventListener> create(JSC::JSObject* listener, JSC::JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld) 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 358a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return adoptRef(new JSEventListener(listener, wrapper, isAttribute, isolatedWorld)); 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 37231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 38231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block static const JSEventListener* cast(const EventListener* listener) 39231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block { 40231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return listener->type() == JSEventListenerType 41231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ? static_cast<const JSEventListener*>(listener) 42231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block : 0; 43231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 44231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian virtual ~JSEventListener(); 46231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 47231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block virtual bool operator==(const EventListener& other); 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Returns true if this event listener was created for an event handler attribute, like "onload" or "onclick". 505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool isAttribute() const { return m_isAttribute; } 518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 528a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block JSC::JSObject* jsFunction(ScriptExecutionContext*) const; 538a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block DOMWrapperWorld* isolatedWorld() const { return m_isolatedWorld.get(); } 548a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 558a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block JSC::JSObject* wrapper() const { return m_wrapper.get(); } 5681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch void setWrapper(JSC::JSGlobalData& globalData, JSC::JSObject* wrapper) const { m_wrapper.set(globalData, wrapper, 0); } 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian private: 598a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block virtual JSC::JSObject* initializeJSFunction(ScriptExecutionContext*) const; 600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch virtual void markJSFunction(JSC::MarkStack&); 615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian virtual bool virtualisAttribute() const; 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project protected: 648a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block JSEventListener(JSC::JSObject* function, JSC::JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld); 65ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch virtual void handleEvent(ScriptExecutionContext*, Event*); 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 678a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block private: 682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block mutable JSC::WriteBarrier<JSC::JSObject> m_jsFunction; 692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch mutable JSC::Weak<JSC::JSObject> m_wrapper; 708a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool m_isAttribute; 72cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block RefPtr<DOMWrapperWorld> m_isolatedWorld; 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project }; 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 758a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block inline JSC::JSObject* JSEventListener::jsFunction(ScriptExecutionContext* scriptExecutionContext) const 768a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block { 778a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block if (!m_jsFunction) 782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_jsFunction.set(*scriptExecutionContext->globalData(), m_wrapper.get(), initializeJSFunction(scriptExecutionContext)); 798a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 808a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block // Verify that we have a valid wrapper protecting our function from 818a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block // garbage collection. 828a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block ASSERT(m_wrapper || !m_jsFunction); 838a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block if (!m_wrapper) 848a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return 0; 858a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 868a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block // Try to verify that m_jsFunction wasn't recycled. (Not exact, since an 878a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block // event listener can be almost anything, but this makes test-writing easier). 882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ASSERT(!m_jsFunction || static_cast<JSC::JSCell*>(m_jsFunction.get())->isObject()); 898a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return m_jsFunction.get(); 918a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 928a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 93d0825bca7fe65beaee391d30da42e937db621564Steve Block // Creates a JS EventListener for an "onXXX" event attribute. 948a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block inline PassRefPtr<JSEventListener> createJSAttributeEventListener(JSC::ExecState* exec, JSC::JSValue listener, JSC::JSObject* wrapper) 95d0825bca7fe65beaee391d30da42e937db621564Steve Block { 96d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!listener.isObject()) 97d0825bca7fe65beaee391d30da42e937db621564Steve Block return 0; 98d0825bca7fe65beaee391d30da42e937db621564Steve Block 998a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return JSEventListener::create(asObject(listener), wrapper, true, currentWorld(exec)); 100d0825bca7fe65beaee391d30da42e937db621564Steve Block } 101d0825bca7fe65beaee391d30da42e937db621564Steve Block 102d0825bca7fe65beaee391d30da42e937db621564Steve Block 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif // JSEventListener_h 106