summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.h
blob: 5870ecc2aa6c6cbeeda8f7aee76ec9e768406821 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/*
 *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
 *  Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
 *  Copyright (C) 2007 Samuel Weinig <sam@webkit.org>
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef JSDOMBinding_h
#define JSDOMBinding_h

#include "JSDOMGlobalObject.h"
#include <runtime/Completion.h>
#include <runtime/Lookup.h>
#include <runtime/JSFunction.h>
#include "ScriptState.h"
#include <wtf/Noncopyable.h>

namespace JSC {
    class JSGlobalData;
}

namespace WebCore {

    class Document;
    class Frame;
    class KURL;
    class Node;
    class String;
    class JSNode;

    typedef int ExceptionCode;

#if ENABLE(SVG)
    class SVGElement;
#endif

    // Base class for all objects in this binding except Window.
    class DOMObject : public JSC::JSObject {
    protected:
        explicit DOMObject(PassRefPtr<JSC::Structure> structure) 
            : JSObject(structure)
        {
        }

#ifndef NDEBUG
        virtual ~DOMObject();
#endif
    };

    DOMObject* getCachedDOMObjectWrapper(JSC::JSGlobalData&, void* objectHandle);
    void cacheDOMObjectWrapper(JSC::JSGlobalData&, void* objectHandle, DOMObject* wrapper);
    void forgetDOMObject(JSC::JSGlobalData&, void* objectHandle);

    JSNode* getCachedDOMNodeWrapper(Document*, Node*);
    void cacheDOMNodeWrapper(Document*, Node*, JSNode* wrapper);
    void forgetDOMNode(Document*, Node*);
    void forgetAllDOMNodesForDocument(Document*);
    void updateDOMNodeDocument(Node*, Document* oldDocument, Document* newDocument);
    void markDOMNodesForDocument(Document*);
    void markActiveObjectsForContext(JSC::JSGlobalData&, ScriptExecutionContext*);
    void markDOMObjectWrapper(JSC::JSGlobalData& globalData, void* object);

    JSC::Structure* getCachedDOMStructure(JSDOMGlobalObject*, const JSC::ClassInfo*);
    JSC::Structure* cacheDOMStructure(JSDOMGlobalObject*, PassRefPtr<JSC::Structure>, const JSC::ClassInfo*);
    JSC::Structure* getCachedDOMStructure(JSC::ExecState*, const JSC::ClassInfo*);
    JSC::Structure* cacheDOMStructure(JSC::ExecState*, PassRefPtr<JSC::Structure>, const JSC::ClassInfo*);

    JSC::JSObject* getCachedDOMConstructor(JSC::ExecState*, const JSC::ClassInfo*);
    void cacheDOMConstructor(JSC::ExecState*, const JSC::ClassInfo*, JSC::JSObject* constructor);

    template<class WrapperClass> inline JSC::Structure* getDOMStructure(JSC::ExecState* exec, JSDOMGlobalObject* globalObject)
    {
        if (JSC::Structure* structure = getCachedDOMStructure(globalObject, &WrapperClass::s_info))
            return structure;
        return cacheDOMStructure(globalObject, WrapperClass::createStructure(WrapperClass::createPrototype(exec, globalObject)), &WrapperClass::s_info);
    }
    template<class WrapperClass> inline JSC::Structure* getDOMStructure(JSC::ExecState* exec)
    {
        return getDOMStructure<WrapperClass>(exec, static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()));
    }
    template<class WrapperClass> inline JSC::JSObject* getDOMPrototype(JSC::ExecState* exec, JSC::JSGlobalObject* globalObject)
    {
        return static_cast<JSC::JSObject*>(asObject(getDOMStructure<WrapperClass>(exec, static_cast<JSDOMGlobalObject*>(globalObject))->storedPrototype()));
    }
    #define CREATE_DOM_OBJECT_WRAPPER(exec, className, object) createDOMObjectWrapper<JS##className>(exec, static_cast<className*>(object))
    template<class WrapperClass, class DOMClass> inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object)
    {
        ASSERT(object);
        ASSERT(!getCachedDOMObjectWrapper(exec->globalData(), object));
        WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec), object);
        cacheDOMObjectWrapper(exec->globalData(), object, wrapper);
        return wrapper;
    }
    template<class WrapperClass, class DOMClass> inline JSC::JSValuePtr getDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object)
    {
        if (!object)
            return JSC::jsNull();
        if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), object))
            return wrapper;
        return createDOMObjectWrapper<WrapperClass>(exec, object);
    }

#if ENABLE(SVG)
    #define CREATE_SVG_OBJECT_WRAPPER(exec, className, object, context) createDOMObjectWrapper<JS##className>(exec, static_cast<className*>(object), context)
    template<class WrapperClass, class DOMClass> inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object, SVGElement* context)
    {
        ASSERT(object);
        ASSERT(!getCachedDOMObjectWrapper(exec->globalData(), object));
        WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec), object, context);
        cacheDOMObjectWrapper(exec->globalData(), object, wrapper);
        return wrapper;
    }
    template<class WrapperClass, class DOMClass> inline JSC::JSValuePtr getDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object, SVGElement* context)
    {
        if (!object)
            return JSC::jsNull();
        if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), object))
            return wrapper;
        return createDOMObjectWrapper<WrapperClass>(exec, object, context);
    }
#endif

    #define CREATE_DOM_NODE_WRAPPER(exec, className, object) createDOMNodeWrapper<JS##className>(exec, static_cast<className*>(object))
    template<class WrapperClass, class DOMClass> inline JSNode* createDOMNodeWrapper(JSC::ExecState* exec, DOMClass* node)
    {
        ASSERT(node);
        ASSERT(!getCachedDOMNodeWrapper(node->document(), node));
        WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec), node);
        cacheDOMNodeWrapper(node->document(), node, wrapper);
        return wrapper;
    }
    template<class WrapperClass, class DOMClass> inline JSC::JSValuePtr getDOMNodeWrapper(JSC::ExecState* exec, DOMClass* node)
    {
        if (!node)
            return JSC::jsNull();
        if (JSNode* wrapper = getCachedDOMNodeWrapper(node->document(), node))
            return wrapper;
        return createDOMNodeWrapper<WrapperClass>(exec, node);
    }

    const JSC::HashTable* getHashTableForGlobalData(JSC::JSGlobalData&, const JSC::HashTable* staticTable);

    void reportException(JSC::ExecState*, JSC::JSValuePtr exception);
    void reportCurrentException(JSC::ExecState*);

    // Convert a DOM implementation exception code into a JavaScript exception in the execution state.
    void setDOMException(JSC::ExecState*, ExceptionCode);

    JSC::JSValuePtr jsStringOrNull(JSC::ExecState*, const String&); // null if the string is null
    JSC::JSValuePtr jsStringOrNull(JSC::ExecState*, const KURL&); // null if the URL is null

    JSC::JSValuePtr jsStringOrUndefined(JSC::ExecState*, const String&); // undefined if the string is null
    JSC::JSValuePtr jsStringOrUndefined(JSC::ExecState*, const KURL&); // undefined if the URL is null

    JSC::JSValuePtr jsStringOrFalse(JSC::ExecState*, const String&); // boolean false if the string is null
    JSC::JSValuePtr jsStringOrFalse(JSC::ExecState*, const KURL&); // boolean false if the URL is null

    // See JavaScriptCore for explanation: Should be used for any UString that is already owned by another
    // object, to let the engine know that collecting the JSString wrapper is unlikely to save memory.
    JSC::JSValuePtr jsOwnedStringOrNull(JSC::ExecState*, const JSC::UString&); 

    JSC::UString valueToStringWithNullCheck(JSC::ExecState*, JSC::JSValuePtr); // null if the value is null
    JSC::UString valueToStringWithUndefinedOrNullCheck(JSC::ExecState*, JSC::JSValuePtr); // null if the value is null or undefined

    template <typename T> inline JSC::JSValuePtr toJS(JSC::ExecState* exec, PassRefPtr<T> ptr) { return toJS(exec, ptr.get()); }

    bool checkNodeSecurity(JSC::ExecState*, Node*);

    // Helpers for Window, History, and Location classes to implement cross-domain policy.
    // Besides the cross-domain check, they need non-caching versions of staticFunctionGetter for
    // because we do not want current property values involved at all.
    bool allowsAccessFromFrame(JSC::ExecState*, Frame*);
    bool allowsAccessFromFrame(JSC::ExecState*, Frame*, String& message);
    void printErrorMessageForFrame(Frame*, const String& message);
    JSC::JSValuePtr objectToStringFunctionGetter(JSC::ExecState*, const JSC::Identifier& propertyName, const JSC::PropertySlot&);

    ScriptState* scriptStateFromNode(Node*);

} // namespace WebCore

#endif // JSDOMBinding_h