formschema

command
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 28, 2026 License: BSD-3-Clause Imports: 8 Imported by: 0

Documentation

Overview

Command formschema reads every form on a page and prints what it would take to submit it.

$ formschema < page.html
{
  "forms": [
    {
      "action": "/search",
      "method": "get",
      "fields": [
        {"name": "q", "type": "search", "value": "", "required": true},
        {"name": "sort", "type": "select", "value": "date", "options": ["date", "score"]},
        {"name": "csrf", "type": "hidden", "value": "a1b2c3"}
      ]
    }
  ],
  "notes": ["1 field carries a form attribute and is not inside a form: it is reported
             separately, since which form owns it cannot be known in one pass"]
}

The point of the schema is replay: everything a client needs to send the same request the browser would, including the hidden fields and the pre-selected values, which is what makes this different from listing the inputs.

What the library decides

A textarea's value is its *text*, not an attribute, and a textarea is a raw-text element - so the value arrives as text chunks with no markup in them, and it has to be accumulated to IsLastInTextNode. A per-chunk read gets a prefix of the value and looks like it worked.

A select's value is its selected option, which is a nested element with a bare boolean attribute. Options arrive as elements inside the select, so the select's own field is not complete until its end tag - which is where it is recorded.

An input is void: it has no end tag, so nothing can be accumulated for it and everything it says is in its attributes. That is why an input's field is recorded at the start tag and a select's at the end tag, in the same program.

A duplicate attribute is a real thing on real pages, and the API is split about it: selectors and Attribute act on the first copy, while iterating yields every copy. A parser keeps the first, so this reads through Attribute - a form saying name="a" name="b" is submitted as "a".

What one pass cannot do

HTML lets a field sit outside its form and name it with a form attribute. Resolving that means knowing about a form that may not have arrived yet, which is the ordering constraint: a rewrite cannot look ahead. Those fields are collected separately and reported rather than guessed at.

Strict mode

Off, deliberately. A raw-text element inside a select - which is a thing minifiers produce - makes strict parsing refuse the document, and a schema reader that refuses a page is less useful than one that reads what it can. The report says when that shape was seen, because the content inside such an element is text to the parser and any fields in it are invisible.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL