Browse Source

Add linting and fix lint errors

feature/service-worker
Hamcha 1 year ago
parent
commit
42ed7591b6
Signed by untrusted user: Hamcha GPG Key ID: 41467804B19A3315
  1. 142
      .drone.yml
  2. 29
      .eslintrc.js
  3. 4
      .prettierrc
  4. 2
      README.md
  5. 22
      index.html
  6. 13
      lib/TabManager.ts
  7. 87
      lib/darkmode.ts
  8. 177
      lib/userscript.ts
  9. 4
      lib/wiki.ts
  10. 9
      package.json
  11. 875
      yarn.lock

142
.drone.yml

@ -0,0 +1,142 @@
kind: pipeline
name: default
steps:
- name: restore-cache
image: drillster/drone-volume-cache
volumes:
- name: cache
path: /cache
settings:
restore: true
mount:
- ./node_modules
- name: dependencies
image: node
failure: ignore
commands:
- yarn
depends_on:
- restore-cache
- name: lint
image: node
commands:
- yarn lint
depends_on:
- dependencies
- name: build_versioned
image: node
commands:
- yarn build
when:
event:
- push
branch:
exclude:
- master
depends_on:
- dependencies
- name: build_pr
image: node
commands:
- yarn build
when:
event:
- pull_request
depends_on:
- dependencies
- name: build_master
image: node
commands:
- yarn build
environment:
SUBPATH: /latest
when:
event:
- push
branch:
- master
depends_on:
- dependencies
- name: upload_build_versioned
image: plugins/s3
settings:
bucket: tghandbook
access_key:
from_secret: minio_access
secret_key:
from_secret: minio_secret
source: dist/**/*
target: /${DRONE_COMMIT_SHA:0:8}/
path_style: true
endpoint: https://artifacts.fromouter.space
when:
event:
- push
branch:
exclude:
- master
depends_on:
- build_versioned
- name: upload_build_pr
image: plugins/s3
settings:
bucket: tghandbook
access_key:
from_secret: minio_access
secret_key:
from_secret: minio_secret
source: dist/**/*
target: /pr-${DRONE_PULL_REQUEST}/
path_style: true
endpoint: https://artifacts.fromouter.space
when:
event:
- pull_request
depends_on:
- build_pr
- name: upload_build_master
image: plugins/s3
settings:
bucket: tghandbook
access_key:
from_secret: minio_access
secret_key:
from_secret: minio_secret
source: dist/**/*
target: /latest/
path_style: true
endpoint: https://artifacts.fromouter.space
when:
event:
- push
branch:
- master
depends_on:
- build_master
- name: rebuild-cache
image: drillster/drone-volume-cache
failure: ignore
volumes:
- name: cache
path: /cache
settings:
rebuild: true
mount:
- ./node_modules
depends_on:
- dependencies
volumes:
- name: cache
host:
path: /opt/gitea/drone-cache/hamcha/tghandbook

29
.eslintrc.js

@ -0,0 +1,29 @@
module.exports = {
env: {
browser: true,
es2020: true,
},
extends: [
"airbnb-base",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
],
parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint", "prettier"],
rules: {
"prettier/prettier": "error",
"one-var": "off", // WHO CARES?????
"no-use-before-define": "off", // YOU ARE WRONG
"import/extensions": "off",
"import/no-unresolved": "off",
"no-param-reassign": "off",
"no-alert": "off",
"no-console": "off",
"@typescript-eslint/ban-ts-comment": [
"error",
{
"ts-expect-error": "allow-with-description",
},
],
},
};

4
.prettierrc

@ -0,0 +1,4 @@
{
"singleQuote": false,
"endOfLine": "auto"
}

2
README.md

