Skip to content

Commit

Permalink
Cleanup frontend code and add test.html
Browse files Browse the repository at this point in the history
  • Loading branch information
jviereck committed Sep 11, 2013
1 parent 9c1ac2d commit 2dd4e44
Show file tree
Hide file tree
Showing 19 changed files with 296 additions and 7,014 deletions.
File renamed without changes.
File renamed without changes.
190 changes: 190 additions & 0 deletions frontend/index.js
@@ -0,0 +1,190 @@
function parseHash() {
var hash = location.hash.substring(1);
if (!hash) return {};

var parts = hash.split('&');
var keys = {};
parts.forEach(function(part) {
var splits = part.split('=');
keys[splits[0]] = decodeURIComponent(splits[1]);
});
return keys;
}

function saveOnHash() {
var regexp = regExpDom.value;
var input = editor.getValue();
location.hash = 'regexp=' + encodeURIComponent(regexp) + '&' + 'input=' + encodeURIComponent(input);

alert('Stored current RegExp and input on the URL. Feel free to pass the URL to someone else for sharing.')
}

var lastRes = null;
var currentTrace = null;

function selectRegExpDom(from, to) {
regExpDom.selectionStart = from;
regExpDom.selectionEnd = to;
}

function reflectSelection(trace) {
var selection;
var pos;
currentTrace = trace;
if (!trace || !trace.node || !trace.node.parseEntry) {
selection = { from: 0, to: 0 };
} else {
selection = trace.node.parseEntry;
}
if (trace) {
pos = { from: trace.pos, to: trace.pos + 1 };
} else {
pos = { from: 0, to: 0 };
}

selectRegExpDom(selection.from, selection.to);

if (editor._overlay) {
editor._overlay.clear();
editor.removeOverlay(editor._overlay);
}
var doc = editor.getDoc();
editor._overlay = doc.markText(
doc.posFromIndex(pos.from),
doc.posFromIndex(pos.to),
{className: 'matchhighlight'});
}

function traceToHTML(trace) {
function traceNodeToHTML(traceNode, className) {
if (traceNode == null || traceNode.node.dontCountTraceNode ) {
return '';
}
var display = '';

if (traceNode.node.type == 'GROUP_BEGIN') {
display = ''; //(';
} else if (traceNode.node.type == 'GROUP_END') {
display = ''; //')';
} else if (traceNode.node.type == 'BACK') {
display = 'B';
className += 'arrow_box';
} else if (traceNode.node.type == 'FORWARD') {
display = '>>';
} else {
display = traceNode.node.parseEntry.raw;
}

display = display.replace(/\s/g, ' ');

var html = '';
if (display) {
html = '<span class="' + className + '" data-trace-id="' + traceNode.id + '">' + display + '</span>';
}
return html;
}

var html = '';
var forkIdx = trace.lastBackIdx;
var lastVisibleNodeIdx = trace.length;

for (var i = trace.length - 1; i >= 0; i--) {
if (!trace[i].node.dontCountTraceNode) {
lastVisibleNodeIdx = i;
break;
}
}

for (var i = 0; i < trace.length; i++) {
var className = '';
if (i <= forkIdx) {
className = 'hide ';
} else if (trace.isEndTrace && i === lastVisibleNodeIdx) {
className = trace.isEndTrace + ' ';
}
html += traceNodeToHTML(trace[i], className);
}

return html;
}

function matchIt() {
try {
var regExp = new RegExpJS(regExpDom.value);
} catch (e) {
regExpErrorDom.textContent = e.toString();
return;
}
regExpErrorDom.textContent = '';

var input = editor.getValue();

try {
var res = window.res = lastRes = regExp.execDebug(input, regexp);
} catch (exp) {
alert('Sorry: ' + exp);
return;
}

var resOutput;
if (res.matches) {
resOutput = JSON.stringify(res.matches, null, 4);
} else {
resOutput = 'null';
}

var traceOutput = '';
traceOutput += res.traces.filter(function(trace) {
return trace.isEndTrace;
}).map(function(trace) {
var html = traceToHTML(trace);
return '<div class="traceRun"><nobr>' + html + '</nobr></div>';
}).join('\n');
tracesDom.innerHTML = traceOutput;

document.getElementById('result').value = resOutput;
document.getElementById('parseTree').value = JSON.stringify(res.parseTree, null, 4);
}

window.onload = function() {
// Leak globally.
editor = null;
regExpDom = document.getElementById('regexp');
regExpErrorDom = document.getElementById('regexperror');
tracesDom = document.getElementById('traces');

tracesDom.addEventListener('mouseover', function(e) {
var target = e.target;
var traceId = target.getAttribute('data-trace-id');
var trace = lastRes.traces.data.traceHash[traceId];

reflectSelection(trace);
});

var inputDom = document.getElementById('area');

editor = CodeMirror.fromTextArea(inputDom, {
lineNumbers: true
});
editor.setSize(null, '100px');
editor._overlay = null;

var hashData = parseHash();
if ('regexp' in hashData) regExpDom.value = hashData.regexp;
if ('input' in hashData) editor.setValue(hashData.input);

var matchItTimer = null;
function scheduleMatchIt() {
if (matchItTimer) {
clearTimeout(matchItTimer);
}
matchItTimer = setTimeout(matchIt, 200);
}

editor.on('change', scheduleMatchIt);

var previousRegExpDomValue = null;
regExpDom.addEventListener('keyup', scheduleMatchIt);

matchIt();
}
77 changes: 77 additions & 0 deletions frontend/main.css
@@ -0,0 +1,77 @@
.CodeMirror {
border: 1px solid black;
}
.CodeMirror .matchhighlight {
background-color: orange;
background-position: bottom;
background-repeat: repeat-x;
}

#regexp {
font-size: 20pt;
font-family: monospace;
}

span.highlight {
background-color: orange;
}

#traces span {
border: 1px solid gray;
display: inline-block;
width: 20px;
text-align: center;
overflow: hidden;
}

#traces span.failed {
background-color: #FFB2A8;
}

#traces span:hover {
border: 1px solid red;
background-color: orange;
}

#traces span.success {
background-color: #4FC467;
}

.arrow_box {
position: relative;
background: #88b7d5;
border: 4px solid #c2e1f5;
overflow: visible !important;
}
.arrow_box:after, .arrow_box:before {
bottom: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}

.arrow_box:after {
border-color: rgba(136, 183, 213, 0);
border-bottom-color: #88b7d5;
border-width: 2px;
left: 50%;
margin-left: -2px;
}
.arrow_box:before {
border-color: rgba(194, 225, 245, 0);
border-bottom-color: #c2e1f5;
border-width: 8px;
left: 50%;
margin-left: -8px;
}

.hide {
opacity: 0.5;
}

#traces .traceRun {
margin-bottom: 3px;
}

0 comments on commit 2dd4e44

Please sign in to comment.