159 lines
5.1 KiB
JavaScript
159 lines
5.1 KiB
JavaScript
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();
|
|
} |