83d0d2ee9b8ccfdc4a008121c56a2a7681990f6c
[WebKit-https.git] / Source / WebCore / bindings / js / JSEventListener.h
1 /*
2  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
3  *  Copyright (C) 2003, 2008, 2009 Apple Inc. All rights reserved.
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Lesser General Public
7  *  License as published by the Free Software Foundation; either
8  *  version 2 of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public
16  *  License along with this library; if not, write to the Free Software
17  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19
20 #ifndef JSEventListener_h
21 #define JSEventListener_h
22
23 #include "EventListener.h"
24 #include "JSDOMWindow.h"
25 #include <runtime/WeakGCPtr.h>
26
27 namespace WebCore {
28
29     class JSDOMGlobalObject;
30
31     class JSEventListener : public EventListener {
32     public:
33         static PassRefPtr<JSEventListener> create(JSC::JSObject* listener, JSC::JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld)
34         {
35             return adoptRef(new JSEventListener(listener, wrapper, isAttribute, isolatedWorld));
36         }
37
38         static const JSEventListener* cast(const EventListener* listener)
39         {
40             return listener->type() == JSEventListenerType
41                 ? static_cast<const JSEventListener*>(listener)
42                 : 0;
43         }
44
45         virtual ~JSEventListener();
46
47         virtual bool operator==(const EventListener& other);
48
49         // Returns true if this event listener was created for an event handler attribute, like "onload" or "onclick".
50         bool isAttribute() const { return m_isAttribute; }
51
52         JSC::JSObject* jsFunction(ScriptExecutionContext*) const;
53         DOMWrapperWorld* isolatedWorld() const { return m_isolatedWorld.get(); }
54
55         JSC::JSObject* wrapper() const { return m_wrapper.get(); }
56         void setWrapper(JSC::JSObject* wrapper) const { m_wrapper = wrapper; }
57
58     private:
59         virtual JSC::JSObject* initializeJSFunction(ScriptExecutionContext*) const;
60         virtual void markJSFunction(JSC::MarkStack&);
61         virtual void invalidateJSFunction(JSC::JSObject*);
62         virtual bool virtualisAttribute() const;
63
64     protected:
65         JSEventListener(JSC::JSObject* function, JSC::JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld);
66         virtual void handleEvent(ScriptExecutionContext*, Event*);
67
68     private:
69         mutable JSC::JSObject* m_jsFunction;
70         mutable JSC::WeakGCPtr<JSC::JSObject> m_wrapper;
71
72         bool m_isAttribute;
73         RefPtr<DOMWrapperWorld> m_isolatedWorld;
74     };
75
76     inline JSC::JSObject* JSEventListener::jsFunction(ScriptExecutionContext* scriptExecutionContext) const
77     {
78         if (!m_jsFunction)
79             m_jsFunction = initializeJSFunction(scriptExecutionContext);
80
81         // Verify that we have a valid wrapper protecting our function from
82         // garbage collection.
83         ASSERT(m_wrapper || !m_jsFunction);
84         if (!m_wrapper)
85             return 0;
86
87         // Try to verify that m_jsFunction wasn't recycled. (Not exact, since an
88         // event listener can be almost anything, but this makes test-writing easier).
89         ASSERT(!m_jsFunction || static_cast<JSC::JSCell*>(m_jsFunction)->isObject());
90
91         return m_jsFunction;
92     }
93
94     inline void JSEventListener::invalidateJSFunction(JSC::JSObject* wrapper)
95     {
96         m_wrapper.clear(wrapper);
97     }
98
99     // Creates a JS EventListener for an "onXXX" event attribute.
100     inline PassRefPtr<JSEventListener> createJSAttributeEventListener(JSC::ExecState* exec, JSC::JSValue listener, JSC::JSObject* wrapper)
101     {
102         if (!listener.isObject())
103             return 0;
104
105         return JSEventListener::create(asObject(listener), wrapper, true, currentWorld(exec));
106     }
107
108
109 } // namespace WebCore
110
111 #endif // JSEventListener_h