diff options
-rw-r--r-- | webkit/data/layout_tests/chrome/fast/dom/onload-fires-twice-expected.txt | 5 | ||||
-rw-r--r-- | webkit/data/layout_tests/chrome/fast/dom/onload-fires-twice.html | 22 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_events.cpp | 16 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_events.h | 21 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_proxy.cpp | 24 |
5 files changed, 58 insertions, 30 deletions
diff --git a/webkit/data/layout_tests/chrome/fast/dom/onload-fires-twice-expected.txt b/webkit/data/layout_tests/chrome/fast/dom/onload-fires-twice-expected.txt new file mode 100644 index 0000000..a1dae55 --- /dev/null +++ b/webkit/data/layout_tests/chrome/fast/dom/onload-fires-twice-expected.txt @@ -0,0 +1,5 @@ +Makes sure an inline "load" event does not fire twice. This may occur if +an inline event listener is not removed prior to being re-added in the case of +multiple body nodes in the document. + +This test has succeeded. diff --git a/webkit/data/layout_tests/chrome/fast/dom/onload-fires-twice.html b/webkit/data/layout_tests/chrome/fast/dom/onload-fires-twice.html new file mode 100644 index 0000000..691d83c --- /dev/null +++ b/webkit/data/layout_tests/chrome/fast/dom/onload-fires-twice.html @@ -0,0 +1,22 @@ +<html>
+<head>
+ <!-- any unknown element in HEAD will trigger creation of a BODY node -->
+ <anytag>
+ <script type="text/javascript">
+ if (window.layoutTestController)
+ layoutTestController.dumpAsText()
+
+ var count = 2;
+ function testDoubleLoad() {
+ if (!--count)
+ document.getElementById("status").innerHTML = "failed";
+ }
+ </script>
+</head>
+<body onload="testDoubleLoad()">
+ <p>Makes sure an inline "load" event does not fire twice. This may occur if<br>
+ an inline event listener is not removed prior to being re-added in the case of<br>
+ multiple body nodes in the document.</p>
+ <p>This test has <span id="status">succeeded</span>.
+</body>
+</html>
diff --git a/webkit/port/bindings/v8/v8_events.cpp b/webkit/port/bindings/v8/v8_events.cpp index bdd7e8a..0d41a67 100644 --- a/webkit/port/bindings/v8/v8_events.cpp +++ b/webkit/port/bindings/v8/v8_events.cpp @@ -45,15 +45,15 @@ namespace WebCore { -V8AbstractEventListener::V8AbstractEventListener(Frame* frame, bool html) - : m_frame(frame), m_html(html) { +V8AbstractEventListener::V8AbstractEventListener(Frame* frame, bool isInline) + : m_frame(frame), m_isInline(isInline) { ASSERT(m_frame); if (!m_frame) return; // Get the position in the source if any. m_lineNumber = 0; m_columnNumber = 0; - if (m_html && m_frame->document()->tokenizer()) { + if (m_isInline && m_frame->document()->tokenizer()) { m_lineNumber = m_frame->document()->tokenizer()->lineNumber(); m_columnNumber = m_frame->document()->tokenizer()->columnNumber(); } @@ -121,7 +121,7 @@ void V8AbstractEventListener::handleEvent(Event* event, bool isWindowEvent) { } // Prevent default action if the return value is false; // TODO(fqian): example, and reference to buganizer entry - if (m_html) { + if (m_isInline) { if (ret->IsBoolean() && !ret->BooleanValue()) { event->preventDefault(); } @@ -147,8 +147,8 @@ void V8AbstractEventListener::DisposeListenerObject() { V8EventListener::V8EventListener(Frame* frame, v8::Local<v8::Object> listener, - bool html) - : V8AbstractEventListener(frame, html) { + bool isInline) + : V8AbstractEventListener(frame, isInline) { m_listener = v8::Persistent<v8::Object>::New(listener); #ifndef NDEBUG V8Proxy::RegisterGlobalHandle(EVENT_LISTENER, this, m_listener); @@ -267,8 +267,8 @@ static void WeakObjectEventListenerCallback(v8::Persistent<v8::Value> obj, V8ObjectEventListener::V8ObjectEventListener(Frame* frame, v8::Local<v8::Object> listener, - bool html) - : V8EventListener(frame, listener, html) { + bool isInline) + : V8EventListener(frame, listener, isInline) { // make m_listener weak. m_listener.MakeWeak(this, WeakObjectEventListenerCallback); } diff --git a/webkit/port/bindings/v8/v8_events.h b/webkit/port/bindings/v8/v8_events.h index 5ff5e96..73edb5a 100644 --- a/webkit/port/bindings/v8/v8_events.h +++ b/webkit/port/bindings/v8/v8_events.h @@ -45,7 +45,7 @@ class V8AbstractEventListener : public EventListener { void DisposeListenerObject(); private: - V8AbstractEventListener(Frame* frame, bool html); + V8AbstractEventListener(Frame* frame, bool isInline); // Call listener function. @@ -65,7 +65,7 @@ class V8AbstractEventListener : public EventListener { v8::Persistent<v8::Object> m_listener; // Flags this is a HTML type listener. - bool m_html; + bool m_isInline; // Position in the HTML source for HTML event listeners. int m_lineNumber; @@ -82,13 +82,13 @@ class V8AbstractEventListener : public EventListener { class V8EventListener : public V8AbstractEventListener { public: static PassRefPtr<V8EventListener> create(Frame* frame, - v8::Local<v8::Object> listener, bool html) { - return adoptRef(new V8EventListener(frame, listener, html)); + v8::Local<v8::Object> listener, bool isInline) { + return adoptRef(new V8EventListener(frame, listener, isInline)); } - V8EventListener(Frame* frame, v8::Local<v8::Object> listener, bool html); + V8EventListener(Frame* frame, v8::Local<v8::Object> listener, bool isInline); virtual ~V8EventListener(); - virtual bool isHTMLEventListener() const { return m_html; } + virtual bool isAttachedToEventTargetNode() const { return m_isInline; } // Detach the listener from its owner frame. void disconnectFrame() { m_frame = 0; } @@ -107,10 +107,11 @@ class V8EventListener : public V8AbstractEventListener { class V8ObjectEventListener : public V8EventListener { public: static PassRefPtr<V8ObjectEventListener> create(Frame* frame, - v8::Local<v8::Object> listener, bool html) { - return adoptRef(new V8ObjectEventListener(frame, listener, html)); + v8::Local<v8::Object> listener, bool isInline) { + return adoptRef(new V8ObjectEventListener(frame, listener, isInline)); } - V8ObjectEventListener(Frame* frame, v8::Local<v8::Object> listener, bool html); + V8ObjectEventListener(Frame* frame, v8::Local<v8::Object> listener, + bool isInline); virtual ~V8ObjectEventListener(); }; @@ -127,7 +128,7 @@ class V8LazyEventListener : public V8AbstractEventListener { V8LazyEventListener(Frame *frame, const String& code, const String& func_name); virtual ~V8LazyEventListener(); - virtual bool isHTMLEventListener() const { return true; } + virtual bool isAttachedToEventTargetNode() const { return true; } // For lazy event listener, the listener object is the same as its listener // function without additional scope chains. diff --git a/webkit/port/bindings/v8/v8_proxy.cpp b/webkit/port/bindings/v8/v8_proxy.cpp index f0e48cc..cf71fb7 100644 --- a/webkit/port/bindings/v8/v8_proxy.cpp +++ b/webkit/port/bindings/v8/v8_proxy.cpp @@ -851,7 +851,7 @@ PassRefPtr<EventListener> V8Proxy::createSVGEventHandler(const String& functionN static V8EventListener* FindEventListenerInList(V8EventListenerList& list, v8::Local<v8::Value> listener, - bool html) + bool isInline) { ASSERT(v8::Context::InContext()); @@ -868,7 +868,7 @@ static V8EventListener* FindEventListenerInList(V8EventListenerList& list, // check using the == operator on the handles. This is much, // much faster than calling StrictEquals through the API in // the negative case. - if (el->isHTMLEventListener() == html && listener == wrapper) + if (el->isAttachedToEventTargetNode() == isInline && listener == wrapper) return el; ++p; } @@ -877,12 +877,12 @@ static V8EventListener* FindEventListenerInList(V8EventListenerList& list, // Find an existing wrapper for a JS event listener in the map. PassRefPtr<V8EventListener> V8Proxy::FindV8EventListener(v8::Local<v8::Value> listener, - bool html) + bool isInline) { - return FindEventListenerInList(m_event_listeners, listener, html); + return FindEventListenerInList(m_event_listeners, listener, isInline); } -PassRefPtr<V8EventListener> V8Proxy::FindOrCreateV8EventListener(v8::Local<v8::Value> obj, bool html) +PassRefPtr<V8EventListener> V8Proxy::FindOrCreateV8EventListener(v8::Local<v8::Value> obj, bool isInline) { ASSERT(v8::Context::InContext()); @@ -890,13 +890,13 @@ PassRefPtr<V8EventListener> V8Proxy::FindOrCreateV8EventListener(v8::Local<v8::V return 0; V8EventListener* wrapper = - FindEventListenerInList(m_event_listeners, obj, html); + FindEventListenerInList(m_event_listeners, obj, isInline); if (wrapper) return wrapper; // Create a new one, and add to cache. RefPtr<V8EventListener> new_listener = - V8EventListener::create(m_frame, v8::Local<v8::Object>::Cast(obj), html); + V8EventListener::create(m_frame, v8::Local<v8::Object>::Cast(obj), isInline); m_event_listeners.push_back(new_listener.get()); return new_listener; @@ -923,14 +923,14 @@ PassRefPtr<V8EventListener> V8Proxy::FindOrCreateV8EventListener(v8::Local<v8::V // of V8ObjectEventListener. PassRefPtr<V8EventListener> V8Proxy::FindObjectEventListener( - v8::Local<v8::Value> listener, bool html) + v8::Local<v8::Value> listener, bool isInline) { - return FindEventListenerInList(m_xhr_listeners, listener, html); + return FindEventListenerInList(m_xhr_listeners, listener, isInline); } PassRefPtr<V8EventListener> V8Proxy::FindOrCreateObjectEventListener( - v8::Local<v8::Value> obj, bool html) + v8::Local<v8::Value> obj, bool isInline) { ASSERT(v8::Context::InContext()); @@ -938,13 +938,13 @@ PassRefPtr<V8EventListener> V8Proxy::FindOrCreateObjectEventListener( return 0; V8EventListener* wrapper = - FindEventListenerInList(m_xhr_listeners, obj, html); + FindEventListenerInList(m_xhr_listeners, obj, isInline); if (wrapper) return wrapper; // Create a new one, and add to cache. RefPtr<V8EventListener> new_listener = - V8ObjectEventListener::create(m_frame, v8::Local<v8::Object>::Cast(obj), html); + V8ObjectEventListener::create(m_frame, v8::Local<v8::Object>::Cast(obj), isInline); m_xhr_listeners.push_back(new_listener.get()); return new_listener.release(); |