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 |