@@ -658,8 +658,12 @@ Raven.prototype = {
658
658
659
659
function wrapTimeFn ( orig ) {
660
660
return function ( fn , t ) { // preserve arity
661
- // Make a copy of the arguments
662
- var args = [ ] . slice . call ( arguments ) ;
661
+ // Make a copy of the arguments to prevent deoptimization
662
+ // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments
663
+ var args = new Array ( arguments . length ) ;
664
+ for ( var i = 0 ; i < args . length ; ++ i ) {
665
+ args [ i ] = arguments [ i ] ;
666
+ }
663
667
var originalCallback = args [ 0 ] ;
664
668
if ( isFunction ( originalCallback ) ) {
665
669
args [ 0 ] = self . wrap ( originalCallback ) ;
@@ -676,26 +680,7 @@ Raven.prototype = {
676
680
} ;
677
681
}
678
682
679
- fill ( window , 'setTimeout' , wrapTimeFn ) ;
680
- fill ( window , 'setInterval' , wrapTimeFn ) ;
681
- if ( window . requestAnimationFrame ) {
682
- fill ( window , 'requestAnimationFrame' , function ( orig ) {
683
- return function ( cb ) {
684
- return orig ( self . wrap ( cb ) ) ;
685
- } ;
686
- } ) ;
687
- }
688
-
689
- // Capture breadcrubms from any click that is unhandled / bubbled up all the way
690
- // to the document. Do this before we instrument addEventListener.
691
- if ( this . _hasDocument ) {
692
- document . addEventListener ( 'click' , self . _breadcrumbEventHandler ( 'click' ) ) ;
693
-
694
- }
695
-
696
- // event targets borrowed from bugsnag-js:
697
- // https://github.com/bugsnag/bugsnag-js/blob/master/src/bugsnag.js#L666
698
- 'EventTarget Window Node ApplicationCache AudioTrackList ChannelMergerNode CryptoOperation EventSource FileReader HTMLUnknownElement IDBDatabase IDBRequest IDBTransaction KeyOperation MediaController MessagePort ModalWindow Notification SVGElementInstance Screen TextTrack TextTrackCue TextTrackList WebSocket WebSocketWorker Worker XMLHttpRequest XMLHttpRequestEventTarget XMLHttpRequestUpload' . replace ( / \w + / g, function ( global ) {
683
+ function wrapEventTarget ( global ) {
699
684
var proto = window [ global ] && window [ global ] . prototype ;
700
685
if ( proto && proto . hasOwnProperty && proto . hasOwnProperty ( 'addEventListener' ) ) {
701
686
fill ( proto , 'addEventListener' , function ( orig ) {
@@ -724,7 +709,38 @@ Raven.prototype = {
724
709
} ;
725
710
} ) ;
726
711
}
727
- } ) ;
712
+ }
713
+
714
+ function wrapProp ( prop , xhr ) {
715
+ if ( prop in xhr && isFunction ( xhr [ prop ] ) ) {
716
+ fill ( xhr , prop , function ( orig ) {
717
+ return self . wrap ( orig ) ;
718
+ } , true /* noUndo */ ) ; // don't track filled methods on XHR instances
719
+ }
720
+ }
721
+
722
+ fill ( window , 'setTimeout' , wrapTimeFn ) ;
723
+ fill ( window , 'setInterval' , wrapTimeFn ) ;
724
+ if ( window . requestAnimationFrame ) {
725
+ fill ( window , 'requestAnimationFrame' , function ( orig ) {
726
+ return function ( cb ) {
727
+ return orig ( self . wrap ( cb ) ) ;
728
+ } ;
729
+ } ) ;
730
+ }
731
+
732
+ // Capture breadcrubms from any click that is unhandled / bubbled up all the way
733
+ // to the document. Do this before we instrument addEventListener.
734
+ if ( this . _hasDocument ) {
735
+ document . addEventListener ( 'click' , self . _breadcrumbEventHandler ( 'click' ) ) ;
736
+ }
737
+
738
+ // event targets borrowed from bugsnag-js:
739
+ // https://github.com/bugsnag/bugsnag-js/blob/master/src/bugsnag.js#L666
740
+ var eventTargets = [ 'EventTarget' , 'Window' , 'Node' , 'ApplicationCache' , 'AudioTrackList' , 'ChannelMergerNode' , 'CryptoOperation' , 'EventSource' , 'FileReader' , 'HTMLUnknownElement' , 'IDBDatabase' , 'IDBRequest' , 'IDBTransaction' , 'KeyOperation' , 'MediaController' , 'MessagePort' , 'ModalWindow' , 'Notification' , 'SVGElementInstance' , 'Screen' , 'TextTrack' , 'TextTrackCue' , 'TextTrackList' , 'WebSocket' , 'WebSocketWorker' , 'Worker' , 'XMLHttpRequest' , 'XMLHttpRequestEventTarget' , 'XMLHttpRequestUpload' ] ;
741
+ for ( var i = 0 ; i < eventTargets . length ; i ++ ) {
742
+ wrapEventTarget ( eventTargets [ i ] ) ;
743
+ }
728
744
729
745
if ( 'XMLHttpRequest' in window ) {
730
746
var xhrproto = XMLHttpRequest . prototype ;
@@ -754,13 +770,10 @@ Raven.prototype = {
754
770
}
755
771
}
756
772
757
- 'onload onerror onprogress' . replace ( / \w + / g, function ( prop ) {
758
- if ( prop in xhr && isFunction ( xhr [ prop ] ) ) {
759
- fill ( xhr , prop , function ( orig ) {
760
- return self . wrap ( orig ) ;
761
- } , true /* noUndo */ ) ; // don't track filled methods on XHR instances
762
- }
763
- } ) ;
773
+ var props = [ 'onload' , 'onerror' , 'onprogress' ] ;
774
+ for ( var j = 0 ; j < props . length ; j ++ ) {
775
+ wrapProp ( props [ j ] , xhr ) ;
776
+ }
764
777
765
778
if ( 'onreadystatechange' in xhr && isFunction ( xhr . onreadystatechange ) ) {
766
779
fill ( xhr , 'onreadystatechange' , function ( orig ) {
0 commit comments