@ -1,5 +1,7 @@
# /tg/ handbook
[![Build Status](https://drone.zyg.ovh/api/badges/Hamcha/tghandbook/status.svg)](https://drone.zyg.ovh/Hamcha/tghandbook)
## Building
`yarn build`

22
index.html

@ -3,7 +3,25 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="assets/fonts/iosevka/iosevka-aile.css" />
<link
rel="preload"
href="assets/fonts/iosevka/iosevka-aile.css"
as="style"
/>
<link
rel="preload"
href="assets/fonts/iosevka/woff2/iosevka-aile-regular.woff2"
as="font"
/>
<link rel="preload" href="style/main.scss" as="style" />
<link rel="preload" href="style/bgus.scss" as="style" />
<link rel="preload" href="lib/index.ts" as="script" />
<link
rel="stylesheet"
href="assets/fonts/iosevka/iosevka-aile.css"
media="async"
onload="this.media='all'"
/>
<link rel="stylesheet" href="style/main.scss" />
<link rel="stylesheet" href="style/bgus.scss" />
<title>/tg/ Handbook</title>
@ -16,6 +34,6 @@
<nav id="tab-list"></nav>
<section id="tabs"></section>
</main>
<script src="lib/index.ts"></script>
<script src="lib/index.ts" async></script>
</body>
</html>

13
lib/TabManager.ts

@ -1,3 +1,4 @@
// @ts-expect-error: Asset imports are handled by parcel
import speen from "~/assets/images/speen.svg";
import { getPageHTML } from "./wiki";
import userscript from "./userscript";
@ -19,7 +20,7 @@ function initWaiting(elem: HTMLElement) {
async function loadPage(page: string, elem: HTMLElement) {
// Fetch page content
console.log(page + ": fetching");
console.log(`${page}: fetching`);
let html = await getPageHTML(page);
// Convert relative links to absolute
@ -28,9 +29,9 @@ async function loadPage(page: string, elem: HTMLElement) {
// Set as HTML content and run HTML manipulations on it
requestAnimationFrame(() => {
elem.innerHTML = html;
console.log(page + ": processing");
console.log(`${page}: processing`);
userscript(elem, page);
console.log(page + ": userscript applied");
console.log(`${page}: userscript applied`);
elem.classList.remove("waiting");
});
}
@ -39,7 +40,9 @@ type TabElements = { tabListItem: HTMLElement; tabContentItem: HTMLElement };
export default class TabManager {
tabListContainer: HTMLElement;
tabContentContainer: HTMLElement;
tabs: Record<string, TabElements> = {};
constructor(tablist: HTMLElement, tabcontent: HTMLElement) {
@ -47,7 +50,7 @@ export default class TabManager {
this.tabContentContainer = tabcontent;
}
openTab(page: string, setActive: boolean) {
openTab(page: string, setActive: boolean): void {
// Create tab list item
const tabListItem = document.createElement("div");
tabListItem.className = "tab";
@ -80,7 +83,7 @@ export default class TabManager {
}
}
setActive(page: string) {
setActive(page: string): void {
// Make sure tab exists (why wouldn't it?!)
if (!(page in this.tabs)) {
throw new Error("tab not found");

87
lib/darkmode.ts

@ -16,48 +16,61 @@ export enum ColorFmt {
}
function hsvToRgb({ h, s, v }: ColorHSV): ColorRGB {
var r, g, b;
let r, g, b;
var i = Math.floor(h * 6);
var f = h * 6 - i;
var p = v * (1 - s);
var q = v * (1 - f * s);
var t = v * (1 - (1 - f) * s);
const i = Math.floor(h * 6);
const f = h * 6 - i;
const p = v * (1 - s);
const q = v * (1 - f * s);
const t = v * (1 - (1 - f) * s);
switch (i % 6) {
case 0:
(r = v), (g = t), (b = p);
r = v;
g = t;
b = p;
break;
case 1:
(r = q), (g = v), (b = p);
r = q;
g = v;
b = p;
break;
case 2:
(r = p), (g = v), (b = t);
r = p;
g = v;
b = t;
break;
case 3:
(r = p), (g = q), (b = v);
r = p;
g = q;
b = v;
break;
case 4:
(r = t), (g = p), (b = v);
r = t;
g = p;
b = v;
break;
case 5:
(r = v), (g = p), (b = q);
r = v;
g = p;
b = q;
break;
default:
throw new Error("unreacheable");
}
return { r, g, b };
}
function rgbToHsv({ r, g, b }: ColorRGB): ColorHSV {
var max = Math.max(r, g, b),
min = Math.min(r, g, b);
var h,
s,
v = max;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
const v = max;
var d = max - min;
s = max == 0 ? 0 : d / max;
const d = max - min;
const s = max === 0 ? 0 : d / max;
if (max == min) {
let h;
if (max === min) {
h = 0; // achromatic
} else {
switch (max) {
@ -70,6 +83,8 @@ function rgbToHsv({ r, g, b }: ColorRGB): ColorHSV {
case b:
h = (r - g) / d + 4;
break;
default:
throw new Error("unreacheable");
}
h /= 6;
}
@ -80,13 +95,13 @@ function rgbToHsv({ r, g, b }: ColorRGB): ColorHSV {
// Hacky way to get RGB values FOR SURE!
function nameToRGB(name: string): ColorRGB {
// Create fake div
let fakeDiv = document.createElement("div");
const fakeDiv = document.createElement("div");
fakeDiv.style.color = name;
document.body.appendChild(fakeDiv);
// Get color of div
let cs = window.getComputedStyle(fakeDiv),
pv = cs.getPropertyValue("color");
const cs = window.getComputedStyle(fakeDiv);
const pv = cs.getPropertyValue("color");
// Remove div after obtaining desired color value
document.body.removeChild(fakeDiv);
@ -98,9 +113,9 @@ function nameToRGB(name: string): ColorRGB {
// https://stackoverflow.com/questions/11068240/what-is-the-most-efficient-way-to-parse-a-css-color-in-javascript
function parseColor(input: string): ColorRGB {
// Hex format
if (input.substr(0, 1) == "#") {
var collen = (input.length - 1) / 3;
var fact = [17, 1, 0.062272][collen - 1];
if (input.substr(0, 1) === "#") {
const collen = (input.length - 1) / 3;
const fact = [17, 1, 0.062272][collen - 1];
return {
r: Math.round(parseInt(input.substr(1, collen), 16) * fact) / 256,
g:
@ -132,11 +147,13 @@ function serializeColor(col: ColorRGB, format: ColorFmt): string {
case ColorFmt.RGB:
return `rgb(${r}, ${g}, ${b})`;
case ColorFmt.HEX: {
const rhex = ("00" + r.toString(16)).slice(-2);
const ghex = ("00" + g.toString(16)).slice(-2);
const bhex = ("00" + b.toString(16)).slice(-2);
return "#" + rhex + ghex + bhex;
const rhex = `00${r.toString(16)}`.slice(-2);
const ghex = `00${g.toString(16)}`.slice(-2);
const bhex = `00${b.toString(16)}`.slice(-2);
return `#${rhex}${ghex}${bhex}`;
}
default:
return "#000";
}
}
@ -147,12 +164,10 @@ export function darken(color: string, format: ColorFmt): string {
hsl.h = 0.6;
hsl.s = 0.5;
hsl.v = Math.max(0.2, 1 - hsl.v);
} else {
if (hsl.v > 0.5) {
hsl.v = 0.4;
if (hsl.s > 0.2) {
hsl.s = Math.min(1, hsl.s + 0.2);
}
} else if (hsl.v > 0.5) {
hsl.v = 0.4;
if (hsl.s > 0.2) {
hsl.s = Math.min(1, hsl.s + 0.2);
}
}
const out = hsvToRgb(hsl);

177
lib/userscript.ts

@ -4,7 +4,7 @@ const DEFAULT_OPTS = {
alignment: "center",
};
export default function (root: HTMLElement, docname: string) {
export default function userscript(root: HTMLElement, docname: string): void {
root.querySelectorAll(".mw-editsection").forEach((editLink) => {
editLink.parentElement.removeChild(editLink);
});
@ -15,16 +15,16 @@ export default function (root: HTMLElement, docname: string) {
// Shitty way to detect if it's hex or not
// Basically, none of the css colors long 6 letters only use hex letters
// THANK FUCKING GOD
if (bgcolor.length === 6 && parseInt(bgcolor, 16) !== NaN) {
bgcolor = "#" + bgcolor;
if (bgcolor.length === 6 && Number.isNaN(parseInt(bgcolor, 16))) {
bgcolor = `#${bgcolor}`;
}
td.setAttribute("bgcolor", darken(bgcolor, ColorFmt.HEX).slice(1));
});
root.querySelectorAll("*[style]").forEach((td: HTMLElement) => {
if (td.style.backgroundColor != "") {
if (td.style.backgroundColor !== "") {
td.style.backgroundColor = darken(td.style.backgroundColor, ColorFmt.RGB);
}
if (td.style.background != "") {
if (td.style.background !== "") {
td.style.backgroundColor = darken(td.style.background, ColorFmt.RGB);
}
});
@ -32,8 +32,8 @@ export default function (root: HTMLElement, docname: string) {
// Lighten fgcolors
root.querySelectorAll("*[color]").forEach((td) => {
let color = td.getAttribute("color");
if (color.length === 6 && !isNaN(parseInt(color, 16))) {
color = "#" + color;
if (color.length === 6 && !Number.isNaN(parseInt(color, 16))) {
color = `#${color}`;
}
td.setAttribute("color", lighten(color, ColorFmt.HEX).slice(1));
});
@ -43,7 +43,7 @@ export default function (root: HTMLElement, docname: string) {
td.setAttribute("width", "100%");
});
root.querySelectorAll("table[style]").forEach((td: HTMLTableElement) => {
if (td.style.width != "") {
if (td.style.width !== "") {
td.style.width = "100%";
}
});
@ -88,14 +88,14 @@ export default function (root: HTMLElement, docname: string) {
postbody.insertBefore(statusMessage, postbody.firstChild);
// TODO Refactor this mess
function searchBox(el, search_candidate, options = DEFAULT_OPTS) {
function searchBox(el, searchCandidate, options = DEFAULT_OPTS) {
// Fuzzy search box
const resultList = document.createElement("ul");
const searchBox = document.createElement("div");
let selected_result = null;
const searchBoxElem = document.createElement("div");
let selectedResult = null;
let results = [];
const jumpTo = function (id) {
const jumpTo = (id) => {
el[id].scrollIntoView({
block: options.alignment,
inline: "nearest",
@ -103,15 +103,15 @@ export default function (root: HTMLElement, docname: string) {
});
document
.querySelectorAll("table.wikitable .bgus_fz_selected")
.forEach((el) => el.classList.remove("bgus_fz_selected"));
.forEach((sel) => sel.classList.remove("bgus_fz_selected"));
el[id].parentElement.classList.add("bgus_fz_selected");
};
const setSelectedResult = function (i) {
selected_result = i;
const setSelectedResult = (i) => {
selectedResult = i;
resultList
.querySelectorAll(".selected")
.forEach((el) => el.classList.remove("selected"));
.forEach((sel) => sel.classList.remove("selected"));
resultList.children[i].classList.add("selected");
jumpTo(results[i].id);
};
@ -121,15 +121,13 @@ export default function (root: HTMLElement, docname: string) {
return;
}
const regex = new RegExp(
"^(.*?)([" +
str
.split("")
.map((c) => (c.includes(["\\", "]", "^"]) ? "\\" + c : c))
.join("])(.*?)([") +
"])(.*?)$",
`^(.*?)([${str
.split("")
.map((c) => (c.includes(["\\", "]", "^"]) ? `\\${c}` : c))
.join("])(.*?)([")}])(.*?)$`,
"i"
);
const arr = search_candidate
const arr = searchCandidate
.map((o) => {
o.matches = (o.str.match(regex) || [])
.slice(1)
@ -148,7 +146,7 @@ export default function (root: HTMLElement, docname: string) {
}
return list;
}, [])
.map((str) => str.join(""));
.map((cstr) => cstr.join(""));
return o;
})
// Strike non-matching rows
@ -164,7 +162,7 @@ export default function (root: HTMLElement, docname: string) {
if (a.length !== 1 && b.length === 1) return 1;
// Most complete groups (alphanumeric)
const clean = (el) => !/[^a-zA-Z0-9]*$/.test(el);
const clean = (cel) => !/[^a-zA-Z0-9]*$/.test(cel);
const cLen = a.filter(clean).length - b.filter(clean).length;
if (cLen !== 0) return cLen;
@ -187,11 +185,11 @@ export default function (root: HTMLElement, docname: string) {
arr.forEach(({ matches, id }) => {
const li = document.createElement("li");
li.innerHTML = matches
.map((c, i) => (i % 2 ? "<strong>" + c + "</strong>" : c))
.map((c, i) => (i % 2 ? `<strong>${c}</strong>` : c))
.join("");
li.addEventListener("click", () => {
jumpTo(id);
searchBox.classList.add("bgus_hidden");
searchBoxElem.classList.add("bgus_hidden");
});
resultList.appendChild(li);
});
@ -203,58 +201,60 @@ export default function (root: HTMLElement, docname: string) {
// Create fuzzy search box
const sel = document.createElement("input");
searchBox.id = "bgus_fz_searchbox";
searchBox.classList.add("bgus_hidden");
searchBox.appendChild(sel);
searchBox.appendChild(resultList);
root.appendChild(searchBox);
searchBoxElem.id = "bgus_fz_searchbox";
searchBoxElem.classList.add("bgus_hidden");
searchBoxElem.appendChild(sel);
searchBoxElem.appendChild(resultList);
root.appendChild(searchBoxElem);
// Bind events
let oldValue = "";
sel.addEventListener("keyup", function (event) {
sel.addEventListener("keyup", (event) => {
switch (event.keyCode) {
case 27: // Escape - Hide bar
searchBox.classList.add("bgus_hidden");
searchBoxElem.classList.add("bgus_hidden");
return;
case 13: // Enter - Jump to first result and hide bar
if (results.length > 0) {
jumpTo(results[selected_result].id);
jumpTo(results[selectedResult].id);
}
searchBox.classList.add("bgus_hidden");
searchBoxElem.classList.add("bgus_hidden");
return;
case 40: // Down arrow - Select next result
if (selected_result < results.length - 1) {
setSelectedResult(selected_result + 1);
if (selectedResult < results.length - 1) {
setSelectedResult(selectedResult + 1);
}
return;
case 38: // Up arrow - Select previous result
if (selected_result > 0) {
setSelectedResult(selected_result - 1);
if (selectedResult > 0) {
setSelectedResult(selectedResult - 1);
}
return;
default:
if (this.value != oldValue) {
search(this.value);
oldValue = this.value;
if (sel.value !== oldValue) {
search(sel.value);
oldValue = sel.value;
}
}
});
document.body.addEventListener("keyup", function (ev) {
document.body.addEventListener("keyup", (ev) => {
if (ev.keyCode === 83) {
sel.focus();
}
});
document.body.addEventListener("keydown", function (ev) {
document.body.addEventListener("keydown", (ev) => {
if (ev.shiftKey) {
switch (ev.keyCode) {
// SHIFT+S = Fuzzy search
case 83: {
searchBox.classList.remove("bgus_hidden");
searchBoxElem.classList.remove("bgus_hidden");
sel.value = "";
return;
break;
}
default:
// Do nothing
}
}
});
@ -268,14 +268,16 @@ export default function (root: HTMLElement, docname: string) {
"table.wikitable > tbody > tr:not(:first-child) > td:nth-child(2), .tooltiptext"
)
.forEach((td) => {
const tmp = td.cloneNode();
const tmp = td.cloneNode() as HTMLElement;
// The cast to Array is necessary because, while childNodes's NodeList technically has a forEach method, it's a live list and operations mess with its lenght in the middle of the loop.
// Nodes can only have one parent so append removes them from the original NodeList and shifts the following one back into the wrong index.
Array.from(td.childNodes).forEach((el) => {
if (el.tagName === "P") {
tmp.append(...el.childNodes);
} else {
tmp.append(el);
if (el instanceof HTMLElement) {
if (el.tagName === "P") {
tmp.append(...el.childNodes);
} else {
tmp.append(el);
}
}
});
td.parentNode.replaceChild(tmp, td);
@ -303,18 +305,20 @@ export default function (root: HTMLElement, docname: string) {
// Add event to autofill child checkboxes
root
.querySelectorAll(".bgus_part_tooltip > .bgus_checkbox")
.forEach((box) => {
.forEach((box: HTMLInputElement) => {
const tooltip = box.parentElement.nextElementSibling;
box.addEventListener("click", function () {
box.addEventListener("click", () => {
tooltip
.querySelectorAll(".bgus_checkbox")
.forEach((el) => (el.checked = this.checked));
.forEach((el: HTMLInputElement) => {
el.checked = box.checked;
});
});
});
// Add event to collapse subsections
root.querySelectorAll(".bgus_nested_element").forEach((twistie) => {
twistie.addEventListener("click", function (evt) {
twistie.addEventListener("click", () => {
twistie.classList.toggle("bgus_collapsed");
});
});
@ -322,15 +326,16 @@ export default function (root: HTMLElement, docname: string) {
// Wrap every recipe with extra metadata
root.querySelectorAll(".bgus_part").forEach((el: HTMLElement) => {
if ("parts" in el.parentElement.dataset) {
el.parentElement.dataset.parts =
parseInt(el.parentElement.dataset.parts) +
parseInt(el.dataset.amount);
el.parentElement.dataset.parts = (
parseInt(el.parentElement.dataset.parts, 10) +
parseInt(el.dataset.amount, 10)
).toString();
} else {
el.parentElement.dataset.parts = el.dataset.amount;
}
});
const setPartSize = function (labels, ml) {
const setPartSize = (labels, ml) => {
labels.forEach((el) => {
const part = el.parentElement.dataset.amount;
const total = el.parentElement.parentElement.dataset.parts;
@ -340,7 +345,7 @@ export default function (root: HTMLElement, docname: string) {
let next = el.parentElement.nextElementSibling;
while (next) {
if (next.classList.contains("tooltip")) {
let sublabels = [];
const sublabels = [];
next.querySelector(".tooltiptext").childNodes.forEach((ch) => {
if (ch.classList && ch.classList.contains("bgus_part")) {
sublabels.push(ch.querySelector(".bgus_part_label"));
@ -365,13 +370,13 @@ export default function (root: HTMLElement, docname: string) {
)
);
const name = el.map((elem) => {
let name = "";
let partial = "";
elem.childNodes.forEach((t) => {
if (t instanceof Text) {
name += t.textContent;
partial += t.textContent;
}
});
return name.trim();
return partial.trim();
});
searchBox(
el,
@ -379,23 +384,23 @@ export default function (root: HTMLElement, docname: string) {
);
// Remove "Removed medicines" section
let remTable = root.querySelector(
const remTable = root.querySelector(
"#Non-craftable_Medicines + h4 + p + table"
);
remTable.parentElement.removeChild(remTable);
root
.querySelectorAll("div[data-name] .wikitable.sortable tr")
.forEach((el: HTMLElement) => {
let sectionEl = el.parentElement;
.forEach((row: HTMLElement) => {
let sectionEl = row.parentElement;
while (!sectionEl.dataset.name) {
sectionEl = sectionEl.parentElement;
}
const section = sectionEl.dataset.name;
if (el.querySelector("td") === null) {
if (row.querySelector("td") === null) {
// Remove unused rows if found
const row = el.querySelectorAll("th");
row.forEach((th, i) => {
const headers = row.querySelectorAll("th");
headers.forEach((th, i) => {
if (i < 2) {
th.classList.add("table-head");
return;
@ -404,7 +409,7 @@ export default function (root: HTMLElement, docname: string) {
});
return;
}
let rows = Array.from(el.querySelectorAll("td")).slice(1);
const rows = Array.from(row.querySelectorAll("td")).slice(1);
let treatment = null;
let desc = null;
let metabolism = null;
@ -428,7 +433,7 @@ export default function (root: HTMLElement, docname: string) {
// All fields
[treatment, desc, metabolism, overdose, addiction] = rows;
}
const title = el.querySelector("th");
const title = row.querySelector("th");
let content = `<div class="reagent-header">${title.innerHTML}</div>`;
if (treatment) {
content += `<p class="treatment">${treatment.innerHTML}</p>`;
@ -436,10 +441,10 @@ export default function (root: HTMLElement, docname: string) {
if (metabolism) {
content += `<p class="metabolism">${metabolism.innerHTML}</p>`;
}
if (addiction && addiction.innerHTML.trim() != "N/A") {
if (addiction && addiction.innerHTML.trim() !== "N/A") {
content += `<p class="addiction">${addiction.innerHTML}</p>`;
}
if (overdose && overdose.innerHTML.trim() != "N/A") {
if (overdose && overdose.innerHTML.trim() !== "N/A") {
content += `<p class="overdose">${overdose.innerHTML}</p>`;
}
if (desc) {
@ -454,7 +459,7 @@ export default function (root: HTMLElement, docname: string) {
if (addiction) addiction.parentElement.removeChild(addiction);
});
document.body.addEventListener("keydown", function (ev) {
document.body.addEventListener("keydown", (ev) => {
if (ev.shiftKey) {
switch (ev.keyCode) {
// SHIFT+C = Toggle checkboxes
@ -462,28 +467,36 @@ export default function (root: HTMLElement, docname: string) {
root.classList.toggle("bgus_cbox");
root
.querySelectorAll(".bgus_checkbox:checked")
.forEach((el: HTMLInputElement) => {
el.checked = false;
.forEach((sel: HTMLInputElement) => {
sel.checked = false;
});
return;
break;
}
// SHIFT+B = Set whole size (beaker?) for parts/units
case 66: {
let size = parseInt(prompt("Write target ml (0 to reset)", "90"));
if (isNaN(size) || size <= 0) {
const size = parseInt(
prompt("Write target ml (0 to reset)", "90"),
10
);
if (Number.isNaN(size) || size <= 0) {
// Reset to parts/unit
root
.querySelectorAll(".bgus_part_label")
.forEach((el: HTMLElement) => (el.innerHTML = el.dataset.src));
.forEach((sel: HTMLElement) => {
sel.innerHTML = sel.dataset.src;
});
return;
}
setPartSize(
root.querySelectorAll("td > .bgus_part > .bgus_part_label"),
+size
);
return;
break;
}
default:
// Do nothing
}
}
});

4
lib/wiki.ts

@ -1,4 +1,4 @@
const WIKI_BASE = "https://cors-anywhere.herokuapp.com/tgstation13.org/wiki";
const WIKI_BASE = "https://tgproxy.ovo.ovh/wiki";
/**
* Get HTML content of a page using Mediawiki Parse APIs
@ -9,3 +9,5 @@ export async function getPageHTML(name: string): Promise<string> {
const apiURL = `/api.php?action=parse&page=${urlname}&prop=text&format=json`;
return (await (await fetch(WIKI_BASE + apiURL)).json()).parse.text["*"];
}
export default { getPageHTML };

9
package.json

@ -5,10 +5,19 @@
"license": "MIT",
"scripts": {
"dev": "parcel index.html",
"lint": "eslint lib",
"build": "parcel build index.html"
},
"dependencies": {
"@typescript-eslint/eslint-plugin": "^3.3.0",
"@typescript-eslint/parser": "^3.3.0",
"eslint": "7.2.0",
"eslint-config-airbnb-base": "^14.2.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-import": "2.21.2",
"eslint-plugin-prettier": "^3.1.4",
"parcel-bundler": "^1.12.4",
"prettier": "^2.0.5",
"sass": "^1.26.8",
"typescript": "^3.9.5"
},

875
yarn.lock

File diff suppressed because it is too large
Loading…
Cancel
Save