From 8f72e70a9fd78eec56623b3a62e68f16b7b27e28 Mon Sep 17 00:00:00 2001 From: Feng Qian <> Date: Fri, 10 Apr 2009 18:11:29 -0700 Subject: AI 145796: Land the WebKit merge @r42026. Automated import of CL 145796 --- WebCore/bindings/js/JSAudioConstructor.cpp | 12 +- WebCore/bindings/js/JSAudioConstructor.h | 4 +- .../bindings/js/JSCSSStyleDeclarationCustom.cpp | 2 +- WebCore/bindings/js/JSCustomPositionCallback.cpp | 8 +- .../bindings/js/JSCustomPositionErrorCallback.cpp | 8 +- .../bindings/js/JSCustomSQLStatementCallback.cpp | 6 +- .../js/JSCustomSQLStatementErrorCallback.cpp | 6 +- .../bindings/js/JSCustomSQLTransactionCallback.cpp | 7 +- .../js/JSCustomSQLTransactionErrorCallback.cpp | 6 +- WebCore/bindings/js/JSCustomVoidCallback.cpp | 7 +- WebCore/bindings/js/JSCustomXPathNSResolver.cpp | 8 +- .../bindings/js/JSDOMApplicationCacheCustom.cpp | 43 +-- WebCore/bindings/js/JSDOMGlobalObject.cpp | 56 ++-- WebCore/bindings/js/JSDOMGlobalObject.h | 30 +- WebCore/bindings/js/JSDOMWindowBase.cpp | 48 ++- WebCore/bindings/js/JSDOMWindowBase.h | 4 +- WebCore/bindings/js/JSDOMWindowCustom.cpp | 12 +- WebCore/bindings/js/JSDOMWindowCustom.h | 12 +- WebCore/bindings/js/JSDOMWindowShell.cpp | 14 +- WebCore/bindings/js/JSDocumentCustom.cpp | 6 +- WebCore/bindings/js/JSEventListener.cpp | 165 ++-------- WebCore/bindings/js/JSEventListener.h | 77 ++--- WebCore/bindings/js/JSEventTarget.cpp | 53 +++- WebCore/bindings/js/JSEventTarget.h | 1 + WebCore/bindings/js/JSEventTargetNodeCustom.cpp | 71 ----- WebCore/bindings/js/JSGeolocationCustom.cpp | 9 +- WebCore/bindings/js/JSHTMLDocumentCustom.cpp | 45 ++- WebCore/bindings/js/JSHTMLInputElementCustom.cpp | 48 +-- WebCore/bindings/js/JSImageConstructor.cpp | 16 +- WebCore/bindings/js/JSImageConstructor.h | 4 +- WebCore/bindings/js/JSInspectedObjectWrapper.cpp | 4 +- WebCore/bindings/js/JSInspectorCallbackWrapper.cpp | 2 +- .../bindings/js/JSInspectorControllerCustom.cpp | 333 +++++++++++++++++++++ WebCore/bindings/js/JSLazyEventListener.cpp | 131 ++++++++ WebCore/bindings/js/JSLazyEventListener.h | 63 ++++ .../bindings/js/JSMessageChannelConstructor.cpp | 20 +- WebCore/bindings/js/JSMessageChannelConstructor.h | 5 +- WebCore/bindings/js/JSMessagePortCustom.cpp | 19 +- WebCore/bindings/js/JSNamedNodesCollection.cpp | 2 +- WebCore/bindings/js/JSNavigatorCustom.cpp | 4 - WebCore/bindings/js/JSNodeCustom.cpp | 29 ++ WebCore/bindings/js/JSNodeFilterCondition.cpp | 2 +- WebCore/bindings/js/JSOptionConstructor.cpp | 25 +- WebCore/bindings/js/JSOptionConstructor.h | 4 +- WebCore/bindings/js/JSPluginElementFunctions.cpp | 4 - WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp | 9 +- WebCore/bindings/js/JSRGBColor.cpp | 2 +- WebCore/bindings/js/JSSVGElementInstanceCustom.cpp | 4 +- WebCore/bindings/js/JSSVGPODTypeWrapper.h | 1 - WebCore/bindings/js/JSStyleSheetCustom.cpp | 1 + .../bindings/js/JSWebKitCSSMatrixConstructor.cpp | 4 +- WebCore/bindings/js/JSWebKitCSSMatrixConstructor.h | 2 +- WebCore/bindings/js/JSWebKitPointConstructor.cpp | 68 +++++ WebCore/bindings/js/JSWebKitPointConstructor.h | 46 +++ WebCore/bindings/js/JSWorkerConstructor.cpp | 1 + WebCore/bindings/js/JSWorkerContextBase.cpp | 36 ++- WebCore/bindings/js/JSWorkerContextBase.h | 2 + WebCore/bindings/js/JSWorkerContextCustom.cpp | 76 ++++- WebCore/bindings/js/JSWorkerCustom.cpp | 19 +- .../bindings/js/JSXMLHttpRequestConstructor.cpp | 19 +- WebCore/bindings/js/JSXMLHttpRequestConstructor.h | 5 +- WebCore/bindings/js/JSXMLHttpRequestCustom.cpp | 35 +-- .../bindings/js/JSXMLHttpRequestUploadCustom.cpp | 31 +- WebCore/bindings/js/JSXSLTProcessorConstructor.cpp | 2 +- WebCore/bindings/js/ScheduledAction.cpp | 7 +- WebCore/bindings/js/ScriptController.cpp | 53 ++-- WebCore/bindings/js/ScriptController.h | 2 + WebCore/bindings/js/ScriptControllerMac.mm | 6 +- WebCore/bindings/js/ScriptControllerQt.cpp | 6 +- WebCore/bindings/js/ScriptFunctionCall.cpp | 138 +++++++++ WebCore/bindings/js/ScriptFunctionCall.h | 68 +++++ WebCore/bindings/js/ScriptObject.cpp | 43 +++ WebCore/bindings/js/ScriptObject.h | 50 ++++ WebCore/bindings/js/ScriptObjectQuarantine.cpp | 85 ++++++ WebCore/bindings/js/ScriptObjectQuarantine.h | 51 ++++ WebCore/bindings/js/ScriptValue.cpp | 12 +- WebCore/bindings/js/ScriptValue.h | 6 + WebCore/bindings/js/WorkerScriptController.cpp | 40 ++- WebCore/bindings/js/WorkerScriptController.h | 4 +- 79 files changed, 1709 insertions(+), 660 deletions(-) delete mode 100644 WebCore/bindings/js/JSEventTargetNodeCustom.cpp create mode 100644 WebCore/bindings/js/JSInspectorControllerCustom.cpp create mode 100644 WebCore/bindings/js/JSLazyEventListener.cpp create mode 100644 WebCore/bindings/js/JSLazyEventListener.h create mode 100644 WebCore/bindings/js/JSWebKitPointConstructor.cpp create mode 100644 WebCore/bindings/js/JSWebKitPointConstructor.h create mode 100644 WebCore/bindings/js/ScriptFunctionCall.cpp create mode 100644 WebCore/bindings/js/ScriptFunctionCall.h create mode 100644 WebCore/bindings/js/ScriptObject.cpp create mode 100644 WebCore/bindings/js/ScriptObject.h create mode 100644 WebCore/bindings/js/ScriptObjectQuarantine.cpp create mode 100644 WebCore/bindings/js/ScriptObjectQuarantine.h (limited to 'WebCore/bindings/js') diff --git a/WebCore/bindings/js/JSAudioConstructor.cpp b/WebCore/bindings/js/JSAudioConstructor.cpp index f0bdbe8..3fd53fe 100644 --- a/WebCore/bindings/js/JSAudioConstructor.cpp +++ b/WebCore/bindings/js/JSAudioConstructor.cpp @@ -43,13 +43,19 @@ const ClassInfo JSAudioConstructor::s_info = { "AudioConstructor", 0, 0, 0 }; JSAudioConstructor::JSAudioConstructor(ExecState* exec, ScriptExecutionContext* context) : DOMObject(JSAudioConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) + , m_globalObject(toJSDOMGlobalObject(context)) { ASSERT(context->isDocument()); - m_document = static_cast(asObject(toJS(exec, static_cast(context)))); + putDirect(exec->propertyNames().prototype, JSHTMLAudioElementPrototype::self(exec), None); putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum); } +Document* JSAudioConstructor::document() const +{ + return static_cast(m_globalObject->scriptExecutionContext()); +} + static JSObject* constructAudio(ExecState* exec, JSObject* constructor, const ArgList& args) { // FIXME: Why doesn't this need the call toJS on the document like JSImageConstructor? @@ -71,8 +77,8 @@ ConstructType JSAudioConstructor::getConstructData(ConstructData& constructData) void JSAudioConstructor::mark() { DOMObject::mark(); - if (!m_document->marked()) - m_document->mark(); + if (!m_globalObject->marked()) + m_globalObject->mark(); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSAudioConstructor.h b/WebCore/bindings/js/JSAudioConstructor.h index cdff10f..1078b0f 100644 --- a/WebCore/bindings/js/JSAudioConstructor.h +++ b/WebCore/bindings/js/JSAudioConstructor.h @@ -38,7 +38,7 @@ namespace WebCore { public: JSAudioConstructor(JSC::ExecState*, ScriptExecutionContext*); - Document* document() const { return m_document->impl(); } + Document* document() const; static const JSC::ClassInfo s_info; @@ -48,7 +48,7 @@ namespace WebCore { virtual const JSC::ClassInfo* classInfo() const { return &s_info; } - JSDocument* m_document; + JSDOMGlobalObject* m_globalObject; }; } // namespace WebCore diff --git a/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp b/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp index 6c46ae4..22154ce 100644 --- a/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp +++ b/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp @@ -77,7 +77,7 @@ static String cssPropertyName(const Identifier& propertyName, bool* hadPixelOrPo return String(); Vector name; - name.reserveCapacity(length); + name.reserveInitialCapacity(length); unsigned i = 0; diff --git a/WebCore/bindings/js/JSCustomPositionCallback.cpp b/WebCore/bindings/js/JSCustomPositionCallback.cpp index cae1e1e..6b0bb43 100644 --- a/WebCore/bindings/js/JSCustomPositionCallback.cpp +++ b/WebCore/bindings/js/JSCustomPositionCallback.cpp @@ -26,10 +26,8 @@ #include "config.h" #include "JSCustomPositionCallback.h" -#include "CString.h" #include "Frame.h" #include "JSGeoposition.h" -#include "Page.h" #include "ScriptController.h" #include @@ -73,14 +71,16 @@ void JSCustomPositionCallback::handleEvent(Geoposition* geoposition, bool& raise ArgList args; args.append(toJS(exec, geoposition)); - globalObject->startTimeoutCheck(); + globalObject->globalData()->timeoutChecker.start(); call(exec, function, callType, callData, m_callback, args); - globalObject->stopTimeoutCheck(); + globalObject->globalData()->timeoutChecker.stop(); if (exec->hadException()) { reportCurrentException(exec); raisedException = true; } + + Document::updateDocumentsRendering(); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp b/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp index 766f698..ecc67dd 100644 --- a/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp +++ b/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp @@ -26,10 +26,8 @@ #include "config.h" #include "JSCustomPositionErrorCallback.h" -#include "CString.h" #include "Frame.h" #include "JSPositionError.h" -#include "Page.h" #include "ScriptController.h" #include @@ -73,12 +71,14 @@ void JSCustomPositionErrorCallback::handleEvent(PositionError* positionError) ArgList args; args.append(toJS(exec, positionError)); - globalObject->startTimeoutCheck(); + globalObject->globalData()->timeoutChecker.start(); call(exec, function, callType, callData, m_callback, args); - globalObject->stopTimeoutCheck(); + globalObject->globalData()->timeoutChecker.stop(); if (exec->hadException()) reportCurrentException(exec); + + Document::updateDocumentsRendering(); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp b/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp index f61306c..8733696 100644 --- a/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp +++ b/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp @@ -29,8 +29,6 @@ #include "config.h" #include "JSCustomSQLStatementCallback.h" -#include "CString.h" -#include "DOMWindow.h" #include "Frame.h" #include "ScriptController.h" #include "JSSQLResultSet.h" @@ -78,9 +76,9 @@ void JSCustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLR args.append(toJS(exec, transaction)); args.append(toJS(exec, resultSet)); - globalObject->startTimeoutCheck(); + globalObject->globalData()->timeoutChecker.start(); call(exec, function, callType, callData, m_callback, args); - globalObject->stopTimeoutCheck(); + globalObject->globalData()->timeoutChecker.stop(); if (exec->hadException()) { reportCurrentException(exec); diff --git a/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp index 0d27de7..dd23889 100644 --- a/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp +++ b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp @@ -29,8 +29,6 @@ #include "config.h" #include "JSCustomSQLStatementErrorCallback.h" -#include "CString.h" -#include "DOMWindow.h" #include "Frame.h" #include "ScriptController.h" #include "JSSQLError.h" @@ -81,12 +79,12 @@ bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, args.append(toJS(exec, error)); JSValuePtr result; - globalObject->startTimeoutCheck(); + globalObject->globalData()->timeoutChecker.start(); if (handleEventCallType != CallTypeNone) result = call(exec, handleEventFunction, handleEventCallType, handleEventCallData, m_callback, args); else result = call(exec, m_callback, callbackCallType, callbackCallData, m_callback, args); - globalObject->stopTimeoutCheck(); + globalObject->globalData()->timeoutChecker.stop(); if (exec->hadException()) { reportCurrentException(exec); diff --git a/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp b/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp index d6187bc..9960a0e 100644 --- a/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp +++ b/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp @@ -29,10 +29,7 @@ #include "config.h" #include "JSCustomSQLTransactionCallback.h" -#include "CString.h" -#include "DOMWindow.h" #include "Frame.h" -#include "Logging.h" #include "ScriptController.h" #include "JSSQLTransaction.h" #include "Page.h" @@ -120,12 +117,12 @@ void JSCustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bo ArgList args; args.append(toJS(exec, transaction)); - globalObject->startTimeoutCheck(); + globalObject->globalData()->timeoutChecker.start(); if (handleEventCallType != CallTypeNone) call(exec, handleEventFunction, handleEventCallType, handleEventCallData, m_data->callback(), args); else call(exec, m_data->callback(), callbackCallType, callbackCallData, m_data->callback(), args); - globalObject->stopTimeoutCheck(); + globalObject->globalData()->timeoutChecker.stop(); if (exec->hadException()) { reportCurrentException(exec); diff --git a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp index 5c8b8d4..2324d04 100644 --- a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp +++ b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp @@ -29,8 +29,6 @@ #include "config.h" #include "JSCustomSQLTransactionErrorCallback.h" -#include "CString.h" -#include "DOMWindow.h" #include "Frame.h" #include "ScriptController.h" #include "JSSQLError.h" @@ -77,9 +75,9 @@ bool JSCustomSQLTransactionErrorCallback::handleEvent(SQLError* error) args.append(toJS(exec, error)); JSValuePtr result; - globalObject->startTimeoutCheck(); + globalObject->globalData()->timeoutChecker.start(); result = call(exec, function, callType, callData, m_callback, args); - globalObject->stopTimeoutCheck(); + globalObject->globalData()->timeoutChecker.stop(); if (exec->hadException()) reportCurrentException(exec); diff --git a/WebCore/bindings/js/JSCustomVoidCallback.cpp b/WebCore/bindings/js/JSCustomVoidCallback.cpp index 60b3777..23e9fa6 100644 --- a/WebCore/bindings/js/JSCustomVoidCallback.cpp +++ b/WebCore/bindings/js/JSCustomVoidCallback.cpp @@ -29,11 +29,8 @@ #include "config.h" #include "JSCustomVoidCallback.h" -#include "CString.h" -#include "DOMWindow.h" #include "Frame.h" #include "JSDOMWindowCustom.h" -#include "JSDOMBinding.h" #include "ScriptController.h" #include @@ -76,9 +73,9 @@ void JSCustomVoidCallback::handleEvent() ArgList args; - globalObject->startTimeoutCheck(); + globalObject->globalData()->timeoutChecker.start(); call(exec, function, callType, callData, m_callback, args); - globalObject->stopTimeoutCheck(); + globalObject->globalData()->timeoutChecker.stop(); if (exec->hadException()) reportCurrentException(exec); diff --git a/WebCore/bindings/js/JSCustomXPathNSResolver.cpp b/WebCore/bindings/js/JSCustomXPathNSResolver.cpp index 6796af6..5187411 100644 --- a/WebCore/bindings/js/JSCustomXPathNSResolver.cpp +++ b/WebCore/bindings/js/JSCustomXPathNSResolver.cpp @@ -28,14 +28,10 @@ #if ENABLE(XPATH) -#include "CString.h" -#include "Console.h" -#include "DOMWindow.h" #include "Document.h" #include "ExceptionCode.h" #include "Frame.h" #include "JSDOMWindowCustom.h" -#include "JSDOMBinding.h" #include "ScriptController.h" #include @@ -99,9 +95,9 @@ String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix) ArgList args; args.append(jsString(exec, prefix)); - globalObject->startTimeoutCheck(); + globalObject->globalData()->timeoutChecker.start(); JSValuePtr retval = call(exec, function, callType, callData, m_customResolver, args); - globalObject->stopTimeoutCheck(); + globalObject->globalData()->timeoutChecker.stop(); String result; if (exec->hadException()) diff --git a/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp b/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp index 980d795..20d09dd 100644 --- a/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp +++ b/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -46,38 +46,21 @@ void JSDOMApplicationCache::mark() { DOMObject::mark(); - if (JSUnprotectedEventListener* listener = static_cast(m_impl->onchecking())) - listener->mark(); - - if (JSUnprotectedEventListener* listener = static_cast(m_impl->onerror())) - listener->mark(); - - if (JSUnprotectedEventListener* listener = static_cast(m_impl->onnoupdate())) - listener->mark(); - - if (JSUnprotectedEventListener* listener = static_cast(m_impl->ondownloading())) - listener->mark(); - - if (JSUnprotectedEventListener* listener = static_cast(m_impl->onprogress())) - listener->mark(); - - if (JSUnprotectedEventListener* listener = static_cast(m_impl->onupdateready())) - listener->mark(); - - if (JSUnprotectedEventListener* listener = static_cast(m_impl->oncached())) - listener->mark(); - - if (JSUnprotectedEventListener* listener = static_cast(m_impl->onobsolete())) - listener->mark(); + markIfNotNull(m_impl->onchecking()); + markIfNotNull(m_impl->onerror()); + markIfNotNull(m_impl->onnoupdate()); + markIfNotNull(m_impl->ondownloading()); + markIfNotNull(m_impl->onprogress()); + markIfNotNull(m_impl->onupdateready()); + markIfNotNull(m_impl->oncached()); + markIfNotNull(m_impl->onobsolete()); typedef DOMApplicationCache::EventListenersMap EventListenersMap; typedef DOMApplicationCache::ListenerVector ListenerVector; EventListenersMap& eventListeners = m_impl->eventListeners(); for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { - for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) { - JSUnprotectedEventListener* listener = static_cast(vecIter->get()); - listener->mark(); - } + for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) + (*vecIter)->mark(); } } @@ -129,7 +112,7 @@ JSValuePtr JSDOMApplicationCache::addEventListener(ExecState* exec, const ArgLis JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - RefPtr listener = globalObject->findOrCreateJSUnprotectedEventListener(exec, args.at(exec, 1)); + RefPtr listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1)); if (!listener) return jsUndefined(); impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec)); @@ -141,7 +124,7 @@ JSValuePtr JSDOMApplicationCache::removeEventListener(ExecState* exec, const Arg JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - JSUnprotectedEventListener* listener = globalObject->findJSUnprotectedEventListener(exec, args.at(exec, 1)); + JSEventListener* listener = globalObject->findJSEventListener(exec, args.at(exec, 1)); if (!listener) return jsUndefined(); impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec)); diff --git a/WebCore/bindings/js/JSDOMGlobalObject.cpp b/WebCore/bindings/js/JSDOMGlobalObject.cpp index 27dbf84..849c470 100644 --- a/WebCore/bindings/js/JSDOMGlobalObject.cpp +++ b/WebCore/bindings/js/JSDOMGlobalObject.cpp @@ -54,23 +54,23 @@ JSDOMGlobalObject::JSDOMGlobalObject(PassRefPtr structure, JSDOMGloba JSDOMGlobalObject::~JSDOMGlobalObject() { // Clear any backpointers to the window - ListenersMap::iterator i1 = d()->jsEventListeners.begin(); - ListenersMap::iterator e1 = d()->jsEventListeners.end(); + ProtectedListenersMap::iterator i1 = d()->jsProtectedEventListeners.begin(); + ProtectedListenersMap::iterator e1 = d()->jsProtectedEventListeners.end(); for (; i1 != e1; ++i1) i1->second->clearGlobalObject(); - i1 = d()->jsInlineEventListeners.begin(); - e1 = d()->jsInlineEventListeners.end(); + i1 = d()->jsProtectedInlineEventListeners.begin(); + e1 = d()->jsProtectedInlineEventListeners.end(); for (; i1 != e1; ++i1) i1->second->clearGlobalObject(); - UnprotectedListenersMap::iterator i2 = d()->jsUnprotectedEventListeners.begin(); - UnprotectedListenersMap::iterator e2 = d()->jsUnprotectedEventListeners.end(); + JSListenersMap::iterator i2 = d()->jsEventListeners.begin(); + JSListenersMap::iterator e2 = d()->jsEventListeners.end(); for (; i2 != e2; ++i2) i2->second->clearGlobalObject(); - i2 = d()->jsUnprotectedInlineEventListeners.begin(); - e2 = d()->jsUnprotectedInlineEventListeners.end(); + i2 = d()->jsInlineEventListeners.begin(); + e2 = d()->jsInlineEventListeners.end(); for (; i2 != e2; ++i2) i2->second->clearGlobalObject(); } @@ -90,66 +90,66 @@ void JSDOMGlobalObject::mark() } } -JSEventListener* JSDOMGlobalObject::findJSEventListener(JSValuePtr val, bool isInline) +JSProtectedEventListener* JSDOMGlobalObject::findJSProtectedEventListener(JSValuePtr val, bool isInline) { if (!val.isObject()) return 0; JSObject* object = asObject(val); - ListenersMap& listeners = isInline ? d()->jsInlineEventListeners : d()->jsEventListeners; + ProtectedListenersMap& listeners = isInline ? d()->jsProtectedInlineEventListeners : d()->jsProtectedEventListeners; return listeners.get(object); } -PassRefPtr JSDOMGlobalObject::findOrCreateJSEventListener(ExecState*, JSValuePtr val, bool isInline) +PassRefPtr JSDOMGlobalObject::findOrCreateJSProtectedEventListener(ExecState*, JSValuePtr val, bool isInline) { - if (JSEventListener* listener = findJSEventListener(val, isInline)) + if (JSProtectedEventListener* listener = findJSProtectedEventListener(val, isInline)) return listener; if (!val.isObject()) return 0; - // The JSEventListener constructor adds it to our jsEventListeners map. - return JSEventListener::create(asObject(val), this, isInline).get(); + // The JSProtectedEventListener constructor adds it to our jsProtectedEventListeners map. + return JSProtectedEventListener::create(asObject(val), this, isInline).get(); } -JSUnprotectedEventListener* JSDOMGlobalObject::findJSUnprotectedEventListener(ExecState*, JSValuePtr val, bool isInline) +JSEventListener* JSDOMGlobalObject::findJSEventListener(ExecState*, JSValuePtr val, bool isInline) { if (!val.isObject()) return 0; - UnprotectedListenersMap& listeners = isInline ? d()->jsUnprotectedInlineEventListeners : d()->jsUnprotectedEventListeners; + JSListenersMap& listeners = isInline ? d()->jsInlineEventListeners : d()->jsEventListeners; return listeners.get(asObject(val)); } -PassRefPtr JSDOMGlobalObject::findOrCreateJSUnprotectedEventListener(ExecState* exec, JSValuePtr val, bool isInline) +PassRefPtr JSDOMGlobalObject::findOrCreateJSEventListener(ExecState* exec, JSValuePtr val, bool isInline) { - if (JSUnprotectedEventListener* listener = findJSUnprotectedEventListener(exec, val, isInline)) + if (JSEventListener* listener = findJSEventListener(exec, val, isInline)) return listener; if (!val.isObject()) return 0; - // The JSUnprotectedEventListener constructor adds it to our jsUnprotectedEventListeners map. - return JSUnprotectedEventListener::create(asObject(val), this, isInline).get(); + // The JSEventListener constructor adds it to our jsEventListeners map. + return JSEventListener::create(asObject(val), this, isInline).get(); } -JSDOMGlobalObject::ListenersMap& JSDOMGlobalObject::jsEventListeners() +JSDOMGlobalObject::ProtectedListenersMap& JSDOMGlobalObject::jsProtectedEventListeners() { - return d()->jsEventListeners; + return d()->jsProtectedEventListeners; } -JSDOMGlobalObject::ListenersMap& JSDOMGlobalObject::jsInlineEventListeners() +JSDOMGlobalObject::ProtectedListenersMap& JSDOMGlobalObject::jsProtectedInlineEventListeners() { - return d()->jsInlineEventListeners; + return d()->jsProtectedInlineEventListeners; } -JSDOMGlobalObject::UnprotectedListenersMap& JSDOMGlobalObject::jsUnprotectedEventListeners() +JSDOMGlobalObject::JSListenersMap& JSDOMGlobalObject::jsEventListeners() { - return d()->jsUnprotectedEventListeners; + return d()->jsEventListeners; } -JSDOMGlobalObject::UnprotectedListenersMap& JSDOMGlobalObject::jsUnprotectedInlineEventListeners() +JSDOMGlobalObject::JSListenersMap& JSDOMGlobalObject::jsInlineEventListeners() { - return d()->jsUnprotectedInlineEventListeners; + return d()->jsInlineEventListeners; } void JSDOMGlobalObject::setCurrentEvent(Event* evt) diff --git a/WebCore/bindings/js/JSDOMGlobalObject.h b/WebCore/bindings/js/JSDOMGlobalObject.h index fbb3eb9..6ca3797 100644 --- a/WebCore/bindings/js/JSDOMGlobalObject.h +++ b/WebCore/bindings/js/JSDOMGlobalObject.h @@ -32,8 +32,8 @@ namespace WebCore { class Event; + class JSProtectedEventListener; class JSEventListener; - class JSUnprotectedEventListener; class ScriptExecutionContext; typedef HashMap > JSDOMStructureMap; @@ -54,24 +54,24 @@ namespace WebCore { virtual ScriptExecutionContext* scriptExecutionContext() const = 0; // Finds a wrapper of a JS EventListener, returns 0 if no existing one. - JSEventListener* findJSEventListener(JSC::JSValuePtr, bool isInline = false); + JSProtectedEventListener* findJSProtectedEventListener(JSC::JSValuePtr, bool isInline = false); // Finds or creates a wrapper of a JS EventListener. JS EventListener object is GC-protected. - PassRefPtr findOrCreateJSEventListener(JSC::ExecState*, JSC::JSValuePtr, bool isInline = false); + PassRefPtr findOrCreateJSProtectedEventListener(JSC::ExecState*, JSC::JSValuePtr, bool isInline = false); // Finds a wrapper of a GC-unprotected JS EventListener, returns 0 if no existing one. - JSUnprotectedEventListener* findJSUnprotectedEventListener(JSC::ExecState*, JSC::JSValuePtr, bool isInline = false); + JSEventListener* findJSEventListener(JSC::ExecState*, JSC::JSValuePtr, bool isInline = false); // Finds or creates a wrapper of a JS EventListener. JS EventListener object is *NOT* GC-protected. - PassRefPtr findOrCreateJSUnprotectedEventListener(JSC::ExecState*, JSC::JSValuePtr, bool isInline = false); + PassRefPtr findOrCreateJSEventListener(JSC::ExecState*, JSC::JSValuePtr, bool isInline = false); - typedef HashMap ListenersMap; - typedef HashMap UnprotectedListenersMap; + typedef HashMap ProtectedListenersMap; + typedef HashMap JSListenersMap; - ListenersMap& jsEventListeners(); - ListenersMap& jsInlineEventListeners(); - UnprotectedListenersMap& jsUnprotectedEventListeners(); - UnprotectedListenersMap& jsUnprotectedInlineEventListeners(); + ProtectedListenersMap& jsProtectedEventListeners(); + ProtectedListenersMap& jsProtectedInlineEventListeners(); + JSListenersMap& jsEventListeners(); + JSListenersMap& jsInlineEventListeners(); void setCurrentEvent(Event*); Event* currentEvent(); @@ -85,10 +85,10 @@ namespace WebCore { JSDOMStructureMap structures; JSDOMConstructorMap constructors; - JSDOMGlobalObject::ListenersMap jsEventListeners; - JSDOMGlobalObject::ListenersMap jsInlineEventListeners; - JSDOMGlobalObject::UnprotectedListenersMap jsUnprotectedEventListeners; - JSDOMGlobalObject::UnprotectedListenersMap jsUnprotectedInlineEventListeners; + JSDOMGlobalObject::ProtectedListenersMap jsProtectedEventListeners; + JSDOMGlobalObject::ProtectedListenersMap jsProtectedInlineEventListeners; + JSDOMGlobalObject::JSListenersMap jsEventListeners; + JSDOMGlobalObject::JSListenersMap jsInlineEventListeners; Event* evt; }; diff --git a/WebCore/bindings/js/JSDOMWindowBase.cpp b/WebCore/bindings/js/JSDOMWindowBase.cpp index 83bc202..5e5ac2f 100644 --- a/WebCore/bindings/js/JSDOMWindowBase.cpp +++ b/WebCore/bindings/js/JSDOMWindowBase.cpp @@ -28,26 +28,21 @@ #include "DOMTimer.h" #include "DOMWindow.h" #include "Element.h" -#include "EventListener.h" -#include "ExceptionCode.h" #include "FloatRect.h" #include "Frame.h" #include "FrameLoadRequest.h" -#include "FrameLoader.h" -#include "FrameTree.h" -#include "GCController.h" #include "HTMLDocument.h" #include "InspectorController.h" #include "JSAudioConstructor.h" #include "JSDOMWindowCustom.h" #include "JSEvent.h" -#include "JSEventListener.h" #include "JSHTMLCollection.h" #include "JSImageConstructor.h" #include "JSMessageChannelConstructor.h" #include "JSNode.h" #include "JSWebKitCSSMatrixConstructor.h" #include "JSOptionConstructor.h" +#include "JSWebKitPointConstructor.h" #include "JSWorkerConstructor.h" #include "JSXMLHttpRequestConstructor.h" #include "JSXSLTProcessorConstructor.h" @@ -62,10 +57,7 @@ #include "SecurityOrigin.h" #include "Settings.h" #include "WindowFeatures.h" -#include "htmlediting.h" -#include #include -#include #include using namespace JSC; @@ -91,6 +83,8 @@ static JSValuePtr jsDOMWindowBaseOption(ExecState*, const Identifier&, const Pro static void setJSDOMWindowBaseOption(ExecState*, JSObject*, JSValuePtr); static JSValuePtr jsDOMWindowBaseWebKitCSSMatrix(ExecState*, const Identifier&, const PropertySlot&); static void setJSDOMWindowBaseWebKitCSSMatrix(ExecState*, JSObject*, JSValuePtr); +static JSValuePtr jsDOMWindowBaseWebKitPoint(ExecState*, const Identifier&, const PropertySlot&); +static void setJSDOMWindowBaseWebKitPoint(ExecState*, JSObject*, JSValuePtr); static JSValuePtr jsDOMWindowBaseXMLHttpRequest(ExecState*, const Identifier&, const PropertySlot&); static void setJSDOMWindowBaseXMLHttpRequest(ExecState*, JSObject*, JSValuePtr); static JSValuePtr jsDOMWindowBaseXSLTProcessor(ExecState*, const Identifier&, const PropertySlot&); @@ -121,6 +115,7 @@ const ClassInfo JSDOMWindowBase::s_info = { "Window", 0, &JSDOMWindowBaseTable, MessageChannel jsDOMWindowBaseMessageChannel DontDelete Option jsDOMWindowBaseOption DontDelete WebKitCSSMatrix jsDOMWindowBaseWebKitCSSMatrix DontDelete + WebKitPoint jsDOMWindowBaseWebKitPoint DontDelete Worker jsDOMWindowBaseWorker DontDelete XMLHttpRequest jsDOMWindowBaseXMLHttpRequest DontDelete XSLTProcessor jsDOMWindowBaseXSLTProcessor DontDelete @@ -137,9 +132,6 @@ JSDOMWindowBase::JSDOMWindowBaseData::JSDOMWindowBaseData(PassRefPtr JSDOMWindowBase::JSDOMWindowBase(PassRefPtr structure, PassRefPtr window, JSDOMWindowShell* shell) : JSDOMGlobalObject(structure, new JSDOMWindowBaseData(window, shell), shell) { - // Time in milliseconds before the script timeout handler kicks in. - setTimeoutTime(10000); - GlobalPropertyInfo staticGlobals[] = { GlobalPropertyInfo(Identifier(globalExec(), "document"), jsNull(), DontDelete | ReadOnly), GlobalPropertyInfo(Identifier(globalExec(), "window"), d()->shell, DontDelete | ReadOnly) @@ -409,7 +401,7 @@ JSValuePtr jsDOMWindowBaseWebKitCSSMatrix(ExecState* exec, const Identifier&, co { if (!static_cast(asObject(slot.slotBase()))->allowsAccessFrom(exec)) return jsUndefined(); - return getDOMConstructor(exec, static_cast(asObject(slot.slotBase()))); + return getDOMConstructor(exec); } JSValuePtr jsDOMWindowBaseXMLHttpRequest(ExecState* exec, const Identifier&, const PropertySlot& slot) @@ -428,10 +420,19 @@ JSValuePtr jsDOMWindowBaseAudio(ExecState* exec, const Identifier&, const Proper return jsUndefined(); return getDOMConstructor(exec, static_cast(asObject(slot.slotBase()))); #else + UNUSED_PARAM(exec); + UNUSED_PARAM(slot); return jsUndefined(); #endif } +JSValuePtr jsDOMWindowBaseWebKitPoint(ExecState* exec, const Identifier&, const PropertySlot& slot) +{ + if (!static_cast(asObject(slot.slotBase()))->allowsAccessFrom(exec)) + return jsUndefined(); + return getDOMConstructor(exec); +} + JSValuePtr jsDOMWindowBaseWorker(ExecState* exec, const Identifier&, const PropertySlot& slot) { #if ENABLE(WORKERS) @@ -439,6 +440,8 @@ JSValuePtr jsDOMWindowBaseWorker(ExecState* exec, const Identifier&, const Prope return jsUndefined(); return getDOMConstructor(exec); #else + UNUSED_PARAM(exec); + UNUSED_PARAM(slot); return jsUndefined(); #endif } @@ -450,6 +453,8 @@ JSValuePtr jsDOMWindowBaseXSLTProcessor(ExecState* exec, const Identifier&, cons return jsUndefined(); return getDOMConstructor(exec); #else + UNUSED_PARAM(exec); + UNUSED_PARAM(slot); return jsUndefined(); #endif } @@ -510,6 +515,14 @@ void setJSDOMWindowBaseWebKitCSSMatrix(ExecState* exec, JSObject* thisObject, JS static_cast(thisObject)->putDirect(Identifier(exec, "WebKitCSSMatrix"), value); } +void setJSDOMWindowBaseWebKitPoint(ExecState* exec, JSObject* thisObject, JSValuePtr value) +{ + if (!static_cast(thisObject)->allowsAccessFrom(exec)) + return; + // Shadowing a built-in constructor + static_cast(thisObject)->putDirect(Identifier(exec, "WebKitPoint"), value); +} + void setJSDOMWindowBaseXMLHttpRequest(ExecState* exec, JSObject* thisObject, JSValuePtr value) { if (!static_cast(thisObject)->allowsAccessFrom(exec)) @@ -609,7 +622,7 @@ bool JSDOMWindowBase::getOwnPropertySlot(ExecState* exec, const Identifier& prop // Allow shortcuts like 'Image1' instead of document.images.Image1 Document* document = impl()->frame()->document(); - if (document && document->isHTMLDocument()) { + if (document->isHTMLDocument()) { AtomicStringImpl* atomicPropertyName = AtomicString::find(propertyName); if (atomicPropertyName && (static_cast(document)->hasNamedItem(atomicPropertyName) || document->hasElementWithId(atomicPropertyName))) { slot.setCustom(this, namedItemGetter); @@ -735,7 +748,12 @@ JSDOMWindowShell* JSDOMWindowBase::shell() const JSGlobalData* JSDOMWindowBase::commonJSGlobalData() { - static JSGlobalData* globalData = JSGlobalData::createLeaked().releaseRef(); + static JSGlobalData* globalData; + if (!globalData) { + globalData = JSGlobalData::createLeaked().releaseRef(); + globalData->timeoutChecker.setTimeoutInterval(10000); // 10 seconds + } + return globalData; } diff --git a/WebCore/bindings/js/JSDOMWindowBase.h b/WebCore/bindings/js/JSDOMWindowBase.h index 2398172..ef87f20 100644 --- a/WebCore/bindings/js/JSDOMWindowBase.h +++ b/WebCore/bindings/js/JSDOMWindowBase.h @@ -34,9 +34,9 @@ namespace WebCore { class Frame; class JSDOMWindow; class JSDOMWindowShell; - class JSEventListener; + class JSProtectedEventListener; class JSLocation; - class JSUnprotectedEventListener; + class JSEventListener; class ScheduledAction; class SecurityOrigin; diff --git a/WebCore/bindings/js/JSDOMWindowCustom.cpp b/WebCore/bindings/js/JSDOMWindowCustom.cpp index 562e661..703ad8a 100644 --- a/WebCore/bindings/js/JSDOMWindowCustom.cpp +++ b/WebCore/bindings/js/JSDOMWindowCustom.cpp @@ -268,10 +268,8 @@ JSValuePtr JSDOMWindow::addEventListener(ExecState* exec, const ArgList& args) if (!frame) return jsUndefined(); - if (RefPtr listener = findOrCreateJSEventListener(exec, args.at(exec, 1))) { - if (Document* doc = frame->document()) - doc->addWindowEventListener(AtomicString(args.at(exec, 0).toString(exec)), listener.release(), args.at(exec, 2).toBoolean(exec)); - } + if (RefPtr listener = findOrCreateJSProtectedEventListener(exec, args.at(exec, 1))) + frame->document()->addWindowEventListener(AtomicString(args.at(exec, 0).toString(exec)), listener.release(), args.at(exec, 2).toBoolean(exec)); return jsUndefined(); } @@ -282,10 +280,8 @@ JSValuePtr JSDOMWindow::removeEventListener(ExecState* exec, const ArgList& args if (!frame) return jsUndefined(); - if (JSEventListener* listener = findJSEventListener(args.at(exec, 1))) { - if (Document* doc = frame->document()) - doc->removeWindowEventListener(AtomicString(args.at(exec, 0).toString(exec)), listener, args.at(exec, 2).toBoolean(exec)); - } + if (JSProtectedEventListener* listener = findJSProtectedEventListener(args.at(exec, 1))) + frame->document()->removeWindowEventListener(AtomicString(args.at(exec, 0).toString(exec)), listener, args.at(exec, 2).toBoolean(exec)); return jsUndefined(); } diff --git a/WebCore/bindings/js/JSDOMWindowCustom.h b/WebCore/bindings/js/JSDOMWindowCustom.h index 838abab..73a9656 100644 --- a/WebCore/bindings/js/JSDOMWindowCustom.h +++ b/WebCore/bindings/js/JSDOMWindowCustom.h @@ -74,12 +74,10 @@ ALWAYS_INLINE bool JSDOMWindow::customGetOwnPropertySlot(JSC::ExecState* exec, c // is allowed. bool allowsAccess = allowsAccessFromNoErrorMessage(exec); - // Look for overrides before looking at any of our own properties. - if (JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot)) { - // But ignore overrides completely if this is cross-domain access. - if (allowsAccess) - return true; - } + // Look for overrides before looking at any of our own properties, but ignore overrides completely + // if this is cross-domain access. + if (allowsAccess && JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot)) + return true; // We need this code here because otherwise JSC::Window will stop the search before we even get to the // prototype due to the blanket same origin (allowsAccessFrom) check at the end of getOwnPropertySlot. @@ -128,7 +126,7 @@ inline bool JSDOMWindow::customPut(JSC::ExecState* exec, const JSC::Identifier& if (!impl()->frame()) return true; - // We have a local override (e.g. "var location"), save time and jump directly to JSGlobalObject. + // Optimization: access JavaScript global variables directly before involving the DOM. JSC::PropertySlot getSlot; bool slotIsWriteable; if (JSGlobalObject::getOwnPropertySlot(exec, propertyName, getSlot, slotIsWriteable)) { diff --git a/WebCore/bindings/js/JSDOMWindowShell.cpp b/WebCore/bindings/js/JSDOMWindowShell.cpp index d54611e..f14c2f7 100644 --- a/WebCore/bindings/js/JSDOMWindowShell.cpp +++ b/WebCore/bindings/js/JSDOMWindowShell.cpp @@ -39,7 +39,7 @@ using namespace JSC; namespace WebCore { -ASSERT_CLASS_FITS_IN_CELL(JSDOMWindowShell) +ASSERT_CLASS_FITS_IN_CELL(JSDOMWindowShell); const ClassInfo JSDOMWindowShell::s_info = { "JSDOMWindowShell", 0, 0, 0 }; @@ -54,11 +54,17 @@ JSDOMWindowShell::~JSDOMWindowShell() { } -void JSDOMWindowShell::setWindow(PassRefPtr window) +void JSDOMWindowShell::setWindow(PassRefPtr domWindow) { + // Explicitly protect the global object's prototype so it isn't collected + // when we allocate the global object. (Once the global object is fully + // constructed, it can mark its own prototype.) RefPtr prototypeStructure = JSDOMWindowPrototype::createStructure(jsNull()); - RefPtr structure = JSDOMWindow::createStructure(new JSDOMWindowPrototype(prototypeStructure.release())); - setWindow(new (JSDOMWindow::commonJSGlobalData()) JSDOMWindow(structure.release(), window, this)); + ProtectedPtr prototype = new JSDOMWindowPrototype(prototypeStructure.release()); + + RefPtr structure = JSDOMWindow::createStructure(prototype); + JSDOMWindow* jsDOMWindow = new (JSDOMWindow::commonJSGlobalData()) JSDOMWindow(structure.release(), domWindow, this); + setWindow(jsDOMWindow); } // ---- diff --git a/WebCore/bindings/js/JSDocumentCustom.cpp b/WebCore/bindings/js/JSDocumentCustom.cpp index fff0ea5..c432aea 100644 --- a/WebCore/bindings/js/JSDocumentCustom.cpp +++ b/WebCore/bindings/js/JSDocumentCustom.cpp @@ -20,7 +20,6 @@ #include "config.h" #include "JSDocument.h" -#include "DOMWindow.h" #include "ExceptionCode.h" #include "Frame.h" #include "FrameLoader.h" @@ -28,9 +27,6 @@ #include "JSDOMWindowCustom.h" #include "JSHTMLDocument.h" #include "JSLocation.h" -#include "JSNodeList.h" -#include "Location.h" -#include "NodeList.h" #include "ScriptController.h" #if ENABLE(SVG) @@ -44,7 +40,7 @@ namespace WebCore { void JSDocument::mark() { - JSEventTargetNode::mark(); + JSNode::mark(); markDOMNodesForDocument(impl()); markActiveObjectsForContext(*Heap::heap(this)->globalData(), impl()); } diff --git a/WebCore/bindings/js/JSEventListener.cpp b/WebCore/bindings/js/JSEventListener.cpp index 4eb00fa..4c9cf0d 100644 --- a/WebCore/bindings/js/JSEventListener.cpp +++ b/WebCore/bindings/js/JSEventListener.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,19 +20,10 @@ #include "config.h" #include "JSEventListener.h" -#include "CString.h" -#include "Console.h" -#include "DOMWindow.h" -#include "Document.h" #include "Event.h" #include "Frame.h" -#include "FrameLoader.h" -#include "JSDOMWindow.h" #include "JSEvent.h" #include "JSEventTarget.h" -#include "JSEventTargetNode.h" -#include "ScriptController.h" -#include #include #include @@ -40,13 +31,11 @@ using namespace JSC; namespace WebCore { -ASSERT_CLASS_FITS_IN_CELL(JSAbstractEventListener) - void JSAbstractEventListener::handleEvent(Event* event, bool isWindowEvent) { JSLock lock(false); - JSObject* listener = listenerObj(); + JSObject* listener = function(); if (!listener) return; @@ -103,7 +92,7 @@ void JSAbstractEventListener::handleEvent(Event* event, bool isWindowEvent) JSValuePtr retval; if (handleEventFunction) { - globalObject->startTimeoutCheck(); + globalObject->globalData()->timeoutChecker.start(); retval = call(exec, handleEventFunction, callType, callData, listener, args); } else { JSValuePtr thisValue; @@ -111,10 +100,10 @@ void JSAbstractEventListener::handleEvent(Event* event, bool isWindowEvent) thisValue = globalObject->toThisObject(exec); else thisValue = toJS(exec, event->currentTarget()); - globalObject->startTimeoutCheck(); + globalObject->globalData()->timeoutChecker.start(); retval = call(exec, listener, callType, callData, thisValue, args); } - globalObject->stopTimeoutCheck(); + globalObject->globalData()->timeoutChecker.stop(); globalObject->setCurrentEvent(savedEvent); @@ -136,50 +125,50 @@ void JSAbstractEventListener::handleEvent(Event* event, bool isWindowEvent) } } -bool JSAbstractEventListener::isInline() const +bool JSAbstractEventListener::virtualIsInline() const { return m_isInline; } // ------------------------------------------------------------------------- -JSUnprotectedEventListener::JSUnprotectedEventListener(JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline) +JSEventListener::JSEventListener(JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline) : JSAbstractEventListener(isInline) , m_listener(listener) , m_globalObject(globalObject) { if (m_listener) { - JSDOMWindow::UnprotectedListenersMap& listeners = isInline - ? globalObject->jsUnprotectedInlineEventListeners() : globalObject->jsUnprotectedEventListeners(); + JSDOMWindow::JSListenersMap& listeners = isInline + ? globalObject->jsInlineEventListeners() : globalObject->jsEventListeners(); listeners.set(m_listener, this); } } -JSUnprotectedEventListener::~JSUnprotectedEventListener() +JSEventListener::~JSEventListener() { if (m_listener && m_globalObject) { - JSDOMWindow::UnprotectedListenersMap& listeners = isInline() - ? m_globalObject->jsUnprotectedInlineEventListeners() : m_globalObject->jsUnprotectedEventListeners(); + JSDOMWindow::JSListenersMap& listeners = isInline() + ? m_globalObject->jsInlineEventListeners() : m_globalObject->jsEventListeners(); listeners.remove(m_listener); } } -JSObject* JSUnprotectedEventListener::listenerObj() const +JSObject* JSEventListener::function() const { return m_listener; } -JSDOMGlobalObject* JSUnprotectedEventListener::globalObject() const +JSDOMGlobalObject* JSEventListener::globalObject() const { return m_globalObject; } -void JSUnprotectedEventListener::clearGlobalObject() +void JSEventListener::clearGlobalObject() { m_globalObject = 0; } -void JSUnprotectedEventListener::mark() +void JSEventListener::mark() { if (m_listener && !m_listener->marked()) m_listener->mark(); @@ -191,14 +180,14 @@ static WTF::RefCountedLeakCounter eventListenerCounter("EventListener"); // ------------------------------------------------------------------------- -JSEventListener::JSEventListener(JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline) +JSProtectedEventListener::JSProtectedEventListener(JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline) : JSAbstractEventListener(isInline) , m_listener(listener) , m_globalObject(globalObject) { if (m_listener) { - JSDOMWindow::ListenersMap& listeners = isInline - ? m_globalObject->jsInlineEventListeners() : m_globalObject->jsEventListeners(); + JSDOMWindow::ProtectedListenersMap& listeners = isInline + ? m_globalObject->jsProtectedInlineEventListeners() : m_globalObject->jsProtectedEventListeners(); listeners.set(m_listener, this); } #ifndef NDEBUG @@ -206,11 +195,11 @@ JSEventListener::JSEventListener(JSObject* listener, JSDOMGlobalObject* globalOb #endif } -JSEventListener::~JSEventListener() +JSProtectedEventListener::~JSProtectedEventListener() { if (m_listener && m_globalObject) { - JSDOMWindow::ListenersMap& listeners = isInline() - ? m_globalObject->jsInlineEventListeners() : m_globalObject->jsEventListeners(); + JSDOMWindow::ProtectedListenersMap& listeners = isInline() + ? m_globalObject->jsProtectedInlineEventListeners() : m_globalObject->jsProtectedEventListeners(); listeners.remove(m_listener); } #ifndef NDEBUG @@ -218,123 +207,19 @@ JSEventListener::~JSEventListener() #endif } -JSObject* JSEventListener::listenerObj() const +JSObject* JSProtectedEventListener::function() const { return m_listener; } -JSDOMGlobalObject* JSEventListener::globalObject() const +JSDOMGlobalObject* JSProtectedEventListener::globalObject() const { return m_globalObject; } -void JSEventListener::clearGlobalObject() +void JSProtectedEventListener::clearGlobalObject() { m_globalObject = 0; } -// ------------------------------------------------------------------------- - -JSLazyEventListener::JSLazyEventListener(LazyEventListenerType type, const String& functionName, const String& code, JSDOMGlobalObject* globalObject, Node* node, int lineNumber) - : JSEventListener(0, globalObject, true) - , m_functionName(functionName) - , m_code(code) - , m_parsed(false) - , m_lineNumber(lineNumber) - , m_originalNode(node) - , m_type(type) -{ - // We don't retain the original node because we assume it - // will stay alive as long as this handler object is around - // and we need to avoid a reference cycle. If JS transfers - // this handler to another node, parseCode will be called and - // then originalNode is no longer needed. - - // A JSLazyEventListener can be created with a line number of zero when it is created with - // a setAttribute call from JavaScript, so make the line number 1 in that case. - if (m_lineNumber == 0) - m_lineNumber = 1; -} - -JSObject* JSLazyEventListener::listenerObj() const -{ - parseCode(); - return m_listener; -} - -// Helper function -inline JSValuePtr eventParameterName(JSLazyEventListener::LazyEventListenerType type, ExecState* exec) -{ - switch (type) { - case JSLazyEventListener::HTMLLazyEventListener: - return jsNontrivialString(exec, "event"); -#if ENABLE(SVG) - case JSLazyEventListener::SVGLazyEventListener: - return jsNontrivialString(exec, "evt"); -#endif - default: - ASSERT_NOT_REACHED(); - return jsUndefined(); - } -} - -void JSLazyEventListener::parseCode() const -{ - if (m_parsed) - return; - - if (globalObject()->scriptExecutionContext()->isDocument()) { - JSDOMWindow* window = static_cast(globalObject()); - Frame* frame = window->impl()->frame(); - if (!frame) - return; - // FIXME: Is this check needed for non-Document contexts? - ScriptController* script = frame->script(); - if (!script->isEnabled() || script->isPaused()) - return; - } - - m_parsed = true; - - ExecState* exec = globalObject()->globalExec(); - - ArgList args; - UString sourceURL(globalObject()->scriptExecutionContext()->url().string()); - args.append(eventParameterName(m_type, exec)); - args.append(jsString(exec, m_code)); - - // FIXME: Passing the document's URL to construct is not always correct, since this event listener might - // have been added with setAttribute from a script, and we should pass String() in that case. - m_listener = constructFunction(exec, args, Identifier(exec, m_functionName), sourceURL, m_lineNumber); // FIXME: is globalExec ok? - - JSFunction* listenerAsFunction = static_cast(m_listener.get()); - - if (exec->hadException()) { - exec->clearException(); - - // failed to parse, so let's just make this listener a no-op - m_listener = 0; - } else if (m_originalNode) { - // Add the event's home element to the scope - // (and the document, and the form - see JSHTMLElement::eventHandlerScope) - ScopeChain scope = listenerAsFunction->scope(); - - JSValuePtr thisObj = toJS(exec, m_originalNode); - if (thisObj.isObject()) { - static_cast(asObject(thisObj))->pushEventHandlerScope(exec, scope); - listenerAsFunction->setScope(scope); - } - } - - // no more need to keep the unparsed code around - m_functionName = String(); - m_code = String(); - - if (m_listener) { - ASSERT(isInline()); - JSDOMWindow::ListenersMap& listeners = globalObject()->jsInlineEventListeners(); - listeners.set(m_listener, const_cast(this)); - } -} - } // namespace WebCore diff --git a/WebCore/bindings/js/JSEventListener.h b/WebCore/bindings/js/JSEventListener.h index 859d5d4..9589001 100644 --- a/WebCore/bindings/js/JSEventListener.h +++ b/WebCore/bindings/js/JSEventListener.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,21 +21,15 @@ #define JSEventListener_h #include "EventListener.h" -#include "PlatformString.h" #include namespace WebCore { - class Event; class JSDOMGlobalObject; - class Node; class JSAbstractEventListener : public EventListener { public: - virtual void handleEvent(Event*, bool isWindowEvent); - virtual bool isInline() const; - virtual JSC::JSObject* listenerObj() const = 0; - virtual JSDOMGlobalObject* globalObject() const = 0; + bool isInline() const { return m_isInline; } protected: JSAbstractEventListener(bool isInline) @@ -44,80 +38,53 @@ namespace WebCore { } private: + virtual void handleEvent(Event*, bool isWindowEvent); + virtual JSDOMGlobalObject* globalObject() const = 0; + virtual bool virtualIsInline() const; + bool m_isInline; }; - class JSUnprotectedEventListener : public JSAbstractEventListener { + class JSEventListener : public JSAbstractEventListener { public: - static PassRefPtr create(JSC::JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline) + static PassRefPtr create(JSC::JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline) { - return adoptRef(new JSUnprotectedEventListener(listener, globalObject, isInline)); + return adoptRef(new JSEventListener(listener, globalObject, isInline)); } - virtual ~JSUnprotectedEventListener(); + virtual ~JSEventListener(); - virtual JSC::JSObject* listenerObj() const; - virtual JSDOMGlobalObject* globalObject() const; void clearGlobalObject(); - void mark(); private: - JSUnprotectedEventListener(JSC::JSObject* listener, JSDOMGlobalObject*, bool isInline); + JSEventListener(JSC::JSObject* listener, JSDOMGlobalObject*, bool isInline); + + virtual JSC::JSObject* function() const; + virtual void mark(); + virtual JSDOMGlobalObject* globalObject() const; JSC::JSObject* m_listener; JSDOMGlobalObject* m_globalObject; }; - class JSEventListener : public JSAbstractEventListener { + class JSProtectedEventListener : public JSAbstractEventListener { public: - static PassRefPtr create(JSC::JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline) + static PassRefPtr create(JSC::JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline) { - return adoptRef(new JSEventListener(listener, globalObject, isInline)); + return adoptRef(new JSProtectedEventListener(listener, globalObject, isInline)); } - virtual ~JSEventListener(); + virtual ~JSProtectedEventListener(); - virtual JSC::JSObject* listenerObj() const; - virtual JSDOMGlobalObject* globalObject() const; void clearGlobalObject(); protected: - JSEventListener(JSC::JSObject* listener, JSDOMGlobalObject*, bool isInline); + JSProtectedEventListener(JSC::JSObject* listener, JSDOMGlobalObject*, bool isInline); mutable JSC::ProtectedPtr m_listener; - - private: JSC::ProtectedPtr m_globalObject; - }; - - class JSLazyEventListener : public JSEventListener { - public: - enum LazyEventListenerType { - HTMLLazyEventListener -#if ENABLE(SVG) - , SVGLazyEventListener -#endif - }; - - virtual bool wasCreatedFromMarkup() const { return true; } - - static PassRefPtr create(LazyEventListenerType type, const String& functionName, const String& code, JSDOMGlobalObject* globalObject, Node* node, int lineNumber) - { - return adoptRef(new JSLazyEventListener(type, functionName, code, globalObject, node, lineNumber)); - } - virtual JSC::JSObject* listenerObj() const; - - protected: - JSLazyEventListener(LazyEventListenerType type, const String& functionName, const String& code, JSDOMGlobalObject*, Node*, int lineNumber); private: - void parseCode() const; - - mutable String m_functionName; - mutable String m_code; - mutable bool m_parsed; - int m_lineNumber; - Node* m_originalNode; - - LazyEventListenerType m_type; + virtual JSC::JSObject* function() const; + virtual JSDOMGlobalObject* globalObject() const; }; } // namespace WebCore diff --git a/WebCore/bindings/js/JSEventTarget.cpp b/WebCore/bindings/js/JSEventTarget.cpp index fb72ce7..d9cff4a 100644 --- a/WebCore/bindings/js/JSEventTarget.cpp +++ b/WebCore/bindings/js/JSEventTarget.cpp @@ -28,23 +28,31 @@ #include "Document.h" #include "JSEventListener.h" -#include "JSEventTargetNode.h" #include "JSMessagePort.h" -#ifdef ANDROID_FIX // these are generated files, need to check ENABLE(WORKERS) -#if ENABLE(WORKERS) -#include "JSWorker.h" -#include "JSWorkerContext.h" -#endif -#endif +#include "JSNode.h" +#include "JSXMLHttpRequest.h" #include "JSXMLHttpRequestUpload.h" -#include "Worker.h" -#include "WorkerContext.h" +#include "MessagePort.h" +#include "XMLHttpRequest.h" +#include "XMLHttpRequestUpload.h" + +#if ENABLE(OFFLINE_WEB_APPLICATIONS) +#include "DOMApplicationCache.h" +#include "JSDOMApplicationCache.h" +#endif #if ENABLE(SVG) #include "SVGElementInstance.h" #include "JSSVGElementInstance.h" #endif +#if ENABLE(WORKERS) +#include "JSWorker.h" +#include "JSWorkerContext.h" +#include "Worker.h" +#include "WorkerContext.h" +#endif + using namespace JSC; namespace WebCore { @@ -91,4 +99,31 @@ JSValuePtr toJS(ExecState* exec, EventTarget* target) return jsNull(); } +EventTarget* toEventTarget(JSC::JSValuePtr value) +{ + #define CONVERT_TO_EVENT_TARGET(type) \ + if (value.isObject(&JS##type::s_info)) \ + return static_cast(asObject(value))->impl(); + + CONVERT_TO_EVENT_TARGET(Node) + CONVERT_TO_EVENT_TARGET(XMLHttpRequest) + CONVERT_TO_EVENT_TARGET(XMLHttpRequestUpload) + CONVERT_TO_EVENT_TARGET(MessagePort) + +#if ENABLE(OFFLINE_WEB_APPLICATIONS) + CONVERT_TO_EVENT_TARGET(DOMApplicationCache) +#endif + +#if ENABLE(SVG) + CONVERT_TO_EVENT_TARGET(SVGElementInstance) +#endif + +#if ENABLE(WORKERS) + CONVERT_TO_EVENT_TARGET(Worker) + CONVERT_TO_EVENT_TARGET(WorkerContext) +#endif + + return 0; +} + } // namespace WebCore diff --git a/WebCore/bindings/js/JSEventTarget.h b/WebCore/bindings/js/JSEventTarget.h index 00dd848..02f3734 100644 --- a/WebCore/bindings/js/JSEventTarget.h +++ b/WebCore/bindings/js/JSEventTarget.h @@ -37,6 +37,7 @@ namespace WebCore { class EventTarget; JSC::JSValuePtr toJS(JSC::ExecState*, EventTarget*); + EventTarget* toEventTarget(JSC::JSValuePtr); } // namespace WebCore diff --git a/WebCore/bindings/js/JSEventTargetNodeCustom.cpp b/WebCore/bindings/js/JSEventTargetNodeCustom.cpp deleted file mode 100644 index 3193272..0000000 --- a/WebCore/bindings/js/JSEventTargetNodeCustom.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "JSEventTargetNode.h" - -#include "AtomicString.h" -#include "Document.h" -#include "Event.h" -#include "EventTargetNode.h" -#include "ExceptionCode.h" -#include "Frame.h" -#include "JSDOMWindow.h" -#include "JSEvent.h" -#include "JSEventListener.h" - -using namespace JSC; - -namespace WebCore { - -JSValuePtr JSEventTargetNode::addEventListener(ExecState* exec, const ArgList& args) -{ - JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); - if (!globalObject) - return jsUndefined(); - - if (RefPtr listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1))) - impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec)); - - return jsUndefined(); -} - -JSValuePtr JSEventTargetNode::removeEventListener(ExecState* exec, const ArgList& args) -{ - JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); - if (!globalObject) - return jsUndefined(); - - if (JSEventListener* listener = globalObject->findJSEventListener(args.at(exec, 1))) - impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec)); - - return jsUndefined(); -} - -void JSEventTargetNode::pushEventHandlerScope(ExecState*, ScopeChain&) const -{ -} - -} // namespace WebCore diff --git a/WebCore/bindings/js/JSGeolocationCustom.cpp b/WebCore/bindings/js/JSGeolocationCustom.cpp index 1b9bce8..c818dd9 100644 --- a/WebCore/bindings/js/JSGeolocationCustom.cpp +++ b/WebCore/bindings/js/JSGeolocationCustom.cpp @@ -60,7 +60,14 @@ static PassRefPtr createPositionOptions(ExecState* exec, JSValu if (exec->hadException()) return 0; - return PositionOptions::create(enableHighAccuracy, timeout); + JSValuePtr maximumAgeValue = object->get(exec, Identifier(exec, "maximumAge")); + if (exec->hadException()) + return 0; + unsigned maximumAge = maximumAgeValue.toUInt32(exec); + if (exec->hadException()) + return 0; + + return PositionOptions::create(enableHighAccuracy, timeout, maximumAge); } JSValuePtr JSGeolocation::getCurrentPosition(ExecState* exec, const ArgList& args) diff --git a/WebCore/bindings/js/JSHTMLDocumentCustom.cpp b/WebCore/bindings/js/JSHTMLDocumentCustom.cpp index be2d158..1bc40ff 100644 --- a/WebCore/bindings/js/JSHTMLDocumentCustom.cpp +++ b/WebCore/bindings/js/JSHTMLDocumentCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,6 +26,7 @@ #include "config.h" #include "JSHTMLDocument.h" +#include "CharacterNames.h" #include "Frame.h" #include "HTMLBodyElement.h" #include "HTMLCollection.h" @@ -37,6 +38,8 @@ #include "JSDOMWindowCustom.h" #include "JSDOMWindowShell.h" #include "JSHTMLCollection.h" +#include "SegmentedString.h" +#include "Tokenizer.h" #include using namespace JSC; @@ -124,32 +127,42 @@ JSValuePtr JSHTMLDocument::open(ExecState* exec, const ArgList& args) return this; } -static String writeHelper(ExecState* exec, const ArgList& args) -{ - // DOM only specifies single string argument, but NS & IE allow multiple - // or no arguments. +enum NewlineRequirement { DoNotAddNewline, DoAddNewline }; - unsigned size = args.size(); - if (size == 1) - return args.at(exec, 0).toString(exec); +static inline void documentWrite(ExecState* exec, const ArgList& args, HTMLDocument* document, NewlineRequirement addNewline) +{ + // DOM only specifies single string argument, but browsers allow multiple or no arguments. + + size_t size = args.size(); + + UString firstString = args.at(exec, 0).toString(exec); + SegmentedString segmentedString = String(firstString); + if (size != 1) { + if (!size) + segmentedString.clear(); + else { + for (size_t i = 1; i < size; ++i) { + UString subsequentString = args.at(exec, i).toString(exec); + segmentedString.append(SegmentedString(String(subsequentString))); + } + } + } + if (addNewline) + segmentedString.append(SegmentedString(&newlineCharacter, 1)); - Vector result; - for (unsigned i = 0; i < size; ++i) - append(result, args.at(exec, i).toString(exec)); - return String::adopt(result); + Document* activeDocument = asJSDOMWindow(exec->lexicalGlobalObject())->impl()->document(); + document->write(segmentedString, activeDocument); } JSValuePtr JSHTMLDocument::write(ExecState* exec, const ArgList& args) { - Document* activeDocument = asJSDOMWindow(exec->lexicalGlobalObject())->impl()->document(); - static_cast(impl())->write(writeHelper(exec, args), activeDocument); + documentWrite(exec, args, static_cast(impl()), DoNotAddNewline); return jsUndefined(); } JSValuePtr JSHTMLDocument::writeln(ExecState* exec, const ArgList& args) { - Document* activeDocument = asJSDOMWindow(exec->lexicalGlobalObject())->impl()->document(); - static_cast(impl())->write(writeHelper(exec, args) + "\n", activeDocument); + documentWrite(exec, args, static_cast(impl()), DoAddNewline); return jsUndefined(); } diff --git a/WebCore/bindings/js/JSHTMLInputElementCustom.cpp b/WebCore/bindings/js/JSHTMLInputElementCustom.cpp index d59ef92..aa52007 100644 --- a/WebCore/bindings/js/JSHTMLInputElementCustom.cpp +++ b/WebCore/bindings/js/JSHTMLInputElementCustom.cpp @@ -32,41 +32,53 @@ using namespace JSC; namespace WebCore { -bool JSHTMLInputElement::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +JSValuePtr JSHTMLInputElement::selectionStart(ExecState* exec) const { HTMLInputElement* input = static_cast(impl()); - if (input->canHaveSelection()) - return false; - - const HashEntry* entry = JSHTMLInputElementPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); - if (entry) { - if (entry->attributes() & Function) { - if (entry->function() == jsHTMLInputElementPrototypeFunctionSetSelectionRange) { - slot.setUndefined(); - return true; - } - } - } + if (!input->canHaveSelection()) + return throwError(exec, TypeError); - return false; + return jsNumber(exec, input->selectionStart()); } -JSValuePtr JSHTMLInputElement::selectionStart(ExecState* exec) const +void JSHTMLInputElement::setSelectionStart(ExecState* exec, JSValuePtr value) { HTMLInputElement* input = static_cast(impl()); if (!input->canHaveSelection()) - return jsUndefined(); + throwError(exec, TypeError); - return jsNumber(exec, input->selectionStart()); + input->setSelectionStart(value.toInt32(exec)); } JSValuePtr JSHTMLInputElement::selectionEnd(ExecState* exec) const { HTMLInputElement* input = static_cast(impl()); if (!input->canHaveSelection()) - return jsUndefined(); + return throwError(exec, TypeError); return jsNumber(exec, input->selectionEnd()); } +void JSHTMLInputElement::setSelectionEnd(ExecState* exec, JSValuePtr value) +{ + HTMLInputElement* input = static_cast(impl()); + if (!input->canHaveSelection()) + throwError(exec, TypeError); + + input->setSelectionEnd(value.toInt32(exec)); +} + +JSValuePtr JSHTMLInputElement::setSelectionRange(ExecState* exec, const ArgList& args) +{ + HTMLInputElement* input = static_cast(impl()); + if (!input->canHaveSelection()) + return throwError(exec, TypeError); + + int start = args.at(exec, 0).toInt32(exec); + int end = args.at(exec, 1).toInt32(exec); + + input->setSelectionRange(start, end); + return jsUndefined(); +} + } // namespace WebCore diff --git a/WebCore/bindings/js/JSImageConstructor.cpp b/WebCore/bindings/js/JSImageConstructor.cpp index 0dc55b4..aa44c73 100644 --- a/WebCore/bindings/js/JSImageConstructor.cpp +++ b/WebCore/bindings/js/JSImageConstructor.cpp @@ -22,6 +22,7 @@ #include "HTMLImageElement.h" #include "HTMLNames.h" +#include "JSHTMLImageElement.h" #include "JSNode.h" #include "ScriptExecutionContext.h" @@ -29,15 +30,22 @@ using namespace JSC; namespace WebCore { -ASSERT_CLASS_FITS_IN_CELL(JSImageConstructor) +ASSERT_CLASS_FITS_IN_CELL(JSImageConstructor); const ClassInfo JSImageConstructor::s_info = { "ImageConstructor", 0, 0, 0 }; JSImageConstructor::JSImageConstructor(ExecState* exec, ScriptExecutionContext* context) : DOMObject(JSImageConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) + , m_globalObject(toJSDOMGlobalObject(context)) { ASSERT(context->isDocument()); - m_document = static_cast(asObject(toJS(exec, static_cast(context)))); + + putDirect(exec->propertyNames().prototype, JSHTMLImageElementPrototype::self(exec), None); +} + +Document* JSImageConstructor::document() const +{ + return static_cast(m_globalObject->scriptExecutionContext()); } static JSObject* constructImage(ExecState* exec, JSObject* constructor, const ArgList& args) @@ -79,8 +87,8 @@ ConstructType JSImageConstructor::getConstructData(ConstructData& constructData) void JSImageConstructor::mark() { DOMObject::mark(); - if (!m_document->marked()) - m_document->mark(); + if (!m_globalObject->marked()) + m_globalObject->mark(); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSImageConstructor.h b/WebCore/bindings/js/JSImageConstructor.h index 13cce26..578d1cf 100644 --- a/WebCore/bindings/js/JSImageConstructor.h +++ b/WebCore/bindings/js/JSImageConstructor.h @@ -28,7 +28,7 @@ namespace WebCore { class JSImageConstructor : public DOMObject { public: JSImageConstructor(JSC::ExecState*, ScriptExecutionContext*); - Document* document() const { return m_document->impl(); } + Document* document() const; static const JSC::ClassInfo s_info; @@ -37,7 +37,7 @@ namespace WebCore { virtual JSC::ConstructType getConstructData(JSC::ConstructData&); virtual const JSC::ClassInfo* classInfo() const { return &s_info; } - JSDocument* m_document; + JSDOMGlobalObject* m_globalObject; }; } // namespace WebCore diff --git a/WebCore/bindings/js/JSInspectedObjectWrapper.cpp b/WebCore/bindings/js/JSInspectedObjectWrapper.cpp index 09ad9f4..09007c1 100644 --- a/WebCore/bindings/js/JSInspectedObjectWrapper.cpp +++ b/WebCore/bindings/js/JSInspectedObjectWrapper.cpp @@ -34,7 +34,7 @@ using namespace JSC; namespace WebCore { -ASSERT_CLASS_FITS_IN_CELL(JSInspectedObjectWrapper) +ASSERT_CLASS_FITS_IN_CELL(JSInspectedObjectWrapper); typedef HashMap WrapperMap; typedef HashMap GlobalObjectWrapperMap; @@ -57,7 +57,7 @@ JSValuePtr JSInspectedObjectWrapper::wrap(ExecState* unwrappedExec, JSValuePtr u if (unwrappedObject->inherits(&JSInspectedObjectWrapper::s_info)) return unwrappedObject; - if (WrapperMap* wrapperMap = wrappers().get(unwrappedExec->dynamicGlobalObject())) + if (WrapperMap* wrapperMap = wrappers().get(unwrappedExec->lexicalGlobalObject())) if (JSInspectedObjectWrapper* wrapper = wrapperMap->get(unwrappedObject)) return wrapper; diff --git a/WebCore/bindings/js/JSInspectorCallbackWrapper.cpp b/WebCore/bindings/js/JSInspectorCallbackWrapper.cpp index 7ccf312..1fb5eae 100644 --- a/WebCore/bindings/js/JSInspectorCallbackWrapper.cpp +++ b/WebCore/bindings/js/JSInspectorCallbackWrapper.cpp @@ -33,7 +33,7 @@ using namespace JSC; namespace WebCore { -ASSERT_CLASS_FITS_IN_CELL(JSInspectorCallbackWrapper) +ASSERT_CLASS_FITS_IN_CELL(JSInspectorCallbackWrapper); typedef HashMap WrapperMap; diff --git a/WebCore/bindings/js/JSInspectorControllerCustom.cpp b/WebCore/bindings/js/JSInspectorControllerCustom.cpp new file mode 100644 index 0000000..79c69c8 --- /dev/null +++ b/WebCore/bindings/js/JSInspectorControllerCustom.cpp @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008 Matt Lilek + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSInspectorController.h" + +#include "Console.h" +#if ENABLE(DATABASE) +#include "Database.h" +#include "JSDatabase.h" +#endif +#include "ExceptionCode.h" +#include "Frame.h" +#include "FrameLoader.h" +#include "InspectorController.h" +#include "InspectorResource.h" +#include "JavaScriptProfile.h" +#include "JSDOMWindow.h" +#include "JSInspectedObjectWrapper.h" +#include "JSInspectorCallbackWrapper.h" +#include "JSNode.h" +#include "JSRange.h" +#include "Node.h" +#include "Page.h" +#include "TextIterator.h" +#include "VisiblePosition.h" +#include +#include +#include +#include +#include + +#if ENABLE(JAVASCRIPT_DEBUGGER) +#include "JavaScriptCallFrame.h" +#include "JavaScriptDebugServer.h" +#include "JSJavaScriptCallFrame.h" +#endif + +using namespace JSC; + +namespace WebCore { + +JSValuePtr JSInspectorController::profiles(JSC::ExecState* exec, const JSC::ArgList&) +{ + JSLock lock(false); + ArgList result; + const Vector >& profiles = impl()->profiles(); + + for (size_t i = 0; i < profiles.size(); ++i) + result.append(toJS(exec, profiles[i].get())); + + return constructArray(exec, result); +} + +JSValuePtr JSInspectorController::highlightDOMNode(JSC::ExecState* exec, const JSC::ArgList& args) +{ + if (args.size() < 1) + return jsUndefined(); + + JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(args.at(exec, 0)); + if (!wrapper) + return jsUndefined(); + + Node* node = toNode(wrapper->unwrappedObject()); + if (!node) + return jsUndefined(); + + impl()->highlight(node); + + return jsUndefined(); +} + +JSValuePtr JSInspectorController::addResourceSourceToFrame(ExecState* exec, const ArgList& args) +{ + if (args.size() < 2) + return jsUndefined(); + + bool ok = false; + unsigned identifier = args.at(exec, 0).toUInt32(exec, ok); + if (!ok) + return jsUndefined(); + + RefPtr resource = impl()->resources().get(identifier); + ASSERT(resource); + if (!resource) + return jsUndefined(); + + String sourceString = resource->sourceString(); + if (sourceString.isEmpty()) + return jsUndefined(); + + return jsBoolean(impl()->addSourceToFrame(resource->mimeType, sourceString, toNode(args.at(exec, 1)))); +} + +JSValuePtr JSInspectorController::addSourceToFrame(ExecState* exec, const ArgList& args) +{ + if (args.size() < 3) + return jsUndefined(); + + String mimeType = args.at(exec, 0).toString(exec); + if (exec->hadException()) + return jsUndefined(); + + String sourceString = args.at(exec, 1).toString(exec); + if (exec->hadException()) + return jsUndefined(); + + return jsBoolean(impl()->addSourceToFrame(mimeType, sourceString, toNode(args.at(exec, 1)))); +} + +JSValuePtr JSInspectorController::getResourceDocumentNode(ExecState* exec, const ArgList& args) +{ + if (args.size() < 1) + return jsUndefined(); + + bool ok = false; + unsigned identifier = args.at(exec, 0).toUInt32(exec, ok); + if (!ok) + return jsUndefined(); + + RefPtr resource = impl()->resources().get(identifier); + ASSERT(resource); + if (!resource) + return jsUndefined(); + + Frame* frame = resource->frame.get(); + Document* document = frame->document(); + + if (document->isPluginDocument() || document->isImageDocument() || document->isMediaDocument()) + return jsUndefined(); + + // FIXME: I am not sure if this is actually needed. Can we just use exec? + ExecState* resourceExec = toJSDOMWindowShell(resource->frame.get())->window()->globalExec(); + + JSLock lock(false); + return JSInspectedObjectWrapper::wrap(resourceExec, toJS(resourceExec, document)); +} + +JSValuePtr JSInspectorController::search(ExecState* exec, const ArgList& args) +{ + if (args.size() < 2) + return jsUndefined(); + + Node* node = toNode(args.at(exec, 0)); + if (!node) + return jsUndefined(); + + String target = args.at(exec, 1).toString(exec); + if (exec->hadException()) + return jsUndefined(); + + ArgList result; + RefPtr searchRange(rangeOfContents(node)); + + ExceptionCode ec = 0; + do { + RefPtr resultRange(findPlainText(searchRange.get(), target, true, false)); + if (resultRange->collapsed(ec)) + break; + + // A non-collapsed result range can in some funky whitespace cases still not + // advance the range's start position (4509328). Break to avoid infinite loop. + VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM); + if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM)) + break; + + result.append(toJS(exec, resultRange.get())); + + setStart(searchRange.get(), newStart); + } while (true); + + return constructArray(exec, result); +} + +#if ENABLE(DATABASE) +JSValuePtr JSInspectorController::databaseTableNames(ExecState* exec, const ArgList& args) +{ + if (args.size() < 1) + return jsUndefined(); + + JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(args.at(exec, 0)); + if (!wrapper) + return jsUndefined(); + + Database* database = toDatabase(wrapper->unwrappedObject()); + if (!database) + return jsUndefined(); + + ArgList result; + + Vector tableNames = database->tableNames(); + unsigned length = tableNames.size(); + for (unsigned i = 0; i < length; ++i) + result.append(jsString(exec, tableNames[i])); + + return constructArray(exec, result); +} +#endif + +JSValuePtr JSInspectorController::inspectedWindow(ExecState*, const ArgList&) +{ + JSDOMWindow* inspectedWindow = toJSDOMWindow(impl()->inspectedPage()->mainFrame()); + return JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), inspectedWindow); +} + +JSValuePtr JSInspectorController::setting(ExecState* exec, const ArgList& args) +{ + if (args.size() < 1) + return jsUndefined(); + + String key = args.at(exec, 0).toString(exec); + if (exec->hadException()) + return jsUndefined(); + + const InspectorController::Setting& setting = impl()->setting(key); + + switch (setting.type()) { + default: + case InspectorController::Setting::NoType: + return jsUndefined(); + case InspectorController::Setting::StringType: + return jsString(exec, setting.string()); + case InspectorController::Setting::DoubleType: + return jsNumber(exec, setting.doubleValue()); + case InspectorController::Setting::IntegerType: + return jsNumber(exec, setting.integerValue()); + case InspectorController::Setting::BooleanType: + return jsBoolean(setting.booleanValue()); + case InspectorController::Setting::StringVectorType: { + ArgList stringsArray; + const Vector& strings = setting.stringVector(); + const unsigned length = strings.size(); + for (unsigned i = 0; i < length; ++i) + stringsArray.append(jsString(exec, strings[i])); + return constructArray(exec, stringsArray); + } + } +} + +JSValuePtr JSInspectorController::setSetting(ExecState* exec, const ArgList& args) +{ + if (args.size() < 2) + return jsUndefined(); + + String key = args.at(exec, 0).toString(exec); + if (exec->hadException()) + return jsUndefined(); + + InspectorController::Setting setting; + + JSValuePtr value = args.at(exec, 0); + if (value.isUndefined() || value.isNull()) { + // Do nothing. The setting is already NoType. + ASSERT(setting.type() == InspectorController::Setting::NoType); + } else if (value.isString()) + setting.set(value.toString(exec)); + else if (value.isNumber()) + setting.set(value.toNumber(exec)); + else if (value.isBoolean()) + setting.set(value.toBoolean(exec)); + else { + JSArray* jsArray = asArray(value); + if (!jsArray) + return jsUndefined(); + Vector strings; + for (unsigned i = 0; i < jsArray->length(); ++i) { + String item = jsArray->get(exec, i).toString(exec); + if (exec->hadException()) + return jsUndefined(); + strings.append(item); + } + setting.set(strings); + } + + if (exec->hadException()) + return jsUndefined(); + + impl()->setSetting(key, setting); + + return jsUndefined(); +} + +JSValuePtr JSInspectorController::wrapCallback(ExecState* exec, const ArgList& args) +{ + if (args.size() < 1) + return jsUndefined(); + + return JSInspectorCallbackWrapper::wrap(exec, args.at(exec, 0)); +} + +JSValuePtr JSInspectorController::currentCallFrame(ExecState* exec, const ArgList&) +{ + JavaScriptCallFrame* callFrame = impl()->currentCallFrame(); + if (!callFrame || !callFrame->isValid()) + return jsUndefined(); + + // FIXME: I am not sure if this is actually needed. Can we just use exec? + ExecState* globalExec = callFrame->scopeChain()->globalObject()->globalExec(); + + JSLock lock(false); + return JSInspectedObjectWrapper::wrap(globalExec, toJS(exec, callFrame)); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSLazyEventListener.cpp b/WebCore/bindings/js/JSLazyEventListener.cpp new file mode 100644 index 0000000..3c80efe --- /dev/null +++ b/WebCore/bindings/js/JSLazyEventListener.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2001 Peter Kelly (pmk@post.com) + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All Rights Reserved. + * + * 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 "JSLazyEventListener.h" + +#include "Frame.h" +#include "JSNode.h" +#include + +using namespace JSC; + +namespace WebCore { + +JSLazyEventListener::JSLazyEventListener(LazyEventListenerType type, const String& functionName, const String& code, JSDOMGlobalObject* globalObject, Node* node, int lineNumber) + : JSProtectedEventListener(0, globalObject, true) + , m_functionName(functionName) + , m_code(code) + , m_parsed(false) + , m_lineNumber(lineNumber) + , m_originalNode(node) + , m_type(type) +{ + // We don't retain the original node because we assume it + // will stay alive as long as this handler object is around + // and we need to avoid a reference cycle. If JS transfers + // this handler to another node, parseCode will be called and + // then originalNode is no longer needed. + + // A JSLazyEventListener can be created with a line number of zero when it is created with + // a setAttribute call from JavaScript, so make the line number 1 in that case. + if (m_lineNumber == 0) + m_lineNumber = 1; +} + +JSObject* JSLazyEventListener::function() const +{ + parseCode(); + return m_listener; +} + +static inline JSValuePtr eventParameterName(JSLazyEventListener::LazyEventListenerType type, ExecState* exec) +{ + switch (type) { + case JSLazyEventListener::HTMLLazyEventListener: + return jsNontrivialString(exec, "event"); +#if ENABLE(SVG) + case JSLazyEventListener::SVGLazyEventListener: + return jsNontrivialString(exec, "evt"); +#endif + } + ASSERT_NOT_REACHED(); + return jsUndefined(); +} + +void JSLazyEventListener::parseCode() const +{ + if (m_parsed) + return; + + if (m_globalObject->scriptExecutionContext()->isDocument()) { + JSDOMWindow* window = static_cast(m_globalObject.get()); + Frame* frame = window->impl()->frame(); + if (!frame) + return; + // FIXME: Is this check needed for non-Document contexts? + ScriptController* script = frame->script(); + if (!script->isEnabled() || script->isPaused()) + return; + } + + m_parsed = true; + + ExecState* exec = m_globalObject->globalExec(); + + ArgList args; + UString sourceURL(m_globalObject->scriptExecutionContext()->url().string()); + args.append(eventParameterName(m_type, exec)); + args.append(jsString(exec, m_code)); + + // FIXME: Passing the document's URL to construct is not always correct, since this event listener might + // have been added with setAttribute from a script, and we should pass String() in that case. + m_listener = constructFunction(exec, args, Identifier(exec, m_functionName), sourceURL, m_lineNumber); // FIXME: is globalExec ok? + + JSFunction* listenerAsFunction = static_cast(m_listener.get()); + + if (exec->hadException()) { + exec->clearException(); + + // failed to parse, so let's just make this listener a no-op + m_listener = 0; + } else if (m_originalNode) { + // Add the event's home element to the scope + // (and the document, and the form - see JSHTMLElement::eventHandlerScope) + ScopeChain scope = listenerAsFunction->scope(); + + JSValuePtr thisObj = toJS(exec, m_originalNode); + if (thisObj.isObject()) { + static_cast(asObject(thisObj))->pushEventHandlerScope(exec, scope); + listenerAsFunction->setScope(scope); + } + } + + // no more need to keep the unparsed code around + m_functionName = String(); + m_code = String(); + + if (m_listener) { + ASSERT(isInline()); + JSDOMWindow::ProtectedListenersMap& listeners = m_globalObject->jsProtectedInlineEventListeners(); + listeners.set(m_listener, const_cast(this)); + } +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSLazyEventListener.h b/WebCore/bindings/js/JSLazyEventListener.h new file mode 100644 index 0000000..5424883 --- /dev/null +++ b/WebCore/bindings/js/JSLazyEventListener.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2001 Peter Kelly (pmk@post.com) + * Copyright (C) 2003, 2008, 2009 Apple Inc. All rights reserved. + * + * 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 JSLazyEventListener_h +#define JSLazyEventListener_h + +#include "JSEventListener.h" +#include "PlatformString.h" + +namespace WebCore { + + class Node; + + class JSLazyEventListener : public JSProtectedEventListener { + public: + enum LazyEventListenerType { + HTMLLazyEventListener +#if ENABLE(SVG) + , SVGLazyEventListener +#endif + }; + + static PassRefPtr create(LazyEventListenerType type, const String& functionName, const String& code, JSDOMGlobalObject* globalObject, Node* node, int lineNumber) + { + return adoptRef(new JSLazyEventListener(type, functionName, code, globalObject, node, lineNumber)); + } + + private: + JSLazyEventListener(LazyEventListenerType, const String& functionName, const String& code, JSDOMGlobalObject*, Node*, int lineNumber); + + virtual JSC::JSObject* function() const; + virtual bool wasCreatedFromMarkup() const { return true; } + + void parseCode() const; + + mutable String m_functionName; + mutable String m_code; + mutable bool m_parsed; + int m_lineNumber; + Node* m_originalNode; + + LazyEventListenerType m_type; + }; + +} // namespace WebCore + +#endif // JSEventListener_h diff --git a/WebCore/bindings/js/JSMessageChannelConstructor.cpp b/WebCore/bindings/js/JSMessageChannelConstructor.cpp index 8da9f6d..f5b73df 100644 --- a/WebCore/bindings/js/JSMessageChannelConstructor.cpp +++ b/WebCore/bindings/js/JSMessageChannelConstructor.cpp @@ -44,17 +44,8 @@ const ClassInfo JSMessageChannelConstructor::s_info = { "MessageChannelConstruct JSMessageChannelConstructor::JSMessageChannelConstructor(ExecState* exec, ScriptExecutionContext* scriptExecutionContext) : DOMObject(JSMessageChannelConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) - , m_scriptExecutionContext(scriptExecutionContext) + , m_globalObject(toJSDOMGlobalObject(scriptExecutionContext)) { - if (m_scriptExecutionContext->isDocument()) - m_contextWrapper = toJS(exec, static_cast(scriptExecutionContext)); -#if ENABLE(WORKERS) - else if (m_scriptExecutionContext->isWorkerContext()) - m_contextWrapper = toJSDOMGlobalObject(scriptExecutionContext); -#endif - else - ASSERT_NOT_REACHED(); - putDirect(exec->propertyNames().prototype, JSMessageChannelPrototype::self(exec), None); } @@ -62,6 +53,11 @@ JSMessageChannelConstructor::~JSMessageChannelConstructor() { } +ScriptExecutionContext* JSMessageChannelConstructor::scriptExecutionContext() const +{ + return m_globalObject->scriptExecutionContext(); +} + ConstructType JSMessageChannelConstructor::getConstructData(ConstructData& constructData) { constructData.native.function = construct; @@ -76,8 +72,8 @@ JSObject* JSMessageChannelConstructor::construct(ExecState* exec, JSObject* cons void JSMessageChannelConstructor::mark() { DOMObject::mark(); - if (!m_contextWrapper.marked()) - m_contextWrapper.mark(); + if (!m_globalObject->marked()) + m_globalObject->mark(); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSMessageChannelConstructor.h b/WebCore/bindings/js/JSMessageChannelConstructor.h index 614f6ae..2691777 100644 --- a/WebCore/bindings/js/JSMessageChannelConstructor.h +++ b/WebCore/bindings/js/JSMessageChannelConstructor.h @@ -37,7 +37,7 @@ namespace WebCore { virtual const JSC::ClassInfo* classInfo() const { return &s_info; } static const JSC::ClassInfo s_info; - ScriptExecutionContext* scriptExecutionContext() const { return m_scriptExecutionContext; } + ScriptExecutionContext* scriptExecutionContext() const; virtual bool implementsHasInstance() const { return true; } static JSC::JSObject* construct(JSC::ExecState*, JSC::JSObject*, const JSC::ArgList&); @@ -46,8 +46,7 @@ namespace WebCore { virtual void mark(); private: - ScriptExecutionContext* m_scriptExecutionContext; - JSC::JSValuePtr m_contextWrapper; + JSDOMGlobalObject* m_globalObject; }; } // namespace WebCore diff --git a/WebCore/bindings/js/JSMessagePortCustom.cpp b/WebCore/bindings/js/JSMessagePortCustom.cpp index d30b14c..394f9b1 100644 --- a/WebCore/bindings/js/JSMessagePortCustom.cpp +++ b/WebCore/bindings/js/JSMessagePortCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -42,11 +42,8 @@ void JSMessagePort::mark() { DOMObject::mark(); - if (JSUnprotectedEventListener* listener = static_cast(m_impl->onmessage())) - listener->mark(); - - if (JSUnprotectedEventListener* listener = static_cast(m_impl->onclose())) - listener->mark(); + markIfNotNull(m_impl->onmessage()); + markIfNotNull(m_impl->onclose()); if (MessagePort* entangledPort = m_impl->entangledPort()) { DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), entangledPort); @@ -58,10 +55,8 @@ void JSMessagePort::mark() typedef MessagePort::ListenerVector ListenerVector; EventListenersMap& eventListeners = m_impl->eventListeners(); for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { - for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) { - JSUnprotectedEventListener* listener = static_cast(vecIter->get()); - listener->mark(); - } + for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) + (*vecIter)->mark(); } } @@ -78,7 +73,7 @@ JSValuePtr JSMessagePort::addEventListener(ExecState* exec, const ArgList& args) JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - RefPtr listener = globalObject->findOrCreateJSUnprotectedEventListener(exec, args.at(exec, 1)); + RefPtr listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1)); if (!listener) return jsUndefined(); impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec)); @@ -90,7 +85,7 @@ JSValuePtr JSMessagePort::removeEventListener(ExecState* exec, const ArgList& ar JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - JSUnprotectedEventListener* listener = globalObject->findJSUnprotectedEventListener(exec, args.at(exec, 1)); + JSEventListener* listener = globalObject->findJSEventListener(exec, args.at(exec, 1)); if (!listener) return jsUndefined(); impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec)); diff --git a/WebCore/bindings/js/JSNamedNodesCollection.cpp b/WebCore/bindings/js/JSNamedNodesCollection.cpp index 8a7ee0e..8068a1d 100644 --- a/WebCore/bindings/js/JSNamedNodesCollection.cpp +++ b/WebCore/bindings/js/JSNamedNodesCollection.cpp @@ -35,7 +35,7 @@ namespace WebCore { using namespace JSC; -ASSERT_CLASS_FITS_IN_CELL(JSNamedNodesCollection) +ASSERT_CLASS_FITS_IN_CELL(JSNamedNodesCollection); const ClassInfo JSNamedNodesCollection::s_info = { "Collection", 0, 0, 0 }; diff --git a/WebCore/bindings/js/JSNavigatorCustom.cpp b/WebCore/bindings/js/JSNavigatorCustom.cpp index 2287426..a7b6194 100644 --- a/WebCore/bindings/js/JSNavigatorCustom.cpp +++ b/WebCore/bindings/js/JSNavigatorCustom.cpp @@ -76,10 +76,6 @@ static bool needsYouTubeQuirk(ExecState* exec, Frame* frame) return false; Document* document = frame->document(); - // FIXME: The document is never null, so we should remove this check along with the - // other similar ones in this file when we are absolutely sure it's safe. - if (!document) - return false; // Do the quirk only on the front page of the global version of YouTube. const KURL& url = document->url(); diff --git a/WebCore/bindings/js/JSNodeCustom.cpp b/WebCore/bindings/js/JSNodeCustom.cpp index 2b4d6d4..8f4d2c1 100644 --- a/WebCore/bindings/js/JSNodeCustom.cpp +++ b/WebCore/bindings/js/JSNodeCustom.cpp @@ -43,6 +43,7 @@ #include "JSDocumentType.h" #include "JSEntity.h" #include "JSEntityReference.h" +#include "JSEventListener.h" #include "JSHTMLElement.h" #include "JSHTMLElementWrapperFactory.h" #include "JSNotation.h" @@ -106,6 +107,34 @@ JSValuePtr JSNode::appendChild(ExecState* exec, const ArgList& args) return jsNull(); } +JSValuePtr JSNode::addEventListener(ExecState* exec, const ArgList& args) +{ + JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); + if (!globalObject) + return jsUndefined(); + + if (RefPtr listener = globalObject->findOrCreateJSProtectedEventListener(exec, args.at(exec, 1))) + impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec)); + + return jsUndefined(); +} + +JSValuePtr JSNode::removeEventListener(ExecState* exec, const ArgList& args) +{ + JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); + if (!globalObject) + return jsUndefined(); + + if (JSProtectedEventListener* listener = globalObject->findJSProtectedEventListener(args.at(exec, 1))) + impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec)); + + return jsUndefined(); +} + +void JSNode::pushEventHandlerScope(ExecState*, ScopeChain&) const +{ +} + void JSNode::mark() { ASSERT(!marked()); diff --git a/WebCore/bindings/js/JSNodeFilterCondition.cpp b/WebCore/bindings/js/JSNodeFilterCondition.cpp index 1e4151b..f4b9e0c 100644 --- a/WebCore/bindings/js/JSNodeFilterCondition.cpp +++ b/WebCore/bindings/js/JSNodeFilterCondition.cpp @@ -29,7 +29,7 @@ namespace WebCore { using namespace JSC; -ASSERT_CLASS_FITS_IN_CELL(JSNodeFilterCondition) +ASSERT_CLASS_FITS_IN_CELL(JSNodeFilterCondition); JSNodeFilterCondition::JSNodeFilterCondition(JSValuePtr filter) : m_filter(filter) diff --git a/WebCore/bindings/js/JSOptionConstructor.cpp b/WebCore/bindings/js/JSOptionConstructor.cpp index 0030594..e1d5cfe 100644 --- a/WebCore/bindings/js/JSOptionConstructor.cpp +++ b/WebCore/bindings/js/JSOptionConstructor.cpp @@ -20,6 +20,7 @@ #include "config.h" #include "JSOptionConstructor.h" +#include "HTMLNames.h" #include "HTMLOptionElement.h" #include "JSHTMLOptionElement.h" #include "ScriptExecutionContext.h" @@ -29,30 +30,34 @@ using namespace JSC; namespace WebCore { -ASSERT_CLASS_FITS_IN_CELL(JSOptionConstructor) +ASSERT_CLASS_FITS_IN_CELL(JSOptionConstructor); const ClassInfo JSOptionConstructor::s_info = { "OptionConstructor", 0, 0, 0 }; JSOptionConstructor::JSOptionConstructor(ExecState* exec, ScriptExecutionContext* context) : DOMObject(JSOptionConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) + , m_globalObject(toJSDOMGlobalObject(context)) { ASSERT(context->isDocument()); - m_document = static_cast(asObject(toJS(exec, static_cast(context)))); + putDirect(exec->propertyNames().prototype, JSHTMLOptionElementPrototype::self(exec), None); putDirect(exec->propertyNames().length, jsNumber(exec, 4), ReadOnly|DontDelete|DontEnum); } +Document* JSOptionConstructor::document() const +{ + return static_cast(m_globalObject->scriptExecutionContext()); +} + static JSObject* constructHTMLOptionElement(ExecState* exec, JSObject* constructor, const ArgList& args) { Document* document = static_cast(constructor)->document(); - ExceptionCode ec = 0; + RefPtr element = static_pointer_cast(document->createElement(HTMLNames::optionTag, false)); - RefPtr element = static_pointer_cast(document->createElement("option", ec)); - RefPtr text; - if (ec == 0) - text = document->createTextNode(""); - if (ec == 0 && !args.at(exec, 0).isUndefined()) + ExceptionCode ec = 0; + RefPtr text = document->createTextNode(""); + if (!args.at(exec, 0).isUndefined()) text->setData(args.at(exec, 0).toString(exec), ec); if (ec == 0) element->appendChild(text.release(), ec); @@ -80,8 +85,8 @@ ConstructType JSOptionConstructor::getConstructData(ConstructData& constructData void JSOptionConstructor::mark() { DOMObject::mark(); - if (!m_document->marked()) - m_document->mark(); + if (!m_globalObject->marked()) + m_globalObject->mark(); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSOptionConstructor.h b/WebCore/bindings/js/JSOptionConstructor.h index 5234c49..60f6873 100644 --- a/WebCore/bindings/js/JSOptionConstructor.h +++ b/WebCore/bindings/js/JSOptionConstructor.h @@ -29,7 +29,7 @@ namespace WebCore { class JSOptionConstructor : public DOMObject { public: JSOptionConstructor(JSC::ExecState*, ScriptExecutionContext*); - Document* document() const { return m_document->impl(); } + Document* document() const; static const JSC::ClassInfo s_info; @@ -38,7 +38,7 @@ namespace WebCore { virtual JSC::ConstructType getConstructData(JSC::ConstructData&); virtual const JSC::ClassInfo* classInfo() const { return &s_info; } - JSDocument* m_document; + JSDOMGlobalObject* m_globalObject; }; } // namespace WebCore diff --git a/WebCore/bindings/js/JSPluginElementFunctions.cpp b/WebCore/bindings/js/JSPluginElementFunctions.cpp index 4003efb..eeaa394 100644 --- a/WebCore/bindings/js/JSPluginElementFunctions.cpp +++ b/WebCore/bindings/js/JSPluginElementFunctions.cpp @@ -20,13 +20,9 @@ #include "config.h" #include "JSPluginElementFunctions.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "HTMLDocument.h" #include "HTMLNames.h" #include "HTMLPlugInElement.h" #include "JSHTMLElement.h" -#include "ScriptController.h" #include "runtime.h" #include "runtime_object.h" diff --git a/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp b/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp index b1b0c92..c3fc41f 100644 --- a/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp +++ b/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp @@ -32,7 +32,7 @@ using namespace JSC; namespace WebCore { -ASSERT_CLASS_FITS_IN_CELL(JSQuarantinedObjectWrapper) +ASSERT_CLASS_FITS_IN_CELL(JSQuarantinedObjectWrapper); const ClassInfo JSQuarantinedObjectWrapper::s_info = { "JSQuarantinedObjectWrapper", 0, 0, 0 }; @@ -58,7 +58,7 @@ JSValuePtr JSQuarantinedObjectWrapper::cachedValueGetter(ExecState*, const Ident JSQuarantinedObjectWrapper::JSQuarantinedObjectWrapper(ExecState* unwrappedExec, JSObject* unwrappedObject, PassRefPtr structure) : JSObject(structure) - , m_unwrappedGlobalObject(unwrappedExec->dynamicGlobalObject()) + , m_unwrappedGlobalObject(unwrappedExec->lexicalGlobalObject()) , m_unwrappedObject(unwrappedObject) { ASSERT_ARG(unwrappedExec, unwrappedExec); @@ -72,7 +72,7 @@ JSQuarantinedObjectWrapper::~JSQuarantinedObjectWrapper() bool JSQuarantinedObjectWrapper::allowsUnwrappedAccessFrom(ExecState* exec) const { - return m_unwrappedGlobalObject->profileGroup() == exec->dynamicGlobalObject()->profileGroup(); + return m_unwrappedGlobalObject->profileGroup() == exec->lexicalGlobalObject()->profileGroup(); } ExecState* JSQuarantinedObjectWrapper::unwrappedExecState() const @@ -87,8 +87,9 @@ void JSQuarantinedObjectWrapper::transferExceptionToExecState(ExecState* exec) c if (!unwrappedExecState()->hadException()) return; - exec->setException(wrapOutgoingValue(unwrappedExecState(), unwrappedExecState()->exception())); + JSValuePtr exception = unwrappedExecState()->exception(); unwrappedExecState()->clearException(); + exec->setException(wrapOutgoingValue(unwrappedExecState(), exception)); } void JSQuarantinedObjectWrapper::mark() diff --git a/WebCore/bindings/js/JSRGBColor.cpp b/WebCore/bindings/js/JSRGBColor.cpp index 91fe4b3..90f8037 100644 --- a/WebCore/bindings/js/JSRGBColor.cpp +++ b/WebCore/bindings/js/JSRGBColor.cpp @@ -44,7 +44,7 @@ static JSValuePtr jsRGBColorBlue(ExecState*, const Identifier&, const PropertySl namespace WebCore { -ASSERT_CLASS_FITS_IN_CELL(JSRGBColor) +ASSERT_CLASS_FITS_IN_CELL(JSRGBColor); const ClassInfo JSRGBColor::s_info = { "RGBColor", 0, &JSRGBColorTable, 0 }; diff --git a/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp b/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp index 6309f4a..56ceb7c 100644 --- a/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp +++ b/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp @@ -42,7 +42,7 @@ JSValuePtr JSSVGElementInstance::addEventListener(ExecState* exec, const ArgList if (!globalObject) return jsUndefined(); - if (RefPtr listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1))) + if (RefPtr listener = globalObject->findOrCreateJSProtectedEventListener(exec, args.at(exec, 1))) impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec)); return jsUndefined(); @@ -54,7 +54,7 @@ JSValuePtr JSSVGElementInstance::removeEventListener(ExecState* exec, const ArgL if (!globalObject) return jsUndefined(); - if (JSEventListener* listener = globalObject->findJSEventListener(args.at(exec, 1))) + if (JSProtectedEventListener* listener = globalObject->findJSProtectedEventListener(args.at(exec, 1))) impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec)); return jsUndefined(); diff --git a/WebCore/bindings/js/JSSVGPODTypeWrapper.h b/WebCore/bindings/js/JSSVGPODTypeWrapper.h index c30f97f..51e4e9e 100644 --- a/WebCore/bindings/js/JSSVGPODTypeWrapper.h +++ b/WebCore/bindings/js/JSSVGPODTypeWrapper.h @@ -28,7 +28,6 @@ #define JSSVGPODTypeWrapper_h #if ENABLE(SVG) -#include "Frame.h" #include "SVGElement.h" #include diff --git a/WebCore/bindings/js/JSStyleSheetCustom.cpp b/WebCore/bindings/js/JSStyleSheetCustom.cpp index 04dabf0..2cadcb4 100644 --- a/WebCore/bindings/js/JSStyleSheetCustom.cpp +++ b/WebCore/bindings/js/JSStyleSheetCustom.cpp @@ -27,6 +27,7 @@ #include "JSStyleSheet.h" #include "CSSStyleSheet.h" +#include "Node.h" #include "JSCSSStyleSheet.h" #include "JSNode.h" diff --git a/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp b/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp index ba864ea..3b97eb1 100644 --- a/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp +++ b/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp @@ -35,10 +35,10 @@ namespace WebCore { const ClassInfo JSWebKitCSSMatrixConstructor::s_info = { "WebKitCSSMatrixConstructor", 0, 0, 0 }; -JSWebKitCSSMatrixConstructor::JSWebKitCSSMatrixConstructor(ExecState* exec, ScriptExecutionContext* context) +JSWebKitCSSMatrixConstructor::JSWebKitCSSMatrixConstructor(ExecState* exec) : DOMObject(JSWebKitCSSMatrixConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) { - ASSERT_UNUSED(context, context->isDocument()); + putDirect(exec->propertyNames().prototype, JSWebKitCSSMatrixPrototype::self(exec), None); putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum); } diff --git a/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.h b/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.h index b280241..d0e0bd1 100644 --- a/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.h +++ b/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.h @@ -33,7 +33,7 @@ namespace WebCore { class JSWebKitCSSMatrixConstructor : public DOMObject { public: - JSWebKitCSSMatrixConstructor(JSC::ExecState*, ScriptExecutionContext*); + JSWebKitCSSMatrixConstructor(JSC::ExecState*); static const JSC::ClassInfo s_info; private: diff --git a/WebCore/bindings/js/JSWebKitPointConstructor.cpp b/WebCore/bindings/js/JSWebKitPointConstructor.cpp new file mode 100644 index 0000000..c3a8ea6 --- /dev/null +++ b/WebCore/bindings/js/JSWebKitPointConstructor.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSWebKitPointConstructor.h" + +#include "Document.h" +#include "WebKitPoint.h" +#include "JSWebKitPoint.h" + +namespace WebCore { + +using namespace JSC; + +const ClassInfo JSWebKitPointConstructor::s_info = { "WebKitPointConstructor", 0, 0, 0 }; + +JSWebKitPointConstructor::JSWebKitPointConstructor(ExecState* exec) + : DOMObject(JSWebKitPointConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) +{ + putDirect(exec->propertyNames().prototype, JSWebKitPointPrototype::self(exec), None); + putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum); +} + +static JSObject* constructWebKitPoint(ExecState* exec, JSObject*, const ArgList& args) +{ + float x = 0; + float y = 0; + if (args.size() >= 2) { + x = (float)args.at(exec, 0).toNumber(exec); + y = (float)args.at(exec, 1).toNumber(exec); + if (isnan(x)) + x = 0; + if (isnan(y)) + y = 0; + } + return asObject(toJS(exec, WebKitPoint::create(x, y))); +} + +JSC::ConstructType JSWebKitPointConstructor::getConstructData(JSC::ConstructData& constructData) +{ + constructData.native.function = constructWebKitPoint; + return ConstructTypeHost; +} + + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSWebKitPointConstructor.h b/WebCore/bindings/js/JSWebKitPointConstructor.h new file mode 100644 index 0000000..a5bb5c1 --- /dev/null +++ b/WebCore/bindings/js/JSWebKitPointConstructor.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JSWebKitPointConstructor_h +#define JSWebKitPointConstructor_h + +#include "JSDOMBinding.h" +#include "JSDocument.h" + +namespace WebCore { + +class JSWebKitPointConstructor : public DOMObject { +public: + JSWebKitPointConstructor(JSC::ExecState*); + static const JSC::ClassInfo s_info; + +private: + virtual JSC::ConstructType getConstructData(JSC::ConstructData&); + virtual const JSC::ClassInfo* classInfo() const { return &s_info; } +}; + +} + +#endif // JSWebKitPointConstructor_h diff --git a/WebCore/bindings/js/JSWorkerConstructor.cpp b/WebCore/bindings/js/JSWorkerConstructor.cpp index 52147a2..a9f2f74 100644 --- a/WebCore/bindings/js/JSWorkerConstructor.cpp +++ b/WebCore/bindings/js/JSWorkerConstructor.cpp @@ -44,6 +44,7 @@ const ClassInfo JSWorkerConstructor::s_info = { "WorkerConstructor", 0, 0, 0 }; JSWorkerConstructor::JSWorkerConstructor(ExecState* exec) : DOMObject(JSWorkerConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) { + putDirect(exec->propertyNames().prototype, JSWorkerPrototype::self(exec), None); putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum); } diff --git a/WebCore/bindings/js/JSWorkerContextBase.cpp b/WebCore/bindings/js/JSWorkerContextBase.cpp index 24dd50f..c948b85 100644 --- a/WebCore/bindings/js/JSWorkerContextBase.cpp +++ b/WebCore/bindings/js/JSWorkerContextBase.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2009 Google Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -38,6 +39,7 @@ #include "JSMessagePort.h" #include "JSWorkerLocation.h" #include "JSWorkerNavigator.h" +#include "JSXMLHttpRequestConstructor.h" #include "WorkerContext.h" #include "WorkerLocation.h" @@ -45,14 +47,19 @@ using namespace JSC; /* @begin JSWorkerContextBaseTable +# -- Constructors -- + XMLHttpRequest jsWorkerContextBaseXMLHttpRequest DontDelete @end */ +static JSValuePtr jsWorkerContextBaseXMLHttpRequest(ExecState*, const Identifier&, const PropertySlot&); +static void setJSWorkerContextBaseXMLHttpRequest(ExecState*, JSObject*, JSValuePtr); + #include "JSWorkerContextBase.lut.h" namespace WebCore { -ASSERT_CLASS_FITS_IN_CELL(JSWorkerContextBase) +ASSERT_CLASS_FITS_IN_CELL(JSWorkerContextBase); JSWorkerContextBase::JSWorkerContextBase(PassRefPtr structure, PassRefPtr impl) : JSDOMGlobalObject(structure, new JSDOMGlobalObjectData, this) @@ -81,6 +88,33 @@ void JSWorkerContextBase::put(ExecState* exec, const Identifier& propertyName, J lookupPut(exec, propertyName, value, getJSWorkerContextBaseTable(exec), this, slot); } +bool JSWorkerContextBase::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + const HashEntry* entry = getJSWorkerContextBaseTable(exec)->entry(exec, propertyName); + if (entry) { + if (entry->attributes() & Function) + setUpStaticFunctionSlot(exec, entry, this, propertyName, slot); + else + slot.setCustom(this, entry->propertyGetter()); + return true; + } + + return Base::getOwnPropertySlot(exec, propertyName, slot); +} + } // namespace WebCore +using namespace WebCore; + +JSValuePtr jsWorkerContextBaseXMLHttpRequest(ExecState* exec, const Identifier&, const PropertySlot& slot) +{ + return getDOMConstructor(exec, static_cast(asObject(slot.slotBase()))); +} + +void setJSWorkerContextBaseXMLHttpRequest(ExecState* exec, JSObject* thisObject, JSValuePtr value) +{ + // Shadowing a built-in constructor + static_cast(thisObject)->putDirect(Identifier(exec, "XMLHttpRequest"), value); +} + #endif // ENABLE(WORKERS) diff --git a/WebCore/bindings/js/JSWorkerContextBase.h b/WebCore/bindings/js/JSWorkerContextBase.h index d2d5bd2..5dc1921 100644 --- a/WebCore/bindings/js/JSWorkerContextBase.h +++ b/WebCore/bindings/js/JSWorkerContextBase.h @@ -48,6 +48,8 @@ namespace WebCore { WorkerContext* impl() const { return m_impl.get(); } virtual ScriptExecutionContext* scriptExecutionContext() const; + bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&); + private: RefPtr m_impl; }; diff --git a/WebCore/bindings/js/JSWorkerContextCustom.cpp b/WebCore/bindings/js/JSWorkerContextCustom.cpp index 3a6dca0..a28cb75 100644 --- a/WebCore/bindings/js/JSWorkerContextCustom.cpp +++ b/WebCore/bindings/js/JSWorkerContextCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,7 +31,9 @@ #include "JSDOMBinding.h" #include "JSEventListener.h" +#include "ScheduledAction.h" #include "WorkerContext.h" +#include using namespace JSC; @@ -51,17 +53,14 @@ void JSWorkerContext::mark() markActiveObjectsForContext(*globalData(), scriptExecutionContext()); - if (JSUnprotectedEventListener* listener = static_cast(impl()->onmessage())) - listener->mark(); + markIfNotNull(impl()->onmessage()); typedef WorkerContext::EventListenersMap EventListenersMap; typedef WorkerContext::ListenerVector ListenerVector; EventListenersMap& eventListeners = impl()->eventListeners(); for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { - for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) { - JSUnprotectedEventListener* listener = static_cast(vecIter->get()); - listener->mark(); - } + for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) + (*vecIter)->mark(); } } @@ -75,9 +74,32 @@ void JSWorkerContext::setSelf(ExecState* exec, JSValuePtr value) putDirect(Identifier(exec, "self"), value); } +JSValuePtr JSWorkerContext::importScripts(ExecState* exec, const ArgList& args) +{ + if (!args.size()) + return jsUndefined(); + + Vector urls; + for (unsigned i = 0; i < args.size(); i++) { + urls.append(args.at(exec, i).toString(exec)); + if (exec->hadException()) + return jsUndefined(); + } + ExceptionCode ec = 0; + int signedLineNumber; + intptr_t sourceID; + UString sourceURL; + JSValuePtr function; + exec->interpreter()->retrieveLastCaller(exec, signedLineNumber, sourceID, sourceURL, function); + + impl()->importScripts(urls, sourceURL, signedLineNumber >= 0 ? signedLineNumber : 0, ec); + setDOMException(exec, ec); + return jsUndefined(); +} + JSValuePtr JSWorkerContext::addEventListener(ExecState* exec, const ArgList& args) { - RefPtr listener = findOrCreateJSUnprotectedEventListener(exec, args.at(exec, 1)); + RefPtr listener = findOrCreateJSEventListener(exec, args.at(exec, 1)); if (!listener) return jsUndefined(); impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec)); @@ -86,13 +108,49 @@ JSValuePtr JSWorkerContext::addEventListener(ExecState* exec, const ArgList& arg JSValuePtr JSWorkerContext::removeEventListener(ExecState* exec, const ArgList& args) { - JSUnprotectedEventListener* listener = findJSUnprotectedEventListener(exec, args.at(exec, 1)); + JSEventListener* listener = findJSEventListener(exec, args.at(exec, 1)); if (!listener) return jsUndefined(); impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec)); return jsUndefined(); } +static JSValuePtr setTimeoutOrInterval(ExecState* exec, WorkerContext* workerContext, const ArgList& args, bool singleShot) +{ + JSValuePtr v = args.at(exec, 0); + int delay = args.at(exec, 1).toInt32(exec); + if (v.isString()) + return jsNumber(exec, workerContext->installTimeout(new ScheduledAction(asString(v)->value()), delay, singleShot)); + CallData callData; + if (v.getCallData(callData) == CallTypeNone) + return jsUndefined(); + ArgList argsTail; + args.getSlice(2, argsTail); + return jsNumber(exec, workerContext->installTimeout(new ScheduledAction(exec, v, argsTail), delay, singleShot)); +} + +JSValuePtr JSWorkerContext::setTimeout(ExecState* exec, const ArgList& args) +{ + return setTimeoutOrInterval(exec, impl(), args, true); +} + +JSValuePtr JSWorkerContext::clearTimeout(ExecState* exec, const ArgList& args) +{ + impl()->removeTimeout(args.at(exec, 0).toInt32(exec)); + return jsUndefined(); +} + +JSValuePtr JSWorkerContext::setInterval(ExecState* exec, const ArgList& args) +{ + return setTimeoutOrInterval(exec, impl(), args, false); +} + +JSValuePtr JSWorkerContext::clearInterval(ExecState* exec, const ArgList& args) +{ + impl()->removeTimeout(args.at(exec, 0).toInt32(exec)); + return jsUndefined(); +} + } // namespace WebCore #endif // ENABLE(WORKERS) diff --git a/WebCore/bindings/js/JSWorkerCustom.cpp b/WebCore/bindings/js/JSWorkerCustom.cpp index 2ede0da..12103d3 100644 --- a/WebCore/bindings/js/JSWorkerCustom.cpp +++ b/WebCore/bindings/js/JSWorkerCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -41,20 +41,15 @@ void JSWorker::mark() { DOMObject::mark(); - if (JSUnprotectedEventListener* listener = static_cast(m_impl->onmessage())) - listener->mark(); - - if (JSUnprotectedEventListener* listener = static_cast(m_impl->onerror())) - listener->mark(); + markIfNotNull(m_impl->onmessage()); + markIfNotNull(m_impl->onerror()); typedef Worker::EventListenersMap EventListenersMap; typedef Worker::ListenerVector ListenerVector; EventListenersMap& eventListeners = m_impl->eventListeners(); for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { - for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) { - JSUnprotectedEventListener* listener = static_cast(vecIter->get()); - listener->mark(); - } + for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) + (*vecIter)->mark(); } } @@ -63,7 +58,7 @@ JSValuePtr JSWorker::addEventListener(ExecState* exec, const ArgList& args) JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - RefPtr listener = globalObject->findOrCreateJSUnprotectedEventListener(exec, args.at(exec, 1)); + RefPtr listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1)); if (!listener) return jsUndefined(); impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec)); @@ -75,7 +70,7 @@ JSValuePtr JSWorker::removeEventListener(ExecState* exec, const ArgList& args) JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - JSUnprotectedEventListener* listener = globalObject->findJSUnprotectedEventListener(exec, args.at(exec, 1)); + JSEventListener* listener = globalObject->findJSEventListener(exec, args.at(exec, 1)); if (!listener) return jsUndefined(); impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec)); diff --git a/WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp b/WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp index d7f54de..a7f8ab0 100644 --- a/WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp +++ b/WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp @@ -28,22 +28,25 @@ using namespace JSC; namespace WebCore { -ASSERT_CLASS_FITS_IN_CELL(JSXMLHttpRequestConstructor) +ASSERT_CLASS_FITS_IN_CELL(JSXMLHttpRequestConstructor); const ClassInfo JSXMLHttpRequestConstructor::s_info = { "XMLHttpRequestConstructor", 0, 0, 0 }; -JSXMLHttpRequestConstructor::JSXMLHttpRequestConstructor(ExecState* exec, ScriptExecutionContext* context) +JSXMLHttpRequestConstructor::JSXMLHttpRequestConstructor(ExecState* exec, ScriptExecutionContext* scriptExecutionContext) : DOMObject(JSXMLHttpRequestConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) + , m_globalObject(toJSDOMGlobalObject(scriptExecutionContext)) { - ASSERT(context->isDocument()); - m_document = static_cast(asObject(toJS(exec, static_cast(context)))); - putDirect(exec->propertyNames().prototype, JSXMLHttpRequestPrototype::self(exec), None); } +ScriptExecutionContext* JSXMLHttpRequestConstructor::scriptExecutionContext() const +{ + return m_globalObject->scriptExecutionContext(); +} + static JSObject* constructXMLHttpRequest(ExecState* exec, JSObject* constructor, const ArgList&) { - RefPtr xmlHttpRequest = XMLHttpRequest::create(static_cast(constructor)->document()); + RefPtr xmlHttpRequest = XMLHttpRequest::create(static_cast(constructor)->scriptExecutionContext()); return CREATE_DOM_OBJECT_WRAPPER(exec, XMLHttpRequest, xmlHttpRequest.get()); } @@ -56,8 +59,8 @@ ConstructType JSXMLHttpRequestConstructor::getConstructData(ConstructData& const void JSXMLHttpRequestConstructor::mark() { DOMObject::mark(); - if (!m_document->marked()) - m_document->mark(); + if (!m_globalObject->marked()) + m_globalObject->mark(); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSXMLHttpRequestConstructor.h b/WebCore/bindings/js/JSXMLHttpRequestConstructor.h index f235af6..01d1f85 100644 --- a/WebCore/bindings/js/JSXMLHttpRequestConstructor.h +++ b/WebCore/bindings/js/JSXMLHttpRequestConstructor.h @@ -21,14 +21,13 @@ #define JSXMLHttpRequestConstructor_h #include "JSDOMBinding.h" -#include "JSDocument.h" namespace WebCore { class JSXMLHttpRequestConstructor : public DOMObject { public: JSXMLHttpRequestConstructor(JSC::ExecState*, ScriptExecutionContext*); - Document* document() const { return m_document->impl(); } + ScriptExecutionContext* scriptExecutionContext() const; static const JSC::ClassInfo s_info; virtual void mark(); @@ -36,7 +35,7 @@ private: virtual JSC::ConstructType getConstructData(JSC::ConstructData&); virtual const JSC::ClassInfo* classInfo() const { return &s_info; } - JSDocument* m_document; + JSDOMGlobalObject* m_globalObject; }; } // namespace WebCore diff --git a/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp b/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp index 5122ba3..a7f78b7 100644 --- a/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp +++ b/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -59,32 +59,19 @@ void JSXMLHttpRequest::mark() wrapper->mark(); } - if (JSUnprotectedEventListener* onReadyStateChangeListener = static_cast(m_impl->onreadystatechange())) - onReadyStateChangeListener->mark(); - - if (JSUnprotectedEventListener* onAbortListener = static_cast(m_impl->onabort())) - onAbortListener->mark(); - - if (JSUnprotectedEventListener* onErrorListener = static_cast(m_impl->onerror())) - onErrorListener->mark(); - - if (JSUnprotectedEventListener* onLoadListener = static_cast(m_impl->onload())) - onLoadListener->mark(); - - if (JSUnprotectedEventListener* onLoadStartListener = static_cast(m_impl->onloadstart())) - onLoadStartListener->mark(); - - if (JSUnprotectedEventListener* onProgressListener = static_cast(m_impl->onprogress())) - onProgressListener->mark(); + markIfNotNull(m_impl->onreadystatechange()); + markIfNotNull(m_impl->onabort()); + markIfNotNull(m_impl->onerror()); + markIfNotNull(m_impl->onload()); + markIfNotNull(m_impl->onloadstart()); + markIfNotNull(m_impl->onprogress()); typedef XMLHttpRequest::EventListenersMap EventListenersMap; typedef XMLHttpRequest::ListenerVector ListenerVector; EventListenersMap& eventListeners = m_impl->eventListeners(); for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { - for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) { - JSUnprotectedEventListener* listener = static_cast(vecIter->get()); - listener->mark(); - } + for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) + (*vecIter)->mark(); } } @@ -181,7 +168,7 @@ JSValuePtr JSXMLHttpRequest::addEventListener(ExecState* exec, const ArgList& ar JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - RefPtr listener = globalObject->findOrCreateJSUnprotectedEventListener(exec, args.at(exec, 1)); + RefPtr listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1)); if (!listener) return jsUndefined(); impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec)); @@ -193,7 +180,7 @@ JSValuePtr JSXMLHttpRequest::removeEventListener(ExecState* exec, const ArgList& JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - JSUnprotectedEventListener* listener = globalObject->findJSUnprotectedEventListener(exec, args.at(exec, 1)); + JSEventListener* listener = globalObject->findJSEventListener(exec, args.at(exec, 1)); if (!listener) return jsUndefined(); impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec)); diff --git a/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp b/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp index f456c87..26342e0 100644 --- a/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp +++ b/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -51,29 +51,18 @@ void JSXMLHttpRequestUpload::mark() wrapper->mark(); } - if (JSUnprotectedEventListener* onAbortListener = static_cast(m_impl->onabort())) - onAbortListener->mark(); - - if (JSUnprotectedEventListener* onErrorListener = static_cast(m_impl->onerror())) - onErrorListener->mark(); - - if (JSUnprotectedEventListener* onLoadListener = static_cast(m_impl->onload())) - onLoadListener->mark(); - - if (JSUnprotectedEventListener* onLoadStartListener = static_cast(m_impl->onloadstart())) - onLoadStartListener->mark(); - - if (JSUnprotectedEventListener* onProgressListener = static_cast(m_impl->onprogress())) - onProgressListener->mark(); + markIfNotNull(m_impl->onabort()); + markIfNotNull(m_impl->onerror()); + markIfNotNull(m_impl->onload()); + markIfNotNull(m_impl->onloadstart()); + markIfNotNull(m_impl->onprogress()); typedef XMLHttpRequestUpload::EventListenersMap EventListenersMap; typedef XMLHttpRequestUpload::ListenerVector ListenerVector; EventListenersMap& eventListeners = m_impl->eventListeners(); for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { - for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) { - JSUnprotectedEventListener* listener = static_cast(vecIter->get()); - listener->mark(); - } + for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) + (*vecIter)->mark(); } } @@ -82,7 +71,7 @@ JSValuePtr JSXMLHttpRequestUpload::addEventListener(ExecState* exec, const ArgLi JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - RefPtr listener = globalObject->findOrCreateJSUnprotectedEventListener(exec, args.at(exec, 1)); + RefPtr listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1)); if (!listener) return jsUndefined(); impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec)); @@ -94,7 +83,7 @@ JSValuePtr JSXMLHttpRequestUpload::removeEventListener(ExecState* exec, const Ar JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - JSUnprotectedEventListener* listener = globalObject->findJSUnprotectedEventListener(exec, args.at(exec, 1)); + JSEventListener* listener = globalObject->findJSEventListener(exec, args.at(exec, 1)); if (!listener) return jsUndefined(); impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec)); diff --git a/WebCore/bindings/js/JSXSLTProcessorConstructor.cpp b/WebCore/bindings/js/JSXSLTProcessorConstructor.cpp index ed456e1..448c832 100644 --- a/WebCore/bindings/js/JSXSLTProcessorConstructor.cpp +++ b/WebCore/bindings/js/JSXSLTProcessorConstructor.cpp @@ -37,7 +37,7 @@ using namespace JSC; namespace WebCore { -ASSERT_CLASS_FITS_IN_CELL(JSXSLTProcessorConstructor) +ASSERT_CLASS_FITS_IN_CELL(JSXSLTProcessorConstructor); const ClassInfo JSXSLTProcessorConstructor::s_info = { "XSLTProcessorConsructor", 0, 0, 0 }; diff --git a/WebCore/bindings/js/ScheduledAction.cpp b/WebCore/bindings/js/ScheduledAction.cpp index 8627474..986a96e 100644 --- a/WebCore/bindings/js/ScheduledAction.cpp +++ b/WebCore/bindings/js/ScheduledAction.cpp @@ -88,9 +88,9 @@ void ScheduledAction::executeFunctionInContext(JSGlobalObject* globalObject, JSV for (size_t i = 0; i < size; ++i) args.append(m_args[i]); - globalObject->startTimeoutCheck(); + globalObject->globalData()->timeoutChecker.start(); call(exec, m_function, callType, callData, thisValue, args); - globalObject->stopTimeoutCheck(); + globalObject->globalData()->timeoutChecker.stop(); if (exec->hadException()) reportCurrentException(exec); @@ -136,8 +136,7 @@ void ScheduledAction::execute(Document* document) // FIXME: Is this really the right point to do the update? We need a place that works // for all possible entry points that might possibly execute script, but this seems // to be a bit too low-level. - if (Document* document = frame->document()) - document->updateRendering(); + frame->document()->updateRendering(); frame->script()->setProcessingTimerCallback(false); } diff --git a/WebCore/bindings/js/ScriptController.cpp b/WebCore/bindings/js/ScriptController.cpp index efd3a70..fbca680 100644 --- a/WebCore/bindings/js/ScriptController.cpp +++ b/WebCore/bindings/js/ScriptController.cpp @@ -21,34 +21,24 @@ #include "config.h" #include "ScriptController.h" -#include "Console.h" -#include "DOMWindow.h" -#include "Document.h" #include "Event.h" #include "EventNames.h" #include "Frame.h" -#include "FrameLoader.h" #include "GCController.h" -#include "JSDOMWindow.h" +#include "HTMLPlugInElement.h" #include "JSDocument.h" -#include "JSEventListener.h" -#include "npruntime_impl.h" +#include "JSLazyEventListener.h" #include "NP_jsobject.h" #include "Page.h" #include "PageGroup.h" -#include "runtime_root.h" #include "ScriptSourceCode.h" #include "ScriptValue.h" #include "Settings.h" - -#include +#include "npruntime_impl.h" +#include "runtime_root.h" #include #include -#if ENABLE(NETSCAPE_PLUGIN_API) -#include "HTMLPlugInElement.h" -#endif - using namespace JSC; namespace WebCore { @@ -110,16 +100,16 @@ ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode) // so we start the keep alive timer here. m_frame->keepAlive(); - m_windowShell->window()->startTimeoutCheck(); + m_windowShell->window()->globalData()->timeoutChecker.start(); Completion comp = JSC::evaluate(exec, exec->dynamicGlobalObject()->globalScopeChain(), jsSourceCode, m_windowShell); - m_windowShell->window()->stopTimeoutCheck(); + m_windowShell->window()->globalData()->timeoutChecker.stop(); if (comp.complType() == Normal || comp.complType() == ReturnValue) { m_sourceURL = savedSourceURL; return comp.value(); } - if (comp.complType() == Throw) + if (comp.complType() == Throw || comp.complType() == Interrupted) reportException(exec, comp.value()); m_sourceURL = savedSourceURL; @@ -152,12 +142,14 @@ PassRefPtr ScriptController::createInlineEventListener(const Stri } #if ENABLE(SVG) + PassRefPtr ScriptController::createSVGEventHandler(const String& functionName, const String& code, Node* node) { initScriptIfNeeded(); JSLock lock(false); return JSLazyEventListener::create(JSLazyEventListener::SVGLazyEventListener, functionName, code, m_windowShell->window(), node, m_handlerLineno); } + #endif void ScriptController::initScript() @@ -300,6 +292,7 @@ PassRefPtr ScriptController::createRootObject(void* native } #if ENABLE(NETSCAPE_PLUGIN_API) + NPObject* ScriptController::windowScriptNPObject() { if (!m_windowScriptNPObject) { @@ -323,23 +316,34 @@ NPObject* ScriptController::windowScriptNPObject() NPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement* plugin) { - // Can't create NPObjects when JavaScript is disabled - if (!isEnabled()) + JSObject* object = jsObjectForPluginElement(plugin); + if (!object) return _NPN_CreateNoScriptObject(); + // Wrap the JSObject in an NPObject + return _NPN_CreateScriptObject(0, object, bindingRootObject()); +} + +#endif + +JSObject* ScriptController::jsObjectForPluginElement(HTMLPlugInElement* plugin) +{ + // Can't create JSObjects when JavaScript is disabled + if (!isEnabled()) + return 0; + // Create a JSObject bound to this element JSLock lock(false); ExecState* exec = globalObject()->globalExec(); JSValuePtr jsElementValue = toJS(exec, plugin); if (!jsElementValue || !jsElementValue.isObject()) - return _NPN_CreateNoScriptObject(); - - // Wrap the JSObject in an NPObject - return _NPN_CreateScriptObject(0, jsElementValue.getObject(), bindingRootObject()); + return 0; + + return jsElementValue.getObject(); } -#endif #if !PLATFORM(MAC) + void ScriptController::updatePlatformScriptObjects() { } @@ -347,6 +351,7 @@ void ScriptController::updatePlatformScriptObjects() void ScriptController::disconnectPlatformScriptObjects() { } + #endif void ScriptController::cleanupScriptObjectsForPlugin(void* nativeHandle) diff --git a/WebCore/bindings/js/ScriptController.h b/WebCore/bindings/js/ScriptController.h index 28fd7e9..6f1781e 100644 --- a/WebCore/bindings/js/ScriptController.h +++ b/WebCore/bindings/js/ScriptController.h @@ -127,6 +127,8 @@ public: WebScriptObject* windowScriptObject(); #endif + JSC::JSObject* jsObjectForPluginElement(HTMLPlugInElement*); + #if ENABLE(NETSCAPE_PLUGIN_API) NPObject* createScriptObjectForPluginElement(HTMLPlugInElement*); NPObject* windowScriptNPObject(); diff --git a/WebCore/bindings/js/ScriptControllerMac.mm b/WebCore/bindings/js/ScriptControllerMac.mm index 17ad0b2..6554e11 100644 --- a/WebCore/bindings/js/ScriptControllerMac.mm +++ b/WebCore/bindings/js/ScriptControllerMac.mm @@ -157,11 +157,7 @@ static void updateRenderingForBindings(JSC::ExecState*, JSC::JSObject* rootObjec if (!frame) return; - Document* document = frame->document(); - if (!document) - return; - - document->updateRendering(); + frame->document()->updateRendering(); } void ScriptController::initJavaJSBindings() diff --git a/WebCore/bindings/js/ScriptControllerQt.cpp b/WebCore/bindings/js/ScriptControllerQt.cpp index 8e9dfad..6b14190 100644 --- a/WebCore/bindings/js/ScriptControllerQt.cpp +++ b/WebCore/bindings/js/ScriptControllerQt.cpp @@ -50,15 +50,13 @@ PassRefPtr ScriptController::createScriptInstanceForWid { if (widget->isPluginView()) { PluginView* pluginView = static_cast(widget); - if (pluginView->isNPAPIPlugin()) - return pluginView->bindingInstance(); - return 0; + return pluginView->bindingInstance(); } QWidget* platformWidget = widget->platformWidget(); if (!platformWidget) return 0; - return JSC::Bindings::QtInstance::getQtInstance(platformWidget, bindingRootObject()); + return JSC::Bindings::QtInstance::getQtInstance(platformWidget, bindingRootObject(), QScriptEngine::QtOwnership); } } diff --git a/WebCore/bindings/js/ScriptFunctionCall.cpp b/WebCore/bindings/js/ScriptFunctionCall.cpp new file mode 100644 index 0000000..5d928c1 --- /dev/null +++ b/WebCore/bindings/js/ScriptFunctionCall.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ScriptFunctionCall.h" + +#include "JSDOMBinding.h" +#include "ScriptString.h" +#include "ScriptValue.h" +#include + +using namespace JSC; + +namespace WebCore { + +ScriptFunctionCall::ScriptFunctionCall(ScriptState* exec, const ScriptObject& thisObject, const char* name) + : m_exec(exec) + , m_thisObject(thisObject) + , m_name(name) +{ +} + +void ScriptFunctionCall::appendArgument(const ScriptObject& argument) +{ + m_arguments.append(argument.jsObject()); +} + +void ScriptFunctionCall::appendArgument(const ScriptString& argument) +{ + m_arguments.append(jsString(m_exec, argument)); +} + +void ScriptFunctionCall::appendArgument(const ScriptValue& argument) +{ + m_arguments.append(argument.jsValue()); +} + +void ScriptFunctionCall::appendArgument(const String& argument) +{ + JSLock lock(false); + m_arguments.append(jsString(m_exec, argument)); +} + +void ScriptFunctionCall::appendArgument(unsigned int argument) +{ + JSLock lock(false); + m_arguments.append(jsNumber(m_exec, argument)); +} + +void ScriptFunctionCall::appendArgument(bool argument) +{ + m_arguments.append(jsBoolean(argument)); +} + +ScriptValue ScriptFunctionCall::call(bool& hadException) +{ + JSObject* thisObject = m_thisObject.jsObject(); + + JSLock lock(false); + + JSValuePtr function = thisObject->get(m_exec, Identifier(m_exec, m_name)); + if (m_exec->hadException()) { + reportException(m_exec, m_exec->exception()); + hadException = true; + return ScriptValue(); + } + + CallData callData; + CallType callType = function.getCallData(callData); + if (callType == CallTypeNone) + return ScriptValue(); + + JSValuePtr result = JSC::call(m_exec, function, callType, callData, thisObject, m_arguments); + if (m_exec->hadException()) { + reportException(m_exec, m_exec->exception()); + hadException = true; + return ScriptValue(); + } + + return ScriptValue(result); +} + +ScriptObject ScriptFunctionCall::construct(bool& hadException) +{ + JSObject* thisObject = m_thisObject.jsObject(); + + JSLock lock(false); + + JSObject* constructor = asObject(thisObject->get(m_exec, Identifier(m_exec, m_name))); + if (m_exec->hadException()) { + reportException(m_exec, m_exec->exception()); + hadException = true; + return ScriptObject(); + } + + ConstructData constructData; + ConstructType constructType = constructor->getConstructData(constructData); + if (constructType == ConstructTypeNone) + return ScriptObject(); + + JSValuePtr result = JSC::construct(m_exec, constructor, constructType, constructData, m_arguments); + if (m_exec->hadException()) { + reportException(m_exec, m_exec->exception()); + hadException = true; + return ScriptObject(); + } + + return ScriptObject(asObject(result)); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/ScriptFunctionCall.h b/WebCore/bindings/js/ScriptFunctionCall.h new file mode 100644 index 0000000..0b01717 --- /dev/null +++ b/WebCore/bindings/js/ScriptFunctionCall.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ScriptFunctionCall_h +#define ScriptFunctionCall_h + +#include "PlatformString.h" +#include "ScriptObject.h" +#include "ScriptState.h" + +#include + +namespace WebCore { + class ScriptValue; + class ScriptString; + + class ScriptFunctionCall { + public: + ScriptFunctionCall(ScriptState* exec, const ScriptObject& thisObject, const char* name); + virtual ~ScriptFunctionCall() {}; + + void appendArgument(const ScriptObject&); + void appendArgument(const ScriptString&); + void appendArgument(const ScriptValue&); + void appendArgument(const String&); + void appendArgument(unsigned int); + void appendArgument(bool); + ScriptValue call(bool& hadException); + ScriptObject construct(bool& hadException); + + protected: + ScriptState* m_exec; + ScriptObject m_thisObject; + String m_name; + JSC::ArgList m_arguments; + bool m_quarantineObjects; + }; + +} // namespace WebCore + +#endif // ScriptFunctionCall diff --git a/WebCore/bindings/js/ScriptObject.cpp b/WebCore/bindings/js/ScriptObject.cpp new file mode 100644 index 0000000..148dac5 --- /dev/null +++ b/WebCore/bindings/js/ScriptObject.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ScriptObject.h" + +using namespace JSC; + +namespace WebCore { + +ScriptObject::ScriptObject(JSObject* object) + : ScriptValue(object) +{ +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/ScriptObject.h b/WebCore/bindings/js/ScriptObject.h new file mode 100644 index 0000000..08fa323 --- /dev/null +++ b/WebCore/bindings/js/ScriptObject.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ScriptObject_h +#define ScriptObject_h + +#include "ScriptValue.h" + +#include +#include + +namespace WebCore { + + class ScriptObject : public ScriptValue { + public: + ScriptObject(JSC::JSObject*); + ScriptObject() {} + JSC::JSObject* jsObject() const { return asObject(jsValue()); } + }; + +} + +#endif // ScriptObject_h diff --git a/WebCore/bindings/js/ScriptObjectQuarantine.cpp b/WebCore/bindings/js/ScriptObjectQuarantine.cpp new file mode 100644 index 0000000..9311737 --- /dev/null +++ b/WebCore/bindings/js/ScriptObjectQuarantine.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ScriptObjectQuarantine.h" + +#include "Database.h" +#include "Document.h" +#include "Frame.h" +#include "JSDatabase.h" +#include "JSStorage.h" +#include "JSDOMBinding.h" +#include "JSInspectedObjectWrapper.h" +#include "ScriptObject.h" +#include "ScriptValue.h" + +#include + +using namespace JSC; + +namespace WebCore { + +ScriptValue quarantineValue(ScriptState* scriptState, const ScriptValue& value) +{ + JSLock lock(false); + return ScriptValue(JSInspectedObjectWrapper::wrap(scriptState, value.jsValue())); +} + +bool getQuarantinedScriptObject(Database* database, ScriptObject& quarantinedObject) +{ + ASSERT(database); + + Frame* frame = database->document()->frame(); + if (!frame) + return false; + + ExecState* exec = toJSDOMWindow(frame)->globalExec(); + + JSLock lock(false); + quarantinedObject = ScriptObject(asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, database)))); + + return true; +} + +bool getQuarantinedScriptObject(Frame* frame, Storage* storage, ScriptObject& quarantinedObject) +{ + ASSERT(frame); + ASSERT(storage); + + ExecState* exec = toJSDOMWindow(frame)->globalExec(); + + JSLock lock(false); + quarantinedObject = ScriptObject(asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, storage)))); + + return true; +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/ScriptObjectQuarantine.h b/WebCore/bindings/js/ScriptObjectQuarantine.h new file mode 100644 index 0000000..a3ac7f1 --- /dev/null +++ b/WebCore/bindings/js/ScriptObjectQuarantine.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ScriptObjectQuarantine_h +#define ScriptObjectQuarantine_h + +#include "ScriptState.h" + +namespace WebCore { + + class Database; + class Frame; + class ScriptObject; + class ScriptValue; + class Storage; + + ScriptValue quarantineValue(ScriptState*, const ScriptValue&); + + bool getQuarantinedScriptObject(Database* database, ScriptObject& quarantinedObject); + bool getQuarantinedScriptObject(Frame* frame, Storage* storage, ScriptObject& quarantinedObject); + +} + +#endif // ScriptObjectQuarantine_h diff --git a/WebCore/bindings/js/ScriptValue.cpp b/WebCore/bindings/js/ScriptValue.cpp index 37e3f67..c4a7579 100644 --- a/WebCore/bindings/js/ScriptValue.cpp +++ b/WebCore/bindings/js/ScriptValue.cpp @@ -29,7 +29,9 @@ #include "config.h" #include "ScriptValue.h" -#include "PlatformString.h" +#include +#include + #include #include #include @@ -50,6 +52,14 @@ bool ScriptValue::getString(String& result) const return true; } +bool ScriptValue::isEqual(ScriptState* scriptState, const ScriptValue& anotherValue) const +{ + if (hasNoValue()) + return anotherValue.hasNoValue(); + + return JSValueIsEqual(toRef(scriptState), toRef(jsValue()), toRef(anotherValue.jsValue()), 0); +} + bool ScriptValue::isNull() const { if (!m_value) diff --git a/WebCore/bindings/js/ScriptValue.h b/WebCore/bindings/js/ScriptValue.h index 855509a..e6e7cb1 100644 --- a/WebCore/bindings/js/ScriptValue.h +++ b/WebCore/bindings/js/ScriptValue.h @@ -31,6 +31,8 @@ #ifndef ScriptValue_h #define ScriptValue_h +#include "PlatformString.h" +#include "ScriptState.h" #include namespace WebCore { @@ -40,11 +42,15 @@ class String; class ScriptValue { public: ScriptValue(JSC::JSValuePtr value = JSC::noValue()) : m_value(value) {} + virtual ~ScriptValue() {} JSC::JSValuePtr jsValue() const { return m_value.get(); } bool getString(String& result) const; + String toString(ScriptState* scriptState) const { return m_value.get().toString(scriptState); } + bool isEqual(ScriptState*, const ScriptValue&) const; bool isNull() const; bool isUndefined() const; + bool hasNoValue() const { return m_value == JSC::noValue(); } private: JSC::ProtectedJSValuePtr m_value; diff --git a/WebCore/bindings/js/WorkerScriptController.cpp b/WebCore/bindings/js/WorkerScriptController.cpp index 0727510..25d7eb9 100644 --- a/WebCore/bindings/js/WorkerScriptController.cpp +++ b/WebCore/bindings/js/WorkerScriptController.cpp @@ -35,7 +35,7 @@ #include "ScriptSourceCode.h" #include "ScriptValue.h" #include "WorkerContext.h" -#include "WorkerMessagingProxy.h" +#include "WorkerObjectProxy.h" #include "WorkerThread.h" #include #include @@ -68,8 +68,13 @@ void WorkerScriptController::initScript() JSLock lock(false); + // Explicitly protect the global object's prototype so it isn't collected + // when we allocate the global object. (Once the global object is fully + // constructed, it can mark its own prototype.) RefPtr prototypeStructure = JSWorkerContextPrototype::createStructure(jsNull()); - RefPtr structure = JSWorkerContext::createStructure(new (m_globalData.get()) JSWorkerContextPrototype(prototypeStructure.release())); + ProtectedPtr prototype = new (m_globalData.get()) JSWorkerContextPrototype(prototypeStructure.release()); + + RefPtr structure = JSWorkerContext::createStructure(prototype); m_workerContextWrapper = new (m_globalData.get()) JSWorkerContext(structure.release(), m_workerContext); } @@ -80,25 +85,46 @@ ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode) if (m_executionForbidden) return noValue(); } + ScriptValue exception; + ScriptValue result = evaluate(sourceCode, &exception); + if (exception.jsValue()) { + JSLock lock(false); + reportException(m_workerContextWrapper->globalExec(), exception.jsValue()); + } + return result; +} + +ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, ScriptValue* exception) +{ + { + MutexLocker lock(m_sharedDataMutex); + if (m_executionForbidden) + return noValue(); + } initScriptIfNeeded(); JSLock lock(false); ExecState* exec = m_workerContextWrapper->globalExec(); - m_workerContextWrapper->startTimeoutCheck(); + m_workerContextWrapper->globalData()->timeoutChecker.start(); Completion comp = JSC::evaluate(exec, exec->dynamicGlobalObject()->globalScopeChain(), sourceCode.jsSourceCode(), m_workerContextWrapper); - m_workerContextWrapper->stopTimeoutCheck(); + m_workerContextWrapper->globalData()->timeoutChecker.stop(); - m_workerContext->thread()->messagingProxy()->reportWorkerThreadActivity(m_workerContext->hasPendingActivity()); + m_workerContext->thread()->workerObjectProxy()->reportPendingActivity(m_workerContext->hasPendingActivity()); if (comp.complType() == Normal || comp.complType() == ReturnValue) return comp.value(); if (comp.complType() == Throw) - reportException(exec, comp.value()); + *exception = comp.value(); return noValue(); } +void WorkerScriptController::setException(ScriptValue exception) +{ + m_workerContextWrapper->globalExec()->setException(exception.jsValue()); +} + void WorkerScriptController::forbidExecution() { // This function is called from another thread. @@ -107,7 +133,7 @@ void WorkerScriptController::forbidExecution() // It is not critical for Interpreter::m_timeoutTime to be synchronized, we just rely on it reaching the worker thread's processor sooner or later. MutexLocker lock(m_sharedDataMutex); m_executionForbidden = true; - m_globalData->interpreter->setTimeoutTime(1); // 1 ms is the smallest timeout that can be set. + m_globalData->timeoutChecker.setTimeoutInterval(1); // 1ms is the smallest timeout that can be set. } } // namespace WebCore diff --git a/WebCore/bindings/js/WorkerScriptController.h b/WebCore/bindings/js/WorkerScriptController.h index 1dda5da..0454721 100644 --- a/WebCore/bindings/js/WorkerScriptController.h +++ b/WebCore/bindings/js/WorkerScriptController.h @@ -57,9 +57,11 @@ namespace WebCore { } ScriptValue evaluate(const ScriptSourceCode&); + ScriptValue evaluate(const ScriptSourceCode&, ScriptValue* exception); - void forbidExecution(); + void setException(ScriptValue); + void forbidExecution(); private: void initScriptIfNeeded() { -- cgit v1.1