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

Commit 6b19b89

Browse files
querymetricsbluesmoon
authored andcommitted
Errors: Support capture flag in options object passed in addEventListener
1 parent 66e7e3d commit 6b19b89

3 files changed

Lines changed: 113 additions & 12 deletions

File tree

plugins/errors.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -858,7 +858,7 @@
858858
* @param {object} target Target element (window, element, etc)
859859
* @param {string} type Event type (name)
860860
* @param {function} listener Original listener
861-
* @param {boolean} useCapture Use capture
861+
* @param {boolean|object} useCapture|options Use capture flag or options object
862862
* @param {function} wrapped Wrapped function
863863
*/
864864
trackFn: function(target, type, listener, useCapture, wrapped) {
@@ -875,7 +875,12 @@
875875
target._bmrEvents = [];
876876
}
877877

878-
target._bmrEvents.push([type, listener, !!useCapture, wrapped]);
878+
// 3rd argment can be useCapture flag or options object that may contain a `capture` key.
879+
// Default is false in both cases
880+
useCapture = (useCapture && useCapture.capture || useCapture) === true;
881+
882+
target._bmrEvents.push([type, listener, useCapture, wrapped]);
883+
return true;
879884
},
880885

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

907+
// 3rd argment can be useCapture flag or options object that may contain a `capture` key.
908+
// Default is false in both cases
909+
useCapture = (useCapture && useCapture.capture || useCapture) === true;
910+
902911
for (i = 0; i < target._bmrEvents.length; i++) {
903912
f = target._bmrEvents[i];
904913
if (f[0] === type &&
905914
f[1] === listener &&
906-
f[2] === !!useCapture) {
915+
f[2] === useCapture) {
907916
return i;
908917
}
909918
}

tests/page-templates/14-errors/20-remove-event-listener.html

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,17 @@
1313
}
1414
});
1515

16+
window.aELPassiveSupported = false;
17+
window.aELCaptureSupported = false;
18+
1619
var img1 = new Image(); // "load" tracked, capture = false
1720
var img2 = new Image(); // "load" tracked, capture = true
1821
var img3 = new Image(); // "load" tracked, then removed, capture = false
1922
var img4 = new Image(); // "load" tracked, then removed, capture = true
2023
var img5 = new Image(); // "load" tracked using same as img3, then removed, capture = true
2124
var img6 = new Image(); // "load" tracked using same fn as img1, then removed, capture = false
2225
var img7 = new Image(); // "load" tracked using same fn as img1, then removed, capture = true
26+
var img8 = new Image(); // "load" tracked then removed several times
2327

2428
function errorFunction1() {
2529
// called 3x from img1,6,7
@@ -37,6 +41,10 @@
3741
// called 1x from img4
3842
a.foo4 = false;
3943
}
44+
function errorFunction5() {
45+
// never called
46+
a.foo5 = false;
47+
}
4048

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

5967
img7.addEventListener("load", errorFunction1, true);
6068
img7.removeEventListener("load", errorFunction1, true);
69+
70+
try {
71+
var options = {};
72+
Object.defineProperty(options, "passive", {
73+
get: function() {
74+
window.aELPassiveSupported = true;
75+
}
76+
});
77+
Object.defineProperty(options, "capture", {
78+
get: function() {
79+
window.aELCaptureSupported = true;
80+
}
81+
});
82+
window.addEventListener("test", null, options);
83+
}
84+
catch (err) {
85+
// ignore
86+
}
87+
88+
img8.addEventListener("load", errorFunction5); // useCapture defaults to false
89+
img8.removeEventListener("load", errorFunction5); // useCapture defaults to false
90+
91+
if (aELPassiveSupported) {
92+
img8.addEventListener("load", errorFunction5, {passive: true}); // useCapture defaults to false
93+
img8.removeEventListener("load", errorFunction5); // useCapture defaults to false
94+
95+
img8.addEventListener("load", errorFunction5, {passive: true}); // useCapture defaults to false
96+
img8.removeEventListener("load", errorFunction5, {passive: true}); // useCapture defaults to false
97+
98+
img8.addEventListener("load", errorFunction5, {passive: true}); // useCapture defaults to false
99+
// passive flag should not be considered by rEL
100+
img8.removeEventListener("load", errorFunction5, {passive: false}); // useCapture defaults to false
101+
}
102+
103+
if (aELCaptureSupported) {
104+
img8.addEventListener("load", errorFunction5, {capture: false});
105+
img8.removeEventListener("load", errorFunction5, {capture: false});
106+
107+
img8.addEventListener("load", errorFunction5, {capture: true});
108+
img8.removeEventListener("load", errorFunction5, {capture: true});
109+
110+
img8.addEventListener("load", errorFunction5, {capture: true});
111+
img8.removeEventListener("load", errorFunction5, true);
112+
113+
if (navigator.userAgent.indexOf("Phantom") === -1) {
114+
// these doesn't work in phantom, the event isn't removed
115+
116+
img8.addEventListener("load", errorFunction5, {capture: false});
117+
img8.removeEventListener("load", errorFunction5, false); // useCapture defaults to false
118+
119+
img8.addEventListener("load", errorFunction5, {capture: false});
120+
img8.removeEventListener("load", errorFunction5); // useCapture defaults to false
121+
}
122+
}
61123
}
62124

