diff options
author | levin@chromium.org <levin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-13 00:58:31 +0000 |
---|---|---|
committer | levin@chromium.org <levin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-13 00:58:31 +0000 |
commit | 4b706713acf8483673ca6a2ec543521dd2bd8d16 (patch) | |
tree | 798405f55dd119b7500149348b674e254222859f /webkit/port | |
parent | 6b6734719b15274966e0f4aa0c014ee96b2c8466 (diff) | |
download | chromium_src-4b706713acf8483673ca6a2ec543521dd2bd8d16.zip chromium_src-4b706713acf8483673ca6a2ec543521dd2bd8d16.tar.gz chromium_src-4b706713acf8483673ca6a2ec543521dd2bd8d16.tar.bz2 |
WebKit merge 41588:41613 (Chromium side).
webkit\port\bindings\v8, webkit\build files
These are all adjustments to use the recently upstreamed V8Events files.
percent-top-value-with-relative-position-expected
This is a new test that has the same result in chromium but uses a slightly
different font to display it, so pixels and coordinates were also different.
search-field-cancel-expected
This is a new test that verifies the visual aspects of the search field.
Since chromium doesn't implement this field in a special way, chromium's
results are expected to be different.
Review URL: http://codereview.chromium.org/42163
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@11606 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/port')
-rw-r--r-- | webkit/port/bindings/v8/V8CanvasPixelArrayCustom.cpp | 1 | ||||
-rw-r--r-- | webkit/port/bindings/v8/V8MessagePortCustom.cpp | 10 | ||||
-rw-r--r-- | webkit/port/bindings/v8/V8XMLHttpRequestCustom.cpp | 46 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_custom.cpp | 2 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_events.cpp | 564 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_events.h | 207 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_proxy.cpp | 30 |
7 files changed, 45 insertions, 815 deletions
diff --git a/webkit/port/bindings/v8/V8CanvasPixelArrayCustom.cpp b/webkit/port/bindings/v8/V8CanvasPixelArrayCustom.cpp index b1a659c..d5441a1 100644 --- a/webkit/port/bindings/v8/V8CanvasPixelArrayCustom.cpp +++ b/webkit/port/bindings/v8/V8CanvasPixelArrayCustom.cpp @@ -31,7 +31,6 @@ #include "v8_binding.h" #include "v8_custom.h" -#include "v8_events.h" #include "v8_proxy.h" #include "CanvasPixelArray.h" diff --git a/webkit/port/bindings/v8/V8MessagePortCustom.cpp b/webkit/port/bindings/v8/V8MessagePortCustom.cpp index 63a1ee2..6405b678 100644 --- a/webkit/port/bindings/v8/V8MessagePortCustom.cpp +++ b/webkit/port/bindings/v8/V8MessagePortCustom.cpp @@ -32,11 +32,11 @@ #include "v8_binding.h" #include "v8_custom.h" -#include "v8_events.h" #include "v8_proxy.h" #include "V8Document.h" #include "V8HTMLDocument.h" +#include "V8ObjectEventListener.h" #include "ExceptionCode.h" #include "MessagePort.h" @@ -88,7 +88,7 @@ ACCESSOR_GETTER(MessagePortOnmessage) if (messagePort->onmessage()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(messagePort->onmessage()); - v8::Local<v8::Object> v8Listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); return v8Listener; } return v8::Undefined(); @@ -103,7 +103,7 @@ ACCESSOR_SETTER(MessagePortOnmessage) if (messagePort->onmessage()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(messagePort->onmessage()); - v8::Local<v8::Object> v8Listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); RemoveHiddenDependency(info.Holder(), v8Listener); } @@ -132,7 +132,7 @@ ACCESSOR_GETTER(MessagePortOnclose) if (messagePort->onclose()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(messagePort->onclose()); - v8::Local<v8::Object> v8Listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); return v8Listener; } return v8::Undefined(); @@ -147,7 +147,7 @@ ACCESSOR_SETTER(MessagePortOnclose) if (messagePort->onclose()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(messagePort->onclose()); - v8::Local<v8::Object> v8Listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); RemoveHiddenDependency(info.Holder(), v8Listener); } diff --git a/webkit/port/bindings/v8/V8XMLHttpRequestCustom.cpp b/webkit/port/bindings/v8/V8XMLHttpRequestCustom.cpp index c39d037..c613dee 100644 --- a/webkit/port/bindings/v8/V8XMLHttpRequestCustom.cpp +++ b/webkit/port/bindings/v8/V8XMLHttpRequestCustom.cpp @@ -31,11 +31,11 @@ #include "v8_binding.h" #include "v8_custom.h" -#include "v8_events.h" #include "v8_proxy.h" #include "V8Document.h" #include "V8HTMLDocument.h" +#include "V8ObjectEventListener.h" #include "ExceptionCode.h" #include "Frame.h" @@ -111,7 +111,7 @@ ACCESSOR_GETTER(XMLHttpRequestOnabort) { if (imp->onabort()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onabort()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); return v8_listener; } return v8::Undefined(); @@ -125,7 +125,7 @@ ACCESSOR_SETTER(XMLHttpRequestOnabort) { if (imp->onabort()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onabort()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } @@ -152,7 +152,7 @@ ACCESSOR_GETTER(XMLHttpRequestOnerror) { if (imp->onerror()) { RefPtr<V8ObjectEventListener> listener = static_cast<V8ObjectEventListener*>(imp->onerror()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); return v8_listener; } return v8::Undefined(); @@ -166,7 +166,7 @@ ACCESSOR_SETTER(XMLHttpRequestOnerror) { if (imp->onerror()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onerror()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } @@ -193,7 +193,7 @@ ACCESSOR_GETTER(XMLHttpRequestOnload) { if (imp->onload()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onload()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); return v8_listener; } return v8::Undefined(); @@ -207,7 +207,7 @@ ACCESSOR_SETTER(XMLHttpRequestOnload) if (value->IsNull()) { if (imp->onload()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onload()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } @@ -234,7 +234,7 @@ ACCESSOR_GETTER(XMLHttpRequestOnloadstart) { if (imp->onloadstart()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onloadstart()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); return v8_listener; } return v8::Undefined(); @@ -248,7 +248,7 @@ ACCESSOR_SETTER(XMLHttpRequestOnloadstart) { if (imp->onloadstart()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onloadstart()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } @@ -275,7 +275,7 @@ ACCESSOR_GETTER(XMLHttpRequestOnprogress) { if (imp->onprogress()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onprogress()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); return v8_listener; } return v8::Undefined(); @@ -289,7 +289,7 @@ ACCESSOR_SETTER(XMLHttpRequestOnprogress) { if (imp->onprogress()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onprogress()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } @@ -316,7 +316,7 @@ ACCESSOR_GETTER(XMLHttpRequestOnreadystatechange) { if (imp->onreadystatechange()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onreadystatechange()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); return v8_listener; } return v8::Undefined(); @@ -331,7 +331,7 @@ ACCESSOR_SETTER(XMLHttpRequestOnreadystatechange) if (imp->onreadystatechange()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onreadystatechange()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } @@ -558,7 +558,7 @@ ACCESSOR_GETTER(XMLHttpRequestUploadOnabort) { if (imp->onabort()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onabort()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); return v8_listener; } return v8::Undefined(); @@ -572,7 +572,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnabort) { if (imp->onabort()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onabort()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } @@ -601,7 +601,7 @@ ACCESSOR_GETTER(XMLHttpRequestUploadOnerror) { if (imp->onerror()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onerror()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); return v8_listener; } return v8::Undefined(); @@ -615,7 +615,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnerror) { if (imp->onerror()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onerror()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } @@ -643,7 +643,7 @@ ACCESSOR_GETTER(XMLHttpRequestUploadOnload) { if (imp->onload()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onload()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); return v8_listener; } return v8::Undefined(); @@ -657,7 +657,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnload) { if (imp->onload()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onload()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } @@ -685,7 +685,7 @@ ACCESSOR_GETTER(XMLHttpRequestUploadOnloadstart) { if (imp->onloadstart()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onloadstart()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); return v8_listener; } return v8::Undefined(); @@ -699,7 +699,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnloadstart) { if (imp->onloadstart()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onloadstart()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } @@ -727,7 +727,7 @@ ACCESSOR_GETTER(XMLHttpRequestUploadOnprogress) { if (imp->onprogress()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onprogress()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); return v8_listener; } return v8::Undefined(); @@ -741,7 +741,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnprogress) { if (imp->onprogress()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(imp->onprogress()); - v8::Local<v8::Object> v8_listener = listener->GetListenerObject(); + v8::Local<v8::Object> v8_listener = listener->getListenerObject(); RemoveHiddenXHRDependency(info.Holder(), v8_listener); } diff --git a/webkit/port/bindings/v8/v8_custom.cpp b/webkit/port/bindings/v8/v8_custom.cpp index f5e3e5a..9de743f 100644 --- a/webkit/port/bindings/v8/v8_custom.cpp +++ b/webkit/port/bindings/v8/v8_custom.cpp @@ -27,7 +27,6 @@ #include <wtf/ASCIICType.h> #include "v8_proxy.h" -#include "v8_events.h" #include "v8_binding.h" #include "V8NPObject.h" #include "v8_custom.h" @@ -35,6 +34,7 @@ #include "V8Attr.h" #include "V8CanvasGradient.h" #include "V8CanvasPattern.h" +#include "V8CustomEventListener.h" #include "V8Document.h" #include "V8DOMWindow.h" #include "V8HTMLCanvasElement.h" diff --git a/webkit/port/bindings/v8/v8_events.cpp b/webkit/port/bindings/v8/v8_events.cpp deleted file mode 100644 index 0cebb57..0000000 --- a/webkit/port/bindings/v8/v8_events.cpp +++ /dev/null @@ -1,564 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "config.h" - -#include "v8_events.h" -#include "v8_proxy.h" -#include "v8_binding.h" -#include "Frame.h" -#include "DOMWindow.h" -#include "V8Event.h" -#include "Event.h" -#include "Document.h" -#include "Tokenizer.h" -#include "Node.h" -#include "XMLHttpRequest.h" -#include "WorkerContextExecutionProxy.h" -#include "CString.h" - -namespace WebCore { - - -V8AbstractEventListener::V8AbstractEventListener(Frame* frame, bool isInline) - : m_isInline(isInline), m_frame(frame) { - if (!m_frame) return; - - // Get the position in the source if any. - m_lineNumber = 0; - m_columnNumber = 0; - if (m_isInline && m_frame->document()->tokenizer()) { - m_lineNumber = m_frame->document()->tokenizer()->lineNumber(); - m_columnNumber = m_frame->document()->tokenizer()->columnNumber(); - } -} - - -void V8AbstractEventListener::HandleEventHelper(v8::Handle<v8::Context> context, - Event* event, - v8::Handle<v8::Value> jsevent, - bool isWindowEvent) { - - // For compatibility, we store the event object as a property on the window - // called "event". Because this is the global namespace, we save away any - // existing "event" property, and then restore it after executing the - // javascript handler. - v8::Local<v8::String> event_symbol = v8::String::NewSymbol("event"); - v8::Local<v8::Value> saved_evt; - v8::Local<v8::Value> ret; - - { - // Catch exceptions thrown in the event handler so they do not - // propagate to javascript code that caused the event to fire. - // Setting and getting the 'event' property on the global object - // can throw exceptions as well (for instance if accessors that - // throw exceptions are defined for 'event' using __defineGetter__ - // and __defineSetter__ on the global object). - v8::TryCatch try_catch; - try_catch.SetVerbose(true); - - // Save the old 'event' property so we can restore it later. - saved_evt = context->Global()->Get(event_symbol); - try_catch.Reset(); - - // Make the event available in the window object. - // - // TODO: This does not work as in safari if the window.event - // property is already set. We need to make sure that property - // access is intercepted correctly. - context->Global()->Set(event_symbol, jsevent); - try_catch.Reset(); - - // Call the event handler. - ret = CallListenerFunction(jsevent, event, isWindowEvent); - try_catch.Reset(); - - // Restore the old event. This must be done for all exit paths - // through this method. - if (saved_evt.IsEmpty()) { - context->Global()->Set(event_symbol, v8::Undefined()); - } else { - context->Global()->Set(event_symbol, saved_evt); - } - try_catch.Reset(); - } - - if (V8Proxy::HandleOutOfMemory()) - ASSERT(ret.IsEmpty()); - - if (ret.IsEmpty()) { - return; - } - - if (!ret.IsEmpty()) { - if (!ret->IsNull() && !ret->IsUndefined() && - event->storesResultAsString()) { - event->storeResult(ToWebCoreString(ret)); - } - // Prevent default action if the return value is false; - // TODO(fqian): example, and reference to buganizer entry - if (m_isInline) { - if (ret->IsBoolean() && !ret->BooleanValue()) { - event->preventDefault(); - } - } - } -} - - -void V8AbstractEventListener::handleEvent(Event* event, bool isWindowEvent) { - // EventListener could be disconnected from the frame. - if (disconnected()) - return; - - // The callback function on XMLHttpRequest can clear the event listener - // and destroys 'this' object. Keep a local reference of it. - // See issue 889829 - RefPtr<V8AbstractEventListener> self(this); - - v8::HandleScope handle_scope; - - v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame); - if (context.IsEmpty()) - return; - - // m_frame can removed by the callback function, - // protect it until the callback function returns. - RefPtr<Frame> protector(m_frame); - - IF_DEVEL(log_info(frame, "Handling DOM event", m_frame->document()->URL())); - - { - // Enter the V8 context in which to perform the event handling. - v8::Context::Scope scope(context); - - // Get the V8 wrapper for the event object. - v8::Handle<v8::Value> jsevent = V8Proxy::EventToV8Object(event); - - HandleEventHelper(context, event, jsevent, isWindowEvent); - } - - Document::updateDocumentsRendering(); -} - - -void V8AbstractEventListener::DisposeListenerObject() { - if (!m_listener.IsEmpty()) { -#ifndef NDEBUG - V8Proxy::UnregisterGlobalHandle(this, m_listener); -#endif - m_listener.Dispose(); - m_listener.Clear(); - } -} - - -v8::Local<v8::Object> V8AbstractEventListener::GetReceiverObject( - Event* event, - bool isWindowEvent) { - if (!m_listener.IsEmpty() && !m_listener->IsFunction()) { - return v8::Local<v8::Object>::New(m_listener); - } - - if (isWindowEvent) { - return v8::Context::GetCurrent()->Global(); - } - - EventTarget* target = event->currentTarget(); - v8::Handle<v8::Value> value = V8Proxy::EventTargetToV8Object(target); - if (value.IsEmpty()) return v8::Local<v8::Object>(); - return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value)); -} - - -V8EventListener::V8EventListener(Frame* frame, v8::Local<v8::Object> listener, - bool isInline) - : V8AbstractEventListener(frame, isInline) { - m_listener = v8::Persistent<v8::Object>::New(listener); -#ifndef NDEBUG - V8Proxy::RegisterGlobalHandle(EVENT_LISTENER, this, m_listener); -#endif -} - - -V8EventListener::~V8EventListener() { - if (m_frame) { - V8Proxy* proxy = V8Proxy::retrieve(m_frame); - if (proxy) - proxy->RemoveV8EventListener(this); - } - - DisposeListenerObject(); -} - - -v8::Local<v8::Function> V8EventListener::GetListenerFunction() { - // It could be disposed already. - if (m_listener.IsEmpty()) return v8::Local<v8::Function>(); - - if (m_listener->IsFunction()) { - return v8::Local<v8::Function>::New( - v8::Persistent<v8::Function>::Cast(m_listener)); - - } else if (m_listener->IsObject()) { - v8::Local<v8::Value> prop = - m_listener->Get(v8::String::NewSymbol("handleEvent")); - if (prop->IsFunction()) { - return v8::Local<v8::Function>::Cast(prop); - } - } - - return v8::Local<v8::Function>(); -} - - -v8::Local<v8::Value> -V8EventListener::CallListenerFunction(v8::Handle<v8::Value> jsevent, - Event* event, bool isWindowEvent) { - v8::Local<v8::Function> handler_func = GetListenerFunction(); - v8::Local<v8::Object> receiver = GetReceiverObject(event, isWindowEvent); - if (handler_func.IsEmpty() || receiver.IsEmpty()) { - return v8::Local<v8::Value>(); - } - - v8::Handle<v8::Value> parameters[1] = { jsevent }; - - V8Proxy* proxy = V8Proxy::retrieve(m_frame); - return proxy->CallFunction(handler_func, receiver, 1, parameters); -} - - -// ------- V 8 X H R E v e n t L i s t e n e r ----------------- - -static void WeakObjectEventListenerCallback(v8::Persistent<v8::Value> obj, - void* para) { - V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(para); - - // Remove the wrapper - Frame* frame = listener->frame(); - if (frame) { - V8Proxy* proxy = V8Proxy::retrieve(frame); - if (proxy) - proxy->RemoveObjectEventListener(listener); - - // Because the listener is no longer in the list, it must - // be disconnected from the frame to avoid dangling frame pointer - // in the destructor. - listener->disconnectFrame(); - } - - // Dispose the listener object. - listener->DisposeListenerObject(); -} - - -V8ObjectEventListener::V8ObjectEventListener(Frame* frame, - v8::Local<v8::Object> listener, - bool isInline) - : V8EventListener(frame, listener, isInline) { - // make m_listener weak. - m_listener.MakeWeak(this, WeakObjectEventListenerCallback); -} - - -V8ObjectEventListener::~V8ObjectEventListener() { - if (m_frame) { - ASSERT(!m_listener.IsEmpty()); - V8Proxy* proxy = V8Proxy::retrieve(m_frame); - if (proxy) - proxy->RemoveObjectEventListener(this); - } - - DisposeListenerObject(); -} - - -// ------- L a z y E v e n t L i s t e n e r --------------- - -V8LazyEventListener::V8LazyEventListener(Frame *frame, const String& code, - const String& func_name) - : V8AbstractEventListener(frame, true), m_code(code), - m_func_name(func_name), m_compiled(false), - m_wrapped_function_compiled(false) { -} - - -V8LazyEventListener::~V8LazyEventListener() { - DisposeListenerObject(); - - // Dispose wrapped function - if (!m_wrapped_function.IsEmpty()) { -#ifndef NDEBUG - V8Proxy::UnregisterGlobalHandle(this, m_wrapped_function); -#endif - m_wrapped_function.Dispose(); - m_wrapped_function.Clear(); - } -} - - -v8::Local<v8::Function> V8LazyEventListener::GetListenerFunction() { - if (m_compiled) { - ASSERT(m_listener.IsEmpty() || m_listener->IsFunction()); - return m_listener.IsEmpty() ? - v8::Local<v8::Function>() : - v8::Local<v8::Function>::New( - v8::Persistent<v8::Function>::Cast(m_listener)); - } - - m_compiled = true; - - ASSERT(m_frame); - - { - // Switch to the contex of m_frame - v8::HandleScope handle_scope; - - // Use the outer scope to hold context. - v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame); - // Bail out if we could not get the context. - if (context.IsEmpty()) return v8::Local<v8::Function>(); - - v8::Context::Scope scope(context); - - // Wrap function around the event code. The parenthesis around - // the function are needed so that evaluating the code yields - // the function value. Without the parenthesis the function - // value is thrown away. - - // Make it an anonymous function to avoid name conflict for cases like - // <body onload='onload()'> - // <script> function onload() { alert('hi'); } </script>. - // Set function name to function object instead. - // See issue 944690. - // - // The ECMAScript spec says (very obliquely) that the parameter to - // an event handler is named "evt". - String code = "(function (evt) {\n"; - code.append(m_code); - code.append("})"); - - IF_DEVEL(log_info(frame, code, "<getListener>")); - - v8::Handle<v8::String> codeExternalString = v8ExternalString(code); - v8::Handle<v8::Script> script = V8Proxy::CompileScript(codeExternalString, - m_frame->document()->url(), m_lineNumber - 1); - if (!script.IsEmpty()) { - V8Proxy* proxy = V8Proxy::retrieve(m_frame); - ASSERT(proxy); // must be valid at this point - v8::Local<v8::Value> value = proxy->RunScript(script, false); - if (!value.IsEmpty()) { - ASSERT(value->IsFunction()); - v8::Local<v8::Function> listener_func = - v8::Local<v8::Function>::Cast(value); - // Set the function name. - listener_func->SetName(v8::String::New(FromWebCoreString(m_func_name), - m_func_name.length())); - - m_listener = v8::Persistent<v8::Function>::New(listener_func); -#ifndef NDEBUG - V8Proxy::RegisterGlobalHandle(EVENT_LISTENER, this, m_listener); -#endif - } - } - } // end of HandleScope - - ASSERT(m_listener.IsEmpty() || m_listener->IsFunction()); - return m_listener.IsEmpty() ? - v8::Local<v8::Function>() : - v8::Local<v8::Function>::New( - v8::Persistent<v8::Function>::Cast(m_listener)); -} - - -v8::Local<v8::Value> -V8LazyEventListener::CallListenerFunction(v8::Handle<v8::Value> jsevent, - Event* event, bool isWindowEvent) { - v8::Local<v8::Function> handler_func = GetWrappedListenerFunction(); - v8::Local<v8::Object> receiver = GetReceiverObject(event, isWindowEvent); - if (handler_func.IsEmpty() || receiver.IsEmpty()) { - return v8::Local<v8::Value>(); - } - - v8::Handle<v8::Value> parameters[1] = { jsevent }; - - V8Proxy* proxy = V8Proxy::retrieve(m_frame); - return proxy->CallFunction(handler_func, receiver, 1, parameters); -} - - -v8::Local<v8::Function> V8LazyEventListener::GetWrappedListenerFunction() { - if (m_wrapped_function_compiled) { - ASSERT(m_wrapped_function.IsEmpty() || m_wrapped_function->IsFunction()); - return m_wrapped_function.IsEmpty() ? v8::Local<v8::Function>() : - v8::Local<v8::Function>::New(m_wrapped_function); - } - - m_wrapped_function_compiled = true; - - { - // Switch to the contex of m_frame - v8::HandleScope handle_scope; - - // Use the outer scope to hold context. - v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame); - // Bail out if we cannot get the context. - if (context.IsEmpty()) return v8::Local<v8::Function>(); - - v8::Context::Scope scope(context); - - // TODO(fqian): cache the wrapper function. - String code = "(function (evt) {\n"; - - // Nodes other than the document object, when executing inline event - // handlers push document, form, and the target node on the scope chain. - // We do this by using 'with' statement. - // See chrome/fast/forms/form-action.html - // chrome/fast/forms/selected-index-value.html - // base/fast/overflow/onscroll-layer-self-destruct.html - code.append(" with (this.ownerDocument ? this.ownerDocument : {}) {\n"); - code.append(" with (this.form ? this.form : {}) {\n"); - code.append(" with (this) {\n"); - code.append(" return (function(evt){"); - code.append(m_code); - code.append("}).call(this, evt);\n"); - code.append(" }\n"); - code.append(" }\n"); - code.append(" }\n"); - code.append("})"); - v8::Handle<v8::String> codeExternalString = v8ExternalString(code); - v8::Handle<v8::Script> script = V8Proxy::CompileScript(codeExternalString, - m_frame->document()->url(), m_lineNumber - 4); - if (!script.IsEmpty()) { - V8Proxy* proxy = V8Proxy::retrieve(m_frame); - ASSERT(proxy); - v8::Local<v8::Value> value = proxy->RunScript(script, false); - if (!value.IsEmpty()) { - ASSERT(value->IsFunction()); - - m_wrapped_function = v8::Persistent<v8::Function>::New( - v8::Local<v8::Function>::Cast(value)); -#ifndef NDEBUG - V8Proxy::RegisterGlobalHandle(EVENT_LISTENER, this, m_wrapped_function); -#endif - // Set the function name. - m_wrapped_function->SetName(v8::String::New( - FromWebCoreString(m_func_name), m_func_name.length())); - } - } - } // end of local scope - - return v8::Local<v8::Function>::New(m_wrapped_function); -} - -#if ENABLE(WORKERS) -V8WorkerContextEventListener::V8WorkerContextEventListener( - WorkerContextExecutionProxy* proxy, - v8::Local<v8::Object> listener, - bool isInline) - : V8ObjectEventListener(NULL, listener, isInline) - , m_proxy(proxy) { -} - -V8WorkerContextEventListener::~V8WorkerContextEventListener() { - if (m_proxy) { - m_proxy->RemoveEventListener(this); - } - DisposeListenerObject(); -} - -void V8WorkerContextEventListener::handleEvent(Event* event, - bool isWindowEvent) { - // EventListener could be disconnected from the frame. - if (disconnected()) - return; - - // The callback function on XMLHttpRequest can clear the event listener - // and destroys 'this' object. Keep a local reference of it. - // See issue 889829 - RefPtr<V8AbstractEventListener> self(this); - - v8::Locker locker; - v8::HandleScope handle_scope; - - v8::Handle<v8::Context> context = m_proxy->GetContext(); - if (context.IsEmpty()) - return; - - { - // Enter the V8 context in which to perform the event handling. - v8::Context::Scope scope(context); - - // Get the V8 wrapper for the event object. - v8::Handle<v8::Value> jsevent = - WorkerContextExecutionProxy::EventToV8Object(event); - - HandleEventHelper(context, event, jsevent, isWindowEvent); - } -} - -v8::Local<v8::Value> V8WorkerContextEventListener::CallListenerFunction( - v8::Handle<v8::Value> jsevent, Event* event, bool isWindowEvent) { - v8::Local<v8::Function> handler_func = GetListenerFunction(); - if (handler_func.IsEmpty()) return v8::Local<v8::Value>(); - - v8::Local<v8::Object> receiver = GetReceiverObject(event, isWindowEvent); - v8::Handle<v8::Value> parameters[1] = {jsevent}; - - v8::Local<v8::Value> result; - { - //ConsoleMessageScope scope; - - result = handler_func->Call(receiver, 1, parameters); - } - - m_proxy->TrackEvent(event); - - return result; -} - -v8::Local<v8::Object> V8WorkerContextEventListener::GetReceiverObject( - Event* event, bool isWindowEvent) { - if (!m_listener.IsEmpty() && !m_listener->IsFunction()) { - return v8::Local<v8::Object>::New(m_listener); - } - - if (isWindowEvent) { - return v8::Context::GetCurrent()->Global(); - } - - EventTarget* target = event->currentTarget(); - v8::Handle<v8::Value> value = - WorkerContextExecutionProxy::EventTargetToV8Object(target); - if (value.IsEmpty()) return v8::Local<v8::Object>(); - return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value)); -} -#endif // WORKERS - -} // namespace WebCore diff --git a/webkit/port/bindings/v8/v8_events.h b/webkit/port/bindings/v8/v8_events.h deleted file mode 100644 index 67a7fb6..0000000 --- a/webkit/port/bindings/v8/v8_events.h +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef V8_EVENTS_H__ -#define V8_EVENTS_H__ - -#include "config.h" -#include <v8.h> -#include "Frame.h" -#include "Event.h" -#include "EventListener.h" -#include "PlatformString.h" - -// #define IF_DEVEL(stmt) stmt -#define IF_DEVEL(stmt) ((void) 0) - -namespace WebCore { - -#if ENABLE(WORKERS) -class WorkerContextExecutionProxy; -#endif // WORKERS - -// There are two kinds of event listeners: HTML or non-HMTL. -// onload, onfocus, etc (attributes) are always HTML event handler type; -// Event listeners added by Window.addEventListener -// or EventTargetNode::addEventListener are non-HTML type. -// -// Why does this matter? -// WebKit does not allow duplicated HTML event handlers of the same type, -// but ALLOWs duplicated non-HTML event handlers. - -class V8AbstractEventListener : public EventListener { - public: - virtual ~V8AbstractEventListener() { } - - // Returns the owner frame of the listener. - Frame* frame() { return m_frame; } - - // Handle event. - virtual void handleEvent(Event*, bool isWindowEvent); - - void HandleEventHelper(v8::Handle<v8::Context> context, - Event* event, - v8::Handle<v8::Value> jsevent, - bool isWindowEvent); - - // Returns the listener object, either a function or an object. - virtual v8::Local<v8::Object> GetListenerObject() { - return v8::Local<v8::Object>::New(m_listener); - } - - // Dispose listener object and clear the handle - void DisposeListenerObject(); - - virtual bool disconnected() const { return m_frame == NULL; } - - protected: - // Listener object. - v8::Persistent<v8::Object> m_listener; - - // Flags this is a HTML type listener. - bool m_isInline; - - private: - V8AbstractEventListener(Frame* frame, bool isInline); - - // Call listener function. - virtual v8::Local<v8::Value> CallListenerFunction( - v8::Handle<v8::Value> jsevent, - Event* event, - bool isWindowEvent) = 0; - - // Get the receiver object to use for event listener call. - v8::Local<v8::Object> GetReceiverObject(Event* event, - bool isWindowEvent); - - // Frame to which the event listener is attached to. - // An event listener must be destroyed before its owner - // frame is deleted. - // See fast/dom/replaceChild.html - // TODO(fqian): this could hold m_frame live until - // the event listener is deleted. Fix this! - Frame* m_frame; - - // Position in the HTML source for HTML event listeners. - int m_lineNumber; - int m_columnNumber; - - friend class V8EventListener; - friend class V8ObjectEventListener; - friend class V8LazyEventListener; -}; - -// V8EventListener is a wrapper of a JS object implements EventListener -// interface (has handleEvent(event) method), or a JS function -// that can handle the event. -class V8EventListener : public V8AbstractEventListener { - public: - static PassRefPtr<V8EventListener> create(Frame* frame, - v8::Local<v8::Object> listener, bool isInline) { - return adoptRef(new V8EventListener(frame, listener, isInline)); - } - - V8EventListener(Frame* frame, v8::Local<v8::Object> listener, bool isInline); - virtual ~V8EventListener(); - virtual bool isInline() const { return m_isInline; } - - // Detach the listener from its owner frame. - void disconnectFrame() { m_frame = 0; } - - protected: - v8::Local<v8::Function> GetListenerFunction(); - - private: - // Call listener function. - virtual v8::Local<v8::Value> CallListenerFunction( - v8::Handle<v8::Value> jsevent, Event* event, bool isWindowEvent); -}; - - -// V8ObjectEventListener is a special listener wrapper for objects not -// in the DOM. It keeps the JS listener as a weak pointer. -class V8ObjectEventListener : public V8EventListener { - public: - static PassRefPtr<V8ObjectEventListener> create(Frame* frame, - v8::Local<v8::Object> listener, bool isInline) { - return adoptRef(new V8ObjectEventListener(frame, listener, isInline)); - } - V8ObjectEventListener(Frame* frame, v8::Local<v8::Object> listener, - bool isInline); - virtual ~V8ObjectEventListener(); -}; - - -// V8LazyEventListener is a wrapper for a JavaScript code string that is -// compiled and evaluated when an event is fired. -// A V8LazyEventListener is always a HTML event handler. -class V8LazyEventListener : public V8AbstractEventListener { - public: - static PassRefPtr<V8LazyEventListener> create(Frame* frame, - const String& code, const String& func_name) { - return adoptRef(new V8LazyEventListener(frame, code, func_name)); - } - V8LazyEventListener(Frame *frame, const String& code, - const String& func_name); - virtual ~V8LazyEventListener(); - virtual bool isInline() const { return true; } - - // For lazy event listener, the listener object is the same as its listener - // function without additional scope chains. - virtual v8::Local<v8::Object> GetListenerObject() { - return GetWrappedListenerFunction(); - } - - private: - String m_code; - String m_func_name; // function name - bool m_compiled; - - // If the event listener is on a non-document dom node, - // we compile the function with some implicit scope chains before it. - bool m_wrapped_function_compiled; - v8::Persistent<v8::Function> m_wrapped_function; - - v8::Local<v8::Function> GetWrappedListenerFunction(); - - virtual v8::Local<v8::Value> CallListenerFunction( - v8::Handle<v8::Value> jsevent, Event* event, bool isWindowEvent); - - v8::Local<v8::Function> GetListenerFunction(); -}; - -#if ENABLE(WORKERS) -class V8WorkerContextEventListener : public V8ObjectEventListener { - public: - static PassRefPtr<V8WorkerContextEventListener> create( - WorkerContextExecutionProxy* proxy, - v8::Local<v8::Object> listener, - bool isInline) { - return adoptRef(new V8WorkerContextEventListener(proxy, - listener, - isInline)); - } - V8WorkerContextEventListener(WorkerContextExecutionProxy* proxy, - v8::Local<v8::Object> listener, - bool isInline); - - virtual ~V8WorkerContextEventListener(); - virtual void handleEvent(Event*, bool isWindowEvent); - virtual bool disconnected() const { return m_proxy == NULL; } - - void disconnect() { m_proxy = NULL; } - - private: - virtual v8::Local<v8::Value> - CallListenerFunction(v8::Handle<v8::Value> jsevent, - Event* event, bool isWindowEvent); - v8::Local<v8::Object> GetReceiverObject(Event* event, - bool isWindowEvent); - WorkerContextExecutionProxy* m_proxy; -}; -#endif // WORKERS - -} // namespace WebCore - -#endif // V8_EVENTS_H__ diff --git a/webkit/port/bindings/v8/v8_proxy.cpp b/webkit/port/bindings/v8/v8_proxy.cpp index d3be5b09..21cec01 100644 --- a/webkit/port/bindings/v8/v8_proxy.cpp +++ b/webkit/port/bindings/v8/v8_proxy.cpp @@ -38,12 +38,10 @@ #include "v8_proxy.h" #include "dom_wrapper_map.h" #include "v8_index.h" -#include "v8_events.h" #include "v8_binding.h" #include "v8_custom.h" #include "v8_collection.h" #include "v8_nodefilter.h" -#include "V8DOMWindow.h" #include "ChromiumBridge.h" @@ -138,15 +136,13 @@ #include "TextMetrics.h" #include "TimeRanges.h" #include "TreeWalker.h" -#include "XMLHttpRequest.h" -#include "XMLHttpRequestUpload.h" -#include "XMLHttpRequestException.h" -#include "XMLSerializer.h" -#include "XPathException.h" -#include "XPathExpression.h" -#include "XPathNSResolver.h" -#include "XPathResult.h" #include "XSLTProcessor.h" +#include "V8AbstractEventListener.h" +#include "V8CustomEventListener.h" +#include "V8DOMWindow.h" +#include "V8HTMLElement.h" +#include "V8LazyEventListener.h" +#include "V8ObjectEventListener.h" #include "WebKitAnimationEvent.h" #include "WebKitCSSKeyframeRule.h" #include "WebKitCSSKeyframesRule.h" @@ -155,10 +151,16 @@ #include "WebKitPoint.h" #include "WebKitTransitionEvent.h" #include "WheelEvent.h" +#include "XMLHttpRequest.h" +#include "XMLHttpRequestException.h" #include "XMLHttpRequestProgressEvent.h" +#include "XMLHttpRequestUpload.h" +#include "XMLSerializer.h" +#include "XPathException.h" +#include "XPathExpression.h" +#include "XPathNSResolver.h" +#include "XPathResult.h" -#include "V8DOMWindow.h" -#include "V8HTMLElement.h" #include "ScriptController.h" @@ -1181,7 +1183,7 @@ static V8EventListener* FindEventListenerInList(V8EventListenerList& list, V8EventListenerList::iterator p = list.begin(); while (p != list.end()) { V8EventListener* el = *p; - v8::Local<v8::Object> wrapper = el->GetListenerObject(); + v8::Local<v8::Object> wrapper = el->getListenerObject(); ASSERT(!wrapper.IsEmpty()); // Since the listener is an object, it is safe to compare for // strict equality (in the JS sense) by doing a simple equality @@ -3256,7 +3258,7 @@ v8::Handle<v8::Value> V8Proxy::EventListenerToV8Object( // TODO(fqian): 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(); } |