Last active
March 5, 2018 10:15
-
-
Save dohzya/913276c7d04c0e55629d720bbb5e05b5 to your computer and use it in GitHub Desktop.
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
<html> | |
<head> | |
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/codemirror.css"> | |
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/theme/material.css"> | |
<style> | |
body { | |
background: #EFEFEF; | |
} | |
.display { | |
border: 1px solid #AAA; | |
padding: 20px; | |
font-size: 20px; | |
width: 295px; | |
text-align: right; | |
height: 25px; | |
background: white; | |
font-family: monospace; | |
} | |
.calc ul { | |
margin: 0; | |
padding:0; | |
overflow: hidden; | |
border: 1px solid #CCC; | |
width: 335px; | |
list-style: none; | |
} | |
.calc li { | |
float: left; | |
border: 1px solid #CCC; | |
background-color: #555; | |
color: White; | |
padding: 20px; | |
width: 25px; | |
height: 20px; | |
text-align: center; | |
font-family: monospace; | |
} | |
.calc li:hover { | |
background: #777 | |
} | |
.calc li:active { | |
background: AliceBlue; | |
color: #555 | |
} | |
.calc li.disabled, li.disabled:hover, li.disabled:active { | |
background: #AAA; | |
color: white; | |
} | |
.doc { | |
position: absolute; | |
top: 335px; | |
height: calc(100% - 347px - 9px); | |
left: 9px; | |
width: 313px; | |
background: white; | |
border: 1px solid #CCC; | |
margin: 0; | |
padding: 5px 10px; | |
list-style: none; | |
overflow: auto; | |
} | |
.doc code { | |
background: #EFEFEF; | |
} | |
.doc li { | |
margin-top: 5px; | |
} | |
.doc li:first-child { | |
margin-top: 0; | |
} | |
.reload { | |
position: absolute; | |
top: 9px; | |
left: 355px; | |
right: 9px; | |
height: 30px; | |
width: calc(100% - 355px - 9px); | |
} | |
.editorCompute { | |
position: absolute; | |
top: 50px; | |
left: 355px; | |
right: 9px; | |
bottom: 90px; | |
height: calc(100% - 50px - 70px);; | |
} | |
.editorDisplayValue { | |
position: absolute; | |
bottom: 9px; | |
left: 355px; | |
right: 9px; | |
height: 50px; | |
} | |
</style> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/codemirror.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/mode/javascript/javascript.js"></script> | |
</head> | |
<body> | |
<div class="calc"> | |
<div id="display" class="display"></div> | |
<ul id="buttons"> | |
<li>7</li> | |
<li>8</li> | |
<li>9</li> | |
<li>C</li> | |
<li>AC</li> | |
<li>4</li> | |
<li>5</li> | |
<li>6</li> | |
<li>x</li> | |
<li>/</li> | |
<li>1</li> | |
<li>2</li> | |
<li>3</li> | |
<li>+</li> | |
<li>-</li> | |
<li>0</li> | |
<li class="disabled"></li> | |
<li class="disabled"></li> | |
<li class="disabled"></li> | |
<li>=</li> | |
</ul> | |
</div> | |
<ul class="doc"> | |
<li>“<code>op ? call() : other</code>” means “if <code>op</code> then <code>call()</code>, else <code>other</code>”.</li> | |
<li><code>isDigit(input)</code> checks if <code>input</code> is a digit</li> | |
<li><code>addDigit(number, digit)</code> adds the given digit as last digit of the number. <code>addDigit(1, 2)</code> returns <code>12</code></li> | |
<li><code>call(op, number1, number2)</code> invoke the operation onto the two numbers. <code>call('+', 1, 2)</code> returns <code>3</code></li> | |
<li><code>or(number1, number2)</code> returns the first defined number. <code>or(1, 2)</code> returns <code>1</code>, but <code>or(undefined, 2)</code> returns <code>2</code></li> | |
<li></li> | |
<li></li> | |
<li></li> | |
<li></li> | |
</ul> | |
<button id="reload" class="reload">RELOAD</button> | |
<textarea id="editorCompute">return function compute({total, currentValue, operation}, input) { | |
if (isDigit(input)) { | |
return { | |
total: total, | |
currentValue: addDigit(currentValue, input), | |
operation: operation | |
} | |
} | |
switch (input) { | |
case 'C': | |
return { | |
total: total, | |
currentValue: undefined, | |
operation: operation | |
} | |
case 'AC': | |
return { | |
total: undefined, | |
currentValue: undefined, | |
operation: undefined | |
} | |
case '=': | |
return { | |
total: operation ? call(operation, total, currentValue) : currentValue, | |
currentValue: undefined, | |
operation: undefined | |
} | |
default: // operator | |
return { | |
total: operation ? call(operation, total, currentValue) : or(total, currentValue), | |
currentValue: undefined, | |
operation: input | |
} | |
} | |
}</textarea> | |
<textarea id="editorDisplayValue">return function displayValue({currentValue, total}) { | |
return or(currentValue, total) | |
}</textarea> | |
<script> | |
function isDigit(input) { | |
switch (input) { | |
case '0': | |
case '1': | |
case '2': | |
case '3': | |
case '4': | |
case '5': | |
case '6': | |
case '7': | |
case '8': | |
case '9': | |
return true | |
} | |
return false | |
} | |
function addDigit(currentValue, input) { | |
const digit = parseInt(input, 10) | |
return currentValue ? (currentValue * 10 + digit) : digit | |
} | |
function call(operation, a, b) { | |
if (b === undefined) return a | |
if (a === undefined) return b | |
switch (operation) { | |
case '+': return a + b | |
case '-': return a - b | |
case '*': return a * b | |
case '/': return a / b | |
} | |
} | |
function or(a, b) { | |
return a === undefined ? b : a | |
} | |
const editorCompute = CodeMirror.fromTextArea(document.getElementById('editorCompute'), { | |
lineNumbers: true, | |
mode: 'javascript', | |
// theme: 'material' | |
}) | |
editorCompute.getWrapperElement().classList.add('editorCompute') | |
const editorDisplayValue = CodeMirror.fromTextArea(document.getElementById('editorDisplayValue'), { | |
lineNumbers: true, | |
mode: 'javascript', | |
// theme: 'material' | |
}) | |
editorDisplayValue.getWrapperElement().classList.add('editorDisplayValue') | |
const display = document.getElementById('display') | |
let state = {} | |
document.getElementById('buttons').onclick = function(event) { | |
if (event.target.classList.contains('disabled')) return | |
const input = event.target.innerText | |
console.log('--------------') | |
console.log('input:', input) | |
state = compute(state, input) | |
console.log('state:', state) | |
const valueToDisplay = displayValue(state) | |
display.innerText = valueToDisplay === undefined ? '' : valueToDisplay | |
} | |
function reload() { | |
compute = Function(editorCompute.getValue())() | |
displayValue = Function(editorDisplayValue.getValue())() | |
} | |
reload() | |
document.getElementById('reload').onclick = reload | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment