18f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian/*
28f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
38f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian *
48f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Redistribution and use in source and binary forms, with or without
58f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * modification, are permitted provided that the following conditions are
68f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * met:
78f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian *
88f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian *     * Redistributions of source code must retain the above copyright
98f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * notice, this list of conditions and the following disclaimer.
108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian *     * Redistributions in binary form must reproduce the above
118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * copyright notice, this list of conditions and the following disclaimer
128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * in the documentation and/or other materials provided with the
138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * distribution.
148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian *     * Neither the name of Google Inc. nor the names of its
158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * contributors may be used to endorse or promote products derived from
168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * this software without specific prior written permission.
178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian *
188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian */
308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "config.h"
328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#if ENABLE(WORKERS)
348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "V8WorkerContextEventListener.h"
368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "V8Binding.h"
388a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#include "V8DOMWrapper.h"
398a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#include "V8Event.h"
40cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#include "WorkerContext.h"
418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "WorkerContextExecutionProxy.h"
428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qiannamespace WebCore {
448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
45cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockstatic WorkerContextExecutionProxy* workerProxy(ScriptExecutionContext* context)
468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
47cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    ASSERT(context->isWorkerContext());
48cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    WorkerContext* workerContext = static_cast<WorkerContext*>(context);
49cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    return workerContext->script()->proxy();
508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
52643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockV8WorkerContextEventListener::V8WorkerContextEventListener(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext)
53643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    : V8EventListener(listener, isInline, worldContext)
54cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{
55cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block}
56cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
57cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockvoid V8WorkerContextEventListener::handleEvent(ScriptExecutionContext* context, Event* event)
588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
59643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!context)
608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // The callback function on XMLHttpRequest can clear the event listener and destroys 'this' object. Keep a local reference to it.
638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // See issue 889829.
648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RefPtr<V8AbstractEventListener> protect(this);
658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    v8::HandleScope handleScope;
678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
68cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    WorkerContextExecutionProxy* proxy = workerProxy(context);
69cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (!proxy)
70cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        return;
71cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
72cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    v8::Handle<v8::Context> v8Context = proxy->context();
73cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (v8Context.IsEmpty())
748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Enter the V8 context in which to perform the event handling.
77cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    v8::Context::Scope scope(v8Context);
788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Get the V8 wrapper for the event object.
808a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    v8::Handle<v8::Value> jsEvent = toV8(event);
818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
82231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    invokeEventHandler(context, event, jsEvent);
838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
85cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockv8::Local<v8::Value> V8WorkerContextEventListener::callListenerFunction(ScriptExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
87cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    v8::Local<v8::Function> handlerFunction = getListenerFunction(context);
88cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    v8::Local<v8::Object> receiver = getReceiverObject(context, event);
895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (handlerFunction.IsEmpty() || receiver.IsEmpty())
908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return v8::Local<v8::Value>();
918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    v8::Handle<v8::Value> parameters[1] = { jsEvent };
938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    v8::Local<v8::Value> result = handlerFunction->Call(receiver, 1, parameters);
948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
95cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (WorkerContextExecutionProxy* proxy = workerProxy(context))
96cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        proxy->trackEvent(event);
978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return result;
998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
1008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
101cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockv8::Local<v8::Object> V8WorkerContextEventListener::getReceiverObject(ScriptExecutionContext* context, Event* event)
1028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
103cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    v8::Local<v8::Object> listener = getListenerObject(context);
1048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
105231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!listener.IsEmpty() && !listener->IsFunction())
106231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return listener;
1078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    EventTarget* target = event->currentTarget();
1098a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    v8::Handle<v8::Value> value = V8DOMWrapper::convertEventTargetToV8Object(target);
1108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (value.IsEmpty())
1118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return v8::Local<v8::Object>();
1128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value));
1138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
1148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} // namespace WebCore
1168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif // WORKERS
118