diff options
Diffstat (limited to 'WebCore/bindings')
181 files changed, 10665 insertions, 744 deletions
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<JSDocument*>(asObject(toJS(exec, static_cast<Document*>(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<Document*>(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<UChar> 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 <runtime/JSLock.h> @@ -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 <runtime/JSLock.h> @@ -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 <runtime/JSLock.h> @@ -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 <runtime/JSLock.h> @@ -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<JSUnprotectedEventListener*>(m_impl->onchecking())) - listener->mark(); - - if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->onerror())) - listener->mark(); - - if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->onnoupdate())) - listener->mark(); - - if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->ondownloading())) - listener->mark(); - - if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->onprogress())) - listener->mark(); - - if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->onupdateready())) - listener->mark(); - - if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->oncached())) - listener->mark(); - - if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(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<JSUnprotectedEventListener*>(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<JSUnprotectedEventListener> listener = globalObject->findOrCreateJSUnprotectedEventListener(exec, args.at(exec, 1)); + RefPtr<JSEventListener> 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> 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<JSEventListener> JSDOMGlobalObject::findOrCreateJSEventListener(ExecState*, JSValuePtr val, bool isInline) +PassRefPtr<JSProtectedEventListener> 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<JSUnprotectedEventListener> JSDOMGlobalObject::findOrCreateJSUnprotectedEventListener(ExecState* exec, JSValuePtr val, bool isInline) +PassRefPtr<JSEventListener> 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<const JSC::ClassInfo*, RefPtr<JSC::Structure> > 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<JSEventListener> findOrCreateJSEventListener(JSC::ExecState*, JSC::JSValuePtr, bool isInline = false); + PassRefPtr<JSProtectedEventListener> 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<JSUnprotectedEventListener> findOrCreateJSUnprotectedEventListener(JSC::ExecState*, JSC::JSValuePtr, bool isInline = false); + PassRefPtr<JSEventListener> findOrCreateJSEventListener(JSC::ExecState*, JSC::JSValuePtr, bool isInline = false); - typedef HashMap<JSC::JSObject*, JSEventListener*> ListenersMap; - typedef HashMap<JSC::JSObject*, JSUnprotectedEventListener*> UnprotectedListenersMap; + typedef HashMap<JSC::JSObject*, JSProtectedEventListener*> ProtectedListenersMap; + typedef HashMap<JSC::JSObject*, JSEventListener*> 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 <runtime/Error.h> #include <runtime/JSLock.h> -#include <wtf/AlwaysInline.h> #include <wtf/MathExtras.h> 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<DOMWindow> JSDOMWindowBase::JSDOMWindowBase(PassRefPtr<Structure> structure, PassRefPtr<DOMWindow> 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<JSDOMWindowBase*>(asObject(slot.slotBase()))->allowsAccessFrom(exec)) return jsUndefined(); - return getDOMConstructor<JSWebKitCSSMatrixConstructor>(exec, static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))); + return getDOMConstructor<JSWebKitCSSMatrixConstructor>(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<JSAudioConstructor>(exec, static_cast<JSDOMWindowBase*>(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<JSDOMWindowBase*>(asObject(slot.slotBase()))->allowsAccessFrom(exec)) + return jsUndefined(); + return getDOMConstructor<JSWebKitPointConstructor>(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<JSWorkerConstructor>(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<JSXSLTProcessorConstructor>(exec); #else + UNUSED_PARAM(exec); + UNUSED_PARAM(slot); return jsUndefined(); #endif } @@ -510,6 +515,14 @@ void setJSDOMWindowBaseWebKitCSSMatrix(ExecState* exec, JSObject* thisObject, JS static_cast<JSDOMWindowBase*>(thisObject)->putDirect(Identifier(exec, "WebKitCSSMatrix"), value); } +void setJSDOMWindowBaseWebKitPoint(ExecState* exec, JSObject* thisObject, JSValuePtr value) +{ + if (!static_cast<JSDOMWindowBase*>(thisObject)->allowsAccessFrom(exec)) + return; + // Shadowing a built-in constructor + static_cast<JSDOMWindowBase*>(thisObject)->putDirect(Identifier(exec, "WebKitPoint"), value); +} + void setJSDOMWindowBaseXMLHttpRequest(ExecState* exec, JSObject* thisObject, JSValuePtr value) { if (!static_cast<JSDOMWindowBase*>(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<HTMLDocument*>(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<JSEventListener> 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<JSProtectedEventListener> 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<DOMWindow> window) +void JSDOMWindowShell::setWindow(PassRefPtr<DOMWindow> 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<Structure> prototypeStructure = JSDOMWindowPrototype::createStructure(jsNull()); - RefPtr<Structure> structure = JSDOMWindow::createStructure(new JSDOMWindowPrototype(prototypeStructure.release())); - setWindow(new (JSDOMWindow::commonJSGlobalData()) JSDOMWindow(structure.release(), window, this)); + ProtectedPtr<JSDOMWindowPrototype> prototype = new JSDOMWindowPrototype(prototypeStructure.release()); + + RefPtr<Structure> 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 <runtime/FunctionConstructor.h> #include <runtime/JSLock.h> #include <wtf/RefCountedLeakCounter.h> @@ -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<JSDOMWindow*>(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<JSFunction*>(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<JSEventTargetNode*>(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<JSLazyEventListener*>(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 <runtime/Protect.h> 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<JSUnprotectedEventListener> create(JSC::JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline) + static PassRefPtr<JSEventListener> 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<JSEventListener> create(JSC::JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline) + static PassRefPtr<JSProtectedEventListener> 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<JSC::JSObject> m_listener; - - private: JSC::ProtectedPtr<JSDOMGlobalObject> m_globalObject; - }; - - class JSLazyEventListener : public JSEventListener { - public: - enum LazyEventListenerType { - HTMLLazyEventListener -#if ENABLE(SVG) - , SVGLazyEventListener -#endif - }; - - virtual bool wasCreatedFromMarkup() const { return true; } - - static PassRefPtr<JSLazyEventListener> 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<JS##type*>(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/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<PositionOptions> 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 <runtime/Error.h> 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<UChar> 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<HTMLDocument*>(impl())->write(writeHelper(exec, args), activeDocument); + documentWrite(exec, args, static_cast<HTMLDocument*>(impl()), DoNotAddNewline); return jsUndefined(); } JSValuePtr JSHTMLDocument::writeln(ExecState* exec, const ArgList& args) { - Document* activeDocument = asJSDOMWindow(exec->lexicalGlobalObject())->impl()->document(); - static_cast<HTMLDocument*>(impl())->write(writeHelper(exec, args) + "\n", activeDocument); + documentWrite(exec, args, static_cast<HTMLDocument*>(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<HTMLInputElement*>(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<HTMLInputElement*>(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<HTMLInputElement*>(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<HTMLInputElement*>(impl()); + if (!input->canHaveSelection()) + throwError(exec, TypeError); + + input->setSelectionEnd(value.toInt32(exec)); +} + +JSValuePtr JSHTMLInputElement::setSelectionRange(ExecState* exec, const ArgList& args) +{ + HTMLInputElement* input = static_cast<HTMLInputElement*>(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<JSDocument*>(asObject(toJS(exec, static_cast<Document*>(context)))); + + putDirect(exec->propertyNames().prototype, JSHTMLImageElementPrototype::self(exec), None); +} + +Document* JSImageConstructor::document() const +{ + return static_cast<Document*>(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<JSObject*, JSInspectedObjectWrapper*> WrapperMap; typedef HashMap<JSGlobalObject*, WrapperMap*> 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<JSObject*, JSInspectorCallbackWrapper*> 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 <webkit@mattlilek.com> + * 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 <profiler/Profile.h> +#include <profiler/Profiler.h> +#include <runtime/JSArray.h> +#include <runtime/JSLock.h> +#include <wtf/Vector.h> + +#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<RefPtr<Profile> >& 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<InspectorResource> 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<InspectorResource> 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<Range> searchRange(rangeOfContents(node)); + + ExceptionCode ec = 0; + do { + RefPtr<Range> 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<String> 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<String>& 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<String> 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 <runtime/FunctionConstructor.h> + +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<JSDOMWindow*>(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<JSFunction*>(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<JSNode*>(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<JSLazyEventListener*>(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<JSLazyEventListener> 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<Document*>(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<JSUnprotectedEventListener*>(m_impl->onmessage())) - listener->mark(); - - if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(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<JSUnprotectedEventListener*>(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<JSUnprotectedEventListener> listener = globalObject->findOrCreateJSUnprotectedEventListener(exec, args.at(exec, 1)); + RefPtr<JSEventListener> 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<JSProtectedEventListener> 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<JSDocument*>(asObject(toJS(exec, static_cast<Document*>(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<Document*>(m_globalObject->scriptExecutionContext()); +} + static JSObject* constructHTMLOptionElement(ExecState* exec, JSObject* constructor, const ArgList& args) { Document* document = static_cast<JSOptionConstructor*>(constructor)->document(); - ExceptionCode ec = 0; + RefPtr<HTMLOptionElement> element = static_pointer_cast<HTMLOptionElement>(document->createElement(HTMLNames::optionTag, false)); - RefPtr<HTMLOptionElement> element = static_pointer_cast<HTMLOptionElement>(document->createElement("option", ec)); - RefPtr<Text> text; - if (ec == 0) - text = document->createTextNode(""); - if (ec == 0 && !args.at(exec, 0).isUndefined()) + ExceptionCode ec = 0; + RefPtr<Text> 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> 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<JSEventListener> listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1))) + if (RefPtr<JSProtectedEventListener> 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 <wtf/StdLibExtras.h> 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/JSEventTargetNodeCustom.cpp b/WebCore/bindings/js/JSWebKitPointConstructor.cpp index 3193272..c3a8ea6 100644 --- a/WebCore/bindings/js/JSEventTargetNodeCustom.cpp +++ b/WebCore/bindings/js/JSWebKitPointConstructor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * 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 @@ -20,52 +20,49 @@ * 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. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" -#include "JSEventTargetNode.h" +#include "JSWebKitPointConstructor.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; +#include "WebKitPoint.h" +#include "JSWebKitPoint.h" namespace WebCore { -JSValuePtr JSEventTargetNode::addEventListener(ExecState* exec, const ArgList& args) -{ - JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); - if (!globalObject) - return jsUndefined(); +using namespace JSC; - if (RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1))) - impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec)); +const ClassInfo JSWebKitPointConstructor::s_info = { "WebKitPointConstructor", 0, 0, 0 }; - return jsUndefined(); +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); } -JSValuePtr JSEventTargetNode::removeEventListener(ExecState* exec, const ArgList& args) +static JSObject* constructWebKitPoint(ExecState* exec, JSObject*, 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(); + 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))); } -void JSEventTargetNode::pushEventHandlerScope(ExecState*, ScopeChain&) const +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<JSC::Structure> structure, PassRefPtr<WorkerContext> impl) : JSDOMGlobalObject(structure, new JSDOMGlobalObjectData, this) @@ -81,6 +88,33 @@ void JSWorkerContextBase::put(ExecState* exec, const Identifier& propertyName, J lookupPut<JSWorkerContextBase, Base>(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<JSXMLHttpRequestConstructor>(exec, static_cast<JSWorkerContextBase*>(asObject(slot.slotBase()))); +} + +void setJSWorkerContextBaseXMLHttpRequest(ExecState* exec, JSObject* thisObject, JSValuePtr value) +{ + // Shadowing a built-in constructor + static_cast<JSWorkerContextBase*>(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<WorkerContext> 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 <interpreter/Interpreter.h> using namespace JSC; @@ -51,17 +53,14 @@ void JSWorkerContext::mark() markActiveObjectsForContext(*globalData(), scriptExecutionContext()); - if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(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<JSUnprotectedEventListener*>(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<String> 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<JSUnprotectedEventListener> listener = findOrCreateJSUnprotectedEventListener(exec, args.at(exec, 1)); + RefPtr<JSEventListener> 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<JSUnprotectedEventListener*>(m_impl->onmessage())) - listener->mark(); - - if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(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<JSUnprotectedEventListener*>(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<JSUnprotectedEventListener> listener = globalObject->findOrCreateJSUnprotectedEventListener(exec, args.at(exec, 1)); + RefPtr<JSEventListener> 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<JSDocument*>(asObject(toJS(exec, static_cast<Document*>(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 = XMLHttpRequest::create(static_cast<JSXMLHttpRequestConstructor*>(constructor)->document()); + RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(static_cast<JSXMLHttpRequestConstructor*>(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<JSUnprotectedEventListener*>(m_impl->onreadystatechange())) - onReadyStateChangeListener->mark(); - - if (JSUnprotectedEventListener* onAbortListener = static_cast<JSUnprotectedEventListener*>(m_impl->onabort())) - onAbortListener->mark(); - - if (JSUnprotectedEventListener* onErrorListener = static_cast<JSUnprotectedEventListener*>(m_impl->onerror())) - onErrorListener->mark(); - - if (JSUnprotectedEventListener* onLoadListener = static_cast<JSUnprotectedEventListener*>(m_impl->onload())) - onLoadListener->mark(); - - if (JSUnprotectedEventListener* onLoadStartListener = static_cast<JSUnprotectedEventListener*>(m_impl->onloadstart())) - onLoadStartListener->mark(); - - if (JSUnprotectedEventListener* onProgressListener = static_cast<JSUnprotectedEventListener*>(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<JSUnprotectedEventListener*>(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<JSUnprotectedEventListener> listener = globalObject->findOrCreateJSUnprotectedEventListener(exec, args.at(exec, 1)); + RefPtr<JSEventListener> 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<JSUnprotectedEventListener*>(m_impl->onabort())) - onAbortListener->mark(); - - if (JSUnprotectedEventListener* onErrorListener = static_cast<JSUnprotectedEventListener*>(m_impl->onerror())) - onErrorListener->mark(); - - if (JSUnprotectedEventListener* onLoadListener = static_cast<JSUnprotectedEventListener*>(m_impl->onload())) - onLoadListener->mark(); - - if (JSUnprotectedEventListener* onLoadStartListener = static_cast<JSUnprotectedEventListener*>(m_impl->onloadstart())) - onLoadStartListener->mark(); - - if (JSUnprotectedEventListener* onProgressListener = static_cast<JSUnprotectedEventListener*>(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<JSUnprotectedEventListener*>(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<JSUnprotectedEventListener> listener = globalObject->findOrCreateJSUnprotectedEventListener(exec, args.at(exec, 1)); + RefPtr<JSEventListener> 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 <runtime/Completion.h> +#include "npruntime_impl.h" +#include "runtime_root.h" #include <debugger/Debugger.h> #include <runtime/JSLock.h> -#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<EventListener> ScriptController::createInlineEventListener(const Stri } #if ENABLE(SVG) + PassRefPtr<EventListener> 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<Bindings::RootObject> 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<JSC::Bindings::Instance> ScriptController::createScriptInstanceForWid { if (widget->isPluginView()) { PluginView* pluginView = static_cast<PluginView*>(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 <runtime/JSLock.h> + +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 <runtime/ArgList.h> + +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 <runtime/JSObject.h> +#include <runtime/Protect.h> + +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 <runtime/JSLock.h> + +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 <JavaScriptCore/APICast.h> +#include <JavaScriptCore/JSValueRef.h> + #include <runtime/JSLock.h> #include <runtime/Protect.h> #include <runtime/UString.h> @@ -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 <runtime/Protect.h> 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 <interpreter/Interpreter.h> #include <runtime/Completion.h> @@ -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<Structure> prototypeStructure = JSWorkerContextPrototype::createStructure(jsNull()); - RefPtr<Structure> structure = JSWorkerContext::createStructure(new (m_globalData.get()) JSWorkerContextPrototype(prototypeStructure.release())); + ProtectedPtr<JSWorkerContextPrototype> prototype = new (m_globalData.get()) JSWorkerContextPrototype(prototypeStructure.release()); + + RefPtr<Structure> 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() { diff --git a/WebCore/bindings/objc/DOM.mm b/WebCore/bindings/objc/DOM.mm index 485d011..53be4ff 100644 --- a/WebCore/bindings/objc/DOM.mm +++ b/WebCore/bindings/objc/DOM.mm @@ -31,6 +31,7 @@ #import "DOMHTMLCanvasElement.h" #import "DOMInternal.h" #import "ExceptionHandlers.h" +#import "Frame.h" #import "HTMLNames.h" #import "HTMLPlugInElement.h" #import "NodeIterator.h" @@ -400,7 +401,7 @@ static NSArray *kit(const Vector<IntRect>& rects) WebCore::RenderObject *renderer = [self _node]->renderer(); if (renderer) { Vector<WebCore::IntRect> rects; - renderer->addLineBoxRects(rects); + renderer->absoluteRectsForRange(rects); return kit(rects); } return nil; @@ -524,18 +525,6 @@ static NSArray *kit(const Vector<IntRect>& rects) return nil; } -- (NSRect)_windowClipRect -{ - WebCore::RenderObject* renderer = [self _element]->renderer(); - if (renderer && renderer->view()) { - WebCore::FrameView* frameView = renderer->view()->frameView(); - if (!frameView) - return WebCore::IntRect(); - return frameView->windowClipRectForLayer(renderer->enclosingLayer(), true); - } - return WebCore::IntRect(); -} - // FIXME: this should be implemented in the implementation - (NSURL *)_getURLAttribute:(NSString *)name { @@ -546,17 +535,6 @@ static NSArray *kit(const Vector<IntRect>& rects) } // FIXME: this should be implemented in the implementation -- (void *)_NPObject -{ -#if ENABLE(NETSCAPE_PLUGIN_API) - WebCore::Element* element = [self _element]; - if (element->hasTagName(WebCore::HTMLNames::appletTag) || element->hasTagName(WebCore::HTMLNames::embedTag) || element->hasTagName(WebCore::HTMLNames::objectTag)) - return static_cast<WebCore::HTMLPlugInElement*>(element)->getNPObject(); -#endif - return 0; -} - -// FIXME: this should be implemented in the implementation - (BOOL)isFocused { WebCore::Element* impl = [self _element]; diff --git a/WebCore/bindings/objc/DOMAbstractView.mm b/WebCore/bindings/objc/DOMAbstractView.mm index 728a39a..7bfe7f1 100644 --- a/WebCore/bindings/objc/DOMAbstractView.mm +++ b/WebCore/bindings/objc/DOMAbstractView.mm @@ -44,7 +44,7 @@ - (void)dealloc { - { DOM_ASSERT_MAIN_THREAD(); WebCoreThreadViolationCheck(); } + { DOM_ASSERT_MAIN_THREAD(); WebCoreThreadViolationCheckRoundOne(); } [super dealloc]; } @@ -79,7 +79,7 @@ - (id)_initWithFrame:(WebCore::Frame *)impl { - { DOM_ASSERT_MAIN_THREAD(); WebCoreThreadViolationCheck(); }; + { DOM_ASSERT_MAIN_THREAD(); WebCoreThreadViolationCheckRoundOne(); }; [super _init]; _internal = reinterpret_cast<DOMObjectInternal*>(impl); WebCore::addDOMWrapper(self, impl); @@ -88,7 +88,7 @@ + (DOMAbstractView *)_wrapAbstractView:(WebCore::DOMWindow *)impl { - { DOM_ASSERT_MAIN_THREAD(); WebCoreThreadViolationCheck(); }; + { DOM_ASSERT_MAIN_THREAD(); WebCoreThreadViolationCheckRoundOne(); }; if (!impl) return nil; diff --git a/WebCore/bindings/objc/DOMPrivate.h b/WebCore/bindings/objc/DOMPrivate.h index 0ee5979..ba95ce3 100644 --- a/WebCore/bindings/objc/DOMPrivate.h +++ b/WebCore/bindings/objc/DOMPrivate.h @@ -86,8 +86,6 @@ - (NSFont *)_font; - (NSData *)_imageTIFFRepresentation; - (NSURL *)_getURLAttribute:(NSString *)name; -- (void *)_NPObject; // For subclasses to implement; we only allow NPObjects to be created for certain element types -- (NSRect)_windowClipRect; // Clip rect in NSWindow coords (used by plugins) - (BOOL)isFocused; @end diff --git a/WebCore/bindings/objc/WebScriptObject.mm b/WebCore/bindings/objc/WebScriptObject.mm index f08d61b..3cdae86 100644 --- a/WebCore/bindings/objc/WebScriptObject.mm +++ b/WebCore/bindings/objc/WebScriptObject.mm @@ -298,9 +298,9 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root if (![self _isSafeScript]) return nil; - [self _rootObject]->globalObject()->startTimeoutCheck(); + [self _rootObject]->globalObject()->globalData()->timeoutChecker.start(); JSValuePtr result = call(exec, function, callType, callData, [self _imp], argList); - [self _rootObject]->globalObject()->stopTimeoutCheck(); + [self _rootObject]->globalObject()->globalData()->timeoutChecker.stop(); if (exec->hadException()) { addExceptionToConsole(exec); @@ -327,9 +327,9 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root JSValuePtr result; JSLock lock(false); - [self _rootObject]->globalObject()->startTimeoutCheck(); + [self _rootObject]->globalObject()->globalData()->timeoutChecker.start(); Completion completion = JSC::evaluate([self _rootObject]->globalObject()->globalExec(), [self _rootObject]->globalObject()->globalScopeChain(), makeSource(String(script))); - [self _rootObject]->globalObject()->stopTimeoutCheck(); + [self _rootObject]->globalObject()->globalData()->timeoutChecker.stop(); ComplType type = completion.complType(); if (type == Normal) { diff --git a/WebCore/bindings/scripts/CodeGenerator.pm b/WebCore/bindings/scripts/CodeGenerator.pm index 7a4d095..4f899be 100644 --- a/WebCore/bindings/scripts/CodeGenerator.pm +++ b/WebCore/bindings/scripts/CodeGenerator.pm @@ -131,9 +131,6 @@ sub AddMethodsConstantsAndAttributesFromParentClasses my $functionsRef = $dataNode->functions; my $attributesRef = $dataNode->attributes; - # Exception: For the DOM 'Node' is our topmost baseclass, not EventTargetNode. - return if $parentsMax eq 1 and $parents[0] eq "EventTargetNode"; - foreach (@{$dataNode->parents}) { if ($ignoreParent) { # Ignore first parent class, already handled by the generation itself. @@ -196,9 +193,6 @@ sub GetMethodsAndAttributesFromParentClasses foreach (@{$dataNode->parents}) { my $interface = $object->StripModule($_); - if ($interface eq "EventTargetNode") { - $interface = "Node"; - } # Step #1: Find the IDL file associated with 'interface' $endCondition = 0; diff --git a/WebCore/bindings/scripts/CodeGeneratorCOM.pm b/WebCore/bindings/scripts/CodeGeneratorCOM.pm index 0c86ef2..4e363aa 100644 --- a/WebCore/bindings/scripts/CodeGeneratorCOM.pm +++ b/WebCore/bindings/scripts/CodeGeneratorCOM.pm @@ -236,7 +236,6 @@ sub GetParentInterface { my ($dataNode) = @_; return "I" . $TEMP_PREFIX . "DOMObject" if (@{$dataNode->parents} == 0); - return "I" . $TEMP_PREFIX . "DOMNode" if $codeGenerator->StripModule($dataNode->parents(0)) eq "EventTargetNode"; return GetInterfaceName($codeGenerator->StripModule($dataNode->parents(0))); } @@ -244,7 +243,6 @@ sub GetParentClass { my ($dataNode) = @_; return $TEMP_PREFIX . "DOMObject" if (@{$dataNode->parents} == 0); - return $TEMP_PREFIX . "DOMNode" if $codeGenerator->StripModule($dataNode->parents(0)) eq "EventTargetNode"; return GetClassName($codeGenerator->StripModule($dataNode->parents(0))); } @@ -316,7 +314,6 @@ sub AddIncludesForTypeInCPPImplementation } # Special casing - $CPPImplementationWebCoreIncludes{"EventTargetNode.h"} = 1 if $type eq "Node"; $CPPImplementationWebCoreIncludes{"NameNodeList.h"} = 1 if $type eq "NodeList"; $CPPImplementationWebCoreIncludes{"CSSMutableStyleDeclaration.h"} = 1 if $type eq "CSSStyleDeclaration"; @@ -706,7 +703,6 @@ sub GenerateCPPFunction my $functionName = $function->signature->name; my $returnIDLType = $function->signature->type; my $noReturn = ($returnIDLType eq "void"); - my $requiresEventTargetNodeCast = $function->signature->extendedAttributes->{"EventTargetNodeCast"}; my $raisesExceptions = @{$function->raisesExceptions}; AddIncludesForTypeInCPPImplementation($returnIDLType); @@ -756,9 +752,6 @@ sub GenerateCPPFunction push(@parameterList, "ec") if $raisesExceptions; my $implementationGetter = "impl${implementationClassWithoutNamespace}()"; - if ($requiresEventTargetNodeCast) { - $implementationGetter = "WebCore::EventTargetNodeCast(${implementationGetter})"; - } my $callSigBegin = " "; my $callSigMiddle = "${implementationGetter}->" . $codeGenerator->WK_lcfirst($functionName) . "(" . join(", ", @parameterList) . ")"; @@ -801,10 +794,6 @@ sub GenerateCPPFunction } push(@functionImplementation, " WebCore::ExceptionCode ec = 0;\n") if $raisesExceptions; # FIXME: CHECK EXCEPTION AND DO SOMETHING WITH IT push(@functionImplementation, join("\n", @parameterInitialization) . (@parameterInitialization > 0 ? "\n" : "")); - if ($requiresEventTargetNodeCast) { - push(@functionImplementation, " if (!impl${implementationClassWithoutNamespace}()->isEventTargetNode())\n"); - push(@functionImplementation, " return E_FAIL;\n"); - } push(@functionImplementation, $callSigBegin . $callSigMiddle . $callSigEnd . "\n"); push(@functionImplementation, " return S_OK;\n"); push(@functionImplementation, "}\n\n"); diff --git a/WebCore/bindings/scripts/CodeGeneratorJS.pm b/WebCore/bindings/scripts/CodeGeneratorJS.pm index 2af88e2..08ef971 100644 --- a/WebCore/bindings/scripts/CodeGeneratorJS.pm +++ b/WebCore/bindings/scripts/CodeGeneratorJS.pm @@ -174,7 +174,7 @@ sub AddIncludesForType # When we're finished with the one-file-per-class # reorganization, we won't need these special cases. if ($codeGenerator->IsPrimitiveType($type) or AvoidInclusionOfType($type) - or $type eq "DOMString" or $type eq "DOMObject" or $type eq "RGBColor") { + or $type eq "DOMString" or $type eq "DOMObject" or $type eq "RGBColor" or $type eq "Array") { } elsif ($type =~ /SVGPathSeg/) { $joinedName = $type; $joinedName =~ s/Abs|Rel//; @@ -284,29 +284,19 @@ sub GenerateGetOwnPropertySlotBody push(@getOwnPropertySlotImpl, " return false;\n\n"); } - my $hasNameGetterGeneration = sub { - push(@getOwnPropertySlotImpl, " if (canGetItemsForName(exec, static_cast<$implClassName*>(impl()), propertyName)) {\n"); - push(@getOwnPropertySlotImpl, " slot.setCustom(this, nameGetter);\n"); - push(@getOwnPropertySlotImpl, " return true;\n"); - push(@getOwnPropertySlotImpl, " }\n"); - if ($inlined) { - $headerIncludes{"AtomicString.h"} = 1; - } else { - $implIncludes{"AtomicString.h"} = 1; + my $manualLookupGetterGeneration = sub { + my $requiresManualLookup = $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasNameGetter"}; + if ($requiresManualLookup) { + push(@getOwnPropertySlotImpl, " const ${namespaceMaybe}HashEntry* entry = ${className}Table.entry(exec, propertyName);\n"); + push(@getOwnPropertySlotImpl, " if (entry) {\n"); + push(@getOwnPropertySlotImpl, " slot.setCustom(this, entry->propertyGetter());\n"); + push(@getOwnPropertySlotImpl, " return true;\n"); + push(@getOwnPropertySlotImpl, " }\n"); } }; - if ($dataNode->extendedAttributes->{"HasOverridingNameGetter"}) { - &$hasNameGetterGeneration(); - } - - my $requiresManualLookup = $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasNameGetter"}; - if ($requiresManualLookup) { - push(@getOwnPropertySlotImpl, " const ${namespaceMaybe}HashEntry* entry = ${className}Table.entry(exec, propertyName);\n"); - push(@getOwnPropertySlotImpl, " if (entry) {\n"); - push(@getOwnPropertySlotImpl, " slot.setCustom(this, entry->propertyGetter());\n"); - push(@getOwnPropertySlotImpl, " return true;\n"); - push(@getOwnPropertySlotImpl, " }\n"); + if (!$dataNode->extendedAttributes->{"HasOverridingNameGetter"}) { + &$manualLookupGetterGeneration(); } if ($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"}) { @@ -322,8 +312,20 @@ sub GenerateGetOwnPropertySlotBody push(@getOwnPropertySlotImpl, " }\n"); } - if ($dataNode->extendedAttributes->{"HasNameGetter"}) { - &$hasNameGetterGeneration(); + if ($dataNode->extendedAttributes->{"HasNameGetter"} || $dataNode->extendedAttributes->{"HasOverridingNameGetter"}) { + push(@getOwnPropertySlotImpl, " if (canGetItemsForName(exec, static_cast<$implClassName*>(impl()), propertyName)) {\n"); + push(@getOwnPropertySlotImpl, " slot.setCustom(this, nameGetter);\n"); + push(@getOwnPropertySlotImpl, " return true;\n"); + push(@getOwnPropertySlotImpl, " }\n"); + if ($inlined) { + $headerIncludes{"AtomicString.h"} = 1; + } else { + $implIncludes{"AtomicString.h"} = 1; + } + } + + if ($dataNode->extendedAttributes->{"HasOverridingNameGetter"}) { + &$manualLookupGetterGeneration(); } if ($dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"}) { @@ -386,9 +388,6 @@ sub GenerateHeader push(@headerContentHeader, "#include <runtime/JSGlobalObject.h>\n"); push(@headerContentHeader, "#include <runtime/ObjectPrototype.h>\n"); } - if ($interfaceName eq "Node") { - push(@headerContentHeader, "#include \"EventTargetNode.h\"\n"); - } if ($dataNode->extendedAttributes->{"CustomCall"}) { push(@headerContentHeader, "#include <runtime/CallData.h>\n"); @@ -536,7 +535,7 @@ sub GenerateHeader if ($numAttributes > 0) { foreach (@{$dataNode->attributes}) { my $attribute = $_; - $numCustomAttributes++ if $attribute->signature->extendedAttributes->{"Custom"}; + $numCustomAttributes++ if $attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"JSCCustom"}; $numCustomAttributes++ if $attribute->signature->extendedAttributes->{"CustomGetter"}; $numCustomAttributes++ if $attribute->signature->extendedAttributes->{"CustomSetter"}; } @@ -546,7 +545,7 @@ sub GenerateHeader push(@headerContent, "\n // Custom attributes\n"); foreach my $attribute (@{$dataNode->attributes}) { - if ($attribute->signature->extendedAttributes->{"Custom"}) { + if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"JSCCustom"}) { push(@headerContent, " JSC::JSValuePtr " . $codeGenerator->WK_lcfirst($attribute->signature->name) . "(JSC::ExecState*) const;\n"); if ($attribute->type !~ /^readonly/) { push(@headerContent, " void set" . $codeGenerator->WK_ucfirst($attribute->signature->name) . "(JSC::ExecState*, JSC::JSValuePtr);\n"); @@ -562,13 +561,13 @@ sub GenerateHeader } foreach my $function (@{$dataNode->functions}) { - $numCustomFunctions++ if $function->signature->extendedAttributes->{"Custom"}; + $numCustomFunctions++ if $function->signature->extendedAttributes->{"Custom"} || $function->signature->extendedAttributes->{"JSCCustom"}; } if ($numCustomFunctions > 0) { push(@headerContent, "\n // Custom functions\n"); foreach my $function (@{$dataNode->functions}) { - if ($function->signature->extendedAttributes->{"Custom"}) { + if ($function->signature->extendedAttributes->{"Custom"} || $function->signature->extendedAttributes->{"JSCCustom"}) { my $functionImplementationName = $function->signature->extendedAttributes->{"ImplementationFunction"} || $codeGenerator->WK_lcfirst($function->signature->name); push(@headerContent, " JSC::JSValuePtr " . $functionImplementationName . "(JSC::ExecState*, const JSC::ArgList&);\n"); } @@ -636,11 +635,6 @@ sub GenerateHeader } else { push(@headerContent, "JSC::JSValuePtr toJS(JSC::ExecState*, $implType*);\n"); } - - # Resolve ambiguity with EventTarget that otherwise exists. - if ($interfaceName eq "Node") { - push(@headerContent, "inline JSC::JSValuePtr toJS(JSC::ExecState* exec, EventTargetNode* node) { return toJS(exec, static_cast<Node*>(node)); }\n"); - } } if (!$hasParent || $dataNode->extendedAttributes->{"GenerateNativeConverter"}) { if ($podType) { @@ -763,7 +757,7 @@ sub GenerateImplementation push(@implContent, "\nusing namespace JSC;\n\n"); push(@implContent, "namespace WebCore {\n\n"); - push(@implContent, "ASSERT_CLASS_FITS_IN_CELL($className)\n\n"); + push(@implContent, "ASSERT_CLASS_FITS_IN_CELL($className);\n\n"); # - Add all attributes in a hashtable definition my $numAttributes = @{$dataNode->attributes}; @@ -1080,7 +1074,7 @@ sub GenerateImplementation push(@implContent, " return jsUndefined();\n"); } - if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"CustomGetter"}) { + if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"JSCCustom"} || $attribute->signature->extendedAttributes->{"CustomGetter"}) { push(@implContent, " return static_cast<$className*>(asObject(slot.slotBase()))->$implGetterFunctionName(exec);\n"); } elsif ($attribute->signature->extendedAttributes->{"CheckNodeSecurity"}) { $implIncludes{"JSDOMBinding.h"} = 1; @@ -1092,19 +1086,12 @@ sub GenerateImplementation push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(asObject(slot.slotBase()))->impl());\n"); push(@implContent, " return checkNodeSecurity(exec, imp->contentDocument()) ? " . NativeToJSValue($attribute->signature, 0, $implClassName, $implClassNameForValueConversion, "imp->$implGetterFunctionName()", "static_cast<$className*>(asObject(slot.slotBase()))") . " : jsUndefined();\n"); } elsif ($type eq "EventListener") { - $implIncludes{"JSEventListener.h"} = 1; $implIncludes{"EventListener.h"} = 1; - my $listenerType; - if ($attribute->signature->extendedAttributes->{"ProtectedListener"}) { - $listenerType = "JSEventListener"; - } else { - $listenerType = "JSUnprotectedEventListener"; - } push(@implContent, " UNUSED_PARAM(exec);\n"); push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(asObject(slot.slotBase()))->impl());\n"); - push(@implContent, " if (${listenerType}* listener = static_cast<${listenerType}*>(imp->$implGetterFunctionName())) {\n"); - push(@implContent, " if (JSObject* listenerObj = listener->listenerObj())\n"); - push(@implContent, " return listenerObj;\n"); + push(@implContent, " if (EventListener* listener = imp->$implGetterFunctionName()) {\n"); + push(@implContent, " if (JSObject* function = listener->function())\n"); + push(@implContent, " return function;\n"); push(@implContent, " }\n"); push(@implContent, " return jsNull();\n"); } elsif ($attribute->signature->type =~ /Constructor$/) { @@ -1220,16 +1207,16 @@ sub GenerateImplementation push(@implContent, " return;\n"); } - if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"CustomSetter"}) { + if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"JSCCustom"} || $attribute->signature->extendedAttributes->{"CustomSetter"}) { push(@implContent, " static_cast<$className*>(thisObject)->set$implSetterFunctionName(exec, value);\n"); } elsif ($type eq "EventListener") { $implIncludes{"JSEventListener.h"} = 1; push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(thisObject)->impl());\n"); my $listenerType; if ($attribute->signature->extendedAttributes->{"ProtectedListener"}) { - $listenerType = "JSEventListener"; + $listenerType = "JSProtectedEventListener"; } else { - $listenerType = "JSUnprotectedEventListener"; + $listenerType = "JSEventListener"; } if ($dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"}) { push(@implContent, " JSDOMGlobalObject* globalObject = static_cast<$className*>(thisObject);\n"); @@ -1248,6 +1235,7 @@ sub GenerateImplementation push(@implContent, " // Shadowing a built-in constructor\n"); push(@implContent, " static_cast<$className*>(thisObject)->putDirect(Identifier(exec, \"$name\"), value);\n"); } elsif ($attribute->signature->extendedAttributes->{"Replaceable"}) { + push(@implContent, " // Shadowing a built-in object\n"); push(@implContent, " static_cast<$className*>(thisObject)->putDirect(Identifier(exec, \"$name\"), value);\n"); } else { if ($podType) { @@ -1331,7 +1319,7 @@ sub GenerateImplementation push(@implContent, " return jsUndefined();\n"); } - if ($function->signature->extendedAttributes->{"Custom"}) { + if ($function->signature->extendedAttributes->{"Custom"} || $function->signature->extendedAttributes->{"JSCCustom"}) { push(@implContent, " return castedThisObj->" . $functionImplementationName . "(exec, args);\n"); } else { if ($podType) { @@ -1557,7 +1545,6 @@ sub GetNativeTypeFromSignature my %nativeType = ( "CompareHow" => "Range::CompareHow", "DOMString" => "const UString&", - "EventTarget" => "EventTargetNode*", "NodeFilter" => "RefPtr<NodeFilter>", "SVGLength" => "SVGLength", "SVGMatrix" => "TransformationMatrix", @@ -1605,11 +1592,6 @@ sub JSValueToNative return "$value.toString(exec)"; } - if ($type eq "EventTarget") { - $implIncludes{"JSEventTargetNode.h"} = 1; - return "toEventTargetNode($value)"; - } - $implIncludes{"FloatPoint.h"} = 1 if $type eq "SVGPoint"; $implIncludes{"FloatRect.h"} = 1 if $type eq "SVGRect"; $implIncludes{"HTMLOptionElement.h"} = 1 if $type eq "HTMLOptionElement"; diff --git a/WebCore/bindings/scripts/CodeGeneratorObjC.pm b/WebCore/bindings/scripts/CodeGeneratorObjC.pm index 68fce3d..5ec960e 100644 --- a/WebCore/bindings/scripts/CodeGeneratorObjC.pm +++ b/WebCore/bindings/scripts/CodeGeneratorObjC.pm @@ -79,7 +79,7 @@ my $buildingForTigerOrEarlier = 1 if $ENV{"MACOSX_DEPLOYMENT_TARGET"} and $ENV{" my $buildingForLeopardOrLater = 1 if $ENV{"MACOSX_DEPLOYMENT_TARGET"} and $ENV{"MACOSX_DEPLOYMENT_TARGET"} >= 10.5; my $exceptionInit = "WebCore::ExceptionCode ec = 0;"; my $exceptionRaiseOnError = "WebCore::raiseOnDOMError(ec);"; -my $assertMainThread = "{ DOM_ASSERT_MAIN_THREAD(); WebCoreThreadViolationCheck(); }"; +my $assertMainThread = "{ DOM_ASSERT_MAIN_THREAD(); WebCoreThreadViolationCheckRoundOne(); }"; my %conflictMethod = ( # FIXME: Add C language keywords? @@ -345,7 +345,6 @@ sub GetParentImplClassName my $parent = $codeGenerator->StripModule($dataNode->parents(0)); # special cases - return "Node" if $parent eq "EventTargetNode"; return "Object" if $parent eq "HTMLCollection"; return $parent; @@ -373,8 +372,6 @@ sub GetParentAndProtocols } else { if (IsProtocolType($parentName)) { push(@protocols, "DOM" . $parentName); - } elsif ($parentName eq "EventTargetNode") { - $parent = "DOMNode"; } elsif ($parentName eq "HTMLCollection") { $parent = "DOMObject"; } else { @@ -507,7 +504,7 @@ sub GetObjCTypeGetter my $type = $codeGenerator->StripModule(shift); return $argName if $codeGenerator->IsPrimitiveType($type) or $codeGenerator->IsStringType($type) or IsNativeObjCType($type); - return $argName . "EventTarget" if $type eq "EventTarget"; + return $argName . "Node" if $type eq "EventTarget"; return "static_cast<WebCore::Range::CompareHow>($argName)" if $type eq "CompareHow"; return "static_cast<WebCore::SVGPaint::SVGPaintType>($argName)" if $type eq "SVGPaintType"; @@ -623,7 +620,7 @@ sub AddIncludesForType } if ($type eq "EventTarget") { - $implIncludes{"EventTargetNode.h"} = 1; + $implIncludes{"Node.h"} = 1; $implIncludes{"DOM$type.h"} = 1; return; } @@ -1406,7 +1403,6 @@ sub GenerateImplementation my $paramName = $needsCustom{"EventTarget"}; push(@functionContent, " DOMNode* ${paramName}ObjC = $paramName;\n"); push(@functionContent, " WebCore::Node* ${paramName}Node = [${paramName}ObjC _node];\n"); - push(@functionContent, " WebCore::EventTargetNode* ${paramName}EventTarget = (${paramName}Node && ${paramName}Node->isEventTargetNode()) ? static_cast<WebCore::EventTargetNode*>(${paramName}Node) : 0;\n\n"); $implIncludes{"DOMNode.h"} = 1; $implIncludes{"Node.h"} = 1; } @@ -1419,16 +1415,6 @@ sub GenerateImplementation $caller = "dv"; } - if ($function->signature->extendedAttributes->{"EventTargetNodeCast"}) { - if ($dataNode->name =~ /^SVG/) { - $caller = "static_cast<WebCore::SVGElementInstance*>($caller)"; - } else { - push(@functionContent, " if (!$caller->isEventTargetNode())\n"); - $caller = "WebCore::EventTargetNodeCast($caller)"; - push(@functionContent, " WebCore::raiseDOMException(DOM_NOT_SUPPORTED_ERR);\n"); - } - } - # special case the EventListener if (defined $needsCustom{"EventListener"}) { my $paramName = $needsCustom{"EventListener"}; diff --git a/WebCore/bindings/v8/ScheduledAction.cpp b/WebCore/bindings/v8/ScheduledAction.cpp new file mode 100644 index 0000000..7c71d00 --- /dev/null +++ b/WebCore/bindings/v8/ScheduledAction.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2007-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 "ScheduledAction.h" + +#include "Document.h" +#include "ScriptExecutionContext.h" +#include "ScriptSourceCode.h" + +#include "V8Binding.h" +#include "V8Proxy.h" + +namespace WebCore { + +ScheduledAction::ScheduledAction(v8::Handle<v8::Function> func, int argc, v8::Handle<v8::Value> argv[]) + : m_code(String(), KURL(), 0) +{ + m_function = v8::Persistent<v8::Function>::New(func); + +#ifndef NDEBUG + V8Proxy::RegisterGlobalHandle(SCHEDULED_ACTION, this, m_function); +#endif + + m_argc = argc; + if (argc > 0) { + m_argv = new v8::Persistent<v8::Value>[argc]; + for (int i = 0; i < argc; i++) { + m_argv[i] = v8::Persistent<v8::Value>::New(argv[i]); + +#ifndef NDEBUG + V8Proxy::RegisterGlobalHandle(SCHEDULED_ACTION, this, m_argv[i]); +#endif + } + } else + m_argv = 0; +} + +ScheduledAction::~ScheduledAction() +{ + if (m_function.IsEmpty()) + return; + +#ifndef NDEBUG + V8Proxy::UnregisterGlobalHandle(this, m_function); +#endif + m_function.Dispose(); + + for (int i = 0; i < m_argc; i++) { +#ifndef NDEBUG + V8Proxy::UnregisterGlobalHandle(this, m_argv[i]); +#endif + m_argv[i].Dispose(); + } + + if (m_argc > 0) + delete[] m_argv; +} + +void ScheduledAction::execute(ScriptExecutionContext* context) +{ + // FIXME: Timeouts for running the javascript code are not set. + V8Proxy* proxy = V8Proxy::retrieve(context); + if (!proxy) + return; + + v8::HandleScope handleScope; + v8::Local<v8::Context> v8Context = proxy->GetContext(); + if (v8Context.IsEmpty()) + return; // JS may not be enabled. + + v8::Context::Scope scope(v8Context); + + proxy->setTimerCallback(true); + + if (!m_function.IsEmpty() && m_function->IsFunction()) + proxy->CallFunction(v8::Persistent<v8::Function>::Cast(m_function), v8Context->Global(), m_argc, m_argv); + else + proxy->evaluate(m_code, 0); + + if (context->isDocument()) + static_cast<Document*>(context)->updateRendering(); + + proxy->setTimerCallback(false); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/ScheduledAction.h b/WebCore/bindings/v8/ScheduledAction.h new file mode 100644 index 0000000..da6cb02 --- /dev/null +++ b/WebCore/bindings/v8/ScheduledAction.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2007-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 ScheduledAction_h +#define ScheduledAction_h + +#include "ScriptSourceCode.h" + +#include <v8.h> + +namespace WebCore { + + class String; + class ScriptExecutionContext; + + class ScheduledAction { + public: + ScheduledAction(v8::Handle<v8::Function>, int argc, v8::Handle<v8::Value> argv[]); + explicit ScheduledAction(const WebCore::String& code) + : m_argc(0) + , m_argv(0) + , m_code(code) + { + } + + virtual ~ScheduledAction(); + virtual void execute(ScriptExecutionContext*); + + private: + v8::Persistent<v8::Function> m_function; + int m_argc; + v8::Persistent<v8::Value>* m_argv; + ScriptSourceCode m_code; + }; + +} // namespace WebCore + +#endif // ScheduledAction diff --git a/WebCore/bindings/v8/ScriptCachedFrameData.h b/WebCore/bindings/v8/ScriptCachedFrameData.h new file mode 100644 index 0000000..e6530f4 --- /dev/null +++ b/WebCore/bindings/v8/ScriptCachedFrameData.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2008, 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 ScriptCachedPageData_h +#define ScriptCachedPageData_h + +// We don't use WebKit's page caching, so this implementation is just a stub. + +namespace WebCore { + class Frame; + class DOMWindow; + + class ScriptCachedFrameData { + public: + ScriptCachedFrameData(Frame*) { } + ~ScriptCachedFrameData() { } + + void restore(Frame*) { } + void clear() { } + DOMWindow* domWindow() const { return 0; } + }; + +} // namespace WebCore + +#endif // ScriptCachedPageData_h diff --git a/WebCore/bindings/v8/ScriptCallFrame.cpp b/WebCore/bindings/v8/ScriptCallFrame.cpp new file mode 100644 index 0000000..ab30862 --- /dev/null +++ b/WebCore/bindings/v8/ScriptCallFrame.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2008, 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 "ScriptCallFrame.h" + +#include <v8.h> + +#include "PlatformString.h" +#include "V8Binding.h" +#include "V8Proxy.h" +#include "ScriptValue.h" + +namespace WebCore { + +ScriptCallFrame::ScriptCallFrame(const String& functionName, const String& urlString, int lineNumber, const v8::Arguments& arguments, unsigned skipArgumentCount) + : m_functionName(functionName) + , m_sourceURL(urlString) + , m_lineNumber(lineNumber) +{ + for (int i = 0; i < arguments.Length(); ++i) + m_arguments.append(ScriptValue(arguments[i])); +} + +ScriptCallFrame::~ScriptCallFrame() +{ +} + +const ScriptValue& ScriptCallFrame::argumentAt(unsigned index) const +{ + ASSERT(m_arguments.size() > index); + return m_arguments[index]; +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptCallFrame.h b/WebCore/bindings/v8/ScriptCallFrame.h new file mode 100644 index 0000000..50357cf --- /dev/null +++ b/WebCore/bindings/v8/ScriptCallFrame.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2008, 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 ScriptCallFrame_h +#define ScriptCallFrame_h + +#include "KURL.h" +#include "ScriptString.h" + +#include <wtf/Vector.h> + +namespace v8 { + class Arguments; +} + +namespace WebCore { + class ScriptValue; + + // FIXME: Implement retrieving line number and source URL and storing here + // for all call frames, not just the first one. + // See <https://bugs.webkit.org/show_bug.cgi?id=22556> and + // <https://bugs.webkit.org/show_bug.cgi?id=21180> + class ScriptCallFrame { + public: + ScriptCallFrame(const String& functionName, const String& urlString, int lineNumber, const v8::Arguments&, unsigned skipArgumentCount); + ~ScriptCallFrame(); + + const ScriptString& functionName() const { return m_functionName; } + const KURL& sourceURL() const { return m_sourceURL; } + unsigned lineNumber() const { return m_lineNumber; } + + // argument retrieval methods + const ScriptValue& argumentAt(unsigned) const; + unsigned argumentCount() const { return m_arguments.size(); } + + private: + ScriptString m_functionName; + KURL m_sourceURL; + unsigned m_lineNumber; + + Vector<ScriptValue> m_arguments; + }; + +} // namespace WebCore + +#endif // ScriptCallFrame_h diff --git a/WebCore/bindings/v8/ScriptCallStack.cpp b/WebCore/bindings/v8/ScriptCallStack.cpp new file mode 100644 index 0000000..9188dcf --- /dev/null +++ b/WebCore/bindings/v8/ScriptCallStack.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2008, 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 "ScriptCallStack.h" + +#include <v8.h> + +#include "V8Binding.h" +#include "V8Proxy.h" + +namespace WebCore { + +ScriptCallStack::ScriptCallStack(const v8::Arguments& arguments, unsigned skipArgumentCount) + : m_lastCaller(String(), V8Proxy::GetSourceName(), V8Proxy::GetSourceLineNumber() + 1, arguments, skipArgumentCount) +{ +} + +ScriptCallStack::~ScriptCallStack() +{ +} + +const ScriptCallFrame& ScriptCallStack::at(unsigned index) const +{ + // Currently, only one ScriptCallFrame is supported. When we can get + // a full stack trace from V8, we can do this right. + ASSERT(index == 0); + return m_lastCaller; +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptCallStack.h b/WebCore/bindings/v8/ScriptCallStack.h new file mode 100644 index 0000000..2dfd484 --- /dev/null +++ b/WebCore/bindings/v8/ScriptCallStack.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2008, 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 ScriptCallStack_h +#define ScriptCallStack_h + +#include "ScriptCallFrame.h" +#include "ScriptState.h" +#include "ScriptValue.h" +#include <wtf/Noncopyable.h> + +namespace v8 { + class Arguments; +} + +namespace WebCore { + + class ScriptCallStack : public Noncopyable { + public: + ScriptCallStack(const v8::Arguments&, unsigned skipArgumentCount = 0); + ~ScriptCallStack(); + + const ScriptCallFrame& at(unsigned) const; + // FIXME: implement retrieving and storing call stack trace + unsigned size() const { return 1; } + + // FIXME: This method is obviously not implemented. + ScriptState* state() const { return 0; } + + private: + ScriptCallFrame m_lastCaller; + }; + +} // namespace WebCore + +#endif // ScriptCallStack_h diff --git a/WebCore/bindings/v8/ScriptInstance.cpp b/WebCore/bindings/v8/ScriptInstance.cpp new file mode 100644 index 0000000..aa4a396 --- /dev/null +++ b/WebCore/bindings/v8/ScriptInstance.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2008, 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 "ScriptInstance.h" + +#ifndef NDEBUG +#include "V8Proxy.h" +#endif +#include <wtf/Assertions.h> + +namespace WebCore { + +V8ScriptInstance::V8ScriptInstance() +{ +} + +V8ScriptInstance::V8ScriptInstance(v8::Handle<v8::Object> instance) +{ + set(instance); +} + +V8ScriptInstance::~V8ScriptInstance() +{ + clear(); +} + +v8::Persistent<v8::Object> V8ScriptInstance::instance() +{ + return m_instance; +} + +void V8ScriptInstance::clear() +{ + if (m_instance.IsEmpty()) + return; +#ifndef NDEBUG + V8Proxy::UnregisterGlobalHandle(this, m_instance); +#endif + m_instance.Dispose(); + m_instance.Clear(); +} + +void V8ScriptInstance::set(v8::Handle<v8::Object> instance) +{ + clear(); + if (instance.IsEmpty()) + return; + + m_instance = v8::Persistent<v8::Object>::New(instance); +#ifndef NDEBUG + V8Proxy::RegisterGlobalHandle(SCRIPTINSTANCE, this, m_instance); +#endif +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptInstance.h b/WebCore/bindings/v8/ScriptInstance.h new file mode 100644 index 0000000..2fe3736 --- /dev/null +++ b/WebCore/bindings/v8/ScriptInstance.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2008, 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 ScriptInstance_h +#define ScriptInstance_h + +#include <v8.h> + +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class V8ScriptInstance : public RefCounted<V8ScriptInstance> { +public: + static PassRefPtr<V8ScriptInstance> create(v8::Handle<v8::Object> instance) + { + return adoptRef(new V8ScriptInstance(instance)); + } + V8ScriptInstance(); + V8ScriptInstance(v8::Handle<v8::Object>); + ~V8ScriptInstance(); + v8::Persistent<v8::Object> instance(); + +private: + void clear(); + void set(v8::Handle<v8::Object>); + mutable v8::Persistent<v8::Object> m_instance; +}; + +typedef RefPtr<V8ScriptInstance> ScriptInstance; +typedef PassRefPtr<V8ScriptInstance> PassScriptInstance; + +} // namespace WebCore + +#endif // ScriptInstance_h diff --git a/WebCore/bindings/v8/ScriptSourceCode.h b/WebCore/bindings/v8/ScriptSourceCode.h new file mode 100644 index 0000000..fea387a --- /dev/null +++ b/WebCore/bindings/v8/ScriptSourceCode.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2008, 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 ScriptSourceCode_h +#define ScriptSourceCode_h + +#include "CachedScript.h" +#include "KURL.h" +#include "PlatformString.h" + +namespace WebCore { + +class ScriptSourceCode { +public: + ScriptSourceCode(const String& source, const KURL& url = KURL(), int startLine = 1) + : m_source(source) + , m_url(url) + , m_startLine(startLine) + { + } + + // We lose the encoding information from CachedScript. + // Not sure if that matters. + ScriptSourceCode(CachedScript* cs) + : m_source(cs->script()) + , m_url(cs->url()) + , m_startLine(1) + { + } + + bool isEmpty() const { return m_source.isEmpty(); } + + const String& source() const { return m_source; } + const KURL& url() const { return m_url; } + int startLine() const { return m_startLine; } + +private: + String m_source; + KURL m_url; + int m_startLine; +}; + +} // namespace WebCore + +#endif // ScriptSourceCode_h diff --git a/WebCore/bindings/v8/ScriptState.h b/WebCore/bindings/v8/ScriptState.h new file mode 100644 index 0000000..b5a9578 --- /dev/null +++ b/WebCore/bindings/v8/ScriptState.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2008, 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 ScriptState_h +#define ScriptState_h + +#include <v8.h> + +namespace WebCore { + class ScriptState { + public: + bool hadException() { return !m_exception.IsEmpty(); } + void setException(v8::Local<v8::Value> exception) + { + m_exception = exception; + } + v8::Local<v8::Value> exception() { return m_exception; } + + private: + v8::Local<v8::Value> m_exception; + }; +} + +#endif // ScriptState_h diff --git a/WebCore/bindings/v8/ScriptString.h b/WebCore/bindings/v8/ScriptString.h new file mode 100644 index 0000000..66a575f --- /dev/null +++ b/WebCore/bindings/v8/ScriptString.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2008, 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 ScriptString_h +#define ScriptString_h + +#include "PlatformString.h" + +namespace WebCore { + +class ScriptString { +public: + ScriptString(const String& s) : m_str(s) {} + ScriptString(const char* s) : m_str(s) {} + + operator String() const { return m_str; } + + bool isNull() const { return m_str.isNull(); } + size_t size() const { return m_str.length(); } + + ScriptString& operator=(const char* s) + { + m_str = s; + return *this; + } + + ScriptString& operator+=(const String& s) + { + m_str += s; + return *this; + } + +private: + String m_str; +}; + +} // namespace WebCore + +#endif // ScriptString_h diff --git a/WebCore/bindings/v8/ScriptValue.cpp b/WebCore/bindings/v8/ScriptValue.cpp new file mode 100644 index 0000000..af84e99 --- /dev/null +++ b/WebCore/bindings/v8/ScriptValue.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2008, 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 "ScriptValue.h" + +#include "V8Binding.h" + +namespace WebCore { + +bool ScriptValue::getString(String& result) const +{ + if (m_value.IsEmpty()) + return false; + + if (!m_value->IsString()) + return false; + + result = toWebCoreString(m_value); + return true; +} + +String ScriptValue::toString(ScriptState*) const +{ + return toWebCoreStringWithNullCheck(m_value); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptValue.h b/WebCore/bindings/v8/ScriptValue.h new file mode 100644 index 0000000..bfb11c2 --- /dev/null +++ b/WebCore/bindings/v8/ScriptValue.h @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2008, 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 ScriptValue_h +#define ScriptValue_h + +#include "PlatformString.h" +#include "ScriptState.h" + +#include <v8.h> + +#ifndef NDEBUG +#include "V8Proxy.h" // for register and unregister global handles. +#endif + +namespace WebCore { + +class ScriptValue { +public: + ScriptValue() {} + + ScriptValue(v8::Handle<v8::Value> value) + { + if (value.IsEmpty()) + return; + + m_value = v8::Persistent<v8::Value>::New(value); +#ifndef NDEBUG + V8Proxy::RegisterGlobalHandle(SCRIPTVALUE, this, m_value); +#endif + } + + ScriptValue(const ScriptValue& value) + { + if (value.m_value.IsEmpty()) + return; + + m_value = v8::Persistent<v8::Value>::New(value.m_value); +#ifndef NDEBUG + V8Proxy::RegisterGlobalHandle(SCRIPTVALUE, this, m_value); +#endif + } + + ScriptValue& operator=(const ScriptValue& value) + { + if (this == &value) + return *this; + + clear(); + + if (value.m_value.IsEmpty()) + return *this; + + m_value = v8::Persistent<v8::Value>::New(value.m_value); +#ifndef NDEBUG + V8Proxy::RegisterGlobalHandle(SCRIPTVALUE, this, m_value); +#endif + + return *this; + } + + bool operator==(const ScriptValue value) const + { + return m_value == value.m_value; + } + + bool operator!=(const ScriptValue value) const + { + return !operator==(value); + } + + bool isNull() const + { + return m_value->IsNull(); + } + + bool isUndefined() const + { + return m_value->IsUndefined(); + } + + bool hasNoValue() const + { + return m_value.IsEmpty(); + } + + void clear() + { + if (m_value.IsEmpty()) + return; + +#ifndef NDEBUG + V8Proxy::UnregisterGlobalHandle(this, m_value); +#endif + m_value.Dispose(); + m_value.Clear(); + } + + ~ScriptValue() + { + clear(); + } + + v8::Handle<v8::Value> v8Value() const { return m_value; } + bool getString(String& result) const; + String toString(ScriptState*) const; + +private: + mutable v8::Persistent<v8::Value> m_value; +}; + +} // namespace WebCore + +#endif // ScriptValue_h diff --git a/WebCore/bindings/v8/V8AbstractEventListener.cpp b/WebCore/bindings/v8/V8AbstractEventListener.cpp new file mode 100644 index 0000000..83ab856 --- /dev/null +++ b/WebCore/bindings/v8/V8AbstractEventListener.cpp @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2006, 2007, 2008, 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 "V8AbstractEventListener.h" + +#include "Document.h" +#include "Event.h" +#include "Frame.h" +#include "Tokenizer.h" +#include "V8Binding.h" + +namespace WebCore { + +V8AbstractEventListener::V8AbstractEventListener(Frame* frame, bool isInline) + : m_isInline(isInline) + , m_frame(frame) + , m_lineNumber(0) + , m_columnNumber(0) +{ + if (!m_frame) + return; + + // Get the position in the source if any. + if (m_isInline && m_frame->document()->tokenizer()) { + m_lineNumber = m_frame->document()->tokenizer()->lineNumber(); + m_columnNumber = m_frame->document()->tokenizer()->columnNumber(); + } +} + +void V8AbstractEventListener::invokeEventHandler(v8::Handle<v8::Context> context, Event* event, v8::Handle<v8::Value> jsEvent, bool isWindowEvent) +{ + // For compatibility, we store the event object as a property on the window called "event". Because this is the global namespace, we save away any + // existing "event" property, and then restore it after executing the javascript handler. + v8::Local<v8::String> eventSymbol = v8::String::NewSymbol("event"); + v8::Local<v8::Value> returnValue; + + { + // Catch exceptions thrown in the event handler so they do not propagate to javascript code that caused the event to fire. + // Setting and getting the 'event' property on the global object can throw exceptions as well (for instance if accessors that + // throw exceptions are defined for 'event' using __defineGetter__ and __defineSetter__ on the global object). + v8::TryCatch tryCatch; + tryCatch.SetVerbose(true); + + // Save the old 'event' property so we can restore it later. + v8::Local<v8::Value> savedEvent = context->Global()->Get(eventSymbol); + tryCatch.Reset(); + + // Make the event available in the window object. + // + // FIXME: This does not work as it does with jsc bindings if the window.event property is already set. We need to make sure that property + // access is intercepted correctly. + context->Global()->Set(eventSymbol, jsEvent); + tryCatch.Reset(); + + // Call the event handler. + returnValue = callListenerFunction(jsEvent, event, isWindowEvent); + tryCatch.Reset(); + + // Restore the old event. This must be done for all exit paths through this method. + if (savedEvent.IsEmpty()) + context->Global()->Set(eventSymbol, v8::Undefined()); + else + context->Global()->Set(eventSymbol, savedEvent); + tryCatch.Reset(); + } + + ASSERT(!V8Proxy::HandleOutOfMemory() || returnValue.IsEmpty()); + + if (returnValue.IsEmpty()) + return; + + if (!returnValue->IsNull() && !returnValue->IsUndefined() && event->storesResultAsString()) + event->storeResult(toWebCoreString(returnValue)); + + // Prevent default action if the return value is false; + // FIXME: Add example, and reference to bug entry. + if (m_isInline && returnValue->IsBoolean() && !returnValue->BooleanValue()) + event->preventDefault(); +} + +void V8AbstractEventListener::handleEvent(Event* event, bool isWindowEvent) +{ + // EventListener could be disconnected from the frame. + if (disconnected()) + return; + + // The callback function on XMLHttpRequest can clear the event listener and destroys 'this' object. Keep a local reference to it. + // See issue 889829. + RefPtr<V8AbstractEventListener> protect(this); + + v8::HandleScope handleScope; + + v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame); + if (context.IsEmpty()) + return; + + // m_frame can removed by the callback function, protect it until the callback function returns. + RefPtr<Frame> protectFrame(m_frame); + + // Enter the V8 context in which to perform the event handling. + v8::Context::Scope scope(context); + + // Get the V8 wrapper for the event object. + v8::Handle<v8::Value> jsEvent = V8Proxy::EventToV8Object(event); + + invokeEventHandler(context, event, jsEvent, isWindowEvent); + + Document::updateDocumentsRendering(); +} + +void V8AbstractEventListener::disposeListenerObject() +{ + if (!m_listener.IsEmpty()) { +#ifndef NDEBUG + V8Proxy::UnregisterGlobalHandle(this, m_listener); +#endif + m_listener.Dispose(); + m_listener.Clear(); + } +} + +v8::Local<v8::Object> V8AbstractEventListener::getReceiverObject(Event* event, bool isWindowEvent) +{ + if (!m_listener.IsEmpty() && !m_listener->IsFunction()) + return v8::Local<v8::Object>::New(m_listener); + + if (isWindowEvent) + return v8::Context::GetCurrent()->Global(); + + EventTarget* target = event->currentTarget(); + v8::Handle<v8::Value> value = V8Proxy::EventTargetToV8Object(target); + if (value.IsEmpty()) + return v8::Local<v8::Object>(); + return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value)); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/V8AbstractEventListener.h b/WebCore/bindings/v8/V8AbstractEventListener.h new file mode 100644 index 0000000..0c34a86 --- /dev/null +++ b/WebCore/bindings/v8/V8AbstractEventListener.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2006, 2007, 2008, 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 V8AbstractEventListener_h +#define V8AbstractEventListener_h + +#include "EventListener.h" +#include <v8.h> + +namespace WebCore { + + class Event; + class Frame; + + // There are two kinds of event listeners: HTML or non-HMTL. onload, onfocus, etc (attributes) are always HTML event handler type; + // Event listeners added by Window.addEventListener or EventTargetNode::addEventListener are non-HTML type. + // + // Why does this matter? + // WebKit does not allow duplicated HTML event handlers of the same type, but ALLOWs duplicated non-HTML event handlers. + class V8AbstractEventListener : public EventListener { + public: + virtual ~V8AbstractEventListener() { } + + // Returns the owner frame of the listener. + Frame* frame() { return m_frame; } + + virtual void handleEvent(Event*, bool isWindowEvent); + void invokeEventHandler(v8::Handle<v8::Context>, Event*, v8::Handle<v8::Value> jsEvent, bool isWindowEvent); + + // Returns the listener object, either a function or an object. + virtual v8::Local<v8::Object> getListenerObject() + { + return v8::Local<v8::Object>::New(m_listener); + } + + // Dispose listener object and clear the handle. + void disposeListenerObject(); + + virtual bool disconnected() const { return !m_frame; } + + protected: + v8::Persistent<v8::Object> m_listener; + + // Indicates if this is an HTML type listener. + bool m_isInline; + + private: + V8AbstractEventListener(Frame*, bool isInline); + + virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsevent, Event*, bool isWindowEvent) = 0; + + // Get the receiver object to use for event listener call. + v8::Local<v8::Object> getReceiverObject(Event*, bool isWindowEvent); + + // Frame to which the event listener is attached to. An event listener must be destroyed before its owner frame is + // deleted. See fast/dom/replaceChild.html + // FIXME: this could hold m_frame live until the event listener is deleted. + Frame* m_frame; + + // Position in the HTML source for HTML event listeners. + int m_lineNumber; + int m_columnNumber; + + friend class V8EventListener; + friend class V8ObjectEventListener; + friend class V8LazyEventListener; + }; + +} // namespace WebCore + +#endif // V8AbstractEventListener_h diff --git a/WebCore/bindings/v8/V8Binding.h b/WebCore/bindings/v8/V8Binding.h new file mode 100644 index 0000000..9fce3f2 --- /dev/null +++ b/WebCore/bindings/v8/V8Binding.h @@ -0,0 +1,81 @@ +/* +* 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 V8Binding_h +#define V8Binding_h + +// FIXME: This is a temporary forwarding header until all bindings have migrated +// over and v8_binding actually becomes V8Binding. +#include "v8_binding.h" + +namespace WebCore { + + // FIXME: Remove once migration is complete. + inline int toInt32(v8::Handle<v8::Value> value) + { + return ToInt32(value); + } + + inline float toFloat(v8::Local<v8::Value> value) + { + return static_cast<float>(value->NumberValue()); + } + + // FIXME: Remove once migration is complete. + inline String toWebCoreString(v8::Handle<v8::Value> obj) + { + return ToWebCoreString(obj); + } + + // FIXME: Remove once migration is complete. + inline const uint16_t* fromWebCoreString(const String& str) + { + return FromWebCoreString(str); + } + + // FIXME: Rename valueToStringWithNullCheck once migration is complete. + inline String toWebCoreStringWithNullCheck(v8::Handle<v8::Value> value) + { + return valueToStringWithNullCheck(value); + } + + inline bool isUndefinedOrNull(v8::Handle<v8::Value> value) + { + return value->IsNull() || value->IsUndefined(); + } + + inline v8::Handle<v8::Boolean> v8Boolean(bool value) + { + return value ? v8::True() : v8::False(); + } + +} + +#endif // V8Binding_h diff --git a/WebCore/bindings/v8/V8Collection.h b/WebCore/bindings/v8/V8Collection.h new file mode 100644 index 0000000..247c108 --- /dev/null +++ b/WebCore/bindings/v8/V8Collection.h @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2006, 2007, 2008, 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 V8Collection_h +#define V8Collection_h + +#include "V8Binding.h" +#include "V8Proxy.h" +#include <v8.h> + +namespace WebCore { + // FIXME: These functions should be named using to* since they return the item (get* is used for method that take a ref param). + // See https://bugs.webkit.org/show_bug.cgi?id=24664. + + static v8::Handle<v8::Value> getV8Object(void* implementation, v8::Local<v8::Value> implementationType) + { + if (!implementation) + return v8::Handle<v8::Value>(); + V8ClassIndex::V8WrapperType type = V8ClassIndex::FromInt(implementationType->Int32Value()); + if (type == V8ClassIndex::NODE) + return V8Proxy::NodeToV8Object(static_cast<Node*>(implementation)); + return V8Proxy::ToV8Object(type, implementation); + } + + template<class T> static v8::Handle<v8::Value> getV8Object(PassRefPtr<T> implementation, v8::Local<v8::Value> implementationType) + { + return getV8Object(implementation.get(), implementationType); + } + + // Returns named property of a collection. + template<class Collection, class ItemType> static v8::Handle<v8::Value> getNamedPropertyOfCollection(v8::Local<v8::String> name, v8::Local<v8::Object> object, + v8::Local<v8::Value> implementationType) + { + // FIXME: assert object is a collection type + ASSERT(V8Proxy::MaybeDOMWrapper(object)); + V8ClassIndex::V8WrapperType wrapperType = V8Proxy::GetDOMWrapperType(object); + ASSERT(wrapperType != V8ClassIndex::NODE); + Collection* collection = V8Proxy::ToNativeObject<Collection>(wrapperType, object); + String propertyName = toWebCoreString(name); + return getV8Object<ItemType>(collection->namedItem(propertyName), implementationType); + } + + // A template of named property accessor of collections. + template<class Collection, class ItemType> static v8::Handle<v8::Value> collectionNamedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) + { + return getNamedPropertyOfCollection<Collection, ItemType>(name, info.Holder(), info.Data()); + } + + // A template of named property accessor of HTMLSelectElement and HTMLFormElement. + template<class Collection> static v8::Handle<v8::Value> nodeCollectionNamedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) + { + ASSERT(V8Proxy::MaybeDOMWrapper(info.Holder())); + ASSERT(V8Proxy::GetDOMWrapperType(info.Holder()) == V8ClassIndex::NODE); + Collection* collection = V8Proxy::DOMWrapperToNode<Collection>(info.Holder()); + String propertyName = toWebCoreString(name); + void* implementation = collection->namedItem(propertyName); + return getV8Object(implementation, info.Data()); + } + + // Returns the property at the index of a collection. + template<class Collection, class ItemType> static v8::Handle<v8::Value> getIndexedPropertyOfCollection(uint32_t index, v8::Local<v8::Object> object, + v8::Local<v8::Value> implementationType) + { + // FIXME: Assert that object must be a collection type. + ASSERT(V8Proxy::MaybeDOMWrapper(object)); + V8ClassIndex::V8WrapperType wrapperType = V8Proxy::GetDOMWrapperType(object); + ASSERT(wrapperType != V8ClassIndex::NODE); + Collection* collection = V8Proxy::ToNativeObject<Collection>(wrapperType, object); + return getV8Object<ItemType>(collection->item(index), implementationType); + } + + // A template of index interceptor of collections. + template<class Collection, class ItemType> static v8::Handle<v8::Value> collectionIndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info) + { + return getIndexedPropertyOfCollection<Collection, ItemType>(index, info.Holder(), info.Data()); + } + + // A template of index interceptor of HTMLSelectElement and HTMLFormElement. + template<class Collection> static v8::Handle<v8::Value> nodeCollectionIndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info) + { + ASSERT(V8Proxy::MaybeDOMWrapper(info.Holder())); + ASSERT(V8Proxy::GetDOMWrapperType(info.Holder()) == V8ClassIndex::NODE); + Collection* collection = V8Proxy::DOMWrapperToNode<Collection>(info.Holder()); + void* implementation = collection->item(index); + return getV8Object(implementation, info.Data()); + } + + // Get an array containing the names of indexed properties of HTMLSelectElement and HTMLFormElement. + template<class Collection> static v8::Handle<v8::Array> nodeCollectionIndexedPropertyEnumerator(const v8::AccessorInfo& info) + { + ASSERT(V8Proxy::MaybeDOMWrapper(info.Holder())); + ASSERT(V8Proxy::GetDOMWrapperType(info.Holder()) == V8ClassIndex::NODE); + Collection* collection = V8Proxy::DOMWrapperToNode<Collection>(info.Holder()); + int length = collection->length(); + v8::Handle<v8::Array> properties = v8::Array::New(length); + for (int i = 0; i < length; ++i) { + // FIXME: Do we need to check that the item function returns a non-null value for this index? + v8::Handle<v8::Integer> integer = v8::Integer::New(i); + properties->Set(integer, integer); + } + return properties; + } + + // Get an array containing the names of indexed properties in a collection. + template<class Collection> static v8::Handle<v8::Array> collectionIndexedPropertyEnumerator(const v8::AccessorInfo& info) + { + ASSERT(V8Proxy::MaybeDOMWrapper(info.Holder())); + V8ClassIndex::V8WrapperType wrapperType = V8Proxy::GetDOMWrapperType(info.Holder()); + Collection* collection = V8Proxy::ToNativeObject<Collection>(wrapperType, info.Holder()); + int length = collection->length(); + v8::Handle<v8::Array> properties = v8::Array::New(length); + for (int i = 0; i < length; ++i) { + // FIXME: Do we need to check that the item function returns a non-null value for this index? + v8::Handle<v8::Integer> integer = v8::Integer::New(i); + properties->Set(integer, integer); + } + return properties; + } + + + // A template for indexed getters on collections of strings that should return null if the resulting string is a null string. + template<class Collection> static v8::Handle<v8::Value> collectionStringOrNullIndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info) + { + // FIXME: assert that object must be a collection type + ASSERT(V8Proxy::MaybeDOMWrapper(info.Holder())); + V8ClassIndex::V8WrapperType wrapperType = V8Proxy::GetDOMWrapperType(info.Holder()); + Collection* collection = V8Proxy::ToNativeObject<Collection>(wrapperType, info.Holder()); + String result = collection->item(index); + return v8StringOrNull(result); + } + + + // Add indexed getter to the function template for a collection. + template<class Collection, class ItemType> static void setCollectionIndexedGetter(v8::Handle<v8::FunctionTemplate> desc, V8ClassIndex::V8WrapperType type) + { + desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionIndexedPropertyGetter<Collection, ItemType>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>, + v8::Integer::New(V8ClassIndex::ToInt(type))); + } + + + // Add named getter to the function template for a collection. + template<class Collection, class ItemType> static void setCollectionNamedGetter(v8::Handle<v8::FunctionTemplate> desc, V8ClassIndex::V8WrapperType type) + { + desc->InstanceTemplate()->SetNamedPropertyHandler(collectionNamedPropertyGetter<Collection, ItemType>, 0, 0, 0, 0, v8::Integer::New(V8ClassIndex::ToInt(type))); + } + + + // Add named and indexed getters to the function template for a collection. + template<class Collection, class ItemType> static void setCollectionIndexedAndNamedGetters(v8::Handle<v8::FunctionTemplate> desc, V8ClassIndex::V8WrapperType type) + { + // If we interceptor before object, accessing 'length' can trigger a webkit assertion error (see fast/dom/HTMLDocument/document-special-properties.html). + desc->InstanceTemplate()->SetNamedPropertyHandler(collectionNamedPropertyGetter<Collection, ItemType>, 0, 0, 0, 0, v8::Integer::New(V8ClassIndex::ToInt(type))); + desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionIndexedPropertyGetter<Collection, ItemType>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>, + v8::Integer::New(V8ClassIndex::ToInt(type))); + } + + + // Add indexed getter returning a string or null to a function template for a collection. + template<class Collection> static void setCollectionStringOrNullIndexedGetter(v8::Handle<v8::FunctionTemplate> desc) + { + desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionStringOrNullIndexedPropertyGetter<Collection>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>); + } + +} // namespace WebCore + +#endif // V8Collection_h diff --git a/WebCore/bindings/v8/V8Index.h b/WebCore/bindings/v8/V8Index.h new file mode 100644 index 0000000..58af42e --- /dev/null +++ b/WebCore/bindings/v8/V8Index.h @@ -0,0 +1,38 @@ +/* + * 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 V8Index_h +#define V8Index_h + +// FIXME: This is a temporary forwarding header until all bindings have migrated +// over and v8_index actually becomes V8Index. +#include "v8_index.h" + +#endif // V8Index_h diff --git a/WebCore/bindings/v8/V8LazyEventListener.cpp b/WebCore/bindings/v8/V8LazyEventListener.cpp new file mode 100644 index 0000000..f53370d --- /dev/null +++ b/WebCore/bindings/v8/V8LazyEventListener.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2006, 2007, 2008, 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 "V8LazyEventListener.h" + +#include "Frame.h" +#include "V8Binding.h" +#include "V8Proxy.h" + +namespace WebCore { + +V8LazyEventListener::V8LazyEventListener(Frame *frame, const String& code, const String& functionName) + : V8AbstractEventListener(frame, true) + , m_code(code) + , m_functionName(functionName) + , m_compiled(false) + , m_wrappedFunctionCompiled(false) +{ +} + +V8LazyEventListener::~V8LazyEventListener() +{ + disposeListenerObject(); + + // Dispose wrapped function + if (!m_wrappedFunction.IsEmpty()) { +#ifndef NDEBUG + V8Proxy::UnregisterGlobalHandle(this, m_wrappedFunction); +#endif + m_wrappedFunction.Dispose(); + m_wrappedFunction.Clear(); + } +} + +v8::Local<v8::Function> V8LazyEventListener::getListenerFunction() +{ + if (m_compiled) { + ASSERT(m_listener.IsEmpty() || m_listener->IsFunction()); + return m_listener.IsEmpty() ? v8::Local<v8::Function>() : v8::Local<v8::Function>::New(v8::Persistent<v8::Function>::Cast(m_listener)); + } + + m_compiled = true; + + ASSERT(m_frame); + + { + // Switch to the context of m_frame. + v8::HandleScope handleScope; + + // Use the outer scope to hold context. + v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame); + // Bail out if we could not get the context. + if (context.IsEmpty()) + return v8::Local<v8::Function>(); + + v8::Context::Scope scope(context); + + // Wrap function around the event code. The parenthesis around the function are needed so that evaluating the code yields + // the function value. Without the parenthesis the function value is thrown away. + + // Make it an anonymous function to avoid name conflict for cases like + // <body onload='onload()'> + // <script> function onload() { alert('hi'); } </script>. + // Set function name to function object instead. + // See issue 944690. + // + // The ECMAScript spec says (very obliquely) that the parameter to an event handler is named "evt". + String code = "(function (evt) {\n"; + code.append(m_code); + code.append("\n})"); + + v8::Handle<v8::String> codeExternalString = v8ExternalString(code); + v8::Handle<v8::Script> script = V8Proxy::CompileScript(codeExternalString, m_frame->document()->url(), m_lineNumber - 1); + if (!script.IsEmpty()) { + V8Proxy* proxy = V8Proxy::retrieve(m_frame); + ASSERT(proxy); + v8::Local<v8::Value> value = proxy->RunScript(script, false); + if (!value.IsEmpty()) { + ASSERT(value->IsFunction()); + v8::Local<v8::Function> listenerFunction = v8::Local<v8::Function>::Cast(value); + listenerFunction->SetName(v8::String::New(FromWebCoreString(m_functionName), m_functionName.length())); + + m_listener = v8::Persistent<v8::Function>::New(listenerFunction); +#ifndef NDEBUG + V8Proxy::RegisterGlobalHandle(EVENT_LISTENER, this, m_listener); +#endif + } + } + } + + ASSERT(m_listener.IsEmpty() || m_listener->IsFunction()); + return m_listener.IsEmpty() ? v8::Local<v8::Function>() : v8::Local<v8::Function>::New(v8::Persistent<v8::Function>::Cast(m_listener)); +} + +v8::Local<v8::Value> V8LazyEventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event, bool isWindowEvent) +{ + v8::Local<v8::Function> handlerFunction = getWrappedListenerFunction(); + v8::Local<v8::Object> receiver = getReceiverObject(event, isWindowEvent); + if (handlerFunction.IsEmpty() || receiver.IsEmpty()) + return v8::Local<v8::Value>(); + + v8::Handle<v8::Value> parameters[1] = { jsEvent }; + + V8Proxy* proxy = V8Proxy::retrieve(m_frame); + return proxy->CallFunction(handlerFunction, receiver, 1, parameters); +} + +v8::Local<v8::Function> V8LazyEventListener::getWrappedListenerFunction() +{ + if (m_wrappedFunctionCompiled) { + ASSERT(m_wrappedFunction.IsEmpty() || m_wrappedFunction->IsFunction()); + return m_wrappedFunction.IsEmpty() ? v8::Local<v8::Function>() : v8::Local<v8::Function>::New(m_wrappedFunction); + } + + m_wrappedFunctionCompiled = true; + + { + // Switch to the context of m_frame. + v8::HandleScope handleScope; + + // Use the outer scope to hold context. + v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame); + // Bail out if we cannot get the context. + if (context.IsEmpty()) + return v8::Local<v8::Function>(); + + v8::Context::Scope scope(context); + + // FIXME: cache the wrapper function. + + // Nodes other than the document object, when executing inline event handlers push document, form, and the target node on the scope chain. + // We do this by using 'with' statement. + // See chrome/fast/forms/form-action.html + // chrome/fast/forms/selected-index-value.html + // base/fast/overflow/onscroll-layer-self-destruct.html + String code = "(function (evt) {\n" \ + " with (this.ownerDocument ? this.ownerDocument : {}) {\n" \ + " with (this.form ? this.form : {}) {\n" \ + " with (this) {\n" \ + " return (function(evt){\n"; + code.append(m_code); + code.append( "\n" \ + "}).call(this, evt);\n" \ + " }\n" \ + " }\n" \ + " }\n" \ + "})"); + v8::Handle<v8::String> codeExternalString = v8ExternalString(code); + v8::Handle<v8::Script> script = V8Proxy::CompileScript(codeExternalString, m_frame->document()->url(), m_lineNumber - 4); + if (!script.IsEmpty()) { + V8Proxy* proxy = V8Proxy::retrieve(m_frame); + ASSERT(proxy); + v8::Local<v8::Value> value = proxy->RunScript(script, false); + if (!value.IsEmpty()) { + ASSERT(value->IsFunction()); + + m_wrappedFunction = v8::Persistent<v8::Function>::New(v8::Local<v8::Function>::Cast(value)); +#ifndef NDEBUG + V8Proxy::RegisterGlobalHandle(EVENT_LISTENER, this, m_wrappedFunction); +#endif + m_wrappedFunction->SetName(v8::String::New(fromWebCoreString(m_functionName), m_functionName.length())); + } + } + } + + return v8::Local<v8::Function>::New(m_wrappedFunction); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/V8LazyEventListener.h b/WebCore/bindings/v8/V8LazyEventListener.h new file mode 100644 index 0000000..7c7be34 --- /dev/null +++ b/WebCore/bindings/v8/V8LazyEventListener.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2006, 2007, 2008, 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 V8LazyEventListener_h +#define V8LazyEventListener_h + +#include "PlatformString.h" +#include "V8AbstractEventListener.h" +#include <v8.h> +#include <wtf/PassRefPtr.h> + +namespace WebCore { + + class Event; + class Frame; + + // V8LazyEventListener is a wrapper for a JavaScript code string that is compiled and evaluated when an event is fired. + // A V8LazyEventListener is always a HTML event handler. + class V8LazyEventListener : public V8AbstractEventListener { + public: + static PassRefPtr<V8LazyEventListener> create(Frame* frame, const String& code, const String& functionName) + { + return adoptRef(new V8LazyEventListener(frame, code, functionName)); + } + + virtual bool isInline() const { return true; } + + // For lazy event listener, the listener object is the same as its listener + // function without additional scope chains. + virtual v8::Local<v8::Object> getListenerObject() { return getWrappedListenerFunction(); } + + private: + V8LazyEventListener(Frame*, const String& code, const String& functionName); + virtual ~V8LazyEventListener(); + + String m_code; + String m_functionName; + bool m_compiled; + + // If the event listener is on a non-document dom node, we compile the function with some implicit scope chains before it. + bool m_wrappedFunctionCompiled; + v8::Persistent<v8::Function> m_wrappedFunction; + + v8::Local<v8::Function> getWrappedListenerFunction(); + + virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*, bool isWindowEvent); + + v8::Local<v8::Function> getListenerFunction(); + }; + +} // namespace WebCore + +#endif // V8LazyEventListener_h diff --git a/WebCore/bindings/v8/V8NodeFilterCondition.cpp b/WebCore/bindings/v8/V8NodeFilterCondition.cpp new file mode 100644 index 0000000..b5ae30c --- /dev/null +++ b/WebCore/bindings/v8/V8NodeFilterCondition.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2008, 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 "V8NodeFilterCondition.h" + +#include "Node.h" +#include "NodeFilter.h" +#include "ScriptState.h" +#include "V8Proxy.h" + +#include <wtf/OwnArrayPtr.h> + +namespace WebCore { + +V8NodeFilterCondition::V8NodeFilterCondition(v8::Handle<v8::Value> filter) + : m_filter(v8::Persistent<v8::Value>::New(filter)) +{ +#ifndef NDEBUG + V8Proxy::RegisterGlobalHandle(NODE_FILTER, this, m_filter); +#endif +} + +V8NodeFilterCondition::~V8NodeFilterCondition() +{ +#ifndef NDEBUG + V8Proxy::UnregisterGlobalHandle(this, m_filter); +#endif + m_filter.Dispose(); + m_filter.Clear(); +} + +short V8NodeFilterCondition::acceptNode(ScriptState* state, Node* node) const +{ + ASSERT(v8::Context::InContext()); + + if (!m_filter->IsFunction()) + return NodeFilter::FILTER_ACCEPT; + + v8::TryCatch exceptionCatcher; + + v8::Handle<v8::Object> object = v8::Context::GetCurrent()->Global(); + v8::Handle<v8::Function> callback = v8::Handle<v8::Function>::Cast(m_filter); + OwnArrayPtr<v8::Handle<v8::Value> > args(new v8::Handle<v8::Value>[1]); + args[0] = V8Proxy::ToV8Object(V8ClassIndex::NODE, node); + + V8Proxy* proxy = V8Proxy::retrieve(); + ASSERT(proxy); + + v8::Handle<v8::Value> result = proxy->CallFunction(callback, object, 1, args.get()); + + if (exceptionCatcher.HasCaught()) { + state->setException(exceptionCatcher.Exception()); + return NodeFilter::FILTER_REJECT; + } + + ASSERT(!result.IsEmpty()); + + return result->Int32Value(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/V8NodeFilterCondition.h b/WebCore/bindings/v8/V8NodeFilterCondition.h new file mode 100644 index 0000000..5850b69 --- /dev/null +++ b/WebCore/bindings/v8/V8NodeFilterCondition.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2006, 2007, 2008, 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 V8NodeFilterCondition_h +#define V8NodeFilterCondition_h + +#include "NodeFilterCondition.h" +#include <v8.h> + +// NodeFilter is a JavaScript function that takes a Node as parameter and returns a short (ACCEPT, SKIP, REJECT) as the result. +namespace WebCore { + + class Node; + class ScriptState; + + // NodeFilterCondition is a wrapper around a NodeFilter JS function. + class V8NodeFilterCondition : public NodeFilterCondition { + public: + explicit V8NodeFilterCondition(v8::Handle<v8::Value> filter); + virtual ~V8NodeFilterCondition(); + + virtual short acceptNode(ScriptState*, Node*) const; + + private: + mutable v8::Persistent<v8::Value> m_filter; + }; + +} // namespace WebCore + +#endif // V8NodeFilterCondition_h diff --git a/WebCore/bindings/v8/V8ObjectEventListener.cpp b/WebCore/bindings/v8/V8ObjectEventListener.cpp new file mode 100644 index 0000000..584962a --- /dev/null +++ b/WebCore/bindings/v8/V8ObjectEventListener.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2006, 2007, 2008, 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 "V8ObjectEventListener.h" + +#include "Frame.h" +#include "V8Proxy.h" + +namespace WebCore { + +static void weakObjectEventListenerCallback(v8::Persistent<v8::Value>, void* parameter) +{ + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(parameter); + + // Remove the wrapper + Frame* frame = listener->frame(); + if (frame) { + V8Proxy* proxy = V8Proxy::retrieve(frame); + if (proxy) + proxy->RemoveObjectEventListener(listener); + + // Because the listener is no longer in the list, it must be disconnected from the frame to avoid dangling frame pointer + // in the destructor. + listener->disconnectFrame(); + } + listener->disposeListenerObject(); +} + +V8ObjectEventListener::V8ObjectEventListener(Frame* frame, v8::Local<v8::Object> listener, bool isInline) + : V8EventListener(frame, listener, isInline) +{ + m_listener.MakeWeak(this, weakObjectEventListenerCallback); +} + +V8ObjectEventListener::~V8ObjectEventListener() +{ + if (m_frame) { + ASSERT(!m_listener.IsEmpty()); + V8Proxy* proxy = V8Proxy::retrieve(m_frame); + if (proxy) + proxy->RemoveObjectEventListener(this); + } + + disposeListenerObject(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/V8ObjectEventListener.h b/WebCore/bindings/v8/V8ObjectEventListener.h new file mode 100644 index 0000000..730b96c --- /dev/null +++ b/WebCore/bindings/v8/V8ObjectEventListener.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2006, 2007, 2008, 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 V8ObjectEventListener_h +#define V8ObjectEventListener_h + +#include "V8CustomEventListener.h" +#include <v8.h> +#include <wtf/PassRefPtr.h> + +namespace WebCore { + + class Frame; + + // V8ObjectEventListener is a special listener wrapper for objects not in the DOM. It keeps the JS listener as a weak pointer. + class V8ObjectEventListener : public V8EventListener { + public: + static PassRefPtr<V8ObjectEventListener> create(Frame* frame, v8::Local<v8::Object> listener, bool isInline) + { + return adoptRef(new V8ObjectEventListener(frame, listener, isInline)); + } + + protected: + V8ObjectEventListener(Frame*, v8::Local<v8::Object> listener, bool isInline); + virtual ~V8ObjectEventListener(); + }; + +} // namespace WebCore + +#endif // V8ObjectEventListener_h diff --git a/WebCore/bindings/v8/V8Proxy.h b/WebCore/bindings/v8/V8Proxy.h new file mode 100644 index 0000000..c21e0dd --- /dev/null +++ b/WebCore/bindings/v8/V8Proxy.h @@ -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. + */ + +#ifndef V8Proxy_h +#define V8Proxy_h + +// FIXME: This is a temporary forwarding header until all bindings have migrated +// over and v8_proxy actually becomes V8Proxy. +#include "v8_proxy.h" + +namespace WebCore { + + // Used by an interceptor callback that it hasn't found anything to + // intercept. + inline static v8::Local<v8::Object> notHandledByInterceptor() + { + return v8::Local<v8::Object>(); + } + + inline static v8::Local<v8::Boolean> deletionNotHandledByInterceptor() + { + return v8::Local<v8::Boolean>(); + } + + // FIXME: Remove once migration is complete. + inline static DOMWrapperMap<void>& domObjectMap() + { + return GetDOMObjectMap(); + } + + inline v8::Handle<v8::Primitive> throwError(const char* message, V8Proxy::ErrorType type = V8Proxy::TYPE_ERROR) + { + V8Proxy::ThrowError(type, message); + return v8::Undefined(); + } + + inline v8::Handle<v8::Primitive> throwError(ExceptionCode ec) + { + V8Proxy::SetDOMException(ec); + return v8::Undefined(); + } + + inline v8::Handle<v8::Primitive> throwError(v8::Local<v8::Value> exception) + { + v8::ThrowException(exception); + return v8::Undefined(); + } + + template <class T> inline v8::Handle<v8::Object> toV8(PassRefPtr<T> object, v8::Local<v8::Object> holder) + { + object->ref(); + V8Proxy::SetJSWrapperForDOMObject(object.get(), v8::Persistent<v8::Object>::New(holder)); + return holder; + } + +} + +#endif // V8Proxy_h diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp new file mode 100644 index 0000000..ba7a2c0 --- /dev/null +++ b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2006, 2007, 2008, 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" + +#if ENABLE(WORKERS) + +#include "V8WorkerContextEventListener.h" + +#include "Event.h" +#include "WorkerContextExecutionProxy.h" + +namespace WebCore { + +V8WorkerContextEventListener::V8WorkerContextEventListener(WorkerContextExecutionProxy* proxy, v8::Local<v8::Object> listener, bool isInline) + : V8ObjectEventListener(0, listener, isInline) + , m_proxy(proxy) +{ +} + +V8WorkerContextEventListener::~V8WorkerContextEventListener() +{ + if (m_proxy) + m_proxy->RemoveEventListener(this); + disposeListenerObject(); +} + +void V8WorkerContextEventListener::handleEvent(Event* event, bool isWindowEvent) +{ + // Is the EventListener disconnected from the frame? + if (disconnected()) + return; + + // The callback function on XMLHttpRequest can clear the event listener and destroys 'this' object. Keep a local reference to it. + // See issue 889829. + RefPtr<V8AbstractEventListener> protect(this); + + v8::Locker locker; + v8::HandleScope handleScope; + + v8::Handle<v8::Context> context = m_proxy->GetContext(); + if (context.IsEmpty()) + return; + + // Enter the V8 context in which to perform the event handling. + v8::Context::Scope scope(context); + + // Get the V8 wrapper for the event object. + v8::Handle<v8::Value> jsEvent = WorkerContextExecutionProxy::EventToV8Object(event); + + invokeEventHandler(context, event, jsEvent, isWindowEvent); +} + +v8::Local<v8::Value> V8WorkerContextEventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event, bool isWindowEvent) +{ + v8::Local<v8::Function> handlerFunction = getListenerFunction(); + if (handlerFunction.IsEmpty()) + return v8::Local<v8::Value>(); + + v8::Local<v8::Object> receiver = getReceiverObject(event, isWindowEvent); + v8::Handle<v8::Value> parameters[1] = { jsEvent }; + v8::Local<v8::Value> result = handlerFunction->Call(receiver, 1, parameters); + + m_proxy->trackEvent(event); + + return result; +} + +v8::Local<v8::Object> V8WorkerContextEventListener::getReceiverObject(Event* event, bool isWindowEvent) +{ + if (!m_listener.IsEmpty() && !m_listener->IsFunction()) + return v8::Local<v8::Object>::New(m_listener); + + if (isWindowEvent) + return v8::Context::GetCurrent()->Global(); + + EventTarget* target = event->currentTarget(); + v8::Handle<v8::Value> value = WorkerContextExecutionProxy::EventTargetToV8Object(target); + if (value.IsEmpty()) + return v8::Local<v8::Object>(); + return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value)); +} + +} // namespace WebCore + +#endif // WORKERS diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.h b/WebCore/bindings/v8/V8WorkerContextEventListener.h new file mode 100644 index 0000000..85dae41 --- /dev/null +++ b/WebCore/bindings/v8/V8WorkerContextEventListener.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2006, 2007, 2008, 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 V8WorkerContextEventListener_h +#define V8WorkerContextEventListener_h + +#if ENABLE(WORKERS) + +#include "V8ObjectEventListener.h" +#include <v8.h> +#include <wtf/PassRefPtr.h> + +namespace WebCore { + + class Event; + class WorkerContextExecutionProxy; + + class V8WorkerContextEventListener : public V8ObjectEventListener { + public: + static PassRefPtr<V8WorkerContextEventListener> create(WorkerContextExecutionProxy* proxy, v8::Local<v8::Object> listener, bool isInline) + { + return adoptRef(new V8WorkerContextEventListener(proxy, listener, isInline)); + } + V8WorkerContextEventListener(WorkerContextExecutionProxy*, v8::Local<v8::Object> listener, bool isInline); + + virtual ~V8WorkerContextEventListener(); + virtual void handleEvent(Event*, bool isWindowEvent); + virtual bool disconnected() const { return !m_proxy; } + + void disconnect() { m_proxy = 0; } + + private: + virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*, bool isWindowEvent); + v8::Local<v8::Object> getReceiverObject(Event*, bool isWindowEvent); + WorkerContextExecutionProxy* m_proxy; + }; + +} // namespace WebCore + +#endif // WORKERS + +#endif // V8WorkerContextEventListener_h diff --git a/WebCore/bindings/v8/V8XMLHttpRequestUtilities.cpp b/WebCore/bindings/v8/V8XMLHttpRequestUtilities.cpp new file mode 100644 index 0000000..dfd5e45 --- /dev/null +++ b/WebCore/bindings/v8/V8XMLHttpRequestUtilities.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2008, 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 "V8XMLHttpRequestUtilities.h" + +#include <v8.h> + +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +#include <wtf/Assertions.h> + +namespace WebCore { + +// Use an array to hold dependents. It works like a ref-counted scheme. +// A value can be added more than once to the xmlHttpRequest object. +void createHiddenXHRDependency(v8::Local<v8::Object> xmlHttpRequest, v8::Local<v8::Value> value) +{ + ASSERT(V8Proxy::GetDOMWrapperType(xmlHttpRequest) == V8ClassIndex::XMLHTTPREQUEST || V8Proxy::GetDOMWrapperType(xmlHttpRequest) == V8ClassIndex::XMLHTTPREQUESTUPLOAD); + v8::Local<v8::Value> cache = xmlHttpRequest->GetInternalField(V8Custom::kXMLHttpRequestCacheIndex); + if (cache->IsNull() || cache->IsUndefined()) { + cache = v8::Array::New(); + xmlHttpRequest->SetInternalField(V8Custom::kXMLHttpRequestCacheIndex, cache); + } + + v8::Local<v8::Array> cacheArray = v8::Local<v8::Array>::Cast(cache); + cacheArray->Set(v8::Integer::New(cacheArray->Length()), value); +} + +void removeHiddenXHRDependency(v8::Local<v8::Object> xmlHttpRequest, v8::Local<v8::Value> value) +{ + ASSERT(V8Proxy::GetDOMWrapperType(xmlHttpRequest) == V8ClassIndex::XMLHTTPREQUEST || V8Proxy::GetDOMWrapperType(xmlHttpRequest) == V8ClassIndex::XMLHTTPREQUESTUPLOAD); + v8::Local<v8::Value> cache = xmlHttpRequest->GetInternalField(V8Custom::kXMLHttpRequestCacheIndex); + ASSERT(cache->IsArray()); + v8::Local<v8::Array> cacheArray = v8::Local<v8::Array>::Cast(cache); + for (int i = cacheArray->Length() - 1; i >= 0; --i) { + v8::Local<v8::Value> cached = cacheArray->Get(v8::Integer::New(i)); + if (cached->StrictEquals(value)) { + cacheArray->Delete(i); + return; + } + } + + // We should only get here if we try to remove an event listener that was never added. + ASSERT_NOT_REACHED(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/V8XMLHttpRequestUtilities.h b/WebCore/bindings/v8/V8XMLHttpRequestUtilities.h new file mode 100644 index 0000000..5a55974 --- /dev/null +++ b/WebCore/bindings/v8/V8XMLHttpRequestUtilities.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2008, 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 V8XMLHttpRequestUtilities_h +#define V8XMLHttpRequestUtilities_h + +#include <v8.h> + +namespace WebCore { + +// Use an array to hold dependents. It works like a ref-counted scheme. +// A value can be added more than once to the xmlHttpRequest object. +void createHiddenXHRDependency(v8::Local<v8::Object> xmlHttpRequest, v8::Local<v8::Value>); +void removeHiddenXHRDependency(v8::Local<v8::Object> xmlHttpRequest, v8::Local<v8::Value>); + +} // namespace WebCore + +#endif // V8XMLHttpRequestUtilities_h diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp new file mode 100644 index 0000000..a46aa24 --- /dev/null +++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp @@ -0,0 +1,359 @@ +/* + * 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" + +#if ENABLE(WORKERS) + +#include "WorkerContextExecutionProxy.h" + +#include "V8Binding.h" +#include "V8Proxy.h" +#include "Event.h" +#include "V8WorkerContextEventListener.h" +#include "WorkerContext.h" +#include "WorkerLocation.h" +#include "WorkerNavigator.h" +#include "WorkerScriptController.h" + +namespace WebCore { + +static bool isWorkersEnabled = false; + +bool WorkerContextExecutionProxy::isWebWorkersEnabled() +{ + return isWorkersEnabled; +} + +void WorkerContextExecutionProxy::setIsWebWorkersEnabled(bool value) +{ + isWorkersEnabled = value; +} + +WorkerContextExecutionProxy::WorkerContextExecutionProxy(WorkerContext* workerContext) + : m_workerContext(workerContext) + , m_recursion(0) +{ +} + +WorkerContextExecutionProxy::~WorkerContextExecutionProxy() +{ + dispose(); +} + +void WorkerContextExecutionProxy::dispose() +{ + // Disconnect all event listeners. + for (size_t listenerIndex = 0; listenerIndex < m_listeners.size(); ++listenerIndex) + m_listeners[listenerIndex]->disconnect(); + + m_listeners.clear(); + + // Detach all events from their JS wrappers. + for (size_t eventIndex = 0; eventIndex < m_events.size(); ++eventIndex) { + Event* event = m_events[eventIndex]; + if (forgetV8EventObject(event)) + event->deref(); + } + m_events.clear(); + + // Dispose the context. + if (!m_context.IsEmpty()) { + m_context.Dispose(); + m_context.Clear(); + } + + // Remove the wrapping between JS object and DOM object. This is because + // the worker context object is going to be disposed immediately when a + // worker thread is tearing down. We do not want to re-delete the real object + // when JS object is garbage collected. + v8::Locker locker; + v8::HandleScope scope; + v8::Persistent<v8::Object> wrapper = domObjectMap().get(m_workerContext); + if (!wrapper.IsEmpty()) + V8Proxy::SetDOMWrapper(wrapper, V8ClassIndex::INVALID_CLASS_INDEX, NULL); + domObjectMap().forget(m_workerContext); +} + +WorkerContextExecutionProxy* WorkerContextExecutionProxy::retrieve() +{ + v8::Handle<v8::Context> context = v8::Context::GetCurrent(); + v8::Handle<v8::Object> global = context->Global(); + global = V8Proxy::LookupDOMWrapper(V8ClassIndex::WORKERCONTEXT, global); + ASSERT(!global.IsEmpty()); + WorkerContext* workerContext = V8Proxy::ToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, global); + return workerContext->script()->proxy(); +} + +void WorkerContextExecutionProxy::initContextIfNeeded() +{ + // Bail out if the context has already been initialized. + if (!m_context.IsEmpty()) + return; + + // Create a new environment + v8::Persistent<v8::ObjectTemplate> globalTemplate; + m_context = v8::Context::New(NULL, globalTemplate); + + // Starting from now, use local context only. + v8::Local<v8::Context> context = v8::Local<v8::Context>::New(m_context); + v8::Context::Scope scope(context); + + // Allocate strings used during initialization. + v8::Handle<v8::String> implicitProtoString = v8::String::New("__proto__"); + + // Create a new JS object and use it as the prototype for the shadow global object. + v8::Handle<v8::Function> workerContextConstructor = GetConstructor(V8ClassIndex::WORKERCONTEXT); + v8::Local<v8::Object> jsWorkerContext = SafeAllocation::NewInstance(workerContextConstructor); + // Bail out if allocation failed. + if (jsWorkerContext.IsEmpty()) { + dispose(); + return; + } + + // Wrap the object. + V8Proxy::SetDOMWrapper(jsWorkerContext, V8ClassIndex::ToInt(V8ClassIndex::WORKERCONTEXT), m_workerContext); + + V8Proxy::SetJSWrapperForDOMObject(m_workerContext, v8::Persistent<v8::Object>::New(jsWorkerContext)); + + // Insert the object instance as the prototype of the shadow object. + v8::Handle<v8::Object> globalObject = m_context->Global(); + globalObject->Set(implicitProtoString, jsWorkerContext); +} + +v8::Local<v8::Function> WorkerContextExecutionProxy::GetConstructor(V8ClassIndex::V8WrapperType type) +{ + // Enter the context of the proxy to make sure that the function is + // constructed in the context corresponding to this proxy. + v8::Context::Scope scope(m_context); + v8::Handle<v8::FunctionTemplate> functionTemplate = V8Proxy::GetTemplate(type); + + // Getting the function might fail if we're running out of stack or memory. + v8::TryCatch tryCatch; + v8::Local<v8::Function> value = functionTemplate->GetFunction(); + if (value.IsEmpty()) + return v8::Local<v8::Function>(); + + return value; +} + +v8::Handle<v8::Value> WorkerContextExecutionProxy::ToV8Object(V8ClassIndex::V8WrapperType type, void* impl) +{ + if (!impl) + return v8::Null(); + + if (type == V8ClassIndex::WORKERCONTEXT) + return WorkerContextToV8Object(static_cast<WorkerContext*>(impl)); + + // Non DOM node + v8::Persistent<v8::Object> result = domObjectMap().get(impl); + if (result.IsEmpty()) { + v8::Local<v8::Object> object = toV8(type, type, impl); + if (!object.IsEmpty()) { + switch (type) { + case V8ClassIndex::WORKERLOCATION: + static_cast<WorkerLocation*>(impl)->ref(); + break; + case V8ClassIndex::WORKERNAVIGATOR: + static_cast<WorkerNavigator*>(impl)->ref(); + break; + default: + ASSERT(false); + } + result = v8::Persistent<v8::Object>::New(object); + V8Proxy::SetJSWrapperForDOMObject(impl, result); + } + } + return result; +} + +v8::Handle<v8::Value> WorkerContextExecutionProxy::EventToV8Object(Event* event) +{ + if (!event) + return v8::Null(); + + v8::Handle<v8::Object> wrapper = domObjectMap().get(event); + if (!wrapper.IsEmpty()) + return wrapper; + + V8ClassIndex::V8WrapperType type = V8ClassIndex::EVENT; + + if (event->isMessageEvent()) + type = V8ClassIndex::MESSAGEEVENT; + + v8::Handle<v8::Object> result = toV8(type, V8ClassIndex::EVENT, event); + if (result.IsEmpty()) { + // Instantiation failed. Avoid updating the DOM object map and return null which + // is already handled by callers of this function in case the event is NULL. + return v8::Null(); + } + + event->ref(); // fast ref + V8Proxy::SetJSWrapperForDOMObject(event, v8::Persistent<v8::Object>::New(result)); + + return result; +} + +// A JS object of type EventTarget in the worker context can only be WorkerContext. +v8::Handle<v8::Value> WorkerContextExecutionProxy::EventTargetToV8Object(EventTarget* target) +{ + if (!target) + return v8::Null(); + + WorkerContext* workerContext = target->toWorkerContext(); + if (workerContext) + return WorkerContextToV8Object(workerContext); + + ASSERT_NOT_REACHED(); + return v8::Handle<v8::Value>(); +} + +v8::Handle<v8::Value> WorkerContextExecutionProxy::WorkerContextToV8Object(WorkerContext* workerContext) +{ + if (!workerContext) + return v8::Null(); + + v8::Handle<v8::Context> context = workerContext->script()->proxy()->GetContext(); + + v8::Handle<v8::Object> global = context->Global(); + ASSERT(!global.IsEmpty()); + return global; +} + +v8::Local<v8::Object> WorkerContextExecutionProxy::toV8(V8ClassIndex::V8WrapperType descType, V8ClassIndex::V8WrapperType cptrType, void* impl) +{ + v8::Local<v8::Function> function; + WorkerContextExecutionProxy* proxy = retrieve(); + if (proxy) + function = proxy->GetConstructor(descType); + else + function = V8Proxy::GetTemplate(descType)->GetFunction(); + + v8::Local<v8::Object> instance = SafeAllocation::NewInstance(function); + if (!instance.IsEmpty()) { + // Avoid setting the DOM wrapper for failed allocations. + V8Proxy::SetDOMWrapper(instance, V8ClassIndex::ToInt(cptrType), impl); + } + return instance; +} + +bool WorkerContextExecutionProxy::forgetV8EventObject(Event* event) +{ + if (domObjectMap().contains(event)) { + domObjectMap().forget(event); + return true; + } else + return false; +} + +v8::Local<v8::Value> WorkerContextExecutionProxy::evaluate(const String& script, const String& fileName, int baseLine) +{ + v8::Locker locker; + v8::HandleScope hs; + + initContextIfNeeded(); + v8::Context::Scope scope(m_context); + + v8::Local<v8::String> scriptString = v8ExternalString(script); + v8::Handle<v8::Script> compiledScript = V8Proxy::CompileScript(scriptString, fileName, baseLine); + return runScript(compiledScript); +} + +v8::Local<v8::Value> WorkerContextExecutionProxy::runScript(v8::Handle<v8::Script> script) +{ + if (script.IsEmpty()) + return v8::Local<v8::Value>(); + + // Compute the source string and prevent against infinite recursion. + if (m_recursion >= kMaxRecursionDepth) { + v8::Local<v8::String> code = v8ExternalString("throw RangeError('Recursion too deep')"); + script = V8Proxy::CompileScript(code, "", 0); + } + + if (V8Proxy::HandleOutOfMemory()) + ASSERT(script.IsEmpty()); + + if (script.IsEmpty()) + return v8::Local<v8::Value>(); + + // Run the script and keep track of the current recursion depth. + v8::Local<v8::Value> result; + { + m_recursion++; + result = script->Run(); + m_recursion--; + } + + // Handle V8 internal error situation (Out-of-memory). + if (result.IsEmpty()) + return v8::Local<v8::Value>(); + + return result; +} + +PassRefPtr<V8EventListener> WorkerContextExecutionProxy::FindOrCreateEventListener(v8::Local<v8::Value> object, bool isInline, bool findOnly) +{ + if (!object->IsObject()) + return 0; + + for (size_t index = 0; index < m_listeners.size(); ++index) { + V8EventListener* el = m_listeners[index]; + if (el->isInline() == isInline && el->getListenerObject() == object) + return el; + } + if (findOnly) + return NULL; + + // Create a new one, and add to cache. + RefPtr<V8WorkerContextEventListener> listener = V8WorkerContextEventListener::create(this, v8::Local<v8::Object>::Cast(object), isInline); + m_listeners.append(listener.get()); + + return listener.release(); +} + +void WorkerContextExecutionProxy::RemoveEventListener(V8EventListener* listener) +{ + for (size_t index = 0; index < m_listeners.size(); ++index) { + if (m_listeners[index] == listener) { + m_listeners.remove(index); + return; + } + } +} + +void WorkerContextExecutionProxy::trackEvent(Event* event) +{ + m_events.append(event); +} + +} // namespace WebCore + +#endif // ENABLE(WORKERS) diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.h b/WebCore/bindings/v8/WorkerContextExecutionProxy.h new file mode 100644 index 0000000..3023666 --- /dev/null +++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.h @@ -0,0 +1,106 @@ +/* + * 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 WorkerContextExecutionProxy_h +#define WorkerContextExecutionProxy_h + +#if ENABLE(WORKERS) + +#include <v8.h> +#include "V8Index.h" +#include <wtf/Vector.h> + +namespace WebCore { + + class Event; + class EventTarget; + class V8EventListener; + class V8WorkerContextEventListener; + class WorkerContext; + + class WorkerContextExecutionProxy { + public: + WorkerContextExecutionProxy(WorkerContext*); + ~WorkerContextExecutionProxy(); + + // FIXME: following function sshould have camelCased names once V8 code-generating script is migrated. + v8::Local<v8::Context> GetContext() { return v8::Local<v8::Context>::New(m_context); } + v8::Local<v8::Function> GetConstructor(V8ClassIndex::V8WrapperType); + PassRefPtr<V8EventListener> FindOrCreateEventListener(v8::Local<v8::Value> listener, bool isInline, bool findOnly); + void RemoveEventListener(V8EventListener*); + + static v8::Handle<v8::Value> ToV8Object(V8ClassIndex::V8WrapperType type, void* impl); + static v8::Handle<v8::Value> EventToV8Object(Event* event); + static v8::Handle<v8::Value> EventTargetToV8Object(EventTarget* target); + static v8::Handle<v8::Value> WorkerContextToV8Object(WorkerContext* wc); + + // Track the event so that we can detach it from the JS wrapper when a worker + // terminates. This is needed because we need to be able to dispose these + // events and releases references to their event targets: WorkerContext. + void trackEvent(Event*); + + // Evaluate a script file in the current execution environment. + v8::Local<v8::Value> evaluate(const String& script, const String& fileName, int baseLine); + + // Returns WorkerContext object. + WorkerContext* workerContext() { return m_workerContext; } + + // Returns WorkerContextExecutionProxy object of the currently executing context. + static WorkerContextExecutionProxy* retrieve(); + + // Enables HTML5 worker support. + static bool isWebWorkersEnabled(); + static void setIsWebWorkersEnabled(bool); + + private: + void initContextIfNeeded(); + void dispose(); + + // Run an already compiled script. + v8::Local<v8::Value> runScript(v8::Handle<v8::Script>); + + static v8::Local<v8::Object> toV8(V8ClassIndex::V8WrapperType descType, V8ClassIndex::V8WrapperType cptrType, void* impl); + + static bool forgetV8EventObject(Event*); + + WorkerContext* m_workerContext; + v8::Persistent<v8::Context> m_context; + int m_recursion; + + Vector<V8WorkerContextEventListener*> m_listeners; + Vector<Event*> m_events; + }; + +} // namespace WebCore + +#endif // ENABLE(WORKERS) + +#endif // WorkerContextExecutionProxy_h diff --git a/WebCore/bindings/v8/WorkerScriptController.cpp b/WebCore/bindings/v8/WorkerScriptController.cpp new file mode 100644 index 0000000..85bee0a --- /dev/null +++ b/WebCore/bindings/v8/WorkerScriptController.cpp @@ -0,0 +1,93 @@ +/* + * 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" + +#if ENABLE(WORKERS) + +#include "WorkerScriptController.h" + +#include <v8.h> + +#include "ScriptSourceCode.h" +#include "ScriptValue.h" +#include "DOMTimer.h" +#include "WorkerContext.h" +#include "WorkerContextExecutionProxy.h" +#include "WorkerObjectProxy.h" +#include "WorkerThread.h" + +namespace WebCore { + +WorkerScriptController::WorkerScriptController(WorkerContext* workerContext) + : m_workerContext(workerContext) + , m_proxy(new WorkerContextExecutionProxy(workerContext)) + , m_executionForbidden(false) +{ +} + +WorkerScriptController::~WorkerScriptController() +{ +} + +ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode) +{ + { + MutexLocker lock(m_sharedDataMutex); + if (m_executionForbidden) + return ScriptValue(); + } + + v8::Local<v8::Value> result = m_proxy->evaluate(sourceCode.source(), sourceCode.url().string(), sourceCode.startLine() - 1); + m_workerContext->thread()->workerObjectProxy()->reportPendingActivity(m_workerContext->hasPendingActivity()); + return ScriptValue(); +} + +ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, ScriptValue* /* exception */) +{ + // FIXME: Need to return an exception. + return evaluate(sourceCode); +} + +void WorkerScriptController::forbidExecution() +{ + // This function is called from another thread. + MutexLocker lock(m_sharedDataMutex); + m_executionForbidden = true; +} + +void WorkerScriptController::setException(ScriptValue /* exception */) +{ + notImplemented(); +} + +} // namespace WebCore + +#endif // ENABLE(WORKERS) diff --git a/WebCore/bindings/v8/WorkerScriptController.h b/WebCore/bindings/v8/WorkerScriptController.h new file mode 100644 index 0000000..07e224c --- /dev/null +++ b/WebCore/bindings/v8/WorkerScriptController.h @@ -0,0 +1,72 @@ +/* + * 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 WorkerScriptController_h +#define WorkerScriptController_h + +#if ENABLE(WORKERS) + +#include <wtf/OwnPtr.h> +#include <wtf/Threading.h> + +namespace WebCore { + + class ScriptSourceCode; + class ScriptValue; + class WorkerContext; + class WorkerContextExecutionProxy; + + class WorkerScriptController { + public: + WorkerScriptController(WorkerContext*); + ~WorkerScriptController(); + + WorkerContextExecutionProxy* proxy() { return m_proxy.get(); } + + ScriptValue evaluate(const ScriptSourceCode&); + ScriptValue evaluate(const ScriptSourceCode&, ScriptValue* exception); + + void setException(ScriptValue); + + void forbidExecution(); + + private: + WorkerContext* m_workerContext; + OwnPtr<WorkerContextExecutionProxy> m_proxy; + + Mutex m_sharedDataMutex; + bool m_executionForbidden; + }; + +} // namespace WebCore + +#endif // ENABLE(WORKERS) + +#endif // WorkerScriptController_h diff --git a/WebCore/bindings/v8/custom/V8AttrCustom.cpp b/WebCore/bindings/v8/custom/V8AttrCustom.cpp new file mode 100644 index 0000000..f34a441 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8AttrCustom.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2007-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 "Attr.h" + +#include "Element.h" +#include "ExceptionCode.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +namespace WebCore { + +ACCESSOR_SETTER(AttrValue) +{ + Attr* imp = V8Proxy::DOMWrapperToNode<Attr>(info.Holder()); + String attrValue = toWebCoreStringWithNullCheck(value); + Element* ownerElement = imp->ownerElement(); + + if (ownerElement && !allowSettingSrcToJavascriptURL(ownerElement, imp->name(), attrValue)) + return; + + ExceptionCode ec = 0; + imp->setValue(attrValue, ec); + if (ec) + throwError(ec); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp b/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp new file mode 100644 index 0000000..c86f924 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2007-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 "CSSStyleDeclaration.h" + +#include "CSSValue.h" +#include "CSSPrimitiveValue.h" +#include "EventTarget.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +#include <wtf/ASCIICType.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { + +// FIXME: Next two functions look lifted verbatim from JSCSSStyleDeclarationCustom. Please remove duplication. + +// Check for a CSS prefix. +// Passed prefix is all lowercase. +// First character of the prefix within the property name may be upper or lowercase. +// Other characters in the prefix within the property name must be lowercase. +// The prefix within the property name must be followed by a capital letter. +static bool hasCSSPropertyNamePrefix(const String& propertyName, const char* prefix) +{ +#ifndef NDEBUG + ASSERT(*prefix); + for (const char* p = prefix; *p; ++p) + ASSERT(WTF::isASCIILower(*p)); + ASSERT(propertyName.length()); +#endif + + if (WTF::toASCIILower(propertyName[0]) != prefix[0]) + return false; + + unsigned length = propertyName.length(); + for (unsigned i = 1; i < length; ++i) { + if (!prefix[i]) + return WTF::isASCIIUpper(propertyName[i]); + if (propertyName[i] != prefix[i]) + return false; + } + return false; +} + +// When getting properties on CSSStyleDeclarations, the name used from +// Javascript and the actual name of the property are not the same, so +// we have to do the following translation. The translation turns upper +// case characters into lower case characters and inserts dashes to +// separate words. +// +// Example: 'backgroundPositionY' -> 'background-position-y' +// +// Also, certain prefixes such as 'pos', 'css-' and 'pixel-' are stripped +// and the hadPixelOrPosPrefix out parameter is used to indicate whether or +// not the property name was prefixed with 'pos-' or 'pixel-'. +static String cssPropertyName(const String& propertyName, bool& hadPixelOrPosPrefix) +{ + hadPixelOrPosPrefix = false; + + unsigned length = propertyName.length(); + if (!length) + return String(); + + Vector<UChar> name; + name.reserveCapacity(length); + + unsigned i = 0; + + if (hasCSSPropertyNamePrefix(propertyName, "css")) + i += 3; + else if (hasCSSPropertyNamePrefix(propertyName, "pixel")) { + i += 5; + hadPixelOrPosPrefix = true; + } else if (hasCSSPropertyNamePrefix(propertyName, "pos")) { + i += 3; + hadPixelOrPosPrefix = true; + } else if (hasCSSPropertyNamePrefix(propertyName, "webkit") + || hasCSSPropertyNamePrefix(propertyName, "khtml") + || hasCSSPropertyNamePrefix(propertyName, "apple")) + name.append('-'); + else if (WTF::isASCIIUpper(propertyName[0])) + return String(); + + name.append(WTF::toASCIILower(propertyName[i++])); + + for (; i < length; ++i) { + UChar c = propertyName[i]; + if (!WTF::isASCIIUpper(c)) + name.append(c); + else { + name.append('-'); + name.append(WTF::toASCIILower(c)); + } + } + + return String::adopt(name); +} + +NAMED_PROPERTY_GETTER(CSSStyleDeclaration) +{ + INC_STATS("DOM.CSSStyleDeclaration.NamedPropertyGetter"); + // First look for API defined attributes on the style declaration object. + if (info.Holder()->HasRealNamedCallbackProperty(name)) + return notHandledByInterceptor(); + + // Search the style declaration. + CSSStyleDeclaration* imp = V8Proxy::ToNativeObject<CSSStyleDeclaration>(V8ClassIndex::CSSSTYLEDECLARATION, info.Holder()); + + bool hadPixelOrPosPrefix = false; + String propertyName = cssPropertyName(toWebCoreString(name), hadPixelOrPosPrefix); + + // Do not handle non-property names. + if (!CSSStyleDeclaration::isPropertyName(propertyName)) + return notHandledByInterceptor(); + + + RefPtr<CSSValue> cssValue = imp->getPropertyCSSValue(propertyName); + if (cssValue) { + if (hadPixelOrPosPrefix && cssValue->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE) + return v8::Number::New(static_cast<CSSPrimitiveValue*>(cssValue.get())->getFloatValue(CSSPrimitiveValue::CSS_PX)); + return v8StringOrNull(cssValue->cssText()); + } + + String result = imp->getPropertyValue(propertyName); + if (result.isNull()) + result = ""; // convert null to empty string. + + // The 'filter' attribute is made undetectable in KJS/WebKit + // to avoid confusion with IE's filter extension. + if (propertyName == "filter") + return v8UndetectableString(result); + + return v8String(result); +} + +NAMED_PROPERTY_SETTER(CSSStyleDeclaration) +{ + INC_STATS("DOM.CSSStyleDeclaration.NamedPropertySetter"); + CSSStyleDeclaration* imp = V8Proxy::ToNativeObject<CSSStyleDeclaration>(V8ClassIndex::CSSSTYLEDECLARATION, info.Holder()); + + bool hadPixelOrPosPrefix = false; + String prop = cssPropertyName(toWebCoreString(name), hadPixelOrPosPrefix); + if (!CSSStyleDeclaration::isPropertyName(prop)) + return notHandledByInterceptor(); + + String propertyValue = valueToStringWithNullCheck(value); + if (hadPixelOrPosPrefix) + propertyValue.append("px"); + + ExceptionCode ec = 0; + imp->setProperty(prop, propertyValue, ec); + + if (ec) + throwError(ec); + + return value; +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp b/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp new file mode 100644 index 0000000..0570e0e --- /dev/null +++ b/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp @@ -0,0 +1,95 @@ +/* + * 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 "CanvasRenderingContext2D.h" + +#include "CanvasGradient.h" +#include "CanvasPattern.h" +#include "CanvasStyle.h" + +#include "V8Binding.h" +#include "V8CanvasGradient.h" +#include "V8CanvasPattern.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +namespace WebCore { + +static v8::Handle<v8::Value> toV8(CanvasStyle* style) +{ + if (style->canvasGradient()) + return V8Proxy::ToV8Object(V8ClassIndex::CANVASGRADIENT, style->canvasGradient()); + + if (style->canvasPattern()) + return V8Proxy::ToV8Object(V8ClassIndex::CANVASPATTERN, style->canvasPattern()); + + return v8String(style->color()); +} + +static PassRefPtr<CanvasStyle> toCanvasStyle(v8::Handle<v8::Value> value) +{ + if (value->IsString()) + return CanvasStyle::create(toWebCoreString(value)); + + if (V8CanvasGradient::HasInstance(value)) + return CanvasStyle::create(V8Proxy::DOMWrapperToNative<CanvasGradient>(value)); + + if (V8CanvasPattern::HasInstance(value)) + return CanvasStyle::create(V8Proxy::DOMWrapperToNative<CanvasPattern>(value)); + + return 0; +} + +ACCESSOR_GETTER(CanvasRenderingContext2DStrokeStyle) +{ + CanvasRenderingContext2D* impl = V8Proxy::DOMWrapperToNative<CanvasRenderingContext2D>(info.Holder()); + return toV8(impl->strokeStyle()); +} + +ACCESSOR_SETTER(CanvasRenderingContext2DStrokeStyle) +{ + CanvasRenderingContext2D* impl = V8Proxy::DOMWrapperToNative<CanvasRenderingContext2D>(info.Holder()); + impl->setStrokeStyle(toCanvasStyle(value)); +} + +ACCESSOR_GETTER(CanvasRenderingContext2DFillStyle) +{ + CanvasRenderingContext2D* impl = V8Proxy::DOMWrapperToNative<CanvasRenderingContext2D>(info.Holder()); + return toV8(impl->fillStyle()); +} + +ACCESSOR_SETTER(CanvasRenderingContext2DFillStyle) +{ + CanvasRenderingContext2D* impl = V8Proxy::DOMWrapperToNative<CanvasRenderingContext2D>(info.Holder()); + impl->setFillStyle(toCanvasStyle(value)); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8ClipboardCustom.cpp b/WebCore/bindings/v8/custom/V8ClipboardCustom.cpp new file mode 100644 index 0000000..eff5511 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8ClipboardCustom.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2007-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 "Clipboard.h" + +#include "HTMLImageElement.h" +#include "HTMLNames.h" +#include "IntPoint.h" +#include "Node.h" +#include "Element.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Node.h" +#include "V8Proxy.h" + +namespace WebCore { + +ACCESSOR_GETTER(ClipboardTypes) +{ + INC_STATS("DOM.Clipboard.types()"); + Clipboard* clipboard = V8Proxy::ToNativeObject<Clipboard>(V8ClassIndex::CLIPBOARD, info.Holder()); + + HashSet<String> types = clipboard->types(); + if (types.isEmpty()) + return v8::Null(); + + v8::Local<v8::Array> result = v8::Array::New(types.size()); + HashSet<String>::const_iterator end = types.end(); + int index = 0; + for (HashSet<String>::const_iterator it = types.begin(); it != end; ++it, ++index) + result->Set(v8::Integer::New(index), v8String(*it)); + + return result; +} + +CALLBACK_FUNC_DECL(ClipboardClearData) +{ + INC_STATS("DOM.Clipboard.clearData()"); + Clipboard* clipboard = V8Proxy::ToNativeObject<Clipboard>(V8ClassIndex::CLIPBOARD, args.Holder()); + + if (!args.Length()) { + clipboard->clearAllData(); + return v8::Undefined(); + } + + if (args.Length() != 1) + return throwError("clearData: Invalid number of arguments", V8Proxy::SYNTAX_ERROR); + + String type = toWebCoreString(args[0]); + clipboard->clearData(type); + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(ClipboardGetData) +{ + INC_STATS("DOM.Clipboard.getData()"); + Clipboard* clipboard = V8Proxy::ToNativeObject<Clipboard>(V8ClassIndex::CLIPBOARD, args.Holder()); + + if (args.Length() != 1) + return throwError("getData: Invalid number of arguments", V8Proxy::SYNTAX_ERROR); + + bool success; + String result = clipboard->getData(toWebCoreString(args[0]), success); + if (success) + return v8String(result); + + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(ClipboardSetData) +{ + INC_STATS("DOM.Clipboard.setData()"); + Clipboard* clipboard = V8Proxy::ToNativeObject<Clipboard>(V8ClassIndex::CLIPBOARD, args.Holder()); + + if (args.Length() != 2) + return throwError("setData: Invalid number of arguments", V8Proxy::SYNTAX_ERROR); + + String type = toWebCoreString(args[0]); + String data = toWebCoreString(args[1]); + return v8Boolean(clipboard->setData(type, data)); +} + +CALLBACK_FUNC_DECL(ClipboardSetDragImage) +{ + INC_STATS("DOM.Clipboard.setDragImage()"); + Clipboard* clipboard = V8Proxy::ToNativeObject<Clipboard>(V8ClassIndex::CLIPBOARD, args.Holder()); + + if (!clipboard->isForDragging()) + return v8::Undefined(); + + if (args.Length() != 3) + return throwError("setDragImage: Invalid number of arguments", V8Proxy::SYNTAX_ERROR); + + int x = toInt32(args[1]); + int y = toInt32(args[2]); + + Node* node = 0; + if (V8Node::HasInstance(args[0])) + node = V8Proxy::DOMWrapperToNode<Node>(args[0]); + + if (!node || !node->isElementNode()) + return throwError("setDragImageFromElement: Invalid first argument"); + + if (static_cast<Element*>(node)->hasLocalName(HTMLNames::imgTag) && !node->inDocument()) + clipboard->setDragImage(static_cast<HTMLImageElement*>(node)->cachedImage(), IntPoint(x, y)); + else + clipboard->setDragImageElement(node, IntPoint(x, y)); + + return v8::Undefined(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8CustomBinding.cpp b/WebCore/bindings/v8/custom/V8CustomBinding.cpp new file mode 100644 index 0000000..841382b --- /dev/null +++ b/WebCore/bindings/v8/custom/V8CustomBinding.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2007-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 "V8CustomBinding.h" + +#include "Element.h" +#include "Document.h" +#include "HTMLNames.h" +#include "HTMLFrameElementBase.h" +#include "CSSHelper.h" + +namespace WebCore { + +bool allowSettingFrameSrcToJavascriptUrl(HTMLFrameElementBase* frame, String value) +{ + if (protocolIs(parseURL(value), "javascript")) { + Node* contentDoc = frame->contentDocument(); + if (contentDoc && !V8Proxy::CheckNodeSecurity(contentDoc)) + return false; + } + return true; +} + +bool allowSettingSrcToJavascriptURL(Element* element, String name, String value) +{ + if ((element->hasTagName(HTMLNames::iframeTag) || element->hasTagName(HTMLNames::frameTag)) && equalIgnoringCase(name, "src")) + return allowSettingFrameSrcToJavascriptUrl(static_cast<HTMLFrameElementBase*>(element), value); + return true; +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8CustomBinding.h b/WebCore/bindings/v8/custom/V8CustomBinding.h new file mode 100644 index 0000000..20fa6a1 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8CustomBinding.h @@ -0,0 +1,49 @@ +/* + * 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 V8CustomBinding_h +#define V8CustomBinding_h + +// FIXME: This is a temporary forwarding header until all bindings have migrated +// over and v8_custom actually becomes V8CustomBinding. +#include "v8_custom.h" + +namespace WebCore { + + class HTMLFrameElementBase; + class Element; + class String; + + bool allowSettingFrameSrcToJavascriptUrl(HTMLFrameElementBase*, String value); + bool allowSettingSrcToJavascriptURL(Element*, String name, String value); + +} // namespace WebCore + +#endif // V8CustomBinding_h diff --git a/WebCore/bindings/v8/custom/V8CustomEventListener.cpp b/WebCore/bindings/v8/custom/V8CustomEventListener.cpp new file mode 100644 index 0000000..68c8328 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8CustomEventListener.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2006, 2007, 2008, 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 "V8CustomEventListener.h" + +#include "V8Proxy.h" + +namespace WebCore { + +V8EventListener::V8EventListener(Frame* frame, v8::Local<v8::Object> listener, bool isInline) + : V8AbstractEventListener(frame, isInline) +{ + m_listener = v8::Persistent<v8::Object>::New(listener); +#ifndef NDEBUG + V8Proxy::RegisterGlobalHandle(EVENT_LISTENER, this, m_listener); +#endif +} + +V8EventListener::~V8EventListener() +{ + if (m_frame) { + V8Proxy* proxy = V8Proxy::retrieve(m_frame); + if (proxy) + proxy->RemoveV8EventListener(this); + } + + disposeListenerObject(); +} + +v8::Local<v8::Function> V8EventListener::getListenerFunction() +{ + // Has the listener been disposed? + if (m_listener.IsEmpty()) + return v8::Local<v8::Function>(); + + if (m_listener->IsFunction()) + return v8::Local<v8::Function>::New(v8::Persistent<v8::Function>::Cast(m_listener)); + + if (m_listener->IsObject()) { + v8::Local<v8::Value> property = m_listener->Get(v8::String::NewSymbol("handleEvent")); + if (property->IsFunction()) + return v8::Local<v8::Function>::Cast(property); + } + + return v8::Local<v8::Function>(); +} + +v8::Local<v8::Value> V8EventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event, bool isWindowEvent) +{ + v8::Local<v8::Function> handlerFunction = getListenerFunction(); + v8::Local<v8::Object> receiver = getReceiverObject(event, isWindowEvent); + if (handlerFunction.IsEmpty() || receiver.IsEmpty()) + return v8::Local<v8::Value>(); + + v8::Handle<v8::Value> parameters[1] = { jsEvent }; + + V8Proxy* proxy = V8Proxy::retrieve(m_frame); + return proxy->CallFunction(handlerFunction, receiver, 1, parameters); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8CustomEventListener.h b/WebCore/bindings/v8/custom/V8CustomEventListener.h new file mode 100644 index 0000000..1e613d0 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8CustomEventListener.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2006, 2007, 2008, 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 V8CustomEventListener_h +#define V8CustomEventListener_h + +#include "V8AbstractEventListener.h" +#include <v8.h> +#include <wtf/PassRefPtr.h> + +namespace WebCore { + + class Event; + class Frame; + + // V8EventListener is a wrapper of a JS object implements EventListener interface (has handleEvent(event) method), or a JS function + // that can handle the event. + class V8EventListener : public V8AbstractEventListener { + public: + static PassRefPtr<V8EventListener> create(Frame* frame, v8::Local<v8::Object> listener, bool isInline) + { + return adoptRef(new V8EventListener(frame, listener, isInline)); + } + + virtual bool isInline() const { return m_isInline; } + + // Detach the listener from its owner frame. + void disconnectFrame() { m_frame = 0; } + + protected: + V8EventListener(Frame*, v8::Local<v8::Object> listener, bool isInline); + virtual ~V8EventListener(); + v8::Local<v8::Function> getListenerFunction(); + + private: + virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*, bool isWindowEvent); + }; + +} // namespace WebCore + +#endif // V8CustomEventListener_h diff --git a/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp new file mode 100644 index 0000000..bf07416 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp @@ -0,0 +1,72 @@ +/* + * 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 "V8CustomSQLStatementCallback.h" + +#include "Frame.h" +#include "V8CustomVoidCallback.h" + +namespace WebCore { + +V8CustomSQLStatementCallback::V8CustomSQLStatementCallback(v8::Local<v8::Object> callback, Frame* frame) + : m_callback(v8::Persistent<v8::Object>::New(callback)) + , m_frame(frame) +{ +} + +V8CustomSQLStatementCallback::~V8CustomSQLStatementCallback() +{ + m_callback.Dispose(); +} + +void V8CustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLResultSet* resultSet, bool& raisedException) +{ + v8::HandleScope handleScope; + + v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame.get()); + if (context.IsEmpty()) + return; + + v8::Context::Scope scope(context); + + v8::Handle<v8::Value> argv[] = { + V8Proxy::ToV8Object(V8ClassIndex::SQLTRANSACTION, transaction), + V8Proxy::ToV8Object(V8ClassIndex::SQLRESULTSET, resultSet) + }; + + // Protect the frame until the callback returns. + RefPtr<Frame> protector(m_frame); + + bool callbackReturnValue = false; + raisedException = invokeCallback(m_callback, 2, argv, callbackReturnValue); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.h b/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.h new file mode 100644 index 0000000..5c4b368 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.h @@ -0,0 +1,62 @@ +/* + * 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 V8CustomSQLStatementCallback_h +#define V8CustomSQLStatementCallback_h + +#include "SQLStatementCallback.h" +#include <v8.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class Frame; + +class V8CustomSQLStatementCallback : public SQLStatementCallback { +public: + static PassRefPtr<V8CustomSQLStatementCallback> create(v8::Local<v8::Value> value, Frame* frame) + { + ASSERT(value->IsObject()); + return adoptRef(new V8CustomSQLStatementCallback(value->ToObject(), frame)); + } + virtual ~V8CustomSQLStatementCallback(); + + virtual void handleEvent(SQLTransaction*, SQLResultSet*, bool& raisedException); +private: + V8CustomSQLStatementCallback(v8::Local<v8::Object>, Frame*); + + v8::Persistent<v8::Object> m_callback; + RefPtr<Frame> m_frame; +}; + +} // namespace WebCore + +#endif // V8CustomSQLStatementCallback_h diff --git a/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp new file mode 100644 index 0000000..908d21c --- /dev/null +++ b/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp @@ -0,0 +1,76 @@ +/* + * 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 "V8CustomSQLStatementErrorCallback.h" + +#include "Frame.h" +#include "V8CustomVoidCallback.h" + +namespace WebCore { + +V8CustomSQLStatementErrorCallback::V8CustomSQLStatementErrorCallback(v8::Local<v8::Object> callback, Frame* frame) + : m_callback(v8::Persistent<v8::Object>::New(callback)) + , m_frame(frame) +{ +} + +V8CustomSQLStatementErrorCallback::~V8CustomSQLStatementErrorCallback() +{ + m_callback.Dispose(); +} + +bool V8CustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, SQLError* error) +{ + v8::HandleScope handleScope; + + v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame.get()); + if (context.IsEmpty()) + return true; + + v8::Context::Scope scope(context); + + v8::Handle<v8::Value> argv[] = { + V8Proxy::ToV8Object(V8ClassIndex::SQLTRANSACTION, transaction), + V8Proxy::ToV8Object(V8ClassIndex::SQLERROR, error) + }; + + // Protect the frame until the callback returns. + RefPtr<Frame> protector(m_frame); + + bool callbackReturnValue = false; + // Step 6: If the error callback returns false, then move on to the next + // statement, if any, or onto the next overall step otherwise. Otherwise, + // the error callback did not return false, or there was no error callback. + // Jump to the last step in the overall steps. + return invokeCallback(m_callback, 2, argv, callbackReturnValue) && !callbackReturnValue; +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.h b/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.h new file mode 100644 index 0000000..7dc8114 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.h @@ -0,0 +1,64 @@ +/* + * 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 V8CustomSQLStatementErrorCallback_h +#define V8CustomSQLStatementErrorCallback_h + +#include "SQLStatementErrorCallback.h" + +#include "SQLStatementErrorCallback.h" +#include <v8.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class Frame; + +class V8CustomSQLStatementErrorCallback : public SQLStatementErrorCallback { +public: + static PassRefPtr<V8CustomSQLStatementErrorCallback> create(v8::Local<v8::Value> value, Frame* frame) + { + ASSERT(value->IsObject()); + return adoptRef(new V8CustomSQLStatementErrorCallback(value->ToObject(), frame)); + } + virtual ~V8CustomSQLStatementErrorCallback(); + + virtual bool handleEvent(SQLTransaction*, SQLError*); +private: + V8CustomSQLStatementErrorCallback(v8::Local<v8::Object>, Frame*); + + v8::Persistent<v8::Object> m_callback; + RefPtr<Frame> m_frame; +}; + +} // namespace WebCore + +#endif // V8CustomSQLStatementErrorCallback_h diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp new file mode 100644 index 0000000..a45f3c9 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp @@ -0,0 +1,75 @@ +/* + * 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 "V8CustomSQLTransactionCallback.h" + +#include "Frame.h" +#include "V8CustomVoidCallback.h" + +namespace WebCore { + +V8CustomSQLTransactionCallback::V8CustomSQLTransactionCallback(v8::Local<v8::Object> callback, Frame* frame) + : m_callback(v8::Persistent<v8::Object>::New(callback)) + , m_frame(frame) +{ +} + +V8CustomSQLTransactionCallback::~V8CustomSQLTransactionCallback() +{ + m_callback.Dispose(); +} + + +void V8CustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bool& raisedException) +{ + v8::HandleScope handleScope; + + v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame.get()); + if (context.IsEmpty()) + return; + + v8::Context::Scope scope(context); + + v8::Handle<v8::Value> argv[] = { + V8Proxy::ToV8Object(V8ClassIndex::SQLTRANSACTION, transaction) + }; + + // Protect the frame until the callback returns. + RefPtr<Frame> protector(m_frame); + + // Step 5: If the callback couldn't be called (e.g. it was null) or if + // the callback was invoked and raised an exception, jump to the last + // step (rollback transaction). + bool callbackReturnValue = false; + raisedException = invokeCallback(m_callback, 1, argv, callbackReturnValue); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.h b/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.h new file mode 100644 index 0000000..35497e0 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.h @@ -0,0 +1,62 @@ +/* + * 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 V8CustomSQLTransactionCallback_h +#define V8CustomSQLTransactionCallback_h + +#include "SQLTransactionCallback.h" +#include <v8.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class Frame; + +class V8CustomSQLTransactionCallback : public SQLTransactionCallback { +public: + static PassRefPtr<V8CustomSQLTransactionCallback> create(v8::Local<v8::Value> value, Frame* frame) + { + ASSERT(value->IsObject()); + return adoptRef(new V8CustomSQLTransactionCallback(value->ToObject(), frame)); + } + virtual ~V8CustomSQLTransactionCallback(); + + virtual void handleEvent(SQLTransaction*, bool& raisedException); +private: + V8CustomSQLTransactionCallback(v8::Local<v8::Object>, Frame*); + + v8::Persistent<v8::Object> m_callback; + RefPtr<Frame> m_frame; +}; + +} // namespace WebCore + +#endif // V8CustomSQLTransactionCallback_h diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp new file mode 100644 index 0000000..f1ad740 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp @@ -0,0 +1,75 @@ +/* + * 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 "V8CustomSQLTransactionErrorCallback.h" + +#include "Frame.h" +#include "V8CustomVoidCallback.h" + +namespace WebCore { + +V8CustomSQLTransactionErrorCallback::V8CustomSQLTransactionErrorCallback(v8::Local<v8::Object> callback, Frame* frame) + : m_callback(v8::Persistent<v8::Object>::New(callback)) + , m_frame(frame) +{ +} + +V8CustomSQLTransactionErrorCallback::~V8CustomSQLTransactionErrorCallback() +{ + m_callback.Dispose(); +} + +bool V8CustomSQLTransactionErrorCallback::handleEvent(SQLError* error) +{ + v8::HandleScope handleScope; + + v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame.get()); + if (context.IsEmpty()) + return true; + + v8::Context::Scope scope(context); + + v8::Handle<v8::Value> argv[] = { + V8Proxy::ToV8Object(V8ClassIndex::SQLERROR, error) + }; + + // Protect the frame until the callback returns. + RefPtr<Frame> protector(m_frame); + + bool callbackReturnValue = false; + invokeCallback(m_callback, 1, argv, callbackReturnValue); + + // FIXME: Eliminate return value once SQLTransactionErrorCallback is changed + // to match the spec. + return true; +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h new file mode 100644 index 0000000..bbf5a749 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h @@ -0,0 +1,63 @@ +/* + * 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 V8CustomSQLTransactionErrorCallback_h +#define V8CustomSQLTransactionErrorCallback_h + +#include "SQLTransactionErrorCallback.h" +#include <v8.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class Frame; + +class V8CustomSQLTransactionErrorCallback : public SQLTransactionErrorCallback { +public: + static PassRefPtr<V8CustomSQLTransactionErrorCallback> create(v8::Local<v8::Value> value, Frame* frame) + { + ASSERT(value->IsObject()); + return adoptRef(new V8CustomSQLTransactionErrorCallback(value->ToObject(), frame)); + } + virtual ~V8CustomSQLTransactionErrorCallback(); + + virtual bool handleEvent(SQLError*); + +private: + V8CustomSQLTransactionErrorCallback(v8::Local<v8::Object>, Frame*); + + v8::Persistent<v8::Object> m_callback; + RefPtr<Frame> m_frame; +}; + +} // namespace WebCore + +#endif // V8CustomSQLTransactionErrorCallback_h diff --git a/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp b/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp new file mode 100644 index 0000000..b4daebd --- /dev/null +++ b/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp @@ -0,0 +1,97 @@ +/* + * 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 "V8CustomVoidCallback.h" + +#include "Frame.h" + +namespace WebCore { + +V8CustomVoidCallback::V8CustomVoidCallback(v8::Local<v8::Object> callback, Frame* frame) + : m_callback(v8::Persistent<v8::Object>::New(callback)) + , m_frame(frame) +{ +} + +V8CustomVoidCallback::~V8CustomVoidCallback() +{ + m_callback.Dispose(); +} + +void V8CustomVoidCallback::handleEvent() +{ + v8::HandleScope handleScope; + + v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame.get()); + if (context.IsEmpty()) + return; + + v8::Context::Scope scope(context); + + // Protect the frame until the callback returns. + RefPtr<Frame> protector(m_frame); + + bool callbackReturnValue = false; + invokeCallback(m_callback, 0, 0, callbackReturnValue); +} + +bool invokeCallback(v8::Persistent<v8::Object> callback, int argc, v8::Handle<v8::Value> argv[], bool& callbackReturnValue) +{ + // FIXME: If an exception was thrown by the callback, we should report it + v8::TryCatch exceptionCatcher; + + v8::Local<v8::Function> callbackFunction; + if (callback->IsFunction()) { + callbackFunction = v8::Local<v8::Function>::New(v8::Persistent<v8::Function>::Cast(callback)); + } else if (callback->IsObject()) { + v8::Local<v8::Value> handleEventFunction = callback->Get(v8::String::NewSymbol("handleEvent")); + if (handleEventFunction->IsFunction()) { + callbackFunction = v8::Local<v8::Function>::Cast(handleEventFunction); + } + } else + return false; + + if (callbackFunction.IsEmpty()) + return false; + + v8::Handle<v8::Object> thisObject = v8::Context::GetCurrent()->Global(); + + V8Proxy* proxy = V8Proxy::retrieve(); + ASSERT(proxy); + + v8::Handle<v8::Value> result = proxy->CallFunction(callbackFunction, thisObject, argc, argv); + + callbackReturnValue = result.IsEmpty() && result->IsBoolean() && result->BooleanValue(); + + return exceptionCatcher.HasCaught(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8CustomVoidCallback.h b/WebCore/bindings/v8/custom/V8CustomVoidCallback.h new file mode 100644 index 0000000..586296b --- /dev/null +++ b/WebCore/bindings/v8/custom/V8CustomVoidCallback.h @@ -0,0 +1,66 @@ +/* + * 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 V8CustomVoidCallback_h +#define V8CustomVoidCallback_h + +#include "VoidCallback.h" +#include <v8.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class Frame; + +class V8CustomVoidCallback : public VoidCallback { +public: + static PassRefPtr<V8CustomVoidCallback> create(v8::Local<v8::Value> value, Frame* frame) + { + ASSERT(value->IsObject()); + return adoptRef(new V8CustomVoidCallback(value->ToObject(), frame)); + } + virtual ~V8CustomVoidCallback(); + + virtual void handleEvent(); + +private: + V8CustomVoidCallback(v8::Local<v8::Object>, Frame*); + + v8::Persistent<v8::Object> m_callback; + RefPtr<Frame> m_frame; +}; + +// Returns false if callback failed (null, wrong type, or threw exception). +bool invokeCallback(v8::Persistent<v8::Object> callback, int argc, v8::Handle<v8::Value> argv[], bool& callbackReturnValue); + +} // namespace WebCore + +#endif // V8CustomVoidCallback_h diff --git a/WebCore/bindings/v8/custom/V8DOMParserConstructor.cpp b/WebCore/bindings/v8/custom/V8DOMParserConstructor.cpp new file mode 100644 index 0000000..f96b889 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8DOMParserConstructor.cpp @@ -0,0 +1,45 @@ +/* + * 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 "DOMParser.h" + +#include "V8Binding.h" +#include "V8Proxy.h" + +namespace WebCore { + +CALLBACK_FUNC_DECL(DOMParserConstructor) +{ + INC_STATS("DOM.DOMParser.Contructor"); + return V8Proxy::ConstructDOMObject<V8ClassIndex::DOMPARSER, DOMParser>(args); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8DOMStringListCustom.cpp b/WebCore/bindings/v8/custom/V8DOMStringListCustom.cpp new file mode 100644 index 0000000..52d4399 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8DOMStringListCustom.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2007-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 "DOMStringList.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +namespace WebCore { + +INDEXED_PROPERTY_GETTER(DOMStringList) +{ + INC_STATS("DOM.DOMStringList.IndexedPropertyGetter"); + DOMStringList* imp = V8Proxy::DOMWrapperToNative<DOMStringList>(info.Holder()); + return v8String(imp->item(index)); +} + +CALLBACK_FUNC_DECL(DOMStringListItem) +{ + INC_STATS("DOM.DOMStringListItem()"); + if (!args.Length()) + return v8::Null(); + + uint32_t index = args[0]->Uint32Value(); + + DOMStringList* imp = V8Proxy::DOMWrapperToNative<DOMStringList>(args.Holder()); + if (index >= imp->length()) + return v8::Null(); + + return v8String(imp->item(index)); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8DatabaseCustom.cpp b/WebCore/bindings/v8/custom/V8DatabaseCustom.cpp new file mode 100644 index 0000000..5962ea3 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8DatabaseCustom.cpp @@ -0,0 +1,93 @@ +/* + * 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 "v8_binding.h" +#include "v8_custom.h" +#include "v8_proxy.h" + +#include "Database.h" +#include "V8CustomSQLTransactionCallback.h" +#include "V8CustomSQLTransactionErrorCallback.h" +#include "V8CustomVoidCallback.h" + +namespace WebCore { + +CALLBACK_FUNC_DECL(DatabaseChangeVersion) +{ + INC_STATS("DOM.Database.changeVersion()"); + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(DatabaseTransaction) +{ + INC_STATS("DOM.Database.transaction()"); + + if (args.Length() == 0) { + V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Transaction callback is required."); + return v8::Undefined(); + } + + if (!args[0]->IsObject()) { + V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, "Transaction callback must be of valid type."); + return v8::Undefined(); + } + + Database* database = V8Proxy::ToNativeObject<Database>(V8ClassIndex::DATABASE, args.Holder()); + + Frame* frame = V8Proxy::retrieveFrame(); + + RefPtr<V8CustomSQLTransactionCallback> callback = V8CustomSQLTransactionCallback::create(args[0], frame); + + RefPtr<V8CustomSQLTransactionErrorCallback> errorCallback; + if (args.Length() > 1) { + if (!args[1]->IsObject()) { + V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, "Transaction error callback must be of valid type."); + return v8::Undefined(); + } + errorCallback = V8CustomSQLTransactionErrorCallback::create(args[1], frame); + } + + RefPtr<V8CustomVoidCallback> successCallback; + if (args.Length() > 2) { + if (!args[1]->IsObject()) { + V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, "Transaction success callback must be of valid type."); + return v8::Undefined(); + } + successCallback = V8CustomVoidCallback::create(args[2], frame); + } + + database->transaction(callback.release(), errorCallback.release(), successCallback.release()); + + return v8::Undefined(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8DocumentCustom.cpp b/WebCore/bindings/v8/custom/V8DocumentCustom.cpp new file mode 100644 index 0000000..7f868f1 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8DocumentCustom.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2007-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 "Document.h" + +#include "ExceptionCode.h" +#include "JSXPathNSResolver.h" +#include "Node.h" +#include "XPathNSResolver.h" +#include "XPathResult.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Node.h" +#include "V8Proxy.h" +#include "V8XPathNSResolver.h" +#include "V8XPathResult.h" + +#include <wtf/RefPtr.h> + +namespace WebCore { + +CALLBACK_FUNC_DECL(DocumentEvaluate) +{ + INC_STATS("DOM.Document.evaluate()"); + + Document* document = V8Proxy::DOMWrapperToNode<Document>(args.Holder()); + ExceptionCode ec = 0; + String expression = toWebCoreString(args[0]); + Node* contextNode = 0; + if (V8Node::HasInstance(args[1])) + contextNode = V8Proxy::DOMWrapperToNode<Node>(args[1]); + + XPathNSResolver* resolver = 0; + if (V8XPathNSResolver::HasInstance(args[2])) + resolver = V8Proxy::ToNativeObject<XPathNSResolver>(V8ClassIndex::XPATHNSRESOLVER, args[2]); + else if (args[2]->IsObject()) + resolver = new JSXPathNSResolver(args[2]->ToObject()); + else if (!args[2]->IsNull() && !args[2]->IsUndefined()) + return throwError(TYPE_MISMATCH_ERR); + + int type = toInt32(args[3]); + XPathResult* inResult = 0; + if (V8XPathResult::HasInstance(args[4])) + inResult = V8Proxy::ToNativeObject<XPathResult>(V8ClassIndex::XPATHRESULT, args[4]); + + v8::TryCatch exceptionCatcher; + RefPtr<XPathResult> result = document->evaluate(expression, contextNode, resolver, type, inResult, ec); + if (exceptionCatcher.HasCaught()) + return throwError(exceptionCatcher.Exception()); + + if (ec) + return throwError(ec); + + return V8Proxy::ToV8Object(V8ClassIndex::XPATHRESULT, result.get()); +} + +CALLBACK_FUNC_DECL(DocumentGetCSSCanvasContext) +{ + INC_STATS("DOM.Document.getCSSCanvasContext"); + v8::Handle<v8::Value> holder = args.Holder(); + Document* imp = V8Proxy::DOMWrapperToNode<Document>(holder); + String contextId = toWebCoreString(args[0]); + String name = toWebCoreString(args[1]); + int width = toInt32(args[2]); + int height = toInt32(args[3]); + CanvasRenderingContext2D* result = imp->getCSSCanvasContext(contextId, name, width, height); + return V8Proxy::ToV8Object(V8ClassIndex::CANVASRENDERINGCONTEXT2D, result); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8ElementCustom.cpp b/WebCore/bindings/v8/custom/V8ElementCustom.cpp new file mode 100644 index 0000000..131f401 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8ElementCustom.cpp @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2007-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 "Element.h" + +#include "Attr.h" +#include "CSSHelper.h" +#include "Document.h" +#include "EventListener.h" +#include "ExceptionCode.h" +#include "HTMLFrameElementBase.h" +#include "HTMLNames.h" +#include "Node.h" + +#include "V8Attr.h" +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8CustomEventListener.h" +#include "V8Proxy.h" + +#include <wtf/RefPtr.h> + +namespace WebCore { + +CALLBACK_FUNC_DECL(ElementSetAttribute) +{ + INC_STATS("DOM.Element.setAttribute()"); + Element* element = V8Proxy::DOMWrapperToNode<Element>(args.Holder()); + String name = toWebCoreString(args[0]); + String value = toWebCoreString(args[1]); + + if (!allowSettingSrcToJavascriptURL(element, name, value)) + return v8::Undefined(); + + ExceptionCode ec = 0; + element->setAttribute(name, value, ec); + if (ec) + return throwError(ec); + + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(ElementSetAttributeNode) +{ + INC_STATS("DOM.Element.setAttributeNode()"); + if (!V8Attr::HasInstance(args[0])) + throwError(TYPE_MISMATCH_ERR); + + Attr* newAttr = V8Proxy::DOMWrapperToNode<Attr>(args[0]); + Element* element = V8Proxy::DOMWrapperToNode<Element>(args.Holder()); + + if (!allowSettingSrcToJavascriptURL(element, newAttr->name(), newAttr->value())) + return v8::Undefined(); + + ExceptionCode ec = 0; + RefPtr<Attr> result = element->setAttributeNode(newAttr, ec); + if (ec) + throwError(ec); + + return V8Proxy::NodeToV8Object(result.get()); +} + +CALLBACK_FUNC_DECL(ElementSetAttributeNS) +{ + INC_STATS("DOM.Element.setAttributeNS()"); + Element* element = V8Proxy::DOMWrapperToNode<Element>(args.Holder()); + String namespaceURI = toWebCoreStringWithNullCheck(args[0]); + String qualifiedName = toWebCoreString(args[1]); + String value = toWebCoreString(args[2]); + + if (!allowSettingSrcToJavascriptURL(element, qualifiedName, value)) + return v8::Undefined(); + + ExceptionCode ec = 0; + element->setAttributeNS(namespaceURI, qualifiedName, value, ec); + if (ec) + throwError(ec); + + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(ElementSetAttributeNodeNS) +{ + INC_STATS("DOM.Element.setAttributeNodeNS()"); + if (!V8Attr::HasInstance(args[0])) + return throwError(TYPE_MISMATCH_ERR); + + Attr* newAttr = V8Proxy::DOMWrapperToNode<Attr>(args[0]); + Element* element = V8Proxy::DOMWrapperToNode<Element>(args.Holder()); + + if (!allowSettingSrcToJavascriptURL(element, newAttr->name(), newAttr->value())) + return v8::Undefined(); + + ExceptionCode ec = 0; + RefPtr<Attr> result = element->setAttributeNodeNS(newAttr, ec); + if (ec) + throwError(ec); + + return V8Proxy::NodeToV8Object(result.get()); +} + +static inline String toEventType(v8::Local<v8::String> value) +{ + String key = toWebCoreString(value); + ASSERT(key.startsWith("on")); + return key.substring(2); +} + +ACCESSOR_SETTER(ElementEventHandler) +{ + Node* node = V8Proxy::DOMWrapperToNode<Node>(info.Holder()); + + String eventType = toEventType(name); + + // Set handler if the value is a function. Otherwise, clear the + // event handler. + if (value->IsFunction()) { + V8Proxy* proxy = V8Proxy::retrieve(node->document()->frame()); + // the document might be created using createDocument, + // which does not have a frame, use the active frame + if (!proxy) + proxy = V8Proxy::retrieve(V8Proxy::retrieveActiveFrame()); + if (!proxy) + return; + + if (RefPtr<EventListener> listener = proxy->FindOrCreateV8EventListener(value, true)) + node->setInlineEventListenerForType(eventType, listener); + } else + node->removeInlineEventListenerForType(eventType); +} + +ACCESSOR_GETTER(ElementEventHandler) +{ + Node* node = V8Proxy::DOMWrapperToNode<Node>(info.Holder()); + + EventListener* listener = node->inlineEventListenerForType(toEventType(name)); + return V8Proxy::EventListenerToV8Object(listener); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8EventCustom.cpp b/WebCore/bindings/v8/custom/V8EventCustom.cpp new file mode 100644 index 0000000..1dae845 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8EventCustom.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2007-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 "Event.h" + +#include "Clipboard.h" +#include "ClipboardEvent.h" +#include "MouseEvent.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +namespace WebCore { + +ACCESSOR_SETTER(EventReturnValue) +{ + Event* event = V8Proxy::DOMWrapperToNative<Event>(info.Holder()); + event->setDefaultPrevented(!value->BooleanValue()); +} + +ACCESSOR_GETTER(EventDataTransfer) +{ + Event* event = V8Proxy::DOMWrapperToNative<Event>(info.Holder()); + + if (event->isDragEvent()) + return V8Proxy::ToV8Object(V8ClassIndex::CLIPBOARD, static_cast<MouseEvent*>(event)->clipboard()); + + return v8::Undefined(); +} + +ACCESSOR_GETTER(EventClipboardData) +{ + Event* event = V8Proxy::DOMWrapperToNative<Event>(info.Holder()); + + if (event->isClipboardEvent()) + return V8Proxy::ToV8Object(V8ClassIndex::CLIPBOARD, static_cast<ClipboardEvent*>(event)->clipboard()); + + return v8::Undefined(); +} + +ACCESSOR_GETTER(EventSrcElement) +{ + Event* event = V8Proxy::DOMWrapperToNative<Event>(info.Holder()); + return V8Proxy::EventTargetToV8Object(event->target()); +} + +ACCESSOR_GETTER(EventReturnValue) +{ + Event* event = V8Proxy::DOMWrapperToNative<Event>(info.Holder()); + return event->defaultPrevented() ? v8::False() : v8::True(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp new file mode 100644 index 0000000..cf66e39 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2007-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 "HTMLCanvasElement.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Node.h" +#include "V8Proxy.h" + +namespace WebCore { + +CALLBACK_FUNC_DECL(HTMLCanvasElementGetContext) +{ + INC_STATS("DOM.HTMLCanvasElement.getContext"); + v8::Handle<v8::Value> holder = args.Holder(); + HTMLCanvasElement* imp = V8Proxy::DOMWrapperToNode<HTMLCanvasElement>(holder); + String contextId = ToWebCoreString(args[0]); + CanvasRenderingContext2D* result = imp->getContext(contextId); + return V8Proxy::ToV8Object(V8ClassIndex::CANVASRENDERINGCONTEXT2D, result); +} + +} // namespace WebCore + diff --git a/WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp new file mode 100644 index 0000000..97a3b4f --- /dev/null +++ b/WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp @@ -0,0 +1,140 @@ +/* + * 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 "HTMLCollection.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8NamedNodesCollection.h" +#include "V8Proxy.h" + +namespace WebCore { + +static v8::Handle<v8::Value> getNamedItems(HTMLCollection* collection, String name) +{ + Vector<RefPtr<Node> > namedItems; + collection->namedItems(name, namedItems); + + if (!namedItems.size()) + return v8::Handle<v8::Value>(); + + if (namedItems.size() == 1) + return V8Proxy::NodeToV8Object(namedItems.at(0).get()); + + NodeList* list = new V8NamedNodesCollection(namedItems); + return V8Proxy::ToV8Object(V8ClassIndex::NODELIST, list); +} + +static v8::Handle<v8::Value> getItem(HTMLCollection* collection, v8::Handle<v8::Value> argument) +{ + v8::Local<v8::Uint32> index = argument->ToArrayIndex(); + if (index.IsEmpty()) { + v8::Handle<v8::Value> result = getNamedItems(collection, toWebCoreString(argument->ToString())); + + if (result.IsEmpty()) + return v8::Undefined(); + + return result; + } + + RefPtr<Node> result = collection->item(index->Uint32Value()); + return V8Proxy::NodeToV8Object(result.get()); +} + +NAMED_PROPERTY_GETTER(HTMLCollection) +{ + INC_STATS("DOM.HTMLCollection.NamedPropertyGetter"); + // Search the prototype chain first. + v8::Handle<v8::Value> value = info.Holder()->GetRealNamedPropertyInPrototypeChain(name); + + if (!value.IsEmpty()) + return value; + + // Search local callback properties next to find IDL defined + // properties. + if (info.Holder()->HasRealNamedCallbackProperty(name)) + return v8::Handle<v8::Value>(); + + // Finally, search the DOM structure. + HTMLCollection* imp = V8Proxy::ToNativeObject<HTMLCollection>(V8ClassIndex::HTMLCOLLECTION, info.Holder()); + return getNamedItems(imp, toWebCoreString(name)); +} + +CALLBACK_FUNC_DECL(HTMLCollectionItem) +{ + INC_STATS("DOM.HTMLCollection.item()"); + HTMLCollection* imp = V8Proxy::ToNativeObject<HTMLCollection>(V8ClassIndex::HTMLCOLLECTION, args.Holder()); + return getItem(imp, args[0]); +} + +CALLBACK_FUNC_DECL(HTMLCollectionNamedItem) +{ + INC_STATS("DOM.HTMLCollection.namedItem()"); + HTMLCollection* imp = V8Proxy::ToNativeObject<HTMLCollection>(V8ClassIndex::HTMLCOLLECTION, args.Holder()); + v8::Handle<v8::Value> result = getNamedItems(imp, toWebCoreString(args[0])); + + if (result.IsEmpty()) + return v8::Undefined(); + + return result; +} + +CALLBACK_FUNC_DECL(HTMLCollectionCallAsFunction) +{ + INC_STATS("DOM.HTMLCollection.callAsFunction()"); + if (args.Length() < 1) + return v8::Undefined(); + + HTMLCollection* imp = V8Proxy::ToNativeObject<HTMLCollection>(V8ClassIndex::HTMLCOLLECTION, args.Holder()); + + if (args.Length() == 1) + return getItem(imp, args[0]); + + // If there is a second argument it is the index of the item we want. + String name = toWebCoreString(args[0]); + v8::Local<v8::Uint32> index = args[1]->ToArrayIndex(); + if (index.IsEmpty()) + return v8::Undefined(); + + unsigned current = index->Uint32Value(); + Node* node = imp->namedItem(name); + while (node) { + if (!current) + return V8Proxy::NodeToV8Object(node); + + node = imp->nextNamedItem(name); + current--; + } + + return v8::Undefined(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp new file mode 100644 index 0000000..bc04f7e --- /dev/null +++ b/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2007-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 "HTMLDocument.h" + +#include "Frame.h" +#include "HTMLIFrameElement.h" +#include "HTMLNames.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +#include <wtf/RefPtr.h> + +namespace WebCore { + +NAMED_PROPERTY_DELETER(HTMLDocument) +{ + // Only handle document.all. Insert the marker object into the + // shadow internal field to signal that document.all is no longer + // shadowed. + String key = toWebCoreString(name); + if (key != "all") + return deletionNotHandledByInterceptor(); + + ASSERT(info.Holder()->InternalFieldCount() == kHTMLDocumentInternalFieldCount); + v8::Local<v8::Value> marker = info.Holder()->GetInternalField(kHTMLDocumentMarkerIndex); + info.Holder()->SetInternalField(kHTMLDocumentShadowIndex, marker); + return v8::True(); +} + +NAMED_PROPERTY_SETTER(HTMLDocument) +{ + INC_STATS("DOM.HTMLDocument.NamedPropertySetter"); + // Only handle document.all. We insert the value into the shadow + // internal field from which the getter will retrieve it. + String key = toWebCoreString(name); + if (key == "all") { + ASSERT(info.Holder()->InternalFieldCount() == kHTMLDocumentInternalFieldCount); + info.Holder()->SetInternalField(kHTMLDocumentShadowIndex, value); + } + return notHandledByInterceptor(); +} + +NAMED_PROPERTY_GETTER(HTMLDocument) +{ + INC_STATS("DOM.HTMLDocument.NamedPropertyGetter"); + AtomicString key = toWebCoreString(name); + + // Special case for document.all. If the value in the shadow + // internal field is not the marker object, then document.all has + // been temporarily shadowed and we return the value. + if (key == "all") { + ASSERT(info.Holder()->InternalFieldCount() == kHTMLDocumentInternalFieldCount); + v8::Local<v8::Value> marker = info.Holder()->GetInternalField(kHTMLDocumentMarkerIndex); + v8::Local<v8::Value> value = info.Holder()->GetInternalField(kHTMLDocumentShadowIndex); + if (marker != value) + return value; + } + + HTMLDocument* imp = V8Proxy::DOMWrapperToNode<HTMLDocument>(info.Holder()); + + // Fast case for named elements that are not there. + if (!imp->hasNamedItem(key.impl()) && !imp->hasExtraNamedItem(key.impl())) + return v8::Handle<v8::Value>(); + + RefPtr<HTMLCollection> items = imp->documentNamedItems(key); + if (!items->length()) + return notHandledByInterceptor(); + + if (items->length() == 1) { + Node* node = items->firstItem(); + Frame* frame = 0; + if (node->hasTagName(HTMLNames::iframeTag) && (frame = static_cast<HTMLIFrameElement*>(node)->contentFrame())) + return V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, frame->domWindow()); + + return V8Proxy::NodeToV8Object(node); + } + + return V8Proxy::ToV8Object(V8ClassIndex::HTMLCOLLECTION, items.get()); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8HTMLFormElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLFormElementCustom.cpp new file mode 100644 index 0000000..454bbc0 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8HTMLFormElementCustom.cpp @@ -0,0 +1,70 @@ +/* + * 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 "HTMLFormElement.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8NamedNodesCollection.h" +#include "V8Proxy.h" + +namespace WebCore { + +NAMED_PROPERTY_GETTER(HTMLFormElement) +{ + INC_STATS("DOM.HTMLFormElement.NamedPropertyGetter"); + HTMLFormElement* imp = V8Proxy::DOMWrapperToNode<HTMLFormElement>(info.Holder()); + String v = toWebCoreString(name); + + // Call getNamedElements twice, first time check if it has a value + // and let HTMLFormElement update its cache. + // See issue: 867404 + { + Vector<RefPtr<Node> > elements; + imp->getNamedElements(v, elements); + if (elements.isEmpty()) + return v8::Handle<v8::Value>(); + } + + // Second call may return different results from the first call, + // but if the first the size cannot be zero. + Vector<RefPtr<Node> > elements; + imp->getNamedElements(v, elements); + ASSERT(!elements.isEmpty()); + + if (elements.size() == 1) + return V8Proxy::NodeToV8Object(elements.at(0).get()); + + NodeList* collection = new V8NamedNodesCollection(elements); + return V8Proxy::ToV8Object(V8ClassIndex::NODELIST, collection); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8HTMLFrameElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLFrameElementCustom.cpp new file mode 100644 index 0000000..bfc4c28 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8HTMLFrameElementCustom.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2007-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 "HTMLFrameElement.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +namespace WebCore { + +ACCESSOR_SETTER(HTMLFrameElementSrc) +{ + HTMLFrameElement* frame = V8Proxy::DOMWrapperToNode<HTMLFrameElement>(info.Holder()); + String srcValue = toWebCoreStringWithNullCheck(value); + + if (!allowSettingFrameSrcToJavascriptUrl(frame, srcValue)) + return; + + frame->setSrc(srcValue); +} + +ACCESSOR_SETTER(HTMLFrameElementLocation) +{ + HTMLFrameElement* frame = V8Proxy::DOMWrapperToNode<HTMLFrameElement>(info.Holder()); + String locationValue = toWebCoreStringWithNullCheck(value); + + if (!allowSettingFrameSrcToJavascriptUrl(frame, locationValue)) + return; + + frame->setLocation(locationValue); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp new file mode 100644 index 0000000..df08542 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2007-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 "HTMLFrameSetElement.h" + +#include "Document.h" +#include "Frame.h" +#include "HTMLCollection.h" +#include "HTMLFrameElement.h" +#include "HTMLNames.h" +#include "Node.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +namespace WebCore { + +NAMED_PROPERTY_GETTER(HTMLFrameSetElement) +{ + INC_STATS("DOM.HTMLFrameSetElement.NamedPropertyGetter"); + HTMLFrameSetElement* imp = V8Proxy::DOMWrapperToNode<HTMLFrameSetElement>(info.Holder()); + Node* frameNode = imp->children()->namedItem(toWebCoreString(name)); + if (frameNode && frameNode->hasTagName(HTMLNames::frameTag)) { + Document* doc = static_cast<HTMLFrameElement*>(frameNode)->contentDocument(); + if (!doc) + return v8::Undefined(); + if (Frame* frame = doc->frame()) + return V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, frame->domWindow()); + } + return notHandledByInterceptor(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8HTMLIFrameElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLIFrameElementCustom.cpp new file mode 100644 index 0000000..3739a4e --- /dev/null +++ b/WebCore/bindings/v8/custom/V8HTMLIFrameElementCustom.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2007-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 "HTMLIFrameElement.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +namespace WebCore { + +ACCESSOR_SETTER(HTMLIFrameElementSrc) +{ + HTMLIFrameElement* iframe = V8Proxy::DOMWrapperToNode<HTMLIFrameElement>(info.Holder()); + String v = valueToStringWithNullCheck(value); + + if (!allowSettingFrameSrcToJavascriptUrl(iframe, v)) + return; + + iframe->setSrc(v); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8HTMLInputElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLInputElementCustom.cpp new file mode 100644 index 0000000..628634d --- /dev/null +++ b/WebCore/bindings/v8/custom/V8HTMLInputElementCustom.cpp @@ -0,0 +1,109 @@ +/* + * 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 "HTMLInputElement.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +namespace WebCore { + +ACCESSOR_GETTER(HTMLInputElementSelectionStart) +{ + INC_STATS("DOM.HTMLInputElement.selectionStart._get"); + v8::Handle<v8::Object> holder = info.Holder(); + HTMLInputElement* imp = V8Proxy::DOMWrapperToNode<HTMLInputElement>(holder); + + if (!imp->canHaveSelection()) + return throwError("Accessing selectionStart on an input element that cannot have a selection."); + + int v = imp->selectionStart(); + return v8::Integer::New(v); +} + +ACCESSOR_SETTER(HTMLInputElementSelectionStart) +{ + INC_STATS("DOM.HTMLInputElement.selectionStart._set"); + v8::Handle<v8::Object> holder = info.Holder(); + HTMLInputElement* imp = V8Proxy::DOMWrapperToNode<HTMLInputElement>(holder); + + if (!imp->canHaveSelection()) { + throwError("Accessing selectionStart on an input element that cannot have a selection."); + return; + } + imp->setSelectionStart(value->Int32Value()); +} + +ACCESSOR_GETTER(HTMLInputElementSelectionEnd) +{ + INC_STATS("DOM.HTMLInputElement.selectionEnd._get"); + v8::Handle<v8::Object> holder = info.Holder(); + HTMLInputElement* imp = V8Proxy::DOMWrapperToNode<HTMLInputElement>(holder); + + if (!imp->canHaveSelection()) + return throwError("Accessing selectionEnd on an input element that cannot have a selection."); + + int v = imp->selectionEnd(); + return v8::Integer::New(v); +} + +ACCESSOR_SETTER(HTMLInputElementSelectionEnd) +{ + INC_STATS("DOM.HTMLInputElement.selectionEnd._set"); + v8::Handle<v8::Object> holder = info.Holder(); + HTMLInputElement* imp = V8Proxy::DOMWrapperToNode<HTMLInputElement>(holder); + + if (!imp->canHaveSelection()) { + throwError("Accessing selectionEnd on an input element that cannot have a selection."); + return; + } + + imp->setSelectionEnd(value->Int32Value()); +} + +CALLBACK_FUNC_DECL(HTMLInputElementSetSelectionRange) +{ + INC_STATS("DOM.HTMLInputElement.setSelectionRange"); + v8::Handle<v8::Object> holder = args.Holder(); + HTMLInputElement* imp = V8Proxy::DOMWrapperToNode<HTMLInputElement>(holder); + + if (!imp->canHaveSelection()) + return throwError("Calling setSelectionRange on an input element that cannot have a selection."); + + int start = args[0]->Int32Value(); + int end = args[1]->Int32Value(); + + imp->setSelectionRange(start, end); + return v8::Undefined(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp new file mode 100644 index 0000000..c8f7f6e --- /dev/null +++ b/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp @@ -0,0 +1,116 @@ +/* + * 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 "HTMLOptionsCollection.h" + +#include "HTMLOptionElement.h" +#include "HTMLSelectElement.h" +#include "ExceptionCode.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8HTMLOptionElement.h" +#include "V8HTMLSelectElementCustom.h" +#include "V8Proxy.h" + +namespace WebCore { + +CALLBACK_FUNC_DECL(HTMLOptionsCollectionRemove) +{ + INC_STATS("DOM.HTMLOptionsCollection.remove()"); + HTMLOptionsCollection* imp = V8Proxy::ToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, args.Holder()); + HTMLSelectElement* base = static_cast<HTMLSelectElement*>(imp->base()); + return removeElement(base, args); +} + +CALLBACK_FUNC_DECL(HTMLOptionsCollectionAdd) +{ + INC_STATS("DOM.HTMLOptionsCollection.add()"); + if (!V8HTMLOptionElement::HasInstance(args[0])) { + V8Proxy::SetDOMException(TYPE_MISMATCH_ERR); + return v8::Undefined(); + } + HTMLOptionsCollection* imp = V8Proxy::ToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, args.Holder()); + HTMLOptionElement* option = V8Proxy::DOMWrapperToNode<HTMLOptionElement>(args[0]); + + ExceptionCode ec = 0; + if (args.Length() < 2) + imp->add(option, ec); + else { + bool ok; + v8::TryCatch try_catch; + int index = ToInt32(args[1], ok); + + if (try_catch.HasCaught()) + return v8::Undefined(); + + if (!ok) + ec = TYPE_MISMATCH_ERR; + else + imp->add(option, index, ec); + } + + if (ec != 0) + V8Proxy::SetDOMException(ec); + + return v8::Undefined(); +} + +ACCESSOR_GETTER(HTMLOptionsCollectionLength) +{ + INC_STATS("DOM.HTMLOptionsCollection.length._get"); + HTMLOptionsCollection* imp = V8Proxy::ToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, info.Holder()); + int v = imp->length(); + return v8::Integer::New(v); +} + +ACCESSOR_SETTER(HTMLOptionsCollectionLength) +{ + INC_STATS("DOM.HTMLOptionsCollection.length._set"); + HTMLOptionsCollection* imp = V8Proxy::ToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, info.Holder()); + double v = value->NumberValue(); + unsigned newLength = 0; + ExceptionCode ec = 0; + if (!isnan(v) && !isinf(v)) { + if (v < 0.0) + ec = INDEX_SIZE_ERR; + else if (v > static_cast<double>(UINT_MAX)) + newLength = UINT_MAX; + else + newLength = static_cast<unsigned>(v); + } + if (!ec) + imp->setLength(value->Uint32Value(), ec); + + V8Proxy::SetDOMException(ec); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8HTMLPlugInElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLPlugInElementCustom.cpp new file mode 100644 index 0000000..a6e41a1 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8HTMLPlugInElementCustom.cpp @@ -0,0 +1,111 @@ +/* +* 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 "HTMLPlugInElement.h" + +#include "ScriptInstance.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +// FIXME: The name of this file will change once refactoring is complete +#include "v8_npobject.h" + +namespace WebCore { + +NAMED_PROPERTY_GETTER(HTMLPlugInElement) +{ + INC_STATS("DOM.HTMLPlugInElement.NamedPropertyGetter"); + HTMLPlugInElement* imp = V8Proxy::DOMWrapperToNode<HTMLPlugInElement>(info.Holder()); + ScriptInstance scriptInstance = imp->getInstance(); + if (!scriptInstance) + return notHandledByInterceptor(); + + v8::Local<v8::Object> instance = v8::Local<v8::Object>::New(scriptInstance->instance()); + if (instance.IsEmpty()) + return notHandledByInterceptor(); + + return NPObjectGetNamedProperty(instance, name); +} + +NAMED_PROPERTY_SETTER(HTMLPlugInElement) +{ + INC_STATS("DOM.HTMLPlugInElement.NamedPropertySetter"); + HTMLPlugInElement* imp = V8Proxy::DOMWrapperToNode<HTMLPlugInElement>(info.Holder()); + ScriptInstance scriptInstance = imp->getInstance(); + if (!scriptInstance) + return notHandledByInterceptor(); + + v8::Local<v8::Object> instance = v8::Local<v8::Object>::New(scriptInstance->instance()); + if (instance.IsEmpty()) + return notHandledByInterceptor(); + + return NPObjectSetNamedProperty(instance, name, value); +} + +CALLBACK_FUNC_DECL(HTMLPlugInElement) +{ + INC_STATS("DOM.HTMLPluginElement()"); + return NPObjectInvokeDefaultHandler(args); +} + +INDEXED_PROPERTY_GETTER(HTMLPlugInElement) +{ + INC_STATS("DOM.HTMLPlugInElement.IndexedPropertyGetter"); + HTMLPlugInElement* imp = V8Proxy::DOMWrapperToNode<HTMLPlugInElement>(info.Holder()); + ScriptInstance scriptInstance = imp->getInstance(); + if (!scriptInstance) + return notHandledByInterceptor(); + + v8::Local<v8::Object> instance = v8::Local<v8::Object>::New(scriptInstance->instance()); + if (instance.IsEmpty()) + return notHandledByInterceptor(); + + return NPObjectGetIndexedProperty(instance, index); +} + +INDEXED_PROPERTY_SETTER(HTMLPlugInElement) +{ + INC_STATS("DOM.HTMLPlugInElement.IndexedPropertySetter"); + HTMLPlugInElement* imp = V8Proxy::DOMWrapperToNode<HTMLPlugInElement>(info.Holder()); + ScriptInstance scriptInstance = imp->getInstance(); + if (!scriptInstance) + return notHandledByInterceptor(); + + v8::Local<v8::Object> instance = v8::Local<v8::Object>::New(scriptInstance->instance()); + if (instance.IsEmpty()) + return notHandledByInterceptor(); + + return NPObjectSetIndexedProperty(instance, index, value); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8HTMLSelectElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLSelectElementCustom.cpp new file mode 100644 index 0000000..97f7726 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8HTMLSelectElementCustom.cpp @@ -0,0 +1,63 @@ +/* + * 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 "V8HTMLSelectElementCustom.h" + +#include "HTMLSelectElement.h" +#include "HTMLOptionElement.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8HTMLOptionElement.h" +#include "V8Proxy.h" + +namespace WebCore { + +CALLBACK_FUNC_DECL(HTMLSelectElementRemove) +{ + INC_STATS("DOM.HTMLSelectElement.remove"); + HTMLSelectElement* imp = V8Proxy::DOMWrapperToNode<HTMLSelectElement>(args.Holder()); + return removeElement(imp, args); +} + +v8::Handle<v8::Value> removeElement(HTMLSelectElement* imp, const v8::Arguments& args) +{ + if (V8HTMLOptionElement::HasInstance(args[0])) { + HTMLOptionElement* element = V8Proxy::DOMWrapperToNode<HTMLOptionElement>(args[0]); + imp->remove(element->index()); + return v8::Undefined(); + } + + imp->remove(ToInt32(args[0])); + return v8::Undefined(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8HTMLSelectElementCustom.h b/WebCore/bindings/v8/custom/V8HTMLSelectElementCustom.h new file mode 100644 index 0000000..b956ed8 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8HTMLSelectElementCustom.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2008, 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 V8HTMLSelectElementCustom_h +#define V8HTMLSelectElementCustom_h + +#include <v8.h> + +namespace WebCore { + + class HTMLSelectElement; + + v8::Handle<v8::Value> removeElement(HTMLSelectElement*, const v8::Arguments&); + +} // namespace WebCore + +#endif // V8HTMLSelectElementCustom_h diff --git a/WebCore/bindings/v8/custom/V8InspectorControllerCustom.cpp b/WebCore/bindings/v8/custom/V8InspectorControllerCustom.cpp new file mode 100644 index 0000000..387806f --- /dev/null +++ b/WebCore/bindings/v8/custom/V8InspectorControllerCustom.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2007-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 "InspectorController.h" + +#include "ExceptionCode.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +namespace WebCore { + +CALLBACK_FUNC_DECL(InspectorControllerDebuggerEnabled) +{ + INC_STATS("InspectorController.debuggerEnabled()"); + return v8::False(); +} + +CALLBACK_FUNC_DECL(InspectorControllerPauseOnExceptions) +{ + INC_STATS("InspectorController.pauseOnExceptions()"); + return v8::False(); +} + +CALLBACK_FUNC_DECL(InspectorControllerProfilerEnabled) +{ + INC_STATS("InspectorController.profilerEnabled()"); + return v8::False(); +} + +#if ENABLE(DATABASE) +CALLBACK_FUNC_DECL(InspectorControllerDatabaseTableNames) +{ + INC_STATS("InspectorController.databaseTableNames()"); + v8::Local<v8::Array> result = v8::Array::New(0); + return result; +} +#endif + +CALLBACK_FUNC_DECL(InspectorControllerWrapCallback) +{ + INC_STATS("InspectorController.wrapCallback()"); + return args[0]; +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8LocationCustom.cpp b/WebCore/bindings/v8/custom/V8LocationCustom.cpp new file mode 100644 index 0000000..6dc2652 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8LocationCustom.cpp @@ -0,0 +1,385 @@ +/* + * 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 "Location.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8CustomEventListener.h" +#include "V8Location.h" +#include "V8Proxy.h" + +#include "PlatformString.h" +#include "KURL.h" +#include "Document.h" +#include "FrameLoader.h" +#include "ScriptController.h" +#include "CSSHelper.h" +#include "Frame.h" + +namespace WebCore { + +// Notes about V8/JSC porting of this file. +// This class is not very JS-engine specific. If we can move a couple of +// methods to the scriptController, we should be able to unify the code +// between JSC and V8: +// retrieveActiveFrame() - in JSC, this needs an ExecState. +// isSafeScript() +// Since JSC and V8 have different mechanisms for getting at the ActiveFrame, +// we're just making all these custom for now. The functionality is simple +// and mirrors JSLocationCustom.cpp. + +static void navigateIfAllowed(Frame* frame, const KURL& url, bool lockHistory, bool lockBackForwardList) +{ + if (url.isEmpty()) + return; + + Frame* activeFrame = ScriptController::retrieveActiveFrame(); + if (!activeFrame) + return; + + if (!url.protocolIs("javascript") || ScriptController::isSafeScript(frame)) { + bool userGesture = activeFrame->script()->processingUserGesture(); + frame->loader()->scheduleLocationChange(url.string(), activeFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, userGesture); + } +} + +ACCESSOR_SETTER(LocationHash) +{ + INC_STATS("DOM.Location.hash._set"); + v8::Handle<v8::Object> holder = info.Holder(); + Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); + String hash = toWebCoreString(value); + + Frame* frame = imp->frame(); + if (!frame) + return; + + KURL url = frame->loader()->url(); + String oldRef = url.ref(); + + if (hash.startsWith("#")) + hash = hash.substring(1); + if (oldRef == hash || (oldRef.isNull() && hash.isEmpty())) + return; + url.setRef(hash); + + navigateIfAllowed(frame, url, false, false); +} + +ACCESSOR_SETTER(LocationHost) +{ + INC_STATS("DOM.Location.host._set"); + v8::Handle<v8::Object> holder = info.Holder(); + Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); + String host = toWebCoreString(value); + + Frame* frame = imp->frame(); + if (!frame) + return; + + KURL url = frame->loader()->url(); + String newHost = host.left(host.find(":")); + String newPort = host.substring(host.find(":") + 1); + url.setHost(newHost); + url.setPort(newPort.toUInt()); + + navigateIfAllowed(frame, url, false, false); +} + +ACCESSOR_SETTER(LocationHostname) +{ + INC_STATS("DOM.Location.hostname._set"); + v8::Handle<v8::Object> holder = info.Holder(); + Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); + String hostname = toWebCoreString(value); + + Frame* frame = imp->frame(); + if (!frame) + return; + + KURL url = frame->loader()->url(); + url.setHost(hostname); + + navigateIfAllowed(frame, url, false, false); +} + +ACCESSOR_SETTER(LocationHref) +{ + INC_STATS("DOM.Location.href._set"); + v8::Handle<v8::Object> holder = info.Holder(); + Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); + String href = toWebCoreString(value); + + Frame* frame = imp->frame(); + if (!frame) + return; + + Frame* activeFrame = ScriptController::retrieveActiveFrame(); + if (!activeFrame) + return; + + if (!activeFrame->loader()->shouldAllowNavigation(frame)) + return; + + navigateIfAllowed(frame, activeFrame->loader()->completeURL(href), false, false); +} + +ACCESSOR_SETTER(LocationPathname) +{ + INC_STATS("DOM.Location.pathname._set"); + v8::Handle<v8::Object> holder = info.Holder(); + Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); + String pathname = toWebCoreString(value); + + Frame* frame = imp->frame(); + if (!frame) + return; + + KURL url = frame->loader()->url(); + url.setPath(pathname); + + navigateIfAllowed(frame, url, false, false); +} + +ACCESSOR_SETTER(LocationPort) +{ + INC_STATS("DOM.Location.port._set"); + v8::Handle<v8::Object> holder = info.Holder(); + Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); + String port = toWebCoreString(value); + + Frame* frame = imp->frame(); + if (!frame) + return; + + KURL url = frame->loader()->url(); + url.setPort(port.toUInt()); + + navigateIfAllowed(frame, url, false, false); +} + +ACCESSOR_SETTER(LocationProtocol) +{ + INC_STATS("DOM.Location.protocol._set"); + v8::Handle<v8::Object> holder = info.Holder(); + Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); + String protocol = toWebCoreString(value); + + Frame* frame = imp->frame(); + if (!frame) + return; + + KURL url = frame->loader()->url(); + url.setProtocol(protocol); + + navigateIfAllowed(frame, url, false, false); +} + +ACCESSOR_SETTER(LocationSearch) +{ + INC_STATS("DOM.Location.search._set"); + v8::Handle<v8::Object> holder = info.Holder(); + Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); + String query = toWebCoreString(value); + + Frame* frame = imp->frame(); + if (!frame) + return; + + KURL url = frame->loader()->url(); + url.setQuery(query); + + navigateIfAllowed(frame, url, false, false); +} + +ACCESSOR_GETTER(LocationReload) +{ + INC_STATS("DOM.Location.reload._get"); + static v8::Persistent<v8::FunctionTemplate> privateTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(v8LocationReloadCallback, v8::Handle<v8::Value>(), v8::Signature::New(V8Location::GetRawTemplate()))); + v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::LOCATION, info.This()); + if (holder.IsEmpty()) { + // can only reach here by 'object.__proto__.func', and it should passed + // domain security check already + return privateTemplate->GetFunction(); + } + Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); + if (!V8Proxy::CanAccessFrame(imp->frame(), false)) { + static v8::Persistent<v8::FunctionTemplate> sharedTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(v8LocationReloadCallback, v8::Handle<v8::Value>(), v8::Signature::New(V8Location::GetRawTemplate()))); + return sharedTemplate->GetFunction(); + } else + return privateTemplate->GetFunction(); +} + +ACCESSOR_GETTER(LocationReplace) +{ + INC_STATS("DOM.Location.replace._get"); + static v8::Persistent<v8::FunctionTemplate> privateTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(v8LocationReplaceCallback, v8::Handle<v8::Value>(), v8::Signature::New(V8Location::GetRawTemplate()))); + v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::LOCATION, info.This()); + if (holder.IsEmpty()) { + // can only reach here by 'object.__proto__.func', and it should passed + // domain security check already + return privateTemplate->GetFunction(); + } + Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); + if (!V8Proxy::CanAccessFrame(imp->frame(), false)) { + static v8::Persistent<v8::FunctionTemplate> sharedTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(v8LocationReplaceCallback, v8::Handle<v8::Value>(), v8::Signature::New(V8Location::GetRawTemplate()))); + return sharedTemplate->GetFunction(); + } else + return privateTemplate->GetFunction(); +} + +ACCESSOR_GETTER(LocationAssign) +{ + INC_STATS("DOM.Location.assign._get"); + static v8::Persistent<v8::FunctionTemplate> privateTemplate = + v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(v8LocationAssignCallback, v8::Handle<v8::Value>(), v8::Signature::New(V8Location::GetRawTemplate()))); + v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::LOCATION, info.This()); + if (holder.IsEmpty()) { + // can only reach here by 'object.__proto__.func', and it should passed + // domain security check already + return privateTemplate->GetFunction(); + } + Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); + if (!V8Proxy::CanAccessFrame(imp->frame(), false)) { + static v8::Persistent<v8::FunctionTemplate> sharedTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(v8LocationAssignCallback, v8::Handle<v8::Value>(), v8::Signature::New(V8Location::GetRawTemplate()))); + return sharedTemplate->GetFunction(); + } else + return privateTemplate->GetFunction(); +} + +CALLBACK_FUNC_DECL(LocationReload) +{ + // FIXME: we ignore the "forceget" parameter. + + INC_STATS("DOM.Location.reload"); + v8::Handle<v8::Value> holder = args.Holder(); + Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); + + Frame* frame = imp->frame(); + if (!frame) + return v8::Undefined(); + + Frame* activeFrame = ScriptController::retrieveActiveFrame(); + if (!activeFrame) + return v8::Undefined(); + + if (!ScriptController::isSafeScript(frame)) + return v8::Undefined(); + + bool userGesture = activeFrame->script()->processingUserGesture(); + frame->loader()->scheduleRefresh(userGesture); + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(LocationReplace) +{ + INC_STATS("DOM.Location.replace"); + v8::Handle<v8::Value> holder = args.Holder(); + Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); + String url = toWebCoreString(args[0]); + + Frame* frame = imp->frame(); + if (!frame) + return v8::Undefined(); + + Frame* activeFrame = ScriptController::retrieveActiveFrame(); + if (!activeFrame) + return v8::Undefined(); + + if (!activeFrame->loader()->shouldAllowNavigation(frame)) + return v8::Undefined(); + + navigateIfAllowed(frame, activeFrame->loader()->completeURL(url), true, true); + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(LocationAssign) +{ + INC_STATS("DOM.Location.assign"); + v8::Handle<v8::Value> holder = args.Holder(); + Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); + String url = toWebCoreString(args[0]); + + Frame* frame = imp->frame(); + if (!frame) + return v8::Undefined(); + + Frame* activeFrame = ScriptController::retrieveActiveFrame(); + if (!activeFrame) + return v8::Undefined(); + + if (!activeFrame->loader()->shouldAllowNavigation(frame)) + return v8::Undefined(); + + navigateIfAllowed(frame, activeFrame->loader()->completeURL(url), false, false); + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(LocationValueOf) +{ + // Just return the this object the way the normal valueOf function + // on the Object prototype would. The valueOf function is only + // added to make sure that it cannot be overwritten on location + // objects, since that would provide a hook to change the string + // conversion behavior of location objects. + return args.This(); +} + +CALLBACK_FUNC_DECL(LocationToString) +{ + INC_STATS("DOM.Location.toString"); + v8::Handle<v8::Value> holder = args.Holder(); + Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); + if (!V8Proxy::CanAccessFrame(imp->frame(), true)) + return v8::Undefined(); + String result = imp->href(); + return v8String(result); +} + +INDEXED_ACCESS_CHECK(Location) +{ + ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::LOCATION); + // Only allow same origin access + Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, host); + return V8Proxy::CanAccessFrame(imp->frame(), false); +} + +NAMED_ACCESS_CHECK(Location) +{ + ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::LOCATION); + // Only allow same origin access + Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, host); + return V8Proxy::CanAccessFrame(imp->frame(), false); +} + +} // namespace WebCore + diff --git a/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp b/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp new file mode 100644 index 0000000..3a41467 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp @@ -0,0 +1,77 @@ +/* + * 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 "MessageChannel.h" + +#include "Document.h" +#include "Frame.h" + +#include "V8Binding.h" +#include "V8Proxy.h" + +#include <wtf/RefPtr.h> + +namespace WebCore { + +CALLBACK_FUNC_DECL(MessageChannelConstructor) +{ + INC_STATS("DOM.MessageChannel.Constructor"); + // FIXME: The logic here is almost exact duplicate of V8::ConstructDOMObject. + // Consider refactoring to reduce duplication. + if (!args.IsConstructCall()) + return throwError("DOM object constructor cannot be called as a function."); + + // Get the document. + Frame* frame = V8Proxy::retrieveFrame(); + if (!frame) + return v8::Undefined(); + + Document* document = frame->document(); + + // Note: it's OK to let this RefPtr go out of scope because we also call + // SetDOMWrapper(), which effectively holds a reference to obj. + RefPtr<MessageChannel> obj = MessageChannel::create(document); + + v8::Local<v8::Object> messageChannel = args.Holder(); + + // Create references from the MessageChannel wrapper to the two + // MessagePort wrappers to make sure that the MessagePort wrappers + // stay alive as long as the MessageChannel wrapper is around. + messageChannel->SetInternalField(kMessageChannelPort1Index, V8Proxy::ToV8Object(V8ClassIndex::MESSAGEPORT, obj->port1())); + messageChannel->SetInternalField(kMessageChannelPort2Index, V8Proxy::ToV8Object(V8ClassIndex::MESSAGEPORT, obj->port2())); + + // Setup the standard wrapper object internal fields. + V8Proxy::SetDOMWrapper(messageChannel, V8ClassIndex::MESSAGECHANNEL, obj.get()); + return toV8(obj.release(), messageChannel); +} + + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp b/WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp new file mode 100644 index 0000000..8e529cc --- /dev/null +++ b/WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2007-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 "NamedNodeMap.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +#include <wtf/RefPtr.h> + +namespace WebCore { + +INDEXED_PROPERTY_GETTER(NamedNodeMap) +{ + INC_STATS("DOM.NamedNodeMap.IndexedPropertyGetter"); + NamedNodeMap* imp = V8Proxy::ToNativeObject<NamedNodeMap>(V8ClassIndex::NAMEDNODEMAP, info.Holder()); + RefPtr<Node> result = imp->item(index); + if (!result) + return notHandledByInterceptor(); + + return V8Proxy::NodeToV8Object(result.get()); +} + +NAMED_PROPERTY_GETTER(NamedNodeMap) +{ + INC_STATS("DOM.NamedNodeMap.NamedPropertyGetter"); + // Search the prototype chain first. + v8::Handle<v8::Value> value = info.Holder()->GetRealNamedPropertyInPrototypeChain(name); + if (!value.IsEmpty()) + return value; + + // Then look for IDL defined properties on the object itself. + if (info.Holder()->HasRealNamedCallbackProperty(name)) + return notHandledByInterceptor(); + + // Finally, search the DOM. + NamedNodeMap* imp = V8Proxy::ToNativeObject<NamedNodeMap>(V8ClassIndex::NAMEDNODEMAP, info.Holder()); + RefPtr<Node> result = imp->getNamedItem(toWebCoreString(name)); + if (!result) + return notHandledByInterceptor(); + + return V8Proxy::NodeToV8Object(result.get()); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8NamedNodesCollection.cpp b/WebCore/bindings/v8/custom/V8NamedNodesCollection.cpp new file mode 100644 index 0000000..0723498 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8NamedNodesCollection.cpp @@ -0,0 +1,55 @@ +// Copyright (c) 2008, 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 "V8NamedNodesCollection.h" + +#include "Element.h" +#include "NamedAttrMap.h" + +namespace WebCore { + +Node* V8NamedNodesCollection::item(unsigned index) const +{ + if (index < m_nodes.size()) + return m_nodes[index].get(); + return 0; +} + +Node* V8NamedNodesCollection::itemWithName(const AtomicString& id) const +{ + for (unsigned i = 0; i < m_nodes.size(); ++i) { + Node* node = m_nodes[i].get(); + if (node->hasAttributes() && node->attributes()->id() == id) + return node; + } + return 0; +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8NamedNodesCollection.h b/WebCore/bindings/v8/custom/V8NamedNodesCollection.h new file mode 100644 index 0000000..d13b7a8 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8NamedNodesCollection.h @@ -0,0 +1,55 @@ +/* +* 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 V8NamedNodesCollection_h +#define V8NamedNodesCollection_h + +#include "Node.h" +#include "NodeList.h" +#include <wtf/RefPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { + + class V8NamedNodesCollection : public NodeList { + public: + explicit V8NamedNodesCollection(const Vector<RefPtr<Node> >& nodes) + : m_nodes(nodes) { } + virtual unsigned length() const { return m_nodes.size(); } + virtual Node* item(unsigned) const; + virtual Node* itemWithName(const AtomicString&) const; + + private: + Vector<RefPtr<Node> > m_nodes; + }; + +} // namespace WebCore + +#endif // V8NamedNodesCollection_h diff --git a/WebCore/bindings/v8/custom/V8NavigatorCustom.cpp b/WebCore/bindings/v8/custom/V8NavigatorCustom.cpp new file mode 100644 index 0000000..9adfe25 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8NavigatorCustom.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2007-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 "Navigator.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +namespace WebCore { + +ACCESSOR_GETTER(NavigatorAppVersion) +{ + INC_STATS("DOM.Navigator.appVersion"); + v8::Handle<v8::Object> holder = info.Holder(); + Navigator* navigator = V8Proxy::ToNativeObject<Navigator>(V8ClassIndex::NAVIGATOR, holder); + return v8StringOrUndefined(navigator->appVersion()); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8NodeCustom.cpp b/WebCore/bindings/v8/custom/V8NodeCustom.cpp new file mode 100644 index 0000000..bf30414 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8NodeCustom.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2007-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 "Node.h" + +#include "Document.h" +#include "EventListener.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8CustomEventListener.h" +#include "V8Proxy.h" + +#include <wtf/RefPtr.h> + +namespace WebCore { + +CALLBACK_FUNC_DECL(NodeAddEventListener) +{ + INC_STATS("DOM.Node.addEventListener()"); + Node* node = V8Proxy::DOMWrapperToNode<Node>(args.Holder()); + + V8Proxy* proxy = V8Proxy::retrieve(node->document()->frame()); + if (!proxy) + return v8::Undefined(); + + RefPtr<EventListener> listener = proxy->FindOrCreateV8EventListener(args[1], false); + if (listener) { + String type = toWebCoreString(args[0]); + bool useCapture = args[2]->BooleanValue(); + node->addEventListener(type, listener, useCapture); + } + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(NodeRemoveEventListener) +{ + INC_STATS("DOM.Node.removeEventListener()"); + Node* node = V8Proxy::DOMWrapperToNode<Node>(args.Holder()); + + V8Proxy* proxy = V8Proxy::retrieve(node->document()->frame()); + // It is possbile that the owner document of the node is detached + // from the frame, return immediately in this case. + // See issue http://b/878909 + if (!proxy) + return v8::Undefined(); + + RefPtr<EventListener> listener = proxy->FindV8EventListener(args[1], false); + if (listener) { + String type = toWebCoreString(args[0]); + bool useCapture = args[2]->BooleanValue(); + node->removeEventListener(type, listener.get(), useCapture); + } + + return v8::Undefined(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8NodeFilterCustom.cpp b/WebCore/bindings/v8/custom/V8NodeFilterCustom.cpp new file mode 100644 index 0000000..8839420 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8NodeFilterCustom.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2007-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 "NodeFilter.h" + +#include "ExceptionCode.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +namespace WebCore { + +CALLBACK_FUNC_DECL(NodeFilterAcceptNode) +{ + INC_STATS("DOM.NodeFilter.acceptNode()"); + return throwError(NOT_SUPPORTED_ERR); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8NodeIteratorCustom.cpp b/WebCore/bindings/v8/custom/V8NodeIteratorCustom.cpp new file mode 100644 index 0000000..48e6b8f --- /dev/null +++ b/WebCore/bindings/v8/custom/V8NodeIteratorCustom.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2007-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 "NodeIterator.h" + +#include "ScriptState.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +static inline v8::Handle<v8::Value> toV8(PassRefPtr<Node> object, ExceptionCode ec, ScriptState* state) +{ + if (ec) + return throwError(ec); + + if (state->hadException()) + return throwError(state->exception()); + + if (!object) + return v8::Null(); + + return V8Proxy::NodeToV8Object(object.get()); +} + +CALLBACK_FUNC_DECL(NodeIteratorNextNode) +{ + INC_STATS("DOM.NodeIterator.nextNode()"); + NodeIterator* nodeIterator = V8Proxy::ToNativeObject<NodeIterator>(V8ClassIndex::NODEITERATOR, args.Holder()); + + ExceptionCode ec = 0; + ScriptState state; + RefPtr<Node> result = nodeIterator->nextNode(&state, ec); + return toV8(result.release(), ec, &state); +} + +CALLBACK_FUNC_DECL(NodeIteratorPreviousNode) +{ + INC_STATS("DOM.NodeIterator.previousNode()"); + NodeIterator* nodeIterator = V8Proxy::ToNativeObject<NodeIterator>(V8ClassIndex::NODEITERATOR, args.Holder()); + + ExceptionCode ec = 0; + ScriptState state; + RefPtr<Node> result = nodeIterator->previousNode(&state, ec); + return toV8(result.release(), ec, &state); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8NodeListCustom.cpp b/WebCore/bindings/v8/custom/V8NodeListCustom.cpp new file mode 100644 index 0000000..27a47f5 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8NodeListCustom.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2007-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 "NodeList.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +#include <wtf/RefPtr.h> + +namespace WebCore { + +NAMED_PROPERTY_GETTER(NodeList) +{ + INC_STATS("DOM.NodeList.NamedPropertyGetter"); + NodeList* list = V8Proxy::ToNativeObject<NodeList>(V8ClassIndex::NODELIST, info.Holder()); + String key = toWebCoreString(name); + + // Length property cannot be overridden. + if (key == "length") + return v8::Number::New(list->length()); + + RefPtr<Node> result = list->itemWithName(key); + if (!result) + return notHandledByInterceptor(); + + return V8Proxy::NodeToV8Object(result.get()); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp b/WebCore/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp new file mode 100644 index 0000000..66585be --- /dev/null +++ b/WebCore/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp @@ -0,0 +1,90 @@ +/* + * 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 "v8_binding.h" +#include "v8_custom.h" +#include "v8_proxy.h" + +#include "SQLResultSetRowList.h" + +namespace WebCore { + +CALLBACK_FUNC_DECL(SQLResultSetRowListItem) +{ + INC_STATS("DOM.SQLResultSetRowList.item()"); + + if (args.Length() == 0) { + V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Item index is required."); + return v8::Undefined(); + } + + if (!args[0]->IsNumber()) { + V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, "Item index must be a number."); + return v8::Undefined(); + } + + SQLResultSetRowList* rowList = V8Proxy::ToNativeObject<SQLResultSetRowList>(V8ClassIndex::SQLRESULTSETROWLIST, args.Holder()); + + unsigned long index = args[0]->IntegerValue(); + if (index < 0 || index >= rowList->length()) { + V8Proxy::ThrowError(V8Proxy::RANGE_ERROR, "Item index is out of range."); + return v8::Undefined(); + } + + v8::Local<v8::Object> item = v8::Object::New(); + unsigned numColumns = rowList->columnNames().size(); + unsigned valuesIndex = index * numColumns; + + for (unsigned i = 0; i < numColumns; ++i) { + const SQLValue& sqlValue = rowList->values()[valuesIndex + i]; + v8::Handle<v8::Value> value; + switch(sqlValue.type()) { + case SQLValue::StringValue: + value = v8String(sqlValue.string()); + break; + case SQLValue::NullValue: + value = v8::Null(); + break; + case SQLValue::NumberValue: + value = v8::Number::New(sqlValue.number()); + break; + default: + ASSERT_NOT_REACHED(); + } + + item->Set(v8String(rowList->columnNames()[i]), value, static_cast<v8::PropertyAttribute>(v8::DontDelete|v8::ReadOnly)); + } + + return item; +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8SQLTransactionCustom.cpp b/WebCore/bindings/v8/custom/V8SQLTransactionCustom.cpp new file mode 100644 index 0000000..3ca797c --- /dev/null +++ b/WebCore/bindings/v8/custom/V8SQLTransactionCustom.cpp @@ -0,0 +1,114 @@ +/* + * 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 "v8_binding.h" +#include "v8_custom.h" +#include "v8_proxy.h" + +#include "Database.h" +#include "SQLValue.h" +#include "V8CustomSQLStatementCallback.h" +#include "V8CustomSQLStatementErrorCallback.h" +#include <wtf/Vector.h> + +using namespace WTF; + +namespace WebCore { + +CALLBACK_FUNC_DECL(SQLTransactionExecuteSql) +{ + INC_STATS("DOM.SQLTransaction.executeSql()"); + + if (args.Length() == 0) { + V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "SQL statement is required."); + return v8::Undefined(); + } + + String statement = ToWebCoreString(args[0]); + + Vector<SQLValue> sqlValues; + + if (args.Length() > 1) { + // FIXME: Make this work for v8::Arrayish objects, as well + if (!args[1]->IsArray()) { + V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, "Statement arguments must be an v8::Array."); + return v8::Undefined(); + } + + v8::Local<v8::Array> arguments = v8::Local<v8::Array>::Cast(args[1]); + uint32_t length = arguments->Length(); + + for (unsigned int i = 0; i < length; ++i) { + v8::Local<v8::Value> value = arguments->Get(v8::Integer::New(i)); + if (value.IsEmpty() || value->IsNull()) + sqlValues.append(SQLValue()); + else if (value->IsNumber()) + sqlValues.append(SQLValue(value->NumberValue())); + else + sqlValues.append(SQLValue(ToWebCoreString(value))); + } + } + + SQLTransaction* transaction = V8Proxy::ToNativeObject<SQLTransaction>(V8ClassIndex::SQLTRANSACTION, args.Holder()); + + Frame* frame = V8Proxy::retrieveFrame(); + + RefPtr<SQLStatementCallback> callback; + if (args.Length() > 2) { + if (!args[2]->IsObject()) { + V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, "Statement callback must be of valid type."); + return v8::Undefined(); + } + + if (frame) + callback = V8CustomSQLStatementCallback::create(args[2], frame); + } + + RefPtr<SQLStatementErrorCallback> errorCallback; + if (args.Length() > 3) { + if (!args[2]->IsObject()) { + V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, "Statement error callback must be of valid type."); + return v8::Undefined(); + } + + if (frame) + errorCallback = V8CustomSQLStatementErrorCallback::create(args[3], frame); + } + + ExceptionCode ec = 0; + transaction->executeSQL(statement, sqlValues, callback, errorCallback, ec); + V8Proxy::SetDOMException(ec); + + return v8::Undefined(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp b/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp new file mode 100644 index 0000000..351b030 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp @@ -0,0 +1,87 @@ +/* + * 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> + +#if ENABLE(SVG) + +#include "SVGElementInstance.h" + +#include "EventListener.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8CustomEventListener.h" +#include "V8SVGPODTypeWrapper.h" +#include "V8Proxy.h" + +namespace WebCore { + +CALLBACK_FUNC_DECL(SVGElementInstanceAddEventListener) +{ + INC_STATS("DOM.SVGElementInstance.AddEventListener()"); + SVGElementInstance* instance = V8Proxy::DOMWrapperToNative<SVGElementInstance>(args.Holder()); + + V8Proxy* proxy = V8Proxy::retrieve(instance->scriptExecutionContext()); + if (!proxy) + return v8::Undefined(); + + RefPtr<EventListener> listener = proxy->FindOrCreateV8EventListener(args[1], false); + if (listener) { + String type = toWebCoreString(args[0]); + bool useCapture = args[2]->BooleanValue(); + instance->addEventListener(type, listener, useCapture); + } + + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(SVGElementInstanceRemoveEventListener) +{ + INC_STATS("DOM.SVGElementInstance.RemoveEventListener()"); + SVGElementInstance* instance = V8Proxy::DOMWrapperToNative<SVGElementInstance>(args.Holder()); + + V8Proxy* proxy = V8Proxy::retrieve(instance->scriptExecutionContext()); + if (!proxy) + return v8::Undefined(); + + RefPtr<EventListener> listener = proxy->FindV8EventListener(args[1], false); + if (listener) { + String type = toWebCoreString(args[0]); + bool useCapture = args[2]->BooleanValue(); + instance->removeEventListener(type, listener.get(), useCapture); + } + + return v8::Undefined(); +} + +} // namespace WebCore + +#endif diff --git a/WebCore/bindings/v8/custom/V8SVGLengthCustom.cpp b/WebCore/bindings/v8/custom/V8SVGLengthCustom.cpp new file mode 100644 index 0000000..a2a4d49 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8SVGLengthCustom.cpp @@ -0,0 +1,65 @@ +/* + * 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> + +#if ENABLE(SVG) + +#include "SVGLength.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8SVGPODTypeWrapper.h" +#include "V8Proxy.h" + +namespace WebCore { + +ACCESSOR_GETTER(SVGLengthValue) +{ + INC_STATS("DOM.SVGLength.value"); + V8SVGPODTypeWrapper<SVGLength>* wrapper = V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<SVGLength> >(V8ClassIndex::SVGLENGTH, info.Holder()); + SVGLength imp = *wrapper; + return v8::Number::New(imp.value(V8Proxy::GetSVGContext(wrapper))); +} + +CALLBACK_FUNC_DECL(SVGLengthConvertToSpecifiedUnits) +{ + INC_STATS("DOM.SVGLength.convertToSpecifiedUnits"); + V8SVGPODTypeWrapper<SVGLength>* wrapper = V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<SVGLength> >(V8ClassIndex::SVGLENGTH, args.Holder()); + SVGLength imp = *wrapper; + SVGElement* context = V8Proxy::GetSVGContext(wrapper); + imp.convertToSpecifiedUnits(toInt32(args[0]), context); + wrapper->commitChange(imp, context); + return v8::Undefined(); +} + +} // namespace WebCore + +#endif diff --git a/WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp b/WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp new file mode 100644 index 0000000..b69202b --- /dev/null +++ b/WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp @@ -0,0 +1,86 @@ +/* + * 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> + +#if ENABLE(SVG) + +#include "TransformationMatrix.h" + +#include "SVGException.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8SVGPODTypeWrapper.h" +#include "V8Proxy.h" + +namespace WebCore { + +CALLBACK_FUNC_DECL(SVGMatrixInverse) +{ + INC_STATS("DOM.SVGMatrix.inverse()"); + TransformationMatrix matrix = *V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<TransformationMatrix> >(V8ClassIndex::SVGMATRIX, args.Holder()); + ExceptionCode ec = 0; + TransformationMatrix result = matrix.inverse(); + + if (!matrix.isInvertible()) + ec = SVGException::SVG_MATRIX_NOT_INVERTABLE; + + if (ec != 0) { + V8Proxy::SetDOMException(ec); + return v8::Handle<v8::Value>(); + } + + return V8Proxy::ToV8Object(V8ClassIndex::SVGMATRIX, new V8SVGStaticPODTypeWrapper<TransformationMatrix>(result)); +} + +CALLBACK_FUNC_DECL(SVGMatrixRotateFromVector) +{ + INC_STATS("DOM.SVGMatrix.rotateFromVector()"); + TransformationMatrix matrix = *V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<TransformationMatrix> >(V8ClassIndex::SVGMATRIX, args.Holder()); + ExceptionCode ec = 0; + float x = toFloat(args[0]); + float y = toFloat(args[1]); + TransformationMatrix result = matrix; + result.rotateFromVector(x, y); + if (x == 0.0 || y == 0.0) + ec = SVGException::SVG_INVALID_VALUE_ERR; + + if (ec != 0) { + V8Proxy::SetDOMException(ec); + return v8::Handle<v8::Value>(); + } + + return V8Proxy::ToV8Object(V8ClassIndex::SVGMATRIX, new V8SVGStaticPODTypeWrapper<TransformationMatrix>(result)); +} + +} // namespace WebCore + +#endif diff --git a/WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp b/WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp new file mode 100644 index 0000000..a362ce5 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2007-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 "StyleSheetList.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +namespace WebCore { + +NAMED_PROPERTY_GETTER(StyleSheetList) +{ + INC_STATS("DOM.StyleSheetList.NamedPropertyGetter"); + + if (info.Holder()->HasRealNamedProperty(name)) + return notHandledByInterceptor(); + + // Search style sheet. + StyleSheetList* imp = V8Proxy::ToNativeObject<StyleSheetList>(V8ClassIndex::STYLESHEETLIST, info.Holder()); + HTMLStyleElement* item = imp->getNamedItem(toWebCoreString(name)); + if (!item) + return notHandledByInterceptor(); + + return V8Proxy::ToV8Object(V8ClassIndex::HTMLSTYLEELEMENT, item); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8TreeWalkerCustom.cpp b/WebCore/bindings/v8/custom/V8TreeWalkerCustom.cpp new file mode 100644 index 0000000..baf49c0 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8TreeWalkerCustom.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2007-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 "TreeWalker.h" + +#include "Node.h" +#include "ScriptState.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +static inline v8::Handle<v8::Value> toV8(PassRefPtr<Node> object, ScriptState* state) +{ + if (state->hadException()) + return throwError(state->exception()); + + if (!object) + return v8::Null(); + + return V8Proxy::NodeToV8Object(object.get()); +} + +CALLBACK_FUNC_DECL(TreeWalkerParentNode) +{ + INC_STATS("DOM.TreeWalker.parentNode()"); + TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder()); + + ScriptState state; + RefPtr<Node> result = treeWalker->parentNode(&state); + return toV8(result.release(), &state); +} + +CALLBACK_FUNC_DECL(TreeWalkerFirstChild) +{ + INC_STATS("DOM.TreeWalker.firstChild()"); + TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder()); + + ScriptState state; + RefPtr<Node> result = treeWalker->firstChild(&state); + return toV8(result.release(), &state); +} + +CALLBACK_FUNC_DECL(TreeWalkerLastChild) +{ + INC_STATS("DOM.TreeWalker.lastChild()"); + TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder()); + + ScriptState state; + RefPtr<Node> result = treeWalker->lastChild(&state); + return toV8(result.release(), &state); +} + +CALLBACK_FUNC_DECL(TreeWalkerNextNode) +{ + INC_STATS("DOM.TreeWalker.nextNode()"); + TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder()); + + ScriptState state; + RefPtr<Node> result = treeWalker->nextNode(&state); + return toV8(result.release(), &state); +} + +CALLBACK_FUNC_DECL(TreeWalkerPreviousNode) +{ + INC_STATS("DOM.TreeWalker.previousNode()"); + TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder()); + + ScriptState state; + RefPtr<Node> result = treeWalker->previousNode(&state); + return toV8(result.release(), &state); +} + +CALLBACK_FUNC_DECL(TreeWalkerNextSibling) +{ + INC_STATS("DOM.TreeWalker.nextSibling()"); + TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder()); + + ScriptState state; + RefPtr<Node> result = treeWalker->nextSibling(&state); + return toV8(result.release(), &state); +} + +CALLBACK_FUNC_DECL(TreeWalkerPreviousSibling) +{ + INC_STATS("DOM.TreeWalker.previousSibling()"); + TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder()); + + ScriptState state; + RefPtr<Node> result = treeWalker->previousSibling(&state); + return toV8(result.release(), &state); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp b/WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp new file mode 100644 index 0000000..b07d288 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp @@ -0,0 +1,66 @@ +/* + * 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 "WebKitCSSMatrix.h" + +#include "Document.h" +#include "DocumentFragment.h" +#include "Node.h" + +#include "V8Binding.h" +#include "V8Document.h" +#include "V8Node.h" +#include "V8Proxy.h" + +#include <wtf/RefPtr.h> + +namespace WebCore { + +CALLBACK_FUNC_DECL(WebKitCSSMatrixConstructor) +{ + INC_STATS("DOM.WebKitCSSMatrix.Constructor"); + // FIXME: The logic here is almost exact duplicate of V8::ConstructDOMObject. + // Consider refactoring to reduce duplication. + String cssValue; + if (args.Length() >= 1) + cssValue = toWebCoreString(args[0]); + + ExceptionCode ec = 0; + RefPtr<WebKitCSSMatrix> matrix = WebKitCSSMatrix::create(cssValue, ec); + if (ec) + throwError(ec); + + // Transform the holder into a wrapper object for the matrix. + V8Proxy::SetDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::WEBKITCSSMATRIX), matrix.get()); + return toV8(matrix.release(), args.Holder()); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp new file mode 100644 index 0000000..6b55238 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2008, 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 "Frame.h" +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8ObjectEventListener.h" +#include "V8Proxy.h" +#include "XMLHttpRequest.h" + +namespace WebCore { + +CALLBACK_FUNC_DECL(XMLHttpRequestConstructor) +{ + INC_STATS("DOM.XMLHttpRequest.Constructor"); + + if (!args.IsConstructCall()) + return throwError("DOM object constructor cannot be called as a function.", V8Proxy::TYPE_ERROR); + + // Expect no parameters. + // Allocate a XMLHttpRequest object as its internal field. + Document* doc = V8Proxy::retrieveFrame()->document(); + RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(doc); + V8Proxy::SetDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::XMLHTTPREQUEST), xmlHttpRequest.get()); + + // Add object to the wrapper map. + xmlHttpRequest->ref(); + V8Proxy::SetJSWrapperForActiveDOMObject(xmlHttpRequest.get(), v8::Persistent<v8::Object>::New(args.Holder())); + return args.Holder(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp new file mode 100644 index 0000000..ea69f0b --- /dev/null +++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp @@ -0,0 +1,444 @@ +/* + * Copyright (C) 2008, 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 "XMLHttpRequest.h" + +#include "Frame.h" +#include "V8Binding.h" +#include "V8Document.h" +#include "V8CustomBinding.h" +#include "V8HTMLDocument.h" +#include "V8ObjectEventListener.h" +#include "V8Proxy.h" +#include "V8XMLHttpRequestUtilities.h" + +namespace WebCore { + +ACCESSOR_GETTER(XMLHttpRequestOnabort) +{ + INC_STATS("DOM.XMLHttpRequest.onabort._get"); + XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder()); + if (xmlHttpRequest->onabort()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onabort()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + return v8Listener; + } + return v8::Undefined(); +} + +ACCESSOR_SETTER(XMLHttpRequestOnabort) +{ + INC_STATS("DOM.XMLHttpRequest.onabort._set"); + XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder()); + if (value->IsNull()) { + if (xmlHttpRequest->onabort()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onabort()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + removeHiddenXHRDependency(info.Holder(), v8Listener); + } + + // Clear the listener. + xmlHttpRequest->setOnabort(0); + } else { + V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); + if (!proxy) + return; + + RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); + if (listener) { + xmlHttpRequest->setOnabort(listener); + createHiddenXHRDependency(info.Holder(), value); + } + } +} + +ACCESSOR_GETTER(XMLHttpRequestOnerror) +{ + INC_STATS("DOM.XMLHttpRequest.onerror._get"); + XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder()); + if (xmlHttpRequest->onerror()) { + RefPtr<V8ObjectEventListener> listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onerror()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + return v8Listener; + } + return v8::Undefined(); +} + +ACCESSOR_SETTER(XMLHttpRequestOnerror) +{ + INC_STATS("DOM.XMLHttpRequest.onerror._set"); + XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder()); + if (value->IsNull()) { + if (xmlHttpRequest->onerror()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onerror()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + removeHiddenXHRDependency(info.Holder(), v8Listener); + } + + // Clear the listener. + xmlHttpRequest->setOnerror(0); + } else { + V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); + if (!proxy) + return; + + RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); + if (listener) { + xmlHttpRequest->setOnerror(listener); + createHiddenXHRDependency(info.Holder(), value); + } + } +} + +ACCESSOR_GETTER(XMLHttpRequestOnload) +{ + INC_STATS("DOM.XMLHttpRequest.onload._get"); + XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder()); + if (xmlHttpRequest->onload()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onload()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + return v8Listener; + } + return v8::Undefined(); +} + +ACCESSOR_SETTER(XMLHttpRequestOnload) +{ + INC_STATS("DOM.XMLHttpRequest.onload._set"); + XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder()); + if (value->IsNull()) { + if (xmlHttpRequest->onload()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onload()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + removeHiddenXHRDependency(info.Holder(), v8Listener); + } + + xmlHttpRequest->setOnload(0); + + } else { + V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); + if (!proxy) + return; + + RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); + if (listener) { + xmlHttpRequest->setOnload(listener.get()); + createHiddenXHRDependency(info.Holder(), value); + } + } +} + +ACCESSOR_GETTER(XMLHttpRequestOnloadstart) +{ + INC_STATS("DOM.XMLHttpRequest.onloadstart._get"); + XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder()); + if (xmlHttpRequest->onloadstart()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onloadstart()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + return v8Listener; + } + return v8::Undefined(); +} + +ACCESSOR_SETTER(XMLHttpRequestOnloadstart) +{ + INC_STATS("DOM.XMLHttpRequest.onloadstart._set"); + XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder()); + if (value->IsNull()) { + if (xmlHttpRequest->onloadstart()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onloadstart()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + removeHiddenXHRDependency(info.Holder(), v8Listener); + } + + // Clear the listener. + xmlHttpRequest->setOnloadstart(0); + } else { + V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); + if (!proxy) + return; + + RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); + if (listener) { + xmlHttpRequest->setOnloadstart(listener); + createHiddenXHRDependency(info.Holder(), value); + } + } +} + +ACCESSOR_GETTER(XMLHttpRequestOnprogress) +{ + INC_STATS("DOM.XMLHttpRequest.onprogress._get"); + XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder()); + if (xmlHttpRequest->onprogress()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onprogress()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + return v8Listener; + } + return v8::Undefined(); +} + +ACCESSOR_SETTER(XMLHttpRequestOnprogress) +{ + INC_STATS("DOM.XMLHttpRequest.onprogress._set"); + XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder()); + if (value->IsNull()) { + if (xmlHttpRequest->onprogress()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onprogress()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + removeHiddenXHRDependency(info.Holder(), v8Listener); + } + + // Clear the listener. + xmlHttpRequest->setOnprogress(0); + } else { + V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); + if (!proxy) + return; + + RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); + if (listener) { + xmlHttpRequest->setOnprogress(listener); + createHiddenXHRDependency(info.Holder(), value); + } + } +} + +ACCESSOR_GETTER(XMLHttpRequestOnreadystatechange) +{ + INC_STATS("DOM.XMLHttpRequest.onreadystatechange._get"); + XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder()); + if (xmlHttpRequest->onreadystatechange()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onreadystatechange()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + return v8Listener; + } + return v8::Undefined(); +} + +ACCESSOR_SETTER(XMLHttpRequestOnreadystatechange) +{ + INC_STATS("DOM.XMLHttpRequest.onreadystatechange._set"); + XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder()); + if (value->IsNull()) { + if (xmlHttpRequest->onreadystatechange()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onreadystatechange()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + removeHiddenXHRDependency(info.Holder(), v8Listener); + } + + // Clear the listener. + xmlHttpRequest->setOnreadystatechange(0); + } else { + V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); + if (!proxy) + return; + + RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); + if (listener) { + xmlHttpRequest->setOnreadystatechange(listener.get()); + createHiddenXHRDependency(info.Holder(), value); + } + } +} + +ACCESSOR_GETTER(XMLHttpRequestResponseText) +{ + // FIXME: This is only needed because webkit set this getter as custom. + // So we need a custom method to avoid forking the IDL file. + INC_STATS("DOM.XMLHttpRequest.responsetext._get"); + XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder()); + return v8StringOrNull(xmlHttpRequest->responseText()); +} + +CALLBACK_FUNC_DECL(XMLHttpRequestAddEventListener) +{ + INC_STATS("DOM.XMLHttpRequest.addEventListener()"); + XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder()); + + V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); + if (!proxy) + return v8::Undefined(); + + RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(args[1], false); + if (listener) { + String type = toWebCoreString(args[0]); + bool useCapture = args[2]->BooleanValue(); + xmlHttpRequest->addEventListener(type, listener, useCapture); + + createHiddenXHRDependency(args.Holder(), args[1]); + } + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(XMLHttpRequestRemoveEventListener) +{ + INC_STATS("DOM.XMLHttpRequest.removeEventListener()"); + XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder()); + + V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); + if (!proxy) + return v8::Undefined(); // Probably leaked. + + RefPtr<EventListener> listener = proxy->FindObjectEventListener(args[1], false); + + if (listener) { + String type = toWebCoreString(args[0]); + bool useCapture = args[2]->BooleanValue(); + xmlHttpRequest->removeEventListener(type, listener.get(), useCapture); + + removeHiddenXHRDependency(args.Holder(), args[1]); + } + + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(XMLHttpRequestOpen) +{ + INC_STATS("DOM.XMLHttpRequest.open()"); + // Four cases: + // open(method, url) + // open(method, url, async) + // open(method, url, async, user) + // open(method, url, async, user, passwd) + + if (args.Length() < 2) + return throwError("Not enough arguments", V8Proxy::SYNTAX_ERROR); + + XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder()); + + String method = toWebCoreString(args[0]); + String urlstring = toWebCoreString(args[1]); + V8Proxy* proxy = V8Proxy::retrieve(); + KURL url = proxy->frame()->document()->completeURL(urlstring); + + bool async = (args.Length() < 3) ? true : args[2]->BooleanValue(); + + ExceptionCode ec = 0; + String user, passwd; + if (args.Length() >= 4 && !args[3]->IsUndefined()) { + user = valueToStringWithNullCheck(args[3]); + + if (args.Length() >= 5 && !args[4]->IsUndefined()) { + passwd = valueToStringWithNullCheck(args[4]); + xmlHttpRequest->open(method, url, async, user, passwd, ec); + } else + xmlHttpRequest->open(method, url, async, user, ec); + } else + xmlHttpRequest->open(method, url, async, ec); + + if (ec) + return throwError(ec); + + return v8::Undefined(); +} + +static bool IsDocumentType(v8::Handle<v8::Value> value) +{ + // FIXME: add other document types. + return V8Document::HasInstance(value) || V8HTMLDocument::HasInstance(value); +} + +CALLBACK_FUNC_DECL(XMLHttpRequestSend) +{ + INC_STATS("DOM.XMLHttpRequest.send()"); + XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder()); + + ExceptionCode ec = 0; + if (args.Length() < 1) + xmlHttpRequest->send(ec); + else { + v8::Handle<v8::Value> arg = args[0]; + // FIXME: upstream handles "File" objects too. + if (IsDocumentType(arg)) { + v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg); + Document* document = V8Proxy::DOMWrapperToNode<Document>(object); + ASSERT(document); + xmlHttpRequest->send(document, ec); + } else + xmlHttpRequest->send(valueToStringWithNullCheck(arg), ec); + } + + if (ec) + return throwError(ec); + + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(XMLHttpRequestSetRequestHeader) { + INC_STATS("DOM.XMLHttpRequest.setRequestHeader()"); + if (args.Length() < 2) + return throwError("Not enough arguments", V8Proxy::SYNTAX_ERROR); + + XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder()); + ExceptionCode ec = 0; + String header = toWebCoreString(args[0]); + String value = toWebCoreString(args[1]); + xmlHttpRequest->setRequestHeader(header, value, ec); + if (ec) + return throwError(ec); + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(XMLHttpRequestGetResponseHeader) +{ + INC_STATS("DOM.XMLHttpRequest.getResponseHeader()"); + if (args.Length() < 1) + return throwError("Not enough arguments", V8Proxy::SYNTAX_ERROR); + + XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder()); + ExceptionCode ec = 0; + String header = toWebCoreString(args[0]); + String result = xmlHttpRequest->getResponseHeader(header, ec); + if (ec) + return throwError(ec); + return v8StringOrNull(result); +} + +CALLBACK_FUNC_DECL(XMLHttpRequestOverrideMimeType) +{ + INC_STATS("DOM.XMLHttpRequest.overrideMimeType()"); + if (args.Length() < 1) + return throwError("Not enough arguments", V8Proxy::SYNTAX_ERROR); + + XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder()); + String value = toWebCoreString(args[0]); + xmlHttpRequest->overrideMimeType(value); + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(XMLHttpRequestDispatchEvent) +{ + INC_STATS("DOM.XMLHttpRequest.dispatchEvent()"); + return v8::Undefined(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp new file mode 100644 index 0000000..7ffad82 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2008, 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 "XMLHttpRequestUpload.h" + +#include "ExceptionCode.h" +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8ObjectEventListener.h" +#include "V8Proxy.h" +#include "V8XMLHttpRequestUtilities.h" +#include "XMLHttpRequest.h" + +#include <wtf/Assertions.h> + +namespace WebCore { + +ACCESSOR_GETTER(XMLHttpRequestUploadOnabort) +{ + INC_STATS("DOM.XMLHttpRequestUpload.onabort._get"); + XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder()); + if (xmlHttpRequestUpload->onabort()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onabort()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + return v8Listener; + } + return v8::Undefined(); +} + +ACCESSOR_SETTER(XMLHttpRequestUploadOnabort) +{ + INC_STATS("DOM.XMLHttpRequestUpload.onabort._set"); + XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder()); + if (value->IsNull()) { + if (xmlHttpRequestUpload->onabort()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onabort()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + removeHiddenXHRDependency(info.Holder(), v8Listener); + } + + // Clear the listener. + xmlHttpRequestUpload->setOnabort(0); + } else { + XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest(); + V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); + if (!proxy) + return; + + RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); + if (listener) { + xmlHttpRequestUpload->setOnabort(listener); + createHiddenXHRDependency(info.Holder(), value); + } + } +} + +ACCESSOR_GETTER(XMLHttpRequestUploadOnerror) +{ + INC_STATS("DOM.XMLHttpRequestUpload.onerror._get"); + XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder()); + if (xmlHttpRequestUpload->onerror()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onerror()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + return v8Listener; + } + return v8::Undefined(); +} + +ACCESSOR_SETTER(XMLHttpRequestUploadOnerror) +{ + INC_STATS("DOM.XMLHttpRequestUpload.onerror._set"); + XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder()); + if (value->IsNull()) { + if (xmlHttpRequestUpload->onerror()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onerror()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + removeHiddenXHRDependency(info.Holder(), v8Listener); + } + + // Clear the listener. + xmlHttpRequestUpload->setOnerror(0); + } else { + XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest(); + V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); + if (!proxy) + return; + + RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); + if (listener) { + xmlHttpRequestUpload->setOnerror(listener); + createHiddenXHRDependency(info.Holder(), value); + } + } +} + +ACCESSOR_GETTER(XMLHttpRequestUploadOnload) +{ + INC_STATS("DOM.XMLHttpRequestUpload.onload._get"); + XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder()); + if (xmlHttpRequestUpload->onload()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onload()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + return v8Listener; + } + return v8::Undefined(); +} + +ACCESSOR_SETTER(XMLHttpRequestUploadOnload) +{ + INC_STATS("DOM.XMLHttpRequestUpload.onload._set"); + XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder()); + if (value->IsNull()) { + if (xmlHttpRequestUpload->onload()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onload()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + removeHiddenXHRDependency(info.Holder(), v8Listener); + } + + // Clear the listener. + xmlHttpRequestUpload->setOnload(0); + } else { + XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest(); + V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); + if (!proxy) + return; + + RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); + if (listener) { + xmlHttpRequestUpload->setOnload(listener); + createHiddenXHRDependency(info.Holder(), value); + } + } +} + +ACCESSOR_GETTER(XMLHttpRequestUploadOnloadstart) +{ + INC_STATS("DOM.XMLHttpRequestUpload.onloadstart._get"); + XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder()); + if (xmlHttpRequestUpload->onloadstart()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onloadstart()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + return v8Listener; + } + return v8::Undefined(); +} + +ACCESSOR_SETTER(XMLHttpRequestUploadOnloadstart) +{ + INC_STATS("DOM.XMLHttpRequestUpload.onloadstart._set"); + XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder()); + if (value->IsNull()) { + if (xmlHttpRequestUpload->onloadstart()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onloadstart()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + removeHiddenXHRDependency(info.Holder(), v8Listener); + } + + // Clear the listener. + xmlHttpRequestUpload->setOnloadstart(0); + } else { + XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest(); + V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); + if (!proxy) + return; + + RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); + if (listener) { + xmlHttpRequestUpload->setOnloadstart(listener); + createHiddenXHRDependency(info.Holder(), value); + } + } +} + +ACCESSOR_GETTER(XMLHttpRequestUploadOnprogress) +{ + INC_STATS("DOM.XMLHttpRequestUpload.onprogress._get"); + XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder()); + if (xmlHttpRequestUpload->onprogress()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onprogress()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + return v8Listener; + } + return v8::Undefined(); +} + +ACCESSOR_SETTER(XMLHttpRequestUploadOnprogress) +{ + INC_STATS("DOM.XMLHttpRequestUpload.onprogress._set"); + XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder()); + if (value->IsNull()) { + if (xmlHttpRequestUpload->onprogress()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onprogress()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + removeHiddenXHRDependency(info.Holder(), v8Listener); + } + + // Clear the listener. + xmlHttpRequestUpload->setOnprogress(0); + } else { + XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest(); + V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); + if (!proxy) + return; + + RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); + if (listener) { + xmlHttpRequestUpload->setOnprogress(listener); + createHiddenXHRDependency(info.Holder(), value); + } + } +} + +CALLBACK_FUNC_DECL(XMLHttpRequestUploadAddEventListener) +{ + INC_STATS("DOM.XMLHttpRequestUpload.addEventListener()"); + XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, args.Holder()); + + XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest(); + V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); + if (!proxy) + return v8::Undefined(); + + RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(args[1], false); + if (listener) { + String type = toWebCoreString(args[0]); + bool useCapture = args[2]->BooleanValue(); + xmlHttpRequestUpload->addEventListener(type, listener, useCapture); + + createHiddenXHRDependency(args.Holder(), args[1]); + } + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(XMLHttpRequestUploadRemoveEventListener) +{ + INC_STATS("DOM.XMLHttpRequestUpload.removeEventListener()"); + XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, args.Holder()); + + XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest(); + V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); + if (!proxy) + return v8::Undefined(); // Probably leaked. + + RefPtr<EventListener> listener = proxy->FindObjectEventListener(args[1], false); + + if (listener) { + String type = toWebCoreString(args[0]); + bool useCapture = args[2]->BooleanValue(); + xmlHttpRequestUpload->removeEventListener(type, listener.get(), useCapture); + + removeHiddenXHRDependency(args.Holder(), args[1]); + } + + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(XMLHttpRequestUploadDispatchEvent) +{ + INC_STATS("DOM.XMLHttpRequestUpload.dispatchEvent()"); + return throwError(NOT_SUPPORTED_ERR); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8XMLSerializerConstructor.cpp b/WebCore/bindings/v8/custom/V8XMLSerializerConstructor.cpp new file mode 100644 index 0000000..7b20293 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8XMLSerializerConstructor.cpp @@ -0,0 +1,45 @@ +/* + * 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 "XMLSerializer.h" + +#include "V8Binding.h" +#include "V8Proxy.h" + +namespace WebCore { + +CALLBACK_FUNC_DECL(XMLSerializerConstructor) +{ + INC_STATS("DOM.XMLSerializer.Constructor"); + return V8Proxy::ConstructDOMObject<V8ClassIndex::XMLSERIALIZER, XMLSerializer>(args); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8XPathEvaluatorConstructor.cpp b/WebCore/bindings/v8/custom/V8XPathEvaluatorConstructor.cpp new file mode 100644 index 0000000..84d75db --- /dev/null +++ b/WebCore/bindings/v8/custom/V8XPathEvaluatorConstructor.cpp @@ -0,0 +1,45 @@ +/* + * 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 "XPathEvaluator.h" + +#include "V8Binding.h" +#include "V8Proxy.h" + +namespace WebCore { + +CALLBACK_FUNC_DECL(XPathEvaluatorConstructor) +{ + INC_STATS("DOM.XPathEvaluator.Constructor"); + return V8Proxy::ConstructDOMObject<V8ClassIndex::XPATHEVALUATOR, XPathEvaluator>(args); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8XSLTProcessorCustom.cpp b/WebCore/bindings/v8/custom/V8XSLTProcessorCustom.cpp new file mode 100644 index 0000000..d470f84 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8XSLTProcessorCustom.cpp @@ -0,0 +1,153 @@ +/* + * 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 "XSLTProcessor.h" + +#include "Document.h" +#include "DocumentFragment.h" +#include "Node.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Document.h" +#include "V8Node.h" +#include "V8Proxy.h" + +#include <wtf/RefPtr.h> + +namespace WebCore { + +CALLBACK_FUNC_DECL(XSLTProcessorConstructor) +{ + INC_STATS("DOM.XSLTProcessor.Constructor"); + return V8Proxy::ConstructDOMObject<V8ClassIndex::XSLTPROCESSOR, XSLTProcessor>(args); +} + + +CALLBACK_FUNC_DECL(XSLTProcessorImportStylesheet) +{ + INC_STATS("DOM.XSLTProcessor.importStylesheet"); + if (!V8Node::HasInstance(args[0])) + return v8::Undefined(); + + XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder()); + + Node* node = V8Proxy::DOMWrapperToNode<Node>(args[0]); + imp->importStylesheet(node); + return v8::Undefined(); +} + + +CALLBACK_FUNC_DECL(XSLTProcessorTransformToFragment) +{ + INC_STATS("DOM.XSLTProcessor.transformToFragment"); + if (!V8Node::HasInstance(args[0]) || !V8Document::HasInstance(args[1])) + return v8::Undefined(); + + XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder()); + + Node* source = V8Proxy::DOMWrapperToNode<Node>(args[0]); + Document* owner = V8Proxy::DOMWrapperToNode<Document>(args[1]); + RefPtr<DocumentFragment> result = imp->transformToFragment(source, owner); + return V8Proxy::NodeToV8Object(result.get()); +} + + +CALLBACK_FUNC_DECL(XSLTProcessorTransformToDocument) +{ + INC_STATS("DOM.XSLTProcessor.transformToDocument"); + + if (!V8Node::HasInstance(args[0])) + return v8::Undefined(); + + XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder()); + + Node* source = V8Proxy::DOMWrapperToNode<Node>(args[0]); + if (!source) + return v8::Undefined(); + + RefPtr<Document> result = imp->transformToDocument(source); + if (!result) + return v8::Undefined(); + + return V8Proxy::NodeToV8Object(result.get()); +} + + +CALLBACK_FUNC_DECL(XSLTProcessorSetParameter) +{ + INC_STATS("DOM.XSLTProcessor.setParameter"); + if (isUndefinedOrNull(args[1]) || isUndefinedOrNull(args[2])) + return v8::Undefined(); + + XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder()); + + String namespaceURI = toWebCoreString(args[0]); + String localName = toWebCoreString(args[1]); + String value = toWebCoreString(args[2]); + imp->setParameter(namespaceURI, localName, value); + + return v8::Undefined(); +} + + +CALLBACK_FUNC_DECL(XSLTProcessorGetParameter) +{ + INC_STATS("DOM.XSLTProcessor.getParameter"); + if (isUndefinedOrNull(args[1])) + return v8::Undefined(); + + XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder()); + + String namespaceURI = toWebCoreString(args[0]); + String localName = toWebCoreString(args[1]); + String result = imp->getParameter(namespaceURI, localName); + if (result.isNull()) + return v8::Undefined(); + + return v8String(result); +} + +CALLBACK_FUNC_DECL(XSLTProcessorRemoveParameter) +{ + INC_STATS("DOM.XSLTProcessor.removeParameter"); + if (isUndefinedOrNull(args[1])) + return v8::Undefined(); + + XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder()); + + String namespaceURI = toWebCoreString(args[0]); + String localName = toWebCoreString(args[1]); + imp->removeParameter(namespaceURI, localName); + return v8::Undefined(); +} + +} // namespace WebCore |