UNPKG

armo-breadboard

Version:

Edit a live React component's source in real time.

160 lines (143 loc) 3.92 kB
(function(){ 'use strict'; /** * Check circular references. * Copyright (c) 2014 Freeform Systems * https://github.com/tmpfs/circular * * @param ref A function that returns an alternative reference. * @param methods A boolean that indicates functions should be * coerced to strings. */ function circular() { var seen = []; return function (key, val) { if(typeof val === 'function') { val = val.toString(); } if(!val || typeof (val) !== 'object') { return val; } if(~seen.indexOf(val)) { return '[Circular]'; } seen.push(val); return val; }; } function stringify(obj) { return JSON.stringify(obj, circular()); } if (typeof __BREADBOARD_SETTINGS !== 'object') { window.top.postMessage({ type: 'breadboard-host/source-required', mountpointId: parseInt(window.location.hash.substr(1)), }, '*') } else { init(__BREADBOARD_SETTINGS); const oldOnLoad = window.onload; window.onload = function(e) { if (oldOnLoad) { oldOnLoad(e); } sendLoad(); } } window.addEventListener("message", handleMessage, false); function init(settings) { /* TODO: show error message and bail if window.Proxy doesn't exist */ const windowLocation = settings.location; const windowProxy = new Proxy(window, { get: function(target, name) { return name === 'location' ? windowLocation : target[name]; }, }); window.__BREADBOARD = { window: windowProxy, location: windowLocation, }; sendInit(); } function sendMessage(type, config={}) { window.top.postMessage(Object.assign({}, config, { type: 'breadboard-host/'+type, mountpointId: __BREADBOARD_SETTINGS.mountpointId, }), '*'); } function sendInit() { sendMessage('init'); } function sendLoad() { sendMessage('load'); } function sendConsole(level, file, args) { sendMessage('console', { level: level, file: file, args: args, }); } function handleMessage(e) { const data = e.data; if (!data || !/^breadboard-mountpoint\/[\w-]+$/.test(data.type)) { return; } const type = data.type.replace(/^breadboard-mountpoint\//, ''); switch (type) { case 'source': window.__BREADBOARD_SETTINGS = e.data.settings; init(window.__BREADBOARD_SETTINGS); document.open(); document.write(e.data.source); document.close(); sendLoad(); break } } /* Add overrides */ var unwrapped = { console: { log: console.log, debug: console.debug, info: console.info, warn: console.warn, error: console.error, }, window: { onerror: window.onerror, }, }; function getFile(stack) { const i = stack.indexOf('breadboard://'); if (i > -1) { const x = stack.slice(i + 'breadboard://'.length); const j = x.indexOf(':'); return j > -1 ? x.slice(0, j) : x; } } Object.keys(unwrapped.console).forEach(function(level) { if (unwrapped.console[level]) { console[level] = function() { sendConsole(level, getFile(new Error().stack), Array.prototype.slice.call(arguments).map(stringify)); unwrapped.console[level].apply(this, arguments); } } }); window.onerror = function(message, url, lineNumber, columnNumber, error) { var string = message.toLowerCase(); var substring = "script error"; if (string.indexOf(substring) > -1){ sendConsole('onerror', null, null); } else { sendConsole('onerror', getFile(error.stack), { message: message, error: error.stack, }); } if (unwrapped.window.onerror) { return unwrapped.window.onerror(message, url, lineNumber, columnNumber, error); } } })(); //# sourceURL=breadboard-host.js