234 lines
7.5 KiB
JavaScript
234 lines
7.5 KiB
JavaScript
function JSEval (code) {
|
|
try {
|
|
return eval(code);
|
|
} catch (err) {
|
|
console.error(err);
|
|
}
|
|
}
|
|
|
|
function supportsVB () {
|
|
return typeof window.VBSEval === 'unknown' && typeof window.VBSExecute === 'unknown'
|
|
}
|
|
|
|
function hasWebWizardExtensions () {
|
|
if (typeof window.external !== 'unknown') return false
|
|
return supportsVB() ? InWebWizard() : typeof window.external.SetWizardButtons === 'unknown'
|
|
}
|
|
|
|
function inSketchUp () {
|
|
return /\bSketchUp\//.test(navigator.userAgent)
|
|
}
|
|
|
|
var originalConsole = window.console;
|
|
|
|
window.onload = function () {
|
|
var output = document.getElementById("output");
|
|
var input = document.getElementById("input");
|
|
var languageSelect = document.getElementById("languageselect");
|
|
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 {
|
|
return removeCarriageReturns(new String(value).toString());
|
|
} catch (err) {
|
|
// Give up, just print the type.
|
|
return '[' + typeof value + ']';
|
|
}
|
|
}
|
|
|
|
window.console = {};
|
|
|
|
function makeLogger (name, color) {
|
|
return function () {
|
|
if (originalConsole && originalConsole[name] && originalConsole[name].apply) originalConsole[name].apply(originalConsole, arguments);
|
|
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);
|
|
entry.scrollIntoView();
|
|
}
|
|
}
|
|
|
|
console.log = makeLogger('log');
|
|
console.debug = makeLogger('debug', 'darkgray');
|
|
console.info = makeLogger('info');
|
|
console.warn = makeLogger('warn', 'orange');
|
|
console.error = makeLogger('error', '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());
|
|
}
|
|
|
|
console.clear = function () {
|
|
if (originalConsole && originalConsole.clear) {
|
|
if (originalConsole.clear.apply) originalConsole.clear.apply(originalConsole, arguments);
|
|
else originalConsole.clear();
|
|
}
|
|
output.innerHTML = "";
|
|
}
|
|
|
|
var inputLogger = makeLogger('log', 'lightblue');
|
|
function run () {
|
|
var code = getSelectedText(input) || input.value;
|
|
if (!code.trim()) return;
|
|
|
|
inputLogger(code);
|
|
try {
|
|
switch (languageSelect.value) {
|
|
case 'js':
|
|
result = JSEval(code);
|
|
break;
|
|
case 'vbs-eval':
|
|
result = VBSEval(code);
|
|
break;
|
|
case 'vbs-execute':
|
|
result = VBSExecute(code);
|
|
break;
|
|
default:
|
|
console.error('Unsupported language', languageSelect.value);
|
|
return;
|
|
}
|
|
console.log(result);
|
|
} catch (err) {
|
|
console.error(err);
|
|
}
|
|
}
|
|
|
|
input.onkeypress = function (event) {
|
|
if (!event) event = window.event;
|
|
// Run code if Shift+Enter is pressed
|
|
if (event && event.keyCode === 13 && event.shiftKey) {
|
|
event.cancelBubble = true;
|
|
event.returnValue = false;
|
|
if (event.stopPropagation) event.stopPropagation();
|
|
if (event.preventDefault) event.preventDefault();
|
|
run();
|
|
}
|
|
}
|
|
|
|
languageSelect.onchange = function () {
|
|
switch (languageSelect.value) {
|
|
case 'js':
|
|
languageSelect.setAttribute('placeholder', 'Type some JavaScript to run and press Shift+Enter');
|
|
break;
|
|
case 'vbs-eval':
|
|
languageSelect.setAttribute('placeholder', 'Type a VBScript expression to evaluate and press Shift+Enter');
|
|
break;
|
|
case 'vbs-execute':
|
|
languageSelect.setAttribute('placeholder', 'Type some VBScript to run and press Shift+Enter');
|
|
break;
|
|
default:
|
|
languageSelect.setAttribute('placeholder', 'Type the name of a demonic entity to summon and press Shift+Enter');
|
|
break;
|
|
}
|
|
}
|
|
|
|
runButton.onclick = run;
|
|
clearButton.onclick = console.clear;
|
|
|
|
if (!supportsVB()) {
|
|
for (var i = 0; i < languageSelect.children.length; i++) {
|
|
if (languageSelect.children[i].value.slice(0, 3) === 'vbs') {
|
|
languageSelect.children[i].disabled = true;
|
|
languageSelect.children[i].title = 'VBScript is not supported in this browser.';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Try to detect the wizard extensions.
|
|
try {
|
|
if (hasWebWizardExtensions()) {
|
|
window.external.SetHeaderText('Windows Scripting Console', "Explore this wizard's scripting environment.");
|
|
window.external.SetWizardButtons(1, 0, 0);
|
|
// An onback function is required by the web wizard specification
|
|
window.onback = function () {
|
|
window.external.FinalBack();
|
|
}
|
|
}
|
|
} catch (err) {
|
|
/*
|
|
* In some browser contexts, such as IE7 embedded in the Compiled HTML viewer,
|
|
* interactions with window.external can cause "Not implemented" errors;
|
|
* if any of those occur, we ignore them.
|
|
* We cannot filter the errors to specifically ignore "Not implemented",
|
|
* because the error text gets translated to other languages
|
|
* ("Non implémenté" in French) and there are no other attributes to compare on.
|
|
*/
|
|
if (originalConsole && originalConsole.error) {
|
|
originalConsole.error('Could not setup Web Wizard extensions:', err)
|
|
}
|
|
}
|