From 6e047609ce13ff316498a2711a29cf64dd2188b1 Mon Sep 17 00:00:00 2001 From: Evan Hahn Date: Wed, 2 Aug 2023 13:48:36 -0500 Subject: [PATCH] PNG: move explorer to separate file (no expected impact) --- public/png/explorer.js | 83 ++++++++++++++++++++++++++++++++++++++++++ public/png/png.js | 72 +----------------------------------- 2 files changed, 85 insertions(+), 70 deletions(-) create mode 100644 public/png/explorer.js diff --git a/public/png/explorer.js b/public/png/explorer.js new file mode 100644 index 0000000..b1104b9 --- /dev/null +++ b/public/png/explorer.js @@ -0,0 +1,83 @@ +// @ts-check + +import crel from "../common/crel.js"; +import formatBytes from "../common/formatBytes.js"; +/** @typedef {import("./nodePath.js").NodePath} NodePath */ +/** @typedef {import("../../types/png.d.ts").PngNode} PngNode */ + +/** + * @typedef {Function} NodeUiFn + * @param {PngNode} node + * @returns {NodeUi} + */ + +class Explorer { + #bytesEl = crel("div", { class: "bytes" }); + #treeEl = crel("div", { class: "tree" }); + + /** + * @param {PngNode} rootNode + * @param {NodeUiFn} getNodeUi + */ + constructor(rootNode, getNodeUi) { + /** + * @param {PngNode} node + * @param {NodePath} path + * @returns [HTMLElement, HTMLElement] Each node's bytes and tree elements. + */ + const traverse = (node, path) => { + const nodeBytesEl = crel("span", { "data-path": path }); + + const isRoot = path.length === 0; + const { title, description } = getNodeUi(node); + const nodeTreeEl = crel( + "details", + { "data-path": path, ...(isRoot ? { open: "open" } : {}) }, + crel( + "summary", + {}, + crel("span", { "class": "title" }, title), + crel( + "span", + { "class": "bytecount" }, + "TODO: X bytes", + ), + ), + description, + ); + + if (node.children) { + const treeChildrenEl = crel("div", { class: "children" }); + node.children.forEach((child, index) => { + const [childBytesEl, childTreeEl] = traverse( + child, + path.concat(index), + ); + if (index > 0) nodeBytesEl.append(" "); + nodeBytesEl.append(childBytesEl); + treeChildrenEl.append(childTreeEl); + }); + nodeTreeEl.append(treeChildrenEl); + } else { + nodeBytesEl.innerHTML = formatBytes(node.bytes, 256); + } + + return [nodeBytesEl, nodeTreeEl]; + }; + + // TODO: better variable names + const [a, b] = traverse(rootNode, []); + this.#bytesEl.append(a); + this.#treeEl.append(b); + + this.el = document.createDocumentFragment(); + this.el.append(this.#bytesEl, this.#treeEl); + } +} + +/** + * @param {PngNode} rootNode + * @param {NodeUiFn} getNodeUi + * @returns {DocumentFragment} + */ +export default (rootNode, getNodeUi) => new Explorer(rootNode, getNodeUi).el; diff --git a/public/png/png.js b/public/png/png.js index 0397e8e..fc6b62f 100644 --- a/public/png/png.js +++ b/public/png/png.js @@ -1,80 +1,14 @@ // @ts-check -import crel from "../common/crel.js"; -import formatBytes from "../common/formatBytes.js"; import parsePng from "./parsePng.js"; import parseHash from "./parseHash.js"; import getNodeUi from "./getNodeUi.js"; -/** @typedef {import("./nodePath.js").NodePath} NodePath */ -/** @typedef {import("../../types/png.d.ts").PngNode} PngNode */ +import explorer from "./explorer.js"; const errorEl = document.getElementById("error"); const explorerEl = document.getElementById("explorer"); if (!errorEl || !explorerEl) throw new Error("HTML is not set up correctly"); -class Explorer { - #bytesEl = crel("div", { class: "bytes" }); - #treeEl = crel("div", { class: "tree" }); - - /** - * @param {PngNode} rootNode - */ - constructor(rootNode) { - /** - * @param {PngNode} node - * @param {NodePath} path - * @returns [HTMLElement, HTMLElement] Each node's bytes and tree elements. - */ - const traverse = (node, path) => { - const nodeBytesEl = crel("span", { "data-path": path }); - - const isRoot = path.length === 0; - const { title, description } = getNodeUi(node); - const nodeTreeEl = crel( - "details", - { "data-path": path, ...(isRoot ? { open: "open" } : {}) }, - crel( - "summary", - {}, - crel("span", { "class": "title" }, title), - crel( - "span", - { "class": "bytecount" }, - "TODO: X bytes", - ), - ), - description, - ); - - if (node.children) { - const treeChildrenEl = crel("div", { class: "children" }); - node.children.forEach((child, index) => { - const [childBytesEl, childTreeEl] = traverse( - child, - path.concat(index), - ); - if (index > 0) nodeBytesEl.append(" "); - nodeBytesEl.append(childBytesEl); - treeChildrenEl.append(childTreeEl); - }); - nodeTreeEl.append(treeChildrenEl); - } else { - nodeBytesEl.innerHTML = formatBytes(node.bytes, 256); - } - - return [nodeBytesEl, nodeTreeEl]; - }; - - // TODO: better variable names - const [a, b] = traverse(rootNode, []); - this.#bytesEl.append(a); - this.#treeEl.append(b); - - this.el = document.createDocumentFragment(); - this.el.append(this.#bytesEl, this.#treeEl); - } -} - const main = () => { // TODO: We may want a better UI here. // TODO: Handle hash changes. @@ -93,10 +27,8 @@ const main = () => { return; } - const explorer = new Explorer(rootNode); - explorerEl.innerHTML = ""; - explorerEl.append(explorer.el); + explorerEl.append(explorer(rootNode, getNodeUi)); explorerEl.removeAttribute("hidden"); };