Reformat JavaScript

This commit is contained in:
Florine W. Dekker 2019-11-25 00:01:11 +01:00
parent b2154c3bd4
commit e44bfa1c36
Signed by: FWDekker
GPG Key ID: B1B567AF58D6EE0F
1 changed files with 174 additions and 176 deletions

View File

@ -19,199 +19,197 @@
<link rel="stylesheet" href="https://static.fwdekker.com/css/milligram-common.css" crossorigin="anonymous" /> <link rel="stylesheet" href="https://static.fwdekker.com/css/milligram-common.css" crossorigin="anonymous" />
</head> </head>
<body> <body>
<main class="wrapper"> <main class="wrapper">
<!-- Header --> <!-- Header -->
<header class="header"> <header class="header">
<section class="container">
<h1>Converter</h1>
<blockquote>
<p><em>Convert numbers to and from various bases.</em></p>
</blockquote>
</section>
</header>
<!-- Input -->
<section class="container"> <section class="container">
<div class="row"> <h1>Converter</h1>
<div class="column"> <blockquote>
<form> <p><em>Convert numbers to and from various bases.</em></p>
<fieldset id="inputs"> </blockquote>
</fieldset>
</form>
</div>
</div>
</section> </section>
</header>
<!-- Footer --> <!-- Input -->
<footer class="footer"> <section class="container">
<section class="container"> <div class="row">
Made by <a href="https://fwdekker.com/">Felix W. Dekker</a>. <div class="column">
Licensed under the <form>
<a href="https://git.fwdekker.com/FWDekker/converter/src/branch/master/LICENSE">MIT License</a>. <fieldset id="inputs">
Source code available on <a href="https://git.fwdekker.com/FWDekker/converter/">git</a>. </fieldset>
</section> </form>
</footer> </div>
</main> </div>
</section>
<!-- Scripts --> <!-- Footer -->
<script src="https://static.fwdekker.com/js/common.js" crossorigin="anonymous"></script> <footer class="footer">
<script src="https://cdnjs.cloudflare.com/ajax/libs/big-integer/1.6.44/BigInteger.min.js" <section class="container">
integrity="sha256-es+ex6Oj344uak+VnCPyaHY2nzQkqhr7ByWVQgdjATA=" crossorigin="anonymous"></script> Made by <a href="https://fwdekker.com/">Felix W. Dekker</a>.
<script> Licensed under the
const stringReplaceAt = function (str, index, replacement) { <a href="https://git.fwdekker.com/FWDekker/converter/src/branch/master/LICENSE">MIT License</a>.
return str.substr(0, index) + replacement + str.substr(index + replacement.length); Source code available on <a href="https://git.fwdekker.com/FWDekker/converter/">git</a>.
}; </section>
</footer>
const stringReplaceAll = function (str, target, replacement) { </main>
return str.split(target).join(replacement);
};
class NumeralSystem { <!-- Scripts -->
constructor(base, alphabet, caseSensitive) { <script src="https://static.fwdekker.com/js/common.js" crossorigin="anonymous"></script>
this.base = base; <script src="https://cdnjs.cloudflare.com/ajax/libs/big-integer/1.6.44/BigInteger.min.js"
this.alphabet = alphabet; integrity="sha256-es+ex6Oj344uak+VnCPyaHY2nzQkqhr7ByWVQgdjATA=" crossorigin="anonymous"></script>
this.caseSensitive = caseSensitive; <script>
} const stringReplaceAt =
(str, index, replacement) => str.substr(0, index) + replacement + str.substr(index + replacement.length);
const stringReplaceAll =
(str, target, replacement) => str.split(target).join(replacement);
decimalToBase(decimalNumber) { class NumeralSystem {
return decimalNumber.toString(this.base, this.alphabet); constructor(base, alphabet, caseSensitive) {
} this.base = base;
this.alphabet = alphabet;
baseToDecimal(baseString) { this.caseSensitive = caseSensitive;
return bigInt(baseString, this.base, this.alphabet, this.caseSensitive);
}
filterBaseString(baseString) {
// Regex from https://stackoverflow.com/a/3561711/
const regexSafeAlphabet = this.alphabet.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
return baseString.replace(new RegExp(`[^${regexSafeAlphabet}]`), "");
}
}
class NumeralSystemInput {
constructor(name, numeralSystem) {
this.name = name;
this.numeralSystem = numeralSystem;
this.label = document.createElement("label");
this.label.setAttribute("for", `${this.name}Input`);
this.label.innerHTML = this.name;
this.textarea = document.createElement("textarea");
this.textarea.id = `${this.name}Input`;
this.textarea.className = "numberInput";
this.textarea.oninput = () => {
if (this.textarea.value === undefined || this.textarea.value === null || this.textarea.value === "")
return;
this.textarea.value = this.numeralSystem.filterBaseString(this.textarea.value);
updateAllInputs(this.numeralSystem.baseToDecimal(this.textarea.value));
};
}
addToParent(parent) {
parent.appendChild(this.label);
parent.appendChild(this.textarea);
}
update(decimalNumber) {
this.textarea.value = this.numeralSystem.decimalToBase(decimalNumber);
}
}
class Base64NumeralSystemInput extends NumeralSystemInput {
static defaultAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static dropdownOptions = {"Standard": ['+', '/'], "Filename": ['-', '_'], "IMAP": ['+', ',']};
constructor(name) {
super(name, new NumeralSystem(64, Base64NumeralSystemInput.defaultAlphabet, true));
this.dropdownLabel = document.createElement("label");
this.dropdownLabel.setAttribute("for", `${this.name}Dropdown`);
this.dropdownLabel.innerHTML = "Character set";
this.dropdownLabel.classList.add("label-inline");
this.dropdown = document.createElement("select");
this.dropdown.id = `${this.name}Dropdown`;
this.dropdown.onchange = () => {
const selectedOption = Base64NumeralSystemInput.dropdownOptions[this.dropdown.value];
this.setLastDigits(selectedOption[0], selectedOption[1]);
};
this.dropdownDiv = document.createElement("div");
this.dropdownDiv.classList.add("float-right");
this.options =
Object.keys(Base64NumeralSystemInput.dropdownOptions).map(key => {
const option = document.createElement("option");
option.value = key;
option.text = key + ": " + Base64NumeralSystemInput.dropdownOptions[key].join("");
return option;
});
}
setLastDigits(c62, c63) {
const oc62 = this.numeralSystem.alphabet[62];
const oc63 = this.numeralSystem.alphabet[63];
this.numeralSystem.alphabet =
stringReplaceAt(stringReplaceAt(this.numeralSystem.alphabet, 62, c62), 63, c63);
this.textarea.value =
stringReplaceAll(stringReplaceAll(this.textarea.value, oc62, c62), oc63, c63);
}
addToParent(parent) {
this.dropdownDiv.appendChild(this.dropdownLabel);
this.options.forEach(option => this.dropdown.appendChild(option));
this.dropdownDiv.appendChild(this.dropdown);
parent.appendChild(this.dropdownDiv);
parent.appendChild(this.label);
parent.appendChild(this.textarea);
}
} }
const inputs = [ decimalToBase(decimalNumber) {
new NumeralSystemInput("Binary", new NumeralSystem(2, "01")), return decimalNumber.toString(this.base, this.alphabet);
new NumeralSystemInput("Octal", new NumeralSystem(8, "01234567")), }
new NumeralSystemInput("Decimal", new NumeralSystem(10, "0123456789")),
new NumeralSystemInput("Duodecimal", new NumeralSystem(12, "0123456789ab", caseSensitive = false)),
new NumeralSystemInput("Hexadecimal", new NumeralSystem(16, "0123456789abcdef", caseSensitive = false)),
new Base64NumeralSystemInput("Base64"),
new NumeralSystemInput(
"ASCII",
new NumeralSystem(
256,
new Array(256).fill(0).map((_, it) => String.fromCharCode(it)).join(""),
caseSensitive = true
)
),
];
const updateAllInputs = newValue => { baseToDecimal(baseString) {
for (const input of inputs) return bigInt(baseString, this.base, this.alphabet, this.caseSensitive);
input.update(newValue); }
};
filterBaseString(baseString) {
// Regex from https://stackoverflow.com/a/3561711/
const regexSafeAlphabet = this.alphabet.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
return baseString.replace(new RegExp(`[^${regexSafeAlphabet}]`), "");
}
}
class NumeralSystemInput {
constructor(name, numeralSystem) {
this.name = name;
this.numeralSystem = numeralSystem;
this.label = document.createElement("label");
this.label.setAttribute("for", `${this.name}Input`);
this.label.innerHTML = this.name;
this.textarea = document.createElement("textarea");
this.textarea.id = `${this.name}Input`;
this.textarea.className = "numberInput";
this.textarea.oninput = () => {
if (this.textarea.value === undefined || this.textarea.value === null || this.textarea.value === "")
return;
this.textarea.value = this.numeralSystem.filterBaseString(this.textarea.value);
updateAllInputs(this.numeralSystem.baseToDecimal(this.textarea.value));
};
}
doAfterLoad(() => { addToParent(parent) {
const inputParent = $("#inputs"); parent.appendChild(this.label);
parent.appendChild(this.textarea);
}
for (const input of inputs) update(decimalNumber) {
input.addToParent(inputParent); this.textarea.value = this.numeralSystem.decimalToBase(decimalNumber);
}
}
updateAllInputs(bigInt(42)); class Base64NumeralSystemInput extends NumeralSystemInput {
inputs[0].textarea.focus(); static defaultAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
}); static dropdownOptions = {"Standard": ['+', '/'], "Filename": ['-', '_'], "IMAP": ['+', ',']};
</script>
constructor(name) {
super(name, new NumeralSystem(64, Base64NumeralSystemInput.defaultAlphabet, true));
this.dropdownLabel = document.createElement("label");
this.dropdownLabel.setAttribute("for", `${this.name}Dropdown`);
this.dropdownLabel.innerHTML = "Character set";
this.dropdownLabel.classList.add("label-inline");
this.dropdown = document.createElement("select");
this.dropdown.id = `${this.name}Dropdown`;
this.dropdown.onchange = () => {
const selectedOption = Base64NumeralSystemInput.dropdownOptions[this.dropdown.value];
this.setLastDigits(selectedOption[0], selectedOption[1]);
};
this.dropdownDiv = document.createElement("div");
this.dropdownDiv.classList.add("float-right");
this.options =
Object.keys(Base64NumeralSystemInput.dropdownOptions).map(key => {
const option = document.createElement("option");
option.value = key;
option.text = key + ": " + Base64NumeralSystemInput.dropdownOptions[key].join("");
return option;
});
}
setLastDigits(c62, c63) {
const oc62 = this.numeralSystem.alphabet[62];
const oc63 = this.numeralSystem.alphabet[63];
this.numeralSystem.alphabet =
stringReplaceAt(stringReplaceAt(this.numeralSystem.alphabet, 62, c62), 63, c63);
this.textarea.value =
stringReplaceAll(stringReplaceAll(this.textarea.value, oc62, c62), oc63, c63);
}
addToParent(parent) {
this.dropdownDiv.appendChild(this.dropdownLabel);
this.options.forEach(option => this.dropdown.appendChild(option));
this.dropdownDiv.appendChild(this.dropdown);
parent.appendChild(this.dropdownDiv);
parent.appendChild(this.label);
parent.appendChild(this.textarea);
}
}
const inputs = [
new NumeralSystemInput("Binary", new NumeralSystem(2, "01")),
new NumeralSystemInput("Octal", new NumeralSystem(8, "01234567")),
new NumeralSystemInput("Decimal", new NumeralSystem(10, "0123456789")),
new NumeralSystemInput("Duodecimal", new NumeralSystem(12, "0123456789ab", caseSensitive = false)),
new NumeralSystemInput("Hexadecimal", new NumeralSystem(16, "0123456789abcdef", caseSensitive = false)),
new Base64NumeralSystemInput("Base64"),
new NumeralSystemInput(
"ASCII",
new NumeralSystem(
256,
new Array(256).fill(0).map((_, it) => String.fromCharCode(it)).join(""),
caseSensitive = true
)
),
];
const updateAllInputs = newValue => {
for (const input of inputs)
input.update(newValue);
};
doAfterLoad(() => {
const inputParent = $("#inputs");
for (const input of inputs)
input.addToParent(inputParent);
updateAllInputs(bigInt(42));
inputs[0].textarea.focus();
});
</script>
</body> </body>
</html> </html>