diff options
| author | Martin Fischer <martin@push-f.com> | 2023-09-01 12:07:51 +0200 | 
|---|---|---|
| committer | Martin Fischer <martin@push-f.com> | 2023-09-03 23:00:05 +0200 | 
| commit | 0581e619867bde2374376265b24169b404187529 (patch) | |
| tree | 04b369238b4e13af15fed2324423d1e86d22aaf6 /src | |
| parent | f239037c1b960ba16c6c8b2184ac017c53c631bf (diff) | |
fix!: make attribute spans encoding-independent
Diffstat (limited to 'src')
| -rw-r--r-- | src/attr.rs | 22 | ||||
| -rw-r--r-- | src/emitter.rs | 23 | ||||
| -rw-r--r-- | src/machine.rs | 4 | 
3 files changed, 28 insertions, 21 deletions
| diff --git a/src/attr.rs b/src/attr.rs index 72dfcd9..096235e 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -30,8 +30,8 @@ pub struct AttributeMap<O> {  #[derive(Debug, Eq, PartialEq)]  pub(crate) struct AttrInternal<O> {      pub value: String, -    /// The start offset of the attribute name. -    pub name_offset: O, +    /// The span of the attribute name. +    pub name_span: Range<O>,      /// The span of the attribute value.      /// For the empty attribute syntax this is just `O::default()..O::default()`.      /// We intentionally don't use `Option<Range<O>>` here to spare us a byte (and padding) per attribute. @@ -65,8 +65,8 @@ pub struct AttributeOwned<O> {      pub name: String,      /// The attribute value. Character references have been resolved.      pub value: String, -    /// The start offset of the attribute name. -    pub name_offset: O, +    /// The span of the attribute name. +    pub name_span: Range<O>,      /// The span of the attribute value.      /// `None` in case of the empty attribute syntax (e.g. `disabled` in `<input disabled>`).      pub value_span: Option<Range<O>>, @@ -99,9 +99,9 @@ impl<'a, O: Offset> Attribute<'a, O> {          &self.map_val.value      } -    /// Calculates the span of the attribute name and returns it. +    /// Returns the span of the attribute name.      pub fn name_span(&self) -> Range<O> { -        self.map_val.name_offset..self.map_val.name_offset + self.name.len() +        self.map_val.name_span.clone()      }      /// For explicitly defined values returns the span of the attribute value. @@ -157,7 +157,7 @@ impl<O> Iterator for AttrIntoIter<O> {          Some(AttributeOwned {              name,              value: map_val.value, -            name_offset: map_val.name_offset, +            name_span: map_val.name_span,              value_span: map_val.value_syntax.is_some().then_some(map_val.value_span),              value_syntax: map_val.value_syntax,          }) @@ -196,7 +196,7 @@ impl<O: Default> FromIterator<(String, String)> for AttributeMap<O> {                          name,                          AttrInternal {                              value, -                            name_offset: O::default(), +                            name_span: O::default()..O::default(),                              value_span: O::default()..O::default(),                              value_syntax: Some(AttrValueSyntax::DoubleQuoted),                          }, @@ -206,9 +206,3 @@ impl<O: Default> FromIterator<(String, String)> for AttributeMap<O> {          }      }  } - -impl<O: Offset> AttrInternal<O> { -    pub(crate) fn name_span(&self, name_len: usize) -> Range<O> { -        self.name_offset..self.name_offset + name_len -    } -} diff --git a/src/emitter.rs b/src/emitter.rs index aa84215..bb12ca4 100644 --- a/src/emitter.rs +++ b/src/emitter.rs @@ -83,6 +83,11 @@ pub trait Emitter<O> {      /// [`push_tag_name`]: Self::push_tag_name      fn terminate_tag_name(&mut self, offset: O) {} +    /// Called after the last [`push_attribute_name`] call for an attribute name. +    /// +    /// [`push_attribute_name`]: Self::push_attribute_name +    fn terminate_attribute_name(&mut self, offset: O) {} +      /// Called after the last [`push_attribute_value`] call for an attribute value.      ///      /// [`push_attribute_value`]: Self::push_attribute_value @@ -224,16 +229,14 @@ impl<O> DefaultEmitter<O> {                      Entry::Vacant(vacant) => {                          vacant.insert(map_val);                      } -                    Entry::Occupied(entry) => { -                        let name_len = entry.key().len(); -                        self.push_error(Error::DuplicateAttribute, map_val.name_span(name_len)); +                    Entry::Occupied(_) => { +                        self.push_error(Error::DuplicateAttribute, map_val.name_span);                      }                  },                  Some(Token::EndTag(_)) => { -                    let name_span = map_val.name_span(name.len()); -                    self.attr_in_end_tag_span = Some(name_span.clone()); +                    self.attr_in_end_tag_span = Some(map_val.name_span.clone());                      if !self.seen_attributes.insert(name) { -                        self.push_error(Error::DuplicateAttribute, name_span); +                        self.push_error(Error::DuplicateAttribute, map_val.name_span);                      }                  }                  _ => { @@ -420,7 +423,7 @@ impl<O: Offset> Emitter<O> for DefaultEmitter<O> {          self.current_attribute = Some((              String::new(),              crate::attr::AttrInternal { -                name_offset: offset, +                name_span: offset..O::default(),                  value: String::new(),                  value_span: O::default()..O::default(),                  value_syntax: None, @@ -437,6 +440,12 @@ impl<O: Offset> Emitter<O> for DefaultEmitter<O> {          let current_attr = self.current_attribute.as_mut().unwrap();          current_attr.0.push_str(s);      } + +    fn terminate_attribute_name(&mut self, offset: O) { +        let current_attr = self.current_attribute.as_mut().unwrap(); +        current_attr.1.name_span.end = offset; +    } +      fn push_attribute_value(&mut self, s: &str) {          let current_attr = self.current_attribute.as_mut().unwrap();          current_attr.1.value.push_str(s); diff --git a/src/machine.rs b/src/machine.rs index c27708d..4f2d129 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -715,11 +715,15 @@ where          },          State::AttributeName => match slf.read_char()? {              c @ Some(whitespace_pat!() | '/' | '>') | c @ None => { +                slf.emitter +                    .terminate_attribute_name(slf.position_before_match);                  slf.state = State::AfterAttributeName;                  slf.unread_char(c);                  Ok(ControlToken::Continue)              }              Some('=') => { +                slf.emitter +                    .terminate_attribute_name(slf.position_before_match);                  slf.state = State::BeforeAttributeValue;                  Ok(ControlToken::Continue)              } | 
