| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 #include "bindings/v8/V8Binding.h" | 36 #include "bindings/v8/V8Binding.h" |
| 37 #include "bindings/v8/V8EventListenerList.h" | 37 #include "bindings/v8/V8EventListenerList.h" |
| 38 #include "core/events/BeforeUnloadEvent.h" | 38 #include "core/events/BeforeUnloadEvent.h" |
| 39 #include "core/events/Event.h" | 39 #include "core/events/Event.h" |
| 40 #include "core/events/ThreadLocalEventNames.h" | 40 #include "core/events/ThreadLocalEventNames.h" |
| 41 #include "core/inspector/InspectorCounters.h" | 41 #include "core/inspector/InspectorCounters.h" |
| 42 #include "core/workers/WorkerGlobalScope.h" | 42 #include "core/workers/WorkerGlobalScope.h" |
| 43 | 43 |
| 44 namespace WebCore { | 44 namespace WebCore { |
| 45 | 45 |
| 46 V8AbstractEventListener::V8AbstractEventListener(bool isAttribute, PassRefPtr<DO
MWrapperWorld> world, v8::Isolate* isolate) | 46 V8AbstractEventListener::V8AbstractEventListener(bool isAttribute, DOMWrapperWor
ld* world, v8::Isolate* isolate) |
| 47 : EventListener(JSEventListenerType) | 47 : EventListener(JSEventListenerType) |
| 48 , m_isAttribute(isAttribute) | 48 , m_isAttribute(isAttribute) |
| 49 , m_world(world) | 49 , m_world(world) |
| 50 , m_isolate(isolate) | 50 , m_isolate(isolate) |
| 51 { | 51 { |
| 52 if (isMainThread()) | 52 if (isMainThread()) |
| 53 InspectorCounters::incrementCounter(InspectorCounters::JSEventListenerCo
unter); | 53 InspectorCounters::incrementCounter(InspectorCounters::JSEventListenerCo
unter); |
| 54 } | 54 } |
| 55 | 55 |
| 56 V8AbstractEventListener::~V8AbstractEventListener() | 56 V8AbstractEventListener::~V8AbstractEventListener() |
| (...skipping 13 matching lines...) Expand all Loading... |
| 70 return; | 70 return; |
| 71 | 71 |
| 72 ASSERT(event); | 72 ASSERT(event); |
| 73 | 73 |
| 74 // The callback function on XMLHttpRequest can clear the event listener and
destroys 'this' object. Keep a local reference to it. | 74 // The callback function on XMLHttpRequest can clear the event listener and
destroys 'this' object. Keep a local reference to it. |
| 75 // See issue 889829. | 75 // See issue 889829. |
| 76 RefPtr<V8AbstractEventListener> protect(this); | 76 RefPtr<V8AbstractEventListener> protect(this); |
| 77 | 77 |
| 78 v8::HandleScope handleScope(m_isolate); | 78 v8::HandleScope handleScope(m_isolate); |
| 79 | 79 |
| 80 v8::Local<v8::Context> v8Context = toV8Context(context, world()); | 80 v8::Local<v8::Context> v8Context = toV8Context(context, m_world); |
| 81 if (v8Context.IsEmpty()) | 81 if (v8Context.IsEmpty()) |
| 82 return; | 82 return; |
| 83 | 83 |
| 84 // Enter the V8 context in which to perform the event handling. | 84 // Enter the V8 context in which to perform the event handling. |
| 85 v8::Context::Scope scope(v8Context); | 85 v8::Context::Scope scope(v8Context); |
| 86 | 86 |
| 87 // Get the V8 wrapper for the event object. | 87 // Get the V8 wrapper for the event object. |
| 88 v8::Isolate* isolate = v8Context->GetIsolate(); | 88 v8::Isolate* isolate = v8Context->GetIsolate(); |
| 89 v8::Handle<v8::Value> jsEvent = toV8(event, v8::Handle<v8::Object>(), isolat
e); | 89 v8::Handle<v8::Value> jsEvent = toV8(event, v8::Handle<v8::Object>(), isolat
e); |
| 90 if (jsEvent.IsEmpty()) | 90 if (jsEvent.IsEmpty()) |
| 91 return; | 91 return; |
| 92 invokeEventHandler(context, event, v8::Local<v8::Value>::New(isolate, jsEven
t)); | 92 invokeEventHandler(context, event, v8::Local<v8::Value>::New(isolate, jsEven
t)); |
| 93 } | 93 } |
| 94 | 94 |
| 95 void V8AbstractEventListener::setListenerObject(v8::Handle<v8::Object> listener) | 95 void V8AbstractEventListener::setListenerObject(v8::Handle<v8::Object> listener) |
| 96 { | 96 { |
| 97 m_listener.set(m_isolate, listener); | 97 m_listener.set(m_isolate, listener); |
| 98 m_listener.setWeak(this, &setWeakCallback); | 98 m_listener.setWeak(this, &setWeakCallback); |
| 99 } | 99 } |
| 100 | 100 |
| 101 void V8AbstractEventListener::invokeEventHandler(ExecutionContext* context, Even
t* event, v8::Local<v8::Value> jsEvent) | 101 void V8AbstractEventListener::invokeEventHandler(ExecutionContext* context, Even
t* event, v8::Local<v8::Value> jsEvent) |
| 102 { | 102 { |
| 103 // If jsEvent is empty, attempt to set it as a hidden value would crash v8. | 103 // If jsEvent is empty, attempt to set it as a hidden value would crash v8. |
| 104 if (jsEvent.IsEmpty()) | 104 if (jsEvent.IsEmpty()) |
| 105 return; | 105 return; |
| 106 | 106 |
| 107 v8::Local<v8::Context> v8Context = toV8Context(context, world()); | 107 v8::Local<v8::Context> v8Context = toV8Context(context, m_world); |
| 108 if (v8Context.IsEmpty()) | 108 if (v8Context.IsEmpty()) |
| 109 return; | 109 return; |
| 110 | 110 |
| 111 // We push the event being processed into the global object, so that it can
be exposed by DOMWindow's bindings. | 111 // We push the event being processed into the global object, so that it can
be exposed by DOMWindow's bindings. |
| 112 v8::Handle<v8::String> eventSymbol = v8AtomicString(v8Context->GetIsolate(),
"event"); | 112 v8::Handle<v8::String> eventSymbol = v8AtomicString(v8Context->GetIsolate(),
"event"); |
| 113 v8::Local<v8::Value> returnValue; | 113 v8::Local<v8::Value> returnValue; |
| 114 | 114 |
| 115 { | 115 { |
| 116 // Catch exceptions thrown in the event handler so they do not propagate
to javascript code that caused the event to fire. | 116 // Catch exceptions thrown in the event handler so they do not propagate
to javascript code that caused the event to fire. |
| 117 v8::TryCatch tryCatch; | 117 v8::TryCatch tryCatch; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 | 160 |
| 161 bool V8AbstractEventListener::shouldPreventDefault(v8::Local<v8::Value> returnVa
lue) | 161 bool V8AbstractEventListener::shouldPreventDefault(v8::Local<v8::Value> returnVa
lue) |
| 162 { | 162 { |
| 163 // Prevent default action if the return value is false in accord with the sp
ec | 163 // Prevent default action if the return value is false in accord with the sp
ec |
| 164 // http://www.w3.org/TR/html5/webappapis.html#event-handler-attributes | 164 // http://www.w3.org/TR/html5/webappapis.html#event-handler-attributes |
| 165 return returnValue->IsBoolean() && !returnValue->BooleanValue(); | 165 return returnValue->IsBoolean() && !returnValue->BooleanValue(); |
| 166 } | 166 } |
| 167 | 167 |
| 168 v8::Local<v8::Object> V8AbstractEventListener::getReceiverObject(ExecutionContex
t* context, Event* event) | 168 v8::Local<v8::Object> V8AbstractEventListener::getReceiverObject(ExecutionContex
t* context, Event* event) |
| 169 { | 169 { |
| 170 v8::Isolate* isolate = toV8Context(context, world())->GetIsolate(); | 170 v8::Isolate* isolate = toV8Context(context, m_world)->GetIsolate(); |
| 171 v8::Local<v8::Object> listener = m_listener.newLocal(isolate); | 171 v8::Local<v8::Object> listener = m_listener.newLocal(isolate); |
| 172 if (!m_listener.isEmpty() && !listener->IsFunction()) | 172 if (!m_listener.isEmpty() && !listener->IsFunction()) |
| 173 return listener; | 173 return listener; |
| 174 | 174 |
| 175 EventTarget* target = event->currentTarget(); | 175 EventTarget* target = event->currentTarget(); |
| 176 v8::Handle<v8::Value> value = toV8(target, v8::Handle<v8::Object>(), isolate
); | 176 v8::Handle<v8::Value> value = toV8(target, v8::Handle<v8::Object>(), isolate
); |
| 177 if (value.IsEmpty()) | 177 if (value.IsEmpty()) |
| 178 return v8::Local<v8::Object>(); | 178 return v8::Local<v8::Object>(); |
| 179 return v8::Local<v8::Object>::New(isolate, v8::Handle<v8::Object>::Cast(valu
e)); | 179 return v8::Local<v8::Object>::New(isolate, v8::Handle<v8::Object>::Cast(valu
e)); |
| 180 } | 180 } |
| 181 | 181 |
| 182 bool V8AbstractEventListener::belongsToTheCurrentWorld() const | 182 bool V8AbstractEventListener::belongsToTheCurrentWorld() const |
| 183 { | 183 { |
| 184 return m_isolate->InContext() && m_world == DOMWrapperWorld::current(m_isola
te); | 184 return m_isolate->InContext() && m_world == DOMWrapperWorld::current(m_isola
te); |
| 185 } | 185 } |
| 186 | 186 |
| 187 void V8AbstractEventListener::setWeakCallback(const v8::WeakCallbackData<v8::Obj
ect, V8AbstractEventListener> &data) | 187 void V8AbstractEventListener::setWeakCallback(const v8::WeakCallbackData<v8::Obj
ect, V8AbstractEventListener> &data) |
| 188 { | 188 { |
| 189 data.GetParameter()->m_listener.clear(); | 189 data.GetParameter()->m_listener.clear(); |
| 190 } | 190 } |
| 191 | 191 |
| 192 } // namespace WebCore | 192 } // namespace WebCore |
| OLD | NEW |