/*
* Web Inquirer V 0.7
* Copyright 2016 XWolfOverride@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
* software and associated documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the rights to use, copy, modify,
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies
* or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
var inquirer = inquirer || new function () {
var icon = "data:image/gif;base64,R0lGODlhIAAgAKECADIyMjMzM////////yH5BAEKAAIALAAAAAAgACAAAAJulI8Zke2PFoC0LlZzW7qf633XGGHeiJqcaKWgsQov5JLvTNeYq+kM36vBUJNgaujDiVDIpLK58ylIiiU0NjWVZscHgAuUUXPOpfbhjD1bwmFIrHsvv+3Qrd4Byzda7N7h9zclmEOIFmgolgj4VgAAOw==", //
bugico = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAWlBMVEUkJSMuMC01NzQ+Pz1HSEZPUU5YWldfYV5pa2h6e3iOkI2YmpeipKGpq6ifwFWqxma4urezzHa50YHJy8jC1pLL3aLS4K3a3NnZ5rvo6+fn8NXv8+L19/D9//y9fxQqAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB+EBBAwFN28edE4AAABVaVRYdENvbW1lbnQAAAAAAENvcHlyaWdodCBJTkNPUlMgR21iSCAod3d3Lmljb25leHBlcmllbmNlLmNvbSkgLSBVbmxpY2Vuc2VkIHByZXZpZXcgaW1hZ2VYrophAAAC6UlEQVRYw+2X2barIAxA0U5qK2jFAor//5uXSUUS2q5z1n07vNhC2JCYSbL8cpA/wAeAGswQPwc0xI3qO4BWcPVs95/gvNYQIAhpgGBtATcw3RLSpgBtRYdU8oLeQNhZlQCUnazDny7YrfM2uK8Hh+fDTopUBavuOfwuH+4xlB5QdP5vEU69xdfaAMOONT8fQg012UY1CNGuV1HxraK3UGw6XEhm+BveYw0igNWh3OyJD6fD1WqF+EG7glUeYJdFEWsQe6I1WTG8BdjVMn6JB8DNvXTjY12R2X9HnDMCqNPqSxmCebl6UWatFHgwmdtdl4XzoGcyrHav3rp3IXLRqEq9SEqf5qQq3X8xao+UjstyEvlwNgZglNLePMX9FJ1e203cLDEn9CYfvKgdTLqgaWsDKa6NM4xkbol/SCheyiBek4+8zh04yz4sUP0WMNN9sHHywrNk0bR8C+jpYbDcXBZAEWGWTM5vAHMiSzGAzAH8i4aAdM46GgSI7lrAw5zJKdSrvLRJSmtc9tWprNUXm6z3akH29N0sE5CdELsYI7hse90BPvt1OABOjiFlXFeA338WNpCgxSGAL9qnzUo7gK+ANp+Cl0BfC0J9bmXTEEioHi4fc+S2GUAgNAZQ7zWJI7cN8QkAPrvfDGDYaxrHZMcMwFW4u7VBV3fBKaBs/wZgNrZJLEB1WUavTDBN3wFeWcD8HUDmwxkDPCkWYWg4KyjMQEKyhtVoYVGnFhoBA0hTdwQEmLJUwYTA0BzRuDKVAEzRNS2M/AwYF20KX6HTjBQcugc5jYELtD74j4C1b5kBAGaIQ0dHou7ihnhjCuBrAiqOABHqPwiIWSNePEQ6kEgDhYTUNCNRoEmaVF3jsvXEcSmU0zG97D10GQOcBu3eJjAMwOZjt9ylAIEF9ktiMWg9IbTmZLvT/dirhI08ZLTx2BaYNqxKHAl+2EgbWtyatJcafAyJbz555rHvOePTb77atP77cv3/gH8Wkk7NciByTQAAAABJRU5ErkJggg==", //
VERSION = "0.7c",//
alertIcon
; //
// Locals
var inq = this, inqapp;
// Tools
function objectResume(obj) {
var r, k, v;
if (obj === null)
return "<null>";
if (obj === undefined)
return "<undefined>";
switch (typeof obj) {
case "string":
if (obj.length < 200)
return '"' + obj + '"';
else
return '"' + obj.substr(0, 200) + "...";
case "function":
return "function";
case "object":
r = "";
if (obj instanceof HTMLElement)
r += "<" + obj.tagName + ">:: ";
else if (obj instanceof HTMLDocument)
r += "DOCUMENT:: ";
else if (obj instanceof Window)
r += "WINDOW:: ";
r += "{\n";
for (k in obj) {
r += k + ":" + objectResume(obj[k]) + ",\n";
if (r.length > 500) {
r += " ...";
break;
}
}
r += "}";
return r;
default:
return "" + obj;
}
}
function objectResumeLink(obj) {
var a = document.createElement("a");
a.href = "#";
a.onclick = function () {
inq.inspect(obj);
return false;
}
a.appendChild(document.createTextNode(objectResume(obj)));
a.style.merge({
color: "black",
textDecoration: "none"
});
return a;
}
function errorLink(obj) {
var a = document.createElement("a");
a.href = "#";
a.onclick = function () {
getApp().showError(obj);
return false;
}
if (obj instanceof Error)
a.appendChild(document.createTextNode(obj));
else
a.appendChild(document.createTextNode(obj.message));
a.style.merge({
color: "black",
textDecoration: "none"
});
return a;
}
// Methods
function getApp() {
var
win_err_width = 400,
win_err_height = 150;
if (!inqapp)
inqapp = merger.app("inquirer", {
title: "Inquirer",
icon: icon,
appMenu: [
merger.ui.menuItem("app_preferences", {
text: "Preferences...",
icon: merger.media.createIcon('#EEE', '⚒'),
onClick: function () {
this.getApp().windows.wPref.show();
}
}),
],
menu: [
merger.ui.menuItem("app_tools", {
text: "Tools",
items: [merger.ui.menuItem("tool_console", {
text: "Console",
onClick: function () {
this.getApp().showConsole();
}
})
]
}),
merger.ui.menuItem("app_special", {
text: "Special",
items: [merger.ui.menuItem("special_reload", {
text: "Reload page",
onClick: function () {
location.reload(false);
}
}), merger.ui.menuItem("special_reload_full", {
text: "Reload page (ignore cache)",
onClick: function () {
location.reload(true);
}
}), merger.ui.menuItem("special_debugger", {
text: "Call browser debugger",
onClick: function () {
debugger;
}
})
]
})
],
windows: [merger.ui.window("Wmain", {
title: "Error",
width: win_err_width,
height: win_err_height,
visible: false,
content: [merger.ui.picture("Iico", {
src: bugico,
top: 0,
left: 0,
width: 32,
height: 32,
}),
merger.ui.label("Lerror", {
top: 0,
left: 37,
width: win_err_width - 37,
height: 32,
text: "",
}),
merger.ui.label("Tinfo", {
top: 37,
left: -5,
width: win_err_width,
height: win_err_height - 37 - 25 - 10,
multiple: true,
style: {
whiteSpace: "pre",
fontFamily: "Lucida Console, Monospace",
border: "0",
overflow: "scroll",
background: "#EEE",
padding: "5px",
},
}),
merger.ui.button("Bok", {
top: win_err_height - 20,
left: win_err_width - 35,
width: 35,
height: 20,
text: "Ok",
onClick: function (e) {
this.getWindow().close();
}
}),
],
onClose: function () {
this.hide();
//merger.leave();
},
setError: function (message, data) {
this.content.Lerror.setText(message);
this.content.Tinfo.setText(data);
}
}), merger.ui.window("Wconsole", {
title: "Console",
width: 500,
height: 350,
visible: false,
content: [
merger.ui.html("Hconsole", {
top: 0,
left: 0,
width: 500,
height: 330,
style: {
overflow: "scroll",
},
}),
merger.ui.textbox("Tinput", {
top: 330,
left: -5,
width: 500 + 10,
height: 25,
placeholder: "javascript code here",
//multiple: true,
style: {
whiteSpace: "pre",
fontFamily: "Lucida Console, Monospace",
border: "0",
overflow: "scroll",
background: "#EEE",
padding: "5px",
},
onkeydown: function (e) {
var t, stop;
switch (e.keyCode) {
case 13:
this.getWindow().exec(this.getText());
t = "";
stop = true;
break;
case 38:
t = this.getWindow().conhis.up();
stop = true;
break;
case 40:
t = this.getWindow().conhis.down();
stop = true;
break;
}
if (t != undefined) {
this.setText(t);
}
if (stop)
return false;
},
}),
],
conhis: {
data: [],
sel: 0,
add: function (code) {
var idx = this.data.indexOf(code);
if (idx >= 0)
this.data.splice(idx, 1);
this.data.push(code);
this.sel = this.data.length;
},
up: function () {
if (this.sel > 0)
this.sel--;
return this.data[this.sel];
},
down: function () {
if (this.sel < this.data.length)
this.sel++;
else return;
if (this.sel == this.data.length)
return "";
return this.data[this.sel];
}
},
onClose: function () {
this.hide();
},
log: function (type, object) {
var row = document.createElement("div");
var head = document.createElement("div");
var clear = document.createElement("div");
var d = document.createElement("div");
row.style.merge({
margin: "0 0 0 13px",
});
head.style.merge({
fontFamily: "Lucida Console, Monospace",
fontWeight: "bold",
float: "left",
margin: "0 0 0 -13px",
width: "13px",
});
d.style.merge({
whiteSpace: "pre-wrap",
float: "right",
fontFamily: "Lucida Console, Monospace",
border: "0",
width: "100%",
});
clear.style.merge({
clear: "both",
});
switch (type) {
case 'i':
d.innerText = object;
head.appendChild(document.createTextNode(">"));
head.style.color = "#88F";
d.style.paddingBottom = "3px";
break;
case 'o':
d.appendChild(objectResumeLink(object));
d.style.borderBottom = "1px solid #EEE";
head.appendChild(document.createTextNode("<"));
head.style.color = "#DDD";
break;
case 'e':
d.appendChild(errorLink(object));
head.appendChild(document.createTextNode("!"));
head.style.color = "#F88";
d.style.background = "#FEE";
head.style.background = "#FEE";
break;
}
d.data = object;
row.appendChild(head);
row.appendChild(d);
row.appendChild(clear);
this.content.Hconsole.appendChild(row);
this.content.Hconsole.scrollTop = this.content.Hconsole.scrollHeight;
},
exec: function (code) {
if (code == null || typeof code != "string" || code.length < 1)
return;
this.conhis.add(code);
var err, obj;
this.log('i', code);
try {
obj = eval('(' + code + ')');
} catch (err) {
window.console.error(err);
return;
}
window.console.log(obj);
},
write: function () {
var k;
for (k in arguments)
this.log('o', arguments[k]);
},
writeError: function () {
var k;
for (k in arguments)
this.log('e', arguments[k]);
}
}),
merger.ui.window("wPref", {
title: "Preferences",
width: 175,
height: 100,
visible: false,
content: [
merger.ui.checkbox("pref_autoshow", {
top: 0,
left: 3,
}),
merger.ui.label("pref_autoshow_lbl", {
top: 0,
left: 20,
text: "Open Inquirer on error"
}),
merger.ui.checkbox("pref_erricon", {
top: 15,
left: 3,
}),
merger.ui.label("pref_erricon_lbl", {
top: 15,
left: 20,
text: "Show small error indicator"
}),
merger.ui.button("pref_save", {
top: 80,
left: 150,
text: "Ok",
onClick: function () {
inq.autoShow = this.getWindow().content.pref_autoshow.checked;
inq.alertIcon = this.getWindow().content.pref_erricon.checked;
this.getWindow().close();
}
}),
],
onShow: function () {
this.getWindow().content.pref_autoshow.checked = inq.autoShow;
this.getWindow().content.pref_erricon.checked = inq.alertIcon;
}
}),
],
onLoad: function () {
},
onAbout: function () {
merger.dialogs.messageBox(this, "Inquirer v" + VERSION + " ©2016-2017 XWolf Override.<br>Debugger application layer for web pages. Useful for embedded browser debugging", "About Inquirer", null, this.icon, 100);
},
onFocus: function () {
removeIcon();
if (!inq.autoShow)
this.windows.Wconsole.show();
},
showError: function (err) {
if (err instanceof Error) {
this.windows.Wmain.setError(err.message, err.stack);
} else {
this.windows.Wmain.setError(err.message, "File: " + err.source + "\r\n\r\nAt: " + err.at);
}
this.windows.Wmain.show();
},
showConsole: function () {
this.windows.Wconsole.show();
}
});
return inqapp;
}
/**
* Show a small yellow mark to indicate some error has been happend
*/
function showIcon() {
if (!alertIcon) {
alertIcon = document.createElement("DIV");
alertIcon.style.merge({
position: "absolute",
top: "0px",
right: "3px",
width: "2px",
height: "1px",
background: "gold",
borderBottom: "goldenRod",
});
document.body.appendChild(alertIcon);
}
alertIcon.style.display = "";
}
/**
* Hides a small yellow mark to indicate some error has been happend
*/
function removeIcon() {
if (!alertIcon)
return;
alertIcon.style.display = "none";
}
// === Public members
function show() {
getApp().show();
}
function hide() {
getApp().windows.Wmain.close();
}
// On error hook
function hookOnError() {
var formerOnError = window.onerror;
window.onerror = function (message, source, lineno, colno, err) {
inq.error({
message: message,
source: source,
at: lineno + ":" + colno,
error: err,
raw: arguments
});
if (formerOnError)
formerOnError.apply(window, arguments);
}
}
// Konami code hook
function hookKonamiCode() {
var kc = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65], kcindex = 0 // Konami code
document.addEventListener("keydown", function (e) {
if (e.keyCode == kc[kcindex])
kcindex++;
else
kcindex = 0;
if (kcindex == kc.length)
inquirer.show();
}, false);
}
// Console hook
function hookConsole() {
var wcon = getApp().windows.Wconsole;
if (!window.console)
window.console = {};
function consoleOverride(method, funct) {
var old = window.console[method];
window.console[method] = function () {
funct.apply(this, arguments);
if (old)
old.apply(this, arguments);
};
window.console[method].old = old;
}
consoleOverride("log", function () {
wcon.write.apply(wcon, arguments);
})
consoleOverride("debug", function () {
wcon.write.apply(wcon, arguments);
})
consoleOverride("error", function () {
wcon.writeError.apply(wcon, arguments);
})
}
// Install hooks
function hook() {
hookOnError();
hookKonamiCode();
hookConsole();
}
function error(error) {
getApp().windows.Wconsole.writeError(error);
if (this.autoShow) {
getApp().showError(error);
show();
}
if (this.alertIcon) {
showIcon();
}
}
function inspect(object) {
}
function console() {
getApp().showConsole();
show();
}
function log() {
getApp().windows.Wconsole.write.apply(getApp().windows.Wconsole, arguments);
}
// Publish
this.merge({
version: VERSION,
autoShow: false, // Open Inquirer environment when a new unhandled error happen
alertIcon: true, // Small icon on screen to indicate if there is any new error
show: show, // Enters environment
hide: hide, // Exit environent
hook: hook, // Hook the webpage to control errors (Automatically hooked)
error: error, // Collect an error and if autoShow is true enters environment
inspect: inspect, // Enters environment and open variable inspector
console: console, // Enters environment and open inquirer console
log: log, // Log an object into the console
});
// Hook the page now
hook();
window.addEventListener("load", function () {
getApp().windows.Wconsole.write("Inquirer " + VERSION + " console.");
})
}();