/* * 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 * * 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 #include #include #include "ScriptState.h" #include 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 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(JSC::ExecState*, const JSC::ClassInfo*); JSC::Structure* cacheDOMStructure(JSC::ExecState*, PassRefPtr, const JSC::ClassInfo*); JSC::JSObject* getCachedDOMConstructor(JSC::ExecState*, const JSC::ClassInfo*); void cacheDOMConstructor(JSC::ExecState*, const JSC::ClassInfo*, JSC::JSObject* constructor); template inline JSC::Structure* getDOMStructure(JSC::ExecState* exec) { if (JSC::Structure* structure = getCachedDOMStructure(exec, &WrapperClass::s_info)) return structure; return cacheDOMStructure(exec, WrapperClass::createStructure(WrapperClass::createPrototype(exec)), &WrapperClass::s_info); } template inline JSC::JSObject* getDOMPrototype(JSC::ExecState* exec) { return static_cast(asObject(getDOMStructure(exec)->storedPrototype())); } #define CREATE_DOM_OBJECT_WRAPPER(exec, className, object) createDOMObjectWrapper(exec, static_cast(object)) template inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object) { ASSERT(object); ASSERT(!getCachedDOMObjectWrapper(exec->globalData(), object)); WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure(exec), object); cacheDOMObjectWrapper(exec->globalData(), object, wrapper); return wrapper; } template 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(exec, object); } #if ENABLE(SVG) #define CREATE_SVG_OBJECT_WRAPPER(exec, className, object, context) createDOMObjectWrapper(exec, static_cast(object), context) template inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object, SVGElement* context) { ASSERT(object); ASSERT(!getCachedDOMObjectWrapper(exec->globalData(), object)); WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure(exec), object, context); cacheDOMObjectWrapper(exec->globalData(), object, wrapper); return wrapper; } template 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(exec, object, context); } #endif #define CREATE_DOM_NODE_WRAPPER(exec, className, object) createDOMNodeWrapper(exec, static_cast(object)) template inline JSNode* createDOMNodeWrapper(JSC::ExecState* exec, DOMClass* node) { ASSERT(node); ASSERT(!getCachedDOMNodeWrapper(node->document(), node)); WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure(exec), node); cacheDOMNodeWrapper(node->document(), node, wrapper); return wrapper; } template 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(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 inline JSC::JSValuePtr toJS(JSC::ExecState* exec, PassRefPtr 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