const itemEntries = nodeListToArray(document.querySelectorAll('.g-Recipe ul > li')) .map(function(itemNode) { return { tag: 'li', node: itemNode }; }) const h1 = document.querySelector('.g-Recipe h1') if (h1 !== null) { itemEntries.push( { tag: 'h1' , node: h1 } ) } const inputs = setInputs(itemEntries) inputs.map(function(input) { input.node.oninput = function(e) { if (e.target !==null) { const parsed: ParsedNumber | undefined = parseNumber((e.target as HTMLInputElement).value) if (parsed !== undefined && parsed.before === '' && parsed.after === '') { const factor = parsed.number / input.number inputs.map(function(input2) { input2.node.value = prettyPrintNumber(input2.number * factor) }) } } } }) interface InputEntry { tag: string; node: HTMLElement; } function setInputs(xs: Array) { const res = [] for (var i = 0; i < xs.length; i++) { const parsed = parseNumber(xs[i].node.innerText) if (parsed !== undefined) { const numberNode = parsedNumberNode(xs[i].tag, parsed) const parentNode = xs[i].node.parentNode if (parentNode) { parentNode.replaceChild(numberNode.all, xs[i].node) res.push({ number: parsed.number, node: numberNode.number }) } } } return res } function parsedNumberNode(tag: string, parsedNumber: ParsedNumber) { const node = document.createElement(tag) node.appendChild(document.createTextNode(parsedNumber.before)) const numberNode = document.createElement('input') numberNode.className = 'g-Number' numberNode.value = prettyPrintNumber(parsedNumber.number) node.appendChild(numberNode) node.appendChild(document.createTextNode(parsedNumber.after)) return { all: node, number: numberNode, } } interface ParsedNumber { before: string; number: number; after: string; } function parseNumber(str: string): ParsedNumber | undefined { for (var start = 0; start < str.length; start++) { if (isDigit(str.charAt(start))) { break } } if (start === str.length) { return undefined } // Integer part var integerPart = ''; for (var end = start; 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 var 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): Array { const xs: Array = []; nodeList.forEach(function(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] } }