#ifndef JSDOMBinding_h
#define JSDOMBinding_h
#include "JSDOMGlobalObject.h"
#include "JSDOMWrapper.h"
#include "DOMWrapperWorld.h"
#include "JSSVGContextCache.h"
#include "Document.h"
#include <runtime/Completion.h>
#include <runtime/Lookup.h>
#include <runtime/WeakGCMap.h>
#include <wtf/Noncopyable.h>
namespace JSC {
class JSGlobalData;
class DebuggerCallFrame;
}
namespace WebCore {
class Document;
class Frame;
class JSNode;
class KURL;
class Node;
class String;
class ScriptController;
class ScriptCachedFrameData;
typedef int ExceptionCode;
#if ENABLE(SVG)
class SVGElement;
#endif
class DOMObjectWithGlobalPointer : public DOMObject {
public:
JSDOMGlobalObject* globalObject() const { return static_cast<JSDOMGlobalObject*>(getAnonymousValue(GlobalObjectSlot).asCell()); }
ScriptExecutionContext* scriptExecutionContext() const
{
return globalObject()->scriptExecutionContext();
}
static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype)
{
return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount);
}
protected:
static const unsigned AnonymousSlotCount = 1 + DOMObject::AnonymousSlotCount;
static const unsigned GlobalObjectSlot = AnonymousSlotCount - 1;
DOMObjectWithGlobalPointer(NonNullPassRefPtr<JSC::Structure> structure, JSDOMGlobalObject* globalObject)
: DOMObject(structure)
{
putAnonymousValue(GlobalObjectSlot, globalObject);
}
virtual ~DOMObjectWithGlobalPointer() { }
};
class DOMConstructorObject : public DOMObjectWithGlobalPointer {
public:
static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype)
{
return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount);
}
protected:
static const unsigned StructureFlags = JSC::ImplementsHasInstance | JSC::OverridesMarkChildren | DOMObjectWithGlobalPointer::StructureFlags;
DOMConstructorObject(NonNullPassRefPtr<JSC::Structure> structure, JSDOMGlobalObject* globalObject)
: DOMObjectWithGlobalPointer(structure, globalObject)
{
}
};
class DOMConstructorWithDocument : public DOMConstructorObject {
public:
Document* document() const
{
return static_cast<Document*>(scriptExecutionContext());
}
protected:
DOMConstructorWithDocument(NonNullPassRefPtr<JSC::Structure> structure, JSDOMGlobalObject* globalObject)
: DOMConstructorObject(structure, globalObject)
{
ASSERT(globalObject->scriptExecutionContext()->isDocument());
}
};
DOMObject* getCachedDOMObjectWrapper(JSC::ExecState*, void* objectHandle);
bool hasCachedDOMObjectWrapper(JSC::JSGlobalData*, void* objectHandle);
void cacheDOMObjectWrapper(JSC::ExecState*, void* objectHandle, DOMObject* wrapper);
void forgetDOMNode(JSNode* wrapper, Node* node, Document* document);
void forgetDOMObject(DOMObject* wrapper, void* objectHandle);
JSNode* getCachedDOMNodeWrapper(JSC::ExecState*, Document*, Node*);
void cacheDOMNodeWrapper(JSC::ExecState*, Document*, Node*, JSNode* wrapper);
void updateDOMNodeDocument(Node*, Document* oldDocument, Document* newDocument);
void markDOMNodesForDocument(JSC::MarkStack&, Document*);
void markActiveObjectsForContext(JSC::MarkStack&, JSC::JSGlobalData&, ScriptExecutionContext*);
void markDOMObjectWrapper(JSC::MarkStack&, JSC::JSGlobalData& globalData, void* object);
void markDOMNodeWrapper(JSC::MarkStack& markStack, Document* document, Node* node);
bool hasCachedDOMObjectWrapperUnchecked(JSC::JSGlobalData*, void* objectHandle);
bool hasCachedDOMNodeWrapperUnchecked(Document*, Node*);
JSC::Structure* getCachedDOMStructure(JSDOMGlobalObject*, const JSC::ClassInfo*);
JSC::Structure* cacheDOMStructure(JSDOMGlobalObject*, NonNullPassRefPtr<JSC::Structure>, const JSC::ClassInfo*);
JSC::Structure* getCachedDOMStructure(JSC::ExecState*, const JSC::ClassInfo*);
JSC::Structure* cacheDOMStructure(JSC::ExecState*, NonNullPassRefPtr<JSC::Structure>, const JSC::ClassInfo*);
JSC::JSObject* getCachedDOMConstructor(JSC::ExecState*, const JSC::ClassInfo*);
void cacheDOMConstructor(JSC::ExecState*, const JSC::ClassInfo*, JSC::JSObject* constructor);
inline JSDOMGlobalObject* deprecatedGlobalObjectForPrototype(JSC::ExecState* exec)
{
return static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject());
}
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* deprecatedGetDOMStructure(JSC::ExecState* exec)
{
return getDOMStructure<WrapperClass>(exec, deprecatedGlobalObjectForPrototype(exec));
}
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, globalObject, className, object) createDOMObjectWrapper<JS##className>(exec, globalObject, static_cast<className*>(object))
template<class WrapperClass, class DOMClass> inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object)
{
ASSERT(object);
ASSERT(!getCachedDOMObjectWrapper(exec, object));
WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec, globalObject), globalObject, object);
cacheDOMObjectWrapper(exec, object, wrapper);
return wrapper;
}
template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object)
{
if (!object)
return JSC::jsNull();
if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec, object))
return wrapper;
return createDOMObjectWrapper<WrapperClass>(exec, globalObject, object);
}
#if ENABLE(SVG)
#define CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, className, object, context) createDOMObjectWrapper<JS##className>(exec, globalObject, static_cast<className*>(object), context)
template<class WrapperClass, class DOMClass> inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object, SVGElement* context)
{
DOMObject* wrapper = createDOMObjectWrapper<WrapperClass, DOMClass>(exec, globalObject, object);
ASSERT(wrapper);
if (context)
JSSVGContextCache::addWrapper(wrapper, context);
return wrapper;
}
template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object, SVGElement* context)
{
if (!object)
return JSC::jsNull();
if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec, object)) {
ASSERT(JSSVGContextCache::svgContextForDOMObject(wrapper) == context);
return wrapper;
}
return createDOMObjectWrapper<WrapperClass, DOMClass>(exec, globalObject, object, context);
}
#endif
#define CREATE_DOM_NODE_WRAPPER(exec, globalObject, className, object) createDOMNodeWrapper<JS##className>(exec, globalObject, static_cast<className*>(object))
template<class WrapperClass, class DOMClass> inline JSNode* createDOMNodeWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* node)
{
ASSERT(node);
ASSERT(!getCachedDOMNodeWrapper(exec, node->document(), node));
WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec, globalObject), globalObject, node);
cacheDOMNodeWrapper(exec, node->document(), node, wrapper);
return wrapper;
}
template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMNodeWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* node)
{
if (!node)
return JSC::jsNull();
if (JSNode* wrapper = getCachedDOMNodeWrapper(exec, node->document(), node))
return wrapper;
return createDOMNodeWrapper<WrapperClass>(exec, globalObject, node);
}
const JSC::HashTable* getHashTableForGlobalData(JSC::JSGlobalData&, const JSC::HashTable* staticTable);
void reportException(JSC::ExecState*, JSC::JSValue exception);
void reportCurrentException(JSC::ExecState*);
void setDOMException(JSC::ExecState*, ExceptionCode);
JSC::JSValue jsString(JSC::ExecState*, const String&); JSC::JSValue jsStringSlowCase(JSC::ExecState*, JSStringCache&, StringImpl*);
JSC::JSValue jsString(JSC::ExecState*, const KURL&); inline JSC::JSValue jsString(JSC::ExecState* exec, const AtomicString& s)
{
return jsString(exec, s.string());
}
JSC::JSValue jsStringOrNull(JSC::ExecState*, const String&); JSC::JSValue jsStringOrNull(JSC::ExecState*, const KURL&);
JSC::JSValue jsStringOrUndefined(JSC::ExecState*, const String&); JSC::JSValue jsStringOrUndefined(JSC::ExecState*, const KURL&);
JSC::JSValue jsStringOrFalse(JSC::ExecState*, const String&); JSC::JSValue jsStringOrFalse(JSC::ExecState*, const KURL&);
JSC::JSValue jsOwnedStringOrNull(JSC::ExecState*, const JSC::UString&);
String identifierToString(const JSC::Identifier&);
String ustringToString(const JSC::UString&);
JSC::UString stringToUString(const String&);
AtomicString identifierToAtomicString(const JSC::Identifier&);
AtomicString ustringToAtomicString(const JSC::UString&);
AtomicStringImpl* findAtomicString(const JSC::Identifier&);
String valueToStringWithNullCheck(JSC::ExecState*, JSC::JSValue); String valueToStringWithUndefinedOrNullCheck(JSC::ExecState*, JSC::JSValue);
JSC::JSValue jsDateOrNull(JSC::ExecState*, double);
double valueToDate(JSC::ExecState*, JSC::JSValue);
template <typename T>
inline JSC::JSValue toJS(JSC::ExecState* exec, T* ptr)
{
return toJS(exec, deprecatedGlobalObjectForPrototype(exec), ptr);
}
template <typename T>
inline JSC::JSValue toJS(JSC::ExecState* exec, PassRefPtr<T> ptr)
{
return toJS(exec, deprecatedGlobalObjectForPrototype(exec), ptr.get());
}
template <typename T>
inline JSC::JSValue toJSNewlyCreated(JSC::ExecState* exec, T* ptr)
{
return toJSNewlyCreated(exec, deprecatedGlobalObjectForPrototype(exec), ptr);
}
template <typename T>
inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, PassRefPtr<T> ptr)
{
return toJS(exec, globalObject, ptr.get());
}
JSC::JSObject* toJSSequence(JSC::ExecState*, JSC::JSValue, unsigned&);
bool checkNodeSecurity(JSC::ExecState*, Node*);
bool allowsAccessFromFrame(JSC::ExecState*, Frame*);
bool allowsAccessFromFrame(JSC::ExecState*, Frame*, String& message);
bool shouldAllowNavigation(JSC::ExecState*, Frame*);
bool allowSettingSrcToJavascriptURL(JSC::ExecState*, Element*, const String&, const String&);
void printErrorMessageForFrame(Frame*, const String& message);
JSC::JSValue objectToStringFunctionGetter(JSC::ExecState*, JSC::JSValue, const JSC::Identifier& propertyName);
Frame* toLexicalFrame(JSC::ExecState*);
Frame* toDynamicFrame(JSC::ExecState*);
bool processingUserGesture(JSC::ExecState*);
KURL completeURL(JSC::ExecState*, const String& relativeURL);
inline JSC::JSValue jsString(JSC::ExecState* exec, const String& s)
{
StringImpl* stringImpl = s.impl();
if (!stringImpl || !stringImpl->length())
return jsEmptyString(exec);
if (stringImpl->length() == 1 && stringImpl->characters()[0] <= 0xFF)
return jsString(exec, stringToUString(s));
JSStringCache& stringCache = currentWorld(exec)->m_stringCache;
if (JSC::JSString* wrapper = stringCache.get(stringImpl))
return wrapper;
return jsStringSlowCase(exec, stringCache, stringImpl);
}
inline DOMObjectWrapperMap& domObjectWrapperMapFor(JSC::ExecState* exec)
{
return currentWorld(exec)->m_wrappers;
}
inline String ustringToString(const JSC::UString& u)
{
return u.rep();
}
inline JSC::UString stringToUString(const String& s)
{
return JSC::UString(s.impl());
}
inline String identifierToString(const JSC::Identifier& i)
{
return i.ustring().rep();
}
inline AtomicString ustringToAtomicString(const JSC::UString& u)
{
return AtomicString(u.rep());
}
inline AtomicString identifierToAtomicString(const JSC::Identifier& identifier)
{
return AtomicString(identifier.ustring().rep());
}
}
#endif // JSDOMBinding_h