mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-28 04:19:56 +00:00
f6338d9109
It preserves comments and text positions, enabling us to do syntax highlighting. Hopefully.
226 lines
6.1 KiB
HTML
226 lines
6.1 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Esprima: Operator Precedence Demo</title>
|
|
<script src="../esprima.js"></script>
|
|
<script src="../assets/json2.js"></script>
|
|
<link rel="stylesheet" type="text/css" href="../assets/style.css"/>
|
|
<style>
|
|
#a, #b, #expr {
|
|
font-size: 16px;
|
|
padding: 5px;
|
|
margin: 5px;
|
|
border: 1px solid #ccc;
|
|
}
|
|
|
|
#expr {
|
|
border: none;
|
|
}
|
|
|
|
#answer {
|
|
color: white;
|
|
padding: 5px;
|
|
margin: 20px;
|
|
}
|
|
|
|
.yes {
|
|
background-color: #228B22;
|
|
}
|
|
|
|
.no {
|
|
background-color: #8B2500;
|
|
}
|
|
|
|
.lightred {
|
|
background-color: #FFC0CB;
|
|
}
|
|
</style>
|
|
<script>
|
|
/*jslint sloppy:true browser:true */
|
|
/*global esprima:true */
|
|
var compareId;
|
|
function compare() {
|
|
if (compareId) {
|
|
window.clearTimeout(compareId);
|
|
}
|
|
|
|
function stringify(node) {
|
|
var result;
|
|
|
|
if (typeof node !== 'object') {
|
|
throw new Error('Node is not valid');
|
|
}
|
|
if (typeof node.type !== 'string') {
|
|
throw new Error('Node does not have type property');
|
|
}
|
|
|
|
switch (node.type) {
|
|
|
|
case 'Program':
|
|
if (node.body.length !== 1) {
|
|
throw new Error('Expression is too complex');
|
|
}
|
|
result = stringify(node.body[0]);
|
|
if (result[0] === '(' && result[result.length - 1] === ')') {
|
|
result = result.substr(1, result.length - 2);
|
|
}
|
|
break;
|
|
|
|
case 'ExpressionStatement':
|
|
result = stringify(node.expression);
|
|
break;
|
|
|
|
case 'BinaryExpression':
|
|
case 'LogicalExpression':
|
|
result = '(' + stringify(node.left) + ' ' + node.operator + ' ' + stringify(node.right) + ')';
|
|
break;
|
|
|
|
case 'UnaryExpression':
|
|
result = '(' + node.operator;
|
|
if (node.operator.length > 2) {
|
|
// delete void typeof
|
|
result += ' ';
|
|
}
|
|
result += stringify(node.argument) + ')';
|
|
break;
|
|
|
|
case 'UpdateExpression':
|
|
result = stringify(node.argument);
|
|
if (node.prefix) {
|
|
result = node.operator + result;
|
|
} else {
|
|
result = result + node.operator;
|
|
}
|
|
result = '(' + result + ')';
|
|
break;
|
|
|
|
case 'Literal':
|
|
result = node.value.toString();
|
|
if (typeof node.value === 'string') {
|
|
result = '"' + node.value + '"';
|
|
}
|
|
break;
|
|
|
|
case 'Identifier':
|
|
result = node.name;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (!result) {
|
|
throw new Error('Unknown node type: ' + node.type);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
function setText(el, str) {
|
|
if (typeof el.innerText === 'string') {
|
|
el.innerText = str;
|
|
} else {
|
|
el.textContent = str;
|
|
}
|
|
}
|
|
|
|
compareId = window.setTimeout(function () {
|
|
var a, b, answer, status, expr, left, right, suggest;
|
|
|
|
a = document.getElementById('a');
|
|
b = document.getElementById('b');
|
|
answer = document.getElementById('answer');
|
|
status = document.getElementById('status');
|
|
expr = document.getElementById('expr');
|
|
|
|
a.setAttribute('class', '');
|
|
b.setAttribute('class', '');
|
|
answer.setAttribute('class', '');
|
|
|
|
setText(answer, '');
|
|
setText(status, '');
|
|
setText(expr, '');
|
|
|
|
try {
|
|
left = esprima.parse((typeof a.innerText === 'string') ? a.innerText : a.textContent);
|
|
} catch (e_left) {
|
|
a.setAttribute('class', 'lightred');
|
|
}
|
|
|
|
try {
|
|
right = esprima.parse((typeof b.innerText === 'string') ? b.innerText : b.textContent);
|
|
} catch (e_right) {
|
|
b.setAttribute('class', 'lightred');
|
|
}
|
|
|
|
try {
|
|
suggest = stringify(left);
|
|
} catch (e_suggest) {
|
|
a.setAttribute('class', 'lightred');
|
|
}
|
|
|
|
if (left && right) {
|
|
if (JSON.stringify(left) === JSON.stringify(right)) {
|
|
setText(answer, 'Yes');
|
|
answer.setAttribute('class', 'yes');
|
|
} else {
|
|
setText(answer, 'No');
|
|
answer.setAttribute('class', 'no');
|
|
setText(status, suggest ? 'It is more like ' : '');
|
|
setText(expr, suggest || '');
|
|
}
|
|
} else {
|
|
answer.setAttribute('class', '');
|
|
}
|
|
|
|
compareId = undefined;
|
|
}, 57);
|
|
}
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
|
|
<div class="topbar">
|
|
<ul class="nav">
|
|
<li><a href="../index.html">← Home</a></li>
|
|
<li><a href="http://github.com/ariya/esprima">Code</a></li>
|
|
<li><a href="http://wiki.esprima.org">Documentation</a></li>
|
|
<li><a href="http://issues.esprima.org">Issues</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<h1>Operator precedence <small>is not always easy</small></h1>
|
|
<p>Is <code id="a" contenteditable="true">1 << 2 * 3</code> semantically equivalent to
|
|
<code id="b" contenteditable="true">(1 << 2) * 3</code>? <span id="answer"></span></p>
|
|
<p style="margin-top: 40px;"><span id="status"></span> <code id="expr"></code></p>
|
|
<p style="margin-top: 60px;">This demo is inspired by <a href="http://mothereff.in/operator-precedence">mothereff.in/operator-precedence</a>.</p>
|
|
<div class="footer"><strong>Esprima</strong> is created by
|
|
<a href="http://ariya.ofilabs.com/about" target="_blank">Ariya Hidayat</a>. Follow <a href="http://twitter.com/ariyahidayat">@ariyahidayat</a> on Twitter.
|
|
</div>
|
|
</div>
|
|
<script>
|
|
if (typeof document.body.attachEvent === 'object') {
|
|
// Workaround for old Internet Explorer.
|
|
// Until there is a reliable way to track the modification to the editable
|
|
// inputs, manually track the change periodically.
|
|
window.setInterval(compare, 500);
|
|
}
|
|
|
|
// See http://mathiasbynens.be/notes/oninput for details.
|
|
document.getElementById('a').onkeyup = compare;
|
|
document.getElementById('a').oninput = function () {
|
|
this.onkeyup = null;
|
|
compare();
|
|
};
|
|
document.getElementById('b').onkeyup = compare;
|
|
document.getElementById('b').oninput = function () {
|
|
this.onkeyup = null;
|
|
compare();
|
|
};
|
|
compare();
|
|
</script>
|
|
</body>
|
|
</html>
|