Skip to content

Commit c9621c3

Browse files
committed
Transparently unroll wrapped fns for removeEventListener
1 parent e3732bb commit c9621c3

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

src/raven.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,11 @@ Raven.prototype = {
222222
return func;
223223
}
224224

225+
// If this has already been wrapped in the past, return that
226+
if (func.__wrapper__){
227+
return func.__wrapper__;
228+
}
229+
225230
function wrapped() {
226231
var args = [], i = arguments.length,
227232
deep = !options || options && options.deep !== false;
@@ -246,6 +251,8 @@ Raven.prototype = {
246251
wrapped[property] = func[property];
247252
}
248253
}
254+
func.__wrapper__ = wrapped;
255+
249256
wrapped.prototype = func.prototype;
250257

251258
// Signal that this function has been wrapped already
@@ -584,10 +591,16 @@ Raven.prototype = {
584591
return function (evt, fn, capture, secure) { // preserve arity
585592
try {
586593
if (fn && fn.handleEvent) {
587-
fn.handleEvent = self.wrap(fn.handleEvent, {eventHandler: true});
594+
fn.handleEvent = self.wrap(fn.handleEvent);
588595
}
589596
} catch (err) {} // can sometimes get 'Permission denied to access property "handle Event'
590-
return orig.call(this, evt, self.wrap(fn, {eventHandler: true}), capture, secure);
597+
return orig.call(this, evt, self.wrap(fn), capture, secure);
598+
};
599+
});
600+
fill(proto, 'removeEventListener', function (orig) {
601+
return function (evt, fn, capture, secure) {
602+
fn = fn && (fn.__wrapper__ ? fn.__wrapper__ : fn);
603+
return orig.call(this, evt, fn, capture, secure);
591604
};
592605
});
593606
}

test/integration/test.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ describe('integration', function () {
125125
foo();
126126
}, false);
127127

128-
// use setTimeout to "normalize" stack origin
129128
var evt;
130129
if (document.createEvent) {
131130
evt = document.createEvent('MouseEvents');
@@ -142,6 +141,35 @@ describe('integration', function () {
142141
);
143142
});
144143

144+
it('should transparently remove event listeners from wrapped functions', function (done) {
145+
var iframe = this.iframe;
146+
147+
iframeExecute(iframe, done,
148+
function () {
149+
setTimeout(done);
150+
151+
var div = document.createElement('div');
152+
document.body.appendChild(div);
153+
var fooFn = function () { foo(); };
154+
div.addEventListener('click', fooFn, false);
155+
div.removeEventListener('click', fooFn);
156+
157+
var evt;
158+
if (document.createEvent) {
159+
evt = document.createEvent('MouseEvents');
160+
evt.initEvent('click', true, false);
161+
div.dispatchEvent(evt);
162+
} else if(document.createEventObject) {
163+
div.fireEvent('onclick');
164+
}
165+
},
166+
function () {
167+
var ravenData = iframe.contentWindow.ravenData;
168+
assert.equal(ravenData, null); // should never trigger error
169+
}
170+
);
171+
});
172+
145173
it('should capture exceptions inside setTimeout', function (done) {
146174
var iframe = this.iframe;
147175

0 commit comments

Comments
 (0)