#ifndef JSDOMBinding_h
#define JSDOMBinding_h
#include "JSDOMGlobalObject.h"
#include "JSDOMWrapper.h"
#include "DOMWrapperWorld.h"
#include "Document.h"
#include "Element.h"
#include "StyleBase.h"
#include <heap/Weak.h>
#include <runtime/FunctionPrototype.h>
#include <runtime/Lookup.h>
#include <runtime/ObjectPrototype.h>
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
namespace WebCore {
class Frame;
class KURL;
typedef int ExceptionCode;
class DOMConstructorObject : public JSDOMWrapper {
typedef JSDOMWrapper Base;
public:
static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);
}
protected:
static const unsigned StructureFlags = JSC::ImplementsHasInstance | JSC::OverridesVisitChildren | JSDOMWrapper::StructureFlags;
DOMConstructorObject(JSC::Structure* structure, JSDOMGlobalObject* globalObject)
: JSDOMWrapper(structure, globalObject)
{
}
};
class DOMConstructorWithDocument : public DOMConstructorObject {
typedef DOMConstructorObject Base;
public:
Document* document() const
{
return static_cast<Document*>(scriptExecutionContext());
}
protected:
DOMConstructorWithDocument(JSC::Structure* structure, JSDOMGlobalObject* globalObject)
: DOMConstructorObject(structure, globalObject)
{
}
void finishCreation(JSDOMGlobalObject* globalObject)
{
Base::finishCreation(globalObject->globalData());
ASSERT(globalObject->scriptExecutionContext()->isDocument());
}
};
JSC::Structure* getCachedDOMStructure(JSDOMGlobalObject*, const JSC::ClassInfo*);
JSC::Structure* cacheDOMStructure(JSDOMGlobalObject*, JSC::Structure*, const JSC::ClassInfo*);
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(exec->globalData(), globalObject, 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()));
}
inline JSDOMWrapper* getInlineCachedWrapper(DOMWrapperWorld*, void*) { return 0; }
inline bool setInlineCachedWrapper(DOMWrapperWorld*, void*, JSDOMWrapper*) { return false; }
inline bool clearInlineCachedWrapper(DOMWrapperWorld*, void*, JSDOMWrapper*) { return false; }
template <typename DOMClass> inline JSDOMWrapper* getCachedWrapper(DOMWrapperWorld* world, DOMClass* domObject)
{
if (JSDOMWrapper* wrapper = getInlineCachedWrapper(world, domObject))
return wrapper;
return world->m_wrappers.get(domObject).get();
}
template <typename DOMClass> inline void cacheWrapper(DOMWrapperWorld* world, DOMClass* domObject, JSDOMWrapper* wrapper)
{
if (setInlineCachedWrapper(world, domObject, wrapper))
return;
ASSERT(!world->m_wrappers.contains(domObject));
world->m_wrappers.set(domObject, JSC::Weak<JSDOMWrapper>(*world->globalData(), wrapper, wrapperOwner(world, domObject), wrapperContext(world, domObject)));
}
template <typename DOMClass> inline void uncacheWrapper(DOMWrapperWorld* world, DOMClass* domObject, JSDOMWrapper* wrapper)
{
if (clearInlineCachedWrapper(world, domObject, wrapper))
return;
ASSERT(world->m_wrappers.find(domObject)->second.get() == wrapper);
world->m_wrappers.remove(domObject);
}
#define CREATE_DOM_WRAPPER(exec, globalObject, className, object) createWrapper<JS##className>(exec, globalObject, static_cast<className*>(object))
template<class WrapperClass, class DOMClass> inline JSDOMWrapper* createWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* node)
{
ASSERT(node);
ASSERT(!getCachedWrapper(currentWorld(exec), node));
WrapperClass* wrapper = WrapperClass::create(getDOMStructure<WrapperClass>(exec, globalObject), globalObject, node);
cacheWrapper(currentWorld(exec), node, wrapper);
return wrapper;
}
template<class WrapperClass, class DOMClass> inline JSC::JSValue wrap(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* domObject)
{
if (!domObject)
return JSC::jsNull();
if (JSDOMWrapper* wrapper = getCachedWrapper(currentWorld(exec), domObject))
return wrapper;
return createWrapper<WrapperClass>(exec, globalObject, domObject);
}
inline void* root(Node* node)
{
if (node->inDocument())
return node->document();
while (node->parentOrHostNode())
node = node->parentOrHostNode();
return node;
}
inline void* root(StyleBase* styleBase)
{
while (styleBase->parent())
styleBase = styleBase->parent();
if (Node* node = styleBase->node())
return root(node);
return styleBase;
}
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 String&);
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);
inline int32_t finiteInt32Value(JSC::JSValue value, JSC::ExecState* exec, bool& okay)
{
double number = value.toNumber(exec);
okay = isfinite(number);
return JSC::toInt32(number);
}
JSC::JSValue jsDateOrNull(JSC::ExecState*, double);
double valueToDate(JSC::ExecState*, JSC::JSValue);
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);
DOMWindow* activeDOMWindow(JSC::ExecState*);
DOMWindow* firstDOMWindow(JSC::ExecState*);
void printErrorMessageForFrame(Frame*, const String& message);
JSC::JSValue objectToStringFunctionGetter(JSC::ExecState*, JSC::JSValue, const JSC::Identifier& propertyName);
Frame* toDynamicFrame(JSC::ExecState*);
bool processingUserGesture();
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;
JSStringCache::iterator it = stringCache.find(stringImpl);
if (it != stringCache.end())
return it->second.get();
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.impl();
}
inline JSC::UString stringToUString(const String& s)
{
return JSC::UString(s.impl());
}
inline String identifierToString(const JSC::Identifier& i)
{
return i.impl();
}
inline AtomicString ustringToAtomicString(const JSC::UString& u)
{
return AtomicString(u.impl());
}
inline AtomicString identifierToAtomicString(const JSC::Identifier& identifier)
{
return AtomicString(identifier.impl());
}
}
#endif // JSDOMBinding_h