@usermaven/sdk-js 1.0.9 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -2
- package/dist/npm/usermaven.cjs.js +422 -1812
- package/dist/npm/usermaven.d.ts +61 -40
- package/dist/npm/usermaven.es.js +422 -1812
- package/dist/web/lib.js +1 -1
- package/package.json +1 -1
|
@@ -174,25 +174,24 @@ function createLogger(logLevel) {
|
|
|
174
174
|
* Checks if global variable 'window' is available. If it's available,
|
|
175
175
|
* code runs in browser environment
|
|
176
176
|
*/
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
177
|
+
function isWindowAvailable(warnMsg) {
|
|
178
|
+
if (warnMsg === void 0) { warnMsg = undefined; }
|
|
179
|
+
var windowAvailable = !!globalThis.window;
|
|
180
|
+
if (!windowAvailable && warnMsg) {
|
|
181
|
+
getLogger().warn(warnMsg);
|
|
182
|
+
}
|
|
183
|
+
return windowAvailable;
|
|
184
184
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
185
|
/**
|
|
188
186
|
* @param msg
|
|
189
187
|
* @return {Window}
|
|
190
188
|
*/
|
|
191
|
-
function requireWindow(msg
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
189
|
+
function requireWindow(msg) {
|
|
190
|
+
if (msg === void 0) { msg = undefined; }
|
|
191
|
+
if (!isWindowAvailable()) {
|
|
192
|
+
throw new Error(msg || "window' is not available. Seems like this code runs outside browser environment. It shouldn't happen");
|
|
193
|
+
}
|
|
194
|
+
return window;
|
|
196
195
|
}
|
|
197
196
|
|
|
198
197
|
function serializeCookie(name, val, opt) {
|
|
@@ -467,1500 +466,239 @@ var LocalStorageQueue = /** @class */ (function () {
|
|
|
467
466
|
return LocalStorageQueue;
|
|
468
467
|
}());
|
|
469
468
|
|
|
470
|
-
var
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
navigator$1 = win.navigator || { userAgent: '' },
|
|
490
|
-
document$1 = win.document || {},
|
|
491
|
-
userAgent = navigator$1.userAgent;
|
|
492
|
-
|
|
493
|
-
const nativeBind = FuncProto.bind,
|
|
494
|
-
nativeForEach = ArrayProto.forEach,
|
|
495
|
-
nativeIndexOf = ArrayProto.indexOf,
|
|
496
|
-
nativeIsArray = Array.isArray,
|
|
497
|
-
breaker = {};
|
|
498
|
-
|
|
499
|
-
var _ = {
|
|
500
|
-
trim: function (str) {
|
|
501
|
-
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim#Polyfill
|
|
502
|
-
return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '')
|
|
503
|
-
},
|
|
504
|
-
};
|
|
505
|
-
|
|
506
|
-
// Console override
|
|
507
|
-
var console$1 = {
|
|
508
|
-
/** @type {function(...*)} */
|
|
509
|
-
log: function () {
|
|
510
|
-
},
|
|
511
|
-
/** @type {function(...*)} */
|
|
512
|
-
error: function () {
|
|
513
|
-
},
|
|
514
|
-
/** @type {function(...*)} */
|
|
515
|
-
critical: function () {
|
|
516
|
-
if (!_.isUndefined(window.console) && window.console) {
|
|
517
|
-
var args = ['UserMaven error:', ...arguments];
|
|
518
|
-
try {
|
|
519
|
-
window.console.error.apply(window.console, args);
|
|
520
|
-
} catch (err) {
|
|
521
|
-
_.each(args, function (arg) {
|
|
522
|
-
window.console.error(arg);
|
|
523
|
-
});
|
|
469
|
+
var ObjProto = Object.prototype;
|
|
470
|
+
var toString = ObjProto.toString;
|
|
471
|
+
var hasOwnProperty = ObjProto.hasOwnProperty;
|
|
472
|
+
var ArrayProto = Array.prototype;
|
|
473
|
+
var nativeForEach = ArrayProto.forEach, nativeIsArray = Array.isArray, breaker = {};
|
|
474
|
+
var _isArray = nativeIsArray ||
|
|
475
|
+
function (obj) {
|
|
476
|
+
return toString.call(obj) === '[object Array]';
|
|
477
|
+
};
|
|
478
|
+
function _eachArray(obj, iterator, thisArg) {
|
|
479
|
+
if (Array.isArray(obj)) {
|
|
480
|
+
if (nativeForEach && obj.forEach === nativeForEach) {
|
|
481
|
+
obj.forEach(iterator, thisArg);
|
|
482
|
+
}
|
|
483
|
+
else if ('length' in obj && obj.length === +obj.length) {
|
|
484
|
+
for (var i = 0, l = obj.length; i < l; i++) {
|
|
485
|
+
if (i in obj && iterator.call(thisArg, obj[i], i) === breaker) {
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
524
488
|
}
|
|
525
489
|
}
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
// UNDERSCORE
|
|
490
|
+
}
|
|
491
|
+
}
|
|
530
492
|
// Embed part of the Underscore Library
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
if (nativeBind && func.bind === nativeBind) {
|
|
534
|
-
return nativeBind.apply(func, slice.call(arguments, 1))
|
|
535
|
-
}
|
|
536
|
-
if (!_.isFunction(func)) {
|
|
537
|
-
throw new TypeError()
|
|
538
|
-
}
|
|
539
|
-
args = slice.call(arguments, 2);
|
|
540
|
-
bound = function () {
|
|
541
|
-
if (!(this instanceof bound)) {
|
|
542
|
-
return func.apply(context, args.concat(slice.call(arguments)))
|
|
543
|
-
}
|
|
544
|
-
var ctor = {};
|
|
545
|
-
ctor.prototype = func.prototype;
|
|
546
|
-
var self = new ctor();
|
|
547
|
-
ctor.prototype = null;
|
|
548
|
-
var result = func.apply(self, args.concat(slice.call(arguments)));
|
|
549
|
-
if (Object(result) === result) {
|
|
550
|
-
return result
|
|
551
|
-
}
|
|
552
|
-
return self
|
|
553
|
-
};
|
|
554
|
-
return bound
|
|
493
|
+
var _trim = function (str) {
|
|
494
|
+
return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
|
|
555
495
|
};
|
|
556
|
-
|
|
557
|
-
_.bind_instance_methods = function (obj) {
|
|
496
|
+
var _bind_instance_methods = function (obj) {
|
|
558
497
|
for (var func in obj) {
|
|
559
498
|
if (typeof obj[func] === 'function') {
|
|
560
|
-
obj[func] =
|
|
499
|
+
obj[func] = obj[func].bind(obj);
|
|
561
500
|
}
|
|
562
501
|
}
|
|
563
502
|
};
|
|
564
|
-
|
|
565
503
|
/**
|
|
566
504
|
* @param {*=} obj
|
|
567
505
|
* @param {function(...*)=} iterator
|
|
568
|
-
* @param {Object=}
|
|
506
|
+
* @param {Object=} thisArg
|
|
569
507
|
*/
|
|
570
|
-
|
|
508
|
+
function _each(obj, iterator, thisArg) {
|
|
571
509
|
if (obj === null || obj === undefined) {
|
|
572
|
-
return
|
|
510
|
+
return;
|
|
573
511
|
}
|
|
574
|
-
if (nativeForEach && obj.forEach === nativeForEach) {
|
|
575
|
-
obj.forEach(iterator,
|
|
576
|
-
} else if (obj.length === +obj.length) {
|
|
577
|
-
for (var i = 0, l = obj.length; i < l; i++) {
|
|
578
|
-
if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) {
|
|
579
|
-
return
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
} else {
|
|
583
|
-
for (var key in obj) {
|
|
584
|
-
if (hasOwnProperty.call(obj, key)) {
|
|
585
|
-
if (iterator.call(context, obj[key], key, obj) === breaker) {
|
|
586
|
-
return
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
}
|
|
512
|
+
if (nativeForEach && Array.isArray(obj) && obj.forEach === nativeForEach) {
|
|
513
|
+
obj.forEach(iterator, thisArg);
|
|
590
514
|
}
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
for (var prop in source) {
|
|
596
|
-
if (source[prop] !== void 0) {
|
|
597
|
-
obj[prop] = source[prop];
|
|
515
|
+
else if ('length' in obj && obj.length === +obj.length) {
|
|
516
|
+
for (var i = 0, l = obj.length; i < l; i++) {
|
|
517
|
+
if (i in obj && iterator.call(thisArg, obj[i], i) === breaker) {
|
|
518
|
+
return;
|
|
598
519
|
}
|
|
599
520
|
}
|
|
600
|
-
});
|
|
601
|
-
return obj
|
|
602
|
-
};
|
|
603
|
-
|
|
604
|
-
_.isArray =
|
|
605
|
-
nativeIsArray ||
|
|
606
|
-
function (obj) {
|
|
607
|
-
return toString.call(obj) === '[object Array]'
|
|
608
|
-
};
|
|
609
|
-
|
|
610
|
-
// from a comment on http://dbj.org/dbj/?p=286
|
|
611
|
-
// fails on only one very rare and deliberate custom object:
|
|
612
|
-
// var bomb = { toString : undefined, valueOf: function(o) { return "function BOMBA!"; }};
|
|
613
|
-
_.isFunction = function (f) {
|
|
614
|
-
try {
|
|
615
|
-
return /^\s*\bfunction\b/.test(f)
|
|
616
|
-
} catch (x) {
|
|
617
|
-
return false
|
|
618
|
-
}
|
|
619
|
-
};
|
|
620
|
-
|
|
621
|
-
_.include = function (obj, target) {
|
|
622
|
-
var found = false;
|
|
623
|
-
if (obj === null) {
|
|
624
|
-
return found
|
|
625
|
-
}
|
|
626
|
-
if (nativeIndexOf && obj.indexOf === nativeIndexOf) {
|
|
627
|
-
return obj.indexOf(target) != -1
|
|
628
521
|
}
|
|
629
|
-
|
|
630
|
-
if (found || (found = value === target)) {
|
|
631
|
-
return breaker
|
|
632
|
-
}
|
|
633
|
-
});
|
|
634
|
-
return found
|
|
635
|
-
};
|
|
636
|
-
|
|
637
|
-
_.includes = function (str, needle) {
|
|
638
|
-
return str.indexOf(needle) !== -1
|
|
639
|
-
};
|
|
640
|
-
|
|
641
|
-
// Underscore Addons
|
|
642
|
-
_.isObject = function (obj) {
|
|
643
|
-
return obj === Object(obj) && !_.isArray(obj)
|
|
644
|
-
};
|
|
645
|
-
|
|
646
|
-
_.isEmptyObject = function (obj) {
|
|
647
|
-
if (_.isObject(obj)) {
|
|
522
|
+
else {
|
|
648
523
|
for (var key in obj) {
|
|
649
524
|
if (hasOwnProperty.call(obj, key)) {
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
}
|
|
653
|
-
return true
|
|
654
|
-
}
|
|
655
|
-
return false
|
|
656
|
-
};
|
|
657
|
-
|
|
658
|
-
_.isUndefined = function (obj) {
|
|
659
|
-
return obj === void 0
|
|
660
|
-
};
|
|
661
|
-
|
|
662
|
-
_.isString = function (obj) {
|
|
663
|
-
return toString.call(obj) == '[object String]'
|
|
664
|
-
};
|
|
665
|
-
|
|
666
|
-
_.isDate = function (obj) {
|
|
667
|
-
return toString.call(obj) == '[object Date]'
|
|
668
|
-
};
|
|
669
|
-
|
|
670
|
-
_.isNumber = function (obj) {
|
|
671
|
-
return toString.call(obj) == '[object Number]'
|
|
672
|
-
};
|
|
673
|
-
|
|
674
|
-
_.encodeDates = function (obj) {
|
|
675
|
-
_.each(obj, function (v, k) {
|
|
676
|
-
if (_.isDate(v)) {
|
|
677
|
-
obj[k] = _.formatDate(v);
|
|
678
|
-
} else if (_.isObject(v)) {
|
|
679
|
-
obj[k] = _.encodeDates(v); // recurse
|
|
680
|
-
}
|
|
681
|
-
});
|
|
682
|
-
return obj
|
|
683
|
-
};
|
|
684
|
-
|
|
685
|
-
_.timestamp = function () {
|
|
686
|
-
Date.now =
|
|
687
|
-
Date.now ||
|
|
688
|
-
function () {
|
|
689
|
-
return +new Date()
|
|
690
|
-
};
|
|
691
|
-
return Date.now()
|
|
692
|
-
};
|
|
693
|
-
|
|
694
|
-
_.formatDate = function (d) {
|
|
695
|
-
// YYYY-MM-DDTHH:MM:SS in UTC
|
|
696
|
-
function pad(n) {
|
|
697
|
-
return n < 10 ? '0' + n : n
|
|
698
|
-
}
|
|
699
|
-
return (
|
|
700
|
-
d.getUTCFullYear() +
|
|
701
|
-
'-' +
|
|
702
|
-
pad(d.getUTCMonth() + 1) +
|
|
703
|
-
'-' +
|
|
704
|
-
pad(d.getUTCDate()) +
|
|
705
|
-
'T' +
|
|
706
|
-
pad(d.getUTCHours()) +
|
|
707
|
-
':' +
|
|
708
|
-
pad(d.getUTCMinutes()) +
|
|
709
|
-
':' +
|
|
710
|
-
pad(d.getUTCSeconds())
|
|
711
|
-
)
|
|
712
|
-
};
|
|
713
|
-
|
|
714
|
-
_.safewrap = function (f) {
|
|
715
|
-
return function () {
|
|
716
|
-
try {
|
|
717
|
-
return f.apply(this, arguments)
|
|
718
|
-
} catch (e) {
|
|
719
|
-
console$1.critical('Implementation error. Please turn on debug and contact support@usermaven.com.');
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
};
|
|
723
|
-
|
|
724
|
-
_.safewrap_class = function (klass, functions) {
|
|
725
|
-
for (var i = 0; i < functions.length; i++) {
|
|
726
|
-
klass.prototype[functions[i]] = _.safewrap(klass.prototype[functions[i]]);
|
|
727
|
-
}
|
|
728
|
-
};
|
|
729
|
-
|
|
730
|
-
_.safewrap_instance_methods = function (obj) {
|
|
731
|
-
for (var func in obj) {
|
|
732
|
-
if (typeof obj[func] === 'function') {
|
|
733
|
-
obj[func] = _.safewrap(obj[func]);
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
};
|
|
737
|
-
|
|
738
|
-
_.strip_empty_properties = function (p) {
|
|
739
|
-
var ret = {};
|
|
740
|
-
_.each(p, function (v, k) {
|
|
741
|
-
if (_.isString(v) && v.length > 0) {
|
|
742
|
-
ret[k] = v;
|
|
743
|
-
}
|
|
744
|
-
});
|
|
745
|
-
return ret
|
|
746
|
-
};
|
|
747
|
-
|
|
748
|
-
// Deep copies an object.
|
|
749
|
-
// It handles cycles by replacing all references to them with `undefined`
|
|
750
|
-
// Also supports customizing native values
|
|
751
|
-
const COPY_IN_PROGRESS_ATTRIBUTE =
|
|
752
|
-
typeof Symbol !== 'undefined' ? Symbol('__deepCircularCopyInProgress__') : '__deepCircularCopyInProgress__';
|
|
753
|
-
|
|
754
|
-
function deepCircularCopy(value, customizer) {
|
|
755
|
-
if (value !== Object(value)) return customizer ? customizer(value) : value // primitive value
|
|
756
|
-
|
|
757
|
-
if (value[COPY_IN_PROGRESS_ATTRIBUTE]) return undefined
|
|
758
|
-
|
|
759
|
-
value[COPY_IN_PROGRESS_ATTRIBUTE] = true;
|
|
760
|
-
let result;
|
|
761
|
-
|
|
762
|
-
if (_.isArray(value)) {
|
|
763
|
-
result = [];
|
|
764
|
-
_.each(value, (it) => {
|
|
765
|
-
result.push(deepCircularCopy(it, customizer));
|
|
766
|
-
});
|
|
767
|
-
} else {
|
|
768
|
-
result = {};
|
|
769
|
-
_.each(value, (val, key) => {
|
|
770
|
-
if (key !== COPY_IN_PROGRESS_ATTRIBUTE) {
|
|
771
|
-
result[key] = deepCircularCopy(val, customizer);
|
|
772
|
-
}
|
|
773
|
-
});
|
|
774
|
-
}
|
|
775
|
-
delete value[COPY_IN_PROGRESS_ATTRIBUTE];
|
|
776
|
-
return result
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
_.copyAndTruncateStrings = (object, maxStringLength) =>
|
|
780
|
-
deepCircularCopy(
|
|
781
|
-
object,
|
|
782
|
-
(value) => {
|
|
783
|
-
if (typeof value === 'string' && maxStringLength !== null) {
|
|
784
|
-
value = value.slice(0, maxStringLength);
|
|
785
|
-
}
|
|
786
|
-
return value
|
|
787
|
-
});
|
|
788
|
-
|
|
789
|
-
_.base64Encode = function (data) {
|
|
790
|
-
var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
|
791
|
-
var o1,
|
|
792
|
-
o2,
|
|
793
|
-
o3,
|
|
794
|
-
h1,
|
|
795
|
-
h2,
|
|
796
|
-
h3,
|
|
797
|
-
h4,
|
|
798
|
-
bits,
|
|
799
|
-
i = 0,
|
|
800
|
-
ac = 0,
|
|
801
|
-
enc = '',
|
|
802
|
-
tmp_arr = [];
|
|
803
|
-
|
|
804
|
-
if (!data) {
|
|
805
|
-
return data
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
data = _.utf8Encode(data);
|
|
809
|
-
|
|
810
|
-
do {
|
|
811
|
-
// pack three octets into four hexets
|
|
812
|
-
o1 = data.charCodeAt(i++);
|
|
813
|
-
o2 = data.charCodeAt(i++);
|
|
814
|
-
o3 = data.charCodeAt(i++);
|
|
815
|
-
|
|
816
|
-
bits = (o1 << 16) | (o2 << 8) | o3;
|
|
817
|
-
|
|
818
|
-
h1 = (bits >> 18) & 0x3f;
|
|
819
|
-
h2 = (bits >> 12) & 0x3f;
|
|
820
|
-
h3 = (bits >> 6) & 0x3f;
|
|
821
|
-
h4 = bits & 0x3f;
|
|
822
|
-
|
|
823
|
-
// use hexets to index into b64, and append result to encoded string
|
|
824
|
-
tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
|
|
825
|
-
} while (i < data.length)
|
|
826
|
-
|
|
827
|
-
enc = tmp_arr.join('');
|
|
828
|
-
|
|
829
|
-
switch (data.length % 3) {
|
|
830
|
-
case 1:
|
|
831
|
-
enc = enc.slice(0, -2) + '==';
|
|
832
|
-
break
|
|
833
|
-
case 2:
|
|
834
|
-
enc = enc.slice(0, -1) + '=';
|
|
835
|
-
break
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
return enc
|
|
839
|
-
};
|
|
840
|
-
|
|
841
|
-
_.utf8Encode = function (string) {
|
|
842
|
-
string = (string + '').replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
843
|
-
|
|
844
|
-
var utftext = '',
|
|
845
|
-
start,
|
|
846
|
-
end;
|
|
847
|
-
var stringl = 0,
|
|
848
|
-
n;
|
|
849
|
-
|
|
850
|
-
start = end = 0;
|
|
851
|
-
stringl = string.length;
|
|
852
|
-
|
|
853
|
-
for (n = 0; n < stringl; n++) {
|
|
854
|
-
var c1 = string.charCodeAt(n);
|
|
855
|
-
var enc = null;
|
|
856
|
-
|
|
857
|
-
if (c1 < 128) {
|
|
858
|
-
end++;
|
|
859
|
-
} else if (c1 > 127 && c1 < 2048) {
|
|
860
|
-
enc = String.fromCharCode((c1 >> 6) | 192, (c1 & 63) | 128);
|
|
861
|
-
} else {
|
|
862
|
-
enc = String.fromCharCode((c1 >> 12) | 224, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128);
|
|
863
|
-
}
|
|
864
|
-
if (enc !== null) {
|
|
865
|
-
if (end > start) {
|
|
866
|
-
utftext += string.substring(start, end);
|
|
867
|
-
}
|
|
868
|
-
utftext += enc;
|
|
869
|
-
start = end = n + 1;
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
if (end > start) {
|
|
874
|
-
utftext += string.substring(start, string.length);
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
return utftext
|
|
878
|
-
};
|
|
879
|
-
|
|
880
|
-
_.UUID = (function () {
|
|
881
|
-
// Time/ticks information
|
|
882
|
-
// 1*new Date() is a cross browser version of Date.now()
|
|
883
|
-
var T = function () {
|
|
884
|
-
var d = 1 * new Date(),
|
|
885
|
-
i = 0;
|
|
886
|
-
|
|
887
|
-
// this while loop figures how many browser ticks go by
|
|
888
|
-
// before 1*new Date() returns a new number, ie the amount
|
|
889
|
-
// of ticks that go by per millisecond
|
|
890
|
-
while (d == 1 * new Date()) {
|
|
891
|
-
i++;
|
|
892
|
-
}
|
|
893
|
-
|
|
894
|
-
return d.toString(16) + i.toString(16)
|
|
895
|
-
};
|
|
896
|
-
|
|
897
|
-
// Math.Random entropy
|
|
898
|
-
var R = function () {
|
|
899
|
-
return Math.random().toString(16).replace('.', '')
|
|
900
|
-
};
|
|
901
|
-
|
|
902
|
-
// User agent entropy
|
|
903
|
-
// This function takes the user agent string, and then xors
|
|
904
|
-
// together each sequence of 8 bytes. This produces a final
|
|
905
|
-
// sequence of 8 bytes which it returns as hex.
|
|
906
|
-
var UA = function () {
|
|
907
|
-
var ua = userAgent,
|
|
908
|
-
i,
|
|
909
|
-
ch,
|
|
910
|
-
buffer = [],
|
|
911
|
-
ret = 0;
|
|
912
|
-
|
|
913
|
-
function xor(result, byte_array) {
|
|
914
|
-
var j,
|
|
915
|
-
tmp = 0;
|
|
916
|
-
for (j = 0; j < byte_array.length; j++) {
|
|
917
|
-
tmp |= buffer[j] << (j * 8);
|
|
918
|
-
}
|
|
919
|
-
return result ^ tmp
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
for (i = 0; i < ua.length; i++) {
|
|
923
|
-
ch = ua.charCodeAt(i);
|
|
924
|
-
buffer.unshift(ch & 0xff);
|
|
925
|
-
if (buffer.length >= 4) {
|
|
926
|
-
ret = xor(ret, buffer);
|
|
927
|
-
buffer = [];
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
|
-
|
|
931
|
-
if (buffer.length > 0) {
|
|
932
|
-
ret = xor(ret, buffer);
|
|
933
|
-
}
|
|
934
|
-
|
|
935
|
-
return ret.toString(16)
|
|
936
|
-
};
|
|
937
|
-
|
|
938
|
-
return function () {
|
|
939
|
-
var se = (window.screen.height * window.screen.width).toString(16);
|
|
940
|
-
return T() + '-' + R() + '-' + UA() + '-' + se + '-' + T()
|
|
941
|
-
}
|
|
942
|
-
})();
|
|
943
|
-
|
|
944
|
-
// _.isBlockedUA()
|
|
945
|
-
// This is to block various web spiders from executing our JS and
|
|
946
|
-
// sending false captureing data
|
|
947
|
-
_.isBlockedUA = function (ua) {
|
|
948
|
-
if (/(google web preview|baiduspider|yandexbot|bingbot|googlebot|yahoo! slurp)/i.test(ua)) {
|
|
949
|
-
return true
|
|
950
|
-
}
|
|
951
|
-
return false
|
|
952
|
-
};
|
|
953
|
-
|
|
954
|
-
/**
|
|
955
|
-
* @param {Object=} formdata
|
|
956
|
-
* @param {string=} arg_separator
|
|
957
|
-
*/
|
|
958
|
-
_.HTTPBuildQuery = function (formdata, arg_separator) {
|
|
959
|
-
var use_val,
|
|
960
|
-
use_key,
|
|
961
|
-
tph_arr = [];
|
|
962
|
-
|
|
963
|
-
if (_.isUndefined(arg_separator)) {
|
|
964
|
-
arg_separator = '&';
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
_.each(formdata, function (val, key) {
|
|
968
|
-
use_val = encodeURIComponent(val.toString());
|
|
969
|
-
use_key = encodeURIComponent(key);
|
|
970
|
-
tph_arr[tph_arr.length] = use_key + '=' + use_val;
|
|
971
|
-
});
|
|
972
|
-
|
|
973
|
-
return tph_arr.join(arg_separator)
|
|
974
|
-
};
|
|
975
|
-
|
|
976
|
-
_.getQueryParam = function (url, param) {
|
|
977
|
-
// Expects a raw URL
|
|
978
|
-
|
|
979
|
-
param = param.replace(/[[]/, '\\[').replace(/[\]]/, '\\]');
|
|
980
|
-
var regexS = '[\\?&]' + param + '=([^&#]*)',
|
|
981
|
-
regex = new RegExp(regexS),
|
|
982
|
-
results = regex.exec(url);
|
|
983
|
-
if (results === null || (results && typeof results[1] !== 'string' && results[1].length)) {
|
|
984
|
-
return ''
|
|
985
|
-
} else {
|
|
986
|
-
var result = results[1];
|
|
987
|
-
try {
|
|
988
|
-
result = decodeURIComponent(result);
|
|
989
|
-
} catch (err) {
|
|
990
|
-
}
|
|
991
|
-
return result.replace(/\+/g, ' ')
|
|
992
|
-
}
|
|
993
|
-
};
|
|
994
|
-
|
|
995
|
-
_.getHashParam = function (hash, param) {
|
|
996
|
-
var matches = hash.match(new RegExp(param + '=([^&]*)'));
|
|
997
|
-
return matches ? matches[1] : null
|
|
998
|
-
};
|
|
999
|
-
|
|
1000
|
-
_.register_event = (function () {
|
|
1001
|
-
// written by Dean Edwards, 2005
|
|
1002
|
-
// with input from Tino Zijdel - crisp@xs4all.nl
|
|
1003
|
-
// with input from Carl Sverre - mail@carlsverre.com
|
|
1004
|
-
// http://dean.edwards.name/weblog/2005/10/add-event/
|
|
1005
|
-
// https://gist.github.com/1930440
|
|
1006
|
-
|
|
1007
|
-
/**
|
|
1008
|
-
* @param {Object} element
|
|
1009
|
-
* @param {string} type
|
|
1010
|
-
* @param {function(...*)} handler
|
|
1011
|
-
* @param {boolean=} oldSchool
|
|
1012
|
-
* @param {boolean=} useCapture
|
|
1013
|
-
*/
|
|
1014
|
-
var register_event = function (element, type, handler, oldSchool, useCapture) {
|
|
1015
|
-
if (!element) {
|
|
1016
|
-
return
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
if (element.addEventListener && !oldSchool) {
|
|
1020
|
-
element.addEventListener(type, handler, !!useCapture);
|
|
1021
|
-
} else {
|
|
1022
|
-
var ontype = 'on' + type;
|
|
1023
|
-
var old_handler = element[ontype]; // can be undefined
|
|
1024
|
-
element[ontype] = makeHandler(element, handler, old_handler);
|
|
1025
|
-
}
|
|
1026
|
-
};
|
|
1027
|
-
|
|
1028
|
-
function makeHandler(element, new_handler, old_handlers) {
|
|
1029
|
-
var handler = function (event) {
|
|
1030
|
-
event = event || fixEvent(window.event);
|
|
1031
|
-
|
|
1032
|
-
// this basically happens in firefox whenever another script
|
|
1033
|
-
// overwrites the onload callback and doesn't pass the event
|
|
1034
|
-
// object to previously defined callbacks. All the browsers
|
|
1035
|
-
// that don't define window.event implement addEventListener
|
|
1036
|
-
// so the dom_loaded handler will still be fired as usual.
|
|
1037
|
-
if (!event) {
|
|
1038
|
-
return undefined
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
|
-
var ret = true;
|
|
1042
|
-
var old_result, new_result;
|
|
1043
|
-
|
|
1044
|
-
if (_.isFunction(old_handlers)) {
|
|
1045
|
-
old_result = old_handlers(event);
|
|
1046
|
-
}
|
|
1047
|
-
new_result = new_handler.call(element, event);
|
|
1048
|
-
|
|
1049
|
-
if (false === old_result || false === new_result) {
|
|
1050
|
-
ret = false;
|
|
1051
|
-
}
|
|
1052
|
-
|
|
1053
|
-
return ret
|
|
1054
|
-
};
|
|
1055
|
-
|
|
1056
|
-
return handler
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1059
|
-
function fixEvent(event) {
|
|
1060
|
-
if (event) {
|
|
1061
|
-
event.preventDefault = fixEvent.preventDefault;
|
|
1062
|
-
event.stopPropagation = fixEvent.stopPropagation;
|
|
1063
|
-
}
|
|
1064
|
-
return event
|
|
1065
|
-
}
|
|
1066
|
-
fixEvent.preventDefault = function () {
|
|
1067
|
-
this.returnValue = false;
|
|
1068
|
-
};
|
|
1069
|
-
fixEvent.stopPropagation = function () {
|
|
1070
|
-
this.cancelBubble = true;
|
|
1071
|
-
};
|
|
1072
|
-
|
|
1073
|
-
return register_event
|
|
1074
|
-
})();
|
|
1075
|
-
|
|
1076
|
-
_.info = {
|
|
1077
|
-
campaignParams: function () {
|
|
1078
|
-
var campaign_keywords = 'utm_source utm_medium utm_campaign utm_content utm_term gclid'.split(' '),
|
|
1079
|
-
kw = '',
|
|
1080
|
-
params = {};
|
|
1081
|
-
_.each(campaign_keywords, function (kwkey) {
|
|
1082
|
-
kw = _.getQueryParam(document$1.URL, kwkey);
|
|
1083
|
-
if (kw.length) {
|
|
1084
|
-
params[kwkey] = kw;
|
|
1085
|
-
}
|
|
1086
|
-
});
|
|
1087
|
-
|
|
1088
|
-
return params
|
|
1089
|
-
},
|
|
1090
|
-
|
|
1091
|
-
searchEngine: function (referrer) {
|
|
1092
|
-
if (referrer.search('https?://(.*)google.([^/?]*)') === 0) {
|
|
1093
|
-
return 'google'
|
|
1094
|
-
} else if (referrer.search('https?://(.*)bing.com') === 0) {
|
|
1095
|
-
return 'bing'
|
|
1096
|
-
} else if (referrer.search('https?://(.*)yahoo.com') === 0) {
|
|
1097
|
-
return 'yahoo'
|
|
1098
|
-
} else if (referrer.search('https?://(.*)duckduckgo.com') === 0) {
|
|
1099
|
-
return 'duckduckgo'
|
|
1100
|
-
} else {
|
|
1101
|
-
return null
|
|
1102
|
-
}
|
|
1103
|
-
},
|
|
1104
|
-
|
|
1105
|
-
searchInfo: function (referrer) {
|
|
1106
|
-
var search = _.info.searchEngine(referrer),
|
|
1107
|
-
param = search != 'yahoo' ? 'q' : 'p',
|
|
1108
|
-
ret = {};
|
|
1109
|
-
|
|
1110
|
-
if (search !== null) {
|
|
1111
|
-
ret['$search_engine'] = search;
|
|
1112
|
-
|
|
1113
|
-
var keyword = _.getQueryParam(referrer, param);
|
|
1114
|
-
if (keyword.length) {
|
|
1115
|
-
ret['um_keyword'] = keyword;
|
|
1116
|
-
}
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
|
-
return ret
|
|
1120
|
-
},
|
|
1121
|
-
|
|
1122
|
-
/**
|
|
1123
|
-
* This function detects which browser is running this script.
|
|
1124
|
-
* The order of the checks are important since many user agents
|
|
1125
|
-
* include key words used in later checks.
|
|
1126
|
-
*/
|
|
1127
|
-
browser: function (user_agent, vendor, opera) {
|
|
1128
|
-
vendor = vendor || ''; // vendor is undefined for at least IE9
|
|
1129
|
-
if (opera || _.includes(user_agent, ' OPR/')) {
|
|
1130
|
-
if (_.includes(user_agent, 'Mini')) {
|
|
1131
|
-
return 'Opera Mini'
|
|
1132
|
-
}
|
|
1133
|
-
return 'Opera'
|
|
1134
|
-
} else if (/(BlackBerry|PlayBook|BB10)/i.test(user_agent)) {
|
|
1135
|
-
return 'BlackBerry'
|
|
1136
|
-
} else if (_.includes(user_agent, 'IEMobile') || _.includes(user_agent, 'WPDesktop')) {
|
|
1137
|
-
return 'Internet Explorer Mobile'
|
|
1138
|
-
} else if (_.includes(user_agent, 'SamsungBrowser/')) {
|
|
1139
|
-
// https://developer.samsung.com/internet/user-agent-string-format
|
|
1140
|
-
return 'Samsung Internet'
|
|
1141
|
-
} else if (_.includes(user_agent, 'Edge') || _.includes(user_agent, 'Edg/')) {
|
|
1142
|
-
return 'Microsoft Edge'
|
|
1143
|
-
} else if (_.includes(user_agent, 'FBIOS')) {
|
|
1144
|
-
return 'Facebook Mobile'
|
|
1145
|
-
} else if (_.includes(user_agent, 'Chrome')) {
|
|
1146
|
-
return 'Chrome'
|
|
1147
|
-
} else if (_.includes(user_agent, 'CriOS')) {
|
|
1148
|
-
return 'Chrome iOS'
|
|
1149
|
-
} else if (_.includes(user_agent, 'UCWEB') || _.includes(user_agent, 'UCBrowser')) {
|
|
1150
|
-
return 'UC Browser'
|
|
1151
|
-
} else if (_.includes(user_agent, 'FxiOS')) {
|
|
1152
|
-
return 'Firefox iOS'
|
|
1153
|
-
} else if (_.includes(vendor, 'Apple')) {
|
|
1154
|
-
if (_.includes(user_agent, 'Mobile')) {
|
|
1155
|
-
return 'Mobile Safari'
|
|
1156
|
-
}
|
|
1157
|
-
return 'Safari'
|
|
1158
|
-
} else if (_.includes(user_agent, 'Android')) {
|
|
1159
|
-
return 'Android Mobile'
|
|
1160
|
-
} else if (_.includes(user_agent, 'Konqueror')) {
|
|
1161
|
-
return 'Konqueror'
|
|
1162
|
-
} else if (_.includes(user_agent, 'Firefox')) {
|
|
1163
|
-
return 'Firefox'
|
|
1164
|
-
} else if (_.includes(user_agent, 'MSIE') || _.includes(user_agent, 'Trident/')) {
|
|
1165
|
-
return 'Internet Explorer'
|
|
1166
|
-
} else if (_.includes(user_agent, 'Gecko')) {
|
|
1167
|
-
return 'Mozilla'
|
|
1168
|
-
} else {
|
|
1169
|
-
return ''
|
|
1170
|
-
}
|
|
1171
|
-
},
|
|
1172
|
-
|
|
1173
|
-
/**
|
|
1174
|
-
* This function detects which browser version is running this script,
|
|
1175
|
-
* parsing major and minor version (e.g., 42.1). User agent strings from:
|
|
1176
|
-
* http://www.useragentstring.com/pages/useragentstring.php
|
|
1177
|
-
*/
|
|
1178
|
-
browserVersion: function (userAgent, vendor, opera) {
|
|
1179
|
-
var browser = _.info.browser(userAgent, vendor, opera);
|
|
1180
|
-
var versionRegexs = {
|
|
1181
|
-
'Internet Explorer Mobile': /rv:(\d+(\.\d+)?)/,
|
|
1182
|
-
'Microsoft Edge': /Edge?\/(\d+(\.\d+)?)/,
|
|
1183
|
-
Chrome: /Chrome\/(\d+(\.\d+)?)/,
|
|
1184
|
-
'Chrome iOS': /CriOS\/(\d+(\.\d+)?)/,
|
|
1185
|
-
'UC Browser': /(UCBrowser|UCWEB)\/(\d+(\.\d+)?)/,
|
|
1186
|
-
Safari: /Version\/(\d+(\.\d+)?)/,
|
|
1187
|
-
'Mobile Safari': /Version\/(\d+(\.\d+)?)/,
|
|
1188
|
-
Opera: /(Opera|OPR)\/(\d+(\.\d+)?)/,
|
|
1189
|
-
Firefox: /Firefox\/(\d+(\.\d+)?)/,
|
|
1190
|
-
'Firefox iOS': /FxiOS\/(\d+(\.\d+)?)/,
|
|
1191
|
-
Konqueror: /Konqueror:(\d+(\.\d+)?)/,
|
|
1192
|
-
BlackBerry: /BlackBerry (\d+(\.\d+)?)/,
|
|
1193
|
-
'Android Mobile': /android\s(\d+(\.\d+)?)/,
|
|
1194
|
-
'Samsung Internet': /SamsungBrowser\/(\d+(\.\d+)?)/,
|
|
1195
|
-
'Internet Explorer': /(rv:|MSIE )(\d+(\.\d+)?)/,
|
|
1196
|
-
Mozilla: /rv:(\d+(\.\d+)?)/,
|
|
1197
|
-
};
|
|
1198
|
-
var regex = versionRegexs[browser];
|
|
1199
|
-
if (regex === undefined) {
|
|
1200
|
-
return null
|
|
1201
|
-
}
|
|
1202
|
-
var matches = userAgent.match(regex);
|
|
1203
|
-
if (!matches) {
|
|
1204
|
-
return null
|
|
1205
|
-
}
|
|
1206
|
-
return parseFloat(matches[matches.length - 2])
|
|
1207
|
-
},
|
|
1208
|
-
|
|
1209
|
-
os: function () {
|
|
1210
|
-
var a = userAgent;
|
|
1211
|
-
if (/Windows/i.test(a)) {
|
|
1212
|
-
if (/Phone/.test(a) || /WPDesktop/.test(a)) {
|
|
1213
|
-
return 'Windows Phone'
|
|
1214
|
-
}
|
|
1215
|
-
return 'Windows'
|
|
1216
|
-
} else if (/(iPhone|iPad|iPod)/.test(a)) {
|
|
1217
|
-
return 'iOS'
|
|
1218
|
-
} else if (/Android/.test(a)) {
|
|
1219
|
-
return 'Android'
|
|
1220
|
-
} else if (/(BlackBerry|PlayBook|BB10)/i.test(a)) {
|
|
1221
|
-
return 'BlackBerry'
|
|
1222
|
-
} else if (/Mac/i.test(a)) {
|
|
1223
|
-
return 'Mac OS X'
|
|
1224
|
-
} else if (/Linux/.test(a)) {
|
|
1225
|
-
return 'Linux'
|
|
1226
|
-
} else if (/CrOS/.test(a)) {
|
|
1227
|
-
return 'Chrome OS'
|
|
1228
|
-
} else {
|
|
1229
|
-
return ''
|
|
1230
|
-
}
|
|
1231
|
-
},
|
|
1232
|
-
|
|
1233
|
-
device: function (user_agent) {
|
|
1234
|
-
if (/Windows Phone/i.test(user_agent) || /WPDesktop/.test(user_agent)) {
|
|
1235
|
-
return 'Windows Phone'
|
|
1236
|
-
} else if (/iPad/.test(user_agent)) {
|
|
1237
|
-
return 'iPad'
|
|
1238
|
-
} else if (/iPod/.test(user_agent)) {
|
|
1239
|
-
return 'iPod Touch'
|
|
1240
|
-
} else if (/iPhone/.test(user_agent)) {
|
|
1241
|
-
return 'iPhone'
|
|
1242
|
-
} else if (/(BlackBerry|PlayBook|BB10)/i.test(user_agent)) {
|
|
1243
|
-
return 'BlackBerry'
|
|
1244
|
-
} else if (/Android/.test(user_agent) && !/Mobile/.test(user_agent)) {
|
|
1245
|
-
return 'Android Tablet'
|
|
1246
|
-
} else if (/Android/.test(user_agent)) {
|
|
1247
|
-
return 'Android'
|
|
1248
|
-
} else {
|
|
1249
|
-
return ''
|
|
1250
|
-
}
|
|
1251
|
-
},
|
|
1252
|
-
|
|
1253
|
-
deviceType: function (user_agent) {
|
|
1254
|
-
const device = this.device(user_agent);
|
|
1255
|
-
if (device === 'iPad' || device === 'Android Tablet') {
|
|
1256
|
-
return 'Tablet'
|
|
1257
|
-
} else if (device) {
|
|
1258
|
-
return 'Mobile'
|
|
1259
|
-
} else {
|
|
1260
|
-
return 'Desktop'
|
|
1261
|
-
}
|
|
1262
|
-
},
|
|
1263
|
-
|
|
1264
|
-
referringDomain: function (referrer) {
|
|
1265
|
-
var split = referrer.split('/');
|
|
1266
|
-
if (split.length >= 3) {
|
|
1267
|
-
return split[2]
|
|
1268
|
-
}
|
|
1269
|
-
return ''
|
|
1270
|
-
},
|
|
1271
|
-
|
|
1272
|
-
properties: function () {
|
|
1273
|
-
return _.extend(
|
|
1274
|
-
_.strip_empty_properties({
|
|
1275
|
-
$os: _.info.os(),
|
|
1276
|
-
$browser: _.info.browser(userAgent, navigator$1.vendor, window.opera),
|
|
1277
|
-
$device: _.info.device(userAgent),
|
|
1278
|
-
$device_type: _.info.deviceType(userAgent),
|
|
1279
|
-
}),
|
|
1280
|
-
{
|
|
1281
|
-
$current_url: window.location.href,
|
|
1282
|
-
$host: window.location.host,
|
|
1283
|
-
$pathname: window.location.pathname,
|
|
1284
|
-
$browser_version: _.info.browserVersion(userAgent, navigator$1.vendor, window.opera),
|
|
1285
|
-
$screen_height: window.screen.height,
|
|
1286
|
-
$screen_width: window.screen.width,
|
|
1287
|
-
$viewport_height: window.innerHeight,
|
|
1288
|
-
$viewport_width: window.innerWidth,
|
|
1289
|
-
$lib: 'web',
|
|
1290
|
-
$lib_version: Config$1.LIB_VERSION,
|
|
1291
|
-
$insert_id: Math.random().toString(36).substring(2, 10) + Math.random().toString(36).substring(2, 10),
|
|
1292
|
-
$time: _.timestamp() / 1000, // epoch time in seconds
|
|
1293
|
-
}
|
|
1294
|
-
)
|
|
1295
|
-
},
|
|
1296
|
-
|
|
1297
|
-
people_properties: function () {
|
|
1298
|
-
return _.extend(
|
|
1299
|
-
_.strip_empty_properties({
|
|
1300
|
-
$os: _.info.os(),
|
|
1301
|
-
$browser: _.info.browser(userAgent, navigator$1.vendor, window.opera),
|
|
1302
|
-
}),
|
|
1303
|
-
{
|
|
1304
|
-
$browser_version: _.info.browserVersion(userAgent, navigator$1.vendor, window.opera),
|
|
1305
|
-
}
|
|
1306
|
-
)
|
|
1307
|
-
},
|
|
1308
|
-
};
|
|
1309
|
-
|
|
1310
|
-
// EXPORTS (for closure compiler)
|
|
1311
|
-
_['isObject'] = _.isObject;
|
|
1312
|
-
_['isBlockedUA'] = _.isBlockedUA;
|
|
1313
|
-
_['isEmptyObject'] = _.isEmptyObject;
|
|
1314
|
-
_['info'] = _.info;
|
|
1315
|
-
_['info']['device'] = _.info.device;
|
|
1316
|
-
_['info']['browser'] = _.info.browser;
|
|
1317
|
-
_['info']['browserVersion'] = _.info.browserVersion;
|
|
1318
|
-
_['info']['properties'] = _.info.properties;
|
|
1319
|
-
|
|
1320
|
-
var DOMAIN_MATCH_REGEX = /[a-z0-9][a-z0-9-]+\.[a-z.]{2,6}$/i;
|
|
1321
|
-
|
|
1322
|
-
// Methods partially borrowed from quirksmode.org/js/cookies.html
|
|
1323
|
-
const cookieStore = {
|
|
1324
|
-
get: function (name) {
|
|
1325
|
-
try {
|
|
1326
|
-
var nameEQ = name + '=';
|
|
1327
|
-
var ca = document.cookie.split(';');
|
|
1328
|
-
for (var i = 0; i < ca.length; i++) {
|
|
1329
|
-
var c = ca[i];
|
|
1330
|
-
while (c.charAt(0) == ' ') {
|
|
1331
|
-
c = c.substring(1, c.length);
|
|
1332
|
-
}
|
|
1333
|
-
if (c.indexOf(nameEQ) === 0) {
|
|
1334
|
-
return decodeURIComponent(c.substring(nameEQ.length, c.length))
|
|
1335
|
-
}
|
|
1336
|
-
}
|
|
1337
|
-
} catch (err) {}
|
|
1338
|
-
return null
|
|
1339
|
-
},
|
|
1340
|
-
|
|
1341
|
-
parse: function (name) {
|
|
1342
|
-
var cookie;
|
|
1343
|
-
try {
|
|
1344
|
-
cookie = JSON.parse(cookieStore.get(name)) || {};
|
|
1345
|
-
} catch (err) {
|
|
1346
|
-
// noop
|
|
1347
|
-
}
|
|
1348
|
-
return cookie
|
|
1349
|
-
},
|
|
1350
|
-
|
|
1351
|
-
set: function (name, value, days, cross_subdomain, is_secure) {
|
|
1352
|
-
try {
|
|
1353
|
-
var cdomain = '',
|
|
1354
|
-
expires = '',
|
|
1355
|
-
secure = '';
|
|
1356
|
-
|
|
1357
|
-
if (cross_subdomain) {
|
|
1358
|
-
var matches = document.location.hostname.match(DOMAIN_MATCH_REGEX),
|
|
1359
|
-
domain = matches ? matches[0] : '';
|
|
1360
|
-
|
|
1361
|
-
cdomain = domain ? '; domain=.' + domain : '';
|
|
1362
|
-
}
|
|
1363
|
-
|
|
1364
|
-
if (days) {
|
|
1365
|
-
var date = new Date();
|
|
1366
|
-
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
|
|
1367
|
-
expires = '; expires=' + date.toGMTString();
|
|
1368
|
-
}
|
|
1369
|
-
|
|
1370
|
-
if (is_secure) {
|
|
1371
|
-
secure = '; secure';
|
|
1372
|
-
}
|
|
1373
|
-
|
|
1374
|
-
var new_cookie_val =
|
|
1375
|
-
name + '=' + encodeURIComponent(JSON.stringify(value)) + expires + '; path=/' + cdomain + secure;
|
|
1376
|
-
document.cookie = new_cookie_val;
|
|
1377
|
-
return new_cookie_val
|
|
1378
|
-
} catch (err) {
|
|
1379
|
-
return
|
|
1380
|
-
}
|
|
1381
|
-
},
|
|
1382
|
-
|
|
1383
|
-
remove: function (name, cross_subdomain) {
|
|
1384
|
-
try {
|
|
1385
|
-
cookieStore.set(name, '', -1, cross_subdomain);
|
|
1386
|
-
} catch (err) {
|
|
1387
|
-
return
|
|
1388
|
-
}
|
|
1389
|
-
},
|
|
1390
|
-
};
|
|
1391
|
-
|
|
1392
|
-
var _localStorage_supported = null;
|
|
1393
|
-
const localStore = {
|
|
1394
|
-
is_supported: function () {
|
|
1395
|
-
if (_localStorage_supported !== null) {
|
|
1396
|
-
return _localStorage_supported
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
|
-
var supported = true;
|
|
1400
|
-
if (window) {
|
|
1401
|
-
try {
|
|
1402
|
-
var key = '__mplssupport__',
|
|
1403
|
-
val = 'xyz';
|
|
1404
|
-
localStore.set(key, val);
|
|
1405
|
-
if (localStore.get(key) !== '"xyz"') {
|
|
1406
|
-
supported = false;
|
|
1407
|
-
}
|
|
1408
|
-
localStore.remove(key);
|
|
1409
|
-
} catch (err) {
|
|
1410
|
-
supported = false;
|
|
1411
|
-
}
|
|
1412
|
-
} else {
|
|
1413
|
-
supported = false;
|
|
1414
|
-
}
|
|
1415
|
-
|
|
1416
|
-
_localStorage_supported = supported;
|
|
1417
|
-
return supported
|
|
1418
|
-
},
|
|
1419
|
-
|
|
1420
|
-
error: function (msg) {
|
|
1421
|
-
},
|
|
1422
|
-
|
|
1423
|
-
get: function (name) {
|
|
1424
|
-
try {
|
|
1425
|
-
return window.localStorage.getItem(name)
|
|
1426
|
-
} catch (err) {
|
|
1427
|
-
localStore.error(err);
|
|
1428
|
-
}
|
|
1429
|
-
return null
|
|
1430
|
-
},
|
|
1431
|
-
|
|
1432
|
-
parse: function (name) {
|
|
1433
|
-
try {
|
|
1434
|
-
return JSON.parse(localStore.get(name)) || {}
|
|
1435
|
-
} catch (err) {
|
|
1436
|
-
// noop
|
|
1437
|
-
}
|
|
1438
|
-
return null
|
|
1439
|
-
},
|
|
1440
|
-
|
|
1441
|
-
set: function (name, value) {
|
|
1442
|
-
try {
|
|
1443
|
-
window.localStorage.setItem(name, JSON.stringify(value));
|
|
1444
|
-
} catch (err) {
|
|
1445
|
-
localStore.error(err);
|
|
1446
|
-
}
|
|
1447
|
-
},
|
|
1448
|
-
|
|
1449
|
-
remove: function (name) {
|
|
1450
|
-
try {
|
|
1451
|
-
window.localStorage.removeItem(name);
|
|
1452
|
-
} catch (err) {
|
|
1453
|
-
localStore.error(err);
|
|
1454
|
-
}
|
|
1455
|
-
},
|
|
1456
|
-
};
|
|
1457
|
-
|
|
1458
|
-
// Use localstorage for most data but still use cookie for distinct_id
|
|
1459
|
-
// This solves issues with cookies having too much data in them causing headers too large
|
|
1460
|
-
// Also makes sure we don't have to send a ton of data to the server
|
|
1461
|
-
const localPlusCookieStore = {
|
|
1462
|
-
...localStore,
|
|
1463
|
-
parse: function (name) {
|
|
1464
|
-
try {
|
|
1465
|
-
let extend = {};
|
|
1466
|
-
try {
|
|
1467
|
-
// See if there's a cookie stored with data.
|
|
1468
|
-
extend = cookieStore.parse(name) || {};
|
|
1469
|
-
if (extend['distinct_id']) {
|
|
1470
|
-
cookieStore.set(name, { distinct_id: extend['distinct_id'] });
|
|
1471
|
-
}
|
|
1472
|
-
} catch (err) {}
|
|
1473
|
-
const value = _.extend(extend, JSON.parse(localStore.get(name) || '{}'));
|
|
1474
|
-
localStore.set(name, value);
|
|
1475
|
-
return value
|
|
1476
|
-
} catch (err) {
|
|
1477
|
-
// noop
|
|
1478
|
-
}
|
|
1479
|
-
return null
|
|
1480
|
-
},
|
|
1481
|
-
|
|
1482
|
-
set: function (name, value) {
|
|
1483
|
-
try {
|
|
1484
|
-
localStore.set(name, value);
|
|
1485
|
-
if (value.distinct_id) {
|
|
1486
|
-
cookieStore.set(name, { distinct_id: value.distinct_id });
|
|
1487
|
-
}
|
|
1488
|
-
} catch (err) {
|
|
1489
|
-
localStore.error(err);
|
|
1490
|
-
}
|
|
1491
|
-
},
|
|
1492
|
-
|
|
1493
|
-
remove: function (name) {
|
|
1494
|
-
try {
|
|
1495
|
-
window.localStorage.removeItem(name);
|
|
1496
|
-
cookieStore.remove(name);
|
|
1497
|
-
} catch (err) {
|
|
1498
|
-
localStore.error(err);
|
|
1499
|
-
}
|
|
1500
|
-
},
|
|
1501
|
-
};
|
|
1502
|
-
|
|
1503
|
-
const memoryStorage = {};
|
|
1504
|
-
|
|
1505
|
-
// Storage that only lasts the length of the pageview if we don't want to use cookies
|
|
1506
|
-
const memoryStore = {
|
|
1507
|
-
is_supported: function () {
|
|
1508
|
-
return true
|
|
1509
|
-
},
|
|
1510
|
-
|
|
1511
|
-
error: function (msg) {
|
|
1512
|
-
},
|
|
1513
|
-
|
|
1514
|
-
parse: function (name) {
|
|
1515
|
-
return memoryStorage[name] || null
|
|
1516
|
-
},
|
|
1517
|
-
|
|
1518
|
-
set: function (name, value) {
|
|
1519
|
-
memoryStorage[name] = value;
|
|
1520
|
-
},
|
|
1521
|
-
|
|
1522
|
-
remove: function (name) {
|
|
1523
|
-
delete memoryStorage[name];
|
|
1524
|
-
},
|
|
1525
|
-
};
|
|
1526
|
-
|
|
1527
|
-
// Storage that only lasts the length of a tab/window. Survives page refreshes
|
|
1528
|
-
const sessionStore = {
|
|
1529
|
-
sessionStorageSupported: null,
|
|
1530
|
-
is_supported: function () {
|
|
1531
|
-
if (sessionStore.sessionStorageSupported !== null) {
|
|
1532
|
-
return sessionStore.sessionStorageSupported
|
|
1533
|
-
}
|
|
1534
|
-
sessionStore.sessionStorageSupported = true;
|
|
1535
|
-
if (window) {
|
|
1536
|
-
try {
|
|
1537
|
-
let key = '__support__',
|
|
1538
|
-
val = 'xyz';
|
|
1539
|
-
sessionStore.set(key, val);
|
|
1540
|
-
if (sessionStore.get(key) !== '"xyz"') {
|
|
1541
|
-
sessionStore.sessionStorageSupported = false;
|
|
525
|
+
if (iterator.call(thisArg, obj[key], key) === breaker) {
|
|
526
|
+
return;
|
|
1542
527
|
}
|
|
1543
|
-
sessionStore.remove(key);
|
|
1544
|
-
} catch (err) {
|
|
1545
|
-
sessionStore.sessionStorageSupported = false;
|
|
1546
528
|
}
|
|
1547
|
-
} else {
|
|
1548
|
-
sessionStore.sessionStorageSupported = false;
|
|
1549
|
-
}
|
|
1550
|
-
return sessionStore.sessionStorageSupported
|
|
1551
|
-
},
|
|
1552
|
-
error: function (msg) {
|
|
1553
|
-
if (Config.DEBUG) ;
|
|
1554
|
-
},
|
|
1555
|
-
|
|
1556
|
-
get: function (name) {
|
|
1557
|
-
try {
|
|
1558
|
-
return window.sessionStorage.getItem(name)
|
|
1559
|
-
} catch (err) {
|
|
1560
|
-
sessionStore.error(err);
|
|
1561
|
-
}
|
|
1562
|
-
return null
|
|
1563
|
-
},
|
|
1564
|
-
|
|
1565
|
-
parse: function (name) {
|
|
1566
|
-
try {
|
|
1567
|
-
return JSON.parse(sessionStore.get(name)) || null
|
|
1568
|
-
} catch (err) {
|
|
1569
|
-
// noop
|
|
1570
|
-
}
|
|
1571
|
-
return null
|
|
1572
|
-
},
|
|
1573
|
-
|
|
1574
|
-
set: function (name, value) {
|
|
1575
|
-
try {
|
|
1576
|
-
window.sessionStorage.setItem(name, JSON.stringify(value));
|
|
1577
|
-
} catch (err) {
|
|
1578
|
-
sessionStore.error(err);
|
|
1579
|
-
}
|
|
1580
|
-
},
|
|
1581
|
-
|
|
1582
|
-
remove: function (name) {
|
|
1583
|
-
try {
|
|
1584
|
-
window.sessionStorage.removeItem(name);
|
|
1585
|
-
} catch (err) {
|
|
1586
|
-
sessionStore.error(err);
|
|
1587
529
|
}
|
|
1588
|
-
},
|
|
1589
|
-
};
|
|
1590
|
-
|
|
1591
|
-
/* eslint camelcase: "off" */
|
|
1592
|
-
|
|
1593
|
-
/*
|
|
1594
|
-
* Constants
|
|
1595
|
-
*/
|
|
1596
|
-
/** @const */ var SET_QUEUE_KEY = '__mps';
|
|
1597
|
-
/** @const */ var SET_ONCE_QUEUE_KEY = '__mpso';
|
|
1598
|
-
/** @const */ var UNSET_QUEUE_KEY = '__mpus';
|
|
1599
|
-
/** @const */ var ADD_QUEUE_KEY = '__mpa';
|
|
1600
|
-
/** @const */ var APPEND_QUEUE_KEY = '__mpap';
|
|
1601
|
-
/** @const */ var REMOVE_QUEUE_KEY = '__mpr';
|
|
1602
|
-
/** @const */ var UNION_QUEUE_KEY = '__mpu';
|
|
1603
|
-
/** @const */ var CAMPAIGN_IDS_KEY = '__cmpns';
|
|
1604
|
-
/** @const */ var EVENT_TIMERS_KEY = '__timers';
|
|
1605
|
-
/** @const */ var SESSION_RECORDING_ENABLED = '$session_recording_enabled';
|
|
1606
|
-
/** @const */ var SESSION_ID = '$sesid';
|
|
1607
|
-
/** @const */ var ENABLED_FEATURE_FLAGS = '$enabled_feature_flags';
|
|
1608
|
-
/** @const */ var RESERVED_PROPERTIES = [
|
|
1609
|
-
SET_QUEUE_KEY,
|
|
1610
|
-
SET_ONCE_QUEUE_KEY,
|
|
1611
|
-
UNSET_QUEUE_KEY,
|
|
1612
|
-
ADD_QUEUE_KEY,
|
|
1613
|
-
APPEND_QUEUE_KEY,
|
|
1614
|
-
REMOVE_QUEUE_KEY,
|
|
1615
|
-
UNION_QUEUE_KEY,
|
|
1616
|
-
CAMPAIGN_IDS_KEY,
|
|
1617
|
-
EVENT_TIMERS_KEY,
|
|
1618
|
-
SESSION_RECORDING_ENABLED,
|
|
1619
|
-
SESSION_ID,
|
|
1620
|
-
ENABLED_FEATURE_FLAGS,
|
|
1621
|
-
];
|
|
1622
|
-
|
|
1623
|
-
/**
|
|
1624
|
-
* UserMaven Persistence Object
|
|
1625
|
-
* @constructor
|
|
1626
|
-
*/
|
|
1627
|
-
var UserMavenPersistence = function (config) {
|
|
1628
|
-
// clean chars that aren't accepted by the http spec for cookie values
|
|
1629
|
-
// https://datatracker.ietf.org/doc/html/rfc2616#section-2.2
|
|
1630
|
-
let token = '';
|
|
1631
|
-
|
|
1632
|
-
if (config['token']) {
|
|
1633
|
-
token = config['token'].replace(/\+/g, 'PL').replace(/\//g, 'SL').replace(/=/g, 'EQ');
|
|
1634
|
-
}
|
|
1635
|
-
|
|
1636
|
-
this['props'] = {};
|
|
1637
|
-
this.campaign_params_saved = false;
|
|
1638
|
-
|
|
1639
|
-
if (config['persistence_name']) {
|
|
1640
|
-
this.name = 'um_' + config['persistence_name'];
|
|
1641
|
-
} else {
|
|
1642
|
-
this.name = 'um_' + token + '_usermaven';
|
|
1643
|
-
}
|
|
1644
|
-
|
|
1645
|
-
var storage_type = config['persistence'];
|
|
1646
|
-
if (storage_type !== 'cookie' && storage_type.indexOf('localStorage') === -1 && storage_type !== 'memory') {
|
|
1647
|
-
console$1.critical('Unknown persistence type ' + storage_type + '; falling back to cookie');
|
|
1648
|
-
storage_type = config['persistence'] = 'cookie';
|
|
1649
|
-
}
|
|
1650
|
-
if (storage_type === 'localStorage' && localStore.is_supported()) {
|
|
1651
|
-
this.storage = localStore;
|
|
1652
|
-
} else if (storage_type === 'localStorage+cookie' && localPlusCookieStore.is_supported()) {
|
|
1653
|
-
this.storage = localPlusCookieStore;
|
|
1654
|
-
} else if (storage_type === 'memory') {
|
|
1655
|
-
this.storage = memoryStore;
|
|
1656
|
-
} else {
|
|
1657
|
-
this.storage = cookieStore;
|
|
1658
|
-
}
|
|
1659
|
-
|
|
1660
|
-
this.load();
|
|
1661
|
-
this.update_config(config);
|
|
1662
|
-
this.save();
|
|
1663
|
-
};
|
|
1664
|
-
|
|
1665
|
-
UserMavenPersistence.prototype.properties = function () {
|
|
1666
|
-
var p = {};
|
|
1667
|
-
// Filter out reserved properties
|
|
1668
|
-
_.each(this['props'], function (v, k) {
|
|
1669
|
-
if (k === ENABLED_FEATURE_FLAGS && typeof v === 'object') {
|
|
1670
|
-
var keys = Object.keys(v);
|
|
1671
|
-
for (var i = 0; i < keys.length; i++) {
|
|
1672
|
-
p[`$feature/${keys[i]}`] = v[keys[i]];
|
|
1673
|
-
}
|
|
1674
|
-
} else if (!_.include(RESERVED_PROPERTIES, k)) {
|
|
1675
|
-
p[k] = v;
|
|
1676
|
-
}
|
|
1677
|
-
});
|
|
1678
|
-
return p
|
|
1679
|
-
};
|
|
1680
|
-
|
|
1681
|
-
UserMavenPersistence.prototype.load = function () {
|
|
1682
|
-
if (this.disabled) {
|
|
1683
|
-
return
|
|
1684
|
-
}
|
|
1685
|
-
|
|
1686
|
-
var entry = this.storage.parse(this.name);
|
|
1687
|
-
|
|
1688
|
-
if (entry) {
|
|
1689
|
-
this['props'] = _.extend({}, entry);
|
|
1690
|
-
}
|
|
1691
|
-
};
|
|
1692
|
-
|
|
1693
|
-
UserMavenPersistence.prototype.save = function () {
|
|
1694
|
-
if (this.disabled) {
|
|
1695
|
-
return
|
|
1696
|
-
}
|
|
1697
|
-
this.storage.set(this.name, this['props'], this.expire_days, this.cross_subdomain, this.secure);
|
|
1698
|
-
};
|
|
1699
|
-
|
|
1700
|
-
UserMavenPersistence.prototype.remove = function () {
|
|
1701
|
-
// remove both domain and subdomain cookies
|
|
1702
|
-
this.storage.remove(this.name, false);
|
|
1703
|
-
this.storage.remove(this.name, true);
|
|
1704
|
-
};
|
|
1705
|
-
|
|
1706
|
-
// removes the storage entry and deletes all loaded data
|
|
1707
|
-
// forced name for tests
|
|
1708
|
-
UserMavenPersistence.prototype.clear = function () {
|
|
1709
|
-
this.remove();
|
|
1710
|
-
this['props'] = {};
|
|
1711
|
-
};
|
|
1712
|
-
|
|
1713
|
-
/**
|
|
1714
|
-
* @param {Object} props
|
|
1715
|
-
* @param {*=} default_value
|
|
1716
|
-
* @param {number=} days
|
|
1717
|
-
*/
|
|
1718
|
-
UserMavenPersistence.prototype.register_once = function (props, default_value, days) {
|
|
1719
|
-
if (_.isObject(props)) {
|
|
1720
|
-
if (typeof default_value === 'undefined') {
|
|
1721
|
-
default_value = 'None';
|
|
1722
|
-
}
|
|
1723
|
-
this.expire_days = typeof days === 'undefined' ? this.default_expiry : days;
|
|
1724
|
-
|
|
1725
|
-
_.each(
|
|
1726
|
-
props,
|
|
1727
|
-
function (val, prop) {
|
|
1728
|
-
if (!this['props'].hasOwnProperty(prop) || this['props'][prop] === default_value) {
|
|
1729
|
-
this['props'][prop] = val;
|
|
1730
|
-
}
|
|
1731
|
-
},
|
|
1732
|
-
this
|
|
1733
|
-
);
|
|
1734
|
-
|
|
1735
|
-
this.save();
|
|
1736
|
-
|
|
1737
|
-
return true
|
|
1738
530
|
}
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
* @param {number=} days
|
|
1745
|
-
*/
|
|
1746
|
-
UserMavenPersistence.prototype.register = function (props, days) {
|
|
1747
|
-
if (_.isObject(props)) {
|
|
1748
|
-
this.expire_days = typeof days === 'undefined' ? this.default_expiry : days;
|
|
1749
|
-
|
|
1750
|
-
_.extend(this['props'], props);
|
|
1751
|
-
|
|
1752
|
-
this.save();
|
|
1753
|
-
|
|
1754
|
-
return true
|
|
1755
|
-
}
|
|
1756
|
-
return false
|
|
1757
|
-
};
|
|
1758
|
-
|
|
1759
|
-
UserMavenPersistence.prototype.unregister = function (prop) {
|
|
1760
|
-
if (prop in this['props']) {
|
|
1761
|
-
delete this['props'][prop];
|
|
1762
|
-
this.save();
|
|
1763
|
-
}
|
|
1764
|
-
};
|
|
1765
|
-
|
|
1766
|
-
UserMavenPersistence.prototype.update_campaign_params = function () {
|
|
1767
|
-
if (!this.campaign_params_saved) {
|
|
1768
|
-
this.register(_.info.campaignParams());
|
|
1769
|
-
this.campaign_params_saved = true;
|
|
531
|
+
}
|
|
532
|
+
var _extend = function (obj) {
|
|
533
|
+
var args = [];
|
|
534
|
+
for (var _i = 1; _i < arguments.length; _i++) {
|
|
535
|
+
args[_i - 1] = arguments[_i];
|
|
1770
536
|
}
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
}
|
|
1776
|
-
|
|
1777
|
-
// EXPORTED METHOD, we test this directly.
|
|
1778
|
-
UserMavenPersistence.prototype.update_referrer_info = function (referrer) {
|
|
1779
|
-
// If referrer doesn't exist, we want to note the fact that it was type-in traffic.
|
|
1780
|
-
// Register once, so first touch
|
|
1781
|
-
this.register_once(
|
|
1782
|
-
{
|
|
1783
|
-
$initial_referrer: referrer || '$direct',
|
|
1784
|
-
$initial_referring_domain: _.info.referringDomain(referrer) || '$direct',
|
|
1785
|
-
},
|
|
1786
|
-
''
|
|
1787
|
-
);
|
|
1788
|
-
// Register the current referrer but override if it's different, hence register
|
|
1789
|
-
this.register({
|
|
1790
|
-
$referrer: referrer || this['props']['$referrer'] || '$direct',
|
|
1791
|
-
$referring_domain: _.info.referringDomain(referrer) || this['props']['$referring_domain'] || '$direct',
|
|
1792
|
-
});
|
|
1793
|
-
};
|
|
1794
|
-
|
|
1795
|
-
UserMavenPersistence.prototype.get_referrer_info = function () {
|
|
1796
|
-
return _.strip_empty_properties({
|
|
1797
|
-
$initial_referrer: this['props']['$initial_referrer'],
|
|
1798
|
-
$initial_referring_domain: this['props']['$initial_referring_domain'],
|
|
1799
|
-
})
|
|
1800
|
-
};
|
|
1801
|
-
|
|
1802
|
-
// safely fills the passed in object with stored properties,
|
|
1803
|
-
// does not override any properties defined in both
|
|
1804
|
-
// returns the passed in object
|
|
1805
|
-
UserMavenPersistence.prototype.safe_merge = function (props) {
|
|
1806
|
-
_.each(this['props'], function (val, prop) {
|
|
1807
|
-
if (!(prop in props)) {
|
|
1808
|
-
props[prop] = val;
|
|
537
|
+
_eachArray(args, function (source) {
|
|
538
|
+
for (var prop in source) {
|
|
539
|
+
if (source[prop] !== void 0) {
|
|
540
|
+
obj[prop] = source[prop];
|
|
541
|
+
}
|
|
1809
542
|
}
|
|
1810
543
|
});
|
|
1811
|
-
|
|
1812
|
-
return props
|
|
1813
|
-
};
|
|
1814
|
-
|
|
1815
|
-
UserMavenPersistence.prototype.update_config = function (config) {
|
|
1816
|
-
this.default_expiry = this.expire_days = config['cookie_expiration'];
|
|
1817
|
-
this.set_disabled(config['disable_persistence']);
|
|
1818
|
-
this.set_cross_subdomain(config['cross_subdomain_cookie']);
|
|
1819
|
-
this.set_secure(config['secure_cookie']);
|
|
1820
|
-
};
|
|
1821
|
-
|
|
1822
|
-
UserMavenPersistence.prototype.set_disabled = function (disabled) {
|
|
1823
|
-
this.disabled = disabled;
|
|
1824
|
-
if (this.disabled) {
|
|
1825
|
-
this.remove();
|
|
1826
|
-
} else {
|
|
1827
|
-
this.save();
|
|
1828
|
-
}
|
|
544
|
+
return obj;
|
|
1829
545
|
};
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
546
|
+
function _includes(str, needle) {
|
|
547
|
+
return str.indexOf(needle) !== -1;
|
|
548
|
+
}
|
|
549
|
+
// from a comment on http://dbj.org/dbj/?p=286
|
|
550
|
+
// fails on only one very rare and deliberate custom object:
|
|
551
|
+
// let bomb = { toString : undefined, valueOf: function(o) { return "function BOMBA!"; }};
|
|
552
|
+
var _isFunction = function (f) {
|
|
553
|
+
try {
|
|
554
|
+
return /^\s*\bfunction\b/.test(f);
|
|
1836
555
|
}
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
UserMavenPersistence.prototype.get_cross_subdomain = function () {
|
|
1840
|
-
return this.cross_subdomain
|
|
1841
|
-
};
|
|
1842
|
-
|
|
1843
|
-
UserMavenPersistence.prototype.set_secure = function (secure) {
|
|
1844
|
-
if (secure !== this.secure) {
|
|
1845
|
-
this.secure = secure ? true : false;
|
|
1846
|
-
this.remove();
|
|
1847
|
-
this.save();
|
|
556
|
+
catch (x) {
|
|
557
|
+
return false;
|
|
1848
558
|
}
|
|
1849
559
|
};
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
var timers = this['props'][EVENT_TIMERS_KEY] || {};
|
|
1853
|
-
timers[event_name] = timestamp;
|
|
1854
|
-
this['props'][EVENT_TIMERS_KEY] = timers;
|
|
1855
|
-
this.save();
|
|
1856
|
-
};
|
|
1857
|
-
|
|
1858
|
-
UserMavenPersistence.prototype.remove_event_timer = function (event_name) {
|
|
1859
|
-
var timers = this['props'][EVENT_TIMERS_KEY] || {};
|
|
1860
|
-
var timestamp = timers[event_name];
|
|
1861
|
-
if (!_.isUndefined(timestamp)) {
|
|
1862
|
-
delete this['props'][EVENT_TIMERS_KEY][event_name];
|
|
1863
|
-
this.save();
|
|
1864
|
-
}
|
|
1865
|
-
return timestamp
|
|
560
|
+
var _isUndefined = function (obj) {
|
|
561
|
+
return obj === void 0;
|
|
1866
562
|
};
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
563
|
+
var _register_event = (function () {
|
|
564
|
+
// written by Dean Edwards, 2005
|
|
565
|
+
// with input from Tino Zijdel - crisp@xs4all.nl
|
|
566
|
+
// with input from Carl Sverre - mail@carlsverre.com
|
|
567
|
+
// with input from PostHog
|
|
568
|
+
// http://dean.edwards.name/weblog/2005/10/add-event/
|
|
569
|
+
// https://gist.github.com/1930440
|
|
570
|
+
/**
|
|
571
|
+
* @param {Object} element
|
|
572
|
+
* @param {string} type
|
|
573
|
+
* @param {function(...*)} handler
|
|
574
|
+
* @param {boolean=} oldSchool
|
|
575
|
+
* @param {boolean=} useCapture
|
|
576
|
+
*/
|
|
577
|
+
var register_event = function (element, type, handler, oldSchool, useCapture) {
|
|
578
|
+
if (!element) {
|
|
579
|
+
getLogger().error('No valid element provided to register_event');
|
|
580
|
+
return;
|
|
1879
581
|
}
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
582
|
+
if (element.addEventListener && !oldSchool) {
|
|
583
|
+
element.addEventListener(type, handler, !!useCapture);
|
|
584
|
+
}
|
|
585
|
+
else {
|
|
586
|
+
var ontype = 'on' + type;
|
|
587
|
+
var old_handler = element[ontype] // can be undefined
|
|
588
|
+
;
|
|
589
|
+
element[ontype] = makeHandler(element, handler, old_handler);
|
|
590
|
+
}
|
|
591
|
+
};
|
|
592
|
+
function makeHandler(element, new_handler, old_handlers) {
|
|
593
|
+
return function (event) {
|
|
594
|
+
event = event || fixEvent(window.event);
|
|
595
|
+
// this basically happens in firefox whenever another script
|
|
596
|
+
// overwrites the onload callback and doesn't pass the event
|
|
597
|
+
// object to previously defined callbacks. All the browsers
|
|
598
|
+
// that don't define window.event implement addEventListener
|
|
599
|
+
// so the dom_loaded handler will still be fired as usual.
|
|
600
|
+
if (!event) {
|
|
601
|
+
return undefined;
|
|
602
|
+
}
|
|
603
|
+
var ret = true;
|
|
604
|
+
var old_result;
|
|
605
|
+
if (_isFunction(old_handlers)) {
|
|
606
|
+
old_result = old_handlers(event);
|
|
607
|
+
}
|
|
608
|
+
var new_result = new_handler.call(element, event);
|
|
609
|
+
if (false === old_result || false === new_result) {
|
|
610
|
+
ret = false;
|
|
1891
611
|
}
|
|
612
|
+
return ret;
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
function fixEvent(event) {
|
|
616
|
+
if (event) {
|
|
617
|
+
event.preventDefault = fixEvent.preventDefault;
|
|
618
|
+
event.stopPropagation = fixEvent.stopPropagation;
|
|
1892
619
|
}
|
|
620
|
+
return event;
|
|
1893
621
|
}
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
622
|
+
fixEvent.preventDefault = function () {
|
|
623
|
+
this.returnValue = false;
|
|
624
|
+
};
|
|
625
|
+
fixEvent.stopPropagation = function () {
|
|
626
|
+
this.cancelBubble = true;
|
|
627
|
+
};
|
|
628
|
+
return register_event;
|
|
629
|
+
})();
|
|
630
|
+
var _safewrap = function (f) {
|
|
631
|
+
return function () {
|
|
632
|
+
var args = [];
|
|
633
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
634
|
+
args[_i] = arguments[_i];
|
|
1898
635
|
}
|
|
1899
|
-
|
|
1900
|
-
|
|
636
|
+
try {
|
|
637
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
638
|
+
// @ts-ignore
|
|
639
|
+
return f.apply(this, args);
|
|
1901
640
|
}
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
_setSessionId(sessionId, timestamp) {
|
|
1908
|
-
if (sessionId !== this.sessionId || timestamp !== this.timestamp) {
|
|
1909
|
-
this.timestamp = timestamp;
|
|
1910
|
-
this.sessionId = sessionId;
|
|
1911
|
-
this.persistence.register({ [SESSION_ID]: [timestamp, sessionId] });
|
|
641
|
+
catch (e) {
|
|
642
|
+
getLogger().error('Implementation error. Please turn on debug and contact support@usermaven.com.', e);
|
|
643
|
+
// if (Config.DEBUG) {
|
|
644
|
+
// getLogger.critical(e)
|
|
645
|
+
// }
|
|
1912
646
|
}
|
|
1913
|
-
}
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
647
|
+
};
|
|
648
|
+
};
|
|
649
|
+
var _safewrap_instance_methods = function (obj) {
|
|
650
|
+
for (var func in obj) {
|
|
651
|
+
if (typeof obj[func] === 'function') {
|
|
652
|
+
obj[func] = _safewrap(obj[func]);
|
|
1918
653
|
}
|
|
1919
|
-
return this.persistence['props'][SESSION_ID] || [0, null]
|
|
1920
654
|
}
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
655
|
+
};
|
|
656
|
+
var COPY_IN_PROGRESS_ATTRIBUTE = typeof Symbol !== 'undefined' ? Symbol('__deepCircularCopyInProgress__') : '__deepCircularCopyInProgress__';
|
|
657
|
+
/**
|
|
658
|
+
* Deep copies an object.
|
|
659
|
+
* It handles cycles by replacing all references to them with `undefined`
|
|
660
|
+
* Also supports customizing native values
|
|
661
|
+
*
|
|
662
|
+
* @param value
|
|
663
|
+
* @param customizer
|
|
664
|
+
* @param [key] if provided this is the object key associated with the value to be copied. It allows the customizer function to have context when it runs
|
|
665
|
+
* @returns {{}|undefined|*}
|
|
666
|
+
*/
|
|
667
|
+
function deepCircularCopy(value, customizer, key) {
|
|
668
|
+
if (value !== Object(value))
|
|
669
|
+
return customizer ? customizer(value, key) : value; // primitive value
|
|
670
|
+
if (value[COPY_IN_PROGRESS_ATTRIBUTE])
|
|
671
|
+
return undefined;
|
|
672
|
+
value[COPY_IN_PROGRESS_ATTRIBUTE] = true;
|
|
673
|
+
var result;
|
|
674
|
+
if (_isArray(value)) {
|
|
675
|
+
result = [];
|
|
676
|
+
_eachArray(value, function (it) {
|
|
677
|
+
result.push(deepCircularCopy(it, customizer));
|
|
678
|
+
});
|
|
1926
679
|
}
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
timestamp = timestamp || new Date().getTime();
|
|
1944
|
-
|
|
1945
|
-
let [lastTimestamp, sessionId] = this._getSessionId();
|
|
1946
|
-
let windowId = this._getWindowId();
|
|
1947
|
-
|
|
1948
|
-
if (!sessionId || (Math.abs(timestamp - lastTimestamp) > this.session_change_threshold)) {
|
|
1949
|
-
sessionId = _.UUID();
|
|
1950
|
-
windowId = _.UUID();
|
|
1951
|
-
} else if (!windowId) {
|
|
1952
|
-
windowId = _.UUID();
|
|
680
|
+
else {
|
|
681
|
+
result = {};
|
|
682
|
+
_each(value, function (val, key) {
|
|
683
|
+
if (key !== COPY_IN_PROGRESS_ATTRIBUTE) {
|
|
684
|
+
result[key] = deepCircularCopy(val, customizer, key);
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
delete value[COPY_IN_PROGRESS_ATTRIBUTE];
|
|
689
|
+
return result;
|
|
690
|
+
}
|
|
691
|
+
var LONG_STRINGS_ALLOW_LIST = ['$performance_raw'];
|
|
692
|
+
function _copyAndTruncateStrings(object, maxStringLength) {
|
|
693
|
+
return deepCircularCopy(object, function (value, key) {
|
|
694
|
+
if (key && LONG_STRINGS_ALLOW_LIST.indexOf(key) > -1) {
|
|
695
|
+
return value;
|
|
1953
696
|
}
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
this._setWindowId(windowId);
|
|
1958
|
-
this._setSessionId(sessionId, newTimestamp);
|
|
1959
|
-
return {
|
|
1960
|
-
session_id: sessionId,
|
|
1961
|
-
window_id: windowId,
|
|
697
|
+
if (typeof value === 'string' && maxStringLength !== null) {
|
|
698
|
+
return value.slice(0, maxStringLength);
|
|
1962
699
|
}
|
|
1963
|
-
|
|
700
|
+
return value;
|
|
701
|
+
});
|
|
1964
702
|
}
|
|
1965
703
|
|
|
1966
704
|
/*
|
|
@@ -1971,15 +709,15 @@ class SessionIdManager {
|
|
|
1971
709
|
function getClassName(el) {
|
|
1972
710
|
switch (typeof el.className) {
|
|
1973
711
|
case 'string':
|
|
1974
|
-
return el.className
|
|
712
|
+
return el.className;
|
|
713
|
+
// TODO: when is this ever used?
|
|
1975
714
|
case 'object': // handle cases where className might be SVGAnimatedString or some other type
|
|
1976
|
-
return el.className.baseVal || el.getAttribute('class') || ''
|
|
715
|
+
return ('baseVal' in el.className ? el.className.baseVal : null) || el.getAttribute('class') || '';
|
|
1977
716
|
default:
|
|
1978
717
|
// future proof
|
|
1979
|
-
return ''
|
|
718
|
+
return '';
|
|
1980
719
|
}
|
|
1981
720
|
}
|
|
1982
|
-
|
|
1983
721
|
/*
|
|
1984
722
|
* Get the direct text content of an element, protecting against sensitive data collection.
|
|
1985
723
|
* Concats textContent of each of the element's text node children; this avoids potential
|
|
@@ -1991,11 +729,10 @@ function getClassName(el) {
|
|
|
1991
729
|
*/
|
|
1992
730
|
function getSafeText(el) {
|
|
1993
731
|
var elText = '';
|
|
1994
|
-
|
|
1995
732
|
if (shouldCaptureElement(el) && !isSensitiveElement(el) && el.childNodes && el.childNodes.length) {
|
|
1996
|
-
|
|
733
|
+
_each(el.childNodes, function (child) {
|
|
1997
734
|
if (isTextNode(child) && child.textContent) {
|
|
1998
|
-
elText +=
|
|
735
|
+
elText += _trim(child.textContent)
|
|
1999
736
|
// scrub potentially sensitive values
|
|
2000
737
|
.split(/(\s+)/)
|
|
2001
738
|
.filter(shouldCaptureValue)
|
|
@@ -2008,19 +745,16 @@ function getSafeText(el) {
|
|
|
2008
745
|
}
|
|
2009
746
|
});
|
|
2010
747
|
}
|
|
2011
|
-
|
|
2012
|
-
return _.trim(elText)
|
|
748
|
+
return _trim(elText);
|
|
2013
749
|
}
|
|
2014
|
-
|
|
2015
750
|
/*
|
|
2016
751
|
* Check whether an element has nodeType Node.ELEMENT_NODE
|
|
2017
752
|
* @param {Element} el - element to check
|
|
2018
753
|
* @returns {boolean} whether el is of the correct nodeType
|
|
2019
754
|
*/
|
|
2020
755
|
function isElementNode(el) {
|
|
2021
|
-
return el && el.nodeType === 1 // Node.ELEMENT_NODE - use integer constant for browser portability
|
|
756
|
+
return !!el && el.nodeType === 1; // Node.ELEMENT_NODE - use integer constant for browser portability
|
|
2022
757
|
}
|
|
2023
|
-
|
|
2024
758
|
/*
|
|
2025
759
|
* Check whether an element is of a given tag type.
|
|
2026
760
|
* Due to potential reference discrepancies (such as the webcomponents.js polyfill),
|
|
@@ -2032,18 +766,24 @@ function isElementNode(el) {
|
|
|
2032
766
|
* @returns {boolean} whether el is of the given tag type
|
|
2033
767
|
*/
|
|
2034
768
|
function isTag(el, tag) {
|
|
2035
|
-
return el && el.tagName && el.tagName.toLowerCase() === tag.toLowerCase()
|
|
769
|
+
return !!el && !!el.tagName && el.tagName.toLowerCase() === tag.toLowerCase();
|
|
2036
770
|
}
|
|
2037
|
-
|
|
2038
771
|
/*
|
|
2039
772
|
* Check whether an element has nodeType Node.TEXT_NODE
|
|
2040
773
|
* @param {Element} el - element to check
|
|
2041
774
|
* @returns {boolean} whether el is of the correct nodeType
|
|
2042
775
|
*/
|
|
2043
776
|
function isTextNode(el) {
|
|
2044
|
-
return el && el.nodeType === 3 // Node.TEXT_NODE - use integer constant for browser portability
|
|
777
|
+
return !!el && el.nodeType === 3; // Node.TEXT_NODE - use integer constant for browser portability
|
|
778
|
+
}
|
|
779
|
+
/*
|
|
780
|
+
* Check whether an element has nodeType Node.DOCUMENT_FRAGMENT_NODE
|
|
781
|
+
* @param {Element} el - element to check
|
|
782
|
+
* @returns {boolean} whether el is of the correct nodeType
|
|
783
|
+
*/
|
|
784
|
+
function isDocumentFragment(el) {
|
|
785
|
+
return !!el && el.nodeType === 11; // Node.DOCUMENT_FRAGMENT_NODE - use integer constant for browser portability
|
|
2045
786
|
}
|
|
2046
|
-
|
|
2047
787
|
var usefulElements = ['a', 'button', 'form', 'input', 'select', 'textarea', 'label'];
|
|
2048
788
|
/*
|
|
2049
789
|
* Check whether a DOM event should be "captured" or if it may contain sentitive data
|
|
@@ -2054,60 +794,56 @@ var usefulElements = ['a', 'button', 'form', 'input', 'select', 'textarea', 'lab
|
|
|
2054
794
|
*/
|
|
2055
795
|
function shouldCaptureDomEvent(el, event) {
|
|
2056
796
|
if (!el || isTag(el, 'html') || !isElementNode(el)) {
|
|
2057
|
-
return false
|
|
797
|
+
return false;
|
|
2058
798
|
}
|
|
2059
|
-
|
|
2060
799
|
var parentIsUsefulElement = false;
|
|
2061
|
-
var targetElementList = [el];
|
|
800
|
+
var targetElementList = [el]; // TODO: remove this var, it's never queried
|
|
2062
801
|
var parentNode = true;
|
|
2063
802
|
var curEl = el;
|
|
2064
803
|
while (curEl.parentNode && !isTag(curEl, 'body')) {
|
|
2065
804
|
// If element is a shadow root, we skip it
|
|
2066
|
-
if (curEl.parentNode
|
|
805
|
+
if (isDocumentFragment(curEl.parentNode)) {
|
|
2067
806
|
targetElementList.push(curEl.parentNode.host);
|
|
2068
807
|
curEl = curEl.parentNode.host;
|
|
2069
|
-
continue
|
|
808
|
+
continue;
|
|
2070
809
|
}
|
|
2071
|
-
parentNode = curEl.parentNode;
|
|
2072
|
-
if (!parentNode)
|
|
810
|
+
parentNode = curEl.parentNode || false;
|
|
811
|
+
if (!parentNode)
|
|
812
|
+
break;
|
|
2073
813
|
if (usefulElements.indexOf(parentNode.tagName.toLowerCase()) > -1) {
|
|
2074
814
|
parentIsUsefulElement = true;
|
|
2075
|
-
}
|
|
2076
|
-
|
|
2077
|
-
|
|
815
|
+
}
|
|
816
|
+
else {
|
|
817
|
+
var compStyles_1 = window.getComputedStyle(parentNode);
|
|
818
|
+
if (compStyles_1 && compStyles_1.getPropertyValue('cursor') === 'pointer') {
|
|
2078
819
|
parentIsUsefulElement = true;
|
|
2079
820
|
}
|
|
2080
821
|
}
|
|
2081
|
-
|
|
2082
822
|
targetElementList.push(parentNode);
|
|
2083
823
|
curEl = parentNode;
|
|
2084
824
|
}
|
|
2085
|
-
|
|
2086
|
-
let compStyles = window.getComputedStyle(el);
|
|
825
|
+
var compStyles = window.getComputedStyle(el);
|
|
2087
826
|
if (compStyles && compStyles.getPropertyValue('cursor') === 'pointer' && event.type === 'click') {
|
|
2088
|
-
return true
|
|
827
|
+
return true;
|
|
2089
828
|
}
|
|
2090
|
-
|
|
2091
829
|
var tag = el.tagName.toLowerCase();
|
|
2092
830
|
switch (tag) {
|
|
2093
831
|
case 'html':
|
|
2094
|
-
return false
|
|
832
|
+
return false;
|
|
2095
833
|
case 'form':
|
|
2096
|
-
return event.type === 'submit'
|
|
834
|
+
return event.type === 'submit';
|
|
2097
835
|
case 'input':
|
|
2098
|
-
return event.type === 'change' || event.type === 'click'
|
|
836
|
+
return event.type === 'change' || event.type === 'click';
|
|
2099
837
|
case 'select':
|
|
2100
838
|
case 'textarea':
|
|
2101
|
-
return event.type === 'change' || event.type === 'click'
|
|
839
|
+
return event.type === 'change' || event.type === 'click';
|
|
2102
840
|
default:
|
|
2103
|
-
if (parentIsUsefulElement)
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
(usefulElements.indexOf(tag) > -1 || el.getAttribute('contenteditable') === 'true')
|
|
2107
|
-
)
|
|
841
|
+
if (parentIsUsefulElement)
|
|
842
|
+
return event.type === 'click';
|
|
843
|
+
return (event.type === 'click' &&
|
|
844
|
+
(usefulElements.indexOf(tag) > -1 || el.getAttribute('contenteditable') === 'true'));
|
|
2108
845
|
}
|
|
2109
846
|
}
|
|
2110
|
-
|
|
2111
847
|
/*
|
|
2112
848
|
* Check whether a DOM element should be "captured" or if it may contain sentitive data
|
|
2113
849
|
* using a variety of heuristics.
|
|
@@ -2117,40 +853,38 @@ function shouldCaptureDomEvent(el, event) {
|
|
|
2117
853
|
function shouldCaptureElement(el) {
|
|
2118
854
|
for (var curEl = el; curEl.parentNode && !isTag(curEl, 'body'); curEl = curEl.parentNode) {
|
|
2119
855
|
var classes = getClassName(curEl).split(' ');
|
|
2120
|
-
if (
|
|
2121
|
-
return false
|
|
856
|
+
if (_includes(classes, 'ph-sensitive') || _includes(classes, 'ph-no-capture')) {
|
|
857
|
+
return false;
|
|
2122
858
|
}
|
|
2123
859
|
}
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
return true
|
|
860
|
+
if (_includes(getClassName(el).split(' '), 'ph-include')) {
|
|
861
|
+
return true;
|
|
2127
862
|
}
|
|
2128
|
-
|
|
2129
863
|
// don't include hidden or password fields
|
|
2130
864
|
var type = el.type || '';
|
|
2131
865
|
if (typeof type === 'string') {
|
|
2132
866
|
// it's possible for el.type to be a DOM element if el is a form with a child input[name="type"]
|
|
2133
867
|
switch (type.toLowerCase()) {
|
|
2134
868
|
case 'hidden':
|
|
2135
|
-
return false
|
|
869
|
+
return false;
|
|
2136
870
|
case 'password':
|
|
2137
|
-
return false
|
|
871
|
+
return false;
|
|
2138
872
|
}
|
|
2139
873
|
}
|
|
2140
|
-
|
|
2141
874
|
// filter out data from fields that look like sensitive fields
|
|
2142
875
|
var name = el.name || el.id || '';
|
|
876
|
+
// See https://github.com/posthog/posthog-js/issues/165
|
|
877
|
+
// Under specific circumstances a bug caused .replace to be called on a DOM element
|
|
878
|
+
// instead of a string, removing the element from the page. Ensure this issue is mitigated.
|
|
2143
879
|
if (typeof name === 'string') {
|
|
2144
880
|
// it's possible for el.name or el.id to be a DOM element if el is a form with a child input[name="name"]
|
|
2145
881
|
var sensitiveNameRegex = /^cc|cardnum|ccnum|creditcard|csc|cvc|cvv|exp|pass|pwd|routing|seccode|securitycode|securitynum|socialsec|socsec|ssn/i;
|
|
2146
882
|
if (sensitiveNameRegex.test(name.replace(/[^a-zA-Z0-9]/g, ''))) {
|
|
2147
|
-
return false
|
|
883
|
+
return false;
|
|
2148
884
|
}
|
|
2149
885
|
}
|
|
2150
|
-
|
|
2151
|
-
return true
|
|
886
|
+
return true;
|
|
2152
887
|
}
|
|
2153
|
-
|
|
2154
888
|
/*
|
|
2155
889
|
* Check whether a DOM element is 'sensitive' and we should only capture limited data
|
|
2156
890
|
* @param {Element} el - element to check
|
|
@@ -2159,18 +893,15 @@ function shouldCaptureElement(el) {
|
|
|
2159
893
|
function isSensitiveElement(el) {
|
|
2160
894
|
// don't send data from inputs or similar elements since there will always be
|
|
2161
895
|
// a risk of clientside javascript placing sensitive data in attributes
|
|
2162
|
-
|
|
2163
|
-
if (
|
|
2164
|
-
(isTag(el, 'input') && !allowedInputTypes.includes(el.type)) ||
|
|
896
|
+
var allowedInputTypes = ['button', 'checkbox', 'submit', 'reset'];
|
|
897
|
+
if ((isTag(el, 'input') && !allowedInputTypes.includes(el.type)) ||
|
|
2165
898
|
isTag(el, 'select') ||
|
|
2166
899
|
isTag(el, 'textarea') ||
|
|
2167
|
-
el.getAttribute('contenteditable') === 'true'
|
|
2168
|
-
|
|
2169
|
-
return true
|
|
900
|
+
el.getAttribute('contenteditable') === 'true') {
|
|
901
|
+
return true;
|
|
2170
902
|
}
|
|
2171
|
-
return false
|
|
903
|
+
return false;
|
|
2172
904
|
}
|
|
2173
|
-
|
|
2174
905
|
/*
|
|
2175
906
|
* Check whether a string value should be "captured" or if it may contain sentitive data
|
|
2176
907
|
* using a variety of heuristics.
|
|
@@ -2178,30 +909,25 @@ function isSensitiveElement(el) {
|
|
|
2178
909
|
* @returns {boolean} whether the element should be captured
|
|
2179
910
|
*/
|
|
2180
911
|
function shouldCaptureValue(value) {
|
|
2181
|
-
if (value === null ||
|
|
2182
|
-
return false
|
|
912
|
+
if (value === null || _isUndefined(value)) {
|
|
913
|
+
return false;
|
|
2183
914
|
}
|
|
2184
|
-
|
|
2185
915
|
if (typeof value === 'string') {
|
|
2186
|
-
value =
|
|
2187
|
-
|
|
916
|
+
value = _trim(value);
|
|
2188
917
|
// check to see if input value looks like a credit card number
|
|
2189
918
|
// see: https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9781449327453/ch04s20.html
|
|
2190
919
|
var ccRegex = /^(?:(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11}))$/;
|
|
2191
920
|
if (ccRegex.test((value || '').replace(/[- ]/g, ''))) {
|
|
2192
|
-
return false
|
|
921
|
+
return false;
|
|
2193
922
|
}
|
|
2194
|
-
|
|
2195
923
|
// check to see if input value looks like a social security number
|
|
2196
924
|
var ssnRegex = /(^\d{3}-?\d{2}-?\d{4}$)/;
|
|
2197
925
|
if (ssnRegex.test(value)) {
|
|
2198
|
-
return false
|
|
926
|
+
return false;
|
|
2199
927
|
}
|
|
2200
928
|
}
|
|
2201
|
-
|
|
2202
|
-
return true
|
|
929
|
+
return true;
|
|
2203
930
|
}
|
|
2204
|
-
|
|
2205
931
|
/*
|
|
2206
932
|
* Check whether an attribute name is an Angular style attr (either _ngcontent or _nghost)
|
|
2207
933
|
* These update on each build and lead to noise in the element chain
|
|
@@ -2211,69 +937,58 @@ function shouldCaptureValue(value) {
|
|
|
2211
937
|
*/
|
|
2212
938
|
function isAngularStyleAttr(attributeName) {
|
|
2213
939
|
if (typeof attributeName === 'string') {
|
|
2214
|
-
return attributeName.substring(0, 10) === '_ngcontent' || attributeName.substring(0, 7) === '_nghost'
|
|
2215
|
-
}
|
|
2216
|
-
return false
|
|
2217
|
-
}
|
|
2218
|
-
|
|
2219
|
-
function isDataAttribute(attributeName)
|
|
2220
|
-
{
|
|
2221
|
-
if (typeof attributeName === 'string') {
|
|
2222
|
-
return attributeName.startsWith('data-')
|
|
940
|
+
return attributeName.substring(0, 10) === '_ngcontent' || attributeName.substring(0, 7) === '_nghost';
|
|
2223
941
|
}
|
|
2224
|
-
return false
|
|
942
|
+
return false;
|
|
2225
943
|
}
|
|
2226
944
|
|
|
2227
945
|
// Naive rage click implementation: If mouse has not moved than RAGE_CLICK_THRESHOLD_PX
|
|
2228
946
|
// over RAGE_CLICK_CLICK_COUNT clicks with max RAGE_CLICK_TIMEOUT_MS between clicks, it's
|
|
2229
947
|
// counted as a rage click
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
948
|
+
var RAGE_CLICK_THRESHOLD_PX = 30;
|
|
949
|
+
var RAGE_CLICK_TIMEOUT_MS = 1000;
|
|
950
|
+
var RAGE_CLICK_CLICK_COUNT = 3;
|
|
951
|
+
var RageClick = /** @class */ (function () {
|
|
952
|
+
function RageClick(instance, enabled) {
|
|
953
|
+
if (enabled === void 0) { enabled = false; }
|
|
2236
954
|
this.clicks = [];
|
|
2237
955
|
this.instance = instance;
|
|
2238
956
|
this.enabled = enabled;
|
|
2239
957
|
}
|
|
2240
|
-
|
|
2241
|
-
click(x, y, timestamp) {
|
|
958
|
+
RageClick.prototype.click = function (x, y, timestamp) {
|
|
2242
959
|
if (!this.enabled) {
|
|
2243
|
-
return
|
|
960
|
+
return;
|
|
2244
961
|
}
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
if (
|
|
2248
|
-
lastClick &&
|
|
962
|
+
var lastClick = this.clicks[this.clicks.length - 1];
|
|
963
|
+
if (lastClick &&
|
|
2249
964
|
Math.abs(x - lastClick.x) + Math.abs(y - lastClick.y) < RAGE_CLICK_THRESHOLD_PX &&
|
|
2250
|
-
timestamp - lastClick.timestamp < RAGE_CLICK_TIMEOUT_MS
|
|
2251
|
-
|
|
2252
|
-
this.clicks.push({ x, y, timestamp });
|
|
2253
|
-
|
|
965
|
+
timestamp - lastClick.timestamp < RAGE_CLICK_TIMEOUT_MS) {
|
|
966
|
+
this.clicks.push({ x: x, y: y, timestamp: timestamp });
|
|
2254
967
|
if (this.clicks.length === RAGE_CLICK_CLICK_COUNT) {
|
|
2255
968
|
this.instance.capture('$rageclick');
|
|
2256
969
|
}
|
|
2257
|
-
} else {
|
|
2258
|
-
this.clicks = [{ x, y, timestamp }];
|
|
2259
970
|
}
|
|
2260
|
-
|
|
2261
|
-
}
|
|
971
|
+
else {
|
|
972
|
+
this.clicks = [{ x: x, y: y, timestamp: timestamp }];
|
|
973
|
+
}
|
|
974
|
+
};
|
|
975
|
+
return RageClick;
|
|
976
|
+
}());
|
|
2262
977
|
|
|
2263
978
|
var autocapture = {
|
|
2264
979
|
_initializedTokens: [],
|
|
2265
|
-
|
|
2266
980
|
_previousElementSibling: function (el) {
|
|
2267
981
|
if (el.previousElementSibling) {
|
|
2268
|
-
return el.previousElementSibling
|
|
2269
|
-
}
|
|
982
|
+
return el.previousElementSibling;
|
|
983
|
+
}
|
|
984
|
+
else {
|
|
985
|
+
var _el = el;
|
|
2270
986
|
do {
|
|
2271
|
-
|
|
2272
|
-
} while (
|
|
2273
|
-
return
|
|
987
|
+
_el = _el.previousSibling; // resolves to ChildNode->Node, which is Element's parent class
|
|
988
|
+
} while (_el && !isElementNode(_el));
|
|
989
|
+
return _el;
|
|
2274
990
|
}
|
|
2275
991
|
},
|
|
2276
|
-
|
|
2277
992
|
_getPropertiesFromElement: function (elem, maskInputs, maskText) {
|
|
2278
993
|
var tag_name = elem.tagName.toLowerCase();
|
|
2279
994
|
var props = {
|
|
@@ -2282,22 +997,19 @@ var autocapture = {
|
|
|
2282
997
|
if (usefulElements.indexOf(tag_name) > -1 && !maskText) {
|
|
2283
998
|
props['$el_text'] = getSafeText(elem);
|
|
2284
999
|
}
|
|
2285
|
-
|
|
2286
1000
|
var classes = getClassName(elem);
|
|
2287
1001
|
if (classes.length > 0)
|
|
2288
1002
|
props['classes'] = classes.split(' ').filter(function (c) {
|
|
2289
|
-
return c !== ''
|
|
1003
|
+
return c !== '';
|
|
2290
1004
|
});
|
|
2291
|
-
|
|
2292
|
-
_.each(elem.attributes, function (attr) {
|
|
1005
|
+
_each(elem.attributes, function (attr) {
|
|
2293
1006
|
// Only capture attributes we know are safe
|
|
2294
|
-
if (isSensitiveElement(elem) && ['name', 'id', 'class'].indexOf(attr.name) === -1)
|
|
2295
|
-
|
|
2296
|
-
if (!maskInputs && shouldCaptureValue(attr.value) && !isAngularStyleAttr(attr.name)
|
|
1007
|
+
if (isSensitiveElement(elem) && ['name', 'id', 'class'].indexOf(attr.name) === -1)
|
|
1008
|
+
return;
|
|
1009
|
+
if (!maskInputs && shouldCaptureValue(attr.value) && !isAngularStyleAttr(attr.name)) {
|
|
2297
1010
|
props['attr__' + attr.name] = attr.value;
|
|
2298
1011
|
}
|
|
2299
1012
|
});
|
|
2300
|
-
|
|
2301
1013
|
var nthChild = 1;
|
|
2302
1014
|
var nthOfType = 1;
|
|
2303
1015
|
var currentElem = elem;
|
|
@@ -2310,219 +1022,178 @@ var autocapture = {
|
|
|
2310
1022
|
}
|
|
2311
1023
|
props['nth_child'] = nthChild;
|
|
2312
1024
|
props['nth_of_type'] = nthOfType;
|
|
2313
|
-
|
|
2314
|
-
return props
|
|
1025
|
+
return props;
|
|
2315
1026
|
},
|
|
2316
|
-
|
|
2317
1027
|
_getDefaultProperties: function (eventType) {
|
|
2318
1028
|
return {
|
|
2319
1029
|
$event_type: eventType,
|
|
2320
1030
|
$ce_version: 1,
|
|
2321
|
-
}
|
|
1031
|
+
};
|
|
2322
1032
|
},
|
|
2323
|
-
|
|
2324
1033
|
_extractCustomPropertyValue: function (customProperty) {
|
|
2325
1034
|
var propValues = [];
|
|
2326
|
-
|
|
1035
|
+
_each(document.querySelectorAll(customProperty['css_selector']), function (matchedElem) {
|
|
2327
1036
|
var value;
|
|
2328
|
-
|
|
2329
1037
|
if (['input', 'select'].indexOf(matchedElem.tagName.toLowerCase()) > -1) {
|
|
2330
1038
|
value = matchedElem['value'];
|
|
2331
|
-
}
|
|
1039
|
+
}
|
|
1040
|
+
else if (matchedElem['textContent']) {
|
|
2332
1041
|
value = matchedElem['textContent'];
|
|
2333
1042
|
}
|
|
2334
|
-
|
|
2335
1043
|
if (shouldCaptureValue(value)) {
|
|
2336
1044
|
propValues.push(value);
|
|
2337
1045
|
}
|
|
2338
1046
|
});
|
|
2339
|
-
return propValues.join(', ')
|
|
1047
|
+
return propValues.join(', ');
|
|
2340
1048
|
},
|
|
2341
|
-
|
|
1049
|
+
// TODO: delete custom_properties after changeless typescript refactor
|
|
2342
1050
|
_getCustomProperties: function (targetElementList) {
|
|
2343
|
-
var
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
function (
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
}
|
|
2357
|
-
},
|
|
2358
|
-
this
|
|
2359
|
-
);
|
|
2360
|
-
},
|
|
2361
|
-
this
|
|
2362
|
-
);
|
|
2363
|
-
},
|
|
2364
|
-
this
|
|
2365
|
-
);
|
|
2366
|
-
return props
|
|
1051
|
+
var _this = this;
|
|
1052
|
+
var props = {}; // will be deleted
|
|
1053
|
+
_each(this._customProperties, function (customProperty) {
|
|
1054
|
+
_each(customProperty['event_selectors'], function (eventSelector) {
|
|
1055
|
+
var eventElements = document.querySelectorAll(eventSelector);
|
|
1056
|
+
_each(eventElements, function (eventElement) {
|
|
1057
|
+
if (_includes(targetElementList, eventElement) && shouldCaptureElement(eventElement)) {
|
|
1058
|
+
props[customProperty['name']] = _this._extractCustomPropertyValue(customProperty);
|
|
1059
|
+
}
|
|
1060
|
+
});
|
|
1061
|
+
});
|
|
1062
|
+
});
|
|
1063
|
+
return props;
|
|
2367
1064
|
},
|
|
2368
|
-
|
|
2369
1065
|
_getEventTarget: function (e) {
|
|
1066
|
+
var _a;
|
|
2370
1067
|
// https://developer.mozilla.org/en-US/docs/Web/API/Event/target#Compatibility_notes
|
|
2371
1068
|
if (typeof e.target === 'undefined') {
|
|
2372
|
-
return e.srcElement
|
|
2373
|
-
}
|
|
2374
|
-
|
|
2375
|
-
|
|
1069
|
+
return e.srcElement || null;
|
|
1070
|
+
}
|
|
1071
|
+
else {
|
|
1072
|
+
if ((_a = e.target) === null || _a === void 0 ? void 0 : _a.shadowRoot) {
|
|
1073
|
+
return e.composedPath()[0] || null;
|
|
2376
1074
|
}
|
|
2377
|
-
return e.target
|
|
1075
|
+
return e.target || null;
|
|
2378
1076
|
}
|
|
2379
1077
|
},
|
|
2380
|
-
|
|
2381
|
-
|
|
1078
|
+
_captureEvent: function (e, instance, opts) {
|
|
1079
|
+
var _this = this;
|
|
1080
|
+
var _a;
|
|
2382
1081
|
/*** Don't mess with this code without running IE8 tests on it ***/
|
|
2383
1082
|
var target = this._getEventTarget(e);
|
|
2384
1083
|
if (isTextNode(target)) {
|
|
2385
1084
|
// defeat Safari bug (see: http://www.quirksmode.org/js/events_properties.html)
|
|
2386
|
-
target = target.parentNode;
|
|
1085
|
+
target = (target.parentNode || null);
|
|
2387
1086
|
}
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
this.rageclicks.click(e.clientX, e.clientY, new Date().getTime());
|
|
1087
|
+
if (e.type === 'click' && e instanceof MouseEvent) {
|
|
1088
|
+
(_a = this.rageclicks) === null || _a === void 0 ? void 0 : _a.click(e.clientX, e.clientY, new Date().getTime());
|
|
2391
1089
|
}
|
|
2392
|
-
|
|
2393
|
-
if (shouldCaptureDomEvent(target, e)) {
|
|
1090
|
+
if (target && shouldCaptureDomEvent(target, e)) {
|
|
2394
1091
|
var targetElementList = [target];
|
|
2395
1092
|
var curEl = target;
|
|
2396
1093
|
while (curEl.parentNode && !isTag(curEl, 'body')) {
|
|
2397
|
-
if (curEl.parentNode
|
|
1094
|
+
if (isDocumentFragment(curEl.parentNode)) {
|
|
2398
1095
|
targetElementList.push(curEl.parentNode.host);
|
|
2399
1096
|
curEl = curEl.parentNode.host;
|
|
2400
|
-
continue
|
|
1097
|
+
continue;
|
|
2401
1098
|
}
|
|
2402
1099
|
targetElementList.push(curEl.parentNode);
|
|
2403
1100
|
curEl = curEl.parentNode;
|
|
2404
1101
|
}
|
|
2405
|
-
|
|
2406
|
-
var
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
explicitNoCapture = true;
|
|
2425
|
-
}
|
|
2426
|
-
|
|
2427
|
-
elementsJson.push(
|
|
2428
|
-
this._getPropertiesFromElement(
|
|
2429
|
-
el,
|
|
2430
|
-
instance.get_config('mask_all_element_attributes'),
|
|
2431
|
-
instance.get_config('mask_all_text')
|
|
2432
|
-
)
|
|
2433
|
-
);
|
|
2434
|
-
},
|
|
2435
|
-
this
|
|
2436
|
-
);
|
|
2437
|
-
|
|
2438
|
-
if (!instance.get_config('mask_all_text')) {
|
|
2439
|
-
elementsJson[0]['$el_text'] = getSafeText(target);
|
|
1102
|
+
var elementsJson_1 = [];
|
|
1103
|
+
var href_1, explicitNoCapture_1 = false;
|
|
1104
|
+
_each(targetElementList, function (el) {
|
|
1105
|
+
var shouldCaptureEl = shouldCaptureElement(el);
|
|
1106
|
+
// if the element or a parent element is an anchor tag
|
|
1107
|
+
// include the href as a property
|
|
1108
|
+
if (el.tagName.toLowerCase() === 'a') {
|
|
1109
|
+
href_1 = el.getAttribute('href');
|
|
1110
|
+
href_1 = shouldCaptureEl && shouldCaptureValue(href_1) && href_1;
|
|
1111
|
+
}
|
|
1112
|
+
// allow users to programmatically prevent capturing of elements by adding class 'ph-no-capture'
|
|
1113
|
+
var classes = getClassName(el).split(' ');
|
|
1114
|
+
if (_includes(classes, 'ph-no-capture')) {
|
|
1115
|
+
explicitNoCapture_1 = true;
|
|
1116
|
+
}
|
|
1117
|
+
elementsJson_1.push(_this._getPropertiesFromElement(el, opts === null || opts === void 0 ? void 0 : opts.mask_all_element_attributes, opts === null || opts === void 0 ? void 0 : opts.mask_all_text));
|
|
1118
|
+
});
|
|
1119
|
+
if (!(opts === null || opts === void 0 ? void 0 : opts.mask_all_text)) {
|
|
1120
|
+
elementsJson_1[0]['$el_text'] = getSafeText(target);
|
|
2440
1121
|
}
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
elementsJson[0]['attr__href'] = href;
|
|
1122
|
+
if (href_1) {
|
|
1123
|
+
elementsJson_1[0]['attr__href'] = href_1;
|
|
2444
1124
|
}
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
return false
|
|
1125
|
+
if (explicitNoCapture_1) {
|
|
1126
|
+
return false;
|
|
2448
1127
|
}
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
{
|
|
2453
|
-
$elements: elementsJson,
|
|
2454
|
-
},
|
|
2455
|
-
this._getCustomProperties(targetElementList)
|
|
2456
|
-
);
|
|
2457
|
-
|
|
1128
|
+
var props = _extend(this._getDefaultProperties(e.type), {
|
|
1129
|
+
$elements: elementsJson_1,
|
|
1130
|
+
}, this._getCustomProperties(targetElementList));
|
|
2458
1131
|
instance.capture('$autocapture', props);
|
|
2459
|
-
return true
|
|
1132
|
+
return true;
|
|
2460
1133
|
}
|
|
2461
1134
|
},
|
|
2462
|
-
|
|
2463
1135
|
// only reason is to stub for unit tests
|
|
2464
1136
|
// since you can't override window.location props
|
|
2465
1137
|
_navigate: function (href) {
|
|
2466
1138
|
window.location.href = href;
|
|
2467
1139
|
},
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
var handler =
|
|
1140
|
+
_addDomEventHandlers: function (instance, opts) {
|
|
1141
|
+
var _this = this;
|
|
1142
|
+
var handler = function (e) {
|
|
2471
1143
|
e = e || window.event;
|
|
2472
|
-
|
|
2473
|
-
}
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
1144
|
+
_this._captureEvent(e, instance, opts);
|
|
1145
|
+
};
|
|
1146
|
+
_register_event(document, 'submit', handler, false, true);
|
|
1147
|
+
_register_event(document, 'change', handler, false, true);
|
|
1148
|
+
_register_event(document, 'click', handler, false, true);
|
|
2477
1149
|
},
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
if (this._initializedTokens.indexOf(token) > -1) {
|
|
2484
|
-
console.log('autocapture already initialized for token "' + token + '"');
|
|
2485
|
-
return
|
|
2486
|
-
}
|
|
2487
|
-
|
|
2488
|
-
this._initializedTokens.push(token);
|
|
2489
|
-
|
|
2490
|
-
if (instance.get_config('autocapture')) {
|
|
2491
|
-
this._addDomEventHandlers(instance);
|
|
2492
|
-
} else {
|
|
2493
|
-
instance['__autocapture_enabled'] = false;
|
|
2494
|
-
}
|
|
2495
|
-
|
|
1150
|
+
_customProperties: [],
|
|
1151
|
+
rageclicks: null,
|
|
1152
|
+
opts: {},
|
|
1153
|
+
init: function (instance, opts) {
|
|
1154
|
+
var _this = this;
|
|
2496
1155
|
this.rageclicks = new RageClick(instance);
|
|
1156
|
+
this.opts = opts;
|
|
1157
|
+
if (!(document && document.body)) {
|
|
1158
|
+
console.log('document not ready yet, trying again in 500 milliseconds...');
|
|
1159
|
+
setTimeout(function () {
|
|
1160
|
+
_this.readyAutocapture(instance, opts);
|
|
1161
|
+
}, 500);
|
|
1162
|
+
return;
|
|
1163
|
+
}
|
|
1164
|
+
this.readyAutocapture(instance, opts);
|
|
1165
|
+
},
|
|
1166
|
+
readyAutocapture: function (instance, opts) {
|
|
1167
|
+
this._addDomEventHandlers(instance, opts);
|
|
2497
1168
|
},
|
|
2498
|
-
|
|
2499
1169
|
// this is a mechanism to ramp up CE with no server-side interaction.
|
|
2500
1170
|
// when CE is active, every page load results in a decide request. we
|
|
2501
1171
|
// need to gently ramp this up so we don't overload decide. this decides
|
|
2502
1172
|
// deterministically if CE is enabled for this project by modding the char
|
|
2503
1173
|
// value of the project token.
|
|
2504
1174
|
enabledForProject: function (token, numBuckets, numEnabledBuckets) {
|
|
2505
|
-
|
|
2506
|
-
|
|
1175
|
+
if (!token) {
|
|
1176
|
+
return true;
|
|
1177
|
+
}
|
|
1178
|
+
numBuckets = !_isUndefined(numBuckets) ? numBuckets : 10;
|
|
1179
|
+
numEnabledBuckets = !_isUndefined(numEnabledBuckets) ? numEnabledBuckets : 10;
|
|
2507
1180
|
var charCodeSum = 0;
|
|
2508
1181
|
for (var i = 0; i < token.length; i++) {
|
|
2509
1182
|
charCodeSum += token.charCodeAt(i);
|
|
2510
1183
|
}
|
|
2511
|
-
return charCodeSum % numBuckets < numEnabledBuckets
|
|
1184
|
+
return charCodeSum % numBuckets < numEnabledBuckets;
|
|
2512
1185
|
},
|
|
2513
|
-
|
|
2514
1186
|
isBrowserSupported: function () {
|
|
2515
|
-
return
|
|
1187
|
+
return _isFunction(document.querySelectorAll);
|
|
2516
1188
|
},
|
|
2517
1189
|
};
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
_.safewrap_instance_methods(autocapture);
|
|
1190
|
+
_bind_instance_methods(autocapture);
|
|
1191
|
+
_safewrap_instance_methods(autocapture);
|
|
2521
1192
|
|
|
2522
1193
|
var VERSION_INFO = {
|
|
2523
1194
|
env: 'production',
|
|
2524
|
-
date: '2022-
|
|
2525
|
-
version: '1.0
|
|
1195
|
+
date: '2022-09-03T13:48:55.501Z',
|
|
1196
|
+
version: '1.1.0'
|
|
2526
1197
|
};
|
|
2527
1198
|
var USERMAVEN_VERSION = "".concat(VERSION_INFO.version, "/").concat(VERSION_INFO.env, "@").concat(VERSION_INFO.date);
|
|
2528
1199
|
var MAX_AGE_TEN_YEARS = 31622400 * 10;
|
|
@@ -2902,6 +1573,9 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
2902
1573
|
this.retryTimeout = [500, 1e12];
|
|
2903
1574
|
this.flushing = false;
|
|
2904
1575
|
this.attempt = 1;
|
|
1576
|
+
this.propertyBlacklist = [];
|
|
1577
|
+
// public persistence?: UserMavenPersistence;
|
|
1578
|
+
// public sessionManager?: SessionIdManager;
|
|
2905
1579
|
this.__autocapture_enabled = false;
|
|
2906
1580
|
}
|
|
2907
1581
|
// private anonymousId: string = '';
|
|
@@ -3095,10 +1769,9 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3095
1769
|
UsermavenClientImpl.prototype.getCtx = function (env) {
|
|
3096
1770
|
var now = new Date();
|
|
3097
1771
|
var props = env.describeClient() || {};
|
|
3098
|
-
var _a = (this.cookiePolicy !== "keep") ? { "session_id": "", "window_id": "" } : this.sessionManager.getSessionAndWindowId(), session_id = _a.session_id, window_id = _a.window_id;
|
|
3099
1772
|
var company = this.userProperties['company'] || {};
|
|
3100
1773
|
delete this.userProperties['company'];
|
|
3101
|
-
var payload = __assign(__assign({ event_id: "",
|
|
1774
|
+
var payload = __assign(__assign({ event_id: "", user: __assign({ anonymous_id: this.cookiePolicy !== "strict"
|
|
3102
1775
|
? env.getAnonymousId({
|
|
3103
1776
|
name: this.idCookieName,
|
|
3104
1777
|
domain: this.cookieDomain,
|
|
@@ -3219,21 +1892,17 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3219
1892
|
}
|
|
3220
1893
|
getLogger().debug("Restored persistent properties", this.permanentProperties);
|
|
3221
1894
|
}
|
|
3222
|
-
|
|
1895
|
+
this.propertyBlacklist = options.property_blacklist && options.property_blacklist.length > 0 ? options.property_blacklist : [];
|
|
1896
|
+
// // Added these configuration for session management + autocapture
|
|
3223
1897
|
var defaultConfig = {
|
|
3224
|
-
persistence: 'cookie',
|
|
3225
|
-
persistence_name: 'session',
|
|
3226
1898
|
autocapture: false,
|
|
3227
|
-
capture_pageview: true,
|
|
3228
|
-
store_google: false,
|
|
3229
|
-
save_referrer: false,
|
|
3230
1899
|
properties_string_max_length: null,
|
|
3231
1900
|
property_blacklist: [],
|
|
3232
1901
|
sanitize_properties: null
|
|
3233
1902
|
};
|
|
3234
|
-
this.config =
|
|
1903
|
+
this.config = _extend({}, defaultConfig, options || {}, this.config || {}, { token: this.apiKey });
|
|
3235
1904
|
getLogger().debug('Default Configuration', this.config);
|
|
3236
|
-
this.manageSession(this.config);
|
|
1905
|
+
// this.manageSession(this.config);
|
|
3237
1906
|
this.manageAutoCapture(this.config);
|
|
3238
1907
|
if (options.capture_3rd_party_cookies === false) {
|
|
3239
1908
|
this._3pCookies = {};
|
|
@@ -3347,30 +2016,6 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3347
2016
|
this.propsPersistance.save(this.permanentProperties);
|
|
3348
2017
|
}
|
|
3349
2018
|
};
|
|
3350
|
-
/**
|
|
3351
|
-
* Manage session capability
|
|
3352
|
-
* @param options
|
|
3353
|
-
*/
|
|
3354
|
-
UsermavenClientImpl.prototype.manageSession = function (options) {
|
|
3355
|
-
getLogger().debug('Options', options);
|
|
3356
|
-
options = options || {};
|
|
3357
|
-
getLogger().debug('Options', options);
|
|
3358
|
-
// cross_subdomain_cookie: whether to keep cookie across domains and subdomains
|
|
3359
|
-
var defaultConfig = {
|
|
3360
|
-
persistence: options.persistence || 'cookie',
|
|
3361
|
-
persistence_name: options.persistence_name || 'session',
|
|
3362
|
-
cross_subdomain_cookie: options.cross_subdomain_cookie || true
|
|
3363
|
-
};
|
|
3364
|
-
// TODO: Default session name would be session_
|
|
3365
|
-
this.config = _.extend(defaultConfig, this.config || {}, {
|
|
3366
|
-
token: this.apiKey,
|
|
3367
|
-
});
|
|
3368
|
-
getLogger().debug('Default Configuration', this.config);
|
|
3369
|
-
this.persistence = new UserMavenPersistence(this.config);
|
|
3370
|
-
getLogger().debug('Persistence Configuration', this.persistence);
|
|
3371
|
-
this.sessionManager = new SessionIdManager(this.config, this.persistence);
|
|
3372
|
-
getLogger().debug('Session Configuration', this.sessionManager);
|
|
3373
|
-
};
|
|
3374
2019
|
/**
|
|
3375
2020
|
* Manage auto-capturing
|
|
3376
2021
|
* @param options
|
|
@@ -3385,14 +2030,17 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3385
2030
|
var num_enabled_buckets = 100;
|
|
3386
2031
|
if (!autocapture.enabledForProject(this.apiKey, num_buckets, num_enabled_buckets)) {
|
|
3387
2032
|
this.config['autocapture'] = false;
|
|
2033
|
+
this.__autocapture_enabled = false;
|
|
3388
2034
|
console.log('Not in active bucket: disabling Automatic Event Collection.');
|
|
3389
2035
|
}
|
|
3390
2036
|
else if (!autocapture.isBrowserSupported()) {
|
|
3391
2037
|
this.config['autocapture'] = false;
|
|
2038
|
+
this.__autocapture_enabled = false;
|
|
3392
2039
|
console.log('Disabling Automatic Event Collection because this browser is not supported');
|
|
3393
2040
|
}
|
|
3394
2041
|
else {
|
|
3395
|
-
|
|
2042
|
+
console.log('Autocapture enabled...');
|
|
2043
|
+
autocapture.init(this, options);
|
|
3396
2044
|
}
|
|
3397
2045
|
};
|
|
3398
2046
|
/**
|
|
@@ -3400,12 +2048,7 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3400
2048
|
* frequently used usermaven function.
|
|
3401
2049
|
*
|
|
3402
2050
|
* ### Usage:
|
|
3403
|
-
*
|
|
3404
|
-
* // capture an event named 'Registered'
|
|
3405
|
-
* usermaven.capture('Registered', {'Gender': 'Male', 'Age': 21});
|
|
3406
|
-
*
|
|
3407
|
-
* // capture an event using navigator.sendBeacon
|
|
3408
|
-
* usermaven.capture('Left page', {'duration_seconds': 35}, {transport: 'sendBeacon'});
|
|
2051
|
+
* usermaven.capture('Registered', {'Gender': 'Male', 'Age': 21}, {});
|
|
3409
2052
|
*
|
|
3410
2053
|
* @param {String} event_name The name of the event. This can be anything the user does - 'Button Click', 'Sign Up', 'Item Purchased', etc.
|
|
3411
2054
|
* @param {Object} [properties] A set of properties to include with the event you're sending. These describe the user who did the event or details about the event itself.
|
|
@@ -3419,63 +2062,39 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3419
2062
|
console.error('Trying to capture event before initialization');
|
|
3420
2063
|
return;
|
|
3421
2064
|
}
|
|
3422
|
-
|
|
3423
|
-
|
|
2065
|
+
console.log(properties);
|
|
2066
|
+
if (_isUndefined(event_name) || typeof event_name !== 'string') {
|
|
2067
|
+
console.error('No event name provided to usermaven.capture');
|
|
3424
2068
|
return;
|
|
3425
2069
|
}
|
|
3426
|
-
if (_.isBlockedUA(userAgent)) {
|
|
3427
|
-
|
|
3428
|
-
}
|
|
3429
|
-
var start_timestamp = this['persistence'].remove_event_timer(event_name);
|
|
3430
|
-
// update persistence
|
|
3431
|
-
this['persistence'].update_search_keyword(document.referrer);
|
|
3432
|
-
if (this.get_config('store_google')) {
|
|
3433
|
-
this['persistence'].update_campaign_params();
|
|
3434
|
-
}
|
|
3435
|
-
if (this.get_config('save_referrer')) {
|
|
3436
|
-
this['persistence'].update_referrer_info(document.referrer);
|
|
3437
|
-
}
|
|
2070
|
+
// if (_.isBlockedUA(userAgent)) {
|
|
2071
|
+
// return
|
|
2072
|
+
// }
|
|
3438
2073
|
var data = {
|
|
3439
2074
|
event: event_name + (properties['$event_type'] ? '_' + properties['$event_type'] : ''),
|
|
3440
|
-
properties: this._calculate_event_properties(event_name, properties
|
|
2075
|
+
properties: this._calculate_event_properties(event_name, properties),
|
|
3441
2076
|
};
|
|
3442
|
-
data =
|
|
3443
|
-
// send
|
|
2077
|
+
data = _copyAndTruncateStrings(data, this.get_config('properties_string_max_length'));
|
|
2078
|
+
// send event if there is a tagname available
|
|
3444
2079
|
if ((_b = (_a = data.properties) === null || _a === void 0 ? void 0 : _a.autocapture_attributes) === null || _b === void 0 ? void 0 : _b.tag_name) {
|
|
3445
2080
|
this.track("$autocapture", data.properties);
|
|
3446
2081
|
// this.track(data.event, data.properties)
|
|
3447
2082
|
}
|
|
3448
2083
|
};
|
|
3449
|
-
UsermavenClientImpl.prototype._calculate_event_properties = function (event_name, event_properties
|
|
2084
|
+
UsermavenClientImpl.prototype._calculate_event_properties = function (event_name, event_properties) {
|
|
3450
2085
|
var _a, _b;
|
|
3451
2086
|
// set defaults
|
|
3452
2087
|
var properties = event_properties || {};
|
|
3453
2088
|
if (event_name === '$snapshot') {
|
|
3454
2089
|
return properties;
|
|
3455
2090
|
}
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
var duration_in_ms = new Date().getTime() - start_timestamp;
|
|
3459
|
-
properties['$duration'] = parseFloat((duration_in_ms / 1000).toFixed(3));
|
|
3460
|
-
}
|
|
3461
|
-
// note: extend writes to the first object, so lets make sure we
|
|
3462
|
-
// don't write to the persistence properties object and info
|
|
3463
|
-
// properties object by passing in a new object
|
|
3464
|
-
// update properties with pageview info and super-properties
|
|
3465
|
-
// exlude , _.info.properties()
|
|
3466
|
-
properties = _.extend({}, this['persistence'].properties(), properties);
|
|
3467
|
-
var property_blacklist = this.get_config('property_blacklist');
|
|
3468
|
-
if (_.isArray(property_blacklist)) {
|
|
3469
|
-
_.each(property_blacklist, function (blacklisted_prop) {
|
|
2091
|
+
if (_isArray(this.propertyBlacklist)) {
|
|
2092
|
+
_each(this.propertyBlacklist, function (blacklisted_prop) {
|
|
3470
2093
|
delete properties[blacklisted_prop];
|
|
3471
2094
|
});
|
|
3472
2095
|
}
|
|
3473
2096
|
else {
|
|
3474
|
-
console.error('Invalid value for property_blacklist config: ' +
|
|
3475
|
-
}
|
|
3476
|
-
var sanitize_properties = this.get_config('sanitize_properties');
|
|
3477
|
-
if (sanitize_properties) {
|
|
3478
|
-
properties = sanitize_properties(properties, event_name);
|
|
2097
|
+
console.error('Invalid value for property_blacklist config: ' + this.propertyBlacklist);
|
|
3479
2098
|
}
|
|
3480
2099
|
// assign first element from $elements only
|
|
3481
2100
|
var attributes = {};
|
|
@@ -3486,24 +2105,15 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3486
2105
|
properties['autocapture_attributes'] = attributes;
|
|
3487
2106
|
properties['autocapture_attributes']["el_text"] = (_a = properties['autocapture_attributes']["$el_text"]) !== null && _a !== void 0 ? _a : "";
|
|
3488
2107
|
properties['autocapture_attributes']["event_type"] = (_b = properties["$event_type"]) !== null && _b !== void 0 ? _b : "";
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
delete properties['$initial_referring_domain'];
|
|
3493
|
-
delete properties['$referrer'];
|
|
3494
|
-
delete properties['$referring_domain'];
|
|
3495
|
-
delete properties['$elements'];
|
|
2108
|
+
['$ce_version', "$event_type", "$initial_referrer", "$initial_referring_domain", "$referrer", "$referring_domain", "$elements"].forEach(function (key) {
|
|
2109
|
+
delete properties[key];
|
|
2110
|
+
});
|
|
3496
2111
|
// TODO: later remove this from the autotrack code.
|
|
3497
2112
|
delete properties['autocapture_attributes']["$el_text"];
|
|
3498
2113
|
delete properties['autocapture_attributes']["nth_child"];
|
|
3499
2114
|
delete properties['autocapture_attributes']["nth_of_type"];
|
|
3500
2115
|
return properties;
|
|
3501
2116
|
};
|
|
3502
|
-
UsermavenClientImpl.prototype._handle_unload = function () {
|
|
3503
|
-
if (this.get_config('capture_pageview')) {
|
|
3504
|
-
this.capture('$pageleave');
|
|
3505
|
-
}
|
|
3506
|
-
};
|
|
3507
2117
|
return UsermavenClientImpl;
|
|
3508
2118
|
}());
|
|
3509
2119
|
function interceptSegmentCalls(t) {
|