From cbcc269be607cc964fbd69d179d8a0e8b8e4bffa Mon Sep 17 00:00:00 2001 From: Joris Date: Mon, 3 Feb 2020 18:28:50 +0100 Subject: Extract dom and number utilities to external files --- main.ts | 217 ---------------------------------------------------------------- 1 file changed, 217 deletions(-) delete mode 100644 main.ts (limited to 'main.ts') diff --git a/main.ts b/main.ts deleted file mode 100644 index c120377..0000000 --- a/main.ts +++ /dev/null @@ -1,217 +0,0 @@ -/* Set up done marks for steps */ - -nodeListToArray(document.querySelectorAll('.g-Recipe__Content ol > li')).forEach(todo => { - todo.onclick = e => { - toggleClassName(todo, 'g-Recipe__Completed') - e.stopPropagation() - } -}) - -function toggleClassName(node: Element, className: string) { - if (node.className === className) { - node.className = '' - } else { - node.className = className - } -} - -/* Set up inputs for the ingredients */ - -const itemEntries = - nodeListToArray(document.querySelectorAll('.g-Recipe__Content ul > li')) - .map(itemNode => ({ tag: 'li', node: itemNode })) - -const h1 = document.querySelector('.g-Recipe__Content h1') - -if (h1 !== null) { - itemEntries.push( - { tag: 'h1' - , node: h1 - } - ) -} - -const inputs = setInputs(itemEntries) - -inputs.map(input => { - input.node.oninput = e => { - if (e.target !==null) { - const parsed = parseNumber((e.target as HTMLInputElement).value) - - if (parsed !== undefined && parsed.before === '' && parsed.after === '') { - const factor = parsed.number / input.number - inputs.map(input2 => { - if (input.node !== input2.node) { - input2.node.value = prettyPrintNumber(input2.number * factor) - } - }) - } - } - } -}) - -interface InputEntry { - tag: string; - node: HTMLElement; -} - -interface InputResult { - number: number, - node: HTMLInputElement -} - -function setInputs(xs: InputEntry[]): InputResult[] { - const res: InputResult[] = [] - - xs.forEach(x => { - const parsed = parseNumber(x.node.innerText) - - if (parsed !== undefined) { - const numberElement = createNumberElement(x.tag, parsed) - const parentNode = x.node.parentNode - - if (parentNode) { - parentNode.replaceChild(numberElement.node, x.node) - res.push({ - number: parsed.number, - node: numberElement.number - }) - } - } - }) - - return res -} - -interface NumberElement { - node: Element; - number: HTMLInputElement; -} - -function createNumberElement(tag: string, parsedNumber: ParsedNumber): NumberElement { - const numberElement = h( - 'input', - { - 'class': 'g-Number', - 'value': prettyPrintNumber(parsedNumber.number) - } - ) as HTMLInputElement - - return { - node: h(tag, {}, [parsedNumber.before, numberElement, parsedNumber.after]), - number: numberElement, - } -} - -interface ParsedNumber { - before: string; - number: number; - after: string; -} - -function parseNumber(str: string): ParsedNumber | undefined { - let start; - for (start = 0; start < str.length; start++) { - if (isDigit(str.charAt(start))) { - break - } - } - - if (start === str.length) { - return undefined - } - - // Integer part - let integerPart = ''; - let end = start; - for (; end < str.length; end++) { - const c = str.charAt(end) - - if (!isDigit(c)) { - break - } else { - integerPart += c - } - } - - // Decimal sign - if (end < str.length && (str.charAt(end) === '.' || str.charAt(end) === ',')) { - end++ - } - - // Decimal part - let decimalPart = ''; - for (; end < str.length; end++) { - const c = str.charAt(end) - - if (!isDigit(c)) { - break - } else { - decimalPart += c - } - } - - - return { - before: str.substring(0, start), - number: parseFloat(integerPart + (decimalPart !== '' ? '.' + decimalPart : '')), - after: str.substring(end, str.length) - } -} - -function isDigit(c: string) { - return c >= '0' && c <= '9' -} - -function nodeListToArray(nodeList: NodeListOf): HTMLElement[] { - const xs: HTMLElement[] = []; - nodeList.forEach(node => xs.push(node)) - return xs -} - -function prettyPrintNumber(n: number): string { - const xs = n.toString().split('.') - - if (xs.length == 2) { - return xs[0] + ',' + xs[1].substring(0, 2) - } else { - return xs[0] - } -} - -/* Element creation helper */ - -type Attribute = string | boolean | ((e: Event) => void) - -type Child = Element | string - -function h(tag: string, attrs: {[key: string]: Attribute}, children: Array = []): Element { - let element = document.createElement(tag) - - for (let name in attrs) { - let value = attrs[name] - if (typeof value === 'boolean') { - if (value) { - element.setAttribute(name, name) - } - } else if (typeof value === 'function') { - (element as any)[name] = (e: Event) => { - if (e.target !== null) { - console.log((e.target as HTMLInputElement).value) - } - } - } else { - element.setAttribute(name, value) - } - } - - children.forEach(child => { - if (typeof child === 'string') { - element.appendChild(document.createTextNode(child)) - } else { - element.appendChild(child) - } - }) - - return element -} -- cgit v1.2.3