mixpanel-browser 2.67.0 → 2.69.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/CHANGELOG.md +5 -0
- package/dist/mixpanel-core.cjs.js +132 -6
- package/dist/mixpanel-recorder.js +186 -47
- package/dist/mixpanel-recorder.min.js +1 -1
- package/dist/mixpanel-recorder.min.js.map +1 -1
- package/dist/mixpanel-with-async-recorder.cjs.js +132 -6
- package/dist/mixpanel-with-recorder.js +308 -51
- package/dist/mixpanel-with-recorder.min.js +1 -1
- package/dist/mixpanel.amd.js +308 -51
- package/dist/mixpanel.cjs.js +308 -51
- package/dist/mixpanel.globals.js +132 -6
- package/dist/mixpanel.min.js +148 -146
- package/dist/mixpanel.module.js +308 -51
- package/dist/mixpanel.umd.js +308 -51
- package/dist/rrweb-compiled.js +190 -59
- package/package.json +14 -2
- package/rollup.config.mjs +2 -2
- package/src/autocapture/index.js +59 -1
- package/src/autocapture/rageclick.js +38 -0
- package/src/config.js +1 -1
- package/src/flags/index.js +22 -1
- package/src/index.d.ts +19 -0
- package/src/mixpanel-core.js +10 -2
- package/src/recorder/recorder.js +1 -1
- package/src/recorder/recording-registry.js +37 -2
- package/src/recorder/session-recording.js +2 -3
- package/src/request-queue.js +1 -1
- package/src/storage/indexed-db.js +4 -0
- package/src/storage/local-storage.js +4 -0
- package/src/storage/wrapper.js +1 -0
package/dist/rrweb-compiled.js
CHANGED
|
@@ -460,6 +460,30 @@ function querySelectorAll$1(n2, selectors) {
|
|
|
460
460
|
function mutationObserverCtor$1() {
|
|
461
461
|
return getUntaintedPrototype$1("MutationObserver").constructor;
|
|
462
462
|
}
|
|
463
|
+
function patch$1(source, name, replacement) {
|
|
464
|
+
try {
|
|
465
|
+
if (!(name in source)) {
|
|
466
|
+
return function() {};
|
|
467
|
+
}
|
|
468
|
+
var original = source[name];
|
|
469
|
+
var wrapped = replacement(original);
|
|
470
|
+
if (typeof wrapped === "function") {
|
|
471
|
+
wrapped.prototype = wrapped.prototype || {};
|
|
472
|
+
Object.defineProperties(wrapped, {
|
|
473
|
+
__rrweb_original__: {
|
|
474
|
+
enumerable: false,
|
|
475
|
+
value: original
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
source[name] = wrapped;
|
|
480
|
+
return function() {
|
|
481
|
+
source[name] = original;
|
|
482
|
+
};
|
|
483
|
+
} catch (e) {
|
|
484
|
+
return function() {};
|
|
485
|
+
}
|
|
486
|
+
}
|
|
463
487
|
var index$1 = {
|
|
464
488
|
childNodes: childNodes$1,
|
|
465
489
|
parentNode: parentNode$1,
|
|
@@ -472,7 +496,8 @@ var index$1 = {
|
|
|
472
496
|
shadowRoot: shadowRoot$1,
|
|
473
497
|
querySelector: querySelector$1,
|
|
474
498
|
querySelectorAll: querySelectorAll$1,
|
|
475
|
-
mutationObserver: mutationObserverCtor$1
|
|
499
|
+
mutationObserver: mutationObserverCtor$1,
|
|
500
|
+
patch: patch$1
|
|
476
501
|
};
|
|
477
502
|
function isElement(n2) {
|
|
478
503
|
return n2.nodeType === n2.ELEMENT_NODE;
|
|
@@ -731,26 +756,82 @@ function absolutifyURLs(cssText, href) {
|
|
|
731
756
|
return "url(" + maybeQuote + stack.join("/") + maybeQuote + ")";
|
|
732
757
|
});
|
|
733
758
|
}
|
|
734
|
-
function normalizeCssString(cssText) {
|
|
735
|
-
|
|
759
|
+
function normalizeCssString(cssText, _testNoPxNorm) {
|
|
760
|
+
if (_testNoPxNorm === void 0) _testNoPxNorm = false;
|
|
761
|
+
if (_testNoPxNorm) {
|
|
762
|
+
return cssText.replace(/(\/\*[^*]*\*\/)|[\s;]/g, "");
|
|
763
|
+
} else {
|
|
764
|
+
return cssText.replace(/(\/\*[^*]*\*\/)|[\s;]/g, "").replace(/0px/g, "0");
|
|
765
|
+
}
|
|
736
766
|
}
|
|
737
|
-
function splitCssText(cssText, style) {
|
|
767
|
+
function splitCssText(cssText, style, _testNoPxNorm) {
|
|
768
|
+
if (_testNoPxNorm === void 0) _testNoPxNorm = false;
|
|
738
769
|
var childNodes2 = Array.from(style.childNodes);
|
|
739
770
|
var splits = [];
|
|
771
|
+
var iterCount = 0;
|
|
740
772
|
if (childNodes2.length > 1 && cssText && typeof cssText === "string") {
|
|
741
|
-
var cssTextNorm = normalizeCssString(cssText);
|
|
773
|
+
var cssTextNorm = normalizeCssString(cssText, _testNoPxNorm);
|
|
774
|
+
var normFactor = cssTextNorm.length / cssText.length;
|
|
742
775
|
for(var i2 = 1; i2 < childNodes2.length; i2++){
|
|
743
776
|
if (childNodes2[i2].textContent && typeof childNodes2[i2].textContent === "string") {
|
|
744
|
-
var textContentNorm = normalizeCssString(childNodes2[i2].textContent);
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
777
|
+
var textContentNorm = normalizeCssString(childNodes2[i2].textContent, _testNoPxNorm);
|
|
778
|
+
var jLimit = 100;
|
|
779
|
+
var j = 3;
|
|
780
|
+
for(; j < textContentNorm.length; j++){
|
|
781
|
+
if (// keep consuming css identifiers (to get a decent chunk more quickly)
|
|
782
|
+
textContentNorm[j].match(/[a-zA-Z0-9]/) || // substring needs to be unique to this section
|
|
783
|
+
textContentNorm.indexOf(textContentNorm.substring(0, j), 1) !== -1) {
|
|
784
|
+
continue;
|
|
785
|
+
}
|
|
786
|
+
break;
|
|
787
|
+
}
|
|
788
|
+
for(; j < textContentNorm.length; j++){
|
|
789
|
+
var startSubstring = textContentNorm.substring(0, j);
|
|
790
|
+
var cssNormSplits = cssTextNorm.split(startSubstring);
|
|
791
|
+
var splitNorm = -1;
|
|
792
|
+
if (cssNormSplits.length === 2) {
|
|
793
|
+
splitNorm = cssNormSplits[0].length;
|
|
794
|
+
} else if (cssNormSplits.length > 2 && cssNormSplits[0] === "" && childNodes2[i2 - 1].textContent !== "") {
|
|
795
|
+
splitNorm = cssTextNorm.indexOf(startSubstring, 1);
|
|
796
|
+
} else if (cssNormSplits.length === 1) {
|
|
797
|
+
startSubstring = startSubstring.substring(0, startSubstring.length - 1);
|
|
798
|
+
cssNormSplits = cssTextNorm.split(startSubstring);
|
|
799
|
+
if (cssNormSplits.length <= 1) {
|
|
800
|
+
splits.push(cssText);
|
|
801
|
+
return splits;
|
|
802
|
+
}
|
|
803
|
+
j = jLimit + 1;
|
|
804
|
+
} else if (j === textContentNorm.length - 1) {
|
|
805
|
+
splitNorm = cssTextNorm.indexOf(startSubstring);
|
|
806
|
+
}
|
|
807
|
+
if (cssNormSplits.length >= 2 && j > jLimit) {
|
|
808
|
+
var prevTextContent = childNodes2[i2 - 1].textContent;
|
|
809
|
+
if (prevTextContent && typeof prevTextContent === "string") {
|
|
810
|
+
var prevMinLength = normalizeCssString(prevTextContent).length;
|
|
811
|
+
splitNorm = cssTextNorm.indexOf(startSubstring, prevMinLength);
|
|
812
|
+
}
|
|
813
|
+
if (splitNorm === -1) {
|
|
814
|
+
splitNorm = cssNormSplits[0].length;
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
if (splitNorm !== -1) {
|
|
818
|
+
var k = Math.floor(splitNorm / normFactor);
|
|
819
|
+
for(; k > 0 && k < cssText.length;){
|
|
820
|
+
iterCount += 1;
|
|
821
|
+
if (iterCount > 50 * childNodes2.length) {
|
|
822
|
+
splits.push(cssText);
|
|
823
|
+
return splits;
|
|
824
|
+
}
|
|
825
|
+
var normPart = normalizeCssString(cssText.substring(0, k), _testNoPxNorm);
|
|
826
|
+
if (normPart.length === splitNorm) {
|
|
751
827
|
splits.push(cssText.substring(0, k));
|
|
752
828
|
cssText = cssText.substring(k);
|
|
829
|
+
cssTextNorm = cssTextNorm.substring(splitNorm);
|
|
753
830
|
break;
|
|
831
|
+
} else if (normPart.length < splitNorm) {
|
|
832
|
+
k += Math.max(1, Math.floor((splitNorm - normPart.length) / normFactor));
|
|
833
|
+
} else {
|
|
834
|
+
k -= Math.max(1, Math.floor((normPart.length - splitNorm) * normFactor));
|
|
754
835
|
}
|
|
755
836
|
}
|
|
756
837
|
break;
|
|
@@ -1267,7 +1348,7 @@ function slimDOMExcluded(sn, slimDOMOptions) {
|
|
|
1267
1348
|
} else if (sn.type === NodeType$3.Element) {
|
|
1268
1349
|
if (slimDOMOptions.script && // script tag
|
|
1269
1350
|
(sn.tagName === "script" || // (module)preload link
|
|
1270
|
-
sn.tagName === "link" && (sn.attributes.rel === "preload"
|
|
1351
|
+
sn.tagName === "link" && (sn.attributes.rel === "preload" && sn.attributes.as === "script" || sn.attributes.rel === "modulepreload") || // prefetch link
|
|
1271
1352
|
sn.tagName === "link" && sn.attributes.rel === "prefetch" && typeof sn.attributes.href === "string" && extractFileExtension(sn.attributes.href) === "js")) {
|
|
1272
1353
|
return true;
|
|
1273
1354
|
} else if (slimDOMOptions.headFavicon && (sn.tagName === "link" && sn.attributes.rel === "shortcut icon" || sn.tagName === "meta" && (lowerIfExists(sn.attributes.name).match(/^msapplication-tile(image|color)$/) || lowerIfExists(sn.attributes.name) === "application-name" || lowerIfExists(sn.attributes.rel) === "icon" || lowerIfExists(sn.attributes.rel) === "apple-touch-icon" || lowerIfExists(sn.attributes.rel) === "shortcut icon"))) {
|
|
@@ -5764,11 +5845,16 @@ function getTagName(n2) {
|
|
|
5764
5845
|
function adaptCssForReplay(cssText, cache) {
|
|
5765
5846
|
var cachedStyle = cache == null ? void 0 : cache.stylesWithHoverClass.get(cssText);
|
|
5766
5847
|
if (cachedStyle) return cachedStyle;
|
|
5767
|
-
var
|
|
5768
|
-
|
|
5769
|
-
|
|
5770
|
-
|
|
5771
|
-
|
|
5848
|
+
var result2 = cssText;
|
|
5849
|
+
try {
|
|
5850
|
+
var ast = postcss$1$1([
|
|
5851
|
+
mediaSelectorPlugin,
|
|
5852
|
+
pseudoClassPlugin
|
|
5853
|
+
]).process(cssText);
|
|
5854
|
+
result2 = ast.css;
|
|
5855
|
+
} catch (error) {
|
|
5856
|
+
console.warn("Failed to adapt css for replay", error);
|
|
5857
|
+
}
|
|
5772
5858
|
cache == null ? void 0 : cache.stylesWithHoverClass.set(cssText, result2);
|
|
5773
5859
|
return result2;
|
|
5774
5860
|
}
|
|
@@ -5790,11 +5876,39 @@ function applyCssSplits(n2, cssText, hackCss, cache) {
|
|
|
5790
5876
|
while(cssTextSplits.length > 1 && cssTextSplits.length > childTextNodes.length){
|
|
5791
5877
|
cssTextSplits.splice(-2, 2, cssTextSplits.slice(-2).join(""));
|
|
5792
5878
|
}
|
|
5879
|
+
var adaptedCss = "";
|
|
5880
|
+
if (hackCss) {
|
|
5881
|
+
adaptedCss = adaptCssForReplay(cssTextSplits.join(""), cache);
|
|
5882
|
+
}
|
|
5883
|
+
var startIndex = 0;
|
|
5793
5884
|
for(var i2 = 0; i2 < childTextNodes.length; i2++){
|
|
5885
|
+
if (i2 === cssTextSplits.length) {
|
|
5886
|
+
break;
|
|
5887
|
+
}
|
|
5794
5888
|
var childTextNode = childTextNodes[i2];
|
|
5795
|
-
|
|
5796
|
-
|
|
5797
|
-
|
|
5889
|
+
if (!hackCss) {
|
|
5890
|
+
childTextNode.textContent = cssTextSplits[i2];
|
|
5891
|
+
} else if (i2 < cssTextSplits.length - 1) {
|
|
5892
|
+
var endIndex = startIndex;
|
|
5893
|
+
var endSearch = cssTextSplits[i2 + 1].length;
|
|
5894
|
+
endSearch = Math.min(endSearch, 30);
|
|
5895
|
+
var found = false;
|
|
5896
|
+
for(; endSearch > 2; endSearch--){
|
|
5897
|
+
var searchBit = cssTextSplits[i2 + 1].substring(0, endSearch);
|
|
5898
|
+
var searchIndex = adaptedCss.substring(startIndex).indexOf(searchBit);
|
|
5899
|
+
found = searchIndex !== -1;
|
|
5900
|
+
if (found) {
|
|
5901
|
+
endIndex += searchIndex;
|
|
5902
|
+
break;
|
|
5903
|
+
}
|
|
5904
|
+
}
|
|
5905
|
+
if (!found) {
|
|
5906
|
+
endIndex += cssTextSplits[i2].length;
|
|
5907
|
+
}
|
|
5908
|
+
childTextNode.textContent = adaptedCss.substring(startIndex, endIndex);
|
|
5909
|
+
startIndex = endIndex;
|
|
5910
|
+
} else {
|
|
5911
|
+
childTextNode.textContent = adaptedCss.substring(startIndex);
|
|
5798
5912
|
}
|
|
5799
5913
|
}
|
|
5800
5914
|
}
|
|
@@ -5918,7 +6032,7 @@ function buildNode(n2, options) {
|
|
|
5918
6032
|
} else if (tagName === "meta" && n2.attributes["http-equiv"] === "Content-Security-Policy" && name === "content") {
|
|
5919
6033
|
node2.setAttribute("csp-content", value.toString());
|
|
5920
6034
|
continue;
|
|
5921
|
-
} else if (tagName === "link" && (n2.attributes.rel === "preload"
|
|
6035
|
+
} else if (tagName === "link" && (n2.attributes.rel === "preload" && n2.attributes.as === "script" || n2.attributes.rel === "modulepreload")) {} else if (tagName === "link" && n2.attributes.rel === "prefetch" && typeof n2.attributes.href === "string" && extractFileExtension(n2.attributes.href) === "js") {} else if (tagName === "img" && n2.attributes.srcset && n2.attributes.rr_dataURL) {
|
|
5922
6036
|
node2.setAttribute("rrweb-original-srcset", n2.attributes.srcset);
|
|
5923
6037
|
} else {
|
|
5924
6038
|
node2.setAttribute(name, value.toString());
|
|
@@ -11791,6 +11905,30 @@ function querySelectorAll(n2, selectors) {
|
|
|
11791
11905
|
function mutationObserverCtor() {
|
|
11792
11906
|
return getUntaintedPrototype("MutationObserver").constructor;
|
|
11793
11907
|
}
|
|
11908
|
+
function patch(source, name, replacement) {
|
|
11909
|
+
try {
|
|
11910
|
+
if (!(name in source)) {
|
|
11911
|
+
return function() {};
|
|
11912
|
+
}
|
|
11913
|
+
var original = source[name];
|
|
11914
|
+
var wrapped = replacement(original);
|
|
11915
|
+
if (typeof wrapped === "function") {
|
|
11916
|
+
wrapped.prototype = wrapped.prototype || {};
|
|
11917
|
+
Object.defineProperties(wrapped, {
|
|
11918
|
+
__rrweb_original__: {
|
|
11919
|
+
enumerable: false,
|
|
11920
|
+
value: original
|
|
11921
|
+
}
|
|
11922
|
+
});
|
|
11923
|
+
}
|
|
11924
|
+
source[name] = wrapped;
|
|
11925
|
+
return function() {
|
|
11926
|
+
source[name] = original;
|
|
11927
|
+
};
|
|
11928
|
+
} catch (e) {
|
|
11929
|
+
return function() {};
|
|
11930
|
+
}
|
|
11931
|
+
}
|
|
11794
11932
|
var index = {
|
|
11795
11933
|
childNodes: childNodes,
|
|
11796
11934
|
parentNode: parentNode,
|
|
@@ -11803,7 +11941,8 @@ var index = {
|
|
|
11803
11941
|
shadowRoot: shadowRoot,
|
|
11804
11942
|
querySelector: querySelector,
|
|
11805
11943
|
querySelectorAll: querySelectorAll,
|
|
11806
|
-
mutationObserver: mutationObserverCtor
|
|
11944
|
+
mutationObserver: mutationObserverCtor,
|
|
11945
|
+
patch: patch
|
|
11807
11946
|
};
|
|
11808
11947
|
function on(type, fn, target) {
|
|
11809
11948
|
if (target === void 0) target = document;
|
|
@@ -11896,30 +12035,6 @@ function hookSetter(target, key, d, isRevoked, win) {
|
|
|
11896
12035
|
return hookSetter(target, key, original || {}, true);
|
|
11897
12036
|
};
|
|
11898
12037
|
}
|
|
11899
|
-
function patch(source, name, replacement) {
|
|
11900
|
-
try {
|
|
11901
|
-
if (!(name in source)) {
|
|
11902
|
-
return function() {};
|
|
11903
|
-
}
|
|
11904
|
-
var original = source[name];
|
|
11905
|
-
var wrapped = replacement(original);
|
|
11906
|
-
if (typeof wrapped === "function") {
|
|
11907
|
-
wrapped.prototype = wrapped.prototype || {};
|
|
11908
|
-
Object.defineProperties(wrapped, {
|
|
11909
|
-
__rrweb_original__: {
|
|
11910
|
-
enumerable: false,
|
|
11911
|
-
value: original
|
|
11912
|
-
}
|
|
11913
|
-
});
|
|
11914
|
-
}
|
|
11915
|
-
source[name] = wrapped;
|
|
11916
|
-
return function() {
|
|
11917
|
-
source[name] = original;
|
|
11918
|
-
};
|
|
11919
|
-
} catch (e) {
|
|
11920
|
-
return function() {};
|
|
11921
|
-
}
|
|
11922
|
-
}
|
|
11923
12038
|
var nowTimestamp = Date.now;
|
|
11924
12039
|
if (!/* @__PURE__ */ /[1-9][0-9]{12}/.test(Date.now().toString())) {
|
|
11925
12040
|
nowTimestamp = function() {
|
|
@@ -12202,7 +12317,6 @@ var utils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty(
|
|
|
12202
12317
|
return nowTimestamp;
|
|
12203
12318
|
},
|
|
12204
12319
|
on: on,
|
|
12205
|
-
patch: patch,
|
|
12206
12320
|
polyfill: polyfill$1,
|
|
12207
12321
|
queueToResolveTrees: queueToResolveTrees,
|
|
12208
12322
|
shadowHostInDom: shadowHostInDom,
|
|
@@ -12659,9 +12773,17 @@ var MutationBuffer = /*#__PURE__*/ function() {
|
|
|
12659
12773
|
_this.attributes.push(item);
|
|
12660
12774
|
_this.attributeMap.set(textarea, item);
|
|
12661
12775
|
}
|
|
12662
|
-
|
|
12776
|
+
var value = Array.from(index.childNodes(textarea), function(cn) {
|
|
12663
12777
|
return index.textContent(cn) || "";
|
|
12664
12778
|
}).join("");
|
|
12779
|
+
item.attributes.value = maskInputValue({
|
|
12780
|
+
element: textarea,
|
|
12781
|
+
maskInputOptions: _this.maskInputOptions,
|
|
12782
|
+
tagName: textarea.tagName,
|
|
12783
|
+
type: getInputType(textarea),
|
|
12784
|
+
value: value,
|
|
12785
|
+
maskInputFn: _this.maskInputFn
|
|
12786
|
+
});
|
|
12665
12787
|
});
|
|
12666
12788
|
__publicField(this, "processMutation", function(m) {
|
|
12667
12789
|
if (isIgnored(m.target, _this.mirror, _this.slimDOMOptions)) {
|
|
@@ -15462,8 +15584,15 @@ function record(options) {
|
|
|
15462
15584
|
}, window));
|
|
15463
15585
|
}
|
|
15464
15586
|
return function() {
|
|
15465
|
-
handlers.forEach(function(
|
|
15466
|
-
|
|
15587
|
+
handlers.forEach(function(handler) {
|
|
15588
|
+
try {
|
|
15589
|
+
handler();
|
|
15590
|
+
} catch (error) {
|
|
15591
|
+
var msg = String(error).toLowerCase();
|
|
15592
|
+
if (!msg.includes("cross-origin")) {
|
|
15593
|
+
console.warn(error);
|
|
15594
|
+
}
|
|
15595
|
+
}
|
|
15467
15596
|
});
|
|
15468
15597
|
processedNodeManager.destroy();
|
|
15469
15598
|
recording = false;
|
|
@@ -17093,21 +17222,21 @@ var Replayer = /*#__PURE__*/ function() {
|
|
|
17093
17222
|
event: event
|
|
17094
17223
|
}
|
|
17095
17224
|
});
|
|
17096
|
-
var
|
|
17097
|
-
if (!_this.config.liveMode && event === _this.service.state.context.events[
|
|
17225
|
+
var lastIndex = _this.service.state.context.events.length - 1;
|
|
17226
|
+
if (!_this.config.liveMode && event === _this.service.state.context.events[lastIndex]) {
|
|
17098
17227
|
var finish = function() {
|
|
17099
|
-
if (
|
|
17228
|
+
if (lastIndex < _this.service.state.context.events.length - 1) {
|
|
17100
17229
|
return;
|
|
17101
17230
|
}
|
|
17102
17231
|
_this.backToNormal();
|
|
17103
17232
|
_this.service.send("END");
|
|
17104
17233
|
_this.emitter.emit(ReplayerEvents.Finish);
|
|
17105
17234
|
};
|
|
17106
|
-
var
|
|
17235
|
+
var finishBuffer = 50;
|
|
17107
17236
|
if (event.type === EventType.IncrementalSnapshot && event.data.source === IncrementalSource.MouseMove && event.data.positions.length) {
|
|
17108
|
-
|
|
17237
|
+
finishBuffer += Math.max(0, -event.data.positions[0].timeOffset);
|
|
17109
17238
|
}
|
|
17110
|
-
setTimeout(finish,
|
|
17239
|
+
setTimeout(finish, finishBuffer);
|
|
17111
17240
|
}
|
|
17112
17241
|
_this.emitter.emit(ReplayerEvents.EventCast, event);
|
|
17113
17242
|
};
|
|
@@ -18300,8 +18429,9 @@ var Replayer = /*#__PURE__*/ function() {
|
|
|
18300
18429
|
if (attributeName === "_cssText" && (target.nodeName === "LINK" || target.nodeName === "STYLE")) {
|
|
18301
18430
|
try {
|
|
18302
18431
|
var newSn = mirror2.getMeta(target);
|
|
18303
|
-
|
|
18304
|
-
|
|
18432
|
+
var newNode = buildNodeWithSN(_extends({}, newSn, {
|
|
18433
|
+
attributes: _extends({}, newSn.attributes, mutation.attributes)
|
|
18434
|
+
}), {
|
|
18305
18435
|
doc: target.ownerDocument,
|
|
18306
18436
|
// can be Document or RRDocument
|
|
18307
18437
|
mirror: mirror2,
|
|
@@ -18309,6 +18439,7 @@ var Replayer = /*#__PURE__*/ function() {
|
|
|
18309
18439
|
hackCss: true,
|
|
18310
18440
|
cache: _this.cache
|
|
18311
18441
|
});
|
|
18442
|
+
Object.assign(newSn.attributes, mutation.attributes);
|
|
18312
18443
|
var siblingNode = target.nextSibling;
|
|
18313
18444
|
var parentNode2 = target.parentNode;
|
|
18314
18445
|
if (newNode && parentNode2) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mixpanel-browser",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.69.0",
|
|
4
4
|
"description": "The official Mixpanel JavaScript browser client library",
|
|
5
5
|
"main": "dist/mixpanel.cjs.js",
|
|
6
6
|
"module": "dist/mixpanel.module.js",
|
|
@@ -23,6 +23,18 @@
|
|
|
23
23
|
"validate": "npm ls"
|
|
24
24
|
},
|
|
25
25
|
"types": "./src/index.d.ts",
|
|
26
|
+
"exports": {
|
|
27
|
+
"./src/loaders/loader-module-core": {
|
|
28
|
+
"types": "./src/index.d.ts",
|
|
29
|
+
"import": "./src/loaders/loader-module-core.js",
|
|
30
|
+
"require": "./src/loaders/loader-module-core.js"
|
|
31
|
+
},
|
|
32
|
+
"./src/loaders/loader-module-with-async-recorder": {
|
|
33
|
+
"types": "./src/index.d.ts",
|
|
34
|
+
"import": "./src/loaders/loader-module-with-async-recorder.js",
|
|
35
|
+
"require": "./src/loaders/loader-module-with-async-recorder.js"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
26
38
|
"repository": {
|
|
27
39
|
"type": "git",
|
|
28
40
|
"url": "https://github.com/mixpanel/mixpanel-js.git"
|
|
@@ -66,6 +78,6 @@
|
|
|
66
78
|
"webpack": "1.12.2"
|
|
67
79
|
},
|
|
68
80
|
"dependencies": {
|
|
69
|
-
"rrweb": "2.0.0-alpha.18"
|
|
81
|
+
"@mixpanel/rrweb": "2.0.0-alpha.18.1"
|
|
70
82
|
}
|
|
71
83
|
}
|
package/rollup.config.mjs
CHANGED
|
@@ -8,7 +8,7 @@ const COMPILED_RRWEB_PATH = 'build/rrweb-compiled.js';
|
|
|
8
8
|
|
|
9
9
|
const aliasRrweb = () => alias({
|
|
10
10
|
entries: [
|
|
11
|
-
{ find: 'rrweb', replacement: COMPILED_RRWEB_PATH },
|
|
11
|
+
{ find: '@mixpanel/rrweb', replacement: COMPILED_RRWEB_PATH },
|
|
12
12
|
]
|
|
13
13
|
});
|
|
14
14
|
|
|
@@ -24,7 +24,7 @@ const MINIFY = process.env.MINIFY || process.env.FULL;
|
|
|
24
24
|
const MAIN_BUILDS = [
|
|
25
25
|
// compile rrweb first to es5 with swc, we'll replace the import later on
|
|
26
26
|
{
|
|
27
|
-
'input': 'rrweb',
|
|
27
|
+
'input': '@mixpanel/rrweb',
|
|
28
28
|
'output': [
|
|
29
29
|
{
|
|
30
30
|
file: COMPILED_RRWEB_PATH,
|
package/src/autocapture/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
EV_CHANGE, EV_CLICK, EV_HASHCHANGE, EV_MP_LOCATION_CHANGE, EV_POPSTATE,
|
|
6
6
|
EV_SCROLLEND, EV_SUBMIT
|
|
7
7
|
} from './utils';
|
|
8
|
+
import { RageClickTracker } from './rageclick';
|
|
8
9
|
|
|
9
10
|
var AUTOCAPTURE_CONFIG_KEY = 'autocapture';
|
|
10
11
|
var LEGACY_PAGEVIEW_CONFIG_KEY = 'track_pageview';
|
|
@@ -27,6 +28,7 @@ var CONFIG_SCROLL_CHECKPOINTS = 'scroll_depth_percent_checkpoints';
|
|
|
27
28
|
var CONFIG_TRACK_CLICK = 'click';
|
|
28
29
|
var CONFIG_TRACK_INPUT = 'input';
|
|
29
30
|
var CONFIG_TRACK_PAGEVIEW = 'pageview';
|
|
31
|
+
var CONFIG_TRACK_RAGE_CLICK = 'rage_click';
|
|
30
32
|
var CONFIG_TRACK_SCROLL = 'scroll';
|
|
31
33
|
var CONFIG_TRACK_SUBMIT = 'submit';
|
|
32
34
|
|
|
@@ -44,6 +46,7 @@ CONFIG_DEFAULTS[CONFIG_SCROLL_CHECKPOINTS] = [25, 50, 75, 100];
|
|
|
44
46
|
CONFIG_DEFAULTS[CONFIG_TRACK_CLICK] = true;
|
|
45
47
|
CONFIG_DEFAULTS[CONFIG_TRACK_INPUT] = true;
|
|
46
48
|
CONFIG_DEFAULTS[CONFIG_TRACK_PAGEVIEW] = PAGEVIEW_OPTION_FULL_URL;
|
|
49
|
+
CONFIG_DEFAULTS[CONFIG_TRACK_RAGE_CLICK] = true;
|
|
47
50
|
CONFIG_DEFAULTS[CONFIG_TRACK_SCROLL] = true;
|
|
48
51
|
CONFIG_DEFAULTS[CONFIG_TRACK_SUBMIT] = true;
|
|
49
52
|
|
|
@@ -53,6 +56,7 @@ var DEFAULT_PROPS = {
|
|
|
53
56
|
|
|
54
57
|
var MP_EV_CLICK = '$mp_click';
|
|
55
58
|
var MP_EV_INPUT = '$mp_input_change';
|
|
59
|
+
var MP_EV_RAGE_CLICK = '$mp_rage_click';
|
|
56
60
|
var MP_EV_SCROLL = '$mp_scroll';
|
|
57
61
|
var MP_EV_SUBMIT = '$mp_submit';
|
|
58
62
|
|
|
@@ -75,6 +79,7 @@ Autocapture.prototype.init = function() {
|
|
|
75
79
|
this.initInputTracking();
|
|
76
80
|
this.initScrollTracking();
|
|
77
81
|
this.initSubmitTracking();
|
|
82
|
+
this.initRageClickTracking();
|
|
78
83
|
};
|
|
79
84
|
|
|
80
85
|
Autocapture.prototype.getFullConfig = function() {
|
|
@@ -153,6 +158,11 @@ Autocapture.prototype.trackDomEvent = function(ev, mpEventName) {
|
|
|
153
158
|
return;
|
|
154
159
|
}
|
|
155
160
|
|
|
161
|
+
var isCapturedForHeatMap = this.mp.is_recording_heatmap_data() && (
|
|
162
|
+
(mpEventName === MP_EV_CLICK && !this.getConfig(CONFIG_TRACK_CLICK)) ||
|
|
163
|
+
(mpEventName === MP_EV_RAGE_CLICK && !this._getRageClickConfig())
|
|
164
|
+
);
|
|
165
|
+
|
|
156
166
|
var props = getPropsForDOMEvent(ev, {
|
|
157
167
|
allowElementCallback: this.getConfig(CONFIG_ALLOW_ELEMENT_CALLBACK),
|
|
158
168
|
allowSelectors: this.getConfig(CONFIG_ALLOW_SELECTORS),
|
|
@@ -161,7 +171,7 @@ Autocapture.prototype.trackDomEvent = function(ev, mpEventName) {
|
|
|
161
171
|
blockSelectors: this.getConfig(CONFIG_BLOCK_SELECTORS),
|
|
162
172
|
captureExtraAttrs: this.getConfig(CONFIG_CAPTURE_EXTRA_ATTRS),
|
|
163
173
|
captureTextContent: this.getConfig(CONFIG_CAPTURE_TEXT_CONTENT),
|
|
164
|
-
capturedForHeatMap:
|
|
174
|
+
capturedForHeatMap: isCapturedForHeatMap,
|
|
165
175
|
});
|
|
166
176
|
if (props) {
|
|
167
177
|
_.extend(props, DEFAULT_PROPS);
|
|
@@ -169,6 +179,24 @@ Autocapture.prototype.trackDomEvent = function(ev, mpEventName) {
|
|
|
169
179
|
}
|
|
170
180
|
};
|
|
171
181
|
|
|
182
|
+
Autocapture.prototype._getRageClickConfig = function() {
|
|
183
|
+
var config = this.getConfig(CONFIG_TRACK_RAGE_CLICK);
|
|
184
|
+
|
|
185
|
+
if (!config) {
|
|
186
|
+
return null; // rage click tracking disabled
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (config === true) {
|
|
190
|
+
return {}; // use defaults
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (typeof config === 'object') {
|
|
194
|
+
return config; // use custom configuration
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return {}; // fallback to defaults for any other truthy value
|
|
198
|
+
};
|
|
199
|
+
|
|
172
200
|
Autocapture.prototype.initClickTracking = function() {
|
|
173
201
|
window.removeEventListener(EV_CLICK, this.listenerClick);
|
|
174
202
|
|
|
@@ -270,6 +298,36 @@ Autocapture.prototype.initPageviewTracking = function() {
|
|
|
270
298
|
}.bind(this)));
|
|
271
299
|
};
|
|
272
300
|
|
|
301
|
+
Autocapture.prototype.initRageClickTracking = function() {
|
|
302
|
+
window.removeEventListener(EV_CLICK, this.listenerRageClick);
|
|
303
|
+
|
|
304
|
+
var rageClickConfig = this._getRageClickConfig();
|
|
305
|
+
if (!rageClickConfig && !this.mp.get_config('record_heatmap_data')) {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
logger.log('Initializing rage click tracking');
|
|
310
|
+
if (!this._rageClickTracker) {
|
|
311
|
+
this._rageClickTracker = new RageClickTracker();
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
this.listenerRageClick = function(ev) {
|
|
315
|
+
var currentRageClickConfig = this._getRageClickConfig();
|
|
316
|
+
if (!currentRageClickConfig && !this.mp.is_recording_heatmap_data()) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (this.currentUrlBlocked()) {
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (this._rageClickTracker.isRageClick(ev['pageX'], ev['pageY'], currentRageClickConfig)) {
|
|
325
|
+
this.trackDomEvent(ev, MP_EV_RAGE_CLICK);
|
|
326
|
+
}
|
|
327
|
+
}.bind(this);
|
|
328
|
+
window.addEventListener(EV_CLICK, this.listenerRageClick);
|
|
329
|
+
};
|
|
330
|
+
|
|
273
331
|
Autocapture.prototype.initScrollTracking = function() {
|
|
274
332
|
window.removeEventListener(EV_SCROLLEND, this.listenerScroll);
|
|
275
333
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** @const */ var DEFAULT_RAGE_CLICK_THRESHOLD_PX = 30;
|
|
2
|
+
/** @const */ var DEFAULT_RAGE_CLICK_TIMEOUT_MS = 1000;
|
|
3
|
+
/** @const */ var DEFAULT_RAGE_CLICK_CLICK_COUNT = 4;
|
|
4
|
+
|
|
5
|
+
function RageClickTracker() {
|
|
6
|
+
this.clicks = [];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
RageClickTracker.prototype.isRageClick = function(x, y, options) {
|
|
10
|
+
options = options || {};
|
|
11
|
+
var thresholdPx = options['threshold_px'] || DEFAULT_RAGE_CLICK_THRESHOLD_PX;
|
|
12
|
+
var timeoutMs = options['timeout_ms'] || DEFAULT_RAGE_CLICK_TIMEOUT_MS;
|
|
13
|
+
var clickCount = options['click_count'] || DEFAULT_RAGE_CLICK_CLICK_COUNT;
|
|
14
|
+
var timestamp = Date.now();
|
|
15
|
+
|
|
16
|
+
var lastClick = this.clicks[this.clicks.length - 1];
|
|
17
|
+
if (
|
|
18
|
+
lastClick &&
|
|
19
|
+
timestamp - lastClick.timestamp < timeoutMs &&
|
|
20
|
+
Math.sqrt(Math.pow(x - lastClick.x, 2) + Math.pow(y - lastClick.y, 2)) < thresholdPx
|
|
21
|
+
) {
|
|
22
|
+
this.clicks.push({ x: x, y: y, timestamp: timestamp });
|
|
23
|
+
if (this.clicks.length >= clickCount) {
|
|
24
|
+
this.clicks = [];
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
this.clicks = [{ x: x, y: y, timestamp: timestamp }];
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export {
|
|
34
|
+
RageClickTracker,
|
|
35
|
+
DEFAULT_RAGE_CLICK_THRESHOLD_PX,
|
|
36
|
+
DEFAULT_RAGE_CLICK_TIMEOUT_MS,
|
|
37
|
+
DEFAULT_RAGE_CLICK_CLICK_COUNT
|
|
38
|
+
};
|
package/src/config.js
CHANGED
package/src/flags/index.js
CHANGED
|
@@ -17,6 +17,7 @@ CONFIG_DEFAULTS[CONFIG_CONTEXT] = {};
|
|
|
17
17
|
var FeatureFlagManager = function(initOptions) {
|
|
18
18
|
this.getFullApiRoute = initOptions.getFullApiRoute;
|
|
19
19
|
this.getMpConfig = initOptions.getConfigFunc;
|
|
20
|
+
this.setMpConfig = initOptions.setConfigFunc;
|
|
20
21
|
this.getMpProperty = initOptions.getPropertyFunc;
|
|
21
22
|
this.track = initOptions.trackingFunc;
|
|
22
23
|
};
|
|
@@ -54,6 +55,23 @@ FeatureFlagManager.prototype.isSystemEnabled = function() {
|
|
|
54
55
|
return !!this.getMpConfig(FLAGS_CONFIG_KEY);
|
|
55
56
|
};
|
|
56
57
|
|
|
58
|
+
FeatureFlagManager.prototype.updateContext = function(newContext, options) {
|
|
59
|
+
if (!this.isSystemEnabled()) {
|
|
60
|
+
logger.critical('Feature Flags not enabled, cannot update context');
|
|
61
|
+
return Promise.resolve();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
var ffConfig = this.getMpConfig(FLAGS_CONFIG_KEY);
|
|
65
|
+
if (!_.isObject(ffConfig)) {
|
|
66
|
+
ffConfig = {};
|
|
67
|
+
}
|
|
68
|
+
var oldContext = (options && options['replace']) ? {} : this.getConfig(CONFIG_CONTEXT);
|
|
69
|
+
ffConfig[CONFIG_CONTEXT] = _.extend({}, oldContext, newContext);
|
|
70
|
+
|
|
71
|
+
this.setMpConfig(FLAGS_CONFIG_KEY, ffConfig);
|
|
72
|
+
return this.fetchFlags();
|
|
73
|
+
};
|
|
74
|
+
|
|
57
75
|
FeatureFlagManager.prototype.areFlagsReady = function() {
|
|
58
76
|
if (!this.isSystemEnabled()) {
|
|
59
77
|
logger.error('Feature Flags not enabled');
|
|
@@ -63,7 +81,7 @@ FeatureFlagManager.prototype.areFlagsReady = function() {
|
|
|
63
81
|
|
|
64
82
|
FeatureFlagManager.prototype.fetchFlags = function() {
|
|
65
83
|
if (!this.isSystemEnabled()) {
|
|
66
|
-
return;
|
|
84
|
+
return Promise.resolve();
|
|
67
85
|
}
|
|
68
86
|
|
|
69
87
|
var distinctId = this.getMpProperty('distinct_id');
|
|
@@ -103,6 +121,8 @@ FeatureFlagManager.prototype.fetchFlags = function() {
|
|
|
103
121
|
this.markFetchComplete();
|
|
104
122
|
logger.error(error);
|
|
105
123
|
}.bind(this));
|
|
124
|
+
|
|
125
|
+
return this.fetchPromise;
|
|
106
126
|
};
|
|
107
127
|
|
|
108
128
|
FeatureFlagManager.prototype.markFetchComplete = function() {
|
|
@@ -215,6 +235,7 @@ FeatureFlagManager.prototype['get_variant_value'] = FeatureFlagManager.prototype
|
|
|
215
235
|
FeatureFlagManager.prototype['get_variant_value_sync'] = FeatureFlagManager.prototype.getVariantValueSync;
|
|
216
236
|
FeatureFlagManager.prototype['is_enabled'] = FeatureFlagManager.prototype.isEnabled;
|
|
217
237
|
FeatureFlagManager.prototype['is_enabled_sync'] = FeatureFlagManager.prototype.isEnabledSync;
|
|
238
|
+
FeatureFlagManager.prototype['update_context'] = FeatureFlagManager.prototype.updateContext;
|
|
218
239
|
|
|
219
240
|
// Deprecated method
|
|
220
241
|
FeatureFlagManager.prototype['get_feature_data'] = FeatureFlagManager.prototype.getFeatureData;
|