Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Cleanup frontend code and add test.html
- Loading branch information
Showing
19 changed files
with
296 additions
and
7,014 deletions.
There are no files selected for viewing
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |
Oops, something went wrong.