Skip to content

Instantly share code, notes, and snippets.

@mklaber
Created April 6, 2015 18:58
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save mklaber/79d9e1f64197eec2743b to your computer and use it in GitHub Desktop.
ES Sense Error Formatter User Script

This user script (aka greasemonkey script) adds a "Print Error" button to the upper right corner of Marvel Sense. (It's a ! with a circle around it.)

When clicked, it looks in the output pane and checks if the body of the output looks like an ES error. If it does, it'll display it in a slightly more readable form (adds pretty line breaks, etc.).

Subsequent clicks of the Print Error button will update the error message if the content in the output has changed or hide the error message if the content in the output doesn't look like an error.

Use Greasemonkey in Firefox or Tamplermonkey in Chrome to install it.

// ==UserScript==
// @name es-sense-error-formatter
// @namespace mpk
// @include http://*/_plugin/*/sense/index.html*
// @include https://*/_plugin/*/sense/index.html*
// @version 1
// @grant none
// ==/UserScript==
function $(q, root, single) {
if (root && typeof root == 'string') {
root = $(root, null, true);
if (!root) { return null; }
}
root = root || document;
if (q[0]=='#') { return root.getElementById(q.substr(1)); }
else if (q[0]=='/' || (q[0]=='.' && q[1]=='/')) {
if (single) { return document.evaluate(q, root, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; }
return document.evaluate(q, root, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
}
else if (q[0]=='.') { return root.getElementsByClassName(q.substr(1)); }
return root.getElementsByTagName(q);
}
function $c(className,root){
return (root||document).getElementsByClassName(className);
}
function $c1(className,root){
return $c(className, root)[0];
}
function log(str) {
if (typeof debug !== 'undefined') { debug(str); }
if (typeof GM_log !== 'undefined') { GM_log(str); return true; }
else if (typeof console !== 'undefined' && console.log) { console.log(str); return true; }
return false;
}
function logError(category, x) {
msg = "Error (" + category + ") - " + x.name + ' - ' + x.message + ' in file <' + x.fileName + '> on line ' + x.lineNumber;
log(msg);
}
function onClick(elm, func) { (typeof elm === 'string' ? $('#'+elm) : elm).addEventListener('click', func, false); }
function getEditor() {
var editor = $('#output');
var content = $c1('ace_content', editor);
if (typeof(content) === 'undefined' || !content) {
return null;
}
return content;
}
function getEditorContent() {
var content = getEditor();
if (content) {
content = $c1('ace_text-layer', content);
}
return (content && content.textContent) || "";
}
var STATUS_REGEX = /"status":\s+(\d+)\W*}$/;
function hasErrorMessage(text) {
return typeof(text) !== 'undefined' && text !== '' && /^{\W*"error"/.test(text) && STATUS_REGEX.test(text);
}
function getErrorMessage(text) {
var response = {
message: "",
status: null
};
var errMsg = '"error":';
var statusMsg = '"status":';
// we'd use regular expressions (with text.search(/exp/)) but it doesn't
var startIdx = text.indexOf(errMsg) + errMsg.length + 1;
// find the first double quote after the errMsg
startIdx = text.indexOf('"', startIdx) + 1;
var endIdx = text.lastIndexOf(statusMsg);
// end at the last double quote just before the statusMsg
endIdx = text.substring(0, endIdx).lastIndexOf('"');
response.message = text.substring(startIdx, endIdx);
// get the status integer. we can use a regex for this one
// and, we know this regex is valid because we're assuming hasErrorMessage passed
response.status = parseInt(STATUS_REGEX.exec(text)[1]);
return response;
}
function appendTextToEditor(text) {
var p = $('#mpk-error');
if (p === null) {
var editor = getEditor();
if (!editor) {
return;
}
p = document.createElement('P');
p.id = 'mpk-error';
p.style.position = 'absolute';
p.style.bottom = '1px';
p.style.height = '50%';
p.style.overflow = 'scroll';
p.style.border = '1px #ccc solid';
p.style.backgroundColor = '#F5F5F5';
p.style.padding = '5px';
p.style.zIndex = 1000;
editor.appendChild(p);
}
p.style.display = '';
p.innerHTML = text.replace(/\\n/g, '<br/>').replace(/\\"/g, '"');
}
function hideErrorPanel() {
var p = $('#mpk-error');
if (p) {
p.style.display = 'none';
}
}
function printErrorMessage() {
var text = getEditorContent();
if (hasErrorMessage(text)) {
var err = getErrorMessage(text);
log(err);
appendTextToEditor(err.message);
} else {
log("The current output does not have a recognizable error message");
hideErrorPanel();
}
}
function getNav() {
return $('//div[contains(@class,"navbar")]//ul[contains(@class,"pull-right")][contains(@class,"nav")]', null, true);
}
function addButton() {
var navBar = getNav();
var li = document.createElement('LI');
li.id = "mpk-display-error";
var a = document.createElement('A');
a.title = 'Print Error';
a.href = '#';
a.setAttribute('data-placement', 'bottom');
a.innerHTML = '<i class="fa fa-exclamation-circle"></i>';
onClick(a, function(e) {
try {
printErrorMessage();
} catch(err) {
logError('On Click', err);
}
});
li.appendChild(a);
navBar.appendChild(li);
}
try {
addButton();
}
catch(err) {
logError('Registration', err);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment