mirror of
https://github.com/Asraelite/littlebigcomputer.git
synced 2025-07-18 08:26:51 +00:00
Init commit
This commit is contained in:
commit
c45ad79440
48 changed files with 6786 additions and 0 deletions
85
assembler/ldt/lib/Keybinder.js
Normal file
85
assembler/ldt/lib/Keybinder.js
Normal file
|
@ -0,0 +1,85 @@
|
|||
/* Keybinder.js
|
||||
* written by Colin Kuebler 2012
|
||||
* Part of LDT, dual licensed under GPLv3 and MIT
|
||||
* Simplifies the creation of keybindings on any element
|
||||
*/
|
||||
|
||||
var Keybinder = {
|
||||
bind: function( element, keymap ){
|
||||
element.keymap = keymap;
|
||||
var keyNames = {
|
||||
8: "Backspace",
|
||||
9: "Tab",
|
||||
13: "Enter",
|
||||
16: "Shift",
|
||||
17: "Ctrl",
|
||||
18: "Alt",
|
||||
19: "Pause",
|
||||
20: "CapsLk",
|
||||
27: "Esc",
|
||||
33: "PgUp",
|
||||
34: "PgDn",
|
||||
35: "End",
|
||||
36: "Home",
|
||||
37: "Left",
|
||||
38: "Up",
|
||||
39: "Right",
|
||||
40: "Down",
|
||||
45: "Insert",
|
||||
46: "Delete",
|
||||
112: "F1",
|
||||
113: "F2",
|
||||
114: "F3",
|
||||
115: "F4",
|
||||
116: "F5",
|
||||
117: "F6",
|
||||
118: "F7",
|
||||
119: "F8",
|
||||
120: "F9",
|
||||
121: "F10",
|
||||
122: "F11",
|
||||
123: "F12",
|
||||
145: "ScrLk" };
|
||||
var keyEventNormalizer = function(e){
|
||||
// get the event object and start constructing a query
|
||||
var e = e || window.event;
|
||||
var query = "";
|
||||
// add in prefixes for each key modifier
|
||||
e.shiftKey && (query += "Shift-");
|
||||
e.ctrlKey && (query += "Ctrl-");
|
||||
e.altKey && (query += "Alt-");
|
||||
e.metaKey && (query += "Meta-");
|
||||
// determine the key code
|
||||
var key = e.which || e.keyCode || e.charCode;
|
||||
// if we have a name for it, use it
|
||||
if( keyNames[key] )
|
||||
query += keyNames[key];
|
||||
// otherwise turn it into a string
|
||||
else
|
||||
query += String.fromCharCode(key).toUpperCase();
|
||||
/* DEBUG */
|
||||
//console.log("keyEvent: "+query);
|
||||
// try to run the keybinding, cancel the event if it returns true
|
||||
if( element.keymap[query] && element.keymap[query]() ){
|
||||
e.preventDefault && e.preventDefault();
|
||||
e.stopPropagation && e.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
// capture onkeydown and onkeypress events to capture repeating key events
|
||||
// maintain a boolean so we only fire once per character
|
||||
var fireOnKeyPress = true;
|
||||
element.onkeydown = function(e){
|
||||
fireOnKeyPress = false;
|
||||
return keyEventNormalizer(e);
|
||||
};
|
||||
element.onkeypress = function(e){
|
||||
if( fireOnKeyPress )
|
||||
return keyEventNormalizer(e);
|
||||
fireOnKeyPress = true;
|
||||
return true;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
55
assembler/ldt/lib/Parser.js
Normal file
55
assembler/ldt/lib/Parser.js
Normal file
|
@ -0,0 +1,55 @@
|
|||
/* Parser.js
|
||||
* written by Colin Kuebler 2012
|
||||
* Part of LDT, dual licensed under GPLv3 and MIT
|
||||
* Generates a tokenizer from regular expressions for TextareaDecorator
|
||||
*/
|
||||
|
||||
function Parser(rules, useI) {
|
||||
/* INIT */
|
||||
const api = this;
|
||||
|
||||
// variables used internally
|
||||
const i = useI ? 'i' : '';
|
||||
let parseRegex = null;
|
||||
let ruleSrc = [];
|
||||
let ruleNames = [];
|
||||
let ruleMap = {};
|
||||
|
||||
api.add = function (rules) {
|
||||
for (const [name, rule] of Object.entries(rules)) {
|
||||
let s = rule.source;
|
||||
s = '(?<' + name + '>' + s + ')';
|
||||
ruleSrc.push(s);
|
||||
// ruleMap[rule] = new RegExp('^(' + s + ')$', i);
|
||||
ruleNames.push(name);
|
||||
}
|
||||
parseRegex = new RegExp(ruleSrc.join('|'), 'gm' + i);
|
||||
};
|
||||
api.tokenize = function (input) {
|
||||
const tokens = [];
|
||||
const lines = input.match(/.*\n?/gm);
|
||||
for (const [lineNumber, line] of lines.entries()) {
|
||||
for (const match of line.matchAll(parseRegex)) {
|
||||
for (const ruleName of ruleNames) {
|
||||
if (match.groups[ruleName] !== undefined) {
|
||||
tokens.push({
|
||||
tag: ruleName,
|
||||
text: match[0],
|
||||
lineNumber,
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return tokens;
|
||||
};
|
||||
api.identify = function (token) {
|
||||
return token.tag;
|
||||
};
|
||||
|
||||
api.add(rules);
|
||||
|
||||
return api;
|
||||
};
|
||||
|
25
assembler/ldt/lib/SelectHelper.js
Normal file
25
assembler/ldt/lib/SelectHelper.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* SelectHelper.js
|
||||
* written by Colin Kuebler 2012
|
||||
* Part of LDT, dual licensed under GPLv3 and MIT
|
||||
* Convenient utilities for cross browser textarea selection manipulation
|
||||
*/
|
||||
|
||||
var SelectHelper = {
|
||||
add: function( element ){
|
||||
element.insertAtCursor = element.createTextRange ?
|
||||
// IE version
|
||||
function(x){
|
||||
document.selection.createRange().text = x;
|
||||
} :
|
||||
// standards version
|
||||
function(x){
|
||||
var s = element.selectionStart,
|
||||
e = element.selectionEnd,
|
||||
v = element.value;
|
||||
element.value = v.substring(0, s) + x + v.substring(e);
|
||||
s += x.length;
|
||||
element.setSelectionRange(s, s);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
65
assembler/ldt/lib/TextareaDecorator.css
Normal file
65
assembler/ldt/lib/TextareaDecorator.css
Normal file
|
@ -0,0 +1,65 @@
|
|||
/* TextareaDecorator.css
|
||||
* written by Colin Kuebler 2012
|
||||
* Part of LDT, dual licensed under GPLv3 and MIT
|
||||
* Provides styles for rendering a textarea on top of a pre with scrollbars
|
||||
*/
|
||||
|
||||
/* settings you can play with */
|
||||
|
||||
.ldt, .ldt label {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.ldt, .ldt pre, .ldt textarea {
|
||||
font-size: 16px !important;
|
||||
/* resize algorithm depends on a monospaced font */
|
||||
font-family: monospace !important;
|
||||
}
|
||||
|
||||
.ldt textarea {
|
||||
/* hide the text but show the text caret */
|
||||
color: transparent;
|
||||
/* Firefox caret position is slow to update when color is transparent */
|
||||
color: rgba(0, 0, 0, 0.004);
|
||||
caret-color: #000;
|
||||
}
|
||||
|
||||
/* settings you shouldn't play with unless you have a good reason */
|
||||
|
||||
.ldt {
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ldt pre {
|
||||
margin: 0;
|
||||
overflow: initial;
|
||||
}
|
||||
|
||||
.ldt label {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: inline;
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.ldt textarea {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: 0;
|
||||
outline: none;
|
||||
resize: none;
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
overflow: hidden;
|
||||
/* IE doesn't support rgba textarea, so use vendor specific alpha filter */
|
||||
filter: alpha(opacity = 20);
|
||||
}
|
||||
|
111
assembler/ldt/lib/TextareaDecorator.js
Normal file
111
assembler/ldt/lib/TextareaDecorator.js
Normal file
|
@ -0,0 +1,111 @@
|
|||
/* TextareaDecorator.js
|
||||
* written by Colin Kuebler 2012
|
||||
* Part of LDT, dual licensed under GPLv3 and MIT
|
||||
* Builds and maintains a styled output layer under a textarea input layer
|
||||
*/
|
||||
function TextareaDecorator(textarea, parser) {
|
||||
/* INIT */
|
||||
var api = this;
|
||||
this.parser = parser;
|
||||
this.errorMap = {};
|
||||
|
||||
// construct editor DOM
|
||||
var parent = document.createElement("div");
|
||||
var output = document.createElement("pre");
|
||||
parent.appendChild(output);
|
||||
var label = document.createElement("label");
|
||||
parent.appendChild(label);
|
||||
// replace the textarea with RTA DOM and reattach on label
|
||||
textarea.parentNode.replaceChild(parent, textarea);
|
||||
label.appendChild(textarea);
|
||||
// transfer the CSS styles to our editor
|
||||
parent.className = 'ldt ' + textarea.className;
|
||||
textarea.className = '';
|
||||
// turn off built-in spellchecking in firefox
|
||||
textarea.spellcheck = false;
|
||||
// turn off word wrap
|
||||
textarea.wrap = "off";
|
||||
|
||||
var getParser = () => {
|
||||
return this.parser;
|
||||
}
|
||||
|
||||
var getErrorMap = () => {
|
||||
return this.errorMap;
|
||||
}
|
||||
|
||||
// coloring algorithm
|
||||
var color = function (input, output, parser) {
|
||||
var oldTokens = output.childNodes;
|
||||
var newTokens = parser.tokenize(input);
|
||||
var firstDiff, lastDiffNew, lastDiffOld;
|
||||
output.innerHTML = '';
|
||||
|
||||
// add in modified spans
|
||||
for (const token of newTokens) {
|
||||
var span = document.createElement("span");
|
||||
span.className = token.tag;
|
||||
if (getErrorMap()[token.lineNumber]) {
|
||||
span.classList.add('error');
|
||||
}
|
||||
span.textContent = span.innerText = token.text;
|
||||
output.appendChild(span);
|
||||
}
|
||||
};
|
||||
|
||||
api.input = textarea;
|
||||
api.output = output;
|
||||
api.update = function () {
|
||||
var input = textarea.value;
|
||||
if (input) {
|
||||
color(input, output, getParser());
|
||||
// determine the best size for the textarea
|
||||
var lines = input.split('\n');
|
||||
// find the number of columns
|
||||
var maxlen = 0, curlen;
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
// calculate the width of each tab
|
||||
var tabLength = 0, offset = -1;
|
||||
while ((offset = lines[i].indexOf('\t', offset + 1)) > -1) {
|
||||
tabLength += 7 - (tabLength + offset) % 8;
|
||||
}
|
||||
var curlen = lines[i].length + tabLength;
|
||||
// store the greatest line length thus far
|
||||
maxlen = maxlen > curlen ? maxlen : curlen;
|
||||
}
|
||||
textarea.cols = maxlen + 1;
|
||||
textarea.rows = lines.length + 2;
|
||||
} else {
|
||||
// clear the display
|
||||
output.innerHTML = '';
|
||||
// reset textarea rows/cols
|
||||
textarea.cols = textarea.rows = 1;
|
||||
}
|
||||
};
|
||||
|
||||
// detect all changes to the textarea,
|
||||
// including keyboard input, cut/copy/paste, drag & drop, etc
|
||||
if (textarea.addEventListener) {
|
||||
// standards browsers: oninput event
|
||||
textarea.addEventListener("input", api.update, false);
|
||||
} else {
|
||||
// MSIE: detect changes to the 'value' property
|
||||
textarea.attachEvent("onpropertychange",
|
||||
function (e) {
|
||||
if (e.propertyName.toLowerCase() === 'value') {
|
||||
api.update();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
// initial highlighting
|
||||
api.update();
|
||||
|
||||
api.setErrorMap = (errors) => {
|
||||
this.errorMap = errors;
|
||||
api.update();
|
||||
}
|
||||
|
||||
return api;
|
||||
};
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue