1
1
import { API , getCurrentHub } from '@sentry/core' ;
2
- import { Breadcrumb , BreadcrumbHint , Integration , Severity } from '@sentry/types' ;
2
+ import { Breadcrumb , BreadcrumbHint , Integration , Severity , WrappedFunction } from '@sentry/types' ;
3
3
import {
4
4
fill ,
5
5
getEventDescription ,
@@ -19,7 +19,6 @@ import { breadcrumbEventHandler, keypressEventHandler, wrap } from './helpers';
19
19
20
20
const global = getGlobalObject < Window > ( ) ;
21
21
let lastHref : string | undefined ;
22
-
23
22
/**
24
23
* @hidden
25
24
*/
@@ -77,8 +76,7 @@ export class Breadcrumbs implements Integration {
77
76
if ( ! ( 'console' in global ) ) {
78
77
return ;
79
78
}
80
- const levels = [ 'log' , 'info' , 'warn' , 'error' , 'debug' , 'assert' ] ;
81
- levels . forEach ( function ( level : string ) : void {
79
+ [ 'debug' , 'info' , 'warn' , 'error' , 'log' , 'assert' ] . forEach ( function ( level : string ) : void {
82
80
if ( ! ( level in global . console ) ) {
83
81
return ;
84
82
}
@@ -123,10 +121,82 @@ export class Breadcrumbs implements Integration {
123
121
if ( ! ( 'document' in global ) ) {
124
122
return ;
125
123
}
124
+
126
125
// Capture breadcrumbs from any click that is unhandled / bubbled up all the way
127
126
// to the document. Do this before we instrument addEventListener.
128
127
global . document . addEventListener ( 'click' , breadcrumbEventHandler ( 'click' ) , false ) ;
129
128
global . document . addEventListener ( 'keypress' , keypressEventHandler ( ) , false ) ;
129
+
130
+ // After hooking into document bubbled up click and keypresses events, we also hook into user handled click & keypresses.
131
+ [ 'EventTarget' , 'Node' ] . forEach ( ( target : string ) => {
132
+ const proto = ( global as any ) [ target ] && ( global as any ) [ target ] . prototype ;
133
+
134
+ if ( ! proto || ! proto . hasOwnProperty || ! proto . hasOwnProperty ( 'addEventListener' ) ) {
135
+ return ;
136
+ }
137
+
138
+ fill ( proto , 'addEventListener' , function (
139
+ original : ( ) => void ,
140
+ ) : (
141
+ eventName : string ,
142
+ fn : EventListenerOrEventListenerObject ,
143
+ options ?: boolean | AddEventListenerOptions ,
144
+ ) => void {
145
+ return function (
146
+ this : any ,
147
+ eventName : string ,
148
+ fn : EventListenerOrEventListenerObject ,
149
+ options ?: boolean | AddEventListenerOptions ,
150
+ ) : ( eventName : string , fn : EventListenerOrEventListenerObject , capture ?: boolean , secure ?: boolean ) => void {
151
+ if ( ( fn as any ) . handleEvent ) {
152
+ if ( eventName === 'click' ) {
153
+ fill ( fn , 'handleEvent' , function ( innerOriginal : ( ) => void ) : ( caughtEvent : Event ) => void {
154
+ return function ( this : any , event : Event ) : ( event : Event ) => void {
155
+ breadcrumbEventHandler ( 'click' ) ( event ) ;
156
+ return innerOriginal . call ( this , event ) ;
157
+ } ;
158
+ } ) ;
159
+ }
160
+ if ( eventName === 'keypress' ) {
161
+ fill ( fn , 'handleEvent' , keypressEventHandler ( ) ) ;
162
+ }
163
+ } else {
164
+ if ( eventName === 'click' ) {
165
+ breadcrumbEventHandler ( 'click' , true ) ( this ) ;
166
+ }
167
+ if ( eventName === 'keypress' ) {
168
+ keypressEventHandler ( ) ( this ) ;
169
+ }
170
+ }
171
+
172
+ return original . call ( this , eventName , fn , options ) ;
173
+ } ;
174
+ } ) ;
175
+
176
+ fill ( proto , 'removeEventListener' , function (
177
+ original : ( ) => void ,
178
+ ) : (
179
+ this : any ,
180
+ eventName : string ,
181
+ fn : EventListenerObject ,
182
+ options ?: boolean | EventListenerOptions ,
183
+ ) => ( ) => void {
184
+ return function (
185
+ this : any ,
186
+ eventName : string ,
187
+ fn : EventListenerObject ,
188
+ options ?: boolean | EventListenerOptions ,
189
+ ) : ( ) => void {
190
+ let callback = ( fn as any ) as WrappedFunction ;
191
+ try {
192
+ callback = callback && ( callback . __sentry_wrapped__ || callback ) ;
193
+ } catch ( e ) {
194
+ // ignore, accessing __sentry_wrapped__ will throw in some Selenium environments
195
+ }
196
+ return original . call ( this , eventName , callback , options ) ;
197
+ } ;
198
+ } ) ;
199
+ } ) ;
130
200
}
131
201
132
202
/** JSDoc */
0 commit comments