HTML Cleaner 透過瀏覽器內建的 HTML 解析器來正規化 HTML 片段,並可選擇性地移除註解節點,結果只會顯示在一個唯讀的文字區域中,絕不會預覽或執行該標記內容。對於在 Notepad++ 中撰寫 HTML,卻不想安裝 Tidy2、XML Tools 或 JSMin 外掛就能將格式化的開發者來說,這個基於瀏覽器的路徑執行的是真實瀏覽器在渲染網頁時所使用的同一套解析規則。瀏覽器的 HTML 解析器刻意設計得很寬容:它會將元素名稱轉為小寫、為未加引號的屬性加上引號、插入像 <tbody> 這類隱含的元素、修復某些遺漏的結尾標記,並依據 HTML 樹結構建規則重新排列標記。這代表你所複製的輸出,就是真實瀏覽器在解析完你的 Notepad++ 檔案後於記憶體中所建構的內容,而不是嚴格的 XML 風格驗證結果。貼上你的程式碼、選擇是否要移除註解、執行正規化,然後在決定要貼到哪裡之前,先閱讀僅內容的文字以及註解移除數量。

how to format html code in notepad ++
how to format html code in notepad ++

為何 Notepad++ 使用者會尋求超越內建 HTML 格式化的方案

Notepad++ 是一款快速、輕量的原始碼編輯器,但它開箱即用的 HTML 格式化支援相當薄弱。外掛選單內建了 XML Tools、JSMin,以及過去曾有的 Tidy2,而每一個都帶有使用上的摩擦。Tidy2 是最接近真正 HTML 美化工具的替代品,然而它的安裝檔放在 GitHub releases 上,該處常常無法穩定存取,而且這個外掛在 64 位元版本的 Notepad++ 上安裝失敗的狀況也廣為人知。JSMin 會壓縮空白字元,但並不會做美化排版,因此手動格式化的頁面會被壓縮成單一長行。XML Tools 能格式化標記,但它將輸入解析為 XML,並會拒絕 HTML 刻意容忍的那些未閉合標記、缺漏引號及隱含元素。

對於已經為了查閱文件而開著瀏覽器分頁的開發者來說,這些怪癖加在一起,足以促使他們尋找一個在瀏覽器中執行、使用已部署頁面會用到的同一個解析器、且從不要求更新外掛的正規化步驟。HTML Cleaner 就是那個步驟:貼上你的 Notepad++ 檔案、勾選一個選項,然後在不離開瀏覽器的情況下閱讀結果。同樣的概念也適用於其他文字格式,而 JSON 的情況在 Format JSON Files in Notepad++: Plugins and Alternatives 中另有說明。

瀏覽器的 HTML 解析器如何修復標記

HTML Cleaner 中的正規化作業是由 DOMParser 在 text/html 模式下執行,這與瀏覽器在擷取並渲染網頁時所使用的解析器相同。該解析器刻意設計得寬容,因此幾乎不會擲回語法錯誤。相反地,它會套用 WHATWG HTML Living Standard 所定義的一組固定修復規則。事先了解這些規則,能讓格式化後的輸出可預期,而不令人意外。

輸入樣式正規化期間的解析器行為
大寫或大小寫混合的標籤名稱 (<DIV>、<Html>)轉為小寫的標準 HTML 名稱
未加引號的屬性值 (id=main)在序列化輸出中加上引號
屬性值未加引號或間距異常重新格式化為標準的屬性引號形式
<table> 內部缺少 <tbody>依樹結構建規則插入隱含的 <tbody>
在許多 flow content 位置缺少結尾標記嘗試修復;自動插入回復的結尾標記
被放在原始碼錯誤區段的 token重新排列為標準的文件樹結構

這些修復機制正是輸出結果很少能與原始內容逐位元組相符的原因。樹結構建步驟會在序列化之前,明確地將大小寫、屬性引號及零散 token 的位置進行正規化。MDN 的 DOMParser.parseFromString 參考文件 中說明,此解析器在指令碼停用的獨立文件中執行,這正是 HTML Cleaner 所依賴的惰性環境。

使用 HTML Cleaner 格式化 HTML 程式碼:一個 Notepad++ 工作流程

整個操作都發生在 HTML Cleaner 頁面內。將它視為從 Notepad++ 出發的一趟小行程,而不是用來取代的編輯器:你貼上、執行正規化、檢視已移除註解的數量,然後複製回 Notepad++ 或貼到另一個目的地。三個操作步驟對應到產品本身的合約:

  1. HTML 片段或文件 貼入輸入區,並決定是否要移除 註解節點。若想保留註解,請將選項關閉;若希望序列化前先移除所有 HTML 註解,則將選項開啟。
  2. 執行 正規化,然後在不執行輸出的情況下,檢視僅內容的文字結果以及註解移除數量。文字區域為唯讀,不會插入到可見的頁面中,因此該處的標記無法執行指令碼或渲染預覽。
  3. 只有在確認目的地是否同樣需要真正的 HTML 淨化器之後,才 複製完整的結果。若你計畫將輸出注入到 innerHTML、內容管理系統或電子郵件範本中,請先將它送進一個為該目的地設定且有持續維護的淨化器。

編輯輸入或切換註解選項會立即清除先前的結果、錯誤、統計資訊、複製狀態及複製計時器。剪貼簿的完成狀態受到一個世代編號與掛載狀態檢查的保護,因此即使較早的複製請求較晚才回傳權限結果,也無法在你編輯、重試或離開後還原出過期的狀態。若剪貼簿請求被拒絕,完整的正規化文字仍會保持可見,以供手動選取。

HTML Cleaner 保留、更動與捨棄的內容

輸出的範圍經過刻意界定。序列化讀取 document.body.innerHTML,這代表回傳的文字只包含已解析主體的子標記。Doctype、<html>、<head>、<title>、<meta>、<link> 與 <style> 都不在這個範圍內。僅位於 head 的中繼資料會被捨棄,除非解析器的回復規則在樹結構建過程中恰好將某個 token 移入主體。若你的 Notepad++ 檔案是帶有 doctype 與 head 區段的完整文件,該外殼刻意不會被複製,因此在必須保留整份頁面的情況下,請在能識別文件的編輯器中開啟結果。

建構項目處理方式
註解節點 (<!-- ... -->)選項開啟時移除;否則保留
<script>、<style>、<iframe>、<form>、<svg>、<math>原樣保留
事件處理屬性 (onclick、onerror 等)原樣保留
javascript: 與遠端 URL原樣保留
行內 CSS、data-* 屬性、ID、類別原樣保留
Doctype、<html>、<head>、<title>、<meta>、<link>超出範圍;不會複製到輸出中

這個區別在安全性上至關重要。若結果中仍含有 <script> 標記或 onerror 屬性,當另一個應用程式稍後將它注入到實際運作的頁面時,就會構成危險。這個工具絕不會重寫 URL 協定、強制執行內容政策,或套用白名單。正如 MDN 的 Element.innerHTML 參考文件 所警告的,片段序列化並不會做淨化,而將其複製到另一個執行環境中,可能會在那裡啟動相關行為。

限制、規模與安全界線

兩道嚴格的容量上限守護著整個流程。原始輸入最多只能包含 500,000 個 UTF-16 字碼單元;此限制會在解析前進行檢查,因此空輸入與超長輸入都會以明確的訊息被拒絕,而不是被靜默截斷。正規化後的輸出最多只能包含 1,000,000 個字碼單元,此上限是在結果回傳前,根據完整主體序列化進行測量。剛好等於邊界值會被接受;超過邊界一個的值則會失敗。不會進行切片、取樣、部分序列化,或靜默切換到不同的清理政策。解析後或移除註解後的空白主體,是合法的零長度輸出。

HTML Cleaner 是格式化的輔助工具,而非安全淨化器。瀏覽器解析器在指令碼停用的獨立文件中執行,序列化結果停留在唯讀的文字區域中,因此指令碼無法在工具內部執行。然而,在 DOMParser 建構其獨立文件的過程中,瀏覽器仍可能會下載已解析的 <iframe> 與 <img> 元素所參考的資源,因此若此類請求可能會向其他主機洩漏資訊,請避免貼上含有遠端資源 URL 的敏感 HTML。針對最終會被注入到實際運作頁面的不可信輸入,請在完成格式化後,使用一個為該目的地環境設定且有持續維護的淨化器。

縮排、換行、屬性排序,以及跨瀏覽器版本的逐位元組穩定性,也都明確不在範圍之內。DOMParser 與 innerHTML 會產生標準的瀏覽器序列化,但並不保證美化排版,而 <pre>、<textarea>、<script> 與 <style> 內部的文字遵循的是 HTML 解析規則,而不是自訂的詞法處理,這是為了保持原始文字內容完整所做的刻意選擇。當你想了解瀏覽器會如何正規化一個片段、從其他方面未變動的已解析結構中移除註解,或準備主體標記以供人工檢視時,請使用 HTML Cleaner;請勿將它用於驗證標準符合性、保全使用者輸入、保留完整文件、美化縮排、最小化原始碼,或證明複製出的輸出可以安全發布。

相關閱讀:How to Edit HTML in a Browser Using a Sandboxed Preview