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