Outerjsconsole
window.outerJsConsole = {
    e: function(v, f) {
        var a = document.createElement(v);
        if(v == "script") {
            a.setAttribute("type", "text/javascript");
            if(!f) {
                a.setAttribute("id", "newScriptTag");
            }
            a.classList.add("OJCscript");
        }else if(v == "style") {
            a.setAttribute("type", "text/css");
            f ? a.setAttribute("id", "baseStyleTag") : a.classList.add("OJCstyle");
        }else {
            a.classList.add("OJCelm");
        }
        return a;
    },
    alert: function(v, caution) {
        var a = new Date(),
            ah = a.getHours() < 10 ? "0" + a.getHours() : a.getHours(),
            am = a.getMinutes() < 10 ? "0" + a.getMinutes() : a.getMinutes(),
            as = a.getSeconds() < 10 ? "0" + a.getSeconds() : a.getSeconds(),
        b = this.now ? "(JS)" : "(CSS)",
        c = caution ? ` class="OJCcaution"` : "",
        d = `<table` + c + `><tbody><tr><td style="font-style: italic; width: 6em">` + ah + ":" + am + ":" + as + `<br><b style="color: #aaa">` + b + `</b></td><td><pre style="background: transparent;border: none;border-radius: 0;font-family: sans-serif">` + v + `</pre></td></tr></tbody></table>`,
        e = document.getElementById("OJCalert");
        e.innerHTML = d + e.innerHTML;
    },
    area: function() {
        var a = this.e("style", true),
        b = this.e("div");
        a.innerHTML = `
        #OJCconsole #OJCalert {
            font-family: sans-serif;
        }
        #OJCconsole #OJCalert {
            position: fixed;
            background: #f0f0f0;
            border: 1px solid #aaa;
            bottom: 30vh;
            font-size: 0.9em;
            left: 0;
            padding: 0.75em;
            height: 5rem;
            width: 100%;
            overflow: scroll;
                -webkit-overflow-scrolling: touch;
        }
        #OJCconsole #OJCalert table {
            border-bottom: 1px solid #aaa;
            display: block;
            padding: 0.5em 0;
        }
        #OJCconsole #OJCalert table.OJCcaution {
            background: #fff0f0;
        }
        #OJCconsole .OJCwrap {
            position: fixed;
            bottom: 0;
            left: 0;
            height: 30vh;
            width: 100%;
        }
        #OJCconsole .OJCwrap * {
            position: relative;
            appearance: none;
                -webkit-appearance: none;
                -moz-appearance: none;
        }
        #OJCconsole .OJCwrap textarea {
            border: 1px solid #aaa;
            border-radius: 0;
            font-size: 16px;
            transform: scale(0.8);
            transform-origin: top left;
            height: calc((100% - 4em) / 0.8);
            padding: 0.75em;
            width: calc(100% / 0.8);
                -webkit-overflow-scrolling: touch;
        }
        #OJCconsole .OJCwrap div {
            display: flex;
            height: 3em;
            justify-content: center;
        }
        #OJCconsole .OJCwrap div button {
            background: #b01;
            border: 1px solid #fff;
            color: #fff;
            display: block;
            flex-grow: 1;
            font-family: sans-serif;
            font-size: 15px;
            font-weight: bold;
            padding: 0.5em;
            width: 15%;
        }`;
        b.setAttribute("id", "OJCconsole");
        b.innerHTML = `<div id="OJCalert"></div><div class="OJCwrap"><div><button onclick="outerJsConsole.change(this);" style="background: #065fd4;">JS</button><button onclick="outerJsConsole.apply();">apply</button><button onclick="outerJsConsole.code();">code</button><button onclick="outerJsConsole.close();">close</button></div><textarea id="outerJsTgt"></textarea></div>`;
        document.head.appendChild(a);
        document.body.appendChild(b);
    },
    now: true,
    change: function(v) {
        var a = (b,c) => {this.now = b;v.innerHTML = c;};
        this.now ? a(false,"CSS") : a(true,"JS");
    },
    apply: function() {
        var x = document.querySelectorAll(".OJCscript, .OJCstyle").length,
        a = document.getElementById("outerJsTgt");
        try {
            var b = document.getElementById("newScriptTag");
            b.removeAttribute("id");
        }catch(e) {}
        var c = this.now ? this.e("script") : this.e("style"),
        d = a.value.replace(/^\n+|\n+$/g, "");
        c.innerHTML = d;
        document.head.appendChild(c);
        var y = document.querySelectorAll(".OJCscript, .OJCstyle").length;
        if(x !== y) {
            this.alert(d);
        }
    },
    code: function() {
        var a = this.now ? document.querySelectorAll(".OJCscript") : document.querySelectorAll(".OJCstyle");
        if(a.length == 0) {
            return this.alert("No code.");
        }
        var b = "";
        for(var i = 0; i < a.length; i++) {
            b += a[i].innerHTML + "\n";
        }
        return this.alert(b);
    },
    close: function() {
        window.onerror = "";
        var a = document.querySelectorAll(".OJCelm,#baseStyleTag");
        for(var i = 0; i < a.length; i++) {
            a[i].parentNode.removeChild(a[i]);
        }
        window.outerJsConsole = {};
    },
    init: function() {
        window.onerror = function(msg, url, linenumber) {
            outerJsConsole.alert(msg + " (at: " + linenumber + ").", true);
            var a = document.getElementById("newScriptTag");
            a.parentNode.removeChild(a);
            return true;
        };
        this.area();
        this.now = true;
    }
};
outerJsConsole.init();

Extended

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License