diff --git a/plugins/errors.js b/plugins/errors.js index adeb8da3b..dd34077a6 100644 --- a/plugins/errors.js +++ b/plugins/errors.js @@ -1312,6 +1312,12 @@ return; } + var rEL; + if (functionName === "addEventListener") { + // grab the native + rEL = that.removeEventListener; + } + that[functionName] = function() { try { var args = Array.prototype.slice.call(arguments); @@ -1336,6 +1342,14 @@ // if the callback is already tracked, we won't call addEventListener return; } + if (rEL) { + // Remove the listener before adding it back in. + // This takes care of the (pathological) case where code is relying on the native + // de-dupping that the browser provides and BOOMR instruments `addEventListener` between + // their redundant calls to `addEventListener`. + // We detach with the native because there's no point in calling our wrapped version. + rEL.apply(targetObj, arguments); + } } return origFn.apply(targetObj, args); diff --git a/tests/page-templates/14-errors/41-addEventListener-dedupping.html b/tests/page-templates/14-errors/41-addEventListener-dedupping.html new file mode 100644 index 000000000..d2af6b307 --- /dev/null +++ b/tests/page-templates/14-errors/41-addEventListener-dedupping.html @@ -0,0 +1,27 @@ +<%= header %> +<%= boomerangDelayedSnippet %> + + +<%= footer %> diff --git a/tests/page-templates/14-errors/41-addEventListener-dedupping.js b/tests/page-templates/14-errors/41-addEventListener-dedupping.js new file mode 100644 index 000000000..7ac5eb9da --- /dev/null +++ b/tests/page-templates/14-errors/41-addEventListener-dedupping.js @@ -0,0 +1,10 @@ +/*eslint-env mocha*/ + +describe("e2e/14-errors/41-addEventListener-dedupping", function() { + var tf = BOOMR.plugins.TestFramework; + it("Should have only fired the foo handler once", function(done) { + var b = tf.lastBeacon(); + assert.equal(b.foo, "bar"); + done(); + }); +});