15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Google Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/ScriptEventListener.h" 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/ScriptController.h" 3551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "bindings/v8/ScriptState.h" 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/V8AbstractEventListener.h" 3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/V8Binding.h" 38521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "bindings/v8/V8WindowShell.h" 3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h" 4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/DocumentParser.h" 4106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/EventListener.h" 42d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/LocalFrame.h" 43f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include <v8.h> 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 475d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node* node, const QualifiedName& name, const AtomicString& value, const AtomicString& eventParameterName) 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(node); 50926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (value.isNull()) 51d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: Very strange: we initialize zero-based number with '1'. 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TextPosition position(OrdinalNumber::fromZeroBasedInt(1), OrdinalNumber::first()); 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String sourceURL; 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) v8::Isolate* isolate; 58d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (LocalFrame* frame = node->document().frame()) { 5906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) isolate = toIsolate(frame); 60f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) ScriptController& scriptController = frame->script(); 61f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) if (!scriptController.canExecuteScripts(AboutToExecuteScript)) 62d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 63f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) position = scriptController.eventHandlerPosition(); 648abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) sourceURL = node->document().url().string(); 6506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) } else { 6606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) isolate = v8::Isolate::GetCurrent(); 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 695d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return V8LazyEventListener::create(name.localName(), eventParameterName, value, sourceURL, position, node, isolate); 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 725d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)PassRefPtr<V8LazyEventListener> createAttributeEventListener(LocalFrame* frame, const QualifiedName& name, const AtomicString& value, const AtomicString& eventParameterName) 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!frame) 75d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 77926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (value.isNull()) 78d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 80f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) ScriptController& scriptController = frame->script(); 81f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) if (!scriptController.canExecuteScripts(AboutToExecuteScript)) 82d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 84f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) TextPosition position = scriptController.eventHandlerPosition(); 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String sourceURL = frame->document()->url().string(); 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 875d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return V8LazyEventListener::create(name.localName(), eventParameterName, value, sourceURL, position, 0, toIsolate(frame)); 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)static v8::Handle<v8::Function> eventListenerEffectiveFunction(v8::Isolate* isolate, v8::Handle<v8::Object> listenerObject) 9109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 9209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) v8::Handle<v8::Function> function; 9309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (listenerObject->IsFunction()) { 9409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) function = v8::Handle<v8::Function>::Cast(listenerObject); 9509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } else if (listenerObject->IsObject()) { 9609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // Try the "handleEvent" method (EventListener interface). 9709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) v8::Handle<v8::Value> property = listenerObject->Get(v8AtomicString(isolate, "handleEvent")); 9809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (property.IsEmpty() || !property->IsFunction()) { 9909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // Fall back to the "constructor" property. 10009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) property = listenerObject->Get(v8AtomicString(isolate, "constructor")); 10109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 10209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!property.IsEmpty() && property->IsFunction()) 10309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) function = v8::Handle<v8::Function>::Cast(property); 10409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 10509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return function; 10609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 10709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String eventListenerHandlerBody(Document* document, EventListener* listener) 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (listener->type() != EventListener::JSEventListenerType) 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ""; 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1139bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) v8::HandleScope scope(toIsolate(document)); 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) V8AbstractEventListener* v8Listener = static_cast<V8AbstractEventListener*>(listener); 11553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) v8::Handle<v8::Context> context = toV8Context(document, v8Listener->world()); 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Context::Scope contextScope(context); 11709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) v8::Handle<v8::Object> object = v8Listener->getListenerObject(document); 11809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (object.IsEmpty()) 11909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return ""; 12009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) v8::Handle<v8::Function> function = eventListenerEffectiveFunction(scope.GetIsolate(), object); 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (function.IsEmpty()) 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ""; 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch TOSTRING_DEFAULT(V8StringResource<WithNullCheck>, functionString, function, ""); 12509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return functionString; 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 128926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)ScriptValue eventListenerHandler(Document* document, EventListener* listener) 129926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 130926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (listener->type() != EventListener::JSEventListenerType) 131926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return ScriptValue(); 132926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1339bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) v8::Isolate* isolate = toIsolate(document); 1349bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) v8::HandleScope scope(isolate); 135926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) V8AbstractEventListener* v8Listener = static_cast<V8AbstractEventListener*>(listener); 13653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) v8::Handle<v8::Context> context = toV8Context(document, v8Listener->world()); 137926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) v8::Context::Scope contextScope(context); 138926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) v8::Handle<v8::Object> function = v8Listener->getListenerObject(document); 139926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (function.IsEmpty()) 140926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return ScriptValue(); 141323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) return ScriptValue(ScriptState::from(context), function); 142926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 143926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 144d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)ScriptState* eventListenerHandlerScriptState(LocalFrame* frame, EventListener* listener) 145926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 146926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (listener->type() != EventListener::JSEventListenerType) 147926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return 0; 148926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) V8AbstractEventListener* v8Listener = static_cast<V8AbstractEventListener*>(listener); 1499bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) v8::HandleScope scope(toIsolate(frame)); 150f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) v8::Handle<v8::Context> v8Context = frame->script().windowShell(v8Listener->world())->context(); 151f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu return ScriptState::from(v8Context); 152926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 153926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool eventListenerHandlerLocation(Document* document, EventListener* listener, String& sourceName, String& scriptId, int& lineNumber) 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (listener->type() != EventListener::JSEventListenerType) 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1599bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) v8::HandleScope scope(toIsolate(document)); 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) V8AbstractEventListener* v8Listener = static_cast<V8AbstractEventListener*>(listener); 16153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) v8::Handle<v8::Context> context = toV8Context(document, v8Listener->world()); 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) v8::Context::Scope contextScope(context); 16309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) v8::Local<v8::Object> object = v8Listener->getListenerObject(document); 16409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (object.IsEmpty()) 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 16609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) v8::Handle<v8::Function> function = eventListenerEffectiveFunction(scope.GetIsolate(), object); 16709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (function.IsEmpty()) 16809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return false; 16909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) v8::Handle<v8::Function> originalFunction = getBoundFunction(function); 17009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) int scriptIdValue = originalFunction->ScriptId(); 171a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) scriptId = String::number(scriptIdValue); 17209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) v8::ScriptOrigin origin = originalFunction->GetScriptOrigin(); 1739bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) if (!origin.ResourceName().IsEmpty() && origin.ResourceName()->IsString()) 17409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) sourceName = toCoreString(origin.ResourceName().As<v8::String>()); 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sourceName = ""; 17709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) lineNumber = originalFunction->GetScriptLineNumber(); 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore 182