diff --git a/src/wrappers/events.js b/src/wrappers/events.js index d413e61..47d71d0 100644 --- a/src/wrappers/events.js +++ b/src/wrappers/events.js @@ -643,7 +643,12 @@ }, dispatchEvent: function(event) { var target = getTargetToListenAt(this); - return target.dispatchEvent_(unwrap(event)); + var nativeEvent = unwrap(event); + // Allow dispatching the same event again. This is safe because if user + // code calls this during an existing dispatch of the same event the + // native dispatchEvent throws (that is required by the spec). + handledEventsTable.set(nativeEvent, false); + return target.dispatchEvent_(nativeEvent); } }; @@ -654,7 +659,6 @@ forwardMethodsToWrapper(constructors, methodNames); } - var originalElementFromPoint = document.elementFromPoint; function elementFromPoint(self, document, x, y) { diff --git a/test/js/events.js b/test/js/events.js index 0114fcc..6d3c697 100644 --- a/test/js/events.js +++ b/test/js/events.js @@ -1277,4 +1277,43 @@ test('retarget order (multiple shadow roots)', function() { text.dispatchEvent(new Event('x')); }); + test('dispatch same event object twice', function() { + var e = new Event('x', {bubbles: true}); + var doc = wrap(document); + + var count = 0; + function handler(e) { + count++; + }; + + doc.addEventListener('x', handler); + + document.dispatchEvent(e); + assert.equal(count, 1); + document.dispatchEvent(e); + assert.equal(count, 2); + document.dispatchEvent(e); + assert.equal(count, 3); + + doc.removeEventListener('x', handler); + }); + + test('Ensure nested dispatch is not allowed', function() { + var e = new Event('x', {bubbles: true}); + var doc = wrap(document); + + var count = 0; + + doc.addEventListener('x', function f(e) { + count++; + assert.throws(function() { + doc.dispatchEvent(e); + }); + }); + + doc.dispatchEvent(e); + + assert.equal(count, 1); + }); + });