summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/emitter.rs25
-rw-r--r--src/machine.rs6
2 files changed, 31 insertions, 0 deletions
diff --git a/src/emitter.rs b/src/emitter.rs
index 69baec2..ed8e978 100644
--- a/src/emitter.rs
+++ b/src/emitter.rs
@@ -158,6 +158,11 @@ pub trait Emitter<O> {
/// If the current token is not a doctype, this method may panic.
fn init_doctype_name(&mut self, offset: O) {}
+ /// Called after the last [`push_doctype_name`] call for a DOCTYPE name.
+ ///
+ /// [`push_doctype_name`]: Self::push_doctype_name
+ fn terminate_doctype_name(&mut self, offset: O) {}
+
/// Assuming the _current token_ is a doctype, set its "public identifier" to the empty string.
///
/// If the current token is not a doctype, this method may panic.
@@ -422,6 +427,7 @@ impl<O: Offset> Emitter<O> for DefaultEmitter<O> {
return;
};
doctype.name = Some("".into());
+ doctype.name_span.start = offset;
}
fn push_doctype_name(&mut self, s: &str) {
@@ -433,6 +439,15 @@ impl<O: Offset> Emitter<O> for DefaultEmitter<O> {
_ => debug_assert!(false),
}
}
+
+ fn terminate_doctype_name(&mut self, offset: O) {
+ let Some(Token::Doctype(doctype)) = &mut self.current_token else {
+ debug_assert!(false);
+ return;
+ };
+ doctype.name_span.end = offset;
+ }
+
fn init_doctype(&mut self, offset: O) {
self.current_token = Some(Token::Doctype(Doctype {
name: None,
@@ -440,6 +455,7 @@ impl<O: Offset> Emitter<O> for DefaultEmitter<O> {
public_id: None,
system_id: None,
span: offset..O::default(),
+ name_span: O::default()..O::default(),
public_id_span: O::default()..O::default(),
system_id_span: O::default()..O::default(),
}));
@@ -628,6 +644,9 @@ pub struct Doctype<O> {
/// The source code span of the doctype.
pub span: Range<O>,
+ /// The span of the name.
+ name_span: Range<O>,
+
/// The span of the public identifier.
public_id_span: Range<O>,
@@ -636,6 +655,12 @@ pub struct Doctype<O> {
}
impl<O: Offset> Doctype<O> {
+ /// Returns the span of the name.
+ pub fn name_span(&self) -> Option<Range<O>> {
+ self.name.as_ref()?;
+ Some(self.name_span.clone())
+ }
+
/// Returns the span of the public identifier.
pub fn public_id_span(&self) -> Option<Range<O>> {
self.public_id.as_ref()?;
diff --git a/src/machine.rs b/src/machine.rs
index 6c4558c..d175b8b 100644
--- a/src/machine.rs
+++ b/src/machine.rs
@@ -1239,10 +1239,14 @@ where
},
State::DoctypeName => match slf.read_char()? {
Some(whitespace_pat!()) => {
+ slf.emitter
+ .terminate_doctype_name(slf.position_before_match);
slf.state = State::AfterDoctypeName;
Ok(ControlToken::Continue)
}
Some('>') => {
+ slf.emitter
+ .terminate_doctype_name(slf.position_before_match);
slf.state = State::Data;
slf.emitter.emit_current_doctype(slf.reader.position());
Ok(ControlToken::Continue)
@@ -1254,6 +1258,8 @@ where
}
None => {
slf.emit_error(Error::EofInDoctype);
+ slf.emitter
+ .terminate_doctype_name(slf.position_before_match);
slf.emitter.set_force_quirks();
slf.emitter.emit_current_doctype(slf.reader.position());
Ok(ControlToken::Eof)