PNG: very basic UI skeleton
Looks awful and is unusable, but the data seems to be there.
This commit is contained in:
		
							parent
							
								
									d917aaab6b
								
							
						
					
					
						commit
						92098e69b6
					
				| 
						 | 
				
			
			@ -12,10 +12,7 @@
 | 
			
		|||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
  <div id="error" hidden>Failed to parse PNG</div>
 | 
			
		||||
  <div id="explorer" hidden>
 | 
			
		||||
    <div id="bytesEl"></div>
 | 
			
		||||
    <div id="treeEl"></div>
 | 
			
		||||
  </div>
 | 
			
		||||
  <div id="explorer" hidden></div>
 | 
			
		||||
  <script src="png.js" type="module"></script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,8 +3,7 @@
 | 
			
		|||
import { PngNodeType } from "./constants.js";
 | 
			
		||||
import { areBytesEqual, chunkBytes } from "../common/bytes.js";
 | 
			
		||||
import crc32 from "./crc32.js";
 | 
			
		||||
 | 
			
		||||
/** @typedef {import("../../types/png.d.ts").Node<PngNodeType>} PngNode */
 | 
			
		||||
/** @typedef {import("../../types/png.d.ts").PngNode} PngNode */
 | 
			
		||||
 | 
			
		||||
const PNG_SIGNATURE = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +1,82 @@
 | 
			
		|||
// @ts-check
 | 
			
		||||
 | 
			
		||||
import crel from "../common/crel.js";
 | 
			
		||||
import parsePng from "./parsePng.js";
 | 
			
		||||
 | 
			
		||||
import parseHash from "./parseHash.js";
 | 
			
		||||
/** @typedef {import("./nodePath.js").NodePath} NodePath */
 | 
			
		||||
/** @typedef {import("../../types/png.d.ts").PngNode} PngNode */
 | 
			
		||||
 | 
			
		||||
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 });
 | 
			
		||||
 | 
			
		||||
      // TODO: Show a user-friendly title.
 | 
			
		||||
      const isRoot = path.length === 0;
 | 
			
		||||
      const title = node.type;
 | 
			
		||||
      const description = "TODO: Description";
 | 
			
		||||
      const nodeTreeEl = crel(
 | 
			
		||||
        "details",
 | 
			
		||||
        { "data-path": path, open: isRoot },
 | 
			
		||||
        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),
 | 
			
		||||
          );
 | 
			
		||||
          nodeBytesEl.append(childBytesEl);
 | 
			
		||||
          treeChildrenEl.append(childTreeEl);
 | 
			
		||||
        });
 | 
			
		||||
        nodeTreeEl.append(treeChildrenEl);
 | 
			
		||||
      } else {
 | 
			
		||||
        // TODO: Update this formatting
 | 
			
		||||
        nodeBytesEl.innerHTML = [...node.bytes].map((b) =>
 | 
			
		||||
          b.toString(16).padStart(2, "0")
 | 
			
		||||
        ).join("");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      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.
 | 
			
		||||
| 
						 | 
				
			
			@ -26,8 +95,11 @@ const main = () => {
 | 
			
		|||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // TODO: Actually do something!
 | 
			
		||||
  console.log(rootNode);
 | 
			
		||||
  const explorer = new Explorer(rootNode);
 | 
			
		||||
 | 
			
		||||
  explorerEl.innerHTML = "";
 | 
			
		||||
  explorerEl.append(explorer.el);
 | 
			
		||||
  explorerEl.removeAttribute("hidden");
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
main();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,6 @@
 | 
			
		|||
export type Node<T> = {
 | 
			
		||||
import { PngNodeType } from "../public/png/constants.js";
 | 
			
		||||
 | 
			
		||||
type Node<T> = {
 | 
			
		||||
  /**
 | 
			
		||||
   * The type of this node. Typically an enum specific to the format.
 | 
			
		||||
   */
 | 
			
		||||
| 
						 | 
				
			
			@ -17,3 +19,5 @@ export type Node<T> = {
 | 
			
		|||
   */
 | 
			
		||||
  children?: ReadonlyArray<Node<T>>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export type PngNode = Node<PngNodeType>;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue