initial import
[vuplus_webkit] / 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 <heap/Weak.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::JSGlobalData& globalData, JSC::JSObject* wrapper) const { m_wrapper.set(globalData, wrapper, 0); }
57
58     private:
59         virtual JSC::JSObject* initializeJSFunction(ScriptExecutionContext*) const;
60         virtual void visitJSFunction(JSC::SlotVisitor&);
61         virtual bool virtualisAttribute() const;
62
63     protected:
64         JSEventListener(JSC::JSObject* function, JSC::JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld);
65         virtual void handleEvent(ScriptExecutionContext*, Event*);
66
67     private:
68         mutable JSC::WriteBarrier<JSC::JSObject> m_jsFunction;
69         mutable JSC::Weak<JSC::JSObject> m_wrapper;
70
71         bool m_isAttribute;
72         RefPtr<DOMWrapperWorld> m_isolatedWorld;
73     };
74
75     inline JSC::JSObject* JSEventListener::jsFunction(ScriptExecutionContext* scriptExecutionContext) const
76     {
77         if (!m_jsFunction)
78             m_jsFunction.setMayBeNull(*scriptExecutionContext->globalData(), m_wrapper.get(), initializeJSFunction(scriptExecutionContext));
79
80         // Verify that we have a valid wrapper protecting our function from
81         // garbage collection.
82         ASSERT(m_wrapper || !m_jsFunction);
83         if (!m_wrapper)
84             return 0;
85
86         // Try to verify that m_jsFunction wasn't recycled. (Not exact, since an
87         // event listener can be almost anything, but this makes test-writing easier).
88         ASSERT(!m_jsFunction || static_cast<JSC::JSCell*>(m_jsFunction.get())->isObject());
89
90         return m_jsFunction.get();
91     }
92
93     // Creates a JS EventListener for an "onXXX" event attribute.
94     inline PassRefPtr<JSEventListener> createJSAttributeEventListener(JSC::ExecState* exec, JSC::JSValue listener, JSC::JSObject* wrapper)
95     {
96         if (!listener.isObject())
97             return 0;
98
99         return JSEventListener::create(asObject(listener), wrapper, true, currentWorld(exec));
100     }
101
102
103 } // namespace WebCore
104
105 #endif // JSEventListener_h