fix(html/parser): Fix bugs (#4265)

This commit is contained in:
Alexander Akait 2022-04-07 08:12:54 +03:00 committed by GitHub
parent ddbf5a3d43
commit 105a0cccf7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
60 changed files with 64565 additions and 49 deletions

1
Cargo.lock generated
View File

@ -3770,6 +3770,7 @@ version = "0.2.1"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"lexical", "lexical",
"once_cell",
"serde", "serde",
"serde_json", "serde_json",
"swc_atoms", "swc_atoms",

View File

@ -35,6 +35,7 @@ pub enum Token {
Comment { Comment {
data: JsWord, data: JsWord,
}, },
// TODO add `raw` to get real character from code
Character { Character {
value: char, value: char,
}, },

View File

@ -116,7 +116,7 @@ where
start_tag.push('>'); start_tag.push('>');
write_raw!(self, span, &start_tag); write_str!(self, span, &start_tag);
} }
Token::EndTag { Token::EndTag {
tag_name, tag_name,
@ -145,7 +145,7 @@ where
start_tag.push('>'); start_tag.push('>');
write_raw!(self, span, &start_tag); write_str!(self, span, &start_tag);
} }
Token::Comment { data } => { Token::Comment { data } => {
let mut comment = String::new(); let mut comment = String::new();

View File

@ -8,5 +8,55 @@
<label><input type= checkbox checked name = cheese disabled> Cheese</label> <label><input type= checkbox checked name = cheese disabled> Cheese</label>
<label><input type =checkbox checked name = cheese disabled> Cheese</label> <label><input type =checkbox checked name = cheese disabled> Cheese</label>
<label><input type = checkbox checked name = cheese disabled> Cheese</label> <label><input type = checkbox checked name = cheese disabled> Cheese</label>
<label ><input type='checkbox'checked name=cheese disabled="" > Cheese</label >
<p id="" class="" STYLE=" " title="
" lang="" dir="">x</p>
<p id='' class="" STYLE=' ' title='
' lang='' dir=''>x</p>
<p onclick="" ondblclick=" " onmousedown="" ONMOUSEUP="" onmouseover=" " onmousemove="" onmouseout="" onkeypress=
"
"
onkeydown=
"" onkeyup="">x</p>
<input onfocus="" onblur="" onchange=" " value=" boo ">
<input value="" name="foo">
<img src="" alt="">
<div data-foo class id style title lang dir onfocus onblur onchange onclick ondblclick onmousedown onmouseup onmouseover onmousemove onmouseout onkeypress onkeydown onkeyup></div>
<img src="" alt="">
<p class=" foo bar ">foo bar baz</p>
<p class=" foo ">foo bar baz</p>
<p class="
foo
">foo bar baz</p>
<p style=" color: red; background-color: rgb(100, 75, 200); "></p>
<p style="font-weight: bold ; "></p>
<br>x</br>
<p title="</p>">x</p>
<p title=" <!-- hello world --> ">x</p>
<p title=" <![CDATA[ \n\n foobar baz ]]> ">x</p>
<p foo-bar="baz">xxx</p>
<p foo:bar="baz">xxx</p>
<p foo.bar="baz">xxx</p>
<div><div><div><div><div><div><div><div><div><div>i'm 10 levels deep</div></div></div></div></div></div></div></div></div></div>
<a title="x"href=" ">foo</a>
<p id=""class=""title="">x</p>
<p x="x'">x</p>
<p x='x"'>x</p>
<a href="#"><p>Click me</p></a>
<span><button>Hit me</button></span>
<object type="image/svg+xml" data="image.svg"><div>[fallback image]</div></object>
</body> </body>
</html> </html>

View File

@ -4,9 +4,55 @@
<label><input type="checkbox" checked name="cheese" disabled> Cheese</label> <label><input type="checkbox" checked name="cheese" disabled> Cheese</label>
<label><input type="checkbox" checked="checked" name="cheese" disabled="disabled"> Cheese</label> <label><input type="checkbox" checked="checked" name="cheese" disabled="disabled"> Cheese</label>
<label><input type="checkbox" checked name="cheese" disabled=""> Cheese</label>
<label><input type="checkbox" checked name="cheese" disabled> Cheese</label> <label><input type="checkbox" checked name="cheese" disabled> Cheese</label>
<label><input type="checkbox" checked name="cheese" disabled> Cheese</label> <label><input type="checkbox" checked name="cheese" disabled> Cheese</label>
<label><input type="checkbox" checked name="cheese" disabled> Cheese</label> <label><input type="checkbox" checked name="cheese" disabled> Cheese</label>
<label><input type="checkbox" checked name="cheese" disabled> Cheese</label> <label><input type="checkbox" checked name="cheese" disabled=""> Cheese</label>
<p id="" class="" style=" " title="
" lang="" dir="">x</p>
<p id="" class="" style=" " title="
" lang="" dir="">x</p>
<p onclick="" ondblclick=" " onmousedown="" onmouseup="" onmouseover=" " onmousemove="" onmouseout="" onkeypress="
" onkeydown="" onkeyup="">x</p>
<input onfocus="" onblur="" onchange=" " value=" boo ">
<input value="" name="foo">
<img src="" alt="">
<div data-foo class id style title lang dir onfocus onblur onchange onclick ondblclick onmousedown onmouseup onmouseover onmousemove onmouseout onkeypress onkeydown onkeyup></div>
<img src="" alt="">
<p class=" foo bar ">foo bar baz</p>
<p class=" foo ">foo bar baz</p>
<p class="
foo
">foo bar baz</p>
<p style=" color: red; background-color: rgb(100, 75, 200); "></p>
<p style="font-weight: bold ; "></p>
<br>x</br>
<p title="</p>">x</p>
<p title=" <!-- hello world --> ">x</p>
<p title=" <![CDATA[ \n\n foobar baz ]]> ">x</p>
<p foo-bar="baz">xxx</p>
<p foo:bar="baz">xxx</p>
<p foo.bar="baz">xxx</p>
<div><div><div><div><div><div><div><div><div><div>i'm 10 levels deep</div></div></div></div></div></div></div></div></div></div>
<a title="x" href=" ">foo</a>
<p id="" class="" title="">x</p>
<p x="x'">x</p>
<p x='x"'>x</p>
<a href="#"><p>Click me</p></a>
<span><button>Hit me</button></span>
<object type="image/svg+xml" data="image.svg"><div>[fallback image]</div></object>
</body> </body>
</html> </html>

View File

@ -4,9 +4,55 @@
<label><input type="checkbox" checked name="cheese" disabled> Cheese</label> <label><input type="checkbox" checked name="cheese" disabled> Cheese</label>
<label><input type="checkbox" checked="checked" name="cheese" disabled="disabled"> Cheese</label> <label><input type="checkbox" checked="checked" name="cheese" disabled="disabled"> Cheese</label>
<label><input type="checkbox" checked name="cheese" disabled=""> Cheese</label>
<label><input type="checkbox" checked name="cheese" disabled> Cheese</label> <label><input type="checkbox" checked name="cheese" disabled> Cheese</label>
<label><input type="checkbox" checked name="cheese" disabled> Cheese</label> <label><input type="checkbox" checked name="cheese" disabled> Cheese</label>
<label><input type="checkbox" checked name="cheese" disabled> Cheese</label> <label><input type="checkbox" checked name="cheese" disabled> Cheese</label>
<label><input type="checkbox" checked name="cheese" disabled> Cheese</label> <label><input type="checkbox" checked name="cheese" disabled=""> Cheese</label>
<p id="" class="" style=" " title="
" lang="" dir="">x</p>
<p id="" class="" style=" " title="
" lang="" dir="">x</p>
<p onclick="" ondblclick=" " onmousedown="" onmouseup="" onmouseover=" " onmousemove="" onmouseout="" onkeypress="
" onkeydown="" onkeyup="">x</p>
<input onfocus="" onblur="" onchange=" " value=" boo ">
<input value="" name="foo">
<img src="" alt="">
<div data-foo class id style title lang dir onfocus onblur onchange onclick ondblclick onmousedown onmouseup onmouseover onmousemove onmouseout onkeypress onkeydown onkeyup></div>
<img src="" alt="">
<p class=" foo bar ">foo bar baz</p>
<p class=" foo ">foo bar baz</p>
<p class="
foo
">foo bar baz</p>
<p style=" color: red; background-color: rgb(100, 75, 200); "></p>
<p style="font-weight: bold ; "></p>
<br>x</br>
<p title="</p>">x</p>
<p title=" <!-- hello world --> ">x</p>
<p title=" <![CDATA[ \n\n foobar baz ]]> ">x</p>
<p foo-bar="baz">xxx</p>
<p foo:bar="baz">xxx</p>
<p foo.bar="baz">xxx</p>
<div><div><div><div><div><div><div><div><div><div>i'm 10 levels deep</div></div></div></div></div></div></div></div></div></div>
<a title="x" href=" ">foo</a>
<p id="" class="" title="">x</p>
<p x="x'">x</p>
<p x='x"'>x</p>
<a href="#"><p>Click me</p></a>
<span><button>Hit me</button></span>
<object type="image/svg+xml" data="image.svg"><div>[fallback image]</div></object>
</body> </body>
</html> </html>

View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<body>
<h1>HTML Entity Example</h1>
<div>A space character: &AMP;</div>
<div>A space character: &amp;</div>
<div>A space character: &nbsp;</div>
<div>The less-than sign: &lt;</div>
<div>The greater-than sign: &gt;</div>
<div>The double quote sign: &quot;</div>
<div>The single quote sign: &apos;</div>
<div>The cent sign: &cent;</div>
<div>The pound sign: &pound;</div>
<div>The yen sign: &yen;</div>
<div>The euro sign: &euro;</div>
<div>The copyright sign: &copy;</div>
<div>The registered trade mark sign: &reg;</div>
<div>An a with a grave accent: a&#768;</div>
<div>An a with an acute accent: a&#769;</div>
<div>An a with a circumflex accent: a&#770;</div>
<div>An a with a tilde: a&#771;</div>
<div>An o with a grave accent: o&#768;</div>
<div>An o with an acute accent: o&#769;</div>
<div>An o with a circumflex accent: o&#770;</div>
<div>An o with a tilde: o&#771;</div>
<div>A space character: &&</div>
<div>I'm &notin; I tell you</div>
<a href="http://lmgtfy.com/?l=1&amp;q=rick+roll">tired meme</a>
<a href="#" onclick="window.location='?l=1&amp;q=rick+roll';return false">
kablammo!
</a>
</body>
</html>

View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<body>
<h1>HTML Entity Example</h1>
<div>A space character: &</div>
<div>A space character: &</div>
<div>A space character:  </div>
<div>The less-than sign: <</div>
<div>The greater-than sign: ></div>
<div>The double quote sign: "</div>
<div>The single quote sign: '</div>
<div>The cent sign: ¢</div>
<div>The pound sign: £</div>
<div>The yen sign: ¥</div>
<div>The euro sign: €</div>
<div>The copyright sign: ©</div>
<div>The registered trade mark sign: ®</div>
<div>An a with a grave accent: à</div>
<div>An a with an acute accent: á</div>
<div>An a with a circumflex accent: â</div>
<div>An a with a tilde: ã</div>
<div>An o with a grave accent: ò</div>
<div>An o with an acute accent: ó</div>
<div>An o with a circumflex accent: ô</div>
<div>An o with a tilde: õ</div>
<div>A space character: &&</div>
<div>I'm ∉ I tell you</div>
<a href="http://lmgtfy.com/?l=1&q=rick+roll">tired meme</a>
<a href="#" onclick="window.location='?l=1&q=rick+roll';return false">
kablammo!
</a>
</body>
</html>

View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<body>
<h1>HTML Entity Example</h1>
<div>A space character: &</div>
<div>A space character: &</div>
<div>A space character:  </div>
<div>The less-than sign: <</div>
<div>The greater-than sign: ></div>
<div>The double quote sign: "</div>
<div>The single quote sign: '</div>
<div>The cent sign: ¢</div>
<div>The pound sign: £</div>
<div>The yen sign: ¥</div>
<div>The euro sign: €</div>
<div>The copyright sign: ©</div>
<div>The registered trade mark sign: ®</div>
<div>An a with a grave accent: à</div>
<div>An a with an acute accent: á</div>
<div>An a with a circumflex accent: â</div>
<div>An a with a tilde: ã</div>
<div>An o with a grave accent: ò</div>
<div>An o with an acute accent: ó</div>
<div>An o with a circumflex accent: ô</div>
<div>An o with a tilde: õ</div>
<div>A space character: &&</div>
<div>I'm ∉ I tell you</div>
<a href="http://lmgtfy.com/?l=1&q=rick+roll">tired meme</a>
<a href="#" onclick="window.location='?l=1&q=rick+roll';return false">
kablammo!
</a>
</body>
</html>

View File

@ -0,0 +1,3 @@
<ng-include src="x"></ng-include>
<ng:include src="x"></ng:include>
<ng-include src="'views/partial-notification.html'"></ng-include><div ng-view=""></div>

View File

@ -0,0 +1,3 @@
<ng-include src="x"></ng-include>
<ng:include src="x"></ng:include>
<ng-include src="'views/partial-notification.html'"></ng-include><div ng-view=""></div>

View File

@ -0,0 +1,3 @@
<ng-include src="x"></ng-include>
<ng:include src="x"></ng:include>
<ng-include src="'views/partial-notification.html'"></ng-include><div ng-view=""></div>

View File

@ -21,6 +21,9 @@ debug = []
[dependencies] [dependencies]
bitflags = "1.2.1" bitflags = "1.2.1"
lexical = "6.1.0" lexical = "6.1.0"
once_cell = "1.10.0"
serde = { version = "1.0.118", features = ["derive"] }
serde_json = "1.0.61"
swc_atoms = { version = "0.2.7", path = "../swc_atoms" } swc_atoms = { version = "0.2.7", path = "../swc_atoms" }
swc_common = { version = "0.17.19", path = "../swc_common" } swc_common = { version = "0.17.19", path = "../swc_common" }
swc_html_ast = { version = "0.2.0", path = "../swc_html_ast" } swc_html_ast = { version = "0.2.0", path = "../swc_html_ast" }

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,8 @@
// TODO avoid using in future for better AST
use std::char::REPLACEMENT_CHARACTER; use std::char::REPLACEMENT_CHARACTER;
use swc_common::{input::Input, BytePos, Span}; use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use swc_common::{collections::AHashMap, input::Input, BytePos, Span};
use swc_html_ast::{Attribute, Token, TokenAndSpan}; use swc_html_ast::{Attribute, Token, TokenAndSpan};
use crate::{ use crate::{
@ -57,7 +58,20 @@ where
} }
} }
#[derive(Clone)] #[derive(Serialize, Deserialize, Debug)]
pub struct Entity {
codepoints: Vec<u32>,
characters: String,
}
pub static HTML_ENTITIES: Lazy<AHashMap<String, Entity>> = Lazy::new(|| {
let entities: AHashMap<String, Entity> = serde_json::from_str(include_str!("./entities.json"))
.expect("failed to parse entities.json for html entities");
entities
});
#[derive(Debug, Clone)]
#[allow(unused)] #[allow(unused)]
enum State { enum State {
Data, Data,
@ -278,6 +292,33 @@ where
false false
} }
fn flush_code_point_consumed_as_character_reference(&mut self, c: char) {
if self.is_consumed_as_part_of_an_attribute() {
if let Some(ref mut token) = self.cur_token {
match token {
Token::StartTag { attributes, .. } | Token::EndTag { attributes, .. } => {
if let Some(attribute) = attributes.last_mut() {
let mut new_value = String::new();
match &attribute.value {
Some(value) => {
new_value.push_str(value);
new_value.push(c);
}
None => {}
}
attribute.value = Some(new_value.into());
}
}
_ => {}
}
}
} else {
self.emit_token(Token::Character { value: c });
}
}
fn read_token_and_span(&mut self) -> LexResult<TokenAndSpan> { fn read_token_and_span(&mut self) -> LexResult<TokenAndSpan> {
loop { loop {
if !self.pending_tokens.is_empty() { if !self.pending_tokens.is_empty() {
@ -291,8 +332,18 @@ where
return Ok(token_and_span); return Ok(token_and_span);
} }
} }
} } else {
if self.input.cur().is_none() {
return Err(ErrorKind::Eof);
}
self.run()?;
}
}
}
fn run(&mut self) -> LexResult<()> {
loop {
match self.state { match self.state {
// https://html.spec.whatwg.org/multipage/parsing.html#data-state // https://html.spec.whatwg.org/multipage/parsing.html#data-state
State::Data => { State::Data => {
@ -321,6 +372,8 @@ where
// Emit an end-of-file token. // Emit an end-of-file token.
None => { None => {
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Emit the current input character as a character token. // Emit the current input character as a character token.
@ -358,6 +411,8 @@ where
// Emit an end-of-file token. // Emit an end-of-file token.
None => { None => {
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Emit the current input character as a character token. // Emit the current input character as a character token.
@ -386,6 +441,8 @@ where
// Emit an end-of-file token. // Emit an end-of-file token.
None => { None => {
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Emit the current input character as a character token. // Emit the current input character as a character token.
@ -414,6 +471,8 @@ where
// Emit an end-of-file token. // Emit an end-of-file token.
None => { None => {
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Emit the current input character as a character token. // Emit the current input character as a character token.
@ -439,6 +498,8 @@ where
// Emit an end-of-file token. // Emit an end-of-file token.
None => { None => {
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Emit the current input character as a character token. // Emit the current input character as a character token.
@ -492,6 +553,8 @@ where
self.emit_error(ErrorKind::EofBeforeTagName); self.emit_error(ErrorKind::EofBeforeTagName);
self.emit_token(Token::Character { value: '<' }); self.emit_token(Token::Character { value: '<' });
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// This is an invalid-first-character-of-tag-name parse error. Emit a U+003C // This is an invalid-first-character-of-tag-name parse error. Emit a U+003C
@ -536,6 +599,8 @@ where
self.emit_token(Token::Character { value: '<' }); self.emit_token(Token::Character { value: '<' });
self.emit_token(Token::Character { value: '/' }); self.emit_token(Token::Character { value: '/' });
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// This is an invalid-first-character-of-tag-name parse error. Create a // This is an invalid-first-character-of-tag-name parse error. Create a
@ -629,6 +694,8 @@ where
None => { None => {
self.emit_error(ErrorKind::EofInTag); self.emit_error(ErrorKind::EofInTag);
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Append the current input character to the current tag token's tag name. // Append the current input character to the current tag token's tag name.
@ -849,6 +916,7 @@ where
}); });
self.state = State::RawtextEndTagName; self.state = State::RawtextEndTagName;
self.reconsume();
} }
// Anything else // Anything else
// Emit a U+003C LESS-THAN SIGN character token and a U+002F SOLIDUS // Emit a U+003C LESS-THAN SIGN character token and a U+002F SOLIDUS
@ -1205,6 +1273,8 @@ where
None => { None => {
self.emit_error(ErrorKind::EofInScriptHtmlCommentLikeText); self.emit_error(ErrorKind::EofInScriptHtmlCommentLikeText);
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Emit the current input character as a character token. // Emit the current input character as a character token.
@ -1245,6 +1315,8 @@ where
None => { None => {
self.emit_error(ErrorKind::EofInScriptHtmlCommentLikeText); self.emit_error(ErrorKind::EofInScriptHtmlCommentLikeText);
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Switch to the script data escaped state. Emit the current input character // Switch to the script data escaped state. Emit the current input character
@ -1292,6 +1364,8 @@ where
None => { None => {
self.emit_error(ErrorKind::EofInScriptHtmlCommentLikeText); self.emit_error(ErrorKind::EofInScriptHtmlCommentLikeText);
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Switch to the script data escaped state. Emit the current input character // Switch to the script data escaped state. Emit the current input character
@ -1557,6 +1631,8 @@ where
None => { None => {
self.emit_error(ErrorKind::EofInScriptHtmlCommentLikeText); self.emit_error(ErrorKind::EofInScriptHtmlCommentLikeText);
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// end-of-file token. Anything else // end-of-file token. Anything else
// Emit the current input character as a character token. // Emit the current input character as a character token.
@ -1600,6 +1676,8 @@ where
None => { None => {
self.emit_error(ErrorKind::EofInScriptHtmlCommentLikeText); self.emit_error(ErrorKind::EofInScriptHtmlCommentLikeText);
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Switch to the script data double escaped state. Emit the current input // Switch to the script data double escaped state. Emit the current input
@ -1650,6 +1728,8 @@ where
None => { None => {
self.emit_error(ErrorKind::EofInScriptHtmlCommentLikeText); self.emit_error(ErrorKind::EofInScriptHtmlCommentLikeText);
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Switch to the script data double escaped state. Emit the current input // Switch to the script data double escaped state. Emit the current input
@ -1942,6 +2022,8 @@ where
None => { None => {
self.emit_error(ErrorKind::EofInTag); self.emit_error(ErrorKind::EofInTag);
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Start a new attribute in the current tag token. Set that attribute name // Start a new attribute in the current tag token. Set that attribute name
@ -2007,7 +2089,29 @@ where
match self.consume_next_char() { match self.consume_next_char() {
// U+0022 QUOTATION MARK (") // U+0022 QUOTATION MARK (")
// Switch to the after attribute value (quoted) state. // Switch to the after attribute value (quoted) state.
// We set value to support empty attributes (i.e. `attr=""`)
Some('"') => { Some('"') => {
if let Some(ref mut token) = self.cur_token {
match token {
Token::StartTag { attributes, .. }
| Token::EndTag { attributes, .. } => {
if let Some(attribute) = attributes.last_mut() {
let mut new_value = String::new();
match &attribute.value {
Some(value) => {
new_value.push_str(value);
}
None => {}
}
attribute.value = Some(new_value.into());
}
}
_ => {}
}
}
self.state = State::AfterAttributeValueQuoted; self.state = State::AfterAttributeValueQuoted;
} }
// U+0026 AMPERSAND (&) // U+0026 AMPERSAND (&)
@ -2051,6 +2155,8 @@ where
None => { None => {
self.emit_error(ErrorKind::EofInTag); self.emit_error(ErrorKind::EofInTag);
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Append the current input character to the current attribute's value. // Append the current input character to the current attribute's value.
@ -2086,7 +2192,29 @@ where
match self.consume_next_char() { match self.consume_next_char() {
// U+0027 APOSTROPHE (') // U+0027 APOSTROPHE (')
// Switch to the after attribute value (quoted) state. // Switch to the after attribute value (quoted) state.
// We set value to support empty attributes (i.e. `attr=''`)
Some('\'') => { Some('\'') => {
if let Some(ref mut token) = self.cur_token {
match token {
Token::StartTag { attributes, .. }
| Token::EndTag { attributes, .. } => {
if let Some(attribute) = attributes.last_mut() {
let mut new_value = String::new();
match &attribute.value {
Some(value) => {
new_value.push_str(value);
}
None => {}
}
attribute.value = Some(new_value.into());
}
}
_ => {}
}
}
self.state = State::AfterAttributeValueQuoted; self.state = State::AfterAttributeValueQuoted;
} }
// U+0026 AMPERSAND (&) // U+0026 AMPERSAND (&)
@ -2130,6 +2258,8 @@ where
None => { None => {
self.emit_error(ErrorKind::EofInTag); self.emit_error(ErrorKind::EofInTag);
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Append the current input character to the current attribute's value. // Append the current input character to the current attribute's value.
@ -2228,6 +2358,8 @@ where
None => { None => {
self.emit_error(ErrorKind::EofInTag); self.emit_error(ErrorKind::EofInTag);
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Append the current input character to the current attribute's value. // Append the current input character to the current attribute's value.
@ -2285,6 +2417,8 @@ where
None => { None => {
self.emit_error(ErrorKind::EofInTag); self.emit_error(ErrorKind::EofInTag);
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// This is a missing-whitespace-between-attributes parse error. Reconsume in // This is a missing-whitespace-between-attributes parse error. Reconsume in
@ -2324,6 +2458,8 @@ where
None => { None => {
self.emit_error(ErrorKind::EofInTag); self.emit_error(ErrorKind::EofInTag);
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// This is an unexpected-solidus-in-tag parse error. Reconsume in the before // This is an unexpected-solidus-in-tag parse error. Reconsume in the before
@ -2350,6 +2486,8 @@ where
None => { None => {
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// U+0000 NULL // U+0000 NULL
// This is an unexpected-null-character parse error. Append a U+FFFD // This is an unexpected-null-character parse error. Append a U+FFFD
@ -2568,6 +2706,8 @@ where
self.emit_error(ErrorKind::EofInComment); self.emit_error(ErrorKind::EofInComment);
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Append a U+002D HYPHEN-MINUS character (-) to the comment token's data. // Append a U+002D HYPHEN-MINUS character (-) to the comment token's data.
@ -2648,6 +2788,8 @@ where
self.emit_error(ErrorKind::EofInComment); self.emit_error(ErrorKind::EofInComment);
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Append the current input character to the comment token's data. // Append the current input character to the comment token's data.
@ -2747,6 +2889,7 @@ where
// Reconsume in the comment end dash state. // Reconsume in the comment end dash state.
_ => { _ => {
self.state = State::CommentEndDash; self.state = State::CommentEndDash;
self.reconsume()
} }
} }
} }
@ -2786,6 +2929,8 @@ where
self.emit_error(ErrorKind::EofInComment); self.emit_error(ErrorKind::EofInComment);
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Append a U+002D HYPHEN-MINUS character (-) to the comment token's data. // Append a U+002D HYPHEN-MINUS character (-) to the comment token's data.
@ -2847,6 +2992,8 @@ where
self.emit_error(ErrorKind::EofInComment); self.emit_error(ErrorKind::EofInComment);
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Append two U+002D HYPHEN-MINUS characters (-) to the comment token's // Append two U+002D HYPHEN-MINUS characters (-) to the comment token's
@ -2912,6 +3059,8 @@ where
self.emit_error(ErrorKind::EofInComment); self.emit_error(ErrorKind::EofInComment);
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Append two U+002D HYPHEN-MINUS characters (-) and a U+0021 EXCLAMATION // Append two U+002D HYPHEN-MINUS characters (-) and a U+0021 EXCLAMATION
@ -2970,6 +3119,8 @@ where
}); });
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// This is a missing-whitespace-before-doctype-name parse error. Reconsume // This is a missing-whitespace-before-doctype-name parse error. Reconsume
@ -3047,6 +3198,8 @@ where
}); });
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Create a new DOCTYPE token. Set the token's name to the current input // Create a new DOCTYPE token. Set the token's name to the current input
@ -3138,6 +3291,8 @@ where
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Append the current input character to the current DOCTYPE token's name. // Append the current input character to the current DOCTYPE token's name.
@ -3192,6 +3347,8 @@ where
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// If the six characters starting from the current input character are an // If the six characters starting from the current input character are an
@ -3340,6 +3497,8 @@ where
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// This is a missing-quote-before-doctype-public-identifier parse error. Set // This is a missing-quote-before-doctype-public-identifier parse error. Set
@ -3442,6 +3601,8 @@ where
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// This is a missing-quote-before-doctype-public-identifier parse error. Set // This is a missing-quote-before-doctype-public-identifier parse error. Set
@ -3534,6 +3695,8 @@ where
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Append the current input character to the current DOCTYPE token's public // Append the current input character to the current DOCTYPE token's public
@ -3626,6 +3789,8 @@ where
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Append the current input character to the current DOCTYPE token's public // Append the current input character to the current DOCTYPE token's public
@ -3722,6 +3887,8 @@ where
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// This is a missing-quote-before-doctype-system-identifier parse error. Set // This is a missing-quote-before-doctype-system-identifier parse error. Set
@ -3810,6 +3977,8 @@ where
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// This is a missing-quote-before-doctype-system-identifier parse error. Set // This is a missing-quote-before-doctype-system-identifier parse error. Set
@ -3919,6 +4088,8 @@ where
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// This is a missing-quote-before-doctype-system-identifier parse error. Set // This is a missing-quote-before-doctype-system-identifier parse error. Set
@ -4012,6 +4183,8 @@ where
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// This is a missing-quote-before-doctype-system-identifier parse error. Set // This is a missing-quote-before-doctype-system-identifier parse error. Set
@ -4104,6 +4277,8 @@ where
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Append the current input character to the current DOCTYPE token's system // Append the current input character to the current DOCTYPE token's system
@ -4196,6 +4371,8 @@ where
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Append the current input character to the current DOCTYPE token's system // Append the current input character to the current DOCTYPE token's system
@ -4252,6 +4429,8 @@ where
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// This is an unexpected-character-after-doctype-system-identifier parse // This is an unexpected-character-after-doctype-system-identifier parse
@ -4287,6 +4466,8 @@ where
None => { None => {
self.emit_cur_token(); self.emit_cur_token();
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Ignore the character. // Ignore the character.
@ -4307,6 +4488,8 @@ where
None => { None => {
self.emit_error(ErrorKind::EofInCdata); self.emit_error(ErrorKind::EofInCdata);
self.emit_token(Token::Eof); self.emit_token(Token::Eof);
return Ok(());
} }
// Anything else // Anything else
// Emit the current input character as a character token. // Emit the current input character as a character token.
@ -4386,20 +4569,66 @@ where
// Flush code points consumed as a character reference. Reconsume in the // Flush code points consumed as a character reference. Reconsume in the
// return state. // return state.
_ => { _ => {
// TODO fix me if let Some(mut temporary_buffer) = self.temporary_buffer.clone() {
for c in temporary_buffer.drain(..) {
self.flush_code_point_consumed_as_character_reference(c);
}
}
self.state = self.return_state.clone(); self.state = self.return_state.clone();
self.reconsume();
} }
} }
} }
// https://html.spec.whatwg.org/multipage/parsing.html#named-character-reference-state // https://html.spec.whatwg.org/multipage/parsing.html#named-character-reference-state
State::NamedCharacterReference => { State::NamedCharacterReference => {
// TODO fix me // Consume the maximum number of characters possible, where the consumed
let is_matched = true; // characters are one of the identifiers in the first column of the named
// character references table. Append each character to the temporary buffer
// when it's consumed.
// The shortest entity - `&GT`
// The longest entity - `&CounterClockwiseContourIntegral;`
let mut entity: Option<&Entity> = None;
let mut cur_pos: Option<BytePos> = None;
// TODO fix me with surrogate pairs and in `NumericCharacterReferenceEnd` too
while let Some(c) = &self.consume_next_char() {
if let Some(ref mut temporary_buffer) = self.temporary_buffer {
temporary_buffer.push(*c);
let found_entity = HTML_ENTITIES.get(temporary_buffer);
if let Some(found_entity) = found_entity {
cur_pos = Some(self.input.cur_pos());
entity = Some(found_entity);
}
// We stop when:
// - not ascii alphabetic
// - we consume more characters them the longest entity
if !c.is_ascii_alphabetic() || temporary_buffer.len() > 33 {
if let Some(cur_pos) = cur_pos {
self.input.reset_to(cur_pos);
}
break;
}
}
}
let is_last_semicolon =
matches!(&self.temporary_buffer, Some(value) if value.ends_with(';'));
// If there is a match // If there is a match
match is_matched { match entity {
true => { Some(entity) => {
let is_next_equals_sign_or_ascii_alphanumeric = match self.next() {
Some('=') => true,
Some(c) if c.is_ascii_alphanumeric() => true,
_ => false,
};
// If the character reference was consumed as part of an attribute, and // If the character reference was consumed as part of an attribute, and
// the last character matched is not a // the last character matched is not a
// U+003B SEMICOLON character (;), and the next input // U+003B SEMICOLON character (;), and the next input
@ -4407,7 +4636,16 @@ where
// alphanumeric, then, for historical reasons, flush code points // alphanumeric, then, for historical reasons, flush code points
// consumed as a character reference and // consumed as a character reference and
// switch to the return state. // switch to the return state.
if self.is_consumed_as_part_of_an_attribute() { if self.is_consumed_as_part_of_an_attribute()
&& !is_last_semicolon
&& is_next_equals_sign_or_ascii_alphanumeric
{
if let Some(mut temporary_buffer) = self.temporary_buffer.clone() {
for c in temporary_buffer.drain(..) {
self.flush_code_point_consumed_as_character_reference(c);
}
}
self.state = self.return_state.clone(); self.state = self.return_state.clone();
} }
// Otherwise: // Otherwise:
@ -4424,26 +4662,34 @@ where
// Flush code points consumed as a character reference. Switch to the // Flush code points consumed as a character reference. Switch to the
// return state. // return state.
else { else {
// TODO fix me
let is_last_semicolon = false;
if is_last_semicolon { if is_last_semicolon {
self.emit_error( self.emit_error(
ErrorKind::MissingSemicolonAfterCharacterReference, ErrorKind::MissingSemicolonAfterCharacterReference,
); );
} }
self.temporary_buffer = Some("".into()); let mut temporary_buffer = String::new();
// TODO fix me temporary_buffer.push_str(&entity.characters);
for c in temporary_buffer.drain(..) {
self.flush_code_point_consumed_as_character_reference(c);
}
self.temporary_buffer = Some(temporary_buffer);
self.state = self.return_state.clone(); self.state = self.return_state.clone();
} }
} }
// Otherwise // Otherwise
// Flush code points consumed as a character reference. Switch to the // Flush code points consumed as a character reference. Switch to the
// ambiguous ampersand state. // ambiguous ampersand state.
false => { _ => {
if let Some(mut temporary_buffer) = self.temporary_buffer.clone() {
for c in temporary_buffer.drain(..) {
self.flush_code_point_consumed_as_character_reference(c);
}
}
self.state = State::AmbiguousAmpersand; self.state = State::AmbiguousAmpersand;
} }
} }
@ -4542,7 +4788,11 @@ where
_ => { _ => {
self.emit_error(ErrorKind::AbsenceOfDigitsInNumericCharacterReference); self.emit_error(ErrorKind::AbsenceOfDigitsInNumericCharacterReference);
// TODO fix me if let Some(mut temporary_buffer) = self.temporary_buffer.clone() {
for c in temporary_buffer.drain(..) {
self.flush_code_point_consumed_as_character_reference(c);
}
}
self.state = self.return_state.clone(); self.state = self.return_state.clone();
self.reconsume(); self.reconsume();
@ -4566,7 +4816,11 @@ where
_ => { _ => {
self.emit_error(ErrorKind::AbsenceOfDigitsInNumericCharacterReference); self.emit_error(ErrorKind::AbsenceOfDigitsInNumericCharacterReference);
// TODO fix me if let Some(mut temporary_buffer) = self.temporary_buffer.clone() {
for c in temporary_buffer.drain(..) {
self.flush_code_point_consumed_as_character_reference(c);
}
}
self.state = self.return_state.clone(); self.state = self.return_state.clone();
self.reconsume(); self.reconsume();
@ -4665,37 +4919,133 @@ where
State::NumericCharacterReferenceEnd => { State::NumericCharacterReferenceEnd => {
// Check the character reference code: // Check the character reference code:
match self.character_reference_code { match self.character_reference_code {
// If the number is 0x00, then this is a null-character-reference parse Some(cr) => {
// error. Set the character reference code to 0xFFFD. let cr = match cr {
Some(0) => { // If the number is 0x00, then this is a null-character-reference
self.emit_error(ErrorKind::NullCharacterReference); // parse error. Set the character
// reference code to 0xFFFD.
0 => {
self.emit_error(ErrorKind::NullCharacterReference);
self.character_reference_code = Some('\u{FFFD}' as u32); 0xfffd
} }
// If the number is greater than 0x10FFFF, then this is a // If the number is greater than 0x10FFFF, then this is a
// character-reference-outside-unicode-range parse error. Set the character // character-reference-outside-unicode-range parse error. Set the
// reference code to 0xFFFD. // character reference code to
Some(c) if c > '\u{10FFFF}' as u32 => { // 0xFFFD.
self.emit_error(ErrorKind::CharacterReferenceOutsideUnicodeRange); cr if cr > 0x10ffff => {
self.emit_error(
ErrorKind::CharacterReferenceOutsideUnicodeRange,
);
self.character_reference_code = Some('\u{FFFD}' as u32); 0xfffd
}
// If the number is a surrogate, then this is a
// surrogate-character-reference parse error. Set the character
// reference code to 0xFFFD.
//
// If the number is a noncharacter, then this is a
// noncharacter-character-reference parse error.
cr if is_noncharacter(cr) => {
self.emit_error(ErrorKind::NoncharacterCharacterReference);
cr
}
// If the number is 0x0D, or a control that's not ASCII whitespace,
// then
// this is a control-character-reference parse error. If the number
// is one of the numbers in the
// first column of the following table, then find the
// row with that number in the first column, and set the character
// reference code to the number in
// the second column of that row.
cr if cr == 0x0d || is_control(cr) => {
self.emit_error(ErrorKind::ControlCharacterReference);
match cr {
// 0x80 0x20AC EURO SIGN (€)
0x80 => 0x20ac,
// 0x82 0x201A SINGLE LOW-9 QUOTATION MARK ()
0x82 => 0x201a,
// 0x83 0x0192 LATIN SMALL LETTER F WITH HOOK (ƒ)
0x83 => 0x0192,
// 0x84 0x201E DOUBLE LOW-9 QUOTATION MARK („)
0x84 => 0x201e,
// 0x85 0x2026 HORIZONTAL ELLIPSIS (…)
0x85 => 0x2026,
// 0x86 0x2020 DAGGER (†)
0x86 => 0x2020,
// 0x87 0x2021 DOUBLE DAGGER (‡)
0x87 => 0x2021,
// 0x88 0x02C6 MODIFIER LETTER CIRCUMFLEX ACCENT (ˆ)
0x88 => 0x02c6,
// 0x89 0x2030 PER MILLE SIGN (‰)
0x89 => 0x2030,
// 0x8A 0x0160 LATIN CAPITAL LETTER S WITH CARON (Š)
0x8a => 0x0160,
// 0x8B 0x2039 SINGLE LEFT-POINTING ANGLE QUOTATION MARK ()
0x8b => 0x2039,
// 0x8C 0x0152 LATIN CAPITAL LIGATURE OE (Œ)
0x8c => 0x0152,
// 0x8E 0x017D LATIN CAPITAL LETTER Z WITH CARON (Ž)
0x8e => 0x017d,
// 0x91 0x2018 LEFT SINGLE QUOTATION MARK ()
0x91 => 0x2018,
// 0x92 0x2018 RIGHT SINGLE QUOTATION MARK ()
0x92 => 0x2019,
// 0x93 0x201C LEFT DOUBLE QUOTATION MARK (“)
0x93 => 0x201c,
// 0x94 0x201D RIGHT DOUBLE QUOTATION MARK (”)
0x94 => 0x201d,
// 0x95 0x2022 BULLET (•)
0x95 => 0x2022,
// 0x96 0x2013 EN DASH ()
0x96 => 0x2013,
// 0x97 0x2014 EM DASH (—)
0x97 => 0x2014,
// 0x98 0x02DC SMALL TILDE (˜)
0x98 => 0x02dc,
// 0x99 0x2122 TRADE MARK SIGN (™)
0x99 => 0x2122,
// 0x9A 0x0161 LATIN SMALL LETTER S WITH CARON (š)
0x9a => 0x0161,
// 0x9B 0x203A SINGLE RIGHT-POINTING ANGLE QUOTATION MARK ()
0x9b => 0x203a,
// 0x9C 0x0153 LATIN SMALL LIGATURE OE (œ)
0x9c => 0x0153,
// 0x9E 0x017E LATIN SMALL LETTER Z WITH CARON (ž)
0x9e => 0x017e,
// 0x9F 0x0178 LATIN CAPITAL LETTER Y WITH DIAERESIS (Ÿ)
0x9f => 0x0178,
_ => cr,
}
}
_ => cr,
};
// Set the temporary buffer to the empty string. Append a code point
// equal to the character reference
// code to the temporary buffer. Flush code
// points consumed as a character reference. Switch to the return
// state.
let mut temporary_buffer = String::new();
let c = match char::from_u32(cr) {
Some(c) => c,
_ => {
unreachable!();
}
};
temporary_buffer.push(c);
self.flush_code_point_consumed_as_character_reference(c);
self.temporary_buffer = Some(temporary_buffer);
self.state = self.return_state.clone();
} }
// TODO fix me None => {
// If the number is a surrogate, then this is a unreachable!();
// surrogate-character-reference parse error. Set the character reference
// code to 0xFFFD.
// If the number is a noncharacter, then this is a
// noncharacter-character-reference parse error.
Some(c) if is_noncharacter(c) => {
self.emit_error(ErrorKind::NoncharacterCharacterReference);
} }
// TODO fix me
// If the number is 0x0D, or a control that's not ASCII whitespace, then
// this is a control-character-reference parse error. If the number is one
// of the numbers in the first column of the following table, then find the
// row with that number in the first column, and set the character reference
// code to the number in the second column of that row.
_ => {}
} }
} }
} }
@ -4703,12 +5053,18 @@ where
} }
} }
#[inline(always)]
fn is_control(c: u32) -> bool {
matches!(c, c @ 0x7f..=0x9f if !matches!(c, 0x20 | 0x0a | 0x0d | 0x09 | 0x0c | 0x01 | 0x1f))
}
// A noncharacter is a code point that is in the range U+FDD0 to U+FDEF, // A noncharacter is a code point that is in the range U+FDD0 to U+FDEF,
// inclusive, or U+FFFE, U+FFFF, U+1FFFE, U+1FFFF, U+2FFFE, U+2FFFF, U+3FFFE, // inclusive, or U+FFFE, U+FFFF, U+1FFFE, U+1FFFF, U+2FFFE, U+2FFFF, U+3FFFE,
// U+3FFFF, U+4FFFE, U+4FFFF, U+5FFFE, U+5FFFF, U+6FFFE, U+6FFFF, U+7FFFE, // U+3FFFF, U+4FFFE, U+4FFFF, U+5FFFE, U+5FFFF, U+6FFFE, U+6FFFF, U+7FFFE,
// U+7FFFF, U+8FFFE, U+8FFFF, U+9FFFE, U+9FFFF, U+AFFFE, U+AFFFF, U+BFFFE, // U+7FFFF, U+8FFFE, U+8FFFF, U+9FFFE, U+9FFFF, U+AFFFE, U+AFFFF, U+BFFFE,
// U+BFFFF, U+CFFFE, U+CFFFF, U+DFFFE, U+DFFFF, U+EFFFE, U+EFFFF, U+FFFFE, // U+BFFFF, U+CFFFE, U+CFFFF, U+DFFFE, U+DFFFF, U+EFFFE, U+EFFFF, U+FFFFE,
// U+FFFFF, U+10FFFE, or U+10FFFF. // U+FFFFF, U+10FFFE, or U+10FFFF.
#[inline(always)]
fn is_noncharacter(c: u32) -> bool { fn is_noncharacter(c: u32) -> bool {
let c = char::from_u32(c); let c = char::from_u32(c);

View File

@ -0,0 +1,10 @@
<a 0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z></a>
<p title=" <![CDATA[ \n\n foobar baz ]]> ">x</p>
<p title=" <!-- hello world --> ">x</p>
<tag v-ref:vm_pv :imgs=" objpicsurl_ "></tag>
<br a=\u00A0 b="&nbsp;" c="\u00A0">
<img
src
=
"test"
/>

View File

@ -0,0 +1,433 @@
{
"type": "Document",
"span": {
"start": 0,
"end": 271,
"ctxt": 0
},
"children": [
{
"type": "TokenAndSpan",
"span": {
"start": 0,
"end": 75,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "a",
"self_closing": false,
"attributes": [
{
"name": "0",
"value": null
},
{
"name": "1",
"value": null
},
{
"name": "2",
"value": null
},
{
"name": "3",
"value": null
},
{
"name": "4",
"value": null
},
{
"name": "5",
"value": null
},
{
"name": "6",
"value": null
},
{
"name": "7",
"value": null
},
{
"name": "8",
"value": null
},
{
"name": "9",
"value": null
},
{
"name": "a",
"value": null
},
{
"name": "b",
"value": null
},
{
"name": "c",
"value": null
},
{
"name": "d",
"value": null
},
{
"name": "e",
"value": null
},
{
"name": "f",
"value": null
},
{
"name": "g",
"value": null
},
{
"name": "h",
"value": null
},
{
"name": "i",
"value": null
},
{
"name": "j",
"value": null
},
{
"name": "k",
"value": null
},
{
"name": "l",
"value": null
},
{
"name": "m",
"value": null
},
{
"name": "n",
"value": null
},
{
"name": "o",
"value": null
},
{
"name": "p",
"value": null
},
{
"name": "q",
"value": null
},
{
"name": "r",
"value": null
},
{
"name": "s",
"value": null
},
{
"name": "t",
"value": null
},
{
"name": "u",
"value": null
},
{
"name": "v",
"value": null
},
{
"name": "w",
"value": null
},
{
"name": "x",
"value": null
},
{
"name": "y",
"value": null
},
{
"name": "z",
"value": null
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 75,
"end": 79,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "a",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 79,
"end": 80,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 80,
"end": 123,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "p",
"self_closing": false,
"attributes": [
{
"name": "title",
"value": " <![CDATA[ \\n\\n foobar baz ]]> "
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 123,
"end": 124,
"ctxt": 0
},
"token": {
"Character": {
"value": "x"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 124,
"end": 128,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "p",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 128,
"end": 129,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 129,
"end": 163,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "p",
"self_closing": false,
"attributes": [
{
"name": "title",
"value": " <!-- hello world --> "
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 163,
"end": 164,
"ctxt": 0
},
"token": {
"Character": {
"value": "x"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 164,
"end": 168,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "p",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 168,
"end": 169,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 169,
"end": 208,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "tag",
"self_closing": false,
"attributes": [
{
"name": "v-ref:vm_pv",
"value": null
},
{
"name": ":imgs",
"value": " objpicsurl_ "
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 208,
"end": 214,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "tag",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 214,
"end": 215,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 215,
"end": 250,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "br",
"self_closing": false,
"attributes": [
{
"name": "a",
"value": "\\u00A0"
},
{
"name": "b",
"value": ""
},
{
"name": "c",
"value": "\\u00A0"
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 250,
"end": 251,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 251,
"end": 271,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "img",
"self_closing": true,
"attributes": [
{
"name": "src",
"value": "test"
}
]
}
}
}
]
}

View File

@ -0,0 +1,136 @@
x Document
,-[$DIR/tests/fixture/attributes/input.html:1:1]
1 | ,-> <a 0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z></a>
2 | | <p title=" <![CDATA[ \n\n foobar baz ]]> ">x</p>
3 | | <p title=" <!-- hello world --> ">x</p>
4 | | <tag v-ref:vm_pv :imgs=" objpicsurl_ "></tag>
5 | | <br a=\u00A0 b="&nbsp;" c="\u00A0">
6 | | <img
7 | | src
8 | | =
9 | | "test"
10 | `-> />
`----
x StartTag { tag_name: Atom('a' type=inline), self_closing: false, attributes: [Attribute { name: Atom('0' type=inline), value: None }, Attribute { name: Atom('1' type=inline), value: None },
| Attribute { name: Atom('2' type=inline), value: None }, Attribute { name: Atom('3' type=inline), value: None }, Attribute { name: Atom('4' type=inline), value: None }, Attribute { name: Atom('5'
| type=inline), value: None }, Attribute { name: Atom('6' type=inline), value: None }, Attribute { name: Atom('7' type=inline), value: None }, Attribute { name: Atom('8' type=inline), value:
| None }, Attribute { name: Atom('9' type=inline), value: None }, Attribute { name: Atom('a' type=inline), value: None }, Attribute { name: Atom('b' type=inline), value: None }, Attribute { name:
| Atom('c' type=inline), value: None }, Attribute { name: Atom('d' type=inline), value: None }, Attribute { name: Atom('e' type=inline), value: None }, Attribute { name: Atom('f' type=inline),
| value: None }, Attribute { name: Atom('g' type=inline), value: None }, Attribute { name: Atom('h' type=inline), value: None }, Attribute { name: Atom('i' type=inline), value: None }, Attribute
| { name: Atom('j' type=inline), value: None }, Attribute { name: Atom('k' type=inline), value: None }, Attribute { name: Atom('l' type=inline), value: None }, Attribute { name: Atom('m'
| type=inline), value: None }, Attribute { name: Atom('n' type=inline), value: None }, Attribute { name: Atom('o' type=inline), value: None }, Attribute { name: Atom('p' type=inline), value:
| None }, Attribute { name: Atom('q' type=inline), value: None }, Attribute { name: Atom('r' type=inline), value: None }, Attribute { name: Atom('s' type=inline), value: None }, Attribute { name:
| Atom('t' type=inline), value: None }, Attribute { name: Atom('u' type=inline), value: None }, Attribute { name: Atom('v' type=inline), value: None }, Attribute { name: Atom('w' type=inline),
| value: None }, Attribute { name: Atom('x' type=inline), value: None }, Attribute { name: Atom('y' type=inline), value: None }, Attribute { name: Atom('z' type=inline), value: None }] }
,-[$DIR/tests/fixture/attributes/input.html:1:1]
1 | <a 0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z></a>
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x EndTag { tag_name: Atom('a' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/attributes/input.html:1:1]
1 | <a 0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z></a>
: ^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/attributes/input.html:1:1]
1 | <a 0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z></a>
: ^
2 | <p title=" <![CDATA[ \n\n foobar baz ]]> ">x</p>
`----
x StartTag { tag_name: Atom('p' type=inline), self_closing: false, attributes: [Attribute { name: Atom('title' type=inline), value: Some(Atom(' <![CDATA[ \n\n foobar baz ]]> ' type=dynamic)) }] }
,-[$DIR/tests/fixture/attributes/input.html:2:1]
2 | <p title=" <![CDATA[ \n\n foobar baz ]]> ">x</p>
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x Character { value: 'x' }
,-[$DIR/tests/fixture/attributes/input.html:2:1]
2 | <p title=" <![CDATA[ \n\n foobar baz ]]> ">x</p>
: ^
`----
x EndTag { tag_name: Atom('p' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/attributes/input.html:2:1]
2 | <p title=" <![CDATA[ \n\n foobar baz ]]> ">x</p>
: ^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/attributes/input.html:2:1]
2 | <p title=" <![CDATA[ \n\n foobar baz ]]> ">x</p>
: ^
3 | <p title=" <!-- hello world --> ">x</p>
`----
x StartTag { tag_name: Atom('p' type=inline), self_closing: false, attributes: [Attribute { name: Atom('title' type=inline), value: Some(Atom(' <!-- hello world --> ' type=dynamic)) }] }
,-[$DIR/tests/fixture/attributes/input.html:3:1]
3 | <p title=" <!-- hello world --> ">x</p>
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x Character { value: 'x' }
,-[$DIR/tests/fixture/attributes/input.html:3:1]
3 | <p title=" <!-- hello world --> ">x</p>
: ^
`----
x EndTag { tag_name: Atom('p' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/attributes/input.html:3:1]
3 | <p title=" <!-- hello world --> ">x</p>
: ^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/attributes/input.html:3:1]
3 | <p title=" <!-- hello world --> ">x</p>
: ^
4 | <tag v-ref:vm_pv :imgs=" objpicsurl_ "></tag>
`----
x StartTag { tag_name: Atom('tag' type=inline), self_closing: false, attributes: [Attribute { name: Atom('v-ref:vm_pv' type=dynamic), value: None }, Attribute { name: Atom(':imgs' type=inline),
| value: Some(Atom(' objpicsurl_ ' type=dynamic)) }] }
,-[$DIR/tests/fixture/attributes/input.html:4:1]
4 | <tag v-ref:vm_pv :imgs=" objpicsurl_ "></tag>
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x EndTag { tag_name: Atom('tag' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/attributes/input.html:4:1]
4 | <tag v-ref:vm_pv :imgs=" objpicsurl_ "></tag>
: ^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/attributes/input.html:4:1]
4 | <tag v-ref:vm_pv :imgs=" objpicsurl_ "></tag>
: ^
5 | <br a=\u00A0 b="&nbsp;" c="\u00A0">
`----
x StartTag { tag_name: Atom('br' type=inline), self_closing: false, attributes: [Attribute { name: Atom('a' type=inline), value: Some(Atom('\u00A0' type=inline)) }, Attribute { name: Atom('b'
| type=inline), value: Some(Atom('' type=static)) }, Attribute { name: Atom('c' type=inline), value: Some(Atom('\u00A0' type=inline)) }] }
,-[$DIR/tests/fixture/attributes/input.html:5:1]
5 | <br a=\u00A0 b="&nbsp;" c="\u00A0">
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/attributes/input.html:5:1]
5 | <br a=\u00A0 b="&nbsp;" c="\u00A0">
: ^
6 | <img
`----
x StartTag { tag_name: Atom('img' type=inline), self_closing: true, attributes: [Attribute { name: Atom('src' type=inline), value: Some(Atom('test' type=inline)) }] }
,-[$DIR/tests/fixture/attributes/input.html:6:1]
6 | ,-> <img
7 | | src
8 | | =
9 | | "test"
10 | `-> />
`----

View File

@ -0,0 +1 @@
<! Failing New York Times Comment -->

View File

@ -0,0 +1,23 @@
{
"type": "Document",
"span": {
"start": 0,
"end": 43,
"ctxt": 0
},
"children": [
{
"type": "TokenAndSpan",
"span": {
"start": 0,
"end": 43,
"ctxt": 0
},
"token": {
"Comment": {
"data": " Failing New York Times Comment --"
}
}
}
]
}

View File

@ -0,0 +1,12 @@
x Document
,-[$DIR/tests/fixture/bogus-comment-1/input.html:1:1]
1 | <! Failing New York Times Comment -->
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x Comment { data: Atom(' Failing New York Times Comment --' type=dynamic) }
,-[$DIR/tests/fixture/bogus-comment-1/input.html:1:1]
1 | <! Failing New York Times Comment -->
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----

View File

@ -0,0 +1 @@
<!-- test

View File

@ -0,0 +1,23 @@
{
"type": "Document",
"span": {
"start": 0,
"end": 9,
"ctxt": 0
},
"children": [
{
"type": "TokenAndSpan",
"span": {
"start": 0,
"end": 9,
"ctxt": 0
},
"token": {
"Comment": {
"data": " test"
}
}
}
]
}

View File

@ -0,0 +1,12 @@
x Document
,-[$DIR/tests/fixture/bogus-comment/input.html:1:1]
1 | <!-- test
: ^^^^^^^^^
`----
x Comment { data: Atom(' test' type=inline) }
,-[$DIR/tests/fixture/bogus-comment/input.html:1:1]
1 | <!-- test
: ^^^^^^^^^
`----

View File

@ -0,0 +1,8 @@
<!DOCTYPE html broken>
<html>
<body>
<a href=https://www.w3schools.com>This is a link</a>
</body>
</html>

View File

@ -0,0 +1,407 @@
{
"type": "Document",
"span": {
"start": 0,
"end": 108,
"ctxt": 0
},
"children": [
{
"type": "TokenAndSpan",
"span": {
"start": 0,
"end": 22,
"ctxt": 0
},
"token": {
"Doctype": {
"name": "html",
"force_quirks": true,
"public_id": null,
"system_id": null
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 22,
"end": 23,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 23,
"end": 29,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "html",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 29,
"end": 30,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 30,
"end": 36,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "body",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 36,
"end": 37,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 37,
"end": 38,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 38,
"end": 72,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "a",
"self_closing": false,
"attributes": [
{
"name": "href",
"value": "https://www.w3schools.com"
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 72,
"end": 73,
"ctxt": 0
},
"token": {
"Character": {
"value": "T"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 73,
"end": 74,
"ctxt": 0
},
"token": {
"Character": {
"value": "h"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 74,
"end": 75,
"ctxt": 0
},
"token": {
"Character": {
"value": "i"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 75,
"end": 76,
"ctxt": 0
},
"token": {
"Character": {
"value": "s"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 76,
"end": 77,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 77,
"end": 78,
"ctxt": 0
},
"token": {
"Character": {
"value": "i"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 78,
"end": 79,
"ctxt": 0
},
"token": {
"Character": {
"value": "s"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 79,
"end": 80,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 80,
"end": 81,
"ctxt": 0
},
"token": {
"Character": {
"value": "a"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 81,
"end": 82,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 82,
"end": 83,
"ctxt": 0
},
"token": {
"Character": {
"value": "l"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 83,
"end": 84,
"ctxt": 0
},
"token": {
"Character": {
"value": "i"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 84,
"end": 85,
"ctxt": 0
},
"token": {
"Character": {
"value": "n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 85,
"end": 86,
"ctxt": 0
},
"token": {
"Character": {
"value": "k"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 86,
"end": 90,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "a",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 90,
"end": 91,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 91,
"end": 92,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 92,
"end": 99,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "body",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 99,
"end": 100,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 100,
"end": 107,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "html",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 107,
"end": 108,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
}
]
}

View File

@ -0,0 +1,191 @@
x Document
,-[$DIR/tests/fixture/broken-doctype/input.html:1:1]
1 | ,-> <!DOCTYPE html broken>
2 | | <html>
3 | | <body>
4 | |
5 | | <a href=https://www.w3schools.com>This is a link</a>
6 | |
7 | | </body>
8 | `-> </html>
`----
x Doctype { name: Some(Atom('html' type=inline)), force_quirks: true, public_id: None, system_id: None }
,-[$DIR/tests/fixture/broken-doctype/input.html:1:1]
1 | <!DOCTYPE html broken>
: ^^^^^^^^^^^^^^^^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/broken-doctype/input.html:1:1]
1 | <!DOCTYPE html broken>
: ^
2 | <html>
`----
x StartTag { tag_name: Atom('html' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/broken-doctype/input.html:2:1]
2 | <html>
: ^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/broken-doctype/input.html:2:1]
2 | <html>
: ^
3 | <body>
`----
x StartTag { tag_name: Atom('body' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/broken-doctype/input.html:3:1]
3 | <body>
: ^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/broken-doctype/input.html:3:1]
3 | <body>
: ^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/broken-doctype/input.html:4:1]
4 |
: ^
5 | <a href=https://www.w3schools.com>This is a link</a>
`----
x StartTag { tag_name: Atom('a' type=inline), self_closing: false, attributes: [Attribute { name: Atom('href' type=inline), value: Some(Atom('https://www.w3schools.com' type=dynamic)) }] }
,-[$DIR/tests/fixture/broken-doctype/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x Character { value: 'T' }
,-[$DIR/tests/fixture/broken-doctype/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: 'h' }
,-[$DIR/tests/fixture/broken-doctype/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: 'i' }
,-[$DIR/tests/fixture/broken-doctype/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: 's' }
,-[$DIR/tests/fixture/broken-doctype/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/broken-doctype/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: 'i' }
,-[$DIR/tests/fixture/broken-doctype/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: 's' }
,-[$DIR/tests/fixture/broken-doctype/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/broken-doctype/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: 'a' }
,-[$DIR/tests/fixture/broken-doctype/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/broken-doctype/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: 'l' }
,-[$DIR/tests/fixture/broken-doctype/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: 'i' }
,-[$DIR/tests/fixture/broken-doctype/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: 'n' }
,-[$DIR/tests/fixture/broken-doctype/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: 'k' }
,-[$DIR/tests/fixture/broken-doctype/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x EndTag { tag_name: Atom('a' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/broken-doctype/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/broken-doctype/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/broken-doctype/input.html:6:1]
6 |
: ^
7 | </body>
`----
x EndTag { tag_name: Atom('body' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/broken-doctype/input.html:7:1]
7 | </body>
: ^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/broken-doctype/input.html:7:1]
7 | </body>
: ^
8 | </html>
`----
x EndTag { tag_name: Atom('html' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/broken-doctype/input.html:8:1]
8 | </html>
: ^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/broken-doctype/input.html:8:1]
8 | </html>
: ^
`----

View File

@ -0,0 +1,10 @@
<a class="0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z"></a>
<a class="add sort keys createSorter"></a>
<span class="sprite sprite-{{sprite}}"></span>
<span class="{{sprite}}-sprite sprite"></span>
<span class="sprite-{{sprite}}-sprite"></span>
<span class="{{sprite}}"></span>
<span class={{sprite}}></span>
<div class></div>
<div class="nav_sv_fo_v_column <#=(j === 0) ? 'nav_sv_fo_v_first' : '' #> foo_bar"></div>
<a class="moo <!-- htmlmin:ignore -->bar<!-- htmlmin:ignore --> foo baz"></a>

View File

@ -0,0 +1,477 @@
{
"type": "Document",
"span": {
"start": 0,
"end": 521,
"ctxt": 0
},
"children": [
{
"type": "TokenAndSpan",
"span": {
"start": 0,
"end": 83,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "a",
"self_closing": false,
"attributes": [
{
"name": "class",
"value": "0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z"
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 83,
"end": 87,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "a",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 87,
"end": 88,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 88,
"end": 126,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "a",
"self_closing": false,
"attributes": [
{
"name": "class",
"value": "add sort keys createSorter"
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 126,
"end": 130,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "a",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 130,
"end": 131,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 131,
"end": 170,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "span",
"self_closing": false,
"attributes": [
{
"name": "class",
"value": "sprite sprite-{{sprite}}"
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 170,
"end": 177,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "span",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 177,
"end": 178,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 178,
"end": 217,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "span",
"self_closing": false,
"attributes": [
{
"name": "class",
"value": "{{sprite}}-sprite sprite"
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 217,
"end": 224,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "span",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 224,
"end": 225,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 225,
"end": 264,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "span",
"self_closing": false,
"attributes": [
{
"name": "class",
"value": "sprite-{{sprite}}-sprite"
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 264,
"end": 271,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "span",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 271,
"end": 272,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 272,
"end": 297,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "span",
"self_closing": false,
"attributes": [
{
"name": "class",
"value": "{{sprite}}"
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 297,
"end": 304,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "span",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 304,
"end": 305,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 305,
"end": 328,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "span",
"self_closing": false,
"attributes": [
{
"name": "class",
"value": "{{sprite}}"
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 328,
"end": 335,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "span",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 335,
"end": 336,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 336,
"end": 347,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "div",
"self_closing": false,
"attributes": [
{
"name": "class",
"value": null
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 347,
"end": 353,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "div",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 353,
"end": 354,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 354,
"end": 437,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "div",
"self_closing": false,
"attributes": [
{
"name": "class",
"value": "nav_sv_fo_v_column <#=(j === 0) ? 'nav_sv_fo_v_first' : '' #> foo_bar"
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 437,
"end": 443,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "div",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 443,
"end": 444,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 444,
"end": 517,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "a",
"self_closing": false,
"attributes": [
{
"name": "class",
"value": "moo <!-- htmlmin:ignore -->bar<!-- htmlmin:ignore --> foo baz"
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 517,
"end": 521,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "a",
"self_closing": false,
"attributes": []
}
}
}
]
}

View File

@ -0,0 +1,200 @@
x Document
,-[$DIR/tests/fixture/class-attribute/input.html:1:1]
1 | ,-> <a class="0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z"></a>
2 | | <a class="add sort keys createSorter"></a>
3 | | <span class="sprite sprite-{{sprite}}"></span>
4 | | <span class="{{sprite}}-sprite sprite"></span>
5 | | <span class="sprite-{{sprite}}-sprite"></span>
6 | | <span class="{{sprite}}"></span>
7 | | <span class={{sprite}}></span>
8 | | <div class></div>
9 | | <div class="nav_sv_fo_v_column <#=(j === 0) ? 'nav_sv_fo_v_first' : '' #> foo_bar"></div>
10 | `-> <a class="moo <!-- htmlmin:ignore -->bar<!-- htmlmin:ignore --> foo baz"></a>
`----
x StartTag { tag_name: Atom('a' type=inline), self_closing: false, attributes: [Attribute { name: Atom('class' type=static), value: Some(Atom('0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q
| r s t u v w x y z' type=dynamic)) }] }
,-[$DIR/tests/fixture/class-attribute/input.html:1:1]
1 | <a class="0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z"></a>
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x EndTag { tag_name: Atom('a' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/class-attribute/input.html:1:1]
1 | <a class="0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z"></a>
: ^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/class-attribute/input.html:1:1]
1 | <a class="0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z"></a>
: ^
2 | <a class="add sort keys createSorter"></a>
`----
x StartTag { tag_name: Atom('a' type=inline), self_closing: false, attributes: [Attribute { name: Atom('class' type=static), value: Some(Atom('add sort keys createSorter' type=dynamic)) }] }
,-[$DIR/tests/fixture/class-attribute/input.html:2:1]
2 | <a class="add sort keys createSorter"></a>
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x EndTag { tag_name: Atom('a' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/class-attribute/input.html:2:1]
2 | <a class="add sort keys createSorter"></a>
: ^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/class-attribute/input.html:2:1]
2 | <a class="add sort keys createSorter"></a>
: ^
3 | <span class="sprite sprite-{{sprite}}"></span>
`----
x StartTag { tag_name: Atom('span' type=inline), self_closing: false, attributes: [Attribute { name: Atom('class' type=static), value: Some(Atom('sprite sprite-{{sprite}}' type=dynamic)) }] }
,-[$DIR/tests/fixture/class-attribute/input.html:3:1]
3 | <span class="sprite sprite-{{sprite}}"></span>
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x EndTag { tag_name: Atom('span' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/class-attribute/input.html:3:1]
3 | <span class="sprite sprite-{{sprite}}"></span>
: ^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/class-attribute/input.html:3:1]
3 | <span class="sprite sprite-{{sprite}}"></span>
: ^
4 | <span class="{{sprite}}-sprite sprite"></span>
`----
x StartTag { tag_name: Atom('span' type=inline), self_closing: false, attributes: [Attribute { name: Atom('class' type=static), value: Some(Atom('{{sprite}}-sprite sprite' type=dynamic)) }] }
,-[$DIR/tests/fixture/class-attribute/input.html:4:1]
4 | <span class="{{sprite}}-sprite sprite"></span>
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x EndTag { tag_name: Atom('span' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/class-attribute/input.html:4:1]
4 | <span class="{{sprite}}-sprite sprite"></span>
: ^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/class-attribute/input.html:4:1]
4 | <span class="{{sprite}}-sprite sprite"></span>
: ^
5 | <span class="sprite-{{sprite}}-sprite"></span>
`----
x StartTag { tag_name: Atom('span' type=inline), self_closing: false, attributes: [Attribute { name: Atom('class' type=static), value: Some(Atom('sprite-{{sprite}}-sprite' type=dynamic)) }] }
,-[$DIR/tests/fixture/class-attribute/input.html:5:1]
5 | <span class="sprite-{{sprite}}-sprite"></span>
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x EndTag { tag_name: Atom('span' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/class-attribute/input.html:5:1]
5 | <span class="sprite-{{sprite}}-sprite"></span>
: ^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/class-attribute/input.html:5:1]
5 | <span class="sprite-{{sprite}}-sprite"></span>
: ^
6 | <span class="{{sprite}}"></span>
`----
x StartTag { tag_name: Atom('span' type=inline), self_closing: false, attributes: [Attribute { name: Atom('class' type=static), value: Some(Atom('{{sprite}}' type=dynamic)) }] }
,-[$DIR/tests/fixture/class-attribute/input.html:6:1]
6 | <span class="{{sprite}}"></span>
: ^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x EndTag { tag_name: Atom('span' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/class-attribute/input.html:6:1]
6 | <span class="{{sprite}}"></span>
: ^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/class-attribute/input.html:6:1]
6 | <span class="{{sprite}}"></span>
: ^
7 | <span class={{sprite}}></span>
`----
x StartTag { tag_name: Atom('span' type=inline), self_closing: false, attributes: [Attribute { name: Atom('class' type=static), value: Some(Atom('{{sprite}}' type=dynamic)) }] }
,-[$DIR/tests/fixture/class-attribute/input.html:7:1]
7 | <span class={{sprite}}></span>
: ^^^^^^^^^^^^^^^^^^^^^^^
`----
x EndTag { tag_name: Atom('span' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/class-attribute/input.html:7:1]
7 | <span class={{sprite}}></span>
: ^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/class-attribute/input.html:7:1]
7 | <span class={{sprite}}></span>
: ^
8 | <div class></div>
`----
x StartTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [Attribute { name: Atom('class' type=static), value: None }] }
,-[$DIR/tests/fixture/class-attribute/input.html:8:1]
8 | <div class></div>
: ^^^^^^^^^^^
`----
x EndTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/class-attribute/input.html:8:1]
8 | <div class></div>
: ^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/class-attribute/input.html:8:1]
8 | <div class></div>
: ^
9 | <div class="nav_sv_fo_v_column <#=(j === 0) ? 'nav_sv_fo_v_first' : '' #> foo_bar"></div>
`----
x StartTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [Attribute { name: Atom('class' type=static), value: Some(Atom('nav_sv_fo_v_column <#=(j === 0) ?
| 'nav_sv_fo_v_first' : '' #> foo_bar' type=dynamic)) }] }
,-[$DIR/tests/fixture/class-attribute/input.html:9:1]
9 | <div class="nav_sv_fo_v_column <#=(j === 0) ? 'nav_sv_fo_v_first' : '' #> foo_bar"></div>
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x EndTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/class-attribute/input.html:9:1]
9 | <div class="nav_sv_fo_v_column <#=(j === 0) ? 'nav_sv_fo_v_first' : '' #> foo_bar"></div>
: ^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/class-attribute/input.html:9:1]
9 | <div class="nav_sv_fo_v_column <#=(j === 0) ? 'nav_sv_fo_v_first' : '' #> foo_bar"></div>
: ^
10 | <a class="moo <!-- htmlmin:ignore -->bar<!-- htmlmin:ignore --> foo baz"></a>
`----
x StartTag { tag_name: Atom('a' type=inline), self_closing: false, attributes: [Attribute { name: Atom('class' type=static), value: Some(Atom('moo <!-- htmlmin:ignore -->bar<!-- htmlmin:ignore -->
| foo baz' type=dynamic)) }] }
,-[$DIR/tests/fixture/class-attribute/input.html:10:1]
10 | <a class="moo <!-- htmlmin:ignore -->bar<!-- htmlmin:ignore --> foo baz"></a>
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x EndTag { tag_name: Atom('a' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/class-attribute/input.html:10:1]
10 | <a class="moo <!-- htmlmin:ignore -->bar<!-- htmlmin:ignore --> foo baz"></a>
: ^^^^
`----

View File

@ -0,0 +1,9 @@
<!-- test -->
<!-- foo --><div>baz</div><!-- bar
moo -->
<script><!-- alert(1) --></script>
<script>alert('<!--')</script>
<script>alert('<!-- foo -->')</script>
<script>alert('-->')</script>

View File

@ -0,0 +1,572 @@
{
"type": "Document",
"span": {
"start": 0,
"end": 193,
"ctxt": 0
},
"children": [
{
"type": "TokenAndSpan",
"span": {
"start": 0,
"end": 13,
"ctxt": 0
},
"token": {
"Comment": {
"data": " test "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 13,
"end": 14,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 14,
"end": 15,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 15,
"end": 27,
"ctxt": 0
},
"token": {
"Comment": {
"data": " foo "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 27,
"end": 32,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "div",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 32,
"end": 33,
"ctxt": 0
},
"token": {
"Character": {
"value": "b"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 33,
"end": 34,
"ctxt": 0
},
"token": {
"Character": {
"value": "a"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 34,
"end": 35,
"ctxt": 0
},
"token": {
"Character": {
"value": "z"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 35,
"end": 41,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "div",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 41,
"end": 58,
"ctxt": 0
},
"token": {
"Comment": {
"data": " bar\n\nmoo "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 58,
"end": 59,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 59,
"end": 67,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "script",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 67,
"end": 84,
"ctxt": 0
},
"token": {
"Comment": {
"data": " alert(1) "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 84,
"end": 93,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "script",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 93,
"end": 94,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 94,
"end": 102,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "script",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 102,
"end": 103,
"ctxt": 0
},
"token": {
"Character": {
"value": "a"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 103,
"end": 104,
"ctxt": 0
},
"token": {
"Character": {
"value": "l"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 104,
"end": 105,
"ctxt": 0
},
"token": {
"Character": {
"value": "e"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 105,
"end": 106,
"ctxt": 0
},
"token": {
"Character": {
"value": "r"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 106,
"end": 107,
"ctxt": 0
},
"token": {
"Character": {
"value": "t"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 107,
"end": 108,
"ctxt": 0
},
"token": {
"Character": {
"value": "("
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 108,
"end": 109,
"ctxt": 0
},
"token": {
"Character": {
"value": "'"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 109,
"end": 152,
"ctxt": 0
},
"token": {
"Comment": {
"data": "')</script>\n<script>alert('<!- foo "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 152,
"end": 153,
"ctxt": 0
},
"token": {
"Character": {
"value": "'"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 153,
"end": 154,
"ctxt": 0
},
"token": {
"Character": {
"value": ")"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 154,
"end": 163,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "script",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 163,
"end": 164,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 164,
"end": 172,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "script",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 172,
"end": 173,
"ctxt": 0
},
"token": {
"Character": {
"value": "a"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 173,
"end": 174,
"ctxt": 0
},
"token": {
"Character": {
"value": "l"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 174,
"end": 175,
"ctxt": 0
},
"token": {
"Character": {
"value": "e"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 175,
"end": 176,
"ctxt": 0
},
"token": {
"Character": {
"value": "r"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 176,
"end": 177,
"ctxt": 0
},
"token": {
"Character": {
"value": "t"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 177,
"end": 178,
"ctxt": 0
},
"token": {
"Character": {
"value": "("
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 178,
"end": 179,
"ctxt": 0
},
"token": {
"Character": {
"value": "'"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 179,
"end": 180,
"ctxt": 0
},
"token": {
"Character": {
"value": "-"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 180,
"end": 181,
"ctxt": 0
},
"token": {
"Character": {
"value": "-"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 181,
"end": 182,
"ctxt": 0
},
"token": {
"Character": {
"value": ">"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 182,
"end": 183,
"ctxt": 0
},
"token": {
"Character": {
"value": "'"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 183,
"end": 184,
"ctxt": 0
},
"token": {
"Character": {
"value": ")"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 184,
"end": 193,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "script",
"self_closing": false,
"attributes": []
}
}
}
]
}

View File

@ -0,0 +1,273 @@
x Document
,-[$DIR/tests/fixture/comments/input.html:1:1]
1 | ,-> <!-- test -->
2 | |
3 | | <!-- foo --><div>baz</div><!-- bar
4 | |
5 | | moo -->
6 | | <script><!-- alert(1) --></script>
7 | | <script>alert('<!--')</script>
8 | | <script>alert('<!-- foo -->')</script>
9 | `-> <script>alert('-->')</script>
`----
x Comment { data: Atom(' test ' type=inline) }
,-[$DIR/tests/fixture/comments/input.html:1:1]
1 | <!-- test -->
: ^^^^^^^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/comments/input.html:1:1]
1 | <!-- test -->
: ^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/comments/input.html:2:1]
2 |
: ^
3 | <!-- foo --><div>baz</div><!-- bar
`----
x Comment { data: Atom(' foo ' type=inline) }
,-[$DIR/tests/fixture/comments/input.html:3:1]
3 | <!-- foo --><div>baz</div><!-- bar
: ^^^^^^^^^^^^
`----
x StartTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/comments/input.html:3:1]
3 | <!-- foo --><div>baz</div><!-- bar
: ^^^^^
`----
x Character { value: 'b' }
,-[$DIR/tests/fixture/comments/input.html:3:1]
3 | <!-- foo --><div>baz</div><!-- bar
: ^
`----
x Character { value: 'a' }
,-[$DIR/tests/fixture/comments/input.html:3:1]
3 | <!-- foo --><div>baz</div><!-- bar
: ^
`----
x Character { value: 'z' }
,-[$DIR/tests/fixture/comments/input.html:3:1]
3 | <!-- foo --><div>baz</div><!-- bar
: ^
`----
x EndTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/comments/input.html:3:1]
3 | <!-- foo --><div>baz</div><!-- bar
: ^^^^^^
`----
x Comment { data: Atom(' bar
|
| moo ' type=dynamic) }
,-[$DIR/tests/fixture/comments/input.html:3:1]
3 | ,-> <!-- foo --><div>baz</div><!-- bar
4 | |
5 | `-> moo -->
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/comments/input.html:5:1]
5 | moo -->
: ^
6 | <script><!-- alert(1) --></script>
`----
x StartTag { tag_name: Atom('script' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/comments/input.html:6:1]
6 | <script><!-- alert(1) --></script>
: ^^^^^^^^
`----
x Comment { data: Atom(' alert(1) ' type=dynamic) }
,-[$DIR/tests/fixture/comments/input.html:6:1]
6 | <script><!-- alert(1) --></script>
: ^^^^^^^^^^^^^^^^^
`----
x EndTag { tag_name: Atom('script' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/comments/input.html:6:1]
6 | <script><!-- alert(1) --></script>
: ^^^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/comments/input.html:6:1]
6 | <script><!-- alert(1) --></script>
: ^
7 | <script>alert('<!--')</script>
`----
x StartTag { tag_name: Atom('script' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/comments/input.html:7:1]
7 | <script>alert('<!--')</script>
: ^^^^^^^^
`----
x Character { value: 'a' }
,-[$DIR/tests/fixture/comments/input.html:7:1]
7 | <script>alert('<!--')</script>
: ^
`----
x Character { value: 'l' }
,-[$DIR/tests/fixture/comments/input.html:7:1]
7 | <script>alert('<!--')</script>
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/comments/input.html:7:1]
7 | <script>alert('<!--')</script>
: ^
`----
x Character { value: 'r' }
,-[$DIR/tests/fixture/comments/input.html:7:1]
7 | <script>alert('<!--')</script>
: ^
`----
x Character { value: 't' }
,-[$DIR/tests/fixture/comments/input.html:7:1]
7 | <script>alert('<!--')</script>
: ^
`----
x Character { value: '(' }
,-[$DIR/tests/fixture/comments/input.html:7:1]
7 | <script>alert('<!--')</script>
: ^
`----
x Character { value: '\'' }
,-[$DIR/tests/fixture/comments/input.html:7:1]
7 | <script>alert('<!--')</script>
: ^
`----
x Comment { data: Atom('')</script>
| <script>alert('<!- foo ' type=dynamic) }
,-[$DIR/tests/fixture/comments/input.html:7:1]
7 | ,-> <script>alert('<!--')</script>
8 | `-> <script>alert('<!-- foo -->')</script>
`----
x Character { value: '\'' }
,-[$DIR/tests/fixture/comments/input.html:8:1]
8 | <script>alert('<!-- foo -->')</script>
: ^
`----
x Character { value: ')' }
,-[$DIR/tests/fixture/comments/input.html:8:1]
8 | <script>alert('<!-- foo -->')</script>
: ^
`----
x EndTag { tag_name: Atom('script' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/comments/input.html:8:1]
8 | <script>alert('<!-- foo -->')</script>
: ^^^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/comments/input.html:8:1]
8 | <script>alert('<!-- foo -->')</script>
: ^
9 | <script>alert('-->')</script>
`----
x StartTag { tag_name: Atom('script' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/comments/input.html:9:1]
9 | <script>alert('-->')</script>
: ^^^^^^^^
`----
x Character { value: 'a' }
,-[$DIR/tests/fixture/comments/input.html:9:1]
9 | <script>alert('-->')</script>
: ^
`----
x Character { value: 'l' }
,-[$DIR/tests/fixture/comments/input.html:9:1]
9 | <script>alert('-->')</script>
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/comments/input.html:9:1]
9 | <script>alert('-->')</script>
: ^
`----
x Character { value: 'r' }
,-[$DIR/tests/fixture/comments/input.html:9:1]
9 | <script>alert('-->')</script>
: ^
`----
x Character { value: 't' }
,-[$DIR/tests/fixture/comments/input.html:9:1]
9 | <script>alert('-->')</script>
: ^
`----
x Character { value: '(' }
,-[$DIR/tests/fixture/comments/input.html:9:1]
9 | <script>alert('-->')</script>
: ^
`----
x Character { value: '\'' }
,-[$DIR/tests/fixture/comments/input.html:9:1]
9 | <script>alert('-->')</script>
: ^
`----
x Character { value: '-' }
,-[$DIR/tests/fixture/comments/input.html:9:1]
9 | <script>alert('-->')</script>
: ^
`----
x Character { value: '-' }
,-[$DIR/tests/fixture/comments/input.html:9:1]
9 | <script>alert('-->')</script>
: ^
`----
x Character { value: '>' }
,-[$DIR/tests/fixture/comments/input.html:9:1]
9 | <script>alert('-->')</script>
: ^
`----
x Character { value: '\'' }
,-[$DIR/tests/fixture/comments/input.html:9:1]
9 | <script>alert('-->')</script>
: ^
`----
x Character { value: ')' }
,-[$DIR/tests/fixture/comments/input.html:9:1]
9 | <script>alert('-->')</script>
: ^
`----
x EndTag { tag_name: Atom('script' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/comments/input.html:9:1]
9 | <script>alert('-->')</script>
: ^^^^^^^^^
`----

View File

@ -0,0 +1 @@
<!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;

View File

@ -0,0 +1,507 @@
{
"type": "Document",
"span": {
"start": 0,
"end": 94,
"ctxt": 0
},
"children": [
{
"type": "TokenAndSpan",
"span": {
"start": 0,
"end": 15,
"ctxt": 0
},
"token": {
"Doctype": {
"name": "html",
"force_quirks": false,
"public_id": null,
"system_id": null
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 15,
"end": 35,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "meta",
"self_closing": false,
"attributes": [
{
"name": "charset",
"value": "utf-8"
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 35,
"end": 42,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "title",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 42,
"end": 47,
"ctxt": 0
},
"token": {
"Character": {
"value": "&"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 47,
"end": 48,
"ctxt": 0
},
"token": {
"Character": {
"value": "#"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 48,
"end": 49,
"ctxt": 0
},
"token": {
"Character": {
"value": "x"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 49,
"end": 50,
"ctxt": 0
},
"token": {
"Character": {
"value": "0"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 50,
"end": 51,
"ctxt": 0
},
"token": {
"Character": {
"value": "d"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 51,
"end": 52,
"ctxt": 0
},
"token": {
"Character": {
"value": ";"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 52,
"end": 60,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "title",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 60,
"end": 63,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "p",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 63,
"end": 64,
"ctxt": 0
},
"token": {
"Character": {
"value": "T"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 64,
"end": 65,
"ctxt": 0
},
"token": {
"Character": {
"value": "h"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 65,
"end": 66,
"ctxt": 0
},
"token": {
"Character": {
"value": "e"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 66,
"end": 67,
"ctxt": 0
},
"token": {
"Character": {
"value": "r"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 67,
"end": 68,
"ctxt": 0
},
"token": {
"Character": {
"value": "e"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 68,
"end": 69,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 69,
"end": 70,
"ctxt": 0
},
"token": {
"Character": {
"value": "s"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 70,
"end": 71,
"ctxt": 0
},
"token": {
"Character": {
"value": "h"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 71,
"end": 72,
"ctxt": 0
},
"token": {
"Character": {
"value": "o"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 72,
"end": 73,
"ctxt": 0
},
"token": {
"Character": {
"value": "u"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 73,
"end": 74,
"ctxt": 0
},
"token": {
"Character": {
"value": "l"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 74,
"end": 75,
"ctxt": 0
},
"token": {
"Character": {
"value": "d"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 75,
"end": 76,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 76,
"end": 77,
"ctxt": 0
},
"token": {
"Character": {
"value": "b"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 77,
"end": 78,
"ctxt": 0
},
"token": {
"Character": {
"value": "e"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 78,
"end": 79,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 79,
"end": 80,
"ctxt": 0
},
"token": {
"Character": {
"value": "a"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 80,
"end": 81,
"ctxt": 0
},
"token": {
"Character": {
"value": "n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 81,
"end": 82,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 82,
"end": 83,
"ctxt": 0
},
"token": {
"Character": {
"value": "e"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 83,
"end": 84,
"ctxt": 0
},
"token": {
"Character": {
"value": "r"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 84,
"end": 85,
"ctxt": 0
},
"token": {
"Character": {
"value": "r"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 85,
"end": 86,
"ctxt": 0
},
"token": {
"Character": {
"value": "o"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 86,
"end": 87,
"ctxt": 0
},
"token": {
"Character": {
"value": "r"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 87,
"end": 88,
"ctxt": 0
},
"token": {
"Character": {
"value": "."
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 88,
"end": 94,
"ctxt": 0
},
"token": {
"Character": {
"value": "\r"
}
}
}
]
}

View File

@ -0,0 +1,228 @@
x Document
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x Doctype { name: Some(Atom('html' type=inline)), force_quirks: false, public_id: None, system_id: None }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^^^^^^^^^^^^^^^
`----
x StartTag { tag_name: Atom('meta' type=static), self_closing: false, attributes: [Attribute { name: Atom('charset' type=inline), value: Some(Atom('utf-8' type=inline)) }] }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^^^^^^^^^^^^^^^^^^^^
`----
x StartTag { tag_name: Atom('title' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^^^^^^^
`----
x Character { value: '&' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^^^^^
`----
x Character { value: '#' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 'x' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: '0' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 'd' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: ';' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x EndTag { tag_name: Atom('title' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^^^^^^^^
`----
x StartTag { tag_name: Atom('p' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^^^
`----
x Character { value: 'T' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 'h' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 'r' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 's' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 'h' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 'o' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 'u' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 'l' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 'd' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 'b' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 'a' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 'n' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 'r' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 'r' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 'o' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: 'r' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: '.' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^
`----
x Character { value: '\r' }
,-[$DIR/tests/fixture/cr-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x0d;</title><p>There should be an error.&#x0d;
: ^^^^^^
`----

View File

@ -0,0 +1,105 @@
<!DOCTYPE html>
<html>
<body>
<h1>HTML Entity Example</h1>
<div>A space character: &AMP;</div>
<div>A space character: &amp;</div>
<div>A space character: &amp;;</div>
<div>A space character: &nbsp;</div>
<div>The less-than sign: &lt;</div>
<div>The greater-than sign: &gt;</div>
<div>The double quote sign: &quot;</div>
<div>The single quote sign: &apos;</div>
<div>The cent sign: &cent;</div>
<div>The pound sign: &pound;</div>
<div>The yen sign: &yen;</div>
<div>The euro sign: &euro;</div>
<div>The copyright sign: &copy;</div>
<div>The registered trade mark sign: &reg;</div>
<div>&reg;</div>
<div>&REG;</div>
<div>&reg;;</div>
<div>&reg</div>
<div>reg</div>
<div>&CounterClockwiseContourIntegral;</div>
<div>&&reg;</div>
<div>An a with a grave accent: a&#768;</div>
<div>An a with an acute accent: a&#769;</div>
<div>An a with a circumflex accent: a&#770;</div>
<div>An a with a tilde: a&#771;</div>
<div>An o with a grave accent: o&#768;</div>
<div>An o with an acute accent: o&#769;</div>
<div>An o with a circumflex accent: o&#770;</div>
<div>An o with a tilde: o&#771;</div>
<div>A space character: &&</div>
<div>I'm &notin; I tell you</div>
<div>I'm &not; I tell you</div>
<a href="http://lmgtfy.com/?l=1&amp;q=rick+roll">tired meme</a>
<a href="#" onclick="window.location='?l=1&amp;q=rick+roll';return false">
kablammo!
</a>
<div>&#x2715;</div>
<div>&#10005;</div>
<div></div>
<div>&#x24;</div>
<div>&#36;</div>
<div>&dollar;</div>
<div>&#q;</div>
<div>&#qq;</div>
<div>&#qqq;</div>
<div>&#x24;</div>
<div>&#X24;</div>
<div>&#xq;</div>
<div>&#xqq;</div>
<div>&#xqqq;</div>
<div>
&#x80 0x20AC EURO SIGN (€)
&#x82 0x201A SINGLE LOW-9 QUOTATION MARK ()
&#x83 0x0192 LATIN SMALL LETTER F WITH HOOK (ƒ)
&#x84 0x201E DOUBLE LOW-9 QUOTATION MARK („)
&#x85 0x2026 HORIZONTAL ELLIPSIS (…)
&#x86 0x2020 DAGGER (†)
&#x87 0x2021 DOUBLE DAGGER (‡)
&#x88 0x02C6 MODIFIER LETTER CIRCUMFLEX ACCENT (ˆ)
&#x89 0x2030 PER MILLE SIGN (‰)
&#x8A 0x0160 LATIN CAPITAL LETTER S WITH CARON (Š)
&#x8B 0x2039 SINGLE LEFT-POINTING ANGLE QUOTATION MARK ()
&#x8C 0x0152 LATIN CAPITAL LIGATURE OE (Œ)
&#x8E 0x017D LATIN CAPITAL LETTER Z WITH CARON (Ž)
&#x91 0x2018 LEFT SINGLE QUOTATION MARK ()
&#x92 0x2019 RIGHT SINGLE QUOTATION MARK ()
&#x93 0x201C LEFT DOUBLE QUOTATION MARK (“)
&#x94 0x201D RIGHT DOUBLE QUOTATION MARK (”)
&#x95 0x2022 BULLET (•)
&#x96 0x2013 EN DASH ()
&#x97 0x2014 EM DASH (—)
&#x98 0x02DC SMALL TILDE (˜)
&#x99 0x2122 TRADE MARK SIGN (™)
&#x9A 0x0161 LATIN SMALL LETTER S WITH CARON (š)
&#x9B 0x203A SINGLE RIGHT-POINTING ANGLE QUOTATION MARK ()
&#x9C 0x0153 LATIN SMALL LIGATURE OE (œ)
&#x9E 0x017E LATIN SMALL LETTER Z WITH CARON (ž)
&#x9F 0x0178 LATIN CAPITAL LETTER Y WITH DIAERESIS (Ÿ)
</div>
<div>I'm &notin; I tell you</div>
<div>I'm &notit; I tell you</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
<!DOCTYPE>
<html>
<body>
<a href=https://www.w3schools.com>This is a link</a>
</body>
</html>

View File

@ -0,0 +1,394 @@
{
"type": "Document",
"span": {
"start": 0,
"end": 95,
"ctxt": 0
},
"children": [
{
"type": "TokenAndSpan",
"span": {
"start": 0,
"end": 10,
"ctxt": 0
},
"token": {
"Doctype": {
"name": "<22>",
"force_quirks": true,
"public_id": null,
"system_id": null
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 10,
"end": 11,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 11,
"end": 17,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "html",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 17,
"end": 18,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 18,
"end": 24,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "body",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 24,
"end": 25,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 25,
"end": 26,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 26,
"end": 60,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "a",
"self_closing": false,
"attributes": [
{
"name": "href",
"value": "https://www.w3schools.com"
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 60,
"end": 61,
"ctxt": 0
},
"token": {
"Character": {
"value": "T"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 61,
"end": 62,
"ctxt": 0
},
"token": {
"Character": {
"value": "h"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 62,
"end": 63,
"ctxt": 0
},
"token": {
"Character": {
"value": "i"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 63,
"end": 64,
"ctxt": 0
},
"token": {
"Character": {
"value": "s"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 64,
"end": 65,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 65,
"end": 66,
"ctxt": 0
},
"token": {
"Character": {
"value": "i"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 66,
"end": 67,
"ctxt": 0
},
"token": {
"Character": {
"value": "s"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 67,
"end": 68,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 68,
"end": 69,
"ctxt": 0
},
"token": {
"Character": {
"value": "a"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 69,
"end": 70,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 70,
"end": 71,
"ctxt": 0
},
"token": {
"Character": {
"value": "l"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 71,
"end": 72,
"ctxt": 0
},
"token": {
"Character": {
"value": "i"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 72,
"end": 73,
"ctxt": 0
},
"token": {
"Character": {
"value": "n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 73,
"end": 74,
"ctxt": 0
},
"token": {
"Character": {
"value": "k"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 74,
"end": 78,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "a",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 78,
"end": 79,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 79,
"end": 80,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 80,
"end": 87,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "body",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 87,
"end": 88,
"ctxt": 0
},
"token": {
"Character": {
"value": "\n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 88,
"end": 95,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "html",
"self_closing": false,
"attributes": []
}
}
}
]
}

View File

@ -0,0 +1,185 @@
x Document
,-[$DIR/tests/fixture/missing-doctype-name/input.html:1:1]
1 | ,-> <!DOCTYPE>
2 | | <html>
3 | | <body>
4 | |
5 | | <a href=https://www.w3schools.com>This is a link</a>
6 | |
7 | | </body>
8 | `-> </html>
`----
x Doctype { name: Some(Atom('<27>' type=inline)), force_quirks: true, public_id: None, system_id: None }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:1:1]
1 | <!DOCTYPE>
: ^^^^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:1:1]
1 | <!DOCTYPE>
: ^
2 | <html>
`----
x StartTag { tag_name: Atom('html' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:2:1]
2 | <html>
: ^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:2:1]
2 | <html>
: ^
3 | <body>
`----
x StartTag { tag_name: Atom('body' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:3:1]
3 | <body>
: ^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:3:1]
3 | <body>
: ^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:4:1]
4 |
: ^
5 | <a href=https://www.w3schools.com>This is a link</a>
`----
x StartTag { tag_name: Atom('a' type=inline), self_closing: false, attributes: [Attribute { name: Atom('href' type=inline), value: Some(Atom('https://www.w3schools.com' type=dynamic)) }] }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x Character { value: 'T' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: 'h' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: 'i' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: 's' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: 'i' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: 's' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: 'a' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: 'l' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: 'i' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: 'n' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: 'k' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x EndTag { tag_name: Atom('a' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:5:1]
5 | <a href=https://www.w3schools.com>This is a link</a>
: ^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:6:1]
6 |
: ^
7 | </body>
`----
x EndTag { tag_name: Atom('body' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:7:1]
7 | </body>
: ^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:7:1]
7 | </body>
: ^
8 | </html>
`----
x EndTag { tag_name: Atom('html' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/missing-doctype-name/input.html:8:1]
8 | </html>
: ^^^^^^^
`----

View File

@ -0,0 +1 @@
<!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;

View File

@ -0,0 +1,559 @@
{
"type": "Document",
"span": {
"start": 0,
"end": 102,
"ctxt": 0
},
"children": [
{
"type": "TokenAndSpan",
"span": {
"start": 0,
"end": 15,
"ctxt": 0
},
"token": {
"Doctype": {
"name": "html",
"force_quirks": false,
"public_id": null,
"system_id": null
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 15,
"end": 35,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "meta",
"self_closing": false,
"attributes": [
{
"name": "charset",
"value": "utf-8"
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 35,
"end": 42,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "title",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 42,
"end": 47,
"ctxt": 0
},
"token": {
"Character": {
"value": "&"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 47,
"end": 48,
"ctxt": 0
},
"token": {
"Character": {
"value": "#"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 48,
"end": 49,
"ctxt": 0
},
"token": {
"Character": {
"value": "x"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 49,
"end": 50,
"ctxt": 0
},
"token": {
"Character": {
"value": "1"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 50,
"end": 51,
"ctxt": 0
},
"token": {
"Character": {
"value": "1"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 51,
"end": 52,
"ctxt": 0
},
"token": {
"Character": {
"value": "0"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 52,
"end": 53,
"ctxt": 0
},
"token": {
"Character": {
"value": "0"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 53,
"end": 54,
"ctxt": 0
},
"token": {
"Character": {
"value": "0"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 54,
"end": 55,
"ctxt": 0
},
"token": {
"Character": {
"value": "0"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 55,
"end": 56,
"ctxt": 0
},
"token": {
"Character": {
"value": ";"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 56,
"end": 64,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "title",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 64,
"end": 67,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "p",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 67,
"end": 68,
"ctxt": 0
},
"token": {
"Character": {
"value": "T"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 68,
"end": 69,
"ctxt": 0
},
"token": {
"Character": {
"value": "h"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 69,
"end": 70,
"ctxt": 0
},
"token": {
"Character": {
"value": "e"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 70,
"end": 71,
"ctxt": 0
},
"token": {
"Character": {
"value": "r"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 71,
"end": 72,
"ctxt": 0
},
"token": {
"Character": {
"value": "e"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 72,
"end": 73,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 73,
"end": 74,
"ctxt": 0
},
"token": {
"Character": {
"value": "s"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 74,
"end": 75,
"ctxt": 0
},
"token": {
"Character": {
"value": "h"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 75,
"end": 76,
"ctxt": 0
},
"token": {
"Character": {
"value": "o"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 76,
"end": 77,
"ctxt": 0
},
"token": {
"Character": {
"value": "u"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 77,
"end": 78,
"ctxt": 0
},
"token": {
"Character": {
"value": "l"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 78,
"end": 79,
"ctxt": 0
},
"token": {
"Character": {
"value": "d"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 79,
"end": 80,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 80,
"end": 81,
"ctxt": 0
},
"token": {
"Character": {
"value": "b"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 81,
"end": 82,
"ctxt": 0
},
"token": {
"Character": {
"value": "e"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 82,
"end": 83,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 83,
"end": 84,
"ctxt": 0
},
"token": {
"Character": {
"value": "a"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 84,
"end": 85,
"ctxt": 0
},
"token": {
"Character": {
"value": "n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 85,
"end": 86,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 86,
"end": 87,
"ctxt": 0
},
"token": {
"Character": {
"value": "e"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 87,
"end": 88,
"ctxt": 0
},
"token": {
"Character": {
"value": "r"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 88,
"end": 89,
"ctxt": 0
},
"token": {
"Character": {
"value": "r"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 89,
"end": 90,
"ctxt": 0
},
"token": {
"Character": {
"value": "o"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 90,
"end": 91,
"ctxt": 0
},
"token": {
"Character": {
"value": "r"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 91,
"end": 92,
"ctxt": 0
},
"token": {
"Character": {
"value": "."
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 92,
"end": 102,
"ctxt": 0
},
"token": {
"Character": {
"value": "<22>"
}
}
}
]
}

View File

@ -0,0 +1,252 @@
x Document
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x Doctype { name: Some(Atom('html' type=inline)), force_quirks: false, public_id: None, system_id: None }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^^^^^^^^^^^^^^^
`----
x StartTag { tag_name: Atom('meta' type=static), self_closing: false, attributes: [Attribute { name: Atom('charset' type=inline), value: Some(Atom('utf-8' type=inline)) }] }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^^^^^^^^^^^^^^^^^^^^
`----
x StartTag { tag_name: Atom('title' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^^^^^^^
`----
x Character { value: '&' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^^^^^
`----
x Character { value: '#' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: 'x' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: '1' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: '1' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: '0' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: '0' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: '0' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: '0' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: ';' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x EndTag { tag_name: Atom('title' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^^^^^^^^
`----
x StartTag { tag_name: Atom('p' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^^^
`----
x Character { value: 'T' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: 'h' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: 'r' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: 's' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: 'h' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: 'o' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: 'u' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: 'l' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: 'd' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: 'b' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: 'a' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: 'n' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: 'r' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: 'r' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: 'o' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: 'r' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: '.' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^
`----
x Character { value: '<27>' }
,-[$DIR/tests/fixture/range-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x110000;</title><p>There should be an error.&#x110000;
: ^^^^^^^^^^
`----

View File

@ -0,0 +1,26 @@
<div></div>
<div><div></div></div>
<div></div><div></div>
<br>
<br />
<h:ællæ></h:ællæ>
<html ></html>
<some-tag-1></some-tag-1><some-tag-2></some-tag-2>
<a href="test.html"><div>hey</div></a>
<CUSTOM-TAG></CUSTOM-TAG><div>Hello :)</div>
<div>
test
</div>
<div></div test="a">
<div data-test="a"></div data-test="a">
<br data-test="a" />
<br data-test="a" >
<br data-test="a">
<div
>
Test
</div
>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,536 @@
x Document
,-[$DIR/tests/fixture/tag/basic/input.html:1:1]
1 | ,-> <div></div>
2 | | <div><div></div></div>
3 | | <div></div><div></div>
4 | | <br>
5 | | <br />
6 | | <h:ællæ></h:ællæ>
7 | | <html ⚡></html>
8 | | <some-tag-1></some-tag-1><some-tag-2></some-tag-2>
9 | | <a href="test.html"><div>hey</div></a>
10 | | <CUSTOM-TAG></CUSTOM-TAG><div>Hello :)</div>
11 | | <div>
12 | |
13 | | test
14 | |
15 | | </div>
16 | |
17 | | <div></div test="a">
18 | | <div data-test="a"></div data-test="a">
19 | | <br data-test="a" />
20 | | <br data-test="a" >
21 | | <br data-test="a">
22 | | <div
23 | | >
24 | | Test
25 | | </div
26 | `-> >
`----
x StartTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:1:1]
1 | <div></div>
: ^^^^^
`----
x EndTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:1:1]
1 | <div></div>
: ^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:1:1]
1 | <div></div>
: ^
2 | <div><div></div></div>
`----
x StartTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:2:1]
2 | <div><div></div></div>
: ^^^^^
`----
x StartTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:2:1]
2 | <div><div></div></div>
: ^^^^^
`----
x EndTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:2:1]
2 | <div><div></div></div>
: ^^^^^^
`----
x EndTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:2:1]
2 | <div><div></div></div>
: ^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:2:1]
2 | <div><div></div></div>
: ^
3 | <div></div><div></div>
`----
x StartTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:3:1]
3 | <div></div><div></div>
: ^^^^^
`----
x EndTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:3:1]
3 | <div></div><div></div>
: ^^^^^^
`----
x StartTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:3:1]
3 | <div></div><div></div>
: ^^^^^
`----
x EndTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:3:1]
3 | <div></div><div></div>
: ^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:3:1]
3 | <div></div><div></div>
: ^
4 | <br>
`----
x StartTag { tag_name: Atom('br' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:4:1]
4 | <br>
: ^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:4:1]
4 | <br>
: ^
5 | <br />
`----
x StartTag { tag_name: Atom('br' type=inline), self_closing: true, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:5:1]
5 | <br />
: ^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:5:1]
5 | <br />
: ^
6 | <h:ællæ></h:ællæ>
`----
x StartTag { tag_name: Atom('h:ællæ' type=dynamic), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:6:1]
6 | <h:ællæ></h:ællæ>
: ^^^^^^^^^^
`----
x EndTag { tag_name: Atom('h:ællæ' type=dynamic), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:6:1]
6 | <h:ællæ></h:ællæ>
: ^^^^^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:6:1]
6 | <h:ællæ></h:ællæ>
: ^
7 | <html ⚡></html>
`----
x StartTag { tag_name: Atom('html' type=inline), self_closing: false, attributes: [Attribute { name: Atom('⚡' type=inline), value: None }] }
,-[$DIR/tests/fixture/tag/basic/input.html:7:1]
7 | <html ⚡></html>
: ^^^^^^^^^^
`----
x EndTag { tag_name: Atom('html' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:7:1]
7 | <html ⚡></html>
: ^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:7:1]
7 | <html ⚡></html>
: ^
8 | <some-tag-1></some-tag-1><some-tag-2></some-tag-2>
`----
x StartTag { tag_name: Atom('some-tag-1' type=dynamic), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:8:1]
8 | <some-tag-1></some-tag-1><some-tag-2></some-tag-2>
: ^^^^^^^^^^^^
`----
x EndTag { tag_name: Atom('some-tag-1' type=dynamic), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:8:1]
8 | <some-tag-1></some-tag-1><some-tag-2></some-tag-2>
: ^^^^^^^^^^^^^
`----
x StartTag { tag_name: Atom('some-tag-2' type=dynamic), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:8:1]
8 | <some-tag-1></some-tag-1><some-tag-2></some-tag-2>
: ^^^^^^^^^^^^
`----
x EndTag { tag_name: Atom('some-tag-2' type=dynamic), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:8:1]
8 | <some-tag-1></some-tag-1><some-tag-2></some-tag-2>
: ^^^^^^^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:8:1]
8 | <some-tag-1></some-tag-1><some-tag-2></some-tag-2>
: ^
9 | <a href="test.html"><div>hey</div></a>
`----
x StartTag { tag_name: Atom('a' type=inline), self_closing: false, attributes: [Attribute { name: Atom('href' type=inline), value: Some(Atom('test.html' type=dynamic)) }] }
,-[$DIR/tests/fixture/tag/basic/input.html:9:1]
9 | <a href="test.html"><div>hey</div></a>
: ^^^^^^^^^^^^^^^^^^^^
`----
x StartTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:9:1]
9 | <a href="test.html"><div>hey</div></a>
: ^^^^^
`----
x Character { value: 'h' }
,-[$DIR/tests/fixture/tag/basic/input.html:9:1]
9 | <a href="test.html"><div>hey</div></a>
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/tag/basic/input.html:9:1]
9 | <a href="test.html"><div>hey</div></a>
: ^
`----
x Character { value: 'y' }
,-[$DIR/tests/fixture/tag/basic/input.html:9:1]
9 | <a href="test.html"><div>hey</div></a>
: ^
`----
x EndTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:9:1]
9 | <a href="test.html"><div>hey</div></a>
: ^^^^^^
`----
x EndTag { tag_name: Atom('a' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:9:1]
9 | <a href="test.html"><div>hey</div></a>
: ^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:9:1]
9 | <a href="test.html"><div>hey</div></a>
: ^
10 | <CUSTOM-TAG></CUSTOM-TAG><div>Hello :)</div>
`----
x StartTag { tag_name: Atom('custom-tag' type=dynamic), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:10:1]
10 | <CUSTOM-TAG></CUSTOM-TAG><div>Hello :)</div>
: ^^^^^^^^^^^^
`----
x EndTag { tag_name: Atom('custom-tag' type=dynamic), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:10:1]
10 | <CUSTOM-TAG></CUSTOM-TAG><div>Hello :)</div>
: ^^^^^^^^^^^^^
`----
x StartTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:10:1]
10 | <CUSTOM-TAG></CUSTOM-TAG><div>Hello :)</div>
: ^^^^^
`----
x Character { value: 'H' }
,-[$DIR/tests/fixture/tag/basic/input.html:10:1]
10 | <CUSTOM-TAG></CUSTOM-TAG><div>Hello :)</div>
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/tag/basic/input.html:10:1]
10 | <CUSTOM-TAG></CUSTOM-TAG><div>Hello :)</div>
: ^
`----
x Character { value: 'l' }
,-[$DIR/tests/fixture/tag/basic/input.html:10:1]
10 | <CUSTOM-TAG></CUSTOM-TAG><div>Hello :)</div>
: ^
`----
x Character { value: 'l' }
,-[$DIR/tests/fixture/tag/basic/input.html:10:1]
10 | <CUSTOM-TAG></CUSTOM-TAG><div>Hello :)</div>
: ^
`----
x Character { value: 'o' }
,-[$DIR/tests/fixture/tag/basic/input.html:10:1]
10 | <CUSTOM-TAG></CUSTOM-TAG><div>Hello :)</div>
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/tag/basic/input.html:10:1]
10 | <CUSTOM-TAG></CUSTOM-TAG><div>Hello :)</div>
: ^
`----
x Character { value: ':' }
,-[$DIR/tests/fixture/tag/basic/input.html:10:1]
10 | <CUSTOM-TAG></CUSTOM-TAG><div>Hello :)</div>
: ^
`----
x Character { value: ')' }
,-[$DIR/tests/fixture/tag/basic/input.html:10:1]
10 | <CUSTOM-TAG></CUSTOM-TAG><div>Hello :)</div>
: ^
`----
x EndTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:10:1]
10 | <CUSTOM-TAG></CUSTOM-TAG><div>Hello :)</div>
: ^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:10:1]
10 | <CUSTOM-TAG></CUSTOM-TAG><div>Hello :)</div>
: ^
11 | <div>
`----
x StartTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:11:1]
11 | <div>
: ^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:11:1]
11 | <div>
: ^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:12:1]
12 |
: ^
13 | test
`----
x Character { value: 't' }
,-[$DIR/tests/fixture/tag/basic/input.html:13:1]
13 | test
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/tag/basic/input.html:13:1]
13 | test
: ^
`----
x Character { value: 's' }
,-[$DIR/tests/fixture/tag/basic/input.html:13:1]
13 | test
: ^
`----
x Character { value: 't' }
,-[$DIR/tests/fixture/tag/basic/input.html:13:1]
13 | test
: ^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:13:1]
13 | test
: ^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:14:1]
14 |
: ^
15 | </div>
`----
x EndTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:15:1]
15 | </div>
: ^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:15:1]
15 | </div>
: ^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:16:1]
16 |
: ^
17 | <div></div test="a">
`----
x StartTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:17:1]
17 | <div></div test="a">
: ^^^^^
`----
x EndTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [Attribute { name: Atom('test' type=inline), value: Some(Atom('a' type=inline)) }] }
,-[$DIR/tests/fixture/tag/basic/input.html:17:1]
17 | <div></div test="a">
: ^^^^^^^^^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:17:1]
17 | <div></div test="a">
: ^
18 | <div data-test="a"></div data-test="a">
`----
x StartTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [Attribute { name: Atom('data-test' type=dynamic), value: Some(Atom('a' type=inline)) }] }
,-[$DIR/tests/fixture/tag/basic/input.html:18:1]
18 | <div data-test="a"></div data-test="a">
: ^^^^^^^^^^^^^^^^^^^
`----
x EndTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [Attribute { name: Atom('data-test' type=dynamic), value: Some(Atom('a' type=inline)) }] }
,-[$DIR/tests/fixture/tag/basic/input.html:18:1]
18 | <div data-test="a"></div data-test="a">
: ^^^^^^^^^^^^^^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:18:1]
18 | <div data-test="a"></div data-test="a">
: ^
19 | <br data-test="a" />
`----
x StartTag { tag_name: Atom('br' type=inline), self_closing: true, attributes: [Attribute { name: Atom('data-test' type=dynamic), value: Some(Atom('a' type=inline)) }] }
,-[$DIR/tests/fixture/tag/basic/input.html:19:1]
19 | <br data-test="a" />
: ^^^^^^^^^^^^^^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:19:1]
19 | <br data-test="a" />
: ^
20 | <br data-test="a" >
`----
x StartTag { tag_name: Atom('br' type=inline), self_closing: false, attributes: [Attribute { name: Atom('data-test' type=dynamic), value: Some(Atom('a' type=inline)) }] }
,-[$DIR/tests/fixture/tag/basic/input.html:20:1]
20 | <br data-test="a" >
: ^^^^^^^^^^^^^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:20:1]
20 | <br data-test="a" >
: ^
21 | <br data-test="a">
`----
x StartTag { tag_name: Atom('br' type=inline), self_closing: false, attributes: [Attribute { name: Atom('data-test' type=dynamic), value: Some(Atom('a' type=inline)) }] }
,-[$DIR/tests/fixture/tag/basic/input.html:21:1]
21 | <br data-test="a">
: ^^^^^^^^^^^^^^^^^^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:21:1]
21 | <br data-test="a">
: ^
22 | <div
`----
x StartTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:22:1]
22 | ,-> <div
23 | `-> >
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:23:1]
23 | >
: ^
24 | Test
`----
x Character { value: 'T' }
,-[$DIR/tests/fixture/tag/basic/input.html:24:1]
24 | Test
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/tag/basic/input.html:24:1]
24 | Test
: ^
`----
x Character { value: 's' }
,-[$DIR/tests/fixture/tag/basic/input.html:24:1]
24 | Test
: ^
`----
x Character { value: 't' }
,-[$DIR/tests/fixture/tag/basic/input.html:24:1]
24 | Test
: ^
`----
x Character { value: '\n' }
,-[$DIR/tests/fixture/tag/basic/input.html:24:1]
24 | Test
: ^
25 | </div
`----
x EndTag { tag_name: Atom('div' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/tag/basic/input.html:25:1]
25 | ,-> </div
26 | `-> >
`----

View File

@ -0,0 +1,24 @@
<popup-info img="img/alt.png" data-text="Your card validation code (CVC)
is an extra security feature — it is the last 3 or 4 numbers on the
back of your card."></popup-info>
<custom-square l="100" c="red"></custom-square>
<app-drawer open disabled></app-drawer>
<share-buttons>
<social-button type="twitter"><a href="...">Twitter</a></social-button>
<social-button type="fb"><a href="...">Facebook</a></social-button>
<social-button type="plus"><a href="...">G+</a></social-button>
</share-buttons>
<x-foo-with-markup>
<b>I'm an x-foo-with-markup!</b>
</x-foo-with-markup>
<template id="x-foo-from-template">
<style>
p { color: green; }
</style>
<p>I'm in Shadow DOM. My markup was stamped from a &lt;template&gt;.</p>
</template>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,27 @@
<template id="element-details-template">
<style>
details {font-family: "Open Sans Light", Helvetica, Arial, sans-serif }
.name {font-weight: bold; color: #217ac0; font-size: 120% }
h4 {
margin: 10px 0 -8px 0;
background: #217ac0;
color: white;
padding: 2px 6px;
border: 1px solid #cee9f9;
border-radius: 4px;
}
.attributes { margin-left: 22px; font-size: 90% }
.attributes p { margin-left: 16px; font-style: italic }
</style>
<details>
<summary>
<code class="name">&lt;<slot name="element-name">NEED NAME</slot>&gt;</code>
<i class="desc"><slot name="description">NEED DESCRIPTION</slot></i>
</summary>
<div class="attributes">
<h4>Attributes</h4>
<slot name="attributes"><p>None</p></slot>
</div>
</details>
<hr>
</template>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
<!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;

View File

@ -0,0 +1,533 @@
{
"type": "Document",
"span": {
"start": 0,
"end": 98,
"ctxt": 0
},
"children": [
{
"type": "TokenAndSpan",
"span": {
"start": 0,
"end": 15,
"ctxt": 0
},
"token": {
"Doctype": {
"name": "html",
"force_quirks": false,
"public_id": null,
"system_id": null
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 15,
"end": 35,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "meta",
"self_closing": false,
"attributes": [
{
"name": "charset",
"value": "utf-8"
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 35,
"end": 42,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "title",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 42,
"end": 47,
"ctxt": 0
},
"token": {
"Character": {
"value": "&"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 47,
"end": 48,
"ctxt": 0
},
"token": {
"Character": {
"value": "#"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 48,
"end": 49,
"ctxt": 0
},
"token": {
"Character": {
"value": "x"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 49,
"end": 50,
"ctxt": 0
},
"token": {
"Character": {
"value": "0"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 50,
"end": 51,
"ctxt": 0
},
"token": {
"Character": {
"value": "0"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 51,
"end": 52,
"ctxt": 0
},
"token": {
"Character": {
"value": "0"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 52,
"end": 53,
"ctxt": 0
},
"token": {
"Character": {
"value": "B"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 53,
"end": 54,
"ctxt": 0
},
"token": {
"Character": {
"value": ";"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 54,
"end": 62,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "title",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 62,
"end": 65,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "p",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 65,
"end": 66,
"ctxt": 0
},
"token": {
"Character": {
"value": "T"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 66,
"end": 67,
"ctxt": 0
},
"token": {
"Character": {
"value": "h"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 67,
"end": 68,
"ctxt": 0
},
"token": {
"Character": {
"value": "e"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 68,
"end": 69,
"ctxt": 0
},
"token": {
"Character": {
"value": "r"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 69,
"end": 70,
"ctxt": 0
},
"token": {
"Character": {
"value": "e"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 70,
"end": 71,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 71,
"end": 72,
"ctxt": 0
},
"token": {
"Character": {
"value": "s"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 72,
"end": 73,
"ctxt": 0
},
"token": {
"Character": {
"value": "h"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 73,
"end": 74,
"ctxt": 0
},
"token": {
"Character": {
"value": "o"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 74,
"end": 75,
"ctxt": 0
},
"token": {
"Character": {
"value": "u"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 75,
"end": 76,
"ctxt": 0
},
"token": {
"Character": {
"value": "l"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 76,
"end": 77,
"ctxt": 0
},
"token": {
"Character": {
"value": "d"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 77,
"end": 78,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 78,
"end": 79,
"ctxt": 0
},
"token": {
"Character": {
"value": "b"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 79,
"end": 80,
"ctxt": 0
},
"token": {
"Character": {
"value": "e"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 80,
"end": 81,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 81,
"end": 82,
"ctxt": 0
},
"token": {
"Character": {
"value": "a"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 82,
"end": 83,
"ctxt": 0
},
"token": {
"Character": {
"value": "n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 83,
"end": 84,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 84,
"end": 85,
"ctxt": 0
},
"token": {
"Character": {
"value": "e"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 85,
"end": 86,
"ctxt": 0
},
"token": {
"Character": {
"value": "r"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 86,
"end": 87,
"ctxt": 0
},
"token": {
"Character": {
"value": "r"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 87,
"end": 88,
"ctxt": 0
},
"token": {
"Character": {
"value": "o"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 88,
"end": 89,
"ctxt": 0
},
"token": {
"Character": {
"value": "r"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 89,
"end": 90,
"ctxt": 0
},
"token": {
"Character": {
"value": "."
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 90,
"end": 98,
"ctxt": 0
},
"token": {
"Character": {
"value": "\u000b"
}
}
}
]
}

View File

@ -0,0 +1,240 @@
x Document
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x Doctype { name: Some(Atom('html' type=inline)), force_quirks: false, public_id: None, system_id: None }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^^^^^^^^^^^^^^^
`----
x StartTag { tag_name: Atom('meta' type=static), self_closing: false, attributes: [Attribute { name: Atom('charset' type=inline), value: Some(Atom('utf-8' type=inline)) }] }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^^^^^^^^^^^^^^^^^^^^
`----
x StartTag { tag_name: Atom('title' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^^^^^^^
`----
x Character { value: '&' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^^^^^
`----
x Character { value: '#' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 'x' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: '0' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: '0' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: '0' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 'B' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: ';' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x EndTag { tag_name: Atom('title' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^^^^^^^^
`----
x StartTag { tag_name: Atom('p' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^^^
`----
x Character { value: 'T' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 'h' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 'r' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 's' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 'h' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 'o' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 'u' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 'l' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 'd' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 'b' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 'a' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 'n' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 'r' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 'r' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 'o' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: 'r' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: '.' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^
`----
x Character { value: '\u{b}' }
,-[$DIR/tests/fixture/u000b-charref-novalid/html/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#x000B;</title><p>There should be an error.&#x000B;
: ^^^^^^^^
`----

View File

@ -0,0 +1 @@
<!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;

View File

@ -0,0 +1,533 @@
{
"type": "Document",
"span": {
"start": 0,
"end": 98,
"ctxt": 0
},
"children": [
{
"type": "TokenAndSpan",
"span": {
"start": 0,
"end": 15,
"ctxt": 0
},
"token": {
"Doctype": {
"name": "html",
"force_quirks": false,
"public_id": null,
"system_id": null
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 15,
"end": 35,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "meta",
"self_closing": false,
"attributes": [
{
"name": "charset",
"value": "utf-8"
}
]
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 35,
"end": 42,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "title",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 42,
"end": 47,
"ctxt": 0
},
"token": {
"Character": {
"value": "&"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 47,
"end": 48,
"ctxt": 0
},
"token": {
"Character": {
"value": "#"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 48,
"end": 49,
"ctxt": 0
},
"token": {
"Character": {
"value": "x"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 49,
"end": 50,
"ctxt": 0
},
"token": {
"Character": {
"value": "f"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 50,
"end": 51,
"ctxt": 0
},
"token": {
"Character": {
"value": "d"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 51,
"end": 52,
"ctxt": 0
},
"token": {
"Character": {
"value": "d"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 52,
"end": 53,
"ctxt": 0
},
"token": {
"Character": {
"value": "0"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 53,
"end": 54,
"ctxt": 0
},
"token": {
"Character": {
"value": ";"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 54,
"end": 62,
"ctxt": 0
},
"token": {
"EndTag": {
"tag_name": "title",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 62,
"end": 65,
"ctxt": 0
},
"token": {
"StartTag": {
"tag_name": "p",
"self_closing": false,
"attributes": []
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 65,
"end": 66,
"ctxt": 0
},
"token": {
"Character": {
"value": "T"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 66,
"end": 67,
"ctxt": 0
},
"token": {
"Character": {
"value": "h"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 67,
"end": 68,
"ctxt": 0
},
"token": {
"Character": {
"value": "e"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 68,
"end": 69,
"ctxt": 0
},
"token": {
"Character": {
"value": "r"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 69,
"end": 70,
"ctxt": 0
},
"token": {
"Character": {
"value": "e"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 70,
"end": 71,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 71,
"end": 72,
"ctxt": 0
},
"token": {
"Character": {
"value": "s"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 72,
"end": 73,
"ctxt": 0
},
"token": {
"Character": {
"value": "h"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 73,
"end": 74,
"ctxt": 0
},
"token": {
"Character": {
"value": "o"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 74,
"end": 75,
"ctxt": 0
},
"token": {
"Character": {
"value": "u"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 75,
"end": 76,
"ctxt": 0
},
"token": {
"Character": {
"value": "l"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 76,
"end": 77,
"ctxt": 0
},
"token": {
"Character": {
"value": "d"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 77,
"end": 78,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 78,
"end": 79,
"ctxt": 0
},
"token": {
"Character": {
"value": "b"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 79,
"end": 80,
"ctxt": 0
},
"token": {
"Character": {
"value": "e"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 80,
"end": 81,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 81,
"end": 82,
"ctxt": 0
},
"token": {
"Character": {
"value": "a"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 82,
"end": 83,
"ctxt": 0
},
"token": {
"Character": {
"value": "n"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 83,
"end": 84,
"ctxt": 0
},
"token": {
"Character": {
"value": " "
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 84,
"end": 85,
"ctxt": 0
},
"token": {
"Character": {
"value": "e"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 85,
"end": 86,
"ctxt": 0
},
"token": {
"Character": {
"value": "r"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 86,
"end": 87,
"ctxt": 0
},
"token": {
"Character": {
"value": "r"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 87,
"end": 88,
"ctxt": 0
},
"token": {
"Character": {
"value": "o"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 88,
"end": 89,
"ctxt": 0
},
"token": {
"Character": {
"value": "r"
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 89,
"end": 90,
"ctxt": 0
},
"token": {
"Character": {
"value": "."
}
}
},
{
"type": "TokenAndSpan",
"span": {
"start": 90,
"end": 98,
"ctxt": 0
},
"token": {
"Character": {
"value": "﷐"
}
}
}
]
}

View File

@ -0,0 +1,240 @@
x Document
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
x Doctype { name: Some(Atom('html' type=inline)), force_quirks: false, public_id: None, system_id: None }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^^^^^^^^^^^^^^^
`----
x StartTag { tag_name: Atom('meta' type=static), self_closing: false, attributes: [Attribute { name: Atom('charset' type=inline), value: Some(Atom('utf-8' type=inline)) }] }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^^^^^^^^^^^^^^^^^^^^
`----
x StartTag { tag_name: Atom('title' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^^^^^^^
`----
x Character { value: '&' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^^^^^
`----
x Character { value: '#' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'x' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'f' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'd' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'd' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: '0' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: ';' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x EndTag { tag_name: Atom('title' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^^^^^^^^
`----
x StartTag { tag_name: Atom('p' type=inline), self_closing: false, attributes: [] }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^^^
`----
x Character { value: 'T' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'h' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'r' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 's' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'h' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'o' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'u' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'l' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'd' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'b' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'a' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'n' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: ' ' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'e' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'r' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'r' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'o' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: 'r' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: '.' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^
`----
x Character { value: '\u{fdd0}' }
,-[$DIR/tests/fixture/unassigned-charref-novalid/input.html:1:1]
1 | <!doctype html><meta charset=utf-8><title>&amp;#xfdd0;</title><p>There should be an error.&#xfdd0;
: ^^^^^^^^
`----