window.console = {}; window.onload = function () { var output = document.getElementById("output"); var input = document.getElementById("input"); var runButton = document.getElementById("runbutton"); var clearButton = document.getElementById("clearbutton"); if (!String.prototype.trim) { var _r = /(^\s+|\s+$)/g; String.prototype.trim = function () { return this.replace(_r, ''); } } function removeCarriageReturns (value) { return value.replace(/\r/g, ''); } function getSelectedText (element) { if (typeof element.selectionStart === 'number' && typeof element.selectionEnd === 'number') { return element.value.substring(element.selectionStart, element.selectionEnd); } var range = document.selection.createRange(); if (!range || range.parentElement() !== element) return ''; var normalizedValue = removeCarriageReturns(element.value); var inputRange = element.createTextRange(); inputRange.moveToBookmark(range.getBookmark()); var endRange = element.createTextRange(); endRange.collapse(false); // Selection begins at the end of the input, so it's empty if (inputRange.compareEndPoints('StartToEnd', endRange) > -1) return ''; var start = -inputRange.moveStart('character', -element.value.length); start += normalizedValue.slice(0, start).split('\n').length - 1; var end = element.value.length; if (inputRange.compareEndPoints('EndToEnd', endRange) < 0) { end = -inputRange.moveEnd('character', -element.value.length); end += normalizedValue.slice(0, end).split('\n').length - 1; } return element.value.substring(start, end) } // Try to output something cleanly as a string despite IE's disagreement. // TODO: Cool object output and errors with stack traces? function tryString (value) { try { if (value instanceof Error && value.message) return removeCarriageReturns(value.message); return removeCarriageReturns(new String(value).toString()); } catch (err) { // Give up, just print the type. return '[' + typeof value + ']'; } } function makeLogger (color) { return function () { var entry = document.createElement('div'); entry.style.margin = '0'; entry.style.padding = '1px'; entry.style.borderBottom = '1px solid lightgray'; if (color) entry.style.color = color; var outputText = ''; for (var i = 0; i < arguments.length; i++) { outputText += tryString(arguments[i]); if (i + 1 !== arguments.length) outputText += ' '; } entry.appendChild(document.createTextNode(outputText)); output.appendChild(entry); } } console.log = makeLogger(); console.debug = makeLogger('darkgray'); console.info = makeLogger(); console.warn = makeLogger('orange'); console.error = makeLogger('red'); console.assert = function (assertion) { if (assertion) return; var argArray = Array.prototype.slice.call(arguments); argArray.shift(); console.error.apply(null, argArray); } console.trace = function () { var current = arguments.callee.caller; var stack = 'console.trace(): \n '; while (current) { try { var funcString = current.toString(); funcString = funcString.substring(funcString.indexOf('function') + 8); stack += funcString.substring(0, funcString.indexOf('(')).trim() || 'anonymous'; } catch (err) { stack += 'unknown function'; } stack += '\n '; current = current.caller; } console.log(stack.trim()) } var inputLogger = makeLogger('lightBlue'); function run () { var selected = getSelectedText(input); var code = selected ? selected : input.value; if (!code.trim()) return; inputLogger(code); try { console.log(tryString(eval(code))); } catch (err) { console.error(err); } } console.clear = function () { output.innerHTML = ""; } input.onkeypress = function (event) { // Run code if Shift+Enter is pressed if (event && event.keyCode === 13 && event.shiftKey) { event.preventDefault(); run(); } } runButton.onclick = run; clearButton.onclick = console.clear; // Try to detect the wizard extensions. if (typeof window.external === 'object' && typeof window.external.SetWizardButtons === 'unknown') { window.external.SetHeaderText('JavaScript Console', "Explore this wizard's JavaScript environment."); // Enable the back button window.external.SetWizardButtons(1, 0, 0); } if (/MSIE 7.0/.test(navigator.userAgent)) { /* * For some reason, IE 7 messes up the textarea's width and height * pretty badly. We hardcode the height, removing a little margin, * and add some margin to the output. * Setting the input's width causes it to somehow divide itself by 2 * on every keystroke. */ input.style.height = document.documentElement.clientHeight - 7 + 'px'; output.style.marginLeft = '7px'; } } // An onback function is required by the web wizard specification window.onback = function () { window.external.FinalBack(); }