diff options
Diffstat (limited to 'WebCore/bindings/js/JSDOMBinding.cpp')
-rw-r--r-- | WebCore/bindings/js/JSDOMBinding.cpp | 798 |
1 files changed, 0 insertions, 798 deletions
diff --git a/WebCore/bindings/js/JSDOMBinding.cpp b/WebCore/bindings/js/JSDOMBinding.cpp deleted file mode 100644 index ed579d3..0000000 --- a/WebCore/bindings/js/JSDOMBinding.cpp +++ /dev/null @@ -1,798 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 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 - */ - -#include "config.h" -#include "JSDOMBinding.h" - -#include "debugger/DebuggerCallFrame.h" - -#include "ActiveDOMObject.h" -#include "DOMCoreException.h" -#include "DOMObjectHashTableMap.h" -#include "Document.h" -#include "EventException.h" -#include "ExceptionBase.h" -#include "ExceptionCode.h" -#include "Frame.h" -#include "HTMLAudioElement.h" -#include "HTMLCanvasElement.h" -#include "HTMLFrameElementBase.h" -#include "HTMLImageElement.h" -#include "HTMLLinkElement.h" -#include "HTMLNames.h" -#include "HTMLScriptElement.h" -#include "HTMLStyleElement.h" -#include "JSBinding.h" -#include "JSBindingState.h" -#include "JSDOMCoreException.h" -#include "JSDOMWindowCustom.h" -#include "JSDebugWrapperSet.h" -#include "JSEventException.h" -#include "JSExceptionBase.h" -#include "JSMainThreadExecState.h" -#include "JSNode.h" -#include "JSRangeException.h" -#include "JSXMLHttpRequestException.h" -#include "KURL.h" -#include "MessagePort.h" -#include "ProcessingInstruction.h" -#include "RangeException.h" -#include "ScriptCachedFrameData.h" -#include "ScriptController.h" -#include "Settings.h" -#include "WebCoreJSClientData.h" -#include "XMLHttpRequestException.h" -#include <runtime/DateInstance.h> -#include <runtime/Error.h> -#include <runtime/JSFunction.h> -#include <runtime/PrototypeFunction.h> -#include <wtf/MathExtras.h> -#include <wtf/StdLibExtras.h> - -#if ENABLE(SVG) -#include "JSSVGException.h" -#include "SVGException.h" -#endif - -#if ENABLE(XPATH) -#include "JSXPathException.h" -#include "XPathException.h" -#endif - -#if ENABLE(DATABASE) -#include "JSSQLException.h" -#include "SQLException.h" -#endif - -#if ENABLE(BLOB) || ENABLE(FILE_SYSTEM) -#include "FileException.h" -#include "JSFileException.h" -#endif - -#if ENABLE(INDEXED_DATABASE) -#include "IDBDatabaseException.h" -#include "JSIDBDatabaseException.h" -#endif - -using namespace JSC; - -namespace WebCore { - -using namespace HTMLNames; - -typedef Document::JSWrapperCache JSWrapperCache; -typedef Document::JSWrapperCacheMap JSWrapperCacheMap; - -class JSGlobalDataWorldIterator { -public: - JSGlobalDataWorldIterator(JSGlobalData* globalData) - : m_pos(static_cast<WebCoreJSClientData*>(globalData->clientData)->m_worldSet.begin()) - , m_end(static_cast<WebCoreJSClientData*>(globalData->clientData)->m_worldSet.end()) - { - } - - operator bool() - { - return m_pos != m_end; - } - - DOMWrapperWorld* operator*() - { - ASSERT(m_pos != m_end); - return *m_pos; - } - - DOMWrapperWorld* operator->() - { - ASSERT(m_pos != m_end); - return *m_pos; - } - - JSGlobalDataWorldIterator& operator++() - { - ++m_pos; - return *this; - } - -private: - HashSet<DOMWrapperWorld*>::iterator m_pos; - HashSet<DOMWrapperWorld*>::iterator m_end; -}; - -const JSC::HashTable* getHashTableForGlobalData(JSGlobalData& globalData, const JSC::HashTable* staticTable) -{ - return DOMObjectHashTableMap::mapFor(globalData).get(staticTable); -} - -bool hasCachedDOMObjectWrapperUnchecked(JSGlobalData* globalData, void* objectHandle) -{ - for (JSGlobalDataWorldIterator worldIter(globalData); worldIter; ++worldIter) { - if (worldIter->m_wrappers.uncheckedGet(objectHandle)) - return true; - } - return false; -} - -bool hasCachedDOMObjectWrapper(JSGlobalData* globalData, void* objectHandle) -{ - for (JSGlobalDataWorldIterator worldIter(globalData); worldIter; ++worldIter) { - if (worldIter->m_wrappers.get(objectHandle)) - return true; - } - return false; -} - -DOMObject* getCachedDOMObjectWrapper(JSC::ExecState* exec, void* objectHandle) -{ - return domObjectWrapperMapFor(exec).get(objectHandle); -} - -void cacheDOMObjectWrapper(JSC::ExecState* exec, void* objectHandle, DOMObject* wrapper) -{ - JSDebugWrapperSet::willCacheWrapper(wrapper); - domObjectWrapperMapFor(exec).set(objectHandle, wrapper); -} - -bool hasCachedDOMNodeWrapperUnchecked(Document* document, Node* node) -{ - if (!document) - return hasCachedDOMObjectWrapperUnchecked(JSDOMWindow::commonJSGlobalData(), node); - - JSWrapperCacheMap& wrapperCacheMap = document->wrapperCacheMap(); - for (JSWrapperCacheMap::iterator iter = wrapperCacheMap.begin(); iter != wrapperCacheMap.end(); ++iter) { - if (iter->second->uncheckedGet(node)) - return true; - } - return false; -} - -void forgetDOMObject(DOMObject* wrapper, void* objectHandle) -{ - JSC::JSGlobalData* globalData = Heap::heap(wrapper)->globalData(); - - // Check the normal world first! - JSGlobalData::ClientData* clientData = globalData->clientData; - ASSERT(clientData); - DOMObjectWrapperMap& wrappers = static_cast<WebCoreJSClientData*>(clientData)->normalWorld()->m_wrappers; - if (wrappers.uncheckedRemove(objectHandle, wrapper)) { - JSDebugWrapperSet::didUncacheWrapper(wrapper); - return; - } - - // We can't guarantee that a wrapper is in the cache when it uncaches itself, - // since a new wrapper may be cached before the old wrapper's destructor runs. - for (JSGlobalDataWorldIterator worldIter(globalData); worldIter; ++worldIter) { - if (worldIter->m_wrappers.uncheckedRemove(objectHandle, wrapper)) - break; - } - JSDebugWrapperSet::didUncacheWrapper(wrapper); -} - -void forgetDOMNode(JSNode* wrapper, Node* node, Document* document) -{ - node->clearWrapper(wrapper); - - if (!document) { - forgetDOMObject(wrapper, node); - return; - } - - // We can't guarantee that a wrapper is in the cache when it uncaches itself, - // since a new wrapper may be cached before the old wrapper's destructor runs. - JSWrapperCacheMap& wrapperCacheMap = document->wrapperCacheMap(); - for (JSWrapperCacheMap::iterator wrappersIter = wrapperCacheMap.begin(); wrappersIter != wrapperCacheMap.end(); ++wrappersIter) { - if (wrappersIter->second->uncheckedRemove(node, wrapper)) - break; - } - JSDebugWrapperSet::didUncacheWrapper(wrapper); -} - -void cacheDOMNodeWrapper(JSC::ExecState* exec, Document* document, Node* node, JSNode* wrapper) -{ - JSDebugWrapperSet::willCacheWrapper(wrapper); - - if (!document) - domObjectWrapperMapFor(exec).set(node, wrapper); - else - document->getWrapperCache(currentWorld(exec))->set(node, wrapper); - - if (currentWorld(exec)->isNormal()) - node->setWrapper(wrapper); -} - -static inline bool isObservableThroughDOM(JSNode* jsNode, DOMWrapperWorld* world) -{ - // Certain conditions implicitly make existence of a JS DOM node wrapper observable - // through the DOM, even if no explicit reference to it remains. - - Node* node = jsNode->impl(); - - if (node->inDocument()) { - // If a node is in the document, and its wrapper has custom properties, - // the wrapper is observable because future access to the node through the - // DOM must reflect those properties. - if (jsNode->hasCustomProperties()) - return true; - - // If a node is in the document, and has event listeners, its wrapper is - // observable because its wrapper is responsible for marking those event listeners. - if (node->hasEventListeners()) - return true; // Technically, we may overzealously mark a wrapper for a node that has only non-JS event listeners. Oh well. - - // If a node owns another object with a wrapper with custom properties, - // the wrapper must be treated as observable, because future access to - // those objects through the DOM must reflect those properties. - // FIXME: It would be better if this logic could be in the node next to - // the custom markChildren functions rather than here. - // Note that for some compound objects like stylesheets and CSSStyleDeclarations, - // we don't descend to check children for custom properties, and just conservatively - // keep the node wrappers protecting them alive. - if (node->isElementNode()) { - if (NamedNodeMap* attributes = static_cast<Element*>(node)->attributeMap()) { - if (DOMObject* wrapper = world->m_wrappers.uncheckedGet(attributes)) { - // FIXME: This check seems insufficient, because NamedNodeMap items can have custom properties themselves. - // Maybe it would be OK to just keep the wrapper alive, as it is done for CSSOM objects below. - if (wrapper->hasCustomProperties()) - return true; - } - } - if (node->isStyledElement()) { - if (CSSMutableStyleDeclaration* style = static_cast<StyledElement*>(node)->inlineStyleDecl()) { - if (world->m_wrappers.uncheckedGet(style)) - return true; - } - } - if (static_cast<Element*>(node)->hasTagName(canvasTag)) { - if (CanvasRenderingContext* context = static_cast<HTMLCanvasElement*>(node)->renderingContext()) { - if (DOMObject* wrapper = world->m_wrappers.uncheckedGet(context)) { - if (wrapper->hasCustomProperties()) - return true; - } - } - } else if (static_cast<Element*>(node)->hasTagName(linkTag)) { - if (StyleSheet* sheet = static_cast<HTMLLinkElement*>(node)->sheet()) { - if (world->m_wrappers.uncheckedGet(sheet)) - return true; - } - } else if (static_cast<Element*>(node)->hasTagName(styleTag)) { - if (StyleSheet* sheet = static_cast<HTMLStyleElement*>(node)->sheet()) { - if (world->m_wrappers.uncheckedGet(sheet)) - return true; - } - } - } else if (node->nodeType() == Node::PROCESSING_INSTRUCTION_NODE) { - if (StyleSheet* sheet = static_cast<ProcessingInstruction*>(node)->sheet()) { - if (world->m_wrappers.uncheckedGet(sheet)) - return true; - } - } - } else { - // If a wrapper is the last reference to an image or script element - // that is loading but not in the document, the wrapper is observable - // because it is the only thing keeping the image element alive, and if - // the image element is destroyed, its load event will not fire. - // FIXME: The DOM should manage this issue without the help of JavaScript wrappers. - if (node->hasTagName(imgTag) && !static_cast<HTMLImageElement*>(node)->haveFiredLoadEvent()) - return true; - if (node->hasTagName(scriptTag) && !static_cast<HTMLScriptElement*>(node)->haveFiredLoadEvent()) - return true; -#if ENABLE(VIDEO) - if (node->hasTagName(audioTag) && !static_cast<HTMLAudioElement*>(node)->paused()) - return true; -#endif - } - - // If a node is firing event listeners, its wrapper is observable because - // its wrapper is responsible for marking those event listeners. - if (node->isFiringEventListeners()) - return true; - - return false; -} - -void markDOMNodesForDocument(MarkStack& markStack, Document* document) -{ - JSWrapperCacheMap& wrapperCacheMap = document->wrapperCacheMap(); - for (JSWrapperCacheMap::iterator wrappersIter = wrapperCacheMap.begin(); wrappersIter != wrapperCacheMap.end(); ++wrappersIter) { - DOMWrapperWorld* world = wrappersIter->first; - JSWrapperCache* nodeDict = wrappersIter->second; - - JSWrapperCache::iterator nodeEnd = nodeDict->uncheckedEnd(); - for (JSWrapperCache::iterator nodeIt = nodeDict->uncheckedBegin(); nodeIt != nodeEnd; ++nodeIt) { - JSNode* jsNode = nodeIt->second; - if (isObservableThroughDOM(jsNode, world)) - markStack.append(jsNode); - } - } -} - -void markActiveObjectsForContext(MarkStack& markStack, JSGlobalData& globalData, ScriptExecutionContext* scriptExecutionContext) -{ - // If an element has pending activity that may result in event listeners being called - // (e.g. an XMLHttpRequest), we need to keep JS wrappers alive. - - const HashMap<ActiveDOMObject*, void*>& activeObjects = scriptExecutionContext->activeDOMObjects(); - HashMap<ActiveDOMObject*, void*>::const_iterator activeObjectsEnd = activeObjects.end(); - for (HashMap<ActiveDOMObject*, void*>::const_iterator iter = activeObjects.begin(); iter != activeObjectsEnd; ++iter) { - if (iter->first->hasPendingActivity()) { - // Generally, an active object with pending activity must have a wrapper to mark its listeners. - // However, some ActiveDOMObjects don't have JS wrappers. - markDOMObjectWrapper(markStack, globalData, iter->second); - } - } - - const HashSet<MessagePort*>& messagePorts = scriptExecutionContext->messagePorts(); - HashSet<MessagePort*>::const_iterator portsEnd = messagePorts.end(); - for (HashSet<MessagePort*>::const_iterator iter = messagePorts.begin(); iter != portsEnd; ++iter) { - // If the message port is remotely entangled, then always mark it as in-use because we can't determine reachability across threads. - if (!(*iter)->locallyEntangledPort() || (*iter)->hasPendingActivity()) - markDOMObjectWrapper(markStack, globalData, *iter); - } -} - -typedef std::pair<JSNode*, DOMWrapperWorld*> WrapperAndWorld; -typedef WTF::Vector<WrapperAndWorld, 8> WrapperSet; - -static inline void takeWrappers(Node* node, Document* document, WrapperSet& wrapperSet) -{ - if (document) { - JSWrapperCacheMap& wrapperCacheMap = document->wrapperCacheMap(); - for (JSWrapperCacheMap::iterator iter = wrapperCacheMap.begin(); iter != wrapperCacheMap.end(); ++iter) { - if (JSNode* wrapper = iter->second->take(node)) { - JSDebugWrapperSet::didUncacheWrapper(wrapper); - wrapperSet.append(WrapperAndWorld(wrapper, iter->first)); - } - } - } else { - for (JSGlobalDataWorldIterator worldIter(JSDOMWindow::commonJSGlobalData()); worldIter; ++worldIter) { - DOMWrapperWorld* world = *worldIter; - if (JSNode* wrapper = static_cast<JSNode*>(world->m_wrappers.take(node))) { - JSDebugWrapperSet::didUncacheWrapper(wrapper); - wrapperSet.append(WrapperAndWorld(wrapper, world)); - } - } - } -} - -void updateDOMNodeDocument(Node* node, Document* oldDocument, Document* newDocument) -{ - ASSERT(oldDocument != newDocument); - - WrapperSet wrapperSet; - takeWrappers(node, oldDocument, wrapperSet); - - for (unsigned i = 0; i < wrapperSet.size(); ++i) { - JSNode* wrapper = wrapperSet[i].first; - JSDebugWrapperSet::willCacheWrapper(wrapper); - if (newDocument) - newDocument->getWrapperCache(wrapperSet[i].second)->set(node, wrapper); - else - wrapperSet[i].second->m_wrappers.set(node, wrapper); - } -} - -void markDOMObjectWrapper(MarkStack& markStack, JSGlobalData& globalData, void* object) -{ - // FIXME: This could be changed to only mark wrappers that are "observable" - // as markDOMNodesForDocument does, allowing us to collect more wrappers, - // but doing this correctly would be challenging. - if (!object) - return; - - for (JSGlobalDataWorldIterator worldIter(&globalData); worldIter; ++worldIter) { - if (DOMObject* wrapper = worldIter->m_wrappers.uncheckedGet(object)) - markStack.append(wrapper); - } -} - -void markDOMNodeWrapper(MarkStack& markStack, Document* document, Node* node) -{ - if (document) { - JSWrapperCacheMap& wrapperCacheMap = document->wrapperCacheMap(); - for (JSWrapperCacheMap::iterator iter = wrapperCacheMap.begin(); iter != wrapperCacheMap.end(); ++iter) { - if (JSNode* wrapper = iter->second->uncheckedGet(node)) - markStack.append(wrapper); - } - return; - } - - for (JSGlobalDataWorldIterator worldIter(JSDOMWindow::commonJSGlobalData()); worldIter; ++worldIter) { - if (DOMObject* wrapper = worldIter->m_wrappers.uncheckedGet(node)) - markStack.append(wrapper); - } -} - -static void stringWrapperDestroyed(JSString* str, void* context) -{ - StringImpl* cacheKey = static_cast<StringImpl*>(context); - JSC::JSGlobalData* globalData = Heap::heap(str)->globalData(); - - // Check the normal world first! - JSGlobalData::ClientData* clientData = globalData->clientData; - ASSERT(clientData); - JSStringCache& cache = static_cast<WebCoreJSClientData*>(clientData)->normalWorld()->m_stringCache; - if (cache.uncheckedRemove(cacheKey, str)) { - cacheKey->deref(); - return; - } - - for (JSGlobalDataWorldIterator worldIter(globalData); worldIter; ++worldIter) { - if (worldIter->m_stringCache.uncheckedRemove(cacheKey, str)) - break; - } - - cacheKey->deref(); -} - -JSValue jsStringSlowCase(ExecState* exec, JSStringCache& stringCache, StringImpl* stringImpl) -{ - // If there is a stale entry, we have to explicitly remove it to avoid - // problems down the line. - if (JSString* wrapper = stringCache.uncheckedGet(stringImpl)) - stringCache.uncheckedRemove(stringImpl, wrapper); - - JSString* wrapper = jsStringWithFinalizer(exec, UString(stringImpl), stringWrapperDestroyed, stringImpl); - stringCache.set(stringImpl, wrapper); - // ref explicitly instead of using a RefPtr-keyed hashtable because the wrapper can - // outlive the cache, so the stringImpl has to match the wrapper's lifetime. - stringImpl->ref(); - return wrapper; -} - -JSValue jsStringOrNull(ExecState* exec, const String& s) -{ - if (s.isNull()) - return jsNull(); - return jsString(exec, s); -} - -JSValue jsOwnedStringOrNull(ExecState* exec, const String& s) -{ - if (s.isNull()) - return jsNull(); - return jsOwnedString(exec, stringToUString(s)); -} - -JSValue jsOwnedStringOrNull(ExecState* exec, const UString& s) -{ - if (s.isNull()) - return jsNull(); - return jsOwnedString(exec, s); -} - -JSValue jsStringOrUndefined(ExecState* exec, const String& s) -{ - if (s.isNull()) - return jsUndefined(); - return jsString(exec, s); -} - -JSValue jsStringOrFalse(ExecState* exec, const String& s) -{ - if (s.isNull()) - return jsBoolean(false); - return jsString(exec, s); -} - -JSValue jsString(ExecState* exec, const KURL& url) -{ - return jsString(exec, url.string()); -} - -JSValue jsStringOrNull(ExecState* exec, const KURL& url) -{ - if (url.isNull()) - return jsNull(); - return jsString(exec, url.string()); -} - -JSValue jsStringOrUndefined(ExecState* exec, const KURL& url) -{ - if (url.isNull()) - return jsUndefined(); - return jsString(exec, url.string()); -} - -JSValue jsStringOrFalse(ExecState* exec, const KURL& url) -{ - if (url.isNull()) - return jsBoolean(false); - return jsString(exec, url.string()); -} - -AtomicStringImpl* findAtomicString(const Identifier& identifier) -{ - if (identifier.isNull()) - return 0; - StringImpl* impl = identifier.impl(); - ASSERT(impl->existingHash()); - return AtomicString::find(impl->characters(), impl->length(), impl->existingHash()); -} - -String valueToStringWithNullCheck(ExecState* exec, JSValue value) -{ - if (value.isNull()) - return String(); - return ustringToString(value.toString(exec)); -} - -String valueToStringWithUndefinedOrNullCheck(ExecState* exec, JSValue value) -{ - if (value.isUndefinedOrNull()) - return String(); - return ustringToString(value.toString(exec)); -} - -JSValue jsDateOrNull(ExecState* exec, double value) -{ - if (!isfinite(value)) - return jsNull(); - return new (exec) DateInstance(exec, value); -} - -double valueToDate(ExecState* exec, JSValue value) -{ - if (value.isNumber()) - return value.uncheckedGetNumber(); - if (!value.inherits(&DateInstance::info)) - return std::numeric_limits<double>::quiet_NaN(); - return static_cast<DateInstance*>(value.toObject(exec))->internalNumber(); -} - -void reportException(ExecState* exec, JSValue exception) -{ - if (exception.isObject() && asObject(exception)->exceptionType() == Terminated) - return; - - UString errorMessage = exception.toString(exec); - JSObject* exceptionObject = exception.toObject(exec); - int lineNumber = exceptionObject->get(exec, Identifier(exec, "line")).toInt32(exec); - UString exceptionSourceURL = exceptionObject->get(exec, Identifier(exec, "sourceURL")).toString(exec); - exec->clearException(); - - if (ExceptionBase* exceptionBase = toExceptionBase(exception)) - errorMessage = stringToUString(exceptionBase->message() + ": " + exceptionBase->description()); - - ScriptExecutionContext* scriptExecutionContext = static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->scriptExecutionContext(); - ASSERT(scriptExecutionContext); - - // Crash data indicates null-dereference crashes at this point in the Safari 4 Public Beta. - // It's harmless to return here without reporting the exception to the log and the debugger in this case. - if (!scriptExecutionContext) - return; - - scriptExecutionContext->reportException(ustringToString(errorMessage), lineNumber, ustringToString(exceptionSourceURL)); -} - -void reportCurrentException(ExecState* exec) -{ - JSValue exception = exec->exception(); - exec->clearException(); - reportException(exec, exception); -} - -void setDOMException(ExecState* exec, ExceptionCode ec) -{ - if (!ec || exec->hadException()) - return; - - // FIXME: All callers to setDOMException need to pass in the right global object - // for now, we're going to assume the lexicalGlobalObject. Which is wrong in cases like this: - // frames[0].document.createElement(null, null); // throws an exception which should have the subframes prototypes. - JSDOMGlobalObject* globalObject = deprecatedGlobalObjectForPrototype(exec); - - ExceptionCodeDescription description; - getExceptionCodeDescription(ec, description); - - JSValue errorObject; - switch (description.type) { - case DOMExceptionType: - errorObject = toJS(exec, globalObject, DOMCoreException::create(description)); - break; - case RangeExceptionType: - errorObject = toJS(exec, globalObject, RangeException::create(description)); - break; - case EventExceptionType: - errorObject = toJS(exec, globalObject, EventException::create(description)); - break; - case XMLHttpRequestExceptionType: - errorObject = toJS(exec, globalObject, XMLHttpRequestException::create(description)); - break; -#if ENABLE(SVG) - case SVGExceptionType: - errorObject = toJS(exec, globalObject, SVGException::create(description).get()); - break; -#endif -#if ENABLE(XPATH) - case XPathExceptionType: - errorObject = toJS(exec, globalObject, XPathException::create(description)); - break; -#endif -#if ENABLE(DATABASE) - case SQLExceptionType: - errorObject = toJS(exec, globalObject, SQLException::create(description)); - break; -#endif -#if ENABLE(BLOB) || ENABLE(FILE_SYSTEM) - case FileExceptionType: - errorObject = toJS(exec, globalObject, FileException::create(description)); - break; -#endif -#if ENABLE(INDEXED_DATABASE) - case IDBDatabaseExceptionType: - errorObject = toJS(exec, globalObject, IDBDatabaseException::create(description)); - break; -#endif - } - - ASSERT(errorObject); - throwError(exec, errorObject); -} - -bool checkNodeSecurity(ExecState* exec, Node* node) -{ - return node && allowsAccessFromFrame(exec, node->document()->frame()); -} - -bool allowsAccessFromFrame(ExecState* exec, Frame* frame) -{ - if (!frame) - return false; - JSDOMWindow* window = toJSDOMWindow(frame, currentWorld(exec)); - return window && window->allowsAccessFrom(exec); -} - -bool allowsAccessFromFrame(ExecState* exec, Frame* frame, String& message) -{ - if (!frame) - return false; - JSDOMWindow* window = toJSDOMWindow(frame, currentWorld(exec)); - return window && window->allowsAccessFrom(exec, message); -} - -bool shouldAllowNavigation(ExecState* exec, Frame* frame) -{ - JSBindingState state(exec); - return JSBindingSecurity::shouldAllowNavigation(&state, frame); -} - -bool allowSettingSrcToJavascriptURL(ExecState* exec, Element* element, const String& name, const String& value) -{ - if ((element->hasTagName(iframeTag) || element->hasTagName(frameTag)) && equalIgnoringCase(name, "src") && protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(value))) { - Document* contentDocument = static_cast<HTMLFrameElementBase*>(element)->contentDocument(); - if (contentDocument && !checkNodeSecurity(exec, contentDocument)) - return false; - } - return true; -} - -void printErrorMessageForFrame(Frame* frame, const String& message) -{ - if (!frame) - return; - frame->domWindow()->printErrorMessage(message); -} - -Frame* toLexicalFrame(ExecState* exec) -{ - return JSBindingState(exec).activeFrame(); -} - -Frame* toDynamicFrame(ExecState* exec) -{ - return JSBindingState(exec).firstFrame(); -} - -bool processingUserGesture() -{ - return JSBindingState(JSMainThreadExecState::currentState()).processingUserGesture(); -} - -KURL completeURL(ExecState* exec, const String& relativeURL) -{ - JSBindingState state(exec); - return completeURL(&state, relativeURL); -} - -JSValue objectToStringFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName) -{ - return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->prototypeFunctionStructure(), 0, propertyName, objectProtoFuncToString); -} - -Structure* getCachedDOMStructure(JSDOMGlobalObject* globalObject, const ClassInfo* classInfo) -{ - JSDOMStructureMap& structures = globalObject->structures(); - return structures.get(classInfo).get(); -} - -Structure* cacheDOMStructure(JSDOMGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, const ClassInfo* classInfo) -{ - JSDOMStructureMap& structures = globalObject->structures(); - ASSERT(!structures.contains(classInfo)); - return structures.set(classInfo, structure).first->second.get(); -} - -Structure* getCachedDOMStructure(ExecState* exec, const ClassInfo* classInfo) -{ - return getCachedDOMStructure(static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()), classInfo); -} - -Structure* cacheDOMStructure(ExecState* exec, NonNullPassRefPtr<Structure> structure, const ClassInfo* classInfo) -{ - return cacheDOMStructure(static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()), structure, classInfo); -} - -JSObject* getCachedDOMConstructor(ExecState* exec, const ClassInfo* classInfo) -{ - JSDOMConstructorMap& constructors = static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->constructors(); - return constructors.get(classInfo); -} - -void cacheDOMConstructor(ExecState* exec, const ClassInfo* classInfo, JSObject* constructor) -{ - JSDOMConstructorMap& constructors = static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->constructors(); - ASSERT(!constructors.contains(classInfo)); - constructors.set(classInfo, constructor); -} - -JSC::JSObject* toJSSequence(ExecState* exec, JSValue value, unsigned& length) -{ - JSObject* object = value.getObject(); - if (!object) { - throwTypeError(exec); - return 0; - } - JSValue lengthValue = object->get(exec, exec->propertyNames().length); - if (exec->hadException()) - return 0; - - if (lengthValue.isUndefinedOrNull()) { - throwTypeError(exec); - return 0; - } - - length = lengthValue.toUInt32(exec); - if (exec->hadException()) - return 0; - - return object; -} - -} // namespace WebCore |