~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/bindings/js/JSEventListener.h

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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/StrongInlines.h>
 
26
#include <heap/Weak.h>
 
27
 
 
28
namespace WebCore {
 
29
 
 
30
    class JSDOMGlobalObject;
 
31
 
 
32
    class JSEventListener : public EventListener {
 
33
    public:
 
34
        static PassRefPtr<JSEventListener> create(JSC::JSObject* listener, JSC::JSObject* wrapper, bool isAttribute, DOMWrapperWorld* isolatedWorld)
 
35
        {
 
36
            return adoptRef(new JSEventListener(listener, wrapper, isAttribute, isolatedWorld));
 
37
        }
 
38
 
 
39
        static const JSEventListener* cast(const EventListener* listener)
 
40
        {
 
41
            return listener->type() == JSEventListenerType
 
42
                ? static_cast<const JSEventListener*>(listener)
 
43
                : 0;
 
44
        }
 
45
 
 
46
        virtual ~JSEventListener();
 
47
 
 
48
        virtual bool operator==(const EventListener& other);
 
49
 
 
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; }
 
52
 
 
53
        JSC::JSObject* jsFunction(ScriptExecutionContext*) const;
 
54
        DOMWrapperWorld* isolatedWorld() const { return m_isolatedWorld.get(); }
 
55
 
 
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); }
 
58
 
 
59
    private:
 
60
        virtual JSC::JSObject* initializeJSFunction(ScriptExecutionContext*) const;
 
61
        virtual void visitJSFunction(JSC::SlotVisitor&);
 
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::Weak<JSC::JSObject> m_jsFunction;
 
70
        mutable JSC::Weak<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
        // 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());
 
82
 
 
83
        if (!m_jsFunction) {
 
84
            JSC::JSObject* function = initializeJSFunction(scriptExecutionContext);
 
85
            JSC::Heap::writeBarrier(m_wrapper.get(), function);
 
86
            m_jsFunction = JSC::PassWeak<JSC::JSObject>(function);
 
87
        }
 
88
 
 
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);
 
93
 
 
94
        // If m_wrapper is 0, then m_jsFunction is zombied, and should never be accessed.
 
95
        if (!m_wrapper)
 
96
            return 0;
 
97
 
 
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());
 
101
 
 
102
        return m_jsFunction.get();
 
103
    }
 
104
 
 
105
    // Creates a JS EventListener for an "onXXX" event attribute.
 
106
    inline PassRefPtr<JSEventListener> createJSAttributeEventListener(JSC::ExecState* exec, JSC::JSValue listener, JSC::JSObject* wrapper)
 
107
    {
 
108
        if (!listener.isObject())
 
109
            return 0;
 
110
 
 
111
        return JSEventListener::create(asObject(listener), wrapper, true, currentWorld(exec));
 
112
    }
 
113
 
 
114
 
 
115
} // namespace WebCore
 
116
 
 
117
#endif // JSEventListener_h