Changeset 49050 in webkit
- Timestamp:
- Oct 2, 2009 3:40:59 PM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r49049 r49050 1 2009-10-02 Vitaly Repeshko <vitalyr@chromium.org> 2 3 Reviewed by Dimitri Glazkov. 4 5 [V8] Disconnect event listeners on navigation. 6 Fixes http://crbug.com/23597. 7 https://bugs.webkit.org/show_bug.cgi?id=30027 8 9 Added V8ListenerGuard that is shared by listeners and proxy. On 10 navigation proxy sets a flag in the guard turning off listeners. 11 12 * bindings/v8/V8AbstractEventListener.cpp: 13 (WebCore::V8AbstractEventListener::V8AbstractEventListener): 14 * bindings/v8/V8AbstractEventListener.h: 15 (WebCore::V8ListenerGuard::create): 16 (WebCore::V8ListenerGuard::isDisconnected): 17 (WebCore::V8ListenerGuard::disconnectListeners): 18 (WebCore::V8ListenerGuard::V8ListenerGuard): 19 (WebCore::V8AbstractEventListener::disconnected): 20 * bindings/v8/V8DOMWrapper.cpp: 21 (WebCore::V8DOMWrapper::getEventListener): 22 * bindings/v8/V8EventListenerList.h: 23 (WebCore::V8EventListenerList::findOrCreateWrapper): 24 * bindings/v8/V8LazyEventListener.cpp: 25 (WebCore::V8LazyEventListener::V8LazyEventListener): 26 * bindings/v8/V8Proxy.cpp: 27 (WebCore::V8Proxy::V8Proxy): 28 (WebCore::V8Proxy::disconnectFrame): 29 (WebCore::V8Proxy::disconnectEventListeners): 30 (WebCore::V8Proxy::clearForNavigation): 31 * bindings/v8/V8Proxy.h: 32 (WebCore::V8Proxy::listenerGuard): 33 * bindings/v8/V8WorkerContextEventListener.cpp: 34 (WebCore::V8WorkerContextEventListener::V8WorkerContextEventListener): 35 * bindings/v8/V8WorkerContextEventListener.h: 36 (WebCore::V8WorkerContextEventListener::create): 37 * bindings/v8/WorkerContextExecutionProxy.cpp: 38 (WebCore::WorkerContextExecutionProxy::WorkerContextExecutionProxy): 39 (WebCore::WorkerContextExecutionProxy::dispose): 40 (WebCore::WorkerContextExecutionProxy::findOrCreateEventListener): 41 * bindings/v8/WorkerContextExecutionProxy.h: 42 * bindings/v8/custom/V8CustomEventListener.cpp: 43 (WebCore::V8EventListener::V8EventListener): 44 * bindings/v8/custom/V8CustomEventListener.h: 45 (WebCore::V8EventListener::create): 46 1 47 2009-10-02 Kenneth Russell <kbr@google.com> 2 48 -
trunk/WebCore/bindings/v8/V8AbstractEventListener.cpp
r48978 r49050 39 39 #include "V8Binding.h" 40 40 #include "V8EventListenerList.h" 41 #include "V8Proxy.h" 41 42 #include "V8Utilities.h" 42 43 … … 49 50 } 50 51 51 V8AbstractEventListener::V8AbstractEventListener(Frame* frame, bool isAttribute)52 V8AbstractEventListener::V8AbstractEventListener(Frame* frame, PassRefPtr<V8ListenerGuard> guard, bool isAttribute) 52 53 : EventListener(JSEventListenerType) 53 54 , m_isWeak(true) 54 55 , m_isAttribute(isAttribute) 55 56 , m_frame(frame) 57 , m_guard(guard) 56 58 , m_lineNumber(0) 57 59 , m_columnNumber(0) -
trunk/WebCore/bindings/v8/V8AbstractEventListener.h
r48978 r49050 34 34 #include "EventListener.h" 35 35 #include "OwnHandle.h" 36 #include " V8Proxy.h"36 #include "SharedPersistent.h" 37 37 #include <v8.h> 38 #include <wtf/PassRefPtr.h> 39 #include <wtf/RefCounted.h> 38 40 39 41 namespace WebCore { … … 41 43 class Event; 42 44 class Frame; 45 class V8Proxy; 46 47 // Shared by listener objects and V8Proxy so that V8Proxy can 48 // silence listeners when needed. 49 class V8ListenerGuard : public RefCounted<V8ListenerGuard> { 50 public: 51 static PassRefPtr<V8ListenerGuard> create() 52 { 53 return adoptRef(new V8ListenerGuard); 54 } 55 56 bool isDisconnected() const { return m_disconnected; } 57 58 void disconnectListeners() 59 { 60 m_disconnected = true; 61 } 62 63 private: 64 V8ListenerGuard() 65 : m_disconnected(false) { } 66 67 bool m_disconnected; 68 }; 43 69 44 70 // There are two kinds of event listeners: HTML or non-HMTL. onload, … … 100 126 void disconnectFrame() { m_frame = 0; } 101 127 102 virtual bool disconnected() const { return !m_frame; }128 virtual bool disconnected() const { return m_guard && m_guard->isDisconnected(); } 103 129 104 130 protected: 105 V8AbstractEventListener(Frame*, bool isAttribute);131 V8AbstractEventListener(Frame*, PassRefPtr<V8ListenerGuard>, bool isAttribute); 106 132 107 133 virtual void prepareListenerObject() { } … … 135 161 Frame* m_frame; 136 162 RefPtr<SharedPersistent<v8::Context> > m_context; 163 RefPtr<V8ListenerGuard> m_guard; 137 164 138 165 // Position in the HTML source for HTML event listeners. -
trunk/WebCore/bindings/v8/V8DOMWrapper.cpp
r48978 r49050 1399 1399 1400 1400 if (proxy) 1401 return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), value, isAttribute);1401 return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), proxy->listenerGuard(), value, isAttribute); 1402 1402 1403 1403 return 0; … … 1419 1419 V8Proxy* proxy = V8Proxy::retrieve(worker->scriptExecutionContext()); 1420 1420 if (proxy) 1421 return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), value, isAttribute);1421 return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), proxy->listenerGuard(), value, isAttribute); 1422 1422 1423 1423 return 0; … … 1435 1435 V8Proxy* proxy = V8Proxy::retrieve(notification->scriptExecutionContext()); 1436 1436 if (proxy) 1437 return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), value, isAttribute);1437 return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), proxy->listenerGuard(), value, isAttribute); 1438 1438 1439 1439 return 0; … … 1459 1459 V8Proxy* proxy = V8Proxy::retrieve(eventTarget->scriptExecutionContext()); 1460 1460 if (proxy) 1461 return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), value, isAttribute);1461 return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), proxy->listenerGuard(), value, isAttribute); 1462 1462 1463 1463 #if ENABLE(WORKERS) … … 1473 1473 { 1474 1474 if (proxy) 1475 return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), value, isAttribute);1475 return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), proxy->listenerGuard(), value, isAttribute); 1476 1476 1477 1477 return 0; -
trunk/WebCore/bindings/v8/V8EventListenerList.h
r48978 r49050 56 56 57 57 template<typename WrapperType, typename ContextType> 58 static PassRefPtr<V8EventListener> findOrCreateWrapper(ContextType*, v8::Local<v8::Value>, bool isAttribute);58 static PassRefPtr<V8EventListener> findOrCreateWrapper(ContextType*, PassRefPtr<V8ListenerGuard>, v8::Local<v8::Value>, bool isAttribute); 59 59 60 60 static void clearWrapper(v8::Handle<v8::Object> listenerObject, bool isAttribute) … … 82 82 83 83 template<typename WrapperType, typename ContextType> 84 PassRefPtr<V8EventListener> V8EventListenerList::findOrCreateWrapper(ContextType* context, v8::Local<v8::Value> value, bool isAttribute)84 PassRefPtr<V8EventListener> V8EventListenerList::findOrCreateWrapper(ContextType* context, PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Value> value, bool isAttribute) 85 85 { 86 86 ASSERT(v8::Context::InContext()); … … 95 95 return wrapper; 96 96 97 PassRefPtr<V8EventListener> wrapperPtr = WrapperType::create(context, object, isAttribute);97 PassRefPtr<V8EventListener> wrapperPtr = WrapperType::create(context, guard, object, isAttribute); 98 98 if (wrapperPtr) 99 99 object->SetHiddenValue(wrapperProperty, v8::External::Wrap(wrapperPtr.get())); -
trunk/WebCore/bindings/v8/V8LazyEventListener.cpp
r48978 r49050 39 39 40 40 V8LazyEventListener::V8LazyEventListener(Frame* frame, const String& code, const String& functionName, bool isSVGEvent) 41 : V8AbstractEventListener(frame, true)41 : V8AbstractEventListener(frame, 0, true) 42 42 , m_code(code) 43 43 , m_functionName(functionName) -
trunk/WebCore/bindings/v8/V8Proxy.cpp
r49047 r49050 212 212 } 213 213 214 V8Proxy::V8Proxy(Frame* frame) 215 : m_frame(frame), 216 m_context(SharedPersistent<v8::Context>::create()), 217 m_listenerGuard(V8ListenerGuard::create()), 218 m_inlineCode(false), 219 m_timerCallback(false), 220 m_recursion(0) { } 221 214 222 V8Proxy::~V8Proxy() 215 223 { … … 562 570 void V8Proxy::disconnectFrame() 563 571 { 572 disconnectEventListeners(); 564 573 } 565 574 … … 695 704 } 696 705 706 void V8Proxy::disconnectEventListeners() 707 { 708 m_listenerGuard->disconnectListeners(); 709 m_listenerGuard = V8ListenerGuard::create(); 710 } 711 697 712 void V8Proxy::clearForClose() 698 713 { … … 707 722 void V8Proxy::clearForNavigation() 708 723 { 724 disconnectEventListeners(); 709 725 if (!context().IsEmpty()) { 710 726 v8::HandleScope handle; -
trunk/WebCore/bindings/v8/V8Proxy.h
r48978 r49050 36 36 #include "SecurityOrigin.h" // for WebCore::SecurityOrigin 37 37 #include "SharedPersistent.h" 38 #include "V8AbstractEventListener.h" 38 39 #include "V8DOMWrapper.h" 39 40 #include "V8GCController.h" … … 58 59 class String; 59 60 class V8EventListener; 60 class V8ObjectEventListener;61 61 62 62 // FIXME: use standard logging facilities in WebCore. … … 117 117 }; 118 118 119 explicit V8Proxy(Frame* frame) 120 : m_frame(frame), 121 m_context(SharedPersistent<v8::Context>::create()), 122 m_inlineCode(false), 123 m_timerCallback(false), 124 m_recursion(0) { } 119 explicit V8Proxy(Frame*); 125 120 126 121 ~V8Proxy(); … … 303 298 } 304 299 300 PassRefPtr<V8ListenerGuard> listenerGuard() 301 { 302 return m_listenerGuard; 303 } 304 305 305 bool setContextDebugId(int id); 306 306 static int contextDebugId(v8::Handle<v8::Context>); … … 348 348 void releaseStorageMutex(); 349 349 350 void disconnectEventListeners(); 351 350 352 static bool canAccessPrivate(DOMWindow*); 351 353 … … 382 384 RefPtr<SharedPersistent<v8::Context> > m_context; 383 385 386 RefPtr<V8ListenerGuard> m_listenerGuard; 387 384 388 // For each possible type of wrapper, we keep a boilerplate object. 385 389 // The boilerplate is used to create additional wrappers of the same -
trunk/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
r48978 r49050 41 41 namespace WebCore { 42 42 43 V8WorkerContextEventListener::V8WorkerContextEventListener(WorkerContextExecutionProxy* proxy, v8::Local<v8::Object> listener, bool isInline)44 : V8EventListener(0, listener, isInline)43 V8WorkerContextEventListener::V8WorkerContextEventListener(WorkerContextExecutionProxy* proxy, PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isInline) 44 : V8EventListener(0, guard, listener, isInline) 45 45 , m_proxy(proxy) 46 46 { -
trunk/WebCore/bindings/v8/V8WorkerContextEventListener.h
r48978 r49050 45 45 class V8WorkerContextEventListener : public V8EventListener { 46 46 public: 47 static PassRefPtr<V8WorkerContextEventListener> create(WorkerContextExecutionProxy* proxy, v8::Local<v8::Object> listener, bool isInline)47 static PassRefPtr<V8WorkerContextEventListener> create(WorkerContextExecutionProxy* proxy, PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isInline) 48 48 { 49 return adoptRef(new V8WorkerContextEventListener(proxy, listener, isInline));49 return adoptRef(new V8WorkerContextEventListener(proxy, guard, listener, isInline)); 50 50 } 51 V8WorkerContextEventListener(WorkerContextExecutionProxy*, v8::Local<v8::Object> listener, bool isInline);52 51 53 52 virtual void handleEvent(ScriptExecutionContext*, Event*); 54 53 virtual bool reportError(const String& message, const String& url, int lineNumber); 55 virtual bool disconnected() const { return !m_proxy; }56 54 57 55 WorkerContextExecutionProxy* proxy() const { return m_proxy; } 58 void disconnect() { m_proxy = 0; }59 56 60 57 private: 58 V8WorkerContextEventListener(WorkerContextExecutionProxy*, PassRefPtr<V8ListenerGuard>, v8::Local<v8::Object> listener, bool isInline); 59 61 60 virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*); 62 61 v8::Local<v8::Object> getReceiverObject(Event*); -
trunk/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
r48978 r49050 71 71 : m_workerContext(workerContext) 72 72 , m_recursion(0) 73 , m_listenerGuard(V8ListenerGuard::create()) 73 74 { 74 75 initV8IfNeeded(); … … 82 83 void WorkerContextExecutionProxy::dispose() 83 84 { 85 m_listenerGuard->disconnectListeners(); 86 84 87 // Detach all events from their JS wrappers. 85 88 for (size_t eventIndex = 0; eventIndex < m_events.size(); ++eventIndex) { … … 397 400 PassRefPtr<V8EventListener> WorkerContextExecutionProxy::findOrCreateEventListener(v8::Local<v8::Value> object, bool isInline, bool findOnly) 398 401 { 399 return findOnly ? V8EventListenerList::findWrapper(object, isInline) : V8EventListenerList::findOrCreateWrapper<V8WorkerContextEventListener>(this, object, isInline);402 return findOnly ? V8EventListenerList::findWrapper(object, isInline) : V8EventListenerList::findOrCreateWrapper<V8WorkerContextEventListener>(this, m_listenerGuard, object, isInline); 400 403 } 401 404 -
trunk/WebCore/bindings/v8/WorkerContextExecutionProxy.h
r48978 r49050 111 111 v8::Persistent<v8::Context> m_context; 112 112 int m_recursion; 113 RefPtr<V8ListenerGuard> m_listenerGuard; 113 114 114 115 Vector<Event*> m_events; -
trunk/WebCore/bindings/v8/custom/V8CustomEventListener.cpp
r48978 r49050 36 36 namespace WebCore { 37 37 38 V8EventListener::V8EventListener(Frame* frame, v8::Local<v8::Object> listener, bool isAttribute)39 : V8AbstractEventListener(frame, isAttribute)38 V8EventListener::V8EventListener(Frame* frame, PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isAttribute) 39 : V8AbstractEventListener(frame, guard, isAttribute) 40 40 { 41 41 setListenerObject(listener); -
trunk/WebCore/bindings/v8/custom/V8CustomEventListener.h
r48978 r49050 45 45 class V8EventListener : public V8AbstractEventListener { 46 46 public: 47 static PassRefPtr<V8EventListener> create(Frame* frame, v8::Local<v8::Object> listener, bool isAttribute)47 static PassRefPtr<V8EventListener> create(Frame* frame, PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isAttribute) 48 48 { 49 return adoptRef(new V8EventListener(frame, listener, isAttribute));49 return adoptRef(new V8EventListener(frame, guard, listener, isAttribute)); 50 50 } 51 51 52 52 protected: 53 V8EventListener(Frame*, v8::Local<v8::Object> listener, bool isAttribute);53 V8EventListener(Frame*, PassRefPtr<V8ListenerGuard>, v8::Local<v8::Object> listener, bool isAttribute); 54 54 55 55 v8::Local<v8::Function> getListenerFunction();
Note: See TracChangeset
for help on using the changeset viewer.