63125
img1.src = "/assets/img.jpg?1";
@@ -67,6 +129,7 @@
67129
img5.src = "/assets/img.jpg?5";
68130
img6.src = "/assets/img.jpg?6";
69131
img7.src = "/assets/img.jpg?7";
132+
img8.src = "/assets/img.jpg?8";
70133

71134
</script>
72135
<!-- delay the page by 1second so an error can fire -->

tests/page-templates/14-errors/20-remove-event-listener.js

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ describe("e2e/14-errors/20-remove-event-listener", function() {
66
var t = BOOMR_test;
77
var C = BOOMR.utils.Compression;
88

9+
function getError(error, regex) {
10+
var errors = BOOMR.plugins.Errors.decompressErrors(C.jsUrlDecompress(error));
11+
for (var i = 0; i < errors.length; i++) {
12+
if (regex.test(errors[i].stack)) {
13+
return errors[i];
14+
}
15+
}
16+
}
17+
918
if (!window.addEventListener) {
1019
it("Skipping on browser that doesn't support addEventListener", function() {
1120
});
@@ -30,25 +39,45 @@ describe("e2e/14-errors/20-remove-event-listener", function() {
3039

3140
it("Should have errorFunction1 have count = 1", function() {
3241
var b = tf.lastBeacon();
33-
var err = BOOMR.plugins.Errors.decompressErrors(C.jsUrlDecompress(b.err))[0];
34-
assert.equal(err.count, 1);
42+
var err = getError(b.err, /errorFunction1/);
43+
assert.equal((err && err.count) || 0, 1);
3544
});
3645

3746
it("Should have errorFunction2 have count = 1", function() {
3847
var b = tf.lastBeacon();
39-
var err = BOOMR.plugins.Errors.decompressErrors(C.jsUrlDecompress(b.err))[1];
40-
assert.equal(err.count, 1);
48+
var err = getError(b.err, /errorFunction2/);
49+
assert.equal((err && err.count) || 0, 1);
4150
});
4251

4352
it("Should have errorFunction3 have count = 1", function() {
4453
var b = tf.lastBeacon();
45-
var err = BOOMR.plugins.Errors.decompressErrors(C.jsUrlDecompress(b.err))[2];
46-
assert.equal(err.count, 1);
54+
var err = getError(b.err, /errorFunction3/);
55+
assert.equal((err && err.count) || 0, 1);
4756
});
4857

4958
it("Should have errorFunction4 have count = 1", function() {
5059
var b = tf.lastBeacon();
51-
var err = BOOMR.plugins.Errors.decompressErrors(C.jsUrlDecompress(b.err))[3];
52-
assert.equal(err.count, 1);
60+
var err = getError(b.err, /errorFunction4/);
61+
assert.equal((err && err.count) || 0, 1);
62+
});
63+
64+
it("Should not have errorFunction5", function() {
65+
var b = tf.lastBeacon();
66+
var err = getError(b.err, /errorFunction5/);
67+
assert.isUndefined(err);
68+
});
69+
70+
// informational
71+
it("INFO: addEventListener passive flag was tested for errorFunction5", function() {
72+
if (!window.aELPassiveSupported) {
73+
this.skip();
74+
}
75+
});
76+
77+
// informational
78+
it("INFO: addEventListener capture flag was tested for errorFunction5", function() {
79+
if (!window.aELCaptureSupported) {
80+
this.skip();
81+
}
5382
});
5483
});

0 commit comments

Comments
 (0)