Skip to content
This repository has been archived by the owner on Apr 15, 2019. It is now read-only.

Commit

Permalink
Errors: Support capture flag in options object passed in addEventList…
Browse files Browse the repository at this point in the history
…ener
  • Loading branch information
querymetrics authored and bluesmoon committed Mar 27, 2018
1 parent 66e7e3d commit 6b19b89
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 12 deletions.
17 changes: 13 additions & 4 deletions plugins/errors.js
Expand Up @@ -858,7 +858,7 @@
* @param {object} target Target element (window, element, etc)
* @param {string} type Event type (name)
* @param {function} listener Original listener
* @param {boolean} useCapture Use capture
* @param {boolean|object} useCapture|options Use capture flag or options object
* @param {function} wrapped Wrapped function
*/
trackFn: function(target, type, listener, useCapture, wrapped) {
Expand All @@ -875,7 +875,12 @@
target._bmrEvents = [];
}

target._bmrEvents.push([type, listener, !!useCapture, wrapped]);
// 3rd argment can be useCapture flag or options object that may contain a `capture` key.
// Default is false in both cases
useCapture = (useCapture && useCapture.capture || useCapture) === true;

target._bmrEvents.push([type, listener, useCapture, wrapped]);
return true;
},

/**
Expand All @@ -884,7 +889,7 @@
* @param {object} target Target element (window, element, etc)
* @param {string} type Event type (name)
* @param {function} listener Original listener
* @param {boolean} useCapture Use capture
* @param {boolean|object} useCapture|options Use capture flag or options object
*
* @returns {number} Index of already tracked function, or -1 if it doesn't exist
*/
Expand All @@ -899,11 +904,15 @@
target._bmrEvents = [];
}

// 3rd argment can be useCapture flag or options object that may contain a `capture` key.
// Default is false in both cases
useCapture = (useCapture && useCapture.capture || useCapture) === true;

for (i = 0; i < target._bmrEvents.length; i++) {
f = target._bmrEvents[i];
if (f[0] === type &&
f[1] === listener &&
f[2] === !!useCapture) {
f[2] === useCapture) {
return i;
}
}
Expand Down
63 changes: 63 additions & 0 deletions tests/page-templates/14-errors/20-remove-event-listener.html
Expand Up @@ -13,13 +13,17 @@
}
});

window.aELPassiveSupported = false;
window.aELCaptureSupported = false;

var img1 = new Image(); // "load" tracked, capture = false
var img2 = new Image(); // "load" tracked, capture = true
var img3 = new Image(); // "load" tracked, then removed, capture = false
var img4 = new Image(); // "load" tracked, then removed, capture = true
var img5 = new Image(); // "load" tracked using same as img3, then removed, capture = true
var img6 = new Image(); // "load" tracked using same fn as img1, then removed, capture = false
var img7 = new Image(); // "load" tracked using same fn as img1, then removed, capture = true
var img8 = new Image(); // "load" tracked then removed several times

function errorFunction1() {
// called 3x from img1,6,7
Expand All @@ -37,6 +41,10 @@
// called 1x from img4
a.foo4 = false;
}
function errorFunction5() {
// never called
a.foo5 = false;
}

