rrweb
Version:
record and replay the web
3 lines (2 loc) • 21.4 kB
JavaScript
var rrwebCanvasWebRTCRecord=function(_){"use strict";/*! simple-peer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */function g(d){const e=new Uint8Array(d);for(let t=0;t<d;t++)e[t]=Math.random()*256|0;return e}function f(){if(typeof globalThis>"u")return null;const d={RTCPeerConnection:globalThis.RTCPeerConnection||globalThis.mozRTCPeerConnection||globalThis.webkitRTCPeerConnection,RTCSessionDescription:globalThis.RTCSessionDescription||globalThis.mozRTCSessionDescription||globalThis.webkitRTCSessionDescription,RTCIceCandidate:globalThis.RTCIceCandidate||globalThis.mozRTCIceCandidate||globalThis.webkitRTCIceCandidate};return d.RTCPeerConnection?d:null}function r(d,e){return Object.defineProperty(d,"code",{value:e,enumerable:!0,configurable:!0}),d}function p(d){return d.replace(/a=ice-options:trickle\s\n/g,"")}function y(d){console.warn(d)}class l{constructor(e={}){if(this._map=new Map,this._id=g(4).toString("hex").slice(0,7),this._doDebug=e.debug,this._debug("new peer %o",e),this.channelName=e.initiator?e.channelName||g(20).toString("hex"):null,this.initiator=e.initiator||!1,this.channelConfig=e.channelConfig||l.channelConfig,this.channelNegotiated=this.channelConfig.negotiated,this.config=Object.assign({},l.config,e.config),this.offerOptions=e.offerOptions||{},this.answerOptions=e.answerOptions||{},this.sdpTransform=e.sdpTransform||(t=>t),this.streams=e.streams||(e.stream?[e.stream]:[]),this.trickle=e.trickle!==void 0?e.trickle:!0,this.allowHalfTrickle=e.allowHalfTrickle!==void 0?e.allowHalfTrickle:!1,this.iceCompleteTimeout=e.iceCompleteTimeout||5e3,this.destroyed=!1,this.destroying=!1,this._connected=!1,this.remoteAddress=void 0,this.remoteFamily=void 0,this.remotePort=void 0,this.localAddress=void 0,this.localFamily=void 0,this.localPort=void 0,this._wrtc=e.wrtc&&typeof e.wrtc=="object"?e.wrtc:f(),!this._wrtc)throw r(typeof window>"u"?new Error("No WebRTC support: Specify `opts.wrtc` option in this environment"):new Error("No WebRTC support: Not a supported browser"),"ERR_WEBRTC_SUPPORT");this._pcReady=!1,this._channelReady=!1,this._iceComplete=!1,this._iceCompleteTimer=null,this._channel=null,this._pendingCandidates=[],this._isNegotiating=!1,this._firstNegotiation=!0,this._batchedNegotiation=!1,this._queuedNegotiation=!1,this._sendersAwaitingStable=[],this._senderMap=new Map,this._closingInterval=null,this._remoteTracks=[],this._remoteStreams=[],this._chunk=null,this._cb=null,this._interval=null;try{this._pc=new this._wrtc.RTCPeerConnection(this.config)}catch(t){this.destroy(r(t,"ERR_PC_CONSTRUCTOR"));return}this._isReactNativeWebrtc=typeof this._pc._peerConnectionId=="number",this._pc.oniceconnectionstatechange=()=>{this._onIceStateChange()},this._pc.onicegatheringstatechange=()=>{this._onIceStateChange()},this._pc.onconnectionstatechange=()=>{this._onConnectionStateChange()},this._pc.onsignalingstatechange=()=>{this._onSignalingStateChange()},this._pc.onicecandidate=t=>{this._onIceCandidate(t)},typeof this._pc.peerIdentity=="object"&&this._pc.peerIdentity.catch(t=>{this.destroy(r(t,"ERR_PC_PEER_IDENTITY"))}),this.initiator||this.channelNegotiated?this._setupData({channel:this._pc.createDataChannel(this.channelName,this.channelConfig)}):this._pc.ondatachannel=t=>{this._setupData(t)},this.streams&&this.streams.forEach(t=>{this.addStream(t)}),this._pc.ontrack=t=>{this._onTrack(t)},this._debug("initial negotiation"),this._needsNegotiation()}get bufferSize(){return this._channel&&this._channel.bufferedAmount||0}get connected(){return this._connected&&this._channel.readyState==="open"}address(){return{port:this.localPort,family:this.localFamily,address:this.localAddress}}signal(e){if(!this.destroying){if(this.destroyed)throw r(new Error("cannot signal after peer is destroyed"),"ERR_DESTROYED");if(typeof e=="string")try{e=JSON.parse(e)}catch{e={}}this._debug("signal()"),e.renegotiate&&this.initiator&&(this._debug("got request to renegotiate"),this._needsNegotiation()),e.transceiverRequest&&this.initiator&&(this._debug("got request for transceiver"),this.addTransceiver(e.transceiverRequest.kind,e.transceiverRequest.init)),e.candidate&&(this._pc.remoteDescription&&this._pc.remoteDescription.type?this._addIceCandidate(e.candidate):this._pendingCandidates.push(e.candidate)),e.sdp&&this._pc.setRemoteDescription(new this._wrtc.RTCSessionDescription(e)).then(()=>{this.destroyed||(this._pendingCandidates.forEach(t=>{this._addIceCandidate(t)}),this._pendingCandidates=[],this._pc.remoteDescription.type==="offer"&&this._createAnswer())}).catch(t=>{this.destroy(r(t,"ERR_SET_REMOTE_DESCRIPTION"))}),!e.sdp&&!e.candidate&&!e.renegotiate&&!e.transceiverRequest&&this.destroy(r(new Error("signal() called with invalid signal data"),"ERR_SIGNALING"))}}_addIceCandidate(e){const t=new this._wrtc.RTCIceCandidate(e);this._pc.addIceCandidate(t).catch(s=>{!t.address||t.address.endsWith(".local")?y("Ignoring unsupported ICE candidate."):this.destroy(r(s,"ERR_ADD_ICE_CANDIDATE"))})}send(e){if(!this.destroying){if(this.destroyed)throw r(new Error("cannot send after peer is destroyed"),"ERR_DESTROYED");this._channel.send(e)}}addTransceiver(e,t){if(!this.destroying){if(this.destroyed)throw r(new Error("cannot addTransceiver after peer is destroyed"),"ERR_DESTROYED");if(this._debug("addTransceiver()"),this.initiator)try{this._pc.addTransceiver(e,t),this._needsNegotiation()}catch(s){this.destroy(r(s,"ERR_ADD_TRANSCEIVER"))}else this.emit("signal",{type:"transceiverRequest",transceiverRequest:{kind:e,init:t}})}}addStream(e){if(!this.destroying){if(this.destroyed)throw r(new Error("cannot addStream after peer is destroyed"),"ERR_DESTROYED");this._debug("addStream()"),e.getTracks().forEach(t=>{this.addTrack(t,e)})}}addTrack(e,t){if(this.destroying)return;if(this.destroyed)throw r(new Error("cannot addTrack after peer is destroyed"),"ERR_DESTROYED");this._debug("addTrack()");const s=this._senderMap.get(e)||new Map;let i=s.get(t);if(!i)i=this._pc.addTrack(e,t),s.set(t,i),this._senderMap.set(e,s),this._needsNegotiation();else throw i.removed?r(new Error("Track has been removed. You should enable/disable tracks that you want to re-add."),"ERR_SENDER_REMOVED"):r(new Error("Track has already been added to that stream."),"ERR_SENDER_ALREADY_ADDED")}replaceTrack(e,t,s){if(this.destroying)return;if(this.destroyed)throw r(new Error("cannot replaceTrack after peer is destroyed"),"ERR_DESTROYED");this._debug("replaceTrack()");const i=this._senderMap.get(e),n=i?i.get(s):null;if(!n)throw r(new Error("Cannot replace track that was never added."),"ERR_TRACK_NOT_ADDED");t&&this._senderMap.set(t,i),n.replaceTrack!=null?n.replaceTrack(t):this.destroy(r(new Error("replaceTrack is not supported in this browser"),"ERR_UNSUPPORTED_REPLACETRACK"))}removeTrack(e,t){if(this.destroying)return;if(this.destroyed)throw r(new Error("cannot removeTrack after peer is destroyed"),"ERR_DESTROYED");this._debug("removeSender()");const s=this._senderMap.get(e),i=s?s.get(t):null;if(!i)throw r(new Error("Cannot remove track that was never added."),"ERR_TRACK_NOT_ADDED");try{i.removed=!0,this._pc.removeTrack(i)}catch(n){n.name==="NS_ERROR_UNEXPECTED"?this._sendersAwaitingStable.push(i):this.destroy(r(n,"ERR_REMOVE_TRACK"))}this._needsNegotiation()}removeStream(e){if(!this.destroying){if(this.destroyed)throw r(new Error("cannot removeStream after peer is destroyed"),"ERR_DESTROYED");this._debug("removeSenders()"),e.getTracks().forEach(t=>{this.removeTrack(t,e)})}}_needsNegotiation(){this._debug("_needsNegotiation"),!this._batchedNegotiation&&(this._batchedNegotiation=!0,queueMicrotask(()=>{this._batchedNegotiation=!1,this.initiator||!this._firstNegotiation?(this._debug("starting batched negotiation"),this.negotiate()):this._debug("non-initiator initial negotiation request discarded"),this._firstNegotiation=!1}))}negotiate(){if(!this.destroying){if(this.destroyed)throw r(new Error("cannot negotiate after peer is destroyed"),"ERR_DESTROYED");this.initiator?this._isNegotiating?(this._queuedNegotiation=!0,this._debug("already negotiating, queueing")):(this._debug("start negotiation"),setTimeout(()=>{this._createOffer()},0)):this._isNegotiating?(this._queuedNegotiation=!0,this._debug("already negotiating, queueing")):(this._debug("requesting negotiation from initiator"),this.emit("signal",{type:"renegotiate",renegotiate:!0})),this._isNegotiating=!0}}destroy(e){this.destroyed||this.destroying||(this.destroying=!0,this._debug("destroying (error: %s)",e&&(e.message||e)),queueMicrotask(()=>{if(this.destroyed=!0,this.destroying=!1,this._debug("destroy (error: %s)",e&&(e.message||e)),this._connected=!1,this._pcReady=!1,this._channelReady=!1,this._remoteTracks=null,this._remoteStreams=null,this._senderMap=null,clearInterval(this._closingInterval),this._closingInterval=null,clearInterval(this._interval),this._interval=null,this._chunk=null,this._cb=null,this._channel){try{this._channel.close()}catch{}this._channel.onmessage=null,this._channel.onopen=null,this._channel.onclose=null,this._channel.onerror=null}if(this._pc){try{this._pc.close()}catch{}this._pc.oniceconnectionstatechange=null,this._pc.onicegatheringstatechange=null,this._pc.onsignalingstatechange=null,this._pc.onicecandidate=null,this._pc.ontrack=null,this._pc.ondatachannel=null}this._pc=null,this._channel=null,e&&this.emit("error",e),this.emit("close")}))}_setupData(e){if(!e.channel)return this.destroy(r(new Error("Data channel event is missing `channel` property"),"ERR_DATA_CHANNEL"));this._channel=e.channel,this._channel.binaryType="arraybuffer",typeof this._channel.bufferedAmountLowThreshold=="number"&&(this._channel.bufferedAmountLowThreshold=65536),this.channelName=this._channel.label,this._channel.onmessage=s=>{this._onChannelMessage(s)},this._channel.onbufferedamountlow=()=>{this._onChannelBufferedAmountLow()},this._channel.onopen=()=>{this._onChannelOpen()},this._channel.onclose=()=>{this._onChannelClose()},this._channel.onerror=s=>{this.destroy(r(s,"ERR_DATA_CHANNEL"))};let t=!1;this._closingInterval=setInterval(()=>{this._channel&&this._channel.readyState==="closing"?(t&&this._onChannelClose(),t=!0):t=!1},5e3)}_startIceCompleteTimeout(){this.destroyed||this._iceCompleteTimer||(this._debug("started iceComplete timeout"),this._iceCompleteTimer=setTimeout(()=>{this._iceComplete||(this._iceComplete=!0,this._debug("iceComplete timeout completed"),this.emit("iceTimeout"),this.emit("_iceComplete"))},this.iceCompleteTimeout))}_createOffer(){this.destroyed||this._pc.createOffer(this.offerOptions).then(e=>{if(this.destroyed)return;!this.trickle&&!this.allowHalfTrickle&&(e.sdp=p(e.sdp)),e.sdp=this.sdpTransform(e.sdp);const t=()=>{if(this.destroyed)return;const n=this._pc.localDescription||e;this._debug("signal"),this.emit("signal",{type:n.type,sdp:n.sdp})},s=()=>{this._debug("createOffer success"),!this.destroyed&&(this.trickle||this._iceComplete?t():this.once("_iceComplete",t))},i=n=>{this.destroy(r(n,"ERR_SET_LOCAL_DESCRIPTION"))};this._pc.setLocalDescription(e).then(s).catch(i)}).catch(e=>{this.destroy(r(e,"ERR_CREATE_OFFER"))})}_requestMissingTransceivers(){this._pc.getTransceivers&&this._pc.getTransceivers().forEach(e=>{!e.mid&&e.sender.track&&!e.requested&&(e.requested=!0,this.addTransceiver(e.sender.track.kind))})}_createAnswer(){this.destroyed||this._pc.createAnswer(this.answerOptions).then(e=>{if(this.destroyed)return;!this.trickle&&!this.allowHalfTrickle&&(e.sdp=p(e.sdp)),e.sdp=this.sdpTransform(e.sdp);const t=()=>{if(this.destroyed)return;const n=this._pc.localDescription||e;this._debug("signal"),this.emit("signal",{type:n.type,sdp:n.sdp}),this.initiator||this._requestMissingTransceivers()},s=()=>{this.destroyed||(this.trickle||this._iceComplete?t():this.once("_iceComplete",t))},i=n=>{this.destroy(r(n,"ERR_SET_LOCAL_DESCRIPTION"))};this._pc.setLocalDescription(e).then(s).catch(i)}).catch(e=>{this.destroy(r(e,"ERR_CREATE_ANSWER"))})}_onConnectionStateChange(){this.destroyed||this._pc.connectionState==="failed"&&this.destroy(r(new Error("Connection failed."),"ERR_CONNECTION_FAILURE"))}_onIceStateChange(){if(this.destroyed)return;const e=this._pc.iceConnectionState,t=this._pc.iceGatheringState;this._debug("iceStateChange (connection: %s) (gathering: %s)",e,t),this.emit("iceStateChange",e,t),(e==="connected"||e==="completed")&&(this._pcReady=!0,this._maybeReady()),e==="failed"&&this.destroy(r(new Error("Ice connection failed."),"ERR_ICE_CONNECTION_FAILURE")),e==="closed"&&this.destroy(r(new Error("Ice connection closed."),"ERR_ICE_CONNECTION_CLOSED"))}getStats(e){const t=s=>(Object.prototype.toString.call(s.values)==="[object Array]"&&s.values.forEach(i=>{Object.assign(s,i)}),s);this._pc.getStats.length===0||this._isReactNativeWebrtc?this._pc.getStats().then(s=>{const i=[];s.forEach(n=>{i.push(t(n))}),e(null,i)},s=>e(s)):this._pc.getStats.length>0?this._pc.getStats(s=>{if(this.destroyed)return;const i=[];s.result().forEach(n=>{const o={};n.names().forEach(u=>{o[u]=n.stat(u)}),o.id=n.id,o.type=n.type,o.timestamp=n.timestamp,i.push(t(o))}),e(null,i)},s=>e(s)):e(null,[])}_maybeReady(){if(this._debug("maybeReady pc %s channel %s",this._pcReady,this._channelReady),this._connected||this._connecting||!this._pcReady||!this._channelReady)return;this._connecting=!0;const e=()=>{this.destroyed||this.getStats((t,s)=>{if(this.destroyed)return;t&&(s=[]);const i={},n={},o={};let u=!1;s.forEach(a=>{(a.type==="remotecandidate"||a.type==="remote-candidate")&&(i[a.id]=a),(a.type==="localcandidate"||a.type==="local-candidate")&&(n[a.id]=a),(a.type==="candidatepair"||a.type==="candidate-pair")&&(o[a.id]=a)});const R=a=>{u=!0;let h=n[a.localCandidateId];h&&(h.ip||h.address)?(this.localAddress=h.ip||h.address,this.localPort=Number(h.port)):h&&h.ipAddress?(this.localAddress=h.ipAddress,this.localPort=Number(h.portNumber)):typeof a.googLocalAddress=="string"&&(h=a.googLocalAddress.split(":"),this.localAddress=h[0],this.localPort=Number(h[1])),this.localAddress&&(this.localFamily=this.localAddress.includes(":")?"IPv6":"IPv4");let c=i[a.remoteCandidateId];c&&(c.ip||c.address)?(this.remoteAddress=c.ip||c.address,this.remotePort=Number(c.port)):c&&c.ipAddress?(this.remoteAddress=c.ipAddress,this.remotePort=Number(c.portNumber)):typeof a.googRemoteAddress=="string"&&(c=a.googRemoteAddress.split(":"),this.remoteAddress=c[0],this.remotePort=Number(c[1])),this.remoteAddress&&(this.remoteFamily=this.remoteAddress.includes(":")?"IPv6":"IPv4"),this._debug("connect local: %s:%s remote: %s:%s",this.localAddress,this.localPort,this.remoteAddress,this.remotePort)};if(s.forEach(a=>{a.type==="transport"&&a.selectedCandidatePairId&&R(o[a.selectedCandidatePairId]),(a.type==="googCandidatePair"&&a.googActiveConnection==="true"||(a.type==="candidatepair"||a.type==="candidate-pair")&&a.selected)&&R(a)}),!u&&(!Object.keys(o).length||Object.keys(n).length)){setTimeout(e,100);return}else this._connecting=!1,this._connected=!0;if(this._chunk){try{this.send(this._chunk)}catch(h){return this.destroy(r(h,"ERR_DATA_CHANNEL"))}this._chunk=null,this._debug('sent chunk from "write before connect"');const a=this._cb;this._cb=null,a(null)}typeof this._channel.bufferedAmountLowThreshold!="number"&&(this._interval=setInterval(()=>this._onInterval(),150),this._interval.unref&&this._interval.unref()),this._debug("connect"),this.emit("connect")})};e()}_onInterval(){!this._cb||!this._channel||this._channel.bufferedAmount>65536||this._onChannelBufferedAmountLow()}_onSignalingStateChange(){this.destroyed||(this._pc.signalingState==="stable"&&(this._isNegotiating=!1,this._debug("flushing sender queue",this._sendersAwaitingStable),this._sendersAwaitingStable.forEach(e=>{this._pc.removeTrack(e),this._queuedNegotiation=!0}),this._sendersAwaitingStable=[],this._queuedNegotiation?(this._debug("flushing negotiation queue"),this._queuedNegotiation=!1,this._needsNegotiation()):(this._debug("negotiated"),this.emit("negotiated"))),this._debug("signalingStateChange %s",this._pc.signalingState),this.emit("signalingStateChange",this._pc.signalingState))}_onIceCandidate(e){this.destroyed||(e.candidate&&this.trickle?this.emit("signal",{type:"candidate",candidate:{candidate:e.candidate.candidate,sdpMLineIndex:e.candidate.sdpMLineIndex,sdpMid:e.candidate.sdpMid}}):!e.candidate&&!this._iceComplete&&(this._iceComplete=!0,this.emit("_iceComplete")),e.candidate&&this._startIceCompleteTimeout())}_onChannelMessage(e){if(this.destroyed)return;let t=e.data;t instanceof ArrayBuffer&&(t=new Uint8Array(t)),this.emit("data",t)}_onChannelBufferedAmountLow(){if(this.destroyed||!this._cb)return;this._debug("ending backpressure: bufferedAmount %d",this._channel.bufferedAmount);const e=this._cb;this._cb=null,e(null)}_onChannelOpen(){this._connected||this.destroyed||(this._debug("on channel open"),this._channelReady=!0,this._maybeReady())}_onChannelClose(){this.destroyed||(this._debug("on channel close"),this.destroy())}_onTrack(e){this.destroyed||e.streams.forEach(t=>{this._debug("on track"),this.emit("track",e.track,t),this._remoteTracks.push({track:e.track,stream:t}),!this._remoteStreams.some(s=>s.id===t.id)&&(this._remoteStreams.push(t),queueMicrotask(()=>{this._debug("on stream"),this.emit("stream",t)}))})}_debug(...e){!this._doDebug||(e[0]="["+this._id+"] "+e[0],console.log(...e))}on(e,t){const s=this._map;s.has(e)||s.set(e,new Set),s.get(e).add(t)}off(e,t){const s=this._map,i=s.get(e);!i||(i.delete(t),i.size===0&&s.delete(e))}once(e,t){const s=(...i)=>{this.off(e,s),t(...i)};this.on(e,s)}emit(e,...t){const s=this._map;if(!!s.has(e))for(const i of s.get(e))try{i(...t)}catch(n){console.error(n)}}}l.WEBRTC_SUPPORT=!!f(),l.config={iceServers:[{urls:["stun:stun.l.google.com:19302","stun:global.stun.twilio.com:3478"]}],sdpSemantics:"unified-plan"},l.channelConfig={};const m="rrweb/canvas-webrtc@1";class C{constructor({signalSendCallback:e,peer:t}){this.peer=null,this.streamMap=new Map,this.incomingStreams=new Set,this.outgoingStreams=new Set,this.streamNodeMap=new Map,this.canvasWindowMap=new Map,this.windowPeerMap=new WeakMap,this.peerWindowMap=new WeakMap,this.signalSendCallback=e,window.addEventListener("message",this.windowPostMessageHandler.bind(this)),t&&(this.peer=t)}initPlugin(){return{name:m,getMirror:({nodeMirror:e,crossOriginIframeMirror:t})=>{this.mirror=e,this.crossOriginIframeMirror=t},options:{}}}signalReceive(e){var t;this.peer||this.setupPeer(),(t=this.peer)==null||t.signal(e)}signalReceiveFromCrossOriginIframe(e,t){this.setupPeer(t).signal(e)}startStream(e,t){var s,i;this.peer||this.setupPeer();const n={nodeId:e,streamId:t.id};(s=this.peer)==null||s.send(JSON.stringify(n)),this.outgoingStreams.has(t)||(i=this.peer)==null||i.addStream(t),this.outgoingStreams.add(t)}setupPeer(e){let t;if(e){const i=this.windowPeerMap.get(e);if(i)return i;t=new l({initiator:!1}),this.windowPeerMap.set(e,t),this.peerWindowMap.set(t,e)}else{if(this.peer)return this.peer;t=this.peer=new l({initiator:!0})}const s=i=>{if(!i)return this.peer=null;this.windowPeerMap.delete(i),this.peerWindowMap.delete(t)};return t.on("error",i=>{s(e),console.log("error",i)}),t.on("close",()=>{s(e),console.log("closing")}),t.on("signal",i=>{var n,o;this.inRootFrame()?t===this.peer?this.signalSendCallback(i):(n=this.peerWindowMap.get(t))==null||n.postMessage({type:"rrweb-canvas-webrtc",data:{type:"signal",signal:i}},"*"):(o=window.top)==null||o.postMessage({type:"rrweb-canvas-webrtc",data:{type:"signal",signal:i}},"*")}),t.on("connect",()=>{if(!(this.inRootFrame()&&t!==this.peer))for(const[i,n]of this.streamMap)this.startStream(i,n)}),this.inRootFrame()&&(t.on("data",i=>{try{const n=JSON.parse(i);this.streamNodeMap.set(n.streamId,n.nodeId)}catch(n){console.error("Could not parse data",n)}this.flushStreams()}),t.on("stream",i=>{this.incomingStreams.add(i),this.flushStreams()})),t}setupStream(e,t){var s;if(e===-1)return!1;let i=this.streamMap.get(t||e);if(i)return i;const n=this.mirror.getNode(e);return!n||!("captureStream"in n)?this.setupStreamInCrossOriginIframe(e,t||e):(this.inRootFrame()||(s=window.top)==null||s.postMessage({type:"rrweb-canvas-webrtc",data:{type:"i-have-canvas",rootId:t||e}},"*"),i=n.captureStream(),this.streamMap.set(t||e,i),this.setupPeer(),i)}flushStreams(){this.incomingStreams.forEach(e=>{const t=this.streamNodeMap.get(e.id);!t||this.startStream(t,e)})}inRootFrame(){return Boolean(window.top&&window.top===window)}setupStreamInCrossOriginIframe(e,t){let s=!1;return document.querySelectorAll("iframe").forEach(i=>{var n;if(s)return;const o=this.crossOriginIframeMirror.getRemoteId(i,e);o!==-1&&(s=!0,(n=i.contentWindow)==null||n.postMessage({type:"rrweb-canvas-webrtc",data:{type:"who-has-canvas",id:o,rootId:t}},"*"))}),s}isCrossOriginIframeMessageEventContent(e){return Boolean("type"in e.data&&"data"in e.data&&e.data.type==="rrweb-canvas-webrtc"&&e.data.data)}windowPostMessageHandler(e){if(!this.isCrossOriginIframeMessageEventContent(e))return;const{type:t}=e.data.data;if(t==="who-has-canvas"){const{id:s,rootId:i}=e.data.data;this.setupStream(s,i)}else if(t==="signal"){const{signal:s}=e.data.data,{source:i}=e;if(!i||!("self"in i))return;this.inRootFrame()?this.signalReceiveFromCrossOriginIframe(s,i):this.signalReceive(s)}else if(t==="i-have-canvas"){const{rootId:s}=e.data.data,{source:i}=e;if(!i||!("self"in i))return;this.canvasWindowMap.set(s,i)}}}return _.PLUGIN_NAME=m,_.RRWebPluginCanvasWebRTCRecord=C,Object.defineProperty(_,"__esModule",{value:!0}),_}({});
//# sourceMappingURL=canvas-webrtc-record.min.js.map