const ticksInSecond = 60; class FactorioItemElement extends HTMLElement { static observedAttributes = [ "name" ]; async connectedCallback() { const name = this.getAttribute("name"); const button = document.createElement("button"); const img = document.createElement("img"); img.setAttribute("src", await this.getImagePath(name)); img.setAttribute("alt", name); button.appendChild(img); button.setAttribute("title", name); this.appendChild(button); } async attributeChangedCallback(attribute, _oldValue, newValue) { await dataPromise; await new Promise(setTimeout); // skip one 'frame' to wait for the connectCallback to run if (attribute === "name") { if (this.children.length > 0) { const button = this.firstElementChild; const img = button.firstElementChild; img.setAttribute("src", await this.getImagePath(newValue)); button.setAttribute("title", newValue); img.setAttribute("alt", newValue); } } } async getImagePath(name) { await dataPromise; const recipe = data.recipe[name]; const item = data.item[name]; if (!item) { if (recipe) { return recipe.icon ?? null; } return null; } return item.icon; } static new(name) { const elem = document.createElement("f-item"); elem.setAttribute("name", name); return elem; } } class NoTextElement extends HTMLElement { constructor() { super(); this.observer = new MutationObserver(mutations => { mutations.forEach(m => { m.addedNodes.forEach(n => { if (n.nodeType === Node.TEXT_NODE) { this.removeChild(n); } }) }) }); this.observer.observe(this, { childList: true, subtree: false, }); } } window.customElements.define("f-item", FactorioItemElement); window.customElements.define("f-grid", class extends NoTextElement {}); window.customElements.define("f-row", class extends NoTextElement {}); let data = null; const dataPromise = Promise.all([ new Promise(res => { window.addEventListener("load", res); }), fetch("data.json").then(d => d.json()), ]).then(([_, resData]) => { data = resData; console.log(data.recipe); console.log(data.item); // console.log(data.furnace); // console.log(data["assembling-machine"]); // console.log(data.module); // console.log(data.planet); // console.log(data.resource); // console.log(data.generator); // console.log(data["burner-generator"]); // console.log(data.boiler); // console.log(data.quality); // console.log(data["rocket-silo"]); // console.log(data.plant); // console.log(data["mining-drill"]); // document.body console.log(data.recipe["rocket-silo"]); console.log(data.item["rocket-silo"]); const testRow = document.getElementById("test-row"); testRow.appendChild((i = document.createElement("f-item"), i.setAttribute("name", "uranium-processing"), i)); testRow.appendChild(FactorioItemElement.new("uranium-235")); testRow.appendChild(FactorioItemElement.new("uranium-238")); testRow.appendChild(FactorioItemElement.new("uranium-fuel-cell")); testRow.appendChild(FactorioItemElement.new("depleted-uranium-fuel-cell")); document.getElementById("test-item").setAttribute("name", "rocket-part"); });