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>
 | 
					</head>
 | 
				
			||||||
<body>
 | 
					<body>
 | 
				
			||||||
  <div id="error" hidden>Failed to parse PNG</div>
 | 
					  <div id="error" hidden>Failed to parse PNG</div>
 | 
				
			||||||
  <div id="explorer" hidden>
 | 
					  <div id="explorer" hidden></div>
 | 
				
			||||||
    <div id="bytesEl"></div>
 | 
					 | 
				
			||||||
    <div id="treeEl"></div>
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
  <script src="png.js" type="module"></script>
 | 
					  <script src="png.js" type="module"></script>
 | 
				
			||||||
</body>
 | 
					</body>
 | 
				
			||||||
</html>
 | 
					</html>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,8 +3,7 @@
 | 
				
			||||||
import { PngNodeType } from "./constants.js";
 | 
					import { PngNodeType } from "./constants.js";
 | 
				
			||||||
import { areBytesEqual, chunkBytes } from "../common/bytes.js";
 | 
					import { areBytesEqual, chunkBytes } from "../common/bytes.js";
 | 
				
			||||||
import crc32 from "./crc32.js";
 | 
					import crc32 from "./crc32.js";
 | 
				
			||||||
 | 
					/** @typedef {import("../../types/png.d.ts").PngNode} PngNode */
 | 
				
			||||||
/** @typedef {import("../../types/png.d.ts").Node<PngNodeType>} PngNode */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const PNG_SIGNATURE = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]);
 | 
					const PNG_SIGNATURE = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,13 +1,82 @@
 | 
				
			||||||
// @ts-check
 | 
					// @ts-check
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import crel from "../common/crel.js";
 | 
				
			||||||
import parsePng from "./parsePng.js";
 | 
					import parsePng from "./parsePng.js";
 | 
				
			||||||
 | 
					 | 
				
			||||||
import parseHash from "./parseHash.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 errorEl = document.getElementById("error");
 | 
				
			||||||
const explorerEl = document.getElementById("explorer");
 | 
					const explorerEl = document.getElementById("explorer");
 | 
				
			||||||
if (!errorEl || !explorerEl) throw new Error("HTML is not set up correctly");
 | 
					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 = () => {
 | 
					const main = () => {
 | 
				
			||||||
  // TODO: We may want a better UI here.
 | 
					  // TODO: We may want a better UI here.
 | 
				
			||||||
  // TODO: Handle hash changes.
 | 
					  // TODO: Handle hash changes.
 | 
				
			||||||
| 
						 | 
					@ -26,8 +95,11 @@ const main = () => {
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // TODO: Actually do something!
 | 
					  const explorer = new Explorer(rootNode);
 | 
				
			||||||
  console.log(rootNode);
 | 
					
 | 
				
			||||||
 | 
					  explorerEl.innerHTML = "";
 | 
				
			||||||
 | 
					  explorerEl.append(explorer.el);
 | 
				
			||||||
 | 
					  explorerEl.removeAttribute("hidden");
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
main();
 | 
					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.
 | 
					   * The type of this node. Typically an enum specific to the format.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
| 
						 | 
					@ -17,3 +19,5 @@ export type Node<T> = {
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  children?: ReadonlyArray<Node<T>>;
 | 
					  children?: ReadonlyArray<Node<T>>;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type PngNode = Node<PngNodeType>;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue