// SPDX-License-Identifier: GPL-3.0-or-later //! Link rewriting for mirrored HTML and CSS. //! //! HTML is scanned with a small tokenizer following the HTML5 tokenizer's //! rules for what matters here: tag and attribute syntax (quoted, unquoted //! and valueless attributes), comments, doctype and other `` elements and `style` //! attributes. CSS files get the `url(...)` rewrite only, with the same //! matching as the Go version's regular expression //! `(?i)(url\(\s*["']?)([^"')\s]+)`. Character references in attribute //! values are decoded before a URL is parsed: numeric ones and the named //! `amp`, `lt`, `gt`, `quot`, `apos` and `nbsp`; other named references //! are left as written. /// Something the tokenizer found. #[derive(Debug, PartialEq, Eq)] pub enum Item { /// An attribute value on a start tag: lower-case tag and attribute /// names, the value's byte span, and whether it was quoted. Attr { tag: String, name: String, start: usize, end: usize, quoted: bool, }, /// The raw text inside a `"), "" ); assert_eq!( rw(r#"
caf\xe9
"; assert_eq!(rewrite_html(latin1, &mut |_| None, &mut |_| None), latin1); assert_eq!(unescape("a&b//<&unknown;'&apos"), "a&b//<&unknown;'&apos"); } #[test] fn unterminated_input() { for s in ["", "