UNPKG

ecsy

Version:
172 lines (151 loc) 4.99 kB
/* global Peer */ import { injectScript, generateId } from "./utils.js"; import { hasWindow } from "../Utils.js"; function hookConsoleAndErrors(connection) { var wrapFunctions = ["error", "warning", "log"]; wrapFunctions.forEach((key) => { if (typeof console[key] === "function") { var fn = console[key].bind(console); console[key] = (...args) => { connection.send({ method: "console", type: key, args: JSON.stringify(args), }); return fn.apply(null, args); }; } }); window.addEventListener("error", (error) => { connection.send({ method: "error", error: JSON.stringify({ message: error.error.message, stack: error.error.stack, }), }); }); } function includeRemoteIdHTML(remoteId) { let infoDiv = document.createElement("div"); infoDiv.style.cssText = ` align-items: center; background-color: #333; color: #aaa; display:flex; font-family: Arial; font-size: 1.1em; height: 40px; justify-content: center; left: 0; opacity: 0.9; position: absolute; right: 0; text-align: center; top: 0; `; infoDiv.innerHTML = `Open ECSY devtools to connect to this page using the code:&nbsp;<b style="color: #fff">${remoteId}</b>&nbsp;<button onClick="generateNewCode()">Generate new code</button>`; document.body.appendChild(infoDiv); return infoDiv; } export function enableRemoteDevtools(remoteId) { if (!hasWindow) { console.warn("Remote devtools not available outside the browser"); return; } window.generateNewCode = () => { window.localStorage.clear(); remoteId = generateId(6); window.localStorage.setItem("ecsyRemoteId", remoteId); window.location.reload(false); }; remoteId = remoteId || window.localStorage.getItem("ecsyRemoteId"); if (!remoteId) { remoteId = generateId(6); window.localStorage.setItem("ecsyRemoteId", remoteId); } let infoDiv = includeRemoteIdHTML(remoteId); window.__ECSY_REMOTE_DEVTOOLS_INJECTED = true; window.__ECSY_REMOTE_DEVTOOLS = {}; let Version = ""; // This is used to collect the worlds created before the communication is being established let worldsBeforeLoading = []; let onWorldCreated = (e) => { var world = e.detail.world; Version = e.detail.version; worldsBeforeLoading.push(world); }; window.addEventListener("ecsy-world-created", onWorldCreated); let onLoaded = () => { // var peer = new Peer(remoteId); var peer = new Peer(remoteId, { host: "peerjs.ecsy.io", secure: true, port: 443, config: { iceServers: [ { url: "stun:stun.l.google.com:19302" }, { url: "stun:stun1.l.google.com:19302" }, { url: "stun:stun2.l.google.com:19302" }, { url: "stun:stun3.l.google.com:19302" }, { url: "stun:stun4.l.google.com:19302" }, ], }, debug: 3, }); peer.on("open", (/* id */) => { peer.on("connection", (connection) => { window.__ECSY_REMOTE_DEVTOOLS.connection = connection; connection.on("open", function () { // infoDiv.style.visibility = "hidden"; infoDiv.innerHTML = "Connected"; // Receive messages connection.on("data", function (data) { if (data.type === "init") { var script = document.createElement("script"); script.setAttribute("type", "text/javascript"); script.onload = () => { script.parentNode.removeChild(script); // Once the script is injected we don't need to listen window.removeEventListener( "ecsy-world-created", onWorldCreated ); worldsBeforeLoading.forEach((world) => { var event = new CustomEvent("ecsy-world-created", { detail: { world: world, version: Version }, }); window.dispatchEvent(event); }); }; script.innerHTML = data.script; (document.head || document.documentElement).appendChild(script); script.onload(); hookConsoleAndErrors(connection); } else if (data.type === "executeScript") { let value = eval(data.script); if (data.returnEval) { connection.send({ method: "evalReturn", value: value, }); } } }); }); }); }); }; // Inject PeerJS script injectScript( "https://cdn.jsdelivr.net/npm/peerjs@0.3.20/dist/peer.min.js", onLoaded ); } if (hasWindow) { const urlParams = new URLSearchParams(window.location.search); // @todo Provide a way to disable it if needed if (urlParams.has("enable-remote-devtools")) { enableRemoteDevtools(); } }