///|
fn SourceTokenizer::parse_doctype(self : SourceTokenizer) -> Unit {
self.pos += "') | None => None
Some(ch) if ch.is_ascii_whitespace() => {
self.skip_ascii_whitespace()
None
}
_ => Some(self.pos)
}
let name_start = self.pos
while !self.is_eof() {
match self.current().unwrap() {
'>' => break
ch if ch.is_ascii_whitespace() => break
_ => ignore(self.advance_char())
}
}
let (name, name_errors) = @impl.parse_lower_name_value_replacing_nulls(
self.input,
name_start,
self.pos,
)
let ids_start = self.pos
while !self.is_eof() && !self.starts_with(">") {
ignore(self.advance_char())
}
let external = @impl.parse_doctype_external(
self.input[ids_start:self.pos],
self.starts_with(">"),
)
let public_id = external.public_id
let system_id = external.system_id
let has_external_error = !external.errors.is_empty()
let eof_doctype = name != "" && !has_external_error && !self.starts_with(">")
match missing_before_name {
Some(pos) => self.error_at("missing-whitespace-before-doctype-name", pos)
None => ()
}
for error in name_errors {
self.error_at(error.code, error.offset)
}
if name == "" {
if self.starts_with(">") {
self.error_at("expected-doctype-name-but-got-right-bracket", self.pos)
} else {
self.error_at_eof("eof-in-doctype")
}
} else {
for error in external.errors {
self.error_at(error.code, ids_start + error.offset)
}
}
if eof_doctype {
self.error_at_eof("eof-in-doctype")
}
if self.starts_with(">") {
self.pos += 1
}
let force_quirks = name == "" || external.force_quirks || eof_doctype
self.tokens.push(DoctypeToken({ name, public_id, system_id, force_quirks, }))
}