@openreplay/tracker 3.3.0 → 3.4.1
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/cjs/app/index.d.ts +6 -1
- package/cjs/app/index.js +49 -19
- package/cjs/app/observer.d.ts +19 -2
- package/cjs/app/observer.js +119 -39
- package/cjs/index.js +11 -7
- package/cjs/messages/index.d.ts +8 -0
- package/cjs/messages/index.js +15 -0
- package/cjs/messages/webworker.d.ts +1 -0
- package/cjs/messages/writer.js +3 -0
- package/cjs/modules/console.js +1 -1
- package/cjs/modules/cssrules.js +1 -2
- package/cjs/modules/img.js +2 -2
- package/cjs/modules/mouse.d.ts +5 -1
- package/cjs/modules/mouse.js +8 -3
- package/cjs/modules/timing.js +20 -15
- package/cjs/utils.d.ts +1 -1
- package/cjs/utils.js +3 -12
- package/cjs/vendors/finder/finder.js +12 -8
- package/lib/app/index.d.ts +6 -1
- package/lib/app/index.js +51 -21
- package/lib/app/observer.d.ts +19 -2
- package/lib/app/observer.js +121 -41
- package/lib/index.js +12 -8
- package/lib/messages/index.d.ts +8 -0
- package/lib/messages/index.js +14 -0
- package/lib/messages/tsconfig.tsbuildinfo +1 -1
- package/lib/messages/webworker.d.ts +1 -0
- package/lib/messages/writer.js +3 -0
- package/lib/modules/console.js +1 -1
- package/lib/modules/cssrules.js +1 -2
- package/lib/modules/img.js +3 -3
- package/lib/modules/mouse.d.ts +5 -1
- package/lib/modules/mouse.js +8 -3
- package/lib/modules/timing.js +20 -15
- package/lib/utils.d.ts +1 -1
- package/lib/utils.js +1 -9
- package/lib/vendors/finder/finder.js +12 -8
- package/package.json +2 -1
package/cjs/app/index.d.ts
CHANGED
|
@@ -15,8 +15,10 @@ export declare type Options = {
|
|
|
15
15
|
session_pageno_key: string;
|
|
16
16
|
local_uuid_key: string;
|
|
17
17
|
ingestPoint: string;
|
|
18
|
+
resourceBaseHref: string | null;
|
|
18
19
|
__is_snippet: boolean;
|
|
19
20
|
__debug_report_edp: string | null;
|
|
21
|
+
__debug_log: boolean;
|
|
20
22
|
onStart?: (info: OnStartInfo) => void;
|
|
21
23
|
} & ObserverOptions & WebworkerOptions;
|
|
22
24
|
declare type Callback = () => void;
|
|
@@ -38,7 +40,7 @@ export default class App {
|
|
|
38
40
|
private version;
|
|
39
41
|
private readonly worker?;
|
|
40
42
|
constructor(projectKey: string, sessionToken: string | null | undefined, opts: Partial<Options>);
|
|
41
|
-
private
|
|
43
|
+
private _debug;
|
|
42
44
|
send(message: Message, urgent?: boolean): void;
|
|
43
45
|
private commit;
|
|
44
46
|
addCommitCallback(cb: CommitCallback): void;
|
|
@@ -49,6 +51,9 @@ export default class App {
|
|
|
49
51
|
getSessionToken(): string | undefined;
|
|
50
52
|
getSessionID(): string | undefined;
|
|
51
53
|
getHost(): string;
|
|
54
|
+
getProjectKey(): string;
|
|
55
|
+
getBaseHref(): string;
|
|
56
|
+
resolveResourceURL(resourceURL: string): string;
|
|
52
57
|
isServiceURL(url: string): boolean;
|
|
53
58
|
active(): boolean;
|
|
54
59
|
private _start;
|
package/cjs/app/index.js
CHANGED
|
@@ -17,7 +17,7 @@ class App {
|
|
|
17
17
|
this.commitCallbacks = [];
|
|
18
18
|
this._sessionID = null;
|
|
19
19
|
this.isActive = false;
|
|
20
|
-
this.version = '3.
|
|
20
|
+
this.version = '3.4.1';
|
|
21
21
|
this.projectKey = projectKey;
|
|
22
22
|
this.options = Object.assign({
|
|
23
23
|
revID: '',
|
|
@@ -26,10 +26,13 @@ class App {
|
|
|
26
26
|
session_pageno_key: '__openreplay_pageno',
|
|
27
27
|
local_uuid_key: '__openreplay_uuid',
|
|
28
28
|
ingestPoint: exports.DEFAULT_INGEST_POINT,
|
|
29
|
+
resourceBaseHref: null,
|
|
29
30
|
__is_snippet: false,
|
|
30
31
|
__debug_report_edp: null,
|
|
32
|
+
__debug_log: false,
|
|
31
33
|
obscureTextEmails: true,
|
|
32
34
|
obscureTextNumbers: false,
|
|
35
|
+
captureIFrames: false,
|
|
33
36
|
}, opts);
|
|
34
37
|
if (sessionToken != null) {
|
|
35
38
|
sessionStorage.setItem(this.options.session_token_key, sessionToken);
|
|
@@ -40,12 +43,11 @@ class App {
|
|
|
40
43
|
this.ticker = new ticker_1.default(this);
|
|
41
44
|
this.ticker.attach(() => this.commit());
|
|
42
45
|
try {
|
|
43
|
-
this.worker = new Worker(URL.createObjectURL(new Blob([`"use strict";function t(t){function s(...s){return new t(...s)}return s.prototype=t.prototype,s}const s=new Map;const i=t(class{constructor(t,s,i){this.pageNo=t,this.firstIndex=s,this.timestamp=i,this._id=80}encode(t){return t.uint(80)&&t.uint(this.pageNo)&&t.uint(this.firstIndex)&&t.int(this.timestamp)}});s.set(80,i);const n=t(class{constructor(t){this.timestamp=t,this._id=0}encode(t){return t.uint(0)&&t.uint(this.timestamp)}});s.set(0,n);const e=t(class{constructor(t,s,i){this.url=t,this.referrer=s,this.navigationStart=i,this._id=4}encode(t){return t.uint(4)&&t.string(this.url)&&t.string(this.referrer)&&t.uint(this.navigationStart)}});s.set(4,e);const r=t(class{constructor(t,s){this.width=t,this.height=s,this._id=5}encode(t){return t.uint(5)&&t.uint(this.width)&&t.uint(this.height)}});s.set(5,r);const o=t(class{constructor(t,s){this.x=t,this.y=s,this._id=6}encode(t){return t.uint(6)&&t.int(this.x)&&t.int(this.y)}});s.set(6,o);const h=t(class{constructor(){this._id=7}encode(t){return t.uint(7)}});s.set(7,h);const c=t(class{constructor(t,s,i,n,e){this.id=t,this.parentID=s,this.index=i,this.tag=n,this.svg=e,this._id=8}encode(t){return t.uint(8)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)&&t.string(this.tag)&&t.boolean(this.svg)}});s.set(8,c);const u=t(class{constructor(t,s,i){this.id=t,this.parentID=s,this.index=i,this._id=9}encode(t){return t.uint(9)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)}});s.set(9,u);const a=t(class{constructor(t,s,i){this.id=t,this.parentID=s,this.index=i,this._id=10}encode(t){return t.uint(10)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)}});s.set(10,a);const d=t(class{constructor(t){this.id=t,this._id=11}encode(t){return t.uint(11)&&t.uint(this.id)}});s.set(11,d);const l=t(class{constructor(t,s,i){this.id=t,this.name=s,this.value=i,this._id=12}encode(t){return t.uint(12)&&t.uint(this.id)&&t.string(this.name)&&t.string(this.value)}});s.set(12,l);const g=t(class{constructor(t,s){this.id=t,this.name=s,this._id=13}encode(t){return t.uint(13)&&t.uint(this.id)&&t.string(this.name)}});s.set(13,g);const f=t(class{constructor(t,s){this.id=t,this.data=s,this._id=14}encode(t){return t.uint(14)&&t.uint(this.id)&&t.string(this.data)}});s.set(14,f);const p=t(class{constructor(t,s,i){this.id=t,this.x=s,this.y=i,this._id=16}encode(t){return t.uint(16)&&t.uint(this.id)&&t.int(this.x)&&t.int(this.y)}});s.set(16,p);const m=t(class{constructor(t,s){this.id=t,this.label=s,this._id=17}encode(t){return t.uint(17)&&t.uint(this.id)&&t.string(this.label)}});s.set(17,m);const _=t(class{constructor(t,s,i){this.id=t,this.value=s,this.mask=i,this._id=18}encode(t){return t.uint(18)&&t.uint(this.id)&&t.string(this.value)&&t.int(this.mask)}});s.set(18,_);const y=t(class{constructor(t,s){this.id=t,this.checked=s,this._id=19}encode(t){return t.uint(19)&&t.uint(this.id)&&t.boolean(this.checked)}});s.set(19,y);const v=t(class{constructor(t,s){this.x=t,this.y=s,this._id=20}encode(t){return t.uint(20)&&t.uint(this.x)&&t.uint(this.y)}});s.set(20,v);const S=t(class{constructor(t,s){this.level=t,this.value=s,this._id=22}encode(t){return t.uint(22)&&t.string(this.level)&&t.string(this.value)}});s.set(22,S);const b=t(class{constructor(t,s,i,n,e,r,o,h,c){this.requestStart=t,this.responseStart=s,this.responseEnd=i,this.domContentLoadedEventStart=n,this.domContentLoadedEventEnd=e,this.loadEventStart=r,this.loadEventEnd=o,this.firstPaint=h,this.firstContentfulPaint=c,this._id=23}encode(t){return t.uint(23)&&t.uint(this.requestStart)&&t.uint(this.responseStart)&&t.uint(this.responseEnd)&&t.uint(this.domContentLoadedEventStart)&&t.uint(this.domContentLoadedEventEnd)&&t.uint(this.loadEventStart)&&t.uint(this.loadEventEnd)&&t.uint(this.firstPaint)&&t.uint(this.firstContentfulPaint)}});s.set(23,b);const x=t(class{constructor(t,s,i){this.speedIndex=t,this.visuallyComplete=s,this.timeToInteractive=i,this._id=24}encode(t){return t.uint(24)&&t.uint(this.speedIndex)&&t.uint(this.visuallyComplete)&&t.uint(this.timeToInteractive)}});s.set(24,x);const k=t(class{constructor(t,s,i){this.name=t,this.message=s,this.payload=i,this._id=25}encode(t){return t.uint(25)&&t.string(this.name)&&t.string(this.message)&&t.string(this.payload)}});s.set(25,k);const E=t(class{constructor(t,s){this.name=t,this.payload=s,this._id=27}encode(t){return t.uint(27)&&t.string(this.name)&&t.string(this.payload)}});s.set(27,E);const z=t(class{constructor(t){this.id=t,this._id=28}encode(t){return t.uint(28)&&t.string(this.id)}});s.set(28,z);const w=t(class{constructor(t){this.id=t,this._id=29}encode(t){return t.uint(29)&&t.string(this.id)}});s.set(29,w);const I=t(class{constructor(t,s){this.key=t,this.value=s,this._id=30}encode(t){return t.uint(30)&&t.string(this.key)&&t.string(this.value)}});s.set(30,I);const L=t(class{constructor(t,s,i){this.id=t,this.rule=s,this.index=i,this._id=37}encode(t){return t.uint(37)&&t.uint(this.id)&&t.string(this.rule)&&t.uint(this.index)}});s.set(37,L);const T=t(class{constructor(t,s){this.id=t,this.index=s,this._id=38}encode(t){return t.uint(38)&&t.uint(this.id)&&t.uint(this.index)}});s.set(38,T);const C=t(class{constructor(t,s,i,n,e,r,o){this.method=t,this.url=s,this.request=i,this.response=n,this.status=e,this.timestamp=r,this.duration=o,this._id=39}encode(t){return t.uint(39)&&t.string(this.method)&&t.string(this.url)&&t.string(this.request)&&t.string(this.response)&&t.uint(this.status)&&t.uint(this.timestamp)&&t.uint(this.duration)}});s.set(39,C);const A=t(class{constructor(t,s,i,n){this.name=t,this.duration=s,this.args=i,this.result=n,this._id=40}encode(t){return t.uint(40)&&t.string(this.name)&&t.uint(this.duration)&&t.string(this.args)&&t.string(this.result)}});s.set(40,A);const M=t(class{constructor(t,s){this.key=t,this.value=s,this._id=41}encode(t){return t.uint(41)&&t.string(this.key)&&t.string(this.value)}});s.set(41,M);const R=t(class{constructor(t){this.type=t,this._id=42}encode(t){return t.uint(42)&&t.string(this.type)}});s.set(42,R);const U=t(class{constructor(t,s,i){this.action=t,this.state=s,this.duration=i,this._id=44}encode(t){return t.uint(44)&&t.string(this.action)&&t.string(this.state)&&t.uint(this.duration)}});s.set(44,U);const N=t(class{constructor(t,s){this.mutation=t,this.state=s,this._id=45}encode(t){return t.uint(45)&&t.string(this.mutation)&&t.string(this.state)}});s.set(45,N);const O=t(class{constructor(t,s){this.type=t,this.payload=s,this._id=46}encode(t){return t.uint(46)&&t.string(this.type)&&t.string(this.payload)}});s.set(46,O);const q=t(class{constructor(t,s,i){this.action=t,this.state=s,this.duration=i,this._id=47}encode(t){return t.uint(47)&&t.string(this.action)&&t.string(this.state)&&t.uint(this.duration)}});s.set(47,q);const D=t(class{constructor(t,s,i,n){this.operationKind=t,this.operationName=s,this.variables=i,this.response=n,this._id=48}encode(t){return t.uint(48)&&t.string(this.operationKind)&&t.string(this.operationName)&&t.string(this.variables)&&t.string(this.response)}});s.set(48,D);const H=t(class{constructor(t,s,i,n){this.frames=t,this.ticks=s,this.totalJSHeapSize=i,this.usedJSHeapSize=n,this._id=49}encode(t){return t.uint(49)&&t.int(this.frames)&&t.int(this.ticks)&&t.uint(this.totalJSHeapSize)&&t.uint(this.usedJSHeapSize)}});s.set(49,H);const P=t(class{constructor(t,s,i,n,e,r,o,h){this.timestamp=t,this.duration=s,this.ttfb=i,this.headerSize=n,this.encodedBodySize=e,this.decodedBodySize=r,this.url=o,this.initiator=h,this._id=53}encode(t){return t.uint(53)&&t.uint(this.timestamp)&&t.uint(this.duration)&&t.uint(this.ttfb)&&t.uint(this.headerSize)&&t.uint(this.encodedBodySize)&&t.uint(this.decodedBodySize)&&t.string(this.url)&&t.string(this.initiator)}});s.set(53,P);const B=t(class{constructor(t,s){this.downlink=t,this.type=s,this._id=54}encode(t){return t.uint(54)&&t.uint(this.downlink)&&t.string(this.type)}});s.set(54,B);const J=t(class{constructor(t){this.hidden=t,this._id=55}encode(t){return t.uint(55)&&t.boolean(this.hidden)}});s.set(55,J);const j=t(class{constructor(t,s,i,n,e,r,o){this.timestamp=t,this.duration=s,this.context=i,this.containerType=n,this.containerSrc=e,this.containerId=r,this.containerName=o,this._id=59}encode(t){return t.uint(59)&&t.uint(this.timestamp)&&t.uint(this.duration)&&t.uint(this.context)&&t.uint(this.containerType)&&t.string(this.containerSrc)&&t.string(this.containerId)&&t.string(this.containerName)}});s.set(59,j);const K=t(class{constructor(t,s,i,n){this.id=t,this.name=s,this.value=i,this.baseURL=n,this._id=60}encode(t){return t.uint(60)&&t.uint(this.id)&&t.string(this.name)&&t.string(this.value)&&t.string(this.baseURL)}});s.set(60,K);const G=t(class{constructor(t,s,i){this.id=t,this.data=s,this.baseURL=i,this._id=61}encode(t){return t.uint(61)&&t.uint(this.id)&&t.string(this.data)&&t.string(this.baseURL)}});s.set(61,G);const X=t(class{constructor(t,s){this.type=t,this.value=s,this._id=63}encode(t){return t.uint(63)&&t.string(this.type)&&t.string(this.value)}});s.set(63,X);const F=t(class{constructor(t,s){this.name=t,this.payload=s,this._id=64}encode(t){return t.uint(64)&&t.string(this.name)&&t.string(this.payload)}});s.set(64,F);const Q=t(class{constructor(){this._id=65}encode(t){return t.uint(65)}});s.set(65,Q);const V=t(class{constructor(t,s,i,n){this.id=t,this.rule=s,this.index=i,this.baseURL=n,this._id=67}encode(t){return t.uint(67)&&t.uint(this.id)&&t.string(this.rule)&&t.uint(this.index)&&t.string(this.baseURL)}});s.set(67,V);const W=t(class{constructor(t,s,i,n){this.id=t,this.hesitationTime=s,this.label=i,this.selector=n,this._id=69}encode(t){return t.uint(69)&&t.uint(this.id)&&t.uint(this.hesitationTime)&&t.string(this.label)&&t.string(this.selector)}});s.set(69,W);const Y="function"==typeof TextEncoder?new TextEncoder:{encode(t){const s=t.length,i=new Uint8Array(3*s);let n=-1;for(var e=0,r=0,o=0;o!==s;){if(e=t.charCodeAt(o),o+=1,e>=55296&&e<=56319){if(o===s){i[n+=1]=239,i[n+=1]=191,i[n+=1]=189;break}if(!((r=t.charCodeAt(o))>=56320&&r<=57343)){i[n+=1]=239,i[n+=1]=191,i[n+=1]=189;continue}if(o+=1,(e=1024*(e-55296)+r-56320+65536)>65535){i[n+=1]=240|e>>>18,i[n+=1]=128|e>>>12&63,i[n+=1]=128|e>>>6&63,i[n+=1]=128|63&e;continue}}e<=127?i[n+=1]=0|e:e<=2047?(i[n+=1]=192|e>>>6,i[n+=1]=128|63&e):(i[n+=1]=224|e>>>12,i[n+=1]=128|e>>>6&63,i[n+=1]=128|63&e)}return i.subarray(0,n+1)}};class Z{constructor(t){this.size=t,this.offset=0,this.checkpointOffset=0,this.data=new Uint8Array(t)}checkpoint(){this.checkpointOffset=this.offset}isEmpty(){return 0===this.offset}boolean(t){return this.data[this.offset++]=+t,this.offset<=this.size}uint(t){for(;t>=128;)this.data[this.offset++]=t%256|128,t=Math.floor(t/128);return this.data[this.offset++]=t,this.offset<=this.size}int(t){return t=Math.round(t),this.uint(t>=0?2*t:-2*t-1)}string(t){const s=Y.encode(t),i=s.byteLength;return!(!this.uint(i)||this.offset+i>this.size)&&(this.data.set(s,this.offset),this.offset+=i,!0)}reset(){this.offset=0,this.checkpointOffset=0}flush(){const t=this.data.slice(0,this.checkpointOffset);return this.reset(),t}}let tt,st=1e6,it=4e5,nt=new Z(it),et="",rt="",ot=0,ht=0,ct=0,ut=0,at=!0;function dt(){return new i(ot,ut,ht).encode(nt)}const lt=[];let gt,ft=!1,pt=0,mt=8e3,_t=10;function yt(){if(at||""===rt||""===et)return;const t=nt.flush();ft?lt.push(t):(ft=!0,function t(s){const i=new XMLHttpRequest;i.open("POST",et+"/v1/web/i",!1),i.setRequestHeader("Authorization","Bearer "+rt),i.onreadystatechange=function(){if(4===this.readyState){if(0==this.status)return;if(this.status>=400)return vt(),lt.length=0,403===this.status?void self.postMessage("restart"):void self.postMessage(null);const s=lt.shift();s?t(s):ft=!1}},i.onerror=function(i){if(pt>=_t)return vt(),void self.postMessage(null);pt++,setTimeout(()=>t(s),mt)},i.send(s.buffer)}(t)),at=!0,dt()}function vt(){et="",rt="",clearInterval(tt),nt.reset()}self.onmessage=({data:t})=>{if(null!==t)return"stop"===t?(yt(),void vt()):Array.isArray(t)?void t.forEach(t=>{const i=new(s.get(t._id));if(Object.assign(i,t),i instanceof n?ht=i.timestamp:i instanceof J&&(i.hidden?gt=setTimeout(()=>self.postMessage("restart"),3e5):clearTimeout(gt)),nt.checkpoint(),!i.encode(nt)&&(yt(),!i.encode(nt)))for(;!i.encode(nt);){if(it===st)return console.warn("OpenReplay: beacon size overflow."),nt.reset(),void dt();it=Math.min(2*it,st),nt=new Z(it),dt()}ut++,at=!1}):(et=t.ingestPoint||et,rt=t.token||rt,ot=t.pageNo||ot,ht=t.startTimestamp||ht,ct=t.timeAdjustment||ct,_t=t.connAttemptCount||_t,mt=t.connAttemptGap||mt,st=t.beaconSizeLimit||st,it=Math.min(st,t.beaconSize||it),nt.isEmpty()&&dt(),void(null==tt&&(tt=setInterval(yt,2e4))));yt()};
|
|
46
|
+
this.worker = new Worker(URL.createObjectURL(new Blob([`"use strict";function t(t){function s(...s){return new t(...s)}return s.prototype=t.prototype,s}const s=new Map;const i=t(class{constructor(t,s,i){this.pageNo=t,this.firstIndex=s,this.timestamp=i,this._id=80}encode(t){return t.uint(80)&&t.uint(this.pageNo)&&t.uint(this.firstIndex)&&t.int(this.timestamp)}});s.set(80,i);const n=t(class{constructor(t){this.timestamp=t,this._id=0}encode(t){return t.uint(0)&&t.uint(this.timestamp)}});s.set(0,n);const e=t(class{constructor(t,s,i){this.url=t,this.referrer=s,this.navigationStart=i,this._id=4}encode(t){return t.uint(4)&&t.string(this.url)&&t.string(this.referrer)&&t.uint(this.navigationStart)}});s.set(4,e);const r=t(class{constructor(t,s){this.width=t,this.height=s,this._id=5}encode(t){return t.uint(5)&&t.uint(this.width)&&t.uint(this.height)}});s.set(5,r);const o=t(class{constructor(t,s){this.x=t,this.y=s,this._id=6}encode(t){return t.uint(6)&&t.int(this.x)&&t.int(this.y)}});s.set(6,o);const h=t(class{constructor(){this._id=7}encode(t){return t.uint(7)}});s.set(7,h);const c=t(class{constructor(t,s,i,n,e){this.id=t,this.parentID=s,this.index=i,this.tag=n,this.svg=e,this._id=8}encode(t){return t.uint(8)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)&&t.string(this.tag)&&t.boolean(this.svg)}});s.set(8,c);const u=t(class{constructor(t,s,i){this.id=t,this.parentID=s,this.index=i,this._id=9}encode(t){return t.uint(9)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)}});s.set(9,u);const a=t(class{constructor(t,s,i){this.id=t,this.parentID=s,this.index=i,this._id=10}encode(t){return t.uint(10)&&t.uint(this.id)&&t.uint(this.parentID)&&t.uint(this.index)}});s.set(10,a);const d=t(class{constructor(t){this.id=t,this._id=11}encode(t){return t.uint(11)&&t.uint(this.id)}});s.set(11,d);const l=t(class{constructor(t,s,i){this.id=t,this.name=s,this.value=i,this._id=12}encode(t){return t.uint(12)&&t.uint(this.id)&&t.string(this.name)&&t.string(this.value)}});s.set(12,l);const g=t(class{constructor(t,s){this.id=t,this.name=s,this._id=13}encode(t){return t.uint(13)&&t.uint(this.id)&&t.string(this.name)}});s.set(13,g);const f=t(class{constructor(t,s){this.id=t,this.data=s,this._id=14}encode(t){return t.uint(14)&&t.uint(this.id)&&t.string(this.data)}});s.set(14,f);const p=t(class{constructor(t,s,i){this.id=t,this.x=s,this.y=i,this._id=16}encode(t){return t.uint(16)&&t.uint(this.id)&&t.int(this.x)&&t.int(this.y)}});s.set(16,p);const m=t(class{constructor(t,s){this.id=t,this.label=s,this._id=17}encode(t){return t.uint(17)&&t.uint(this.id)&&t.string(this.label)}});s.set(17,m);const _=t(class{constructor(t,s,i){this.id=t,this.value=s,this.mask=i,this._id=18}encode(t){return t.uint(18)&&t.uint(this.id)&&t.string(this.value)&&t.int(this.mask)}});s.set(18,_);const y=t(class{constructor(t,s){this.id=t,this.checked=s,this._id=19}encode(t){return t.uint(19)&&t.uint(this.id)&&t.boolean(this.checked)}});s.set(19,y);const v=t(class{constructor(t,s){this.x=t,this.y=s,this._id=20}encode(t){return t.uint(20)&&t.uint(this.x)&&t.uint(this.y)}});s.set(20,v);const S=t(class{constructor(t,s){this.level=t,this.value=s,this._id=22}encode(t){return t.uint(22)&&t.string(this.level)&&t.string(this.value)}});s.set(22,S);const b=t(class{constructor(t,s,i,n,e,r,o,h,c){this.requestStart=t,this.responseStart=s,this.responseEnd=i,this.domContentLoadedEventStart=n,this.domContentLoadedEventEnd=e,this.loadEventStart=r,this.loadEventEnd=o,this.firstPaint=h,this.firstContentfulPaint=c,this._id=23}encode(t){return t.uint(23)&&t.uint(this.requestStart)&&t.uint(this.responseStart)&&t.uint(this.responseEnd)&&t.uint(this.domContentLoadedEventStart)&&t.uint(this.domContentLoadedEventEnd)&&t.uint(this.loadEventStart)&&t.uint(this.loadEventEnd)&&t.uint(this.firstPaint)&&t.uint(this.firstContentfulPaint)}});s.set(23,b);const x=t(class{constructor(t,s,i){this.speedIndex=t,this.visuallyComplete=s,this.timeToInteractive=i,this._id=24}encode(t){return t.uint(24)&&t.uint(this.speedIndex)&&t.uint(this.visuallyComplete)&&t.uint(this.timeToInteractive)}});s.set(24,x);const E=t(class{constructor(t,s,i){this.name=t,this.message=s,this.payload=i,this._id=25}encode(t){return t.uint(25)&&t.string(this.name)&&t.string(this.message)&&t.string(this.payload)}});s.set(25,E);const k=t(class{constructor(t,s){this.name=t,this.payload=s,this._id=27}encode(t){return t.uint(27)&&t.string(this.name)&&t.string(this.payload)}});s.set(27,k);const I=t(class{constructor(t){this.id=t,this._id=28}encode(t){return t.uint(28)&&t.string(this.id)}});s.set(28,I);const z=t(class{constructor(t){this.id=t,this._id=29}encode(t){return t.uint(29)&&t.string(this.id)}});s.set(29,z);const w=t(class{constructor(t,s){this.key=t,this.value=s,this._id=30}encode(t){return t.uint(30)&&t.string(this.key)&&t.string(this.value)}});s.set(30,w);const T=t(class{constructor(t,s,i){this.id=t,this.rule=s,this.index=i,this._id=37}encode(t){return t.uint(37)&&t.uint(this.id)&&t.string(this.rule)&&t.uint(this.index)}});s.set(37,T);const L=t(class{constructor(t,s){this.id=t,this.index=s,this._id=38}encode(t){return t.uint(38)&&t.uint(this.id)&&t.uint(this.index)}});s.set(38,L);const A=t(class{constructor(t,s,i,n,e,r,o){this.method=t,this.url=s,this.request=i,this.response=n,this.status=e,this.timestamp=r,this.duration=o,this._id=39}encode(t){return t.uint(39)&&t.string(this.method)&&t.string(this.url)&&t.string(this.request)&&t.string(this.response)&&t.uint(this.status)&&t.uint(this.timestamp)&&t.uint(this.duration)}});s.set(39,A);const C=t(class{constructor(t,s,i,n){this.name=t,this.duration=s,this.args=i,this.result=n,this._id=40}encode(t){return t.uint(40)&&t.string(this.name)&&t.uint(this.duration)&&t.string(this.args)&&t.string(this.result)}});s.set(40,C);const M=t(class{constructor(t,s){this.key=t,this.value=s,this._id=41}encode(t){return t.uint(41)&&t.string(this.key)&&t.string(this.value)}});s.set(41,M);const R=t(class{constructor(t){this.type=t,this._id=42}encode(t){return t.uint(42)&&t.string(this.type)}});s.set(42,R);const N=t(class{constructor(t,s,i){this.action=t,this.state=s,this.duration=i,this._id=44}encode(t){return t.uint(44)&&t.string(this.action)&&t.string(this.state)&&t.uint(this.duration)}});s.set(44,N);const D=t(class{constructor(t,s){this.mutation=t,this.state=s,this._id=45}encode(t){return t.uint(45)&&t.string(this.mutation)&&t.string(this.state)}});s.set(45,D);const U=t(class{constructor(t,s){this.type=t,this.payload=s,this._id=46}encode(t){return t.uint(46)&&t.string(this.type)&&t.string(this.payload)}});s.set(46,U);const O=t(class{constructor(t,s,i){this.action=t,this.state=s,this.duration=i,this._id=47}encode(t){return t.uint(47)&&t.string(this.action)&&t.string(this.state)&&t.uint(this.duration)}});s.set(47,O);const q=t(class{constructor(t,s,i,n){this.operationKind=t,this.operationName=s,this.variables=i,this.response=n,this._id=48}encode(t){return t.uint(48)&&t.string(this.operationKind)&&t.string(this.operationName)&&t.string(this.variables)&&t.string(this.response)}});s.set(48,q);const H=t(class{constructor(t,s,i,n){this.frames=t,this.ticks=s,this.totalJSHeapSize=i,this.usedJSHeapSize=n,this._id=49}encode(t){return t.uint(49)&&t.int(this.frames)&&t.int(this.ticks)&&t.uint(this.totalJSHeapSize)&&t.uint(this.usedJSHeapSize)}});s.set(49,H);const P=t(class{constructor(t,s,i,n,e,r,o,h){this.timestamp=t,this.duration=s,this.ttfb=i,this.headerSize=n,this.encodedBodySize=e,this.decodedBodySize=r,this.url=o,this.initiator=h,this._id=53}encode(t){return t.uint(53)&&t.uint(this.timestamp)&&t.uint(this.duration)&&t.uint(this.ttfb)&&t.uint(this.headerSize)&&t.uint(this.encodedBodySize)&&t.uint(this.decodedBodySize)&&t.string(this.url)&&t.string(this.initiator)}});s.set(53,P);const B=t(class{constructor(t,s){this.downlink=t,this.type=s,this._id=54}encode(t){return t.uint(54)&&t.uint(this.downlink)&&t.string(this.type)}});s.set(54,B);const J=t(class{constructor(t){this.hidden=t,this._id=55}encode(t){return t.uint(55)&&t.boolean(this.hidden)}});s.set(55,J);const j=t(class{constructor(t,s,i,n,e,r,o){this.timestamp=t,this.duration=s,this.context=i,this.containerType=n,this.containerSrc=e,this.containerId=r,this.containerName=o,this._id=59}encode(t){return t.uint(59)&&t.uint(this.timestamp)&&t.uint(this.duration)&&t.uint(this.context)&&t.uint(this.containerType)&&t.string(this.containerSrc)&&t.string(this.containerId)&&t.string(this.containerName)}});s.set(59,j);const G=t(class{constructor(t,s,i,n){this.id=t,this.name=s,this.value=i,this.baseURL=n,this._id=60}encode(t){return t.uint(60)&&t.uint(this.id)&&t.string(this.name)&&t.string(this.value)&&t.string(this.baseURL)}});s.set(60,G);const K=t(class{constructor(t,s,i){this.id=t,this.data=s,this.baseURL=i,this._id=61}encode(t){return t.uint(61)&&t.uint(this.id)&&t.string(this.data)&&t.string(this.baseURL)}});s.set(61,K);const X=t(class{constructor(t,s){this.type=t,this.value=s,this._id=63}encode(t){return t.uint(63)&&t.string(this.type)&&t.string(this.value)}});s.set(63,X);const F=t(class{constructor(t,s){this.name=t,this.payload=s,this._id=64}encode(t){return t.uint(64)&&t.string(this.name)&&t.string(this.payload)}});s.set(64,F);const Q=t(class{constructor(){this._id=65}encode(t){return t.uint(65)}});s.set(65,Q);const V=t(class{constructor(t,s,i,n){this.id=t,this.rule=s,this.index=i,this.baseURL=n,this._id=67}encode(t){return t.uint(67)&&t.uint(this.id)&&t.string(this.rule)&&t.uint(this.index)&&t.string(this.baseURL)}});s.set(67,V);const W=t(class{constructor(t,s,i,n){this.id=t,this.hesitationTime=s,this.label=i,this.selector=n,this._id=69}encode(t){return t.uint(69)&&t.uint(this.id)&&t.uint(this.hesitationTime)&&t.string(this.label)&&t.string(this.selector)}});s.set(69,W);const Y=t(class{constructor(t,s){this.frameID=t,this.id=s,this._id=70}encode(t){return t.uint(70)&&t.uint(this.frameID)&&t.uint(this.id)}});s.set(70,Y);const Z="function"==typeof TextEncoder?new TextEncoder:{encode(t){const s=t.length,i=new Uint8Array(3*s);let n=-1;for(var e=0,r=0,o=0;o!==s;){if(e=t.charCodeAt(o),o+=1,e>=55296&&e<=56319){if(o===s){i[n+=1]=239,i[n+=1]=191,i[n+=1]=189;break}if(!((r=t.charCodeAt(o))>=56320&&r<=57343)){i[n+=1]=239,i[n+=1]=191,i[n+=1]=189;continue}if(o+=1,(e=1024*(e-55296)+r-56320+65536)>65535){i[n+=1]=240|e>>>18,i[n+=1]=128|e>>>12&63,i[n+=1]=128|e>>>6&63,i[n+=1]=128|63&e;continue}}e<=127?i[n+=1]=0|e:e<=2047?(i[n+=1]=192|e>>>6,i[n+=1]=128|63&e):(i[n+=1]=224|e>>>12,i[n+=1]=128|e>>>6&63,i[n+=1]=128|63&e)}return i.subarray(0,n+1)}};class tt{constructor(t){this.size=t,this.offset=0,this.checkpointOffset=0,this.data=new Uint8Array(t)}checkpoint(){this.checkpointOffset=this.offset}isEmpty(){return 0===this.offset}boolean(t){return this.data[this.offset++]=+t,this.offset<=this.size}uint(t){for((t<0||t>Number.MAX_SAFE_INTEGER)&&(t=0);t>=128;)this.data[this.offset++]=t%256|128,t=Math.floor(t/128);return this.data[this.offset++]=t,this.offset<=this.size}int(t){return t=Math.round(t),this.uint(t>=0?2*t:-2*t-1)}string(t){const s=Z.encode(t),i=s.byteLength;return!(!this.uint(i)||this.offset+i>this.size)&&(this.data.set(s,this.offset),this.offset+=i,!0)}reset(){this.offset=0,this.checkpointOffset=0}flush(){const t=this.data.slice(0,this.checkpointOffset);return this.reset(),t}}let st,it=1e6,nt=4e5,et=new tt(nt),rt="",ot="",ht=0,ct=0,ut=0,at=0,dt=!0;function lt(){return new i(ht,at,ct).encode(et)}const gt=[];let ft,pt=!1,mt=0,_t=8e3,yt=10;function vt(){if(dt||""===ot||""===rt)return;const t=et.flush();pt?gt.push(t):(pt=!0,function t(s){const i=new XMLHttpRequest;i.open("POST",rt+"/v1/web/i",!1),i.setRequestHeader("Authorization","Bearer "+ot),i.onreadystatechange=function(){if(4===this.readyState){if(0==this.status)return;if(this.status>=400)return St(),gt.length=0,401===this.status?void self.postMessage("restart"):void self.postMessage(null);const s=gt.shift();s?t(s):pt=!1}},i.onerror=function(i){if(mt>=yt)return St(),void self.postMessage(null);mt++,setTimeout(()=>t(s),_t)},i.send(s.buffer)}(t)),dt=!0,lt()}function St(){rt="",ot="",clearInterval(st),et.reset()}self.onmessage=({data:t})=>{if(null!==t)return"stop"===t?(vt(),void St()):Array.isArray(t)?void t.forEach(t=>{const i=new(s.get(t._id));if(Object.assign(i,t),i instanceof n?ct=i.timestamp:i instanceof J&&(i.hidden?ft=setTimeout(()=>self.postMessage("restart"),3e5):clearTimeout(ft)),et.checkpoint(),!i.encode(et)&&(vt(),!i.encode(et)))for(;!i.encode(et);){if(nt===it)return console.warn("OpenReplay: beacon size overflow."),et.reset(),void lt();nt=Math.min(2*nt,it),et=new tt(nt),lt()}at++,dt=!1}):(rt=t.ingestPoint||rt,ot=t.token||ot,ht=t.pageNo||ht,ct=t.startTimestamp||ct,ut=t.timeAdjustment||ut,yt=t.connAttemptCount||yt,_t=t.connAttemptGap||_t,it=t.beaconSizeLimit||it,nt=Math.min(it,t.beaconSize||nt),et.isEmpty()&<(),void(null==st&&(st=setInterval(vt,2e4))));vt()};
|
|
44
47
|
`], { type: 'text/javascript' })));
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
// }
|
|
48
|
+
this.worker.onerror = e => {
|
|
49
|
+
this._debug("webworker_error", e);
|
|
50
|
+
};
|
|
49
51
|
let lastTs = utils_1.timestamp();
|
|
50
52
|
let fileno = 0;
|
|
51
53
|
this.worker.onmessage = ({ data }) => {
|
|
@@ -62,25 +64,30 @@ class App {
|
|
|
62
64
|
this.worker.postMessage(null);
|
|
63
65
|
}
|
|
64
66
|
};
|
|
67
|
+
// TODO:on start
|
|
65
68
|
// TODO: keep better tactics, discard others (look https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon)
|
|
66
69
|
this.attachEventListener(window, 'beforeunload', alertWorker, false);
|
|
67
70
|
this.attachEventListener(document, 'mouseleave', alertWorker, false, false);
|
|
68
71
|
this.attachEventListener(document, 'visibilitychange', alertWorker, false);
|
|
69
72
|
}
|
|
70
73
|
catch (e) {
|
|
71
|
-
this.
|
|
74
|
+
this._debug("worker_start", e);
|
|
72
75
|
}
|
|
73
76
|
}
|
|
74
|
-
|
|
77
|
+
_debug(context, e) {
|
|
75
78
|
if (this.options.__debug_report_edp !== null) {
|
|
76
79
|
fetch(this.options.__debug_report_edp, {
|
|
77
80
|
method: 'POST',
|
|
81
|
+
headers: { 'Content-Type': 'application/json' },
|
|
78
82
|
body: JSON.stringify({
|
|
79
83
|
context,
|
|
80
84
|
error: `${e}`
|
|
81
85
|
})
|
|
82
86
|
});
|
|
83
87
|
}
|
|
88
|
+
if (this.options.__debug_log) {
|
|
89
|
+
utils_1.warn("OpenReplay errror: ", context, e);
|
|
90
|
+
}
|
|
84
91
|
}
|
|
85
92
|
send(message, urgent = false) {
|
|
86
93
|
if (!this.isActive) {
|
|
@@ -109,12 +116,11 @@ class App {
|
|
|
109
116
|
fn.apply(this, args);
|
|
110
117
|
}
|
|
111
118
|
catch (e) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
})));
|
|
119
|
+
this._debug("safe_fn_call", e);
|
|
120
|
+
// time: timestamp(),
|
|
121
|
+
// name: e.name,
|
|
122
|
+
// message: e.message,
|
|
123
|
+
// stack: e.stack
|
|
118
124
|
}
|
|
119
125
|
}; // TODO: correct typing
|
|
120
126
|
}
|
|
@@ -141,7 +147,30 @@ class App {
|
|
|
141
147
|
return this._sessionID || undefined;
|
|
142
148
|
}
|
|
143
149
|
getHost() {
|
|
144
|
-
return new URL(this.options.ingestPoint).
|
|
150
|
+
return new URL(this.options.ingestPoint).hostname;
|
|
151
|
+
}
|
|
152
|
+
getProjectKey() {
|
|
153
|
+
return this.projectKey;
|
|
154
|
+
}
|
|
155
|
+
getBaseHref() {
|
|
156
|
+
var _a, _b;
|
|
157
|
+
if (typeof this.options.resourceBaseHref === 'string') {
|
|
158
|
+
return this.options.resourceBaseHref;
|
|
159
|
+
}
|
|
160
|
+
else if (typeof this.options.resourceBaseHref === 'object') {
|
|
161
|
+
//switch between types
|
|
162
|
+
}
|
|
163
|
+
if (document.baseURI) {
|
|
164
|
+
return document.baseURI;
|
|
165
|
+
}
|
|
166
|
+
// IE only
|
|
167
|
+
return ((_b = (_a = document.head) === null || _a === void 0 ? void 0 : _a.getElementsByTagName("base")[0]) === null || _b === void 0 ? void 0 : _b.getAttribute("href")) || location.origin + location.pathname;
|
|
168
|
+
}
|
|
169
|
+
resolveResourceURL(resourceURL) {
|
|
170
|
+
const base = new URL(this.getBaseHref());
|
|
171
|
+
base.pathname += "/" + new URL(resourceURL).pathname;
|
|
172
|
+
base.pathname.replace(/\/+/g, "/");
|
|
173
|
+
return base.toString();
|
|
145
174
|
}
|
|
146
175
|
isServiceURL(url) {
|
|
147
176
|
return url.startsWith(this.options.ingestPoint);
|
|
@@ -151,10 +180,10 @@ class App {
|
|
|
151
180
|
}
|
|
152
181
|
_start(reset) {
|
|
153
182
|
if (!this.isActive) {
|
|
154
|
-
this.isActive = true;
|
|
155
183
|
if (!this.worker) {
|
|
156
|
-
|
|
184
|
+
return Promise.reject("No worker found: perhaps, CSP is not set.");
|
|
157
185
|
}
|
|
186
|
+
this.isActive = true;
|
|
158
187
|
let pageNo = 0;
|
|
159
188
|
const pageNoStr = sessionStorage.getItem(this.options.session_pageno_key);
|
|
160
189
|
if (pageNoStr != null) {
|
|
@@ -212,7 +241,7 @@ class App {
|
|
|
212
241
|
this._sessionID = sessionID;
|
|
213
242
|
}
|
|
214
243
|
if (!this.worker) {
|
|
215
|
-
throw new Error("
|
|
244
|
+
throw new Error("no worker found after start request (this might not happen)");
|
|
216
245
|
}
|
|
217
246
|
this.worker.postMessage({ token, beaconSizeLimit });
|
|
218
247
|
this.startCallbacks.forEach((cb) => cb());
|
|
@@ -227,7 +256,8 @@ class App {
|
|
|
227
256
|
})
|
|
228
257
|
.catch(e => {
|
|
229
258
|
this.stop();
|
|
230
|
-
|
|
259
|
+
utils_1.warn("OpenReplay was unable to start. ", e);
|
|
260
|
+
this._debug("session_start", e);
|
|
231
261
|
throw e;
|
|
232
262
|
});
|
|
233
263
|
}
|
package/cjs/app/observer.d.ts
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import App from './index';
|
|
2
|
+
interface Window extends WindowProxy {
|
|
3
|
+
HTMLInputElement: typeof HTMLInputElement;
|
|
4
|
+
HTMLLinkElement: typeof HTMLLinkElement;
|
|
5
|
+
HTMLStyleElement: typeof HTMLStyleElement;
|
|
6
|
+
SVGStyleElement: typeof SVGStyleElement;
|
|
7
|
+
HTMLIFrameElement: typeof HTMLIFrameElement;
|
|
8
|
+
Text: typeof Text;
|
|
9
|
+
Element: typeof Element;
|
|
10
|
+
}
|
|
2
11
|
export interface Options {
|
|
3
12
|
obscureTextEmails: boolean;
|
|
4
13
|
obscureTextNumbers: boolean;
|
|
14
|
+
captureIFrames: boolean;
|
|
5
15
|
}
|
|
6
16
|
export default class Observer {
|
|
7
17
|
private readonly app;
|
|
18
|
+
private readonly options;
|
|
19
|
+
private readonly context;
|
|
8
20
|
private readonly observer;
|
|
9
21
|
private readonly commited;
|
|
10
22
|
private readonly recents;
|
|
@@ -12,9 +24,10 @@ export default class Observer {
|
|
|
12
24
|
private readonly attributesList;
|
|
13
25
|
private readonly textSet;
|
|
14
26
|
private readonly textMasked;
|
|
15
|
-
|
|
16
|
-
constructor(app: App, opts: Options);
|
|
27
|
+
constructor(app: App, options: Options, context?: Window);
|
|
17
28
|
private clear;
|
|
29
|
+
private isInstance;
|
|
30
|
+
private isIgnored;
|
|
18
31
|
private sendNodeAttribute;
|
|
19
32
|
private sendNodeData;
|
|
20
33
|
private bindNode;
|
|
@@ -23,6 +36,10 @@ export default class Observer {
|
|
|
23
36
|
private _commitNode;
|
|
24
37
|
private commitNode;
|
|
25
38
|
private commitNodes;
|
|
39
|
+
private iframeObservers;
|
|
40
|
+
private handleIframe;
|
|
41
|
+
private observeIframe;
|
|
26
42
|
observe(): void;
|
|
27
43
|
disconnect(): void;
|
|
28
44
|
}
|
|
45
|
+
export {};
|
package/cjs/app/observer.js
CHANGED
|
@@ -5,36 +5,40 @@ const messages_1 = require("../messages");
|
|
|
5
5
|
function isSVGElement(node) {
|
|
6
6
|
return node.namespaceURI === 'http://www.w3.org/2000/svg';
|
|
7
7
|
}
|
|
8
|
-
function isIgnored(node) {
|
|
9
|
-
if (node instanceof Text) {
|
|
10
|
-
return false;
|
|
11
|
-
}
|
|
12
|
-
if (!(node instanceof Element)) {
|
|
13
|
-
return true;
|
|
14
|
-
}
|
|
15
|
-
const tag = node.tagName.toUpperCase();
|
|
16
|
-
if (tag === 'LINK') {
|
|
17
|
-
const rel = node.getAttribute('rel');
|
|
18
|
-
const as = node.getAttribute('as');
|
|
19
|
-
return !((rel === null || rel === void 0 ? void 0 : rel.includes('stylesheet')) || as === "style" || as === "font");
|
|
20
|
-
}
|
|
21
|
-
return (tag === 'SCRIPT' ||
|
|
22
|
-
tag === 'NOSCRIPT' ||
|
|
23
|
-
tag === 'META' ||
|
|
24
|
-
tag === 'TITLE' ||
|
|
25
|
-
tag === 'BASE');
|
|
26
|
-
}
|
|
27
8
|
class Observer {
|
|
28
|
-
constructor(app,
|
|
9
|
+
constructor(app, options, context = window) {
|
|
29
10
|
this.app = app;
|
|
30
|
-
this.options =
|
|
11
|
+
this.options = options;
|
|
12
|
+
this.context = context;
|
|
13
|
+
this.iframeObservers = [];
|
|
31
14
|
this.observer = new MutationObserver(this.app.safe((mutations) => {
|
|
15
|
+
var _a;
|
|
32
16
|
for (const mutation of mutations) {
|
|
33
17
|
const target = mutation.target;
|
|
34
|
-
|
|
18
|
+
const type = mutation.type;
|
|
19
|
+
// Special case
|
|
20
|
+
// Document 'childList' might happen in case of iframe.
|
|
21
|
+
// TODO: generalize as much as possible
|
|
22
|
+
if (this.isInstance(target, Document)
|
|
23
|
+
&& type === 'childList'
|
|
24
|
+
//&& new Array(mutation.addedNodes).some(node => this.isInstance(node, HTMLHtmlElement))
|
|
25
|
+
) {
|
|
26
|
+
const parentFrame = (_a = target.defaultView) === null || _a === void 0 ? void 0 : _a.frameElement;
|
|
27
|
+
if (!parentFrame) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
this.bindTree(target.documentElement);
|
|
31
|
+
const frameID = this.app.nodes.getID(parentFrame);
|
|
32
|
+
const docID = this.app.nodes.getID(target.documentElement);
|
|
33
|
+
if (frameID === undefined || docID === undefined) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
this.app.send(messages_1.CreateIFrameDocument(frameID, docID));
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (this.isIgnored(target) || !context.document.contains(target)) {
|
|
35
40
|
continue;
|
|
36
41
|
}
|
|
37
|
-
const type = mutation.type;
|
|
38
42
|
if (type === 'childList') {
|
|
39
43
|
for (let i = 0; i < mutation.removedNodes.length; i++) {
|
|
40
44
|
this.bindTree(mutation.removedNodes[i]);
|
|
@@ -85,6 +89,39 @@ class Observer {
|
|
|
85
89
|
this.textSet.clear();
|
|
86
90
|
this.textMasked.clear();
|
|
87
91
|
}
|
|
92
|
+
// TODO: we need a type expert here so we won't have to ignore the lines
|
|
93
|
+
isInstance(node, constr) {
|
|
94
|
+
let context = this.context;
|
|
95
|
+
while (context.parent && context.parent !== context) {
|
|
96
|
+
// @ts-ignore
|
|
97
|
+
if (node instanceof context[constr.name]) {
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
// @ts-ignore
|
|
101
|
+
context = context.parent;
|
|
102
|
+
}
|
|
103
|
+
// @ts-ignore
|
|
104
|
+
return node instanceof context[constr.name];
|
|
105
|
+
}
|
|
106
|
+
isIgnored(node) {
|
|
107
|
+
if (this.isInstance(node, Text)) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
if (!this.isInstance(node, Element)) {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
const tag = node.tagName.toUpperCase();
|
|
114
|
+
if (tag === 'LINK') {
|
|
115
|
+
const rel = node.getAttribute('rel');
|
|
116
|
+
const as = node.getAttribute('as');
|
|
117
|
+
return !((rel === null || rel === void 0 ? void 0 : rel.includes('stylesheet')) || as === "style" || as === "font");
|
|
118
|
+
}
|
|
119
|
+
return (tag === 'SCRIPT' ||
|
|
120
|
+
tag === 'NOSCRIPT' ||
|
|
121
|
+
tag === 'META' ||
|
|
122
|
+
tag === 'TITLE' ||
|
|
123
|
+
tag === 'BASE');
|
|
124
|
+
}
|
|
88
125
|
sendNodeAttribute(id, node, name, value) {
|
|
89
126
|
if (isSVGElement(node)) {
|
|
90
127
|
if (name.substr(0, 6) === 'xlink:') {
|
|
@@ -97,7 +134,7 @@ class Observer {
|
|
|
97
134
|
if (value.length > 1e5) {
|
|
98
135
|
value = '';
|
|
99
136
|
}
|
|
100
|
-
this.app.send(new messages_1.SetNodeAttributeURLBased(id, name, value,
|
|
137
|
+
this.app.send(new messages_1.SetNodeAttributeURLBased(id, name, value, this.app.getBaseHref()));
|
|
101
138
|
}
|
|
102
139
|
else {
|
|
103
140
|
this.app.send(new messages_1.SetNodeAttribute(id, name, value));
|
|
@@ -113,7 +150,7 @@ class Observer {
|
|
|
113
150
|
return;
|
|
114
151
|
}
|
|
115
152
|
if (name === 'value' &&
|
|
116
|
-
node
|
|
153
|
+
this.isInstance(node, HTMLInputElement) &&
|
|
117
154
|
node.type !== 'button' &&
|
|
118
155
|
node.type !== 'reset' &&
|
|
119
156
|
node.type !== 'submit') {
|
|
@@ -123,8 +160,8 @@ class Observer {
|
|
|
123
160
|
this.app.send(new messages_1.RemoveNodeAttribute(id, name));
|
|
124
161
|
return;
|
|
125
162
|
}
|
|
126
|
-
if (name === 'style' || name === 'href' && node
|
|
127
|
-
this.app.send(new messages_1.SetNodeAttributeURLBased(id, name, value,
|
|
163
|
+
if (name === 'style' || name === 'href' && this.isInstance(node, HTMLLinkElement)) {
|
|
164
|
+
this.app.send(new messages_1.SetNodeAttributeURLBased(id, name, value, this.app.getBaseHref()));
|
|
128
165
|
return;
|
|
129
166
|
}
|
|
130
167
|
if (name === 'href' || value.length > 1e5) {
|
|
@@ -133,8 +170,8 @@ class Observer {
|
|
|
133
170
|
this.app.send(new messages_1.SetNodeAttribute(id, name, value));
|
|
134
171
|
}
|
|
135
172
|
sendNodeData(id, parentElement, data) {
|
|
136
|
-
if (parentElement
|
|
137
|
-
this.app.send(new messages_1.SetCSSDataURLBased(id, data,
|
|
173
|
+
if (this.isInstance(parentElement, HTMLStyleElement) || this.isInstance(parentElement, SVGStyleElement)) {
|
|
174
|
+
this.app.send(new messages_1.SetCSSDataURLBased(id, data, this.app.getBaseHref()));
|
|
138
175
|
return;
|
|
139
176
|
}
|
|
140
177
|
if (this.textMasked.has(id)) {
|
|
@@ -156,12 +193,12 @@ class Observer {
|
|
|
156
193
|
this.recents[id] = r[1] || this.recents[id] || false;
|
|
157
194
|
}
|
|
158
195
|
bindTree(node) {
|
|
159
|
-
if (isIgnored(node)) {
|
|
196
|
+
if (this.isIgnored(node)) {
|
|
160
197
|
return;
|
|
161
198
|
}
|
|
162
199
|
this.bindNode(node);
|
|
163
200
|
const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT + NodeFilter.SHOW_TEXT, {
|
|
164
|
-
acceptNode: (node) => isIgnored(node) || this.app.nodes.getID(node) !== undefined
|
|
201
|
+
acceptNode: (node) => this.isIgnored(node) || this.app.nodes.getID(node) !== undefined
|
|
165
202
|
? NodeFilter.FILTER_REJECT
|
|
166
203
|
: NodeFilter.FILTER_ACCEPT,
|
|
167
204
|
}, false);
|
|
@@ -178,7 +215,10 @@ class Observer {
|
|
|
178
215
|
_commitNode(id, node) {
|
|
179
216
|
const parent = node.parentNode;
|
|
180
217
|
let parentID;
|
|
181
|
-
if (
|
|
218
|
+
if (this.isInstance(node, HTMLHtmlElement)) {
|
|
219
|
+
this.indexes[id] = 0;
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
182
222
|
if (parent === null) {
|
|
183
223
|
this.unbindNode(node);
|
|
184
224
|
return false;
|
|
@@ -193,7 +233,7 @@ class Observer {
|
|
|
193
233
|
return false;
|
|
194
234
|
}
|
|
195
235
|
if (this.textMasked.has(parentID) ||
|
|
196
|
-
(node
|
|
236
|
+
(this.isInstance(node, Element) && utils_1.hasOpenreplayAttribute(node, 'masked'))) {
|
|
197
237
|
this.textMasked.add(id);
|
|
198
238
|
}
|
|
199
239
|
let sibling = node.previousSibling;
|
|
@@ -216,7 +256,7 @@ class Observer {
|
|
|
216
256
|
throw 'commitNode: missing node index';
|
|
217
257
|
}
|
|
218
258
|
if (isNew === true) {
|
|
219
|
-
if (node
|
|
259
|
+
if (this.isInstance(node, Element)) {
|
|
220
260
|
if (parentID !== undefined) {
|
|
221
261
|
this.app.send(new messages_1.CreateElementNode(id, parentID, index, node.tagName, isSVGElement(node)));
|
|
222
262
|
}
|
|
@@ -224,8 +264,12 @@ class Observer {
|
|
|
224
264
|
const attr = node.attributes[i];
|
|
225
265
|
this.sendNodeAttribute(id, node, attr.nodeName, attr.value);
|
|
226
266
|
}
|
|
267
|
+
if (this.isInstance(node, HTMLIFrameElement) &&
|
|
268
|
+
(this.options.captureIFrames || node.getAttribute("data-openreplay-capture"))) {
|
|
269
|
+
this.handleIframe(node);
|
|
270
|
+
}
|
|
227
271
|
}
|
|
228
|
-
else if (node
|
|
272
|
+
else if (this.isInstance(node, Text)) {
|
|
229
273
|
// for text node id != 0, hence parentID !== undefined and parent is Element
|
|
230
274
|
this.app.send(new messages_1.CreateTextNode(id, parentID, index));
|
|
231
275
|
this.sendNodeData(id, parent, node.data);
|
|
@@ -237,7 +281,7 @@ class Observer {
|
|
|
237
281
|
}
|
|
238
282
|
const attr = this.attributesList[id];
|
|
239
283
|
if (attr !== undefined) {
|
|
240
|
-
if (!(node
|
|
284
|
+
if (!this.isInstance(node, Element)) {
|
|
241
285
|
throw 'commitNode: node is not an element';
|
|
242
286
|
}
|
|
243
287
|
for (const name of attr) {
|
|
@@ -245,7 +289,7 @@ class Observer {
|
|
|
245
289
|
}
|
|
246
290
|
}
|
|
247
291
|
if (this.textSet.has(id)) {
|
|
248
|
-
if (!(node
|
|
292
|
+
if (!this.isInstance(node, Text)) {
|
|
249
293
|
throw 'commitNode: node is not a text';
|
|
250
294
|
}
|
|
251
295
|
// for text node id != 0, hence parent is Element
|
|
@@ -274,8 +318,42 @@ class Observer {
|
|
|
274
318
|
}
|
|
275
319
|
this.clear();
|
|
276
320
|
}
|
|
321
|
+
handleIframe(iframe) {
|
|
322
|
+
const handle = () => {
|
|
323
|
+
const context = iframe.contentWindow;
|
|
324
|
+
const id = this.app.nodes.getID(iframe);
|
|
325
|
+
if (!context || id === undefined) {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
const observer = new Observer(this.app, this.options, context);
|
|
329
|
+
this.iframeObservers.push(observer);
|
|
330
|
+
observer.observeIframe(id, context);
|
|
331
|
+
};
|
|
332
|
+
this.app.attachEventListener(iframe, "load", handle);
|
|
333
|
+
handle();
|
|
334
|
+
}
|
|
335
|
+
// TODO: abstract common functionality, separate FrameObserver
|
|
336
|
+
observeIframe(id, context) {
|
|
337
|
+
const doc = context.document;
|
|
338
|
+
this.observer.observe(doc, {
|
|
339
|
+
childList: true,
|
|
340
|
+
attributes: true,
|
|
341
|
+
characterData: true,
|
|
342
|
+
subtree: true,
|
|
343
|
+
attributeOldValue: false,
|
|
344
|
+
characterDataOldValue: false,
|
|
345
|
+
});
|
|
346
|
+
this.bindTree(doc.documentElement);
|
|
347
|
+
const docID = this.app.nodes.getID(doc.documentElement);
|
|
348
|
+
if (docID === undefined) {
|
|
349
|
+
console.log("Wrong");
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
this.app.send(messages_1.CreateIFrameDocument(id, docID));
|
|
353
|
+
this.commitNodes();
|
|
354
|
+
}
|
|
277
355
|
observe() {
|
|
278
|
-
this.observer.observe(document, {
|
|
356
|
+
this.observer.observe(this.context.document, {
|
|
279
357
|
childList: true,
|
|
280
358
|
attributes: true,
|
|
281
359
|
characterData: true,
|
|
@@ -284,10 +362,12 @@ class Observer {
|
|
|
284
362
|
characterDataOldValue: false,
|
|
285
363
|
});
|
|
286
364
|
this.app.send(new messages_1.CreateDocument());
|
|
287
|
-
this.bindTree(document.documentElement);
|
|
365
|
+
this.bindTree(this.context.document.documentElement);
|
|
288
366
|
this.commitNodes();
|
|
289
367
|
}
|
|
290
368
|
disconnect() {
|
|
369
|
+
this.iframeObservers.forEach(o => o.disconnect());
|
|
370
|
+
this.iframeObservers = [];
|
|
291
371
|
this.observer.disconnect();
|
|
292
372
|
this.clear();
|
|
293
373
|
}
|
package/cjs/index.js
CHANGED
|
@@ -23,13 +23,13 @@ const utils_1 = require("./utils");
|
|
|
23
23
|
const DOCS_SETUP = '/installation/setup-or';
|
|
24
24
|
function processOptions(obj) {
|
|
25
25
|
if (obj == null) {
|
|
26
|
-
console.error(`OpenReplay: invalid options argument type. Please, check documentation on
|
|
26
|
+
console.error(`OpenReplay: invalid options argument type. Please, check documentation on ${utils_1.DOCS_HOST}${DOCS_SETUP}`);
|
|
27
27
|
return false;
|
|
28
28
|
}
|
|
29
29
|
if (typeof obj.projectKey !== 'string') {
|
|
30
30
|
if (typeof obj.projectKey !== 'number') {
|
|
31
31
|
if (typeof obj.projectID !== 'number') { // Back compatability
|
|
32
|
-
console.error(`OpenReplay: projectKey is missing or wrong type (string is expected). Please, check
|
|
32
|
+
console.error(`OpenReplay: projectKey is missing or wrong type (string is expected). Please, check ${utils_1.DOCS_HOST}${DOCS_SETUP} for more information.`);
|
|
33
33
|
return false;
|
|
34
34
|
}
|
|
35
35
|
else {
|
|
@@ -43,7 +43,7 @@ function processOptions(obj) {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
if (typeof obj.sessionToken !== 'string' && obj.sessionToken != null) {
|
|
46
|
-
console.warn(`OpenReplay: invalid options argument type. Please, check documentation on
|
|
46
|
+
console.warn(`OpenReplay: invalid options argument type. Please, check documentation on ${utils_1.DOCS_HOST}${DOCS_SETUP}`);
|
|
47
47
|
}
|
|
48
48
|
return true;
|
|
49
49
|
}
|
|
@@ -69,6 +69,10 @@ class API {
|
|
|
69
69
|
if (!utils_1.IN_BROWSER || !processOptions(options)) {
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
72
|
+
if (window.__OPENREPLAY__) {
|
|
73
|
+
console.error("OpenReplay: one tracker instance has been initialised already");
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
72
76
|
if (!options.__DISABLE_SECURE_MODE && location.protocol !== 'https:') {
|
|
73
77
|
console.error("OpenReplay: Your website must be publicly accessible and running on SSL in order for OpenReplay to properly capture and replay the user session. You can disable this check by setting `__DISABLE_SECURE_MODE` option to `true` if you are testing in localhost. Keep in mind, that asset files on a local machine are not available to the outside world. This might affect tracking if you use css files.");
|
|
74
78
|
return;
|
|
@@ -98,17 +102,17 @@ class API {
|
|
|
98
102
|
performance_1.default(this.app, options);
|
|
99
103
|
scroll_1.default(this.app);
|
|
100
104
|
longtasks_1.default(this.app);
|
|
101
|
-
window.__OPENREPLAY__ =
|
|
105
|
+
window.__OPENREPLAY__ = this;
|
|
102
106
|
}
|
|
103
107
|
else {
|
|
104
|
-
console.log("OpenReplay: browser doesn't support API required for tracking.");
|
|
108
|
+
console.log("OpenReplay: browser doesn't support API required for tracking or doNotTrack is set to 1.");
|
|
105
109
|
const req = new XMLHttpRequest();
|
|
106
110
|
const orig = options.ingestPoint || app_1.DEFAULT_INGEST_POINT;
|
|
107
111
|
req.open("POST", orig + "/v1/web/not-started");
|
|
108
112
|
// no-cors issue only with text/plain or not-set Content-Type
|
|
109
113
|
// req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
|
110
114
|
req.send(JSON.stringify({
|
|
111
|
-
trackerVersion: '3.
|
|
115
|
+
trackerVersion: '3.4.1',
|
|
112
116
|
projectKey: options.projectKey,
|
|
113
117
|
doNotTrack,
|
|
114
118
|
// TODO: add precise reason (an exact API missing)
|
|
@@ -130,7 +134,7 @@ class API {
|
|
|
130
134
|
}
|
|
131
135
|
start() {
|
|
132
136
|
if (!utils_1.IN_BROWSER) {
|
|
133
|
-
console.error(`OpenReplay: you are trying to start Tracker on a node.js environment. If you want to use OpenReplay with SSR, please, use componentDidMount or useEffect API for placing the \`tracker.start()\` line. Check documentation on
|
|
137
|
+
console.error(`OpenReplay: you are trying to start Tracker on a node.js environment. If you want to use OpenReplay with SSR, please, use componentDidMount or useEffect API for placing the \`tracker.start()\` line. Check documentation on ${utils_1.DOCS_HOST}${DOCS_SETUP}`);
|
|
134
138
|
return;
|
|
135
139
|
}
|
|
136
140
|
if (this.app === null) {
|
package/cjs/messages/index.d.ts
CHANGED
|
@@ -434,4 +434,12 @@ declare class _MouseClick implements Message {
|
|
|
434
434
|
encode(writer: Writer): boolean;
|
|
435
435
|
}
|
|
436
436
|
export declare const MouseClick: typeof _MouseClick & ((id: number, hesitationTime: number, label: string, selector: string) => _MouseClick);
|
|
437
|
+
declare class _CreateIFrameDocument implements Message {
|
|
438
|
+
frameID: number;
|
|
439
|
+
id: number;
|
|
440
|
+
readonly _id: number;
|
|
441
|
+
constructor(frameID: number, id: number);
|
|
442
|
+
encode(writer: Writer): boolean;
|
|
443
|
+
}
|
|
444
|
+
export declare const CreateIFrameDocument: typeof _CreateIFrameDocument & ((frameID: number, id: number) => _CreateIFrameDocument);
|
|
437
445
|
export {};
|