The Round-Trip Story
Full CycleTogether, tag-to-json and json-to-tag create a complete lossless round-trip loop between native HTML browser elements and declarative JSON specifications:
Live Element
Any rendered HTML node, table, header, or card component
Extract Spec
Traverses tag, attributes, classes, and nested children
Declarative Spec
Portable, serializable JSON specification tree
Rebuild DOM
buildSpecElement({ inSpec }) reconstructs identical DOM
W3C DOM Extraction Architecture (v5)
Official W3C/WHATWG DOM Level 4 standard tree traversal and 5-chapter pipeline.
Rather than treating DOM serialization as flat, unstructured recursion, tag-to-json v5 models the process as a cohesive 5-chapter narrative grounded in browser engine standards (Blink, Gecko, WebKit):
flowchart TD
Start(["Live DOM Node / Element ID"]) --> Ch1["Chapter 1: Target Resolution & Type Guard
Resolve ID string & verify Node.ELEMENT_NODE"]
Ch1 --> Ch2["Chapter 2: Clean Gatekeeping
Filter <script>, <style>, extension artifacts"]
Ch2 --> Ch3["Chapter 3: Attribute Serialization
Extract class, href, id, data-*, SVG attributes"]
Ch3 --> Ch4{"Chapter 4: The Fork in the Road
Does element have child element tags?"}
Ch4 -- "No: Pure Leaf Tag" --> Leaf["Leaf Extraction
Extract clean textContent"]
Ch4 -- "Yes: Mixed Content / Container" --> Ch5["Chapter 5: The W3C Tree Walker
Iterate element.childNodes in exact document order"]
Ch5 --> N1["Node.ELEMENT_NODE (1)
Recursive domToSpec() call"]
Ch5 --> N2["Node.TEXT_NODE (3)
Trimmed text string in place"]
Ch5 --> N3["Node.COMMENT_NODE (8)
Gracefully skipped"]
N1 --> Mixed["Assemble 'children' Array
Preserves SVG icons + sibling text labels"]
N2 --> Mixed
Leaf --> Spec(["Declarative JSON Specification Tree"])
Mixed --> Spec
Spec ==> Rebuild(["json-to-tag: buildSpecElement()"])
Rebuild ==> DomOut(["Faithfully Reconstructed Live DOM Node"])
classDef chapter fill:#f0f7ff,stroke:#0d6efd,stroke-width:2px,color:#0b3c7b;
classDef success fill:#e8f9ee,stroke:#198754,stroke-width:2px,color:#0a522a;
classDef nodeTypes fill:#fff8e6,stroke:#ffc107,stroke-width:1px,color:#664d03;
class Ch1,Ch2,Ch3,Ch4,Ch5 chapter;
class Spec,Rebuild,DomOut success;
class N1,N2,N3 nodeTypes;
The 5 Pipeline Chapters
Target Resolution & Type Guard
Accepts either an HTMLElement node or a string ID (auto-resolves via document.getElementById) and verifies nodeType === Node.ELEMENT_NODE.
Clean Gatekeeping
Filters out non-visual tags (<script>, <style>, <noscript>) and browser extension noise (e.g. Google Input Tools markers).
Attribute Serialization
Maps DOM attribute collections into clean JSON objects, properly capturing classes, inline styles, IDs, and SVG namespaces (xlink:href).
The Fork in the Road (Leaf vs Container)
If an element contains zero child tags (e.g. <h1>Dashboard</h1>), it extracts clean textContent without spawning child arrays.
The W3C Tree Walker (Mixed Content)
Traverses element.childNodes in exact document sequence using native W3C nodeType checks. Sibling text nodes and icons are both preserved!
Why childNodes & W3C nodeType Solves Mixed Content
In modern UI frameworks like Bootstrap 5, navigation links mix SVG icon tags and text labels:
<a class="nav-link"><svg>...</svg> Orders</a>.
Standard element.children only recognizes element tags and drops "Orders" entirely!
By traversing element.childNodes with W3C constants, both are captured in exact order:
// Text "Orders" was dropped!
{
"tagName": "a",
"children": [
{ "tagName": "svg" }
]
}
// 100% Lossless Round-Trip!
{
"tagName": "a",
"children": [
{ "tagName": "svg" },
"Orders"
]
}
Interactive Live Showcase
Extract specs from live HTML elements using docs/dist/min.js
// Click "Extract to JSON Spec" above
Quick Integration
1. Install from npm
npm install @keshavsoft/tag-to-json
2. Import in JavaScript
import { tagToJson } from "@keshavsoft/tag-to-json";
// Pass an element or element ID:
const spec = tagToJson({
inElement: document.getElementById("myTable")
});
console.log(spec);
Browser DevTools Console / Extension
// Load via script tag or WebExtension:
<script type="module" src="./dist/min.js"></script>
// Run directly in DevTools Console:
const spec = window.ks.tagToJson.domToSpec({ inElement: $0 });
// Or extract by ID string:
const spec = window.ks.tagToJson.domToSpec("stockItemsTable");
// Copy straight to clipboard:
copy(JSON.stringify(spec, null, 2));