Ship file viewer, editor improvements, and private package releases
This commit is contained in:
1 parent
645914955c
commit
a4a31032b9
158 files changed
+10523
-137
No files matched your search
@@ -0,0 +1,62 @@
|
||||
import { elementFactory, requireFile, setButtonLabel } from "./dom.ts";
|
||||
import { branch, leaf } from "./tree.ts";
|
||||
import type { ViewerMount } from "../types.ts";
|
||||
|
||||
function label(node: Element): string {
|
||||
const attributes = [...node.attributes]
|
||||
.map((attribute) => `${attribute.name}="${attribute.value}"`)
|
||||
.join(" ");
|
||||
return `<${node.tagName}${attributes ? ` ${attributes}` : ""}>`;
|
||||
}
|
||||
|
||||
function render(doc: Document, node: Element, depth: number): HTMLElement {
|
||||
const children = [...node.childNodes].filter(
|
||||
(child) => child.nodeType === 1 || (child.textContent ?? "").trim(),
|
||||
);
|
||||
const elements = children.filter((child) => child.nodeType === 1) as Element[];
|
||||
if (!elements.length)
|
||||
return leaf(doc, label(node), (node.textContent ?? "").trim(), "wrn-viewer-value");
|
||||
return branch(
|
||||
doc,
|
||||
label(node),
|
||||
"wrn-viewer-key",
|
||||
(into) => {
|
||||
for (const child of children)
|
||||
into.append(
|
||||
child.nodeType === 1
|
||||
? render(doc, child as Element, depth + 1)
|
||||
: leaf(doc, "", (child.textContent ?? "").trim(), "wrn-viewer-value"),
|
||||
);
|
||||
},
|
||||
depth < 2,
|
||||
);
|
||||
}
|
||||
|
||||
export const mountXml: ViewerMount = async ({ parent, file, button, signal }) => {
|
||||
const doc = parent.ownerDocument;
|
||||
const view = doc.defaultView;
|
||||
const element = elementFactory(doc);
|
||||
const text = await requireFile(file).text();
|
||||
if (signal.aborted) return;
|
||||
if (!view?.DOMParser) throw new Error("No XML parser available");
|
||||
const parsed = new view.DOMParser().parseFromString(text, "application/xml");
|
||||
const root = parsed.documentElement;
|
||||
// Malformed XML throws, and the ladder falls through to the source view.
|
||||
if (!root || parsed.getElementsByTagName("parsererror").length)
|
||||
throw new Error("Malformed XML document");
|
||||
|
||||
const tree = element("div");
|
||||
tree.className = "wrn-viewer-tree";
|
||||
tree.append(render(doc, root, 0));
|
||||
const raw = element("pre", text);
|
||||
|
||||
let showingRaw = false;
|
||||
const toggle = button("Raw", () => {
|
||||
showingRaw = !showingRaw;
|
||||
setButtonLabel(toggle, showingRaw ? "Tree" : "Raw");
|
||||
toggle.setAttribute("aria-pressed", String(showingRaw));
|
||||
parent.replaceChildren(showingRaw ? raw : tree);
|
||||
});
|
||||
toggle.setAttribute("aria-pressed", "false");
|
||||
parent.append(tree);
|
||||
};
|
||||
Reference in new issue
Block a user