8
8
SegmentIntegration
9
9
} from './types' ;
10
10
11
+ import cloneDeep from 'lodash.clonedeep'
12
+
11
13
var _analytics = global . analytics ;
12
14
13
15
/*
@@ -27,18 +29,14 @@ var DestinationMiddlewareChain = require('./middleware')
27
29
var Page = require ( 'segmentio-facade' ) . Page ;
28
30
var Track = require ( 'segmentio-facade' ) . Track ;
29
31
var bindAll = require ( 'bind-all' ) ;
30
- var clone = require ( './utils/clone' ) ;
31
32
var extend = require ( 'extend' ) ;
32
33
var cookie = require ( './cookie' ) ;
33
34
var metrics = require ( './metrics' ) ;
34
35
var debug = require ( 'debug' ) ;
35
36
var defaults = require ( '@ndhoule/defaults' ) ;
36
- var each = require ( './utils/each' ) ;
37
- var foldl = require ( '@ndhoule/foldl' ) ;
38
37
var group = require ( './group' ) ;
39
38
var is = require ( 'is' ) ;
40
39
var isMeta = require ( '@segment/is-meta' ) ;
41
- var keys = require ( '@ndhoule/keys' ) ;
42
40
var memory = require ( './memory' ) ;
43
41
var nextTick = require ( 'next-tick' ) ;
44
42
var normalize = require ( './normalize' ) ;
@@ -69,8 +67,9 @@ function Analytics() {
69
67
this . log = debug ( 'analytics.js' ) ;
70
68
bindAll ( this ) ;
71
69
72
- var self = this ;
73
- this . on ( 'initialize' , function ( settings , options ) {
70
+
71
+ const self = this ;
72
+ this . on ( 'initialize' , function ( _ , options ) {
74
73
if ( options . initialPageview ) self . page ( ) ;
75
74
self . _parseQuery ( window . location . search ) ;
76
75
} ) ;
@@ -169,13 +168,16 @@ Analytics.prototype.init = Analytics.prototype.initialize = function(
169
168
170
169
// clean unknown integrations from settings
171
170
var self = this ;
172
- each ( function ( _opts : unknown , name : string | number ) {
173
- var Integration = self . Integrations [ name ] ;
174
- if ( ! Integration ) delete settings [ name ] ;
175
- } , settings ) ;
171
+ Object . keys ( settings ) . forEach ( key => {
172
+ var Integration = self . Integrations [ key ] ;
173
+ if ( ! Integration ) delete settings [ key ] ;
174
+ } ) ;
176
175
177
176
// add integrations
178
- each ( function ( opts : unknown , name : string | number ) {
177
+ Object . keys ( settings ) . forEach ( key => {
178
+ const opts = settings [ key ]
179
+ const name = key
180
+
179
181
// Don't load disabled integrations
180
182
if ( options . integrations ) {
181
183
if (
@@ -186,13 +188,13 @@ Analytics.prototype.init = Analytics.prototype.initialize = function(
186
188
}
187
189
}
188
190
189
- var Integration = self . Integrations [ name ] ;
190
- var clonedOpts = { } ;
191
+ const Integration = self . Integrations [ name ] ;
192
+ const clonedOpts = { } ;
191
193
extend ( true , clonedOpts , opts ) ; // deep clone opts
192
- var integration = new Integration ( clonedOpts ) ;
194
+ const integration = new Integration ( clonedOpts ) ;
193
195
self . log ( 'initialize %o - %o' , name , opts ) ;
194
196
self . add ( integration ) ;
195
- } , settings ) ;
197
+ } ) ;
196
198
197
199
var integrations = this . _integrations ;
198
200
@@ -202,7 +204,7 @@ Analytics.prototype.init = Analytics.prototype.initialize = function(
202
204
203
205
// make ready callback
204
206
var readyCallCount = 0 ;
205
- var integrationCount = keys ( integrations ) . length ;
207
+ var integrationCount = Object . keys ( integrations ) . length ;
206
208
var ready = function ( ) {
207
209
readyCallCount ++ ;
208
210
if ( readyCallCount >= integrationCount ) {
@@ -219,14 +221,15 @@ Analytics.prototype.init = Analytics.prototype.initialize = function(
219
221
// initialize integrations, passing ready
220
222
// create a list of any integrations that did not initialize - this will be passed with all events for replay support:
221
223
this . failedInitializations = [ ] ;
222
- var initialPageSkipped = false ;
223
- each ( function ( integration ) {
224
+ let initialPageSkipped = false ;
225
+ Object . keys ( integrations ) . forEach ( key => {
226
+ const integration = integrations [ key ]
224
227
if (
225
228
options . initialPageview &&
226
229
integration . options . initialPageview === false
227
230
) {
228
231
// We've assumed one initial pageview, so make sure we don't count the first page call.
229
- var page = integration . page ;
232
+ let page = integration . page ;
230
233
integration . page = function ( ) {
231
234
if ( initialPageSkipped ) {
232
235
return page . apply ( this , arguments ) ;
@@ -246,7 +249,7 @@ Analytics.prototype.init = Analytics.prototype.initialize = function(
246
249
} ) ;
247
250
integration . initialize ( ) ;
248
251
} catch ( e ) {
249
- var integrationName = integration . name ;
252
+ let integrationName = integration . name ;
250
253
metrics . increment ( 'analytics_js.integration.invoke.error' , {
251
254
method : 'initialize' ,
252
255
integration_name : integration . name
@@ -257,7 +260,7 @@ Analytics.prototype.init = Analytics.prototype.initialize = function(
257
260
258
261
integration . ready ( ) ;
259
262
}
260
- } , integrations ) ;
263
+ } ) ;
261
264
262
265
// backwards compat with angular plugin and used for init logic checks
263
266
this . initialized = true ;
@@ -466,37 +469,44 @@ Analytics.prototype.track = function(
466
469
*/
467
470
468
471
Analytics . prototype . trackClick = Analytics . prototype . trackLink = function (
469
- links : Element | Array < unknown > ,
472
+ links : Element | Array < Element > | JQuery ,
470
473
event : any ,
471
474
properties ?: any
472
475
) : SegmentAnalytics {
476
+ let elements : Array < Element > = [ ]
473
477
if ( ! links ) return this ;
474
478
// always arrays, handles jquery
475
- if ( type ( links ) === 'element' ) links = [ links ] ;
479
+ if ( links instanceof Element ) {
480
+ elements = [ links ]
481
+ } else if ( "toArray" in links ) {
482
+ elements = links . toArray ( )
483
+ } else {
484
+ elements = links as Array < Element >
485
+ }
476
486
477
- var self = this ;
478
- each ( function ( el ) {
487
+ elements . forEach ( el => {
479
488
if ( type ( el ) !== 'element' ) {
480
489
throw new TypeError ( 'Must pass HTMLElement to `analytics.trackLink`.' ) ;
481
490
}
482
- on ( el , 'click' , function ( e ) {
483
- var ev = is . fn ( event ) ? event ( el ) : event ;
484
- var props = is . fn ( properties ) ? properties ( el ) : properties ;
485
- var href =
491
+ on ( el , 'click' , ( e ) => {
492
+ const ev = is . fn ( event ) ? event ( el ) : event ;
493
+ const props = is . fn ( properties ) ? properties ( el ) : properties ;
494
+ const href =
486
495
el . getAttribute ( 'href' ) ||
487
496
el . getAttributeNS ( 'http://www.w3.org/1999/xlink' , 'href' ) ||
488
497
el . getAttribute ( 'xlink:href' ) ;
489
498
490
- self . track ( ev , props ) ;
499
+ this . track ( ev , props ) ;
491
500
501
+ // @ts -ignore
492
502
if ( href && el . target !== '_blank' && ! isMeta ( e ) ) {
493
503
prevent ( e ) ;
494
- self . _callback ( function ( ) {
504
+ this . _callback ( function ( ) {
495
505
window . location . href = href ;
496
506
} ) ;
497
507
}
498
508
} ) ;
499
- } , links ) ;
509
+ } ) ;
500
510
501
511
return this ;
502
512
} ;
@@ -522,18 +532,19 @@ Analytics.prototype.trackSubmit = Analytics.prototype.trackForm = function(
522
532
// always arrays, handles jquery
523
533
if ( type ( forms ) === 'element' ) forms = [ forms ] ;
524
534
525
- var self = this ;
526
- each ( function ( el : { submit : ( ) => void } ) {
535
+ const elements = forms as Array < unknown >
536
+
537
+ elements . forEach ( ( el : { submit : ( ) => void } ) => {
527
538
if ( type ( el ) !== 'element' )
528
539
throw new TypeError ( 'Must pass HTMLElement to `analytics.trackForm`.' ) ;
529
- function handler ( e ) {
540
+ const handler = ( e ) => {
530
541
prevent ( e ) ;
531
542
532
- var ev = is . fn ( event ) ? event ( el ) : event ;
533
- var props = is . fn ( properties ) ? properties ( el ) : properties ;
534
- self . track ( ev , props ) ;
543
+ const ev = is . fn ( event ) ? event ( el ) : event ;
544
+ const props = is . fn ( properties ) ? properties ( el ) : properties ;
545
+ this . track ( ev , props ) ;
535
546
536
- self . _callback ( function ( ) {
547
+ this . _callback ( function ( ) {
537
548
el . submit ( ) ;
538
549
} ) ;
539
550
}
@@ -546,7 +557,7 @@ Analytics.prototype.trackSubmit = Analytics.prototype.trackForm = function(
546
557
} else {
547
558
on ( el , 'submit' , handler ) ;
548
559
}
549
- } , forms ) ;
560
+ } ) ;
550
561
551
562
return this ;
552
563
} ;
@@ -583,7 +594,7 @@ Analytics.prototype.page = function(
583
594
( name = category ) , ( category = null ) ;
584
595
/* eslint-enable no-unused-expressions, no-sequences */
585
596
586
- properties = clone ( properties ) || { } ;
597
+ properties = cloneDeep ( properties ) || { } ;
587
598
if ( name ) properties . name = name ;
588
599
if ( category ) properties . category = category ;
589
600
@@ -595,7 +606,7 @@ Analytics.prototype.page = function(
595
606
// Mirror user overrides to `options.context.page` (but exclude custom properties)
596
607
// (Any page defaults get applied in `this.normalize` for consistency.)
597
608
// Weird, yeah--moving special props to `context.page` will fix this in the long term.
598
- var overrides = pick ( keys ( defs ) , properties ) ;
609
+ var overrides = pick ( Object . keys ( defs ) , properties ) ;
599
610
if ( ! is . empty ( overrides ) ) {
600
611
options = options || { } ;
601
612
options . context = options . context || { } ;
@@ -796,9 +807,11 @@ Analytics.prototype._invoke = function(
796
807
return this ;
797
808
798
809
function applyIntegrationMiddlewares ( facade ) {
799
- var failedInitializations = self . failedInitializations || [ ] ;
800
- each ( function ( integration , name ) {
801
- var facadeCopy = extend ( true , new Facade ( { } ) , facade ) ;
810
+ let failedInitializations = self . failedInitializations || [ ] ;
811
+ Object . keys ( self . _integrations ) . forEach ( key => {
812
+ const integration = self . _integrations [ key ]
813
+ const { name } = integration
814
+ const facadeCopy = extend ( true , new Facade ( { } ) , facade ) ;
802
815
803
816
if ( ! facadeCopy . enabled ( name ) ) return ;
804
817
// Check if an integration failed to initialize.
@@ -882,7 +895,7 @@ Analytics.prototype._invoke = function(
882
895
) ;
883
896
}
884
897
}
885
- } , self . _integrations ) ;
898
+ } ) ;
886
899
}
887
900
} ;
888
901
@@ -957,7 +970,7 @@ Analytics.prototype.normalize = function(msg: {
957
970
context : { page } ;
958
971
anonymousId : string ;
959
972
} ) : object {
960
- msg = normalize ( msg , keys ( this . _integrations ) ) ;
973
+ msg = normalize ( msg , Object . keys ( this . _integrations ) ) ;
961
974
if ( msg . anonymousId ) user . anonymousId ( msg . anonymousId ) ;
962
975
msg . anonymousId = user . anonymousId ( ) ;
963
976
0 commit comments