WHATWG HTML 規格同日三修:巡覽 API 狀態、樣板內表單指標與 frameset-ok 旗標
WHATWG HTML Living Standard (GitHub commits) · 2026-09-07
WHATWG 在 2026-09-07 對 HTML Living Standard 的 source 檔案送出三筆各自獨立的修正,分別調整 Navigation API 的狀態清空時機(fd344c0)、HTML parser 中表單指標在 <template> 內的忽略規則(9ed7f27)、以及 frameset-ok 旗標在 body 元素被隱式插入時的重置行為(83c0aa8)。三筆都是針對既有演算法步驟的行為修正,不是新增 API 或語法。以下逐一說明每筆改動實際變更了規格的哪個步驟。
跨文件導覽才清空 Navigation API 狀態
HTML 規格為每個 navigable 維護一組「進行中」狀態,包括 ongoing navigate event 與 ongoing API method tracker——分別對應目前正在派送的 NavigateEvent,以及呼叫 navigation.navigate()/reload() 等方法時回傳、稍後要 resolve 或 reject 的 promise 追蹤物件。commit fd344c0 把這兩個狀態的清空條件從「任何 traverse」收斂為「只有跨文件的 traverse」。修正前的演算法在處理 session history traversal 時,不論目的地條目屬於同一份文件(例如同頁的 hash 變化或 pushState 條目)或另一份文件,都會一律把 ongoing navigate event 與 method tracker 設為 null。
問題在於同文件的歷史遍歷理論上不該打斷目前正在進行的導覽,但清空這兩個追蹤狀態實質上等同於讓瀏覽器認為前一個導覽已經結束。修正後,只有在 target entry 所屬文件不是該 navigable 目前的 active document 時才清空,同文件的遍歷不再誤觸這段清空邏輯。commit 同時把規格內多處措辭從「Set the ongoing navigation」統一改為「Set navigable's ongoing navigation」,屬於用詞一致化。這筆修正對應 issue #12832。
樣板內容一律忽略表單指標
HTML parser 在建樹過程中維護一個「form element pointer」,指向最近一次遇到、且尚未被 <template> 包住的 <form> 元素,後續解析到的 <input>、<button> 等控制元件會靠它自動建立 form 屬主關聯。commit 9ed7f27 引入「parsing template contents」這個新定義,取代舊有的「堆疊上有沒有 template 元素」判斷,規格原文為:
An HTML parser is parsing template contents if
there is a template element on the stack of open
elements, or the parser's fragment context element
is a template element.差異在於 fragment 解析情境:舊條件只檢查開放元素堆疊裡有沒有 template,但若 parser 是以 template 的內容本身作為 fragment context 進行解析,堆疊上未必存在另一個 template 元素,舊條件會誤判為「不在 template 內」。新定義同時涵蓋堆疊上有 template、以及 fragment context 本身就是 template 這兩種情況。這個判斷改動了以下幾個演算法步驟:
<form>起始標籤處理:原本檢查「form 指標非 null 且堆疊上無 template」,改為「form 指標非 null 且不在 parsing template contents 狀態」- 表單元素插入邏輯:插入動作本身不變,但只有不在 parsing template contents 時才設定 form 指標
</form>結束標籤處理:把原本「有無 template」的兩條分支邏輯合併為單一的 parsing template contents 判斷- 控制元件與表單的關聯判斷:額外要求 fragment context element 為 null,並套用新定義
這筆修正對應 web-platform-tests/wpt#62488 與 issue #12257,兩者都聚焦於 fragment 解析情境下 template 邊界的判斷方式。
body 隱式插入時重置 frameset-ok 旗標
parser 用一個布林旗標 frameset-ok 追蹤目前輸入是否還有機會把整份文件變成 frameset 文件;一旦看到會構成一般網頁內容的 token(例如字元資料或特定起始標籤),就會把它設成 not ok,之後即使遇到 <frameset> 起始標籤也會被忽略。<template> 起始標籤在 in head insertion mode 會把 frameset-ok 設成 not ok,但規格先前沒有任何步驟會把它設回 ok,commit 83c0aa8 正是修正這個「污染」不會被清除的問題。
結果是像 <head><template></template></head><p><frameset> 這樣的輸入,規格字面上會永遠忽略後面的 frameset,但實際瀏覽器引擎的行為是照樣建立 frameset 文件,規格與實作出現落差。修正方式是在 after head insertion mode 的 anything else 分支——也就是隱式插入 <body> 元素的地方——多加一步「Set the frameset-ok flag to 'ok'」,讓 head 階段殘留的旗標狀態不會延續影響 body 之後的判斷。這筆修正對應 issue #3178 與 web-platform-tests/wpt#62485。
影響範圍
三筆修正都只變更 HTML Living Standard 的敘述文字與演算法步驟,屬於規格層級的行為修正,不影響現有 API 介面或新增語法。其中表單指標與 frameset-ok 兩筆都明確標註規格文字與瀏覽器引擎實際行為不一致,屬於補齊規格追上既有實作的修正;Navigation API 狀態清空這筆則是規格內部邏輯的一致性修正,目的是避免同文件歷史遍歷被誤判為導覽中斷。
| Commit | 修改重點 | 對應 Issue / PR |
|---|---|---|
fd344c0 | Navigation API 狀態只在跨文件 traverse 時清空 | #12832 |
9ed7f27 | 以「parsing template contents」取代堆疊檢查,忽略樣板內的 form 指標 | #12257 / wpt#62488 |
83c0aa8 | body 隱式插入時把 frameset-ok 重設為 ok | #3178 / wpt#62485 |
原始來源:whatwg/html commit fd344c0、whatwg/html commit 9ed7f27、whatwg/html commit 83c0aa8、wpt#62488、wpt#62485