tag-to-json

Native DOM element to declarative JSON specification extractor. The reverse companion to @keshavsoft/json-to-tag.

The Round-Trip Story

Full Cycle

Together, tag-to-json and json-to-tag create a complete lossless round-trip loop between native HTML browser elements and declarative JSON specifications:

1. Live DOM
Live Element

Any rendered HTML node, table, header, or card component

2. tag-to-json
Extract Spec

Traverses tag, attributes, classes, and nested children

3. JSON Tree
Declarative Spec

Portable, serializable JSON specification tree

4. json-to-tag
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.

W3C Standard Compliant

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
Chapter 1
Target Resolution & Type Guard

Accepts either an HTMLElement node or a string ID (auto-resolves via document.getElementById) and verifies nodeType === Node.ELEMENT_NODE.

Chapter 2
Clean Gatekeeping

Filters out non-visual tags (<script>, <style>, <noscript>) and browser extension noise (e.g. Google Input Tools markers).

Chapter 3
Attribute Serialization

Maps DOM attribute collections into clean JSON objects, properly capturing classes, inline styles, IDs, and SVG namespaces (xlink:href).

Chapter 4
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.

Chapter 5
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:

Old Parser (element.children)
// Text "Orders" was dropped!
{
  "tagName": "a",
  "children": [
    { "tagName": "svg" }
  ]
}
v5 W3C Engine (element.childNodes)
// 100% Lossless Round-Trip!
{
  "tagName": "a",
  "children": [
    { "tagName": "svg" },
    "Orders"
  ]
}

Interactive Live Showcase

Extract specs from live HTML elements using docs/dist/min.js

Live Source Element on Screen
Extracted Spec (tag-to-json output) JSON Spec Tree
// Click "Extract to JSON Spec" above
Re-Rendered via json-to-tag Round-Trip Rebuild
Reconstructed DOM node will appear here...

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));
Companion Library @keshavsoft/json-to-tag

tag-to-json extracts specs. json-to-tag renders them back to native DOM. Together they form a complete lossless round-trip loop — pass the JSON output of tagToJson() directly into buildSpecElement({ inSpec }).