Skip to content
This repository was archived by the owner on Mar 13, 2018. It is now read-only.

Commit 7004965

Browse files
committed
Merge pull request #457 from arv/event-reentrancy
Fix issue with event reentrancy
2 parents 26f93ae + 8b59c27 commit 7004965

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

src/wrappers/events.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,10 @@
382382
targetTable.set(event, target);
383383
currentTargetTable.set(event, currentTarget);
384384

385+
// Keep track of the invoke depth so that we only clean up the removed
386+
// listeners if we are in the outermost invoke.
387+
listeners.depth++;
388+
385389
for (var i = 0, len = listeners.length; i < len; i++) {
386390
var listener = listeners[i];
387391
if (listener.removed) {
@@ -410,7 +414,9 @@
410414
}
411415
}
412416

413-
if (anyRemoved) {
417+
listeners.depth--;
418+
419+
if (anyRemoved && listeners.depth === 0) {
414420
var copy = listeners.slice();
415421
listeners.length = 0;
416422
for (var i = 0; i < copy.length; i++) {
@@ -707,6 +713,7 @@
707713
var listeners = listenersTable.get(this);
708714
if (!listeners) {
709715
listeners = [];
716+
listeners.depth = 0;
710717
listenersTable.set(this, listeners);
711718
} else {
712719
// Might have a duplicate.

test/js/events.js

+28
Original file line numberDiff line numberDiff line change
@@ -1448,4 +1448,32 @@ test('retarget order (multiple shadow roots)', function() {
14481448
assert.equal(gCount, 2);
14491449
assert.equal(hCount, 1);
14501450
});
1451+
1452+
test('Event reentrancy', function() {
1453+
div = document.createElement('div');
1454+
document.body.appendChild(div);
1455+
var s = '';
1456+
var depth = 0;
1457+
1458+
function f() {
1459+
s += 'f' + depth;
1460+
if (depth === 0) {
1461+
depth++;
1462+
div.dispatchEvent(new Event('x'));
1463+
} else if (depth === 1) {
1464+
div.removeEventListener('x', g);
1465+
}
1466+
}
1467+
1468+
function g() {
1469+
s += 'g' + depth;
1470+
}
1471+
1472+
div.addEventListener('x', f);
1473+
div.addEventListener('x', g);
1474+
1475+
div.dispatchEvent(new Event('x'));
1476+
1477+
assert.equal(s, 'f0f1');
1478+
});
14511479
});

0 commit comments

Comments
 (0)