Files
zulip/tools/lib/html_elements.py
2025-09-10 09:57:56 -07:00

192 lines
7.0 KiB
Python

from collections.abc import Iterator
VALID_HTML_CONTEXTS: dict[tuple[str, str], str] = {
# https://html.spec.whatwg.org/multipage/indices.html#elements-3
("a", "phrasing"): "transparent",
("abbr", "phrasing"): "phrasing",
("address", "flow"): "flow",
("area", "phrasing"): "void",
("article", "flow"): "flow",
("aside", "flow"): "flow",
("audio", "phrasing"): "<audio>",
("b", "phrasing"): "phrasing",
("base", "<head>"): "void",
("bdi", "phrasing"): "phrasing",
("bdo", "phrasing"): "phrasing",
("blockquote", "flow"): "flow",
("body", "<html>"): "flow",
("br", "phrasing"): "void",
("button", "phrasing"): "phrasing",
("button", "<select>"): "phrasing",
("canvas", "phrasing"): "transparent",
("caption", "<table>"): "flow",
("center", "flow"): "flow", # FIXME: obsolete, remove this
("cite", "phrasing"): "phrasing",
("code", "phrasing"): "phrasing",
("col", "<colgroup>"): "void",
("colgroup", "<table>"): "<colgroup>",
("data", "phrasing"): "phrasing",
("datalist", "phrasing"): "<datalist>",
("dd", "<dl>"): "flow",
("del", "phrasing"): "transparent",
("details", "flow"): "<details>",
("dfn", "phrasing"): "phrasing",
("dialog", "flow"): "flow",
("div", "flow"): "flow",
("div", "<dl>"): "<dl>",
("div", "<select> content"): "<select> content",
("div", "<optgroup> content"): "<optgroup> content",
("div", "<option> content"): "<option> content",
("dl", "flow"): "<dl>",
("dt", "<dl>"): "phrasing",
("em", "phrasing"): "phrasing",
("embed", "phrasing"): "void",
("fieldset", "flow"): "<fieldset>",
("figcaption", "<figure>"): "flow",
("figure", "flow"): "<figure>",
("footer", "flow"): "flow",
("form", "flow"): "flow",
("h1", "plain heading"): "phrasing",
("h2", "plain heading"): "phrasing",
("h3", "plain heading"): "phrasing",
("h4", "plain heading"): "phrasing",
("h5", "plain heading"): "phrasing",
("h6", "plain heading"): "phrasing",
("head", "<html>"): "<head>",
("header", "flow"): "flow",
("hgroup", "heading"): "<hgroup>",
("hr", "flow"): "void",
("hr", "<select> content"): "void",
("html", "document"): "<html>",
("i", "phrasing"): "phrasing",
("iframe", "phrasing"): "empty",
("img", "phrasing"): "void",
("img", "<picture>"): "void",
("input", "phrasing"): "void",
("ins", "phrasing"): "transparent",
("kbd", "phrasing"): "phrasing",
("label", "phrasing"): "phrasing",
("legend", "<fieldset>"): "phrasing/heading",
("li", "list"): "flow",
("link", "<head>"): "void",
("link", "phrasing"): "void",
("main", "flow"): "flow",
("map", "phrasing"): "<map>",
("mark", "phrasing"): "phrasing",
("math", "phrasing"): "MathML",
("menu", "flow"): "list",
("meta", "<head>"): "void",
("meta", "phrasing"): "void",
("meter", "phrasing"): "phrasing",
("nav", "flow"): "flow",
("noscript", "<head>"): "transparent",
("noscript", "phrasing"): "transparent",
("noscript", "<select> content"): "transparent",
("noscript", "<optgroup> content"): "transparent",
("object", "phrasing"): "transparent",
("ol", "flow"): "list",
("optgroup", "<select>"): "<optgroup> content",
("option", "<select>"): "<option> content",
("option", "<datalist>"): "<option> content",
("option", "<optgroup>"): "<option> content",
("output", "phrasing"): "phrasing",
("p", "flow"): "phrasing",
("p", "<hgroup>"): "phrasing",
("picture", "phrasing"): "<picture>",
("pre", "flow"): "phrasing",
("progress", "phrasing"): "phrasing",
("q", "phrasing"): "phrasing",
("rp", "<ruby>"): "phrasing",
("rt", "<ruby>"): "phrasing",
("ruby", "phrasing"): "<ruby>",
("s", "phrasing"): "phrasing",
("samp", "phrasing"): "phrasing",
("script", "<head>"): "<script>",
("script", "phrasing"): "<script>",
("script", "script-supporting"): "<script>",
("search", "flow"): "flow",
("section", "flow"): "flow",
("select", "phrasing"): "<select>",
("selectedcontent", "<button>"): "empty",
("slot", "phrasing"): "transparent",
("small", "phrasing"): "phrasing",
("source", "<picture>"): "void",
("source", "<video>"): "void",
("source", "<audio>"): "void",
("span", "phrasing"): "phrasing",
("strong", "phrasing"): "phrasing",
("style", "<head>"): "<style>",
("sub", "phrasing"): "phrasing",
("summary", "<details>"): "phrasing/heading",
("sup", "phrasing"): "phrasing",
("svg", "phrasing"): "SVG",
("table", "flow"): "<table>",
("tbody", "<table>"): "<tbody>",
("td", "<tr>"): "flow",
("template", "<head>"): "unknown",
("template", "phrasing"): "unknown",
("template", "script-supporting"): "unknown",
("template", "<colgroup>"): "unknown",
("textarea", "phrasing"): "text",
("tfoot", "<table>"): "<tfoot>",
("th", "<tr>"): "flow",
("thead", "<table>"): "<thead>",
("time", "phrasing"): "phrasing",
("title", "<head>"): "text",
("tr", "<table>"): "<tr>",
("tr", "<thead>"): "<tr>",
("tr", "<tbody>"): "<tr>",
("tr", "<tfoot>"): "<tr>",
("track", "<audio>"): "void",
("track", "<video>"): "void",
("u", "phrasing"): "phrasing",
("ul", "flow"): "list",
("var", "phrasing"): "phrasing",
("video", "phrasing"): "<video>",
("wbr", "phrasing"): "void",
# https://html.spec.whatwg.org/multipage/embedded-content-other.html#mathml
("annotation-xml", "MathML"): "flow",
("mi", "MathML"): "phrasing",
("mo", "MathML"): "phrasing",
("mn", "MathML"): "phrasing",
("ms", "MathML"): "phrasing",
("mtext", "MathML"): "phrasing",
# https://html.spec.whatwg.org/multipage/embedded-content-other.html#svg-0
("foreignObject", "SVG"): "flow",
("title", "SVG"): "phrasing",
}
HTML_CONTEXT_FALLBACKS: dict[str, list[str]] = {
"<datalist>": ["phrasing", "script-supporting"],
"<details>": ["flow"],
"<dl>": ["script-supporting"],
"<fieldset>": ["flow"],
"<figure>": ["flow"],
"<hgroup>": ["plain heading", "script-supporting"],
"<optgroup> content": ["script-supporting"],
"<option> content": ["phrasing"],
"<option>": ["<option> content"],
"<picture>": ["script-supporting"],
"<ruby>": ["phrasing"],
"<select> content": ["script-supporting"],
"<select>": ["<select> content"],
"<table>": ["script-supporting"],
"<tbody>": ["script-supporting"],
"<tfoot>": ["script-supporting"],
"<thead>": ["script-supporting"],
"<tr>": ["script-supporting"],
"flow": ["phrasing", "heading"],
"heading": ["plain heading"],
"list": ["script-supporting"],
"phrasing/heading": ["phrasing", "heading"],
"unknown": ["document", "flow", "list", "<head>", "<select>", "<table>", "<tr>"],
}
FOREIGN_CONTEXTS = ["MathML", "SVG"]
def html_context_fallbacks(context: str) -> Iterator[str]:
yield context
for fallback_context in HTML_CONTEXT_FALLBACKS.get(context, []):
yield from html_context_fallbacks(fallback_context)