if (window.addEventListener) {
img1.addEventListener("load", errorFunction1, false);
Expand All @@ -58,6 +66,60 @@

img7.addEventListener("load", errorFunction1, true);
img7.removeEventListener("load", errorFunction1, true);

try {
var options = {};
Object.defineProperty(options, "passive", {
get: function() {
window.aELPassiveSupported = true;
}
});
Object.defineProperty(options, "capture", {
get: function() {
window.aELCaptureSupported = true;
}
});
window.addEventListener("test", null, options);
}
catch (err) {
// ignore
}

img8.addEventListener("load", errorFunction5); // useCapture defaults to false
img8.removeEventListener("load", errorFunction5); // useCapture defaults to false

if (aELPassiveSupported) {
img8.addEventListener("load", errorFunction5, {passive: true}); // useCapture defaults to false
img8.removeEventListener("load", errorFunction5); // useCapture defaults to false

img8.addEventListener("load", errorFunction5, {passive: true}); // useCapture defaults to false
img8.removeEventListener("load", errorFunction5, {passive: true}); // useCapture defaults to false

img8.addEventListener("load", errorFunction5, {passive: true}); // useCapture defaults to false
// passive flag should not be considered by rEL
img8.removeEventListener("load", errorFunction5, {passive: false}); // useCapture defaults to false
}

if (aELCaptureSupported) {
img8.addEventListener("load", errorFunction5, {capture: false});
img8.removeEventListener("load", errorFunction5, {capture: false});

img8.addEventListener("load", errorFunction5, {capture: true});
img8.removeEventListener("load", errorFunction5, {capture: true});

img8.addEventListener("load", errorFunction5, {capture: true});
img8.removeEventListener("load", errorFunction5, true);

if (navigator.userAgent.indexOf("Phantom") === -1) {
// these doesn't work in phantom, the event isn't removed

img8.addEventListener("load", errorFunction5, {capture: false});
img8.removeEventListener("load", errorFunction5, false); // useCapture defaults to false

img8.addEventListener("load", errorFunction5, {capture: false});
img8.removeEventListener("load", errorFunction5); // useCapture defaults to false
}
}
}

img1.src = "/assets/img.jpg?1";
Expand All @@ -67,6 +129,7 @@
img5.src = "/assets/img.jpg?5";
img6.src = "/assets/img.jpg?6";
img7.src = "/assets/img.jpg?7";
img8.src = "/assets/img.jpg?8";

</script>
<!-- delay the page by 1second so an error can fire -->
Expand Down
45 changes: 37 additions & 8 deletions tests/page-templates/14-errors/20-remove-event-listener.js
Expand Up @@ -6,6 +6,15 @@ describe("e2e/14-errors/20-remove-event-listener", function() {
var t = BOOMR_test;
var C = BOOMR.utils.Compression;

function getError(error, regex) {
var errors = BOOMR.plugins.Errors.decompressErrors(C.jsUrlDecompress(error));
for (var i = 0; i < errors.length; i++) {
if (regex.test(errors[i].stack)) {
return errors[i];
}
}
}

if (!window.addEventListener) {
it("Skipping on browser that doesn't support addEventListener", function() {
});
Expand All @@ -30,25 +39,45 @@ describe("e2e/14-errors/20-remove-event-listener", function() {

it("Should have errorFunction1 have count = 1", function() {
var b = tf.lastBeacon();
var err = BOOMR.plugins.Errors.decompressErrors(C.jsUrlDecompress(b.err))[0];
assert.equal(err.count, 1);
var err = getError(b.err, /errorFunction1/);
assert.equal((err && err.count) || 0, 1);
});

it("Should have errorFunction2 have count = 1", function() {
var b = tf.lastBeacon();
var err = BOOMR.plugins.Errors.decompressErrors(C.jsUrlDecompress(b.err))[1];
assert.equal(err.count, 1);
var err = getError(b.err, /errorFunction2/);
assert.equal((err && err.count) || 0, 1);
});

it("Should have errorFunction3 have count = 1", function() {
var b = tf.lastBeacon();
var err = BOOMR.plugins.Errors.decompressErrors(C.jsUrlDecompress(b.err))[2];
assert.equal(err.count, 1);
var err = getError(b.err, /errorFunction3/);
assert.equal((err && err.count) || 0, 1);
});

it("Should have errorFunction4 have count = 1", function() {
var b = tf.lastBeacon();
var err = BOOMR.plugins.Errors.decompressErrors(C.jsUrlDecompress(b.err))[3];
assert.equal(err.count, 1);
var err = getError(b.err, /errorFunction4/);
assert.equal((err && err.count) || 0, 1);
});

it("Should not have errorFunction5", function() {
var b = tf.lastBeacon();
var err = getError(b.err, /errorFunction5/);
assert.isUndefined(err);
});

// informational
it("INFO: addEventListener passive flag was tested for errorFunction5", function() {
if (!window.aELPassiveSupported) {
this.skip();
}
});

// informational
it("INFO: addEventListener capture flag was tested for errorFunction5", function() {
if (!window.aELCaptureSupported) {
this.skip();
}
});
});

0 comments on commit 6b19b89

Please sign in to comment.