1/*
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 */
26
27#ifndef JSDOMGlobalObject_h
28#define JSDOMGlobalObject_h
29
30#include <runtime/JSGlobalObject.h>
31
32namespace WebCore {
33
34    class Document;
35    class Event;
36    class DOMWrapperWorld;
37    class JSLazyEventListener;
38    class JSEventListener;
39    class ScriptExecutionContext;
40
41    typedef HashMap<const JSC::ClassInfo*, JSC::WriteBarrier<JSC::Structure> > JSDOMStructureMap;
42    typedef HashMap<const JSC::ClassInfo*, JSC::WriteBarrier<JSC::JSObject> > JSDOMConstructorMap;
43
44    class JSDOMGlobalObject : public JSC::JSGlobalObject {
45        typedef JSC::JSGlobalObject Base;
46    protected:
47        struct JSDOMGlobalObjectData;
48
49        JSDOMGlobalObject(JSC::JSGlobalData&, JSC::Structure*, PassRefPtr<DOMWrapperWorld>, JSC::JSObject* thisValue);
50
51    public:
52        JSDOMStructureMap& structures() { return m_structures; }
53        JSDOMConstructorMap& constructors() { return m_constructors; }
54
55        virtual ScriptExecutionContext* scriptExecutionContext() const = 0;
56
57        // Make binding code generation easier.
58        JSDOMGlobalObject* globalObject() { return this; }
59
60        void setCurrentEvent(Event*);
61        Event* currentEvent() const;
62
63        void setInjectedScript(JSObject*);
64        JSObject* injectedScript() const;
65
66        virtual void markChildren(JSC::MarkStack&);
67
68        DOMWrapperWorld* world() { return m_world.get(); }
69
70        static const JSC::ClassInfo s_info;
71
72        static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSValue prototype)
73        {
74            return JSC::Structure::create(globalData, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
75        }
76
77    protected:
78        JSDOMStructureMap m_structures;
79        JSDOMConstructorMap m_constructors;
80
81        Event* m_currentEvent;
82        RefPtr<DOMWrapperWorld> m_world;
83        JSC::WriteBarrier<JSObject> m_injectedScript;
84    };
85
86    template<class ConstructorClass>
87    inline JSC::JSObject* getDOMConstructor(JSC::ExecState* exec, const JSDOMGlobalObject* globalObject)
88    {
89        if (JSC::JSObject* constructor = const_cast<JSDOMGlobalObject*>(globalObject)->constructors().get(&ConstructorClass::s_info).get())
90            return constructor;
91        JSC::JSObject* constructor = new (exec) ConstructorClass(exec, const_cast<JSDOMGlobalObject*>(globalObject));
92        ASSERT(!const_cast<JSDOMGlobalObject*>(globalObject)->constructors().contains(&ConstructorClass::s_info));
93        JSC::WriteBarrier<JSC::JSObject> temp;
94        const_cast<JSDOMGlobalObject*>(globalObject)->constructors().add(&ConstructorClass::s_info, temp).first->second.set(exec->globalData(), globalObject, constructor);
95        return constructor;
96    }
97
98    JSDOMGlobalObject* toJSDOMGlobalObject(Document*, JSC::ExecState*);
99    JSDOMGlobalObject* toJSDOMGlobalObject(ScriptExecutionContext*, JSC::ExecState*);
100
101    JSDOMGlobalObject* toJSDOMGlobalObject(Document*, DOMWrapperWorld*);
102    JSDOMGlobalObject* toJSDOMGlobalObject(ScriptExecutionContext*, DOMWrapperWorld*);
103
104} // namespace WebCore
105
106#endif // JSDOMGlobalObject_h
107