2
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
3
* Copyright (C) 2003, 2008, 2009 Apple Inc. All rights reserved.
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.
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.
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
20
#ifndef JSEventListener_h
21
#define JSEventListener_h
23
#include "EventListener.h"
24
#include "JSDOMWindow.h"
25
#include <heap/StrongInlines.h>
26
#include <heap/Weak.h>
30
class JSDOMGlobalObject;
32
class JSEventListener : public EventListener {
34
static PassRefPtr<JSEventListener> create(JSC::JSObject* listener, JSC::JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld)
36
return adoptRef(new JSEventListener(listener, wrapper, isAttribute, isolatedWorld));
39
static const JSEventListener* cast(const EventListener* listener)
41
return listener->type() == JSEventListenerType
42
? static_cast<const JSEventListener*>(listener)
46
virtual ~JSEventListener();
48
virtual bool operator==(const EventListener& other);
50
// Returns true if this event listener was created for an event handler attribute, like "onload" or "onclick".
51
bool isAttribute() const { return m_isAttribute; }
53
JSC::JSObject* jsFunction(ScriptExecutionContext*) const;
54
DOMWrapperWorld* isolatedWorld() const { return m_isolatedWorld.get(); }
56
JSC::JSObject* wrapper() const { return m_wrapper.get(); }
57
void setWrapper(JSC::JSGlobalData&, JSC::JSObject* wrapper) const { m_wrapper = JSC::PassWeak<JSC::JSObject>(wrapper); }
60
virtual JSC::JSObject* initializeJSFunction(ScriptExecutionContext*) const;
61
virtual void visitJSFunction(JSC::SlotVisitor&);
62
virtual bool virtualisAttribute() const;
65
JSEventListener(JSC::JSObject* function, JSC::JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld);
66
virtual void handleEvent(ScriptExecutionContext*, Event*);
69
mutable JSC::Weak<JSC::JSObject> m_jsFunction;
70
mutable JSC::Weak<JSC::JSObject> m_wrapper;
73
RefPtr<DOMWrapperWorld> m_isolatedWorld;
76
inline JSC::JSObject* JSEventListener::jsFunction(ScriptExecutionContext* scriptExecutionContext) const
78
// initializeJSFunction can trigger code that deletes this event listener
79
// before we're done. It should always return 0 in this case.
80
RefPtr<JSEventListener> protect(const_cast<JSEventListener*>(this));
81
JSC::Strong<JSC::JSObject> wrapper(*m_isolatedWorld->globalData(), m_wrapper.get());
84
JSC::JSObject* function = initializeJSFunction(scriptExecutionContext);
85
JSC::Heap::writeBarrier(m_wrapper.get(), function);
86
m_jsFunction = JSC::PassWeak<JSC::JSObject>(function);
89
// Verify that we have a valid wrapper protecting our function from
90
// garbage collection. That is except for when we're not in the normal
91
// world and can have zombie m_jsFunctions.
92
ASSERT(!m_isolatedWorld->isNormal() || m_wrapper || !m_jsFunction);
94
// If m_wrapper is 0, then m_jsFunction is zombied, and should never be accessed.
98
// Try to verify that m_jsFunction wasn't recycled. (Not exact, since an
99
// event listener can be almost anything, but this makes test-writing easier).
100
ASSERT(!m_jsFunction || static_cast<JSC::JSCell*>(m_jsFunction.get())->isObject());
102
return m_jsFunction.get();
105
// Creates a JS EventListener for an "onXXX" event attribute.
106
inline PassRefPtr<JSEventListener> createJSAttributeEventListener(JSC::ExecState* exec, JSC::JSValue listener, JSC::JSObject* wrapper)
108
if (!listener.isObject())
111
return JSEventListener::create(asObject(listener), wrapper, true, currentWorld(exec));
115
} // namespace WebCore
117
#endif // JSEventListener_h