diff options
Diffstat (limited to 'WebCore/bindings/v8')
45 files changed, 969 insertions, 281 deletions
diff --git a/WebCore/bindings/v8/DOMObjectsInclude.h b/WebCore/bindings/v8/DOMObjectsInclude.h index fb7ba81..59c6ecb 100644 --- a/WebCore/bindings/v8/DOMObjectsInclude.h +++ b/WebCore/bindings/v8/DOMObjectsInclude.h @@ -33,6 +33,7 @@ #include "BarInfo.h" #include "BeforeLoadEvent.h" +#include "CanvasActiveInfo.h" #include "CanvasArray.h" #include "CanvasArrayBuffer.h" #include "CanvasBuffer.h" diff --git a/WebCore/bindings/v8/DateExtension.cpp b/WebCore/bindings/v8/DateExtension.cpp index 778a15a..7d8b9be 100644 --- a/WebCore/bindings/v8/DateExtension.cpp +++ b/WebCore/bindings/v8/DateExtension.cpp @@ -75,7 +75,7 @@ DateExtension* DateExtension::get() void DateExtension::setAllowSleep(bool allow) { - v8::Local<v8::Value> result = V8Proxy::retrieve()->context()->Global()->Get(v8::String::New("Date")); + v8::Local<v8::Value> result = V8Proxy::currentContext()->Global()->Get(v8::String::New("Date")); if (result.IsEmpty()) return; diff --git a/WebCore/bindings/v8/DerivedSourcesAllInOne.cpp b/WebCore/bindings/v8/DerivedSourcesAllInOne.cpp index 98832f3..4aeee0c 100644 --- a/WebCore/bindings/v8/DerivedSourcesAllInOne.cpp +++ b/WebCore/bindings/v8/DerivedSourcesAllInOne.cpp @@ -34,6 +34,7 @@ #include "bindings/V8Attr.cpp" #include "bindings/V8BarInfo.cpp" #include "bindings/V8BeforeLoadEvent.cpp" +#include "bindings/V8CanvasActiveInfo.cpp" #include "bindings/V8CanvasArray.cpp" #include "bindings/V8CanvasArrayBuffer.cpp" #include "bindings/V8CanvasBuffer.cpp" @@ -253,6 +254,10 @@ #if ENABLE(SHARED_WORKERS) #include "bindings/V8SharedWorker.cpp" +<<<<<<< HEAD:WebCore/bindings/v8/DerivedSourcesAllInOne.cpp +======= +#include "bindings/V8SharedWorkerContext.cpp" +>>>>>>> webkit.org at r50258.:WebCore/bindings/v8/DerivedSourcesAllInOne.cpp #endif #if ENABLE(SVG) @@ -361,7 +366,6 @@ #include "bindings/V8SVGTRefElement.cpp" #include "bindings/V8SVGTSpanElement.cpp" #include "bindings/V8SVGUnitTypes.cpp" -#include "bindings/V8SVGURIReference.cpp" #include "bindings/V8SVGUseElement.cpp" #include "bindings/V8SVGViewElement.cpp" #include "bindings/V8SVGZoomEvent.cpp" @@ -382,6 +386,7 @@ #if ENABLE(INSPECTOR) #include "bindings/V8InspectorBackend.cpp" #endif +<<<<<<< HEAD:WebCore/bindings/v8/DerivedSourcesAllInOne.cpp #if PLATFORM(ANDROID) // TODO: Upstream NOTIFICATIONS guard. @@ -390,3 +395,5 @@ #include "bindings/V8NotificationCenter.cpp" #endif #endif +======= +>>>>>>> webkit.org at r50258.:WebCore/bindings/v8/DerivedSourcesAllInOne.cpp diff --git a/WebCore/bindings/v8/RuntimeEnabledFeatures.cpp b/WebCore/bindings/v8/RuntimeEnabledFeatures.cpp new file mode 100644 index 0000000..21293a5 --- /dev/null +++ b/WebCore/bindings/v8/RuntimeEnabledFeatures.cpp @@ -0,0 +1,40 @@ +/* + * 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 "RuntimeEnabledFeatures.h" + +namespace WebCore { + +bool RuntimeEnabledFeatures::isDatabaseEnabled = false; +bool RuntimeEnabledFeatures::isLocalStorageEnabled = true; +bool RuntimeEnabledFeatures::isSessionStorageEnabled = true; + +} // namespace WebCore diff --git a/WebCore/bindings/v8/RuntimeEnabledFeatures.h b/WebCore/bindings/v8/RuntimeEnabledFeatures.h new file mode 100644 index 0000000..fa42024 --- /dev/null +++ b/WebCore/bindings/v8/RuntimeEnabledFeatures.h @@ -0,0 +1,59 @@ +/* + * 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 RuntimeEnabledFeatures_h +#define RuntimeEnabledFeatures_h + +namespace WebCore { + +// A class that stores static enablers for all experimental features +class RuntimeEnabledFeatures { +public: + static void setDatabaseEnabled(bool isEnabled) { isDatabaseEnabled = isEnabled; } + static bool databaseEnabled() { return isDatabaseEnabled; } + + static void setLocalStorageEnabled(bool isEnabled) { isLocalStorageEnabled = isEnabled; } + static bool localStorageEnabled() { return isLocalStorageEnabled; } + + static void setSessionStorageEnabled(bool isEnabled) { isSessionStorageEnabled = isEnabled; } + static bool sessionStorageEnabled() { return isSessionStorageEnabled; } + +private: + // Never instantiate. + RuntimeEnabledFeatures() { } + + static bool isDatabaseEnabled; + static bool isLocalStorageEnabled; + static bool isSessionStorageEnabled; +}; + +} // namespace WebCore + +#endif // RuntimeEnabledFeatures_h diff --git a/WebCore/bindings/v8/ScriptCallStack.h b/WebCore/bindings/v8/ScriptCallStack.h index 9f628c8..3ba01c5 100644 --- a/WebCore/bindings/v8/ScriptCallStack.h +++ b/WebCore/bindings/v8/ScriptCallStack.h @@ -55,8 +55,8 @@ namespace WebCore { ScriptState* state() const { return m_scriptState.get(); } private: - OwnPtr<ScriptState> m_scriptState; ScriptCallFrame m_lastCaller; + OwnPtr<ScriptState> m_scriptState; }; } // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptController.cpp b/WebCore/bindings/v8/ScriptController.cpp index 85af072..b1614c6 100644 --- a/WebCore/bindings/v8/ScriptController.cpp +++ b/WebCore/bindings/v8/ScriptController.cpp @@ -102,6 +102,7 @@ void ScriptController::gcUnprotectJSWrapper(void* domObject) ScriptController::ScriptController(Frame* frame) : m_frame(frame) , m_sourceURL(0) + , m_inExecuteScript(false) , m_processingTimerCallback(false) , m_paused(false) , m_proxy(new V8Proxy(frame)) @@ -173,6 +174,9 @@ bool ScriptController::processingUserGesture() const // Based on code from kjs_bindings.cpp. // Note: This is more liberal than Firefox's implementation. if (event) { + if (event->createdByDOM()) + return false; + const AtomicString& type = event->type(); bool eventOk = // mouse events @@ -440,4 +444,10 @@ void ScriptController::updateDocument() m_proxy->updateDocument(); } +// FIXME: Stub method so we compile. Currently called from FrameLoader.cpp. +DOMWrapperWorld* mainThreadNormalWorld() +{ + return 0; +} + } // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptController.h b/WebCore/bindings/v8/ScriptController.h index ec15103..c17650a 100644 --- a/WebCore/bindings/v8/ScriptController.h +++ b/WebCore/bindings/v8/ScriptController.h @@ -42,6 +42,7 @@ #include <wtf/Vector.h> namespace WebCore { + class DOMWrapperWorld; class Event; class Frame; class HTMLPlugInElement; @@ -59,6 +60,15 @@ namespace WebCore { // or this accessor should be made JSProxy* V8Proxy* proxy() { return m_proxy.get(); } +<<<<<<< HEAD:WebCore/bindings/v8/ScriptController.h +======= + ScriptValue executeScript(const ScriptSourceCode&); + ScriptValue executeScript(const String& script, bool forceUserGesture = false); + + // Returns true if argument is a JavaScript URL. + bool executeIfJavaScriptURL(const KURL&, bool userGesture = false, bool replaceDocument = true); + +>>>>>>> webkit.org at r50258.:WebCore/bindings/v8/ScriptController.h // This function must be called from the main thread. It is safe to call it repeatedly. static void initializeThreading(); @@ -87,14 +97,11 @@ namespace WebCore { // all DOM nodes and DOM constructors. void evaluateInNewContext(const Vector<ScriptSourceCode>&, int extensionGroup); - // JSC has a WindowShell object, but for V8, the ScriptController - // is the WindowShell. - bool haveWindowShell() const { return true; } - // Masquerade 'this' as the windowShell. // This is a bit of a hack, but provides reasonable compatibility // with what JSC does as well. - ScriptController* windowShell() { return this; } + ScriptController* windowShell(DOMWrapperWorld*) { return this; } + ScriptController* existingWindowShell(DOMWrapperWorld*) { return this; } XSSAuditor* xssAuditor() { return m_XSSAuditor.get(); } @@ -165,6 +172,8 @@ namespace WebCore { Frame* m_frame; const String* m_sourceURL; + bool m_inExecuteScript; + bool m_processingTimerCallback; bool m_paused; @@ -183,6 +192,8 @@ namespace WebCore { OwnPtr<XSSAuditor> m_XSSAuditor; }; + DOMWrapperWorld* mainThreadNormalWorld(); + } // namespace WebCore #endif // ScriptController_h diff --git a/WebCore/bindings/v8/ScriptEventListener.cpp b/WebCore/bindings/v8/ScriptEventListener.cpp index 16ca70f..03713be 100644 --- a/WebCore/bindings/v8/ScriptEventListener.cpp +++ b/WebCore/bindings/v8/ScriptEventListener.cpp @@ -36,6 +36,7 @@ #include "EventListener.h" #include "Frame.h" #include "ScriptScope.h" +#include "Tokenizer.h" #include "V8AbstractEventListener.h" #include "V8Binding.h" #include "XSSAuditor.h" @@ -45,18 +46,29 @@ namespace WebCore { PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node* node, Attribute* attr) { ASSERT(node); + int lineNumber = 1; + int columnNumber = 0; + String sourceURL; - Frame* frame = node->document()->frame(); + if (Frame* frame = node->document()->frame()) { + ScriptController* scriptController = frame->script(); + if (!scriptController->isEnabled()) + return 0; - if (!frame) - return 0; + if (!scriptController->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) { + // This script is not safe to execute. + return 0; + } - if (!frame->script()->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) { - // This script is not safe to execute. - return 0; + if (frame->document()->tokenizer()) { + // FIXME: Change to use script->eventHandlerLineNumber() when implemented. + lineNumber = frame->document()->tokenizer()->lineNumber(); + columnNumber = frame->document()->tokenizer()->columnNumber(); + } + sourceURL = node->document()->url().string(); } - return V8LazyEventListener::create(frame, attr->value(), attr->localName().string(), node->isSVGElement()); + return V8LazyEventListener::create(attr->localName().string(), node->isSVGElement(), attr->value(), sourceURL, lineNumber, columnNumber); } PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, Attribute* attr) @@ -64,22 +76,36 @@ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, Attri if (!frame) return 0; - if (!frame->script()->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) { + int lineNumber = 1; + int columnNumber = 0; + String sourceURL; + + ScriptController* scriptController = frame->script(); + if (!scriptController->isEnabled()) + return 0; + + if (!scriptController->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) { // This script is not safe to execute. return 0; } - return V8LazyEventListener::create(frame, attr->value(), attr->localName().string(), frame->document()->isSVGDocument()); + if (frame->document()->tokenizer()) { + // FIXME: Change to use script->eventHandlerLineNumber() when implemented. + lineNumber = frame->document()->tokenizer()->lineNumber(); + columnNumber = frame->document()->tokenizer()->columnNumber(); + } + sourceURL = frame->document()->url().string(); + return V8LazyEventListener::create(attr->localName().string(), frame->document()->isSVGDocument(), attr->value(), sourceURL, lineNumber, columnNumber); } -String getEventListenerHandlerBody(ScriptExecutionContext*, ScriptState* scriptState, EventListener* listener) +String getEventListenerHandlerBody(ScriptExecutionContext* context, ScriptState* scriptState, EventListener* listener) { if (listener->type() != EventListener::JSEventListenerType) return ""; ScriptScope scope(scriptState); V8AbstractEventListener* v8Listener = static_cast<V8AbstractEventListener*>(listener); - v8::Handle<v8::Object> function = v8Listener->getListenerObject(); + v8::Handle<v8::Object> function = v8Listener->getListenerObject(context); if (function.IsEmpty()) return ""; diff --git a/WebCore/bindings/v8/ScriptObjectQuarantine.cpp b/WebCore/bindings/v8/ScriptObjectQuarantine.cpp index 5dd0dc5..6528c9d 100644 --- a/WebCore/bindings/v8/ScriptObjectQuarantine.cpp +++ b/WebCore/bindings/v8/ScriptObjectQuarantine.cpp @@ -57,10 +57,25 @@ bool getQuarantinedScriptObject(Database* database, ScriptObject& quarantinedObj { ASSERT(database); - // FIXME: Implement when Database V8 bindings are enabled +#if ENABLE(DATABASE) + v8::HandleScope handleScope; + Frame* frame = database->document()->frame(); + if (!frame) + return false; + + v8::Local<v8::Context> context = V8Proxy::context(frame); + if (context.IsEmpty()) + return false; + + v8::Context::Scope scope(context); + v8::Handle<v8::Value> v8Database = V8DOMWrapper::convertToV8Object(V8ClassIndex::DATABASE, database); + ScriptState* scriptState = frame->page()->inspectorController()->frontendScriptState(); + quarantinedObject = ScriptObject(scriptState, v8::Local<v8::Object>(v8::Object::Cast(*v8Database))); +#else ASSERT_NOT_REACHED(); quarantinedObject = ScriptObject(); - return false; +#endif + return true; } bool getQuarantinedScriptObject(Storage* storage, ScriptObject& quarantinedObject) @@ -72,7 +87,9 @@ bool getQuarantinedScriptObject(Storage* storage, ScriptObject& quarantinedObjec #if ENABLE(DOM_STORAGE) v8::HandleScope handleScope; v8::Local<v8::Context> context = V8Proxy::context(frame); - // FIXME: What if context.IsEmpty()? + if (context.IsEmpty()) + return false; + v8::Context::Scope scope(context); v8::Handle<v8::Value> v8Storage = V8DOMWrapper::convertToV8Object(V8ClassIndex::STORAGE, storage); diff --git a/WebCore/bindings/v8/ScriptString.h b/WebCore/bindings/v8/ScriptString.h index fe254a5..414818a 100644 --- a/WebCore/bindings/v8/ScriptString.h +++ b/WebCore/bindings/v8/ScriptString.h @@ -32,34 +32,41 @@ #define ScriptString_h #include "PlatformString.h" +#include "ScriptStringImpl.h" +#include "V8Binding.h" namespace WebCore { class ScriptString { public: - ScriptString() {} - ScriptString(const String& s) : m_str(s) {} - ScriptString(const char* s) : m_str(s) {} + ScriptString() : m_impl(0) {} + ScriptString(const String& s) : m_impl(ScriptStringImpl::create(s)) {} + ScriptString(const char* s) : m_impl(ScriptStringImpl::create(s)) {} - operator String() const { return m_str; } + operator String() const { return m_impl->toString(); } - bool isNull() const { return m_str.isNull(); } - size_t size() const { return m_str.length(); } + bool isNull() const { return !m_impl.get() || m_impl->isNull(); } + size_t size() const { return m_impl->size(); } ScriptString& operator=(const char* s) { - m_str = s; + m_impl = ScriptStringImpl::create(s); return *this; } ScriptString& operator+=(const String& s) { - m_str += s; + m_impl->append(s); return *this; } + v8::Handle<v8::Value> v8StringOrNull() const + { + return isNull() ? v8::Handle<v8::Value>(v8::Null()) : v8::Handle<v8::Value>(m_impl->v8StringHandle()); + } + private: - String m_str; + RefPtr<ScriptStringImpl> m_impl; }; } // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptStringImpl.cpp b/WebCore/bindings/v8/ScriptStringImpl.cpp new file mode 100644 index 0000000..afe74b1 --- /dev/null +++ b/WebCore/bindings/v8/ScriptStringImpl.cpp @@ -0,0 +1,74 @@ +/* + * 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 "ScriptStringImpl.h" + +#include "V8Binding.h" + +namespace WebCore { + +ScriptStringImpl::ScriptStringImpl(const String& s) +{ + v8::HandleScope scope; + m_handle.set(v8String(s)); +} + +ScriptStringImpl::ScriptStringImpl(const char* s) +{ + v8::HandleScope scope; + m_handle.set(v8::String::New(s)); +} + +String ScriptStringImpl::toString() const +{ + return v8StringToWebCoreString(m_handle.get()); +} + +bool ScriptStringImpl::isNull() const +{ + return m_handle.get().IsEmpty(); +} + +size_t ScriptStringImpl::size() const +{ + return m_handle.get()->Length(); +} + +void ScriptStringImpl::append(const String& s) +{ + v8::HandleScope scope; + if (m_handle.get().IsEmpty()) + m_handle.set(v8String(s)); + else + m_handle.set(v8::String::Concat(m_handle.get(), v8String(s))); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptStringImpl.h b/WebCore/bindings/v8/ScriptStringImpl.h new file mode 100644 index 0000000..8a47b4f --- /dev/null +++ b/WebCore/bindings/v8/ScriptStringImpl.h @@ -0,0 +1,77 @@ +/* + * 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 ScriptStringImpl_h +#define ScriptStringImpl_h + +#include "OwnHandle.h" +#include "PlatformString.h" + +#include <v8.h> + +namespace WebCore { + +// This class is used for strings that tend to be shared with JavaScript frequently. The JSC implementation uses wtf::UString - see bindings/js/ScriptString.h +// Currently XMLHttpRequest uses a ScriptString to build up the responseText attribute. As data arrives from the network, it is appended to the ScriptString +// via operator+= and a JavaScript readystatechange event is fired. JavaScript can access the responseText attribute of the XMLHttpRequest object. JavaScript +// may also query the responseXML attribute of the XMLHttpRequest object which results in the responseText attribute being coerced into a WebCore::String and +// then parsed as an XML document. +// This implementation optimizes for the common case where the responseText is built up with many calls to operator+= before the actual text is queried. +class ScriptStringImpl : public RefCounted<ScriptStringImpl> { +public: + static PassRefPtr<ScriptStringImpl> create(const String& s) + { + return adoptRef(new ScriptStringImpl(s)); + } + + static PassRefPtr<ScriptStringImpl> create(const char* s) + { + return adoptRef(new ScriptStringImpl(s)); + } + + String toString() const; + + bool isNull() const; + size_t size() const; + + void append(const String& s); + + v8::Handle<v8::String> v8StringHandle() { return m_handle.get(); } + +private: + ScriptStringImpl(const String& s); + ScriptStringImpl(const char* s); + + OwnHandle<v8::String> m_handle; +}; + +} // namespace WebCore + +#endif // ScriptStringImpl_h diff --git a/WebCore/bindings/v8/V8AbstractEventListener.cpp b/WebCore/bindings/v8/V8AbstractEventListener.cpp index 032b6b9..675e466 100644 --- a/WebCore/bindings/v8/V8AbstractEventListener.cpp +++ b/WebCore/bindings/v8/V8AbstractEventListener.cpp @@ -35,11 +35,12 @@ #include "Document.h" #include "Event.h" #include "Frame.h" -#include "Tokenizer.h" #include "V8Binding.h" #include "V8EventListenerList.h" #include "V8Proxy.h" #include "V8Utilities.h" +#include "WorkerContext.h" +#include "WorkerContextExecutionProxy.h" namespace WebCore { @@ -49,28 +50,12 @@ static void weakEventListenerCallback(v8::Persistent<v8::Value>, void* parameter listener->disposeListenerObject(); } -V8AbstractEventListener::V8AbstractEventListener(Frame* frame, PassRefPtr<V8ListenerGuard> guard, bool isAttribute) +V8AbstractEventListener::V8AbstractEventListener(PassRefPtr<V8ListenerGuard> guard, bool isAttribute) : EventListener(JSEventListenerType) , m_isWeak(true) , m_isAttribute(isAttribute) - , m_frame(frame) , m_guard(guard) - , m_lineNumber(0) - , m_columnNumber(0) { - if (!m_frame) - return; - - // We might be called directly from the parser. - v8::HandleScope handleScope; - - m_context = V8Proxy::shared_context(m_frame); - - // Get the position in the source if any. - if (m_isAttribute && m_frame->document()->tokenizer()) { - m_lineNumber = m_frame->document()->tokenizer()->lineNumber(); - m_columnNumber = m_frame->document()->tokenizer()->columnNumber(); - } } V8AbstractEventListener::~V8AbstractEventListener() @@ -83,7 +68,7 @@ V8AbstractEventListener::~V8AbstractEventListener() disposeListenerObject(); } -void V8AbstractEventListener::handleEvent(ScriptExecutionContext* scriptExecutionContext, Event* event) +void V8AbstractEventListener::handleEvent(ScriptExecutionContext* context, Event* event) { // EventListener could be disconnected from the frame. if (disconnected()) @@ -96,25 +81,17 @@ void V8AbstractEventListener::handleEvent(ScriptExecutionContext* scriptExecutio LOCK_V8; v8::HandleScope handleScope; - if (!m_context) - return; - - // Create a new local handle since the persistent handle stored in - // m_context may be disposed before we're done. - v8::Handle<v8::Context> v8Context = v8::Local<v8::Context>::New(m_context->get()); + v8::Local<v8::Context> v8Context = toV8Context(context); if (v8Context.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(v8Context); // Get the V8 wrapper for the event object. v8::Handle<v8::Value> jsEvent = V8DOMWrapper::convertEventToV8Object(event); - invokeEventHandler(v8Context, event, jsEvent); + invokeEventHandler(context, event, jsEvent); Document::updateStyleForAllDocuments(); } @@ -141,8 +118,13 @@ void V8AbstractEventListener::setListenerObject(v8::Handle<v8::Object> listener) m_listener.MakeWeak(this, &weakEventListenerCallback); } -void V8AbstractEventListener::invokeEventHandler(v8::Handle<v8::Context> v8Context, Event* event, v8::Handle<v8::Value> jsEvent) +void V8AbstractEventListener::invokeEventHandler(ScriptExecutionContext* context, Event* event, v8::Handle<v8::Value> jsEvent) { + + v8::Local<v8::Context> v8Context = toV8Context(context); + if (v8Context.IsEmpty()) + return; + // We push the event being processed into the global object, so that it can be exposed by DOMWindow's bindings. v8::Local<v8::String> eventSymbol = v8::String::NewSymbol("event"); v8::Local<v8::Value> returnValue; @@ -166,7 +148,7 @@ void V8AbstractEventListener::invokeEventHandler(v8::Handle<v8::Context> v8Conte // Call the event handler. tryCatch.SetVerbose(false); // We do not want to report the exception to the inspector console. - returnValue = callListenerFunction(jsEvent, event); + returnValue = callListenerFunction(context, jsEvent, event); if (!tryCatch.CanContinue()) return; diff --git a/WebCore/bindings/v8/V8AbstractEventListener.h b/WebCore/bindings/v8/V8AbstractEventListener.h index c7736be..ceff001 100644 --- a/WebCore/bindings/v8/V8AbstractEventListener.h +++ b/WebCore/bindings/v8/V8AbstractEventListener.h @@ -97,15 +97,12 @@ namespace WebCore { virtual void handleEvent(ScriptExecutionContext*, Event*); - // Returns the owner frame of the listener. - Frame* frame() { return m_frame; } - virtual bool isLazy() const { return false; } // Returns the listener object, either a function or an object. - v8::Local<v8::Object> getListenerObject() + v8::Local<v8::Object> getListenerObject(ScriptExecutionContext* context) { - prepareListenerObject(); + prepareListenerObject(context); return v8::Local<v8::Object>::New(m_listener); } @@ -122,30 +119,24 @@ namespace WebCore { // Dispose listener object and clear the handle. void disposeListenerObject(); - // Detach the listener from its owner frame. - void disconnectFrame() { m_frame = 0; } - virtual bool disconnected() const { return m_guard && m_guard->isDisconnected(); } protected: - V8AbstractEventListener(Frame*, PassRefPtr<V8ListenerGuard>, bool isAttribute); + V8AbstractEventListener(PassRefPtr<V8ListenerGuard>, bool isAttribute); - virtual void prepareListenerObject() { } + virtual void prepareListenerObject(ScriptExecutionContext*) { } void setListenerObject(v8::Handle<v8::Object> listener); - void invokeEventHandler(v8::Handle<v8::Context>, Event*, v8::Handle<v8::Value> jsEvent); + void invokeEventHandler(ScriptExecutionContext*, Event*, v8::Handle<v8::Value> jsEvent); // Get the receiver object to use for event listener call. v8::Local<v8::Object> getReceiverObject(Event*); - - int lineNumber() const { return m_lineNumber; } - private: // Implementation of EventListener function. virtual bool virtualisAttribute() const { return m_isAttribute; } - virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsevent, Event*) = 0; + virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsevent, Event*) = 0; v8::Persistent<v8::Object> m_listener; @@ -155,16 +146,7 @@ namespace WebCore { // Indicates if this is an HTML type listener. bool m_isAttribute; - // 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; - RefPtr<SharedPersistent<v8::Context> > m_context; RefPtr<V8ListenerGuard> m_guard; - - // Position in the HTML source for HTML event listeners. - int m_lineNumber; - int m_columnNumber; }; } // namespace WebCore diff --git a/WebCore/bindings/v8/V8Binding.h b/WebCore/bindings/v8/V8Binding.h index a09102d..237bc4d 100644 --- a/WebCore/bindings/v8/V8Binding.h +++ b/WebCore/bindings/v8/V8Binding.h @@ -61,7 +61,7 @@ namespace WebCore { return v8NonStringValueToAtomicWebCoreString(value); } - inline String toString(const String& string) + inline const String& toString(const String& string) { return string; } diff --git a/WebCore/bindings/v8/V8Collection.h b/WebCore/bindings/v8/V8Collection.h index cbfe921..e72dc07 100644 --- a/WebCore/bindings/v8/V8Collection.h +++ b/WebCore/bindings/v8/V8Collection.h @@ -41,7 +41,7 @@ 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) + inline v8::Handle<v8::Value> getV8Object(void* implementation, v8::Local<v8::Value> implementationType) { if (!implementation) return v8::Handle<v8::Value>(); diff --git a/WebCore/bindings/v8/V8DOMWrapper.cpp b/WebCore/bindings/v8/V8DOMWrapper.cpp index 5a6b901..4e41a8c 100644 --- a/WebCore/bindings/v8/V8DOMWrapper.cpp +++ b/WebCore/bindings/v8/V8DOMWrapper.cpp @@ -445,6 +445,24 @@ v8::Persistent<v8::FunctionTemplate> V8DOMWrapper::getTemplate(V8ClassIndex::V8W #endif // WORKERS +#if ENABLE(SHARED_WORKERS) + case V8ClassIndex::SHAREDWORKER: { + // Reserve one more internal field for keeping event listeners. + v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate(); + instanceTemplate->SetInternalFieldCount(V8Custom::kSharedWorkerInternalFieldCount); + descriptor->SetCallHandler(USE_CALLBACK(SharedWorkerConstructor)); + break; + } + + case V8ClassIndex::SHAREDWORKERCONTEXT: { + // Reserve internal fields for keeping event listeners. + v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate(); + ASSERT(instanceTemplate->InternalFieldCount() == V8Custom::kDefaultWrapperInternalFieldCount); + instanceTemplate->SetInternalFieldCount(V8Custom::kSharedWorkerContextInternalFieldCount); + break; + } +#endif // SHARED_WORKERS + #if ENABLE(OFFLINE_WEB_APPLICATIONS) case V8ClassIndex::DOMAPPLICATIONCACHE: { // Reserve one more internal field for keeping event listeners. @@ -598,16 +616,6 @@ v8::Local<v8::Function> V8DOMWrapper::getConstructor(V8ClassIndex::V8WrapperType if (!frame) return v8::Local<v8::Function>(); -#if ENABLE(WEB_SOCKETS) - // Make typeof(window.WebSocket) == 'undefined' when - // experimentalWebSocketEnabled is false. - if (type == V8ClassIndex::WEBSOCKET) { - Settings* settings = frame->settings(); - if (!settings || !settings->experimentalWebSocketsEnabled()) - return v8::Local<v8::Function>(); - } -#endif - v8::Handle<v8::Context> context = V8Proxy::context(frame); if (context.IsEmpty()) return v8::Local<v8::Function>(); @@ -1198,6 +1206,8 @@ v8::Handle<v8::Value> V8DOMWrapper::convertEventToV8Object(Event* event) else if (event->isStorageEvent()) type = V8ClassIndex::STORAGEEVENT; #endif + else if (event->isBeforeLoadEvent()) + type = V8ClassIndex::BEFORELOADEVENT; v8::Handle<v8::Object> result = instantiateV8Object(type, V8ClassIndex::EVENT, event); @@ -1281,14 +1291,14 @@ v8::Handle<v8::Value> V8DOMWrapper::convertNewNodeToV8Object(Node* node, V8Proxy else type = V8ClassIndex::DOCUMENT; } else { - ASSERT(nodeType < sizeof(mapping)/sizeof(mapping[0])); + ASSERT(nodeType < static_cast<int>(sizeof(mapping)/sizeof(mapping[0]))); type = mapping[nodeType]; ASSERT(type != V8ClassIndex::INVALID_CLASS_INDEX); } v8::Handle<v8::Context> context; if (proxy) - context = V8Proxy::context(proxy->frame()); + context = proxy->context(); // Enter the node's context and create the wrapper in that context. if (!context.IsEmpty()) @@ -1400,14 +1410,14 @@ v8::Handle<v8::Value> V8DOMWrapper::convertEventTargetToV8Object(EventTarget* ta return notHandledByInterceptor(); } -v8::Handle<v8::Value> V8DOMWrapper::convertEventListenerToV8Object(EventListener* listener) +v8::Handle<v8::Value> V8DOMWrapper::convertEventListenerToV8Object(ScriptExecutionContext* context, EventListener* listener) { if (!listener) return v8::Null(); // FIXME: can a user take a lazy event listener and set to other places? V8AbstractEventListener* v8listener = static_cast<V8AbstractEventListener*>(listener); - return v8listener->getListenerObject(); + return v8listener->getListenerObject(context); } PassRefPtr<EventListener> V8DOMWrapper::getEventListener(Node* node, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup) @@ -1423,7 +1433,7 @@ PassRefPtr<EventListener> V8DOMWrapper::getEventListener(Node* node, v8::Local<v proxy = V8Proxy::retrieve(V8Proxy::retrieveFrameForEnteredContext()); if (proxy) - return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), proxy->listenerGuard(), value, isAttribute); + return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->listenerGuard(), value, isAttribute); return 0; } @@ -1447,7 +1457,7 @@ PassRefPtr<EventListener> V8DOMWrapper::getEventListener(AbstractWorker* worker, V8Proxy* proxy = V8Proxy::retrieve(worker->scriptExecutionContext()); if (proxy) - return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), proxy->listenerGuard(), value, isAttribute); + return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->listenerGuard(), value, isAttribute); return 0; } @@ -1463,7 +1473,7 @@ PassRefPtr<EventListener> V8DOMWrapper::getEventListener(Notification* notificat V8Proxy* proxy = V8Proxy::retrieve(notification->scriptExecutionContext()); if (proxy) - return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), proxy->listenerGuard(), value, isAttribute); + return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->listenerGuard(), value, isAttribute); return 0; } @@ -1487,7 +1497,7 @@ PassRefPtr<EventListener> V8DOMWrapper::getEventListener(EventTarget* eventTarge { V8Proxy* proxy = V8Proxy::retrieve(eventTarget->scriptExecutionContext()); if (proxy) - return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), proxy->listenerGuard(), value, isAttribute); + return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->listenerGuard(), value, isAttribute); #if ENABLE(WORKERS) WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve(); @@ -1501,7 +1511,7 @@ PassRefPtr<EventListener> V8DOMWrapper::getEventListener(EventTarget* eventTarge PassRefPtr<EventListener> V8DOMWrapper::getEventListener(V8Proxy* proxy, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup) { if (proxy) - return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), proxy->listenerGuard(), value, isAttribute); + return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->listenerGuard(), value, isAttribute); return 0; } diff --git a/WebCore/bindings/v8/V8DOMWrapper.h b/WebCore/bindings/v8/V8DOMWrapper.h index b5587d5..3d50af3 100644 --- a/WebCore/bindings/v8/V8DOMWrapper.h +++ b/WebCore/bindings/v8/V8DOMWrapper.h @@ -166,6 +166,16 @@ namespace WebCore { static v8::Handle<v8::Value> convertDocumentToV8Object(Document*); + static v8::Handle<v8::Value> convertNewNodeToV8Object(PassRefPtr<Node> node) + { + return convertNewNodeToV8Object(node.get()); + } + + static v8::Handle<v8::Value> convertNewNodeToV8Object(Node* node) + { + return convertNewNodeToV8Object(node, 0, getDOMNodeMap()); + } + static v8::Handle<v8::Value> convertNewNodeToV8Object(Node*, V8Proxy*, DOMWrapperMap<Node>&); template <class C> @@ -216,12 +226,12 @@ namespace WebCore { static v8::Handle<v8::Value> convertEventTargetToV8Object(EventTarget*); // Wrap and unwrap JS event listeners. - static v8::Handle<v8::Value> convertEventListenerToV8Object(PassRefPtr<EventListener> eventListener) + static v8::Handle<v8::Value> convertEventListenerToV8Object(ScriptExecutionContext* context, PassRefPtr<EventListener> eventListener) { - return convertEventListenerToV8Object(eventListener.get()); + return convertEventListenerToV8Object(context, eventListener.get()); } - static v8::Handle<v8::Value> convertEventListenerToV8Object(EventListener*); + static v8::Handle<v8::Value> convertEventListenerToV8Object(ScriptExecutionContext*, EventListener*); static PassRefPtr<EventListener> getEventListener(Node* node, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup); diff --git a/WebCore/bindings/v8/V8EventListenerList.h b/WebCore/bindings/v8/V8EventListenerList.h index 506e5dc..29b4874 100644 --- a/WebCore/bindings/v8/V8EventListenerList.h +++ b/WebCore/bindings/v8/V8EventListenerList.h @@ -54,8 +54,8 @@ namespace WebCore { return doFindWrapper(v8::Local<v8::Object>::Cast(value), wrapperProperty); } - template<typename WrapperType, typename ContextType> - static PassRefPtr<V8EventListener> findOrCreateWrapper(ContextType*, PassRefPtr<V8ListenerGuard>, v8::Local<v8::Value>, bool isAttribute); + template<typename WrapperType> + static PassRefPtr<V8EventListener> findOrCreateWrapper(PassRefPtr<V8ListenerGuard>, v8::Local<v8::Value>, bool isAttribute); static void clearWrapper(v8::Handle<v8::Object> listenerObject, bool isAttribute) { @@ -80,8 +80,8 @@ namespace WebCore { } }; - template<typename WrapperType, typename ContextType> - PassRefPtr<V8EventListener> V8EventListenerList::findOrCreateWrapper(ContextType* context, PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Value> value, bool isAttribute) + template<typename WrapperType> + PassRefPtr<V8EventListener> V8EventListenerList::findOrCreateWrapper(PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Value> value, bool isAttribute) { ASSERT(v8::Context::InContext()); if (!value->IsObject()) @@ -94,7 +94,7 @@ namespace WebCore { if (wrapper) return wrapper; - PassRefPtr<V8EventListener> wrapperPtr = WrapperType::create(context, guard, object, isAttribute); + PassRefPtr<V8EventListener> wrapperPtr = WrapperType::create(guard, object, isAttribute); if (wrapperPtr) object->SetHiddenValue(wrapperProperty, v8::External::Wrap(wrapperPtr.get())); diff --git a/WebCore/bindings/v8/V8GCController.cpp b/WebCore/bindings/v8/V8GCController.cpp index f3b1376..4ef3bb8 100644 --- a/WebCore/bindings/v8/V8GCController.cpp +++ b/WebCore/bindings/v8/V8GCController.cpp @@ -342,7 +342,6 @@ public: Vector<v8::Persistent<v8::Value> > group; group.reserveCapacity(nextKeyIndex - i); for (; i < nextKeyIndex; ++i) { - Node* node = m_grouper[i].node(); v8::Persistent<v8::Value> wrapper = m_grouper[i].wrapper(); if (!wrapper.IsEmpty()) group.append(wrapper); diff --git a/WebCore/bindings/v8/V8Index.cpp b/WebCore/bindings/v8/V8Index.cpp index 2cbd16d..89a9f71 100644 --- a/WebCore/bindings/v8/V8Index.cpp +++ b/WebCore/bindings/v8/V8Index.cpp @@ -34,6 +34,7 @@ #include "V8Attr.h" #include "V8BarInfo.h" #include "V8BeforeLoadEvent.h" +#include "V8CanvasActiveInfo.h" #include "V8CanvasRenderingContext.h" #include "V8CanvasRenderingContext2D.h" #include "V8CanvasGradient.h" @@ -355,7 +356,6 @@ #include "V8SVGTransform.h" #include "V8SVGTransformList.h" #include "V8SVGUnitTypes.h" -#include "V8SVGURIReference.h" #include "V8SVGZoomEvent.h" #endif @@ -389,6 +389,7 @@ #if ENABLE(SHARED_WORKERS) #include "V8SharedWorker.h" +#include "V8SharedWorkerContext.h" #endif #if ENABLE(3D_CANVAS) @@ -434,6 +435,7 @@ #include "V8InspectorBackend.h" #endif +<<<<<<< HEAD:WebCore/bindings/v8/V8Index.cpp #if PLATFORM(ANDROID) // TODO: Upstream these guards to webkit.org #if ENABLE(GEOLOCATION) @@ -452,6 +454,8 @@ #include "V8VoidCallback.h" #endif // PLATFORM(ANDROID) +======= +>>>>>>> webkit.org at r50258.:WebCore/bindings/v8/V8Index.cpp namespace WebCore { FunctionTemplateFactory V8ClassIndex::GetFactory(V8WrapperType type) diff --git a/WebCore/bindings/v8/V8Index.h b/WebCore/bindings/v8/V8Index.h index 179b963..ee64125 100644 --- a/WebCore/bindings/v8/V8Index.h +++ b/WebCore/bindings/v8/V8Index.h @@ -445,6 +445,7 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)(); #if ENABLE(3D_CANVAS) #define DOM_OBJECT_3D_CANVAS_TYPES(V) \ + V(CANVASACTIVEINFO, CanvasActiveInfo) \ V(CANVASARRAY, CanvasArray) \ V(CANVASARRAYBUFFER, CanvasArrayBuffer) \ V(CANVASBUFFER, CanvasBuffer) \ @@ -490,6 +491,7 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)(); #define DOM_OBJECT_INSPECTOR_TYPES(V) #endif +<<<<<<< HEAD:WebCore/bindings/v8/V8Index.h #if ENABLE(GEOLOCATION) #define DOM_OBJECT_GEOLOCATION_TYPES(V) \ V(COORDINATES, Coordinates) \ @@ -521,6 +523,8 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)(); #if PLATFORM(ANDROID) // This block is modified, but is not Android-specific. +======= +>>>>>>> webkit.org at r50258.:WebCore/bindings/v8/V8Index.h #define DOM_OBJECT_TYPES(V) \ DOM_OBJECT_TYPES_1(V) \ DOM_OBJECT_TYPES_2(V) \ @@ -530,11 +534,17 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)(); DOM_OBJECT_3D_CANVAS_TYPES(V) \ DOM_OBJECT_XPATH_TYPES(V) \ DOM_OBJECT_XSLT_TYPES(V) \ +<<<<<<< HEAD:WebCore/bindings/v8/V8Index.h DOM_OBJECT_GEOLOCATION_TYPES(V) \ DOM_OBJECT_TOUCH_EVENT_TYPES(V) \ DOM_OBJECT_VOIDCALLBACK_TYPES(V) \ +======= +>>>>>>> webkit.org at r50258.:WebCore/bindings/v8/V8Index.h DOM_OBJECT_INSPECTOR_TYPES(V) +<<<<<<< HEAD:WebCore/bindings/v8/V8Index.h #endif +======= +>>>>>>> webkit.org at r50258.:WebCore/bindings/v8/V8Index.h #if ENABLE(SVG) // SVG_OBJECT_TYPES are svg non-node, non-pod types. diff --git a/WebCore/bindings/v8/V8IsolatedWorld.h b/WebCore/bindings/v8/V8IsolatedWorld.h index 15d8711..663f4bd 100644 --- a/WebCore/bindings/v8/V8IsolatedWorld.h +++ b/WebCore/bindings/v8/V8IsolatedWorld.h @@ -88,7 +88,7 @@ namespace WebCore { } v8::Handle<v8::Context> context() { return m_context->get(); } - PassRefPtr<SharedPersistent<v8::Context> > shared_context() { return m_context; } + PassRefPtr<SharedPersistent<v8::Context> > sharedContext() { return m_context; } DOMDataStore* getDOMDataStore() const { return m_domDataStore.getStore(); } diff --git a/WebCore/bindings/v8/V8LazyEventListener.cpp b/WebCore/bindings/v8/V8LazyEventListener.cpp index 9b58571..54740a9 100644 --- a/WebCore/bindings/v8/V8LazyEventListener.cpp +++ b/WebCore/bindings/v8/V8LazyEventListener.cpp @@ -40,25 +40,30 @@ namespace WebCore { -V8LazyEventListener::V8LazyEventListener(Frame* frame, const String& code, const String& functionName, bool isSVGEvent) - : V8AbstractEventListener(frame, 0, true) - , m_code(code) +V8LazyEventListener::V8LazyEventListener(const String& functionName, bool isSVGEvent, const String& code, const String sourceURL, int lineNumber, int columnNumber) + : V8AbstractEventListener(0, true) , m_functionName(functionName) , m_isSVGEvent(isSVGEvent) + , m_code(code) + , m_sourceURL(sourceURL) + , m_lineNumber(lineNumber) + , m_columnNumber(columnNumber) { } -v8::Local<v8::Value> V8LazyEventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event) +v8::Local<v8::Value> V8LazyEventListener::callListenerFunction(ScriptExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event) { - v8::Local<v8::Function> handlerFunction = v8::Local<v8::Function>::Cast(getListenerObject()); + v8::Local<v8::Function> handlerFunction = v8::Local<v8::Function>::Cast(getListenerObject(context)); v8::Local<v8::Object> receiver = getReceiverObject(event); if (handlerFunction.IsEmpty() || receiver.IsEmpty()) return v8::Local<v8::Value>(); v8::Handle<v8::Value> parameters[1] = { jsEvent }; - V8Proxy* proxy = V8Proxy::retrieve(frame()); - return proxy->callFunction(handlerFunction, receiver, 1, parameters); + if (V8Proxy* proxy = V8Proxy::retrieve(context)) + return proxy->callFunction(handlerFunction, receiver, 1, parameters); + + return v8::Local<v8::Value>(); } static v8::Handle<v8::Value> V8LazyEventListenerToString(const v8::Arguments& args) @@ -66,16 +71,19 @@ static v8::Handle<v8::Value> V8LazyEventListenerToString(const v8::Arguments& ar return args.Holder()->GetHiddenValue(V8HiddenPropertyName::toStringString()); } -void V8LazyEventListener::prepareListenerObject() +void V8LazyEventListener::prepareListenerObject(ScriptExecutionContext* context) { if (hasExistingListenerObject()) return; - // Switch to the context of m_frame. v8::HandleScope handleScope; + V8Proxy* proxy = V8Proxy::retrieve(context); + if (!proxy) + return; + // Use the outer scope to hold context. - v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(frame()); + v8::Handle<v8::Context> v8Context = proxy->context(); // Bail out if we cannot get the context. if (v8Context.IsEmpty()) return; @@ -101,10 +109,8 @@ void V8LazyEventListener::prepareListenerObject() // Insert '\n' otherwise //-style comments could break the handler. code.append( "\n}).call(this, evt);}}}})"); v8::Handle<v8::String> codeExternalString = v8ExternalString(code); - v8::Handle<v8::Script> script = V8Proxy::compileScript(codeExternalString, frame()->document()->url(), lineNumber()); + v8::Handle<v8::Script> script = V8Proxy::compileScript(codeExternalString, m_sourceURL, m_lineNumber); if (!script.IsEmpty()) { - V8Proxy* proxy = V8Proxy::retrieve(frame()); - ASSERT(proxy); v8::Local<v8::Value> value = proxy->runScript(script, false); if (!value.IsEmpty()) { ASSERT(value->IsFunction()); diff --git a/WebCore/bindings/v8/V8LazyEventListener.h b/WebCore/bindings/v8/V8LazyEventListener.h index ba460e6..699460b 100644 --- a/WebCore/bindings/v8/V8LazyEventListener.h +++ b/WebCore/bindings/v8/V8LazyEventListener.h @@ -45,24 +45,27 @@ namespace WebCore { // 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, bool isSVGEvent) + static PassRefPtr<V8LazyEventListener> create(const String& functionName, bool isSVGEvent, const String& code, const String& sourceURL, int lineNumber, int columnNumber) { - return adoptRef(new V8LazyEventListener(frame, code, functionName, isSVGEvent)); + return adoptRef(new V8LazyEventListener(functionName, isSVGEvent, code, sourceURL, lineNumber, columnNumber)); } virtual bool isLazy() const { return true; } protected: - virtual void prepareListenerObject(); + virtual void prepareListenerObject(ScriptExecutionContext*); private: - V8LazyEventListener(Frame*, const String& code, const String& functionName, bool isSVGEvent); + V8LazyEventListener(const String& functionName, bool isSVGEvent, const String& code, const String sourceURL, int lineNumber, int columnNumber); - virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*); + virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*); - String m_code; String m_functionName; bool m_isSVGEvent; + String m_code; + String m_sourceURL; + int m_lineNumber; + int m_columnNumber; }; } // namespace WebCore diff --git a/WebCore/bindings/v8/V8NPObject.cpp b/WebCore/bindings/v8/V8NPObject.cpp index b6bf0f7..75163f1 100644 --- a/WebCore/bindings/v8/V8NPObject.cpp +++ b/WebCore/bindings/v8/V8NPObject.cpp @@ -93,26 +93,30 @@ static v8::Handle<v8::Value> npObjectInvokeImpl(const v8::Arguments& args, Invok NPVariant result; VOID_TO_NPVARIANT(result); + bool retval = true; switch (functionId) { case InvokeMethod: if (npObject->_class->invoke) { v8::Handle<v8::String> functionName(v8::String::Cast(*args.Data())); NPIdentifier identifier = getStringIdentifier(functionName); - npObject->_class->invoke(npObject, identifier, npArgs.get(), numArgs, &result); + retval = npObject->_class->invoke(npObject, identifier, npArgs.get(), numArgs, &result); } break; case InvokeConstruct: if (npObject->_class->construct) - npObject->_class->construct(npObject, npArgs.get(), numArgs, &result); + retval = npObject->_class->construct(npObject, npArgs.get(), numArgs, &result); break; case InvokeDefault: if (npObject->_class->invokeDefault) - npObject->_class->invokeDefault(npObject, npArgs.get(), numArgs, &result); + retval = npObject->_class->invokeDefault(npObject, npArgs.get(), numArgs, &result); break; default: break; } + if (!retval) + throwError("Error calling method on NPObject!", V8Proxy::GeneralError); + for (int i=0; i < numArgs; i++) _NPN_ReleaseVariantValue(&npArgs[i]); diff --git a/WebCore/bindings/v8/V8Proxy.cpp b/WebCore/bindings/v8/V8Proxy.cpp index dd3c218..c78d009 100644 --- a/WebCore/bindings/v8/V8Proxy.cpp +++ b/WebCore/bindings/v8/V8Proxy.cpp @@ -49,6 +49,7 @@ #include "V8HiddenPropertyName.h" #include "V8Index.h" #include "V8IsolatedWorld.h" +#include "WorkerContextExecutionProxy.h" #include <algorithm> #include <utility> @@ -83,15 +84,8 @@ const char* V8Proxy::kContextDebugDataValue = "value"; void batchConfigureAttributes(v8::Handle<v8::ObjectTemplate> instance, v8::Handle<v8::ObjectTemplate> proto, const BatchedAttribute* attributes, size_t attributeCount) { - for (size_t i = 0; i < attributeCount; ++i) { - const BatchedAttribute* attribute = &attributes[i]; - (attribute->onProto ? proto : instance)->SetAccessor(v8::String::New(attribute->name), - attribute->getter, - attribute->setter, - attribute->data == V8ClassIndex::INVALID_CLASS_INDEX ? v8::Handle<v8::Value>() : v8::Integer::New(V8ClassIndex::ToInt(attribute->data)), - attribute->settings, - attribute->attribute); - } + for (size_t i = 0; i < attributeCount; ++i) + configureAttribute(instance, proto, attributes[i]); } void batchConfigureConstants(v8::Handle<v8::FunctionTemplate> functionDescriptor, v8::Handle<v8::ObjectTemplate> proto, const BatchedConstant* constants, size_t constantCount) @@ -223,12 +217,13 @@ static void reportFatalErrorInV8(const char* location, const char* message) } V8Proxy::V8Proxy(Frame* frame) - : m_frame(frame), - m_context(SharedPersistent<v8::Context>::create()), - m_listenerGuard(V8ListenerGuard::create()), - m_inlineCode(false), - m_timerCallback(false), - m_recursion(0) { } + : m_frame(frame) + , m_listenerGuard(V8ListenerGuard::create()) + , m_inlineCode(false) + , m_timerCallback(false) + , m_recursion(0) +{ +} V8Proxy::~V8Proxy() { @@ -311,6 +306,9 @@ void V8Proxy::evaluateInIsolatedWorld(int worldID, const Vector<ScriptSourceCode } else { world = new V8IsolatedWorld(this, extensionGroup); m_isolatedWorlds.set(worldID, world); + + // Setup context id for JS debugger. + setInjectedScriptContextDebugId(world->context()); } } else { world = new V8IsolatedWorld(this, extensionGroup); @@ -332,7 +330,7 @@ void V8Proxy::evaluateInNewContext(const Vector<ScriptSourceCode>& sources, int v8::HandleScope handleScope; // Set up the DOM window as the prototype of the new global object. - v8::Handle<v8::Context> windowContext = context(); + v8::Handle<v8::Context> windowContext = m_context; v8::Handle<v8::Object> windowGlobal = windowContext->Global(); v8::Handle<v8::Object> windowWrapper = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, windowGlobal); @@ -342,14 +340,7 @@ void V8Proxy::evaluateInNewContext(const Vector<ScriptSourceCode>& sources, int v8::Context::Scope contextScope(context); // Setup context id for JS debugger. - v8::Handle<v8::Object> contextData = v8::Object::New(); - v8::Handle<v8::Value> windowContextData = windowContext->GetData(); - if (windowContextData->IsObject()) { - v8::Handle<v8::String> propertyName = v8::String::New(kContextDebugDataValue); - contextData->Set(propertyName, v8::Object::Cast(*windowContextData)->Get(propertyName)); - } - contextData->Set(v8::String::New(kContextDebugDataType), v8::String::New("injected")); - context->SetData(contextData); + setInjectedScriptContextDebugId(context); v8::Handle<v8::Object> global = context->Global(); @@ -375,6 +366,21 @@ void V8Proxy::evaluateInNewContext(const Vector<ScriptSourceCode>& sources, int context.Dispose(); } +void V8Proxy::setInjectedScriptContextDebugId(v8::Handle<v8::Context> targetContext) +{ + // Setup context id for JS debugger. + v8::Context::Scope contextScope(targetContext); + v8::Handle<v8::Object> contextData = v8::Object::New(); + + v8::Handle<v8::Value> windowContextData = m_context->GetData(); + if (windowContextData->IsObject()) { + v8::Handle<v8::String> propertyName = v8::String::New(kContextDebugDataValue); + contextData->Set(propertyName, v8::Object::Cast(*windowContextData)->Get(propertyName)); + } + contextData->Set(v8::String::New(kContextDebugDataType), v8::String::New("injected")); + targetContext->SetData(contextData); +} + v8::Local<v8::Value> V8Proxy::evaluate(const ScriptSourceCode& source, Node* node) { ASSERT(v8::Context::InContext()); @@ -553,8 +559,8 @@ v8::Local<v8::Object> V8Proxy::createWrapperFromCacheSlowCase(V8ClassIndex::V8Wr // Not in cache. int classIndex = V8ClassIndex::ToInt(type); initContextIfNeeded(); - v8::Context::Scope scope(context()); - v8::Local<v8::Function> function = V8DOMWrapper::getConstructor(type, getHiddenObjectPrototype(context())); + v8::Context::Scope scope(m_context); + v8::Local<v8::Function> function = V8DOMWrapper::getConstructor(type, getHiddenObjectPrototype(m_context)); v8::Local<v8::Object> instance = SafeAllocation::newInstance(function); if (!instance.IsEmpty()) { m_wrapperBoilerplates->Set(v8::Integer::New(classIndex), instance); @@ -567,9 +573,9 @@ bool V8Proxy::isContextInitialized() { // m_context, m_global, and m_wrapperBoilerplates should // all be non-empty if if m_context is non-empty. - ASSERT(context().IsEmpty() || !m_global.IsEmpty()); - ASSERT(context().IsEmpty() || !m_wrapperBoilerplates.IsEmpty()); - return !context().IsEmpty(); + ASSERT(m_context.IsEmpty() || !m_global.IsEmpty()); + ASSERT(m_context.IsEmpty() || !m_wrapperBoilerplates.IsEmpty()); + return !m_context.IsEmpty(); } DOMWindow* V8Proxy::retrieveWindow(v8::Handle<v8::Context> context) @@ -722,7 +728,7 @@ void V8Proxy::updateDocumentWrapperCache() { LOCK_V8; v8::HandleScope handleScope; - v8::Context::Scope contextScope(context()); + v8::Context::Scope contextScope(m_context); // If the document has no frame, NodeToV8Object might get the // document wrapper for a document that is about to be deleted. @@ -744,20 +750,21 @@ void V8Proxy::updateDocumentWrapperCache() clearDocumentWrapperCache(); return; } - context()->Global()->ForceSet(v8::String::New("document"), documentWrapper, static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete)); + m_context->Global()->ForceSet(v8::String::New("document"), documentWrapper, static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete)); } void V8Proxy::clearDocumentWrapperCache() { - ASSERT(!context().IsEmpty()); - context()->Global()->ForceDelete(v8::String::New("document")); + ASSERT(!m_context.IsEmpty()); + m_context->Global()->ForceDelete(v8::String::New("document")); } void V8Proxy::disposeContextHandles() { - if (!context().IsEmpty()) { + if (!m_context.IsEmpty()) { m_frame->loader()->client()->didDestroyScriptContextForFrame(); - shared_context()->disposeHandle(); + m_context.Dispose(); + m_context.Clear(); } if (!m_wrapperBoilerplates.IsEmpty()) { @@ -802,8 +809,12 @@ void V8Proxy::clearForClose() { resetIsolatedWorlds(); +<<<<<<< HEAD:WebCore/bindings/v8/V8Proxy.cpp if (!context().IsEmpty()) { LOCK_V8; +======= + if (!m_context.IsEmpty()) { +>>>>>>> webkit.org at r50258.:WebCore/bindings/v8/V8Proxy.cpp v8::HandleScope handleScope; clearDocumentWrapper(); @@ -816,12 +827,16 @@ void V8Proxy::clearForNavigation() disconnectEventListeners(); resetIsolatedWorlds(); +<<<<<<< HEAD:WebCore/bindings/v8/V8Proxy.cpp if (!context().IsEmpty()) { LOCK_V8; +======= + if (!m_context.IsEmpty()) { +>>>>>>> webkit.org at r50258.:WebCore/bindings/v8/V8Proxy.cpp v8::HandleScope handle; clearDocumentWrapper(); - v8::Context::Scope contextScope(context()); + v8::Context::Scope contextScope(m_context); // Clear the document wrapper cache before turning on access checks on // the old DOMWindow wrapper. This way, access to the document wrapper @@ -834,7 +849,7 @@ void V8Proxy::clearForNavigation() wrapper->TurnOnAccessCheck(); // Separate the context from its global object. - context()->DetachGlobal(); + m_context->DetachGlobal(); disposeContextHandles(); } @@ -845,7 +860,7 @@ void V8Proxy::setSecurityToken() Document* document = m_frame->document(); // Setup security origin and security token. if (!document) { - context()->UseDefaultSecurityToken(); + m_context->UseDefaultSecurityToken(); return; } @@ -865,14 +880,14 @@ void V8Proxy::setSecurityToken() // case, we use the global object as the security token to avoid // calling canAccess when a script accesses its own objects. if (token.isEmpty() || token == "null") { - context()->UseDefaultSecurityToken(); + m_context->UseDefaultSecurityToken(); return; } CString utf8Token = token.utf8(); // NOTE: V8 does identity comparison in fast path, must use a symbol // as the security token. - context()->SetSecurityToken(v8::String::NewSymbol(utf8Token.data(), utf8Token.length())); + m_context->SetSecurityToken(v8::String::NewSymbol(utf8Token.data(), utf8Token.length())); } void V8Proxy::updateDocument() @@ -891,7 +906,7 @@ void V8Proxy::updateDocument() initContextIfNeeded(); // Bail out if context initialization failed. - if (context().IsEmpty()) + if (m_context.IsEmpty()) return; // We have a new document and we need to update the cache. @@ -1100,7 +1115,7 @@ bool V8Proxy::installDOMWindow(v8::Handle<v8::Context> context, DOMWindow* windo void V8Proxy::initContextIfNeeded() { // Bail out if the context has already been initialized. - if (!context().IsEmpty()) + if (!m_context.IsEmpty()) return; #ifdef ANDROID_INSTRUMENT @@ -1130,17 +1145,16 @@ void V8Proxy::initContextIfNeeded() } - v8::Persistent<v8::Context> context = createNewContext(m_global, 0); - if (context.IsEmpty()) + m_context = createNewContext(m_global, 0); + if (m_context.IsEmpty()) return; - m_context->set(context); - - v8::Context::Scope contextScope(context); + v8::Local<v8::Context> v8Context = v8::Local<v8::Context>::New(m_context); + v8::Context::Scope contextScope(v8Context); // Store the first global object created so we can reuse it. if (m_global.IsEmpty()) { - m_global = v8::Persistent<v8::Object>::New(context->Global()); + m_global = v8::Persistent<v8::Object>::New(v8Context->Global()); // Bail out if allocation of the first global objects fails. if (m_global.IsEmpty()) { disposeContextHandles(); @@ -1151,7 +1165,7 @@ void V8Proxy::initContextIfNeeded() #endif } - installHiddenObjectPrototype(context); + installHiddenObjectPrototype(v8Context); m_wrapperBoilerplates = v8::Persistent<v8::Array>::New(v8::Array::New(V8ClassIndex::WRAPPER_TYPE_COUNT)); // Bail out if allocation failed. if (m_wrapperBoilerplates.IsEmpty()) { @@ -1162,7 +1176,7 @@ void V8Proxy::initContextIfNeeded() V8GCController::registerGlobalHandle(PROXY, this, m_wrapperBoilerplates); #endif - if (!installDOMWindow(context, m_frame->domWindow())) + if (!installDOMWindow(v8Context, m_frame->domWindow())) disposeContextHandles(); updateDocument(); @@ -1248,21 +1262,16 @@ v8::Local<v8::Context> V8Proxy::context(Frame* frame) return context; } -PassRefPtr<SharedPersistent<v8::Context> > V8Proxy::shared_context(Frame* frame) +v8::Local<v8::Context> V8Proxy::context() { - V8Proxy *proxy = V8Proxy::retrieve(frame); - if (!proxy) - return 0; - - proxy->initContextIfNeeded(); - RefPtr<SharedPersistent<v8::Context> > context = proxy->shared_context(); if (V8IsolatedWorld* world = V8IsolatedWorld::getEntered()) { - context = world->shared_context(); - if (frame != V8Proxy::retrieveFrame(context->get())) - return 0; + RefPtr<SharedPersistent<v8::Context> > context = world->sharedContext(); + if (m_frame != V8Proxy::retrieveFrame(context->get())) + return v8::Local<v8::Context>(); + return v8::Local<v8::Context>::New(context->get()); } - - return context; + initContextIfNeeded(); + return v8::Local<v8::Context>::New(m_context);; } v8::Local<v8::Context> V8Proxy::mainWorldContext(Frame* frame) @@ -1272,7 +1281,7 @@ v8::Local<v8::Context> V8Proxy::mainWorldContext(Frame* frame) return v8::Local<v8::Context>(); proxy->initContextIfNeeded(); - return v8::Local<v8::Context>::New(proxy->context()); + return v8::Local<v8::Context>::New(proxy->m_context); } v8::Local<v8::Context> V8Proxy::currentContext() @@ -1416,17 +1425,17 @@ void V8Proxy::registerExtension(v8::Extension* extension, int extensionGroup) bool V8Proxy::setContextDebugId(int debugId) { ASSERT(debugId > 0); - if (context().IsEmpty()) + if (m_context.IsEmpty()) return false; v8::HandleScope scope; - if (!context()->GetData()->IsUndefined()) + if (!m_context->GetData()->IsUndefined()) return false; - v8::Context::Scope contextScope(context()); + v8::Context::Scope contextScope(m_context); v8::Handle<v8::Object> contextData = v8::Object::New(); contextData->Set(v8::String::New(kContextDebugDataType), v8::String::New("page")); contextData->Set(v8::String::New(kContextDebugDataValue), v8::Integer::New(debugId)); - context()->SetData(contextData); + m_context->SetData(contextData); return true; } @@ -1459,4 +1468,16 @@ void V8Proxy::installHiddenObjectPrototype(v8::Handle<v8::Context> context) context->Global()->SetHiddenValue(hiddenObjectPrototypeString, objectPrototype); } +v8::Local<v8::Context> toV8Context(ScriptExecutionContext* context) +{ + if (context->isDocument()) { + if (V8Proxy* proxy = V8Proxy::retrieve(context)) + return proxy->context(); + } else if (context->isWorkerContext()) { + if (WorkerContextExecutionProxy* proxy = static_cast<WorkerContext*>(context)->script()->proxy()) + return proxy->context(); + } + return v8::Local<v8::Context>(); +} + } // namespace WebCore diff --git a/WebCore/bindings/v8/V8Proxy.h b/WebCore/bindings/v8/V8Proxy.h index 30f682d..86d3b39 100644 --- a/WebCore/bindings/v8/V8Proxy.h +++ b/WebCore/bindings/v8/V8Proxy.h @@ -82,6 +82,16 @@ namespace WebCore { void batchConfigureAttributes(v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::ObjectTemplate>, const BatchedAttribute*, size_t attributeCount); + inline void configureAttribute(v8::Handle<v8::ObjectTemplate> instance, v8::Handle<v8::ObjectTemplate> proto, const BatchedAttribute& attribute) + { + (attribute.onProto ? proto : instance)->SetAccessor(v8::String::New(attribute.name), + attribute.getter, + attribute.setter, + attribute.data == V8ClassIndex::INVALID_CLASS_INDEX ? v8::Handle<v8::Value>() : v8::Integer::New(V8ClassIndex::ToInt(attribute.data)), + attribute.settings, + attribute.attribute); + } + // BatchedConstant translates into calls to Set() for setting up an object's // constants. It sets the constant on both the FunctionTemplate and the // ObjectTemplate. PropertyAttributes is always ReadOnly. @@ -251,7 +261,6 @@ namespace WebCore { // Returns V8 Context of a frame. If none exists, creates // a new context. It is potentially slow and consumes memory. static v8::Local<v8::Context> context(Frame*); - static PassRefPtr<SharedPersistent<v8::Context> > shared_context(Frame*); static v8::Local<v8::Context> mainWorldContext(Frame*); static v8::Local<v8::Context> currentContext(); @@ -296,15 +305,7 @@ namespace WebCore { static int sourceLineNumber(); static String sourceName(); - v8::Handle<v8::Context> context() - { - return m_context->get(); - } - - PassRefPtr<SharedPersistent<v8::Context> > shared_context() - { - return m_context; - } + v8::Local<v8::Context> context(); PassRefPtr<V8ListenerGuard> listenerGuard() { @@ -360,6 +361,8 @@ namespace WebCore { void resetIsolatedWorlds(); + void setInjectedScriptContextDebugId(v8::Handle<v8::Context> targetContext); + static bool canAccessPrivate(DOMWindow*); static const char* rangeExceptionName(int exceptionCode); @@ -392,7 +395,7 @@ namespace WebCore { Frame* m_frame; - RefPtr<SharedPersistent<v8::Context> > m_context; + v8::Persistent<v8::Context> m_context; RefPtr<V8ListenerGuard> m_listenerGuard; @@ -453,6 +456,8 @@ namespace WebCore { } + v8::Local<v8::Context> toV8Context(ScriptExecutionContext*); + // Used by an interceptor callback that it hasn't found anything to // intercept. inline static v8::Local<v8::Object> notHandledByInterceptor() diff --git a/WebCore/bindings/v8/V8Utilities.cpp b/WebCore/bindings/v8/V8Utilities.cpp index a66f435..ecac358 100644 --- a/WebCore/bindings/v8/V8Utilities.cpp +++ b/WebCore/bindings/v8/V8Utilities.cpp @@ -135,9 +135,13 @@ void reportException(ScriptState* scriptState, v8::TryCatch& exceptionCatcher) // There can be a situation that an exception is thrown without setting a message. v8::Local<v8::Message> message = exceptionCatcher.Message(); - if (message.IsEmpty()) - errorMessage = toWebCoreString(exceptionCatcher.Exception()->ToString()); - else { + if (message.IsEmpty()) { + v8::Local<v8::String> exceptionString = exceptionCatcher.Exception()->ToString(); + // Conversion of the exception object to string can fail if an + // exception is thrown during conversion. + if (!exceptionString.IsEmpty()) + errorMessage = toWebCoreString(exceptionString); + } else { errorMessage = toWebCoreString(message->Get()); lineNumber = message->GetLineNumber(); sourceURL = toWebCoreString(message->GetScriptResourceName()); diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp index 24e493c..79911ae 100644 --- a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp +++ b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp @@ -36,18 +36,28 @@ #include "Event.h" #include "V8Binding.h" +<<<<<<< HEAD:WebCore/bindings/v8/V8WorkerContextEventListener.cpp #include "V8Utilities.h" +======= +#include "WorkerContext.h" +>>>>>>> webkit.org at r50258.:WebCore/bindings/v8/V8WorkerContextEventListener.cpp #include "WorkerContextExecutionProxy.h" namespace WebCore { -V8WorkerContextEventListener::V8WorkerContextEventListener(WorkerContextExecutionProxy* proxy, PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isInline) - : V8EventListener(0, guard, listener, isInline) - , m_proxy(proxy) +static WorkerContextExecutionProxy* workerProxy(ScriptExecutionContext* context) { + ASSERT(context->isWorkerContext()); + WorkerContext* workerContext = static_cast<WorkerContext*>(context); + return workerContext->script()->proxy(); } -void V8WorkerContextEventListener::handleEvent(ScriptExecutionContext*, Event* event) +V8WorkerContextEventListener::V8WorkerContextEventListener(PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isInline) + : V8EventListener(guard, listener, isInline) +{ +} + +void V8WorkerContextEventListener::handleEvent(ScriptExecutionContext* context, Event* event) { // Is the EventListener disconnected? if (disconnected()) @@ -60,12 +70,16 @@ void V8WorkerContextEventListener::handleEvent(ScriptExecutionContext*, Event* e LOCK_V8; v8::HandleScope handleScope; - v8::Handle<v8::Context> context = m_proxy->context(); - if (context.IsEmpty()) + WorkerContextExecutionProxy* proxy = workerProxy(context); + if (!proxy) + return; + + v8::Handle<v8::Context> v8Context = proxy->context(); + if (v8Context.IsEmpty()) return; // Enter the V8 context in which to perform the event handling. - v8::Context::Scope scope(context); + v8::Context::Scope scope(v8Context); // Get the V8 wrapper for the event object. v8::Handle<v8::Value> jsEvent = WorkerContextExecutionProxy::convertEventToV8Object(event); @@ -73,7 +87,7 @@ void V8WorkerContextEventListener::handleEvent(ScriptExecutionContext*, Event* e invokeEventHandler(context, event, jsEvent); } -bool V8WorkerContextEventListener::reportError(const String& message, const String& url, int lineNumber) +bool V8WorkerContextEventListener::reportError(ScriptExecutionContext* context, const String& message, const String& url, int lineNumber) { // Is the EventListener disconnected? if (disconnected()) @@ -84,14 +98,18 @@ bool V8WorkerContextEventListener::reportError(const String& message, const Stri v8::HandleScope handleScope; - v8::Handle<v8::Context> context = m_proxy->context(); - if (context.IsEmpty()) + WorkerContextExecutionProxy* proxy = workerProxy(context); + if (!proxy) + return false; + + v8::Handle<v8::Context> v8Context = proxy->context(); + if (v8Context.IsEmpty()) return false; // Enter the V8 context in which to perform the event handling. - v8::Context::Scope scope(context); + v8::Context::Scope scope(v8Context); - v8::Local<v8::Object> listener = getListenerObject(); + v8::Local<v8::Object> listener = getListenerObject(context); v8::Local<v8::Value> returnValue; { // Catch exceptions thrown in calling the function so they do not propagate to javascript code that caused the event to fire. @@ -120,24 +138,25 @@ bool V8WorkerContextEventListener::reportError(const String& message, const Stri return errorHandled; } -v8::Local<v8::Value> V8WorkerContextEventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event) +v8::Local<v8::Value> V8WorkerContextEventListener::callListenerFunction(ScriptExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event) { - v8::Local<v8::Function> handlerFunction = getListenerFunction(); - v8::Local<v8::Object> receiver = getReceiverObject(event); + v8::Local<v8::Function> handlerFunction = getListenerFunction(context); + v8::Local<v8::Object> receiver = getReceiverObject(context, event); if (handlerFunction.IsEmpty() || receiver.IsEmpty()) return v8::Local<v8::Value>(); v8::Handle<v8::Value> parameters[1] = { jsEvent }; v8::Local<v8::Value> result = handlerFunction->Call(receiver, 1, parameters); - m_proxy->trackEvent(event); + if (WorkerContextExecutionProxy* proxy = workerProxy(context)) + proxy->trackEvent(event); return result; } -v8::Local<v8::Object> V8WorkerContextEventListener::getReceiverObject(Event* event) +v8::Local<v8::Object> V8WorkerContextEventListener::getReceiverObject(ScriptExecutionContext* context, Event* event) { - v8::Local<v8::Object> listener = getListenerObject(); + v8::Local<v8::Object> listener = getListenerObject(context); if (!listener.IsEmpty() && !listener->IsFunction()) return listener; diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.h b/WebCore/bindings/v8/V8WorkerContextEventListener.h index 3752533..3f9f862 100644 --- a/WebCore/bindings/v8/V8WorkerContextEventListener.h +++ b/WebCore/bindings/v8/V8WorkerContextEventListener.h @@ -44,22 +44,19 @@ namespace WebCore { class V8WorkerContextEventListener : public V8EventListener { public: - static PassRefPtr<V8WorkerContextEventListener> create(WorkerContextExecutionProxy* proxy, PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isInline) + static PassRefPtr<V8WorkerContextEventListener> create(PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isInline) { - return adoptRef(new V8WorkerContextEventListener(proxy, guard, listener, isInline)); + return adoptRef(new V8WorkerContextEventListener(guard, listener, isInline)); } virtual void handleEvent(ScriptExecutionContext*, Event*); - virtual bool reportError(const String& message, const String& url, int lineNumber); - - WorkerContextExecutionProxy* proxy() const { return m_proxy; } + virtual bool reportError(ScriptExecutionContext*, const String& message, const String& url, int lineNumber); private: - V8WorkerContextEventListener(WorkerContextExecutionProxy*, PassRefPtr<V8ListenerGuard>, v8::Local<v8::Object> listener, bool isInline); + V8WorkerContextEventListener(PassRefPtr<V8ListenerGuard>, v8::Local<v8::Object> listener, bool isInline); - virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*); - v8::Local<v8::Object> getReceiverObject(Event*); - WorkerContextExecutionProxy* m_proxy; + virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*); + v8::Local<v8::Object> getReceiverObject(ScriptExecutionContext*, Event*); }; } // namespace WebCore diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp index 90c1f6f..128f486 100644 --- a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp +++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp @@ -43,6 +43,8 @@ #include "EventException.h" #include "MessagePort.h" #include "RangeException.h" +#include "SharedWorker.h" +#include "SharedWorkerContext.h" #include "V8Binding.h" #include "V8DOMMap.h" #include "V8Index.h" @@ -126,10 +128,18 @@ void WorkerContextExecutionProxy::initV8IfNeeded() v8::V8::IgnoreOutOfMemoryException(); v8::V8::SetFatalErrorHandler(reportFatalErrorInV8); +<<<<<<< HEAD:WebCore/bindings/v8/WorkerContextExecutionProxy.cpp #if PLATFORM(ANDROID) const int workerThreadPreemptionIntervalMs = 5; v8::Locker::StartPreemption(workerThreadPreemptionIntervalMs); #endif +======= + v8::ResourceConstraints resource_constraints; + uint32_t here; + resource_constraints.set_stack_limit(&here - kWorkerMaxStackSize / sizeof(uint32_t*)); + v8::SetResourceConstraints(&resource_constraints); + +>>>>>>> webkit.org at r50258.:WebCore/bindings/v8/WorkerContextExecutionProxy.cpp v8Initialized = true; } @@ -405,7 +415,7 @@ v8::Local<v8::Value> WorkerContextExecutionProxy::runScript(v8::Handle<v8::Scrip PassRefPtr<V8EventListener> WorkerContextExecutionProxy::findOrCreateEventListener(v8::Local<v8::Value> object, bool isInline, bool findOnly) { - return findOnly ? V8EventListenerList::findWrapper(object, isInline) : V8EventListenerList::findOrCreateWrapper<V8WorkerContextEventListener>(this, m_listenerGuard, object, isInline); + return findOnly ? V8EventListenerList::findWrapper(object, isInline) : V8EventListenerList::findOrCreateWrapper<V8WorkerContextEventListener>(m_listenerGuard, object, isInline); } void WorkerContextExecutionProxy::trackEvent(Event* event) diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.h b/WebCore/bindings/v8/WorkerContextExecutionProxy.h index a08395c..e723bc6 100644 --- a/WebCore/bindings/v8/WorkerContextExecutionProxy.h +++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.h @@ -107,6 +107,8 @@ namespace WebCore { static bool forgetV8EventObject(Event*); + static const int kWorkerMaxStackSize = 500 * 1024; + WorkerContext* m_workerContext; v8::Persistent<v8::Context> m_context; int m_recursion; diff --git a/WebCore/bindings/v8/custom/V8CustomBinding.h b/WebCore/bindings/v8/custom/V8CustomBinding.h index 82ce1c1..7781fbc 100644 --- a/WebCore/bindings/v8/custom/V8CustomBinding.h +++ b/WebCore/bindings/v8/custom/V8CustomBinding.h @@ -78,6 +78,8 @@ struct NPObject; bool V8Custom::v8##NAME##IndexedSecurityCheck(v8::Local<v8::Object> host, \ uint32_t index, v8::AccessType type, v8::Local<v8::Value> data) +#define ACCESSOR_RUNTIME_ENABLER(NAME) bool V8Custom::v8##NAME##Enabled() + namespace WebCore { class DOMWindow; @@ -122,17 +124,25 @@ namespace WebCore { static const int kMessagePortInternalFieldCount = kDefaultWrapperInternalFieldCount + 2; #if ENABLE(WORKERS) - static const int kWorkerRequestCacheIndex = kDefaultWrapperInternalFieldCount + 0; - static const int kWorkerInternalFieldCount = kDefaultWrapperInternalFieldCount + 1; + static const int kAbstractWorkerRequestCacheIndex = kDefaultWrapperInternalFieldCount + 0; + static const int kAbstractWorkerInternalFieldCount = kDefaultWrapperInternalFieldCount + 1; + + static const int kWorkerRequestCacheIndex = kAbstractWorkerInternalFieldCount + 0; + static const int kWorkerInternalFieldCount = kAbstractWorkerInternalFieldCount + 1; static const int kWorkerContextRequestCacheIndex = kDefaultWrapperInternalFieldCount + 0; static const int kWorkerContextMinimumInternalFieldCount = kDefaultWrapperInternalFieldCount + 1; static const int kDedicatedWorkerContextRequestCacheIndex = kWorkerContextMinimumInternalFieldCount + 0; static const int kDedicatedWorkerContextInternalFieldCount = kWorkerContextMinimumInternalFieldCount + 1; +#endif - static const int kAbstractWorkerRequestCacheIndex = kDefaultWrapperInternalFieldCount + 0; - static const int kAbstractWorkerInternalFieldCount = kDefaultWrapperInternalFieldCount + 1; +#if ENABLE(SHARED_WORKERS) + static const int kSharedWorkerRequestCacheIndex = kAbstractWorkerInternalFieldCount + 0; + static const int kSharedWorkerInternalFieldCount = kAbstractWorkerInternalFieldCount + 1; + + static const int kSharedWorkerContextRequestCacheIndex = kWorkerContextMinimumInternalFieldCount + 0; + static const int kSharedWorkerContextInternalFieldCount = kWorkerContextMinimumInternalFieldCount + 1; #endif #if ENABLE(NOTIFICATIONS) @@ -232,6 +242,8 @@ namespace WebCore { static bool v8##NAME##IndexedSecurityCheck(v8::Local<v8::Object> host, \ uint32_t index, v8::AccessType type, v8::Local<v8::Value> data) +#define DECLARE_ACCESSOR_RUNTIME_ENABLER(NAME) static bool v8##NAME##Enabled() + DECLARE_PROPERTY_ACCESSOR(CanvasRenderingContext2DStrokeStyle); DECLARE_PROPERTY_ACCESSOR(CanvasRenderingContext2DFillStyle); DECLARE_PROPERTY_ACCESSOR(DOMWindowEvent); @@ -241,6 +253,11 @@ namespace WebCore { #if ENABLE(VIDEO) DECLARE_PROPERTY_ACCESSOR_GETTER(DOMWindowAudio); + DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowAudio); + DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowHTMLMediaElement); + DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowHTMLAudioElement); + DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowHTMLVideoElement); + DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowMediaError); #endif DECLARE_PROPERTY_ACCESSOR_GETTER(DOMWindowImage); @@ -280,6 +297,10 @@ namespace WebCore { DECLARE_CALLBACK(HTMLCollectionNamedItem); DECLARE_CALLBACK(HTMLCollectionCallAsFunction); + DECLARE_CALLBACK(HTMLAllCollectionItem); + DECLARE_CALLBACK(HTMLAllCollectionNamedItem); + DECLARE_CALLBACK(HTMLAllCollectionCallAsFunction); + DECLARE_CALLBACK(HTMLSelectElementRemove); DECLARE_CALLBACK(HTMLOptionsCollectionRemove); @@ -448,7 +469,6 @@ namespace WebCore { DECLARE_CALLBACK(TreeWalkerNextSibling); DECLARE_CALLBACK(TreeWalkerPreviousSibling); - DECLARE_CALLBACK(InspectorBackendProfiles); DECLARE_CALLBACK(InspectorBackendHighlightDOMNode); DECLARE_CALLBACK(InspectorBackendAddResourceSourceToFrame); DECLARE_CALLBACK(InspectorBackendAddSourceToFrame); @@ -505,6 +525,7 @@ namespace WebCore { DECLARE_INDEXED_PROPERTY_SETTER(HTMLOptionsCollection); DECLARE_NAMED_PROPERTY_GETTER(HTMLSelectElementCollection); DECLARE_INDEXED_PROPERTY_SETTER(HTMLSelectElementCollection); + DECLARE_NAMED_PROPERTY_GETTER(HTMLAllCollection); DECLARE_NAMED_PROPERTY_GETTER(HTMLCollection); #if ENABLE(3D_CANVAS) @@ -553,14 +574,20 @@ namespace WebCore { DECLARE_INDEXED_PROPERTY_GETTER(ClientRectList); DECLARE_INDEXED_PROPERTY_GETTER(FileList); - + #if ENABLE(DATAGRID) DECLARE_PROPERTY_ACCESSOR(HTMLDataGridElementDataSource); DECLARE_INDEXED_PROPERTY_GETTER(DataGridColumnList); DECLARE_NAMED_PROPERTY_GETTER(DataGridColumnList); -#endif +#endif + +#if ENABLE(DATABASE) + DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowOpenDatabase); +#endif #if ENABLE(DOM_STORAGE) + DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowLocalStorage); + DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowSessionStorage); DECLARE_INDEXED_PROPERTY_GETTER(Storage); DECLARE_INDEXED_PROPERTY_SETTER(Storage); DECLARE_INDEXED_PROPERTY_DELETER(Storage); @@ -604,6 +631,10 @@ namespace WebCore { DECLARE_CALLBACK(WorkerContextClearInterval); DECLARE_CALLBACK(WorkerContextAddEventListener); DECLARE_CALLBACK(WorkerContextRemoveEventListener); + +#if ENABLE(NOTIFICATIONS) + DECLARE_ACCESSOR_RUNTIME_ENABLER(WorkerContextWebkitNotifications); +#endif #endif // ENABLE(WORKERS) #if ENABLE(NOTIFICATIONS) @@ -624,6 +655,11 @@ namespace WebCore { #if ENABLE(SHARED_WORKERS) DECLARE_CALLBACK(SharedWorkerConstructor); + DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowSharedWorker); +#endif + +#if ENABLE(NOTIFICATIONS) + DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowWebkitNotifications); #endif DECLARE_CALLBACK(GeolocationGetCurrentPosition); @@ -638,8 +674,11 @@ namespace WebCore { DECLARE_PROPERTY_ACCESSOR(WebSocketOnmessage); DECLARE_PROPERTY_ACCESSOR(WebSocketOnclose); DECLARE_CALLBACK(WebSocketConstructor); + DECLARE_CALLBACK(WebSocketAddEventListener); + DECLARE_CALLBACK(WebSocketRemoveEventListener); DECLARE_CALLBACK(WebSocketSend); DECLARE_CALLBACK(WebSocketClose); + DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowWebSocket); #endif #undef DECLARE_INDEXED_ACCESS_CHECK diff --git a/WebCore/bindings/v8/custom/V8CustomEventListener.cpp b/WebCore/bindings/v8/custom/V8CustomEventListener.cpp index 91abecd..17c86a3 100644 --- a/WebCore/bindings/v8/custom/V8CustomEventListener.cpp +++ b/WebCore/bindings/v8/custom/V8CustomEventListener.cpp @@ -35,15 +35,15 @@ namespace WebCore { -V8EventListener::V8EventListener(Frame* frame, PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isAttribute) - : V8AbstractEventListener(frame, guard, isAttribute) +V8EventListener::V8EventListener(PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isAttribute) + : V8AbstractEventListener(guard, isAttribute) { setListenerObject(listener); } -v8::Local<v8::Function> V8EventListener::getListenerFunction() +v8::Local<v8::Function> V8EventListener::getListenerFunction(ScriptExecutionContext* context) { - v8::Local<v8::Object> listener = getListenerObject(); + v8::Local<v8::Object> listener = getListenerObject(context); // Has the listener been disposed? if (listener.IsEmpty()) @@ -61,19 +61,20 @@ v8::Local<v8::Function> V8EventListener::getListenerFunction() return v8::Local<v8::Function>(); } -v8::Local<v8::Value> V8EventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event) +v8::Local<v8::Value> V8EventListener::callListenerFunction(ScriptExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event) { - v8::Local<v8::Function> handlerFunction = getListenerFunction(); + + v8::Local<v8::Function> handlerFunction = getListenerFunction(context); v8::Local<v8::Object> receiver = getReceiverObject(event); if (handlerFunction.IsEmpty() || receiver.IsEmpty()) return v8::Local<v8::Value>(); v8::Handle<v8::Value> parameters[1] = { jsEvent }; - V8Proxy* proxy = V8Proxy::retrieve(frame()); - if (!proxy) - return v8::Local<v8::Value>(); - return proxy->callFunction(handlerFunction, receiver, 1, parameters); + if (V8Proxy* proxy = V8Proxy::retrieve(context)) + return proxy->callFunction(handlerFunction, receiver, 1, parameters); + + return v8::Local<v8::Value>(); } } // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8CustomEventListener.h b/WebCore/bindings/v8/custom/V8CustomEventListener.h index e34f24f..dc9d33b 100644 --- a/WebCore/bindings/v8/custom/V8CustomEventListener.h +++ b/WebCore/bindings/v8/custom/V8CustomEventListener.h @@ -44,18 +44,18 @@ namespace WebCore { // that can handle the event. class V8EventListener : public V8AbstractEventListener { public: - static PassRefPtr<V8EventListener> create(Frame* frame, PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isAttribute) + static PassRefPtr<V8EventListener> create(PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isAttribute) { - return adoptRef(new V8EventListener(frame, guard, listener, isAttribute)); + return adoptRef(new V8EventListener(guard, listener, isAttribute)); } protected: - V8EventListener(Frame*, PassRefPtr<V8ListenerGuard>, v8::Local<v8::Object> listener, bool isAttribute); + V8EventListener(PassRefPtr<V8ListenerGuard>, v8::Local<v8::Object> listener, bool isAttribute); - v8::Local<v8::Function> getListenerFunction(); + v8::Local<v8::Function> getListenerFunction(ScriptExecutionContext*); private: - virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*); + virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*); }; } // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp index 0dc5a96..7eccfb1 100644 --- a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp +++ b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp @@ -45,12 +45,18 @@ #include "FrameLoadRequest.h" #include "FrameView.h" #include "HTMLCollection.h" +#include "MediaPlayer.h" +#include "NotificationCenter.h" #include "Page.h" #include "PlatformScreen.h" +#include "RuntimeEnabledFeatures.h" #include "ScheduledAction.h" #include "ScriptSourceCode.h" #include "SerializedScriptValue.h" #include "Settings.h" +#include "SharedWorkerRepository.h" +#include "Storage.h" +#include "WebSocket.h" #include "WindowFeatures.h" // Horizontal and vertical offset, from the parent content area, around newly @@ -235,6 +241,71 @@ ACCESSOR_GETTER(DOMWindowAudio) return V8DOMWrapper::getConstructor(V8ClassIndex::AUDIO, window); } +ACCESSOR_RUNTIME_ENABLER(DOMWindowAudio) +{ + return MediaPlayer::isAvailable(); +} + +ACCESSOR_RUNTIME_ENABLER(DOMWindowHTMLMediaElement) +{ + return MediaPlayer::isAvailable(); +} + +ACCESSOR_RUNTIME_ENABLER(DOMWindowHTMLAudioElement) +{ + return MediaPlayer::isAvailable(); +} + +ACCESSOR_RUNTIME_ENABLER(DOMWindowHTMLVideoElement) +{ + return MediaPlayer::isAvailable(); +} + +ACCESSOR_RUNTIME_ENABLER(DOMWindowMediaError) +{ + return MediaPlayer::isAvailable(); +} + +#endif + +#if ENABLE(SHARED_WORKERS) +ACCESSOR_RUNTIME_ENABLER(DOMWindowSharedWorker) +{ + return SharedWorkerRepository::isAvailable(); +} +#endif + +#if ENABLE(WEB_SOCKETS) +ACCESSOR_RUNTIME_ENABLER(DOMWindowWebSocket) +{ + return WebSocket::isAvailable(); +} +#endif + +#if ENABLE(DATABASE) +ACCESSOR_RUNTIME_ENABLER(DOMWindowOpenDatabase) +{ + return WebCore::RuntimeEnabledFeatures::databaseEnabled(); +} +#endif + +#if ENABLE(DOM_STORAGE) +ACCESSOR_RUNTIME_ENABLER(DOMWindowLocalStorage) +{ + return RuntimeEnabledFeatures::localStorageEnabled(); +} + +ACCESSOR_RUNTIME_ENABLER(DOMWindowSessionStorage) +{ + return RuntimeEnabledFeatures::sessionStorageEnabled(); +} +#endif + +#if ENABLE(NOTIFICATIONS) +ACCESSOR_RUNTIME_ENABLER(DOMWindowWebkitNotifications) +{ + return NotificationCenter::isAvailable(); +} #endif ACCESSOR_GETTER(DOMWindowImage) diff --git a/WebCore/bindings/v8/custom/V8HTMLAllCollectionCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLAllCollectionCustom.cpp new file mode 100644 index 0000000..419f374 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8HTMLAllCollectionCustom.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 "HTMLAllCollection.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8NamedNodesCollection.h" +#include "V8Proxy.h" + +namespace WebCore { + +static v8::Handle<v8::Value> getNamedItems(HTMLAllCollection* collection, AtomicString name) +{ + Vector<RefPtr<Node> > namedItems; + collection->namedItems(name, namedItems); + + if (!namedItems.size()) + return v8::Handle<v8::Value>(); + + if (namedItems.size() == 1) + return V8DOMWrapper::convertNodeToV8Object(namedItems.at(0).release()); + + NodeList* list = new V8NamedNodesCollection(namedItems); + return V8DOMWrapper::convertToV8Object(V8ClassIndex::NODELIST, list); +} + +static v8::Handle<v8::Value> getItem(HTMLAllCollection* 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 V8DOMWrapper::convertNodeToV8Object(result.release()); +} + +NAMED_PROPERTY_GETTER(HTMLAllCollection) +{ + INC_STATS("DOM.HTMLAllCollection.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. + HTMLAllCollection* imp = V8DOMWrapper::convertToNativeObject<HTMLAllCollection>(V8ClassIndex::HTMLALLCOLLECTION, info.Holder()); + return getNamedItems(imp, v8StringToAtomicWebCoreString(name)); +} + +CALLBACK_FUNC_DECL(HTMLAllCollectionItem) +{ + INC_STATS("DOM.HTMLAllCollection.item()"); + HTMLAllCollection* imp = V8DOMWrapper::convertToNativeObject<HTMLAllCollection>(V8ClassIndex::HTMLALLCOLLECTION, args.Holder()); + return getItem(imp, args[0]); +} + +CALLBACK_FUNC_DECL(HTMLAllCollectionNamedItem) +{ + INC_STATS("DOM.HTMLAllCollection.namedItem()"); + HTMLAllCollection* imp = V8DOMWrapper::convertToNativeObject<HTMLAllCollection>(V8ClassIndex::HTMLALLCOLLECTION, args.Holder()); + v8::Handle<v8::Value> result = getNamedItems(imp, toWebCoreString(args[0])); + + if (result.IsEmpty()) + return v8::Undefined(); + + return result; +} + +CALLBACK_FUNC_DECL(HTMLAllCollectionCallAsFunction) +{ + INC_STATS("DOM.HTMLAllCollection.callAsFunction()"); + if (args.Length() < 1) + return v8::Undefined(); + + HTMLAllCollection* imp = V8DOMWrapper::convertToNativeObject<HTMLAllCollection>(V8ClassIndex::HTMLALLCOLLECTION, 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 V8DOMWrapper::convertNodeToV8Object(node); + + node = imp->nextNamedItem(name); + current--; + } + + return v8::Undefined(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp b/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp index c735c49..c82d88a 100644 --- a/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp +++ b/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp @@ -81,8 +81,11 @@ CALLBACK_FUNC_DECL(HTMLAudioElementConstructor) V8DOMWrapper::convertNodeToV8Object(document); RefPtr<HTMLAudioElement> audio = new HTMLAudioElement(HTMLNames::audioTag, document); - if (args.Length() > 0) + audio->setAutobuffer(true); + if (args.Length() > 0) { audio->setSrc(toWebCoreString(args[0])); + audio->scheduleLoad(); + } V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::NODE), audio.get()); audio->ref(); diff --git a/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp index a0c3d74..afc9ed1 100644 --- a/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp +++ b/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp @@ -32,6 +32,7 @@ #include "HTMLDocument.h" #include "Frame.h" +#include "HTMLAllCollection.h" #include "HTMLCollection.h" #include "HTMLIFrameElement.h" #include "HTMLNames.h" diff --git a/WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp b/WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp index e470bc8..de53ac7 100644 --- a/WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp +++ b/WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp @@ -38,7 +38,6 @@ #include "Frame.h" #include "V8Binding.h" #include "V8CustomBinding.h" -#include "V8ObjectEventListener.h" #include "V8Proxy.h" #include "V8Utilities.h" #include "WorkerContext.h" @@ -53,7 +52,7 @@ CALLBACK_FUNC_DECL(SharedWorkerConstructor) if (!args.IsConstructCall()) return throwError("DOM object constructor cannot be called as a function."); - if (args.Length() < 1) + if (!args.Length()) return throwError("Not enough arguments", V8Proxy::SyntaxError); v8::TryCatch tryCatch; @@ -73,17 +72,19 @@ CALLBACK_FUNC_DECL(SharedWorkerConstructor) if (!context) return v8::Undefined(); - // Create the worker object. + // Create the SharedWorker object. // Note: it's OK to let this RefPtr go out of scope because we also call SetDOMWrapper(), which effectively holds a reference to obj. ExceptionCode ec = 0; RefPtr<SharedWorker> obj = SharedWorker::create(toWebCoreString(scriptUrl), name, context, ec); + if (ec) + return throwError(ec); // Setup the standard wrapper object internal fields. v8::Handle<v8::Object> wrapperObject = args.Holder(); - V8Proxy::setDOMWrapper(wrapperObject, V8ClassIndex::SHAREDWORKER, obj.get()); + V8DOMWrapper::setDOMWrapper(wrapperObject, V8ClassIndex::SHAREDWORKER, obj.get()); obj->ref(); - V8Proxy::setJSWrapperForActiveDOMObject(obj.get(), v8::Persistent<v8::Object>::New(wrapperObject)); + V8DOMWrapper::setJSWrapperForActiveDOMObject(obj.get(), v8::Persistent<v8::Object>::New(wrapperObject)); return wrapperObject; } diff --git a/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp b/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp index f498e4f..b20635b 100644 --- a/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp +++ b/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp @@ -44,7 +44,36 @@ namespace WebCore { -// ??? AddEventListener, RemoveEventListener +CALLBACK_FUNC_DECL(WebSocketAddEventListener) +{ + INC_STATS("DOM.WebSocket.addEventListener()"); + WebSocket* webSocket = V8DOMWrapper::convertToNativeObject<WebSocket>(V8ClassIndex::WEBSOCKET, args.Holder()); + + RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(webSocket, args[1], false, ListenerFindOrCreate); + if (listener) { + String type = toWebCoreString(args[0]); + bool useCapture = args[2]->BooleanValue(); + webSocket->addEventListener(type, listener, useCapture); + + createHiddenDependency(args.Holder(), args[1], V8Custom::kWebSocketCacheIndex); + } + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(WebSocketRemoveEventListener) +{ + INC_STATS("DOM.WebSocket.removeEventListener()"); + WebSocket* webSocket = V8DOMWrapper::convertToNativeObject<WebSocket>(V8ClassIndex::WEBSOCKET, args.Holder()); + + RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(webSocket, args[1], false, ListenerFindOnly); + if (listener) { + String type = toWebCoreString(args[0]); + bool useCapture = args[2]->BooleanValue(); + webSocket->removeEventListener(type, listener.get(), useCapture); + removeHiddenDependency(args.Holder(), args[1], V8Custom::kWebSocketCacheIndex); + } + return v8::Undefined(); +} CALLBACK_FUNC_DECL(WebSocketConstructor) { diff --git a/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp b/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp index 21b3c30..36c7001 100755 --- a/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp +++ b/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp @@ -34,6 +34,7 @@ #include "DOMTimer.h" #include "ExceptionCode.h" +#include "NotificationCenter.h" #include "ScheduledAction.h" #include "V8Binding.h" #include "V8CustomBinding.h" @@ -45,6 +46,13 @@ namespace WebCore { +#if ENABLE(NOTIFICATIONS) +ACCESSOR_RUNTIME_ENABLER(WorkerContextWebkitNotifications) +{ + return NotificationCenter::isAvailable(); +} +#endif + ACCESSOR_GETTER(WorkerContextSelf) { INC_STATS(L"DOM.WorkerContext.self._get"); diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp index 39105de..c3e4645 100644 --- a/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp +++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp @@ -46,11 +46,9 @@ namespace WebCore { 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 = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder()); - return v8StringOrNull(xmlHttpRequest->responseText()); + return xmlHttpRequest->responseText().v8StringOrNull(); } CALLBACK_FUNC_DECL(XMLHttpRequestAddEventListener) |