summaryrefslogtreecommitdiffstats
path: root/vendor/markup5ever/interface
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /vendor/markup5ever/interface
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/markup5ever/interface')
-rw-r--r--vendor/markup5ever/interface/mod.rs377
-rw-r--r--vendor/markup5ever/interface/tree_builder.rs253
2 files changed, 630 insertions, 0 deletions
diff --git a/vendor/markup5ever/interface/mod.rs b/vendor/markup5ever/interface/mod.rs
new file mode 100644
index 000000000..f498fdfbf
--- /dev/null
+++ b/vendor/markup5ever/interface/mod.rs
@@ -0,0 +1,377 @@
+// Copyright 2014-2017 The html5ever Project Developers. See the
+// COPYRIGHT file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+//! Types for tag and attribute names, and tree-builder functionality.
+
+use std::fmt;
+use tendril::StrTendril;
+
+pub use self::tree_builder::{create_element, AppendNode, AppendText, ElementFlags, NodeOrText};
+pub use self::tree_builder::{LimitedQuirks, NoQuirks, Quirks, QuirksMode};
+pub use self::tree_builder::{NextParserState, Tracer, TreeSink};
+use super::{LocalName, Namespace, Prefix};
+
+/// An [expanded name], containing the tag and the namespace.
+///
+/// [expanded name]: https://www.w3.org/TR/REC-xml-names/#dt-expname
+#[derive(Copy, Clone, Eq, Hash)]
+pub struct ExpandedName<'a> {
+ pub ns: &'a Namespace,
+ pub local: &'a LocalName,
+}
+
+impl<'a, 'b> PartialEq<ExpandedName<'a>> for ExpandedName<'b> {
+ fn eq(&self, other: &ExpandedName<'a>) -> bool {
+ self.ns == other.ns && self.local == other.local
+ }
+}
+
+impl<'a> fmt::Debug for ExpandedName<'a> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ if self.ns.is_empty() {
+ write!(f, "{}", self.local)
+ } else {
+ write!(f, "{{{}}}:{}", self.ns, self.local)
+ }
+ }
+}
+
+/// Helper to quickly create an expanded name.
+///
+/// Can be used with no namespace as `expanded_name!("", "some_name")`
+/// or with a namespace as `expanded_name!(ns "some_name")`. In the
+/// latter case, `ns` is one of the symbols which the [`ns!`][ns]
+/// macro accepts; note the lack of a comma between the `ns` and
+/// `"some_name"`.
+///
+/// [ns]: macro.ns.html
+///
+/// # Examples
+///
+/// ```
+/// # #[macro_use] extern crate markup5ever;
+///
+/// # fn main() {
+/// use markup5ever::ExpandedName;
+///
+/// assert_eq!(
+/// expanded_name!("", "div"),
+/// ExpandedName {
+/// ns: &ns!(),
+/// local: &local_name!("div")
+/// }
+/// );
+///
+/// assert_eq!(
+/// expanded_name!(html "div"),
+/// ExpandedName {
+/// ns: &ns!(html),
+/// local: &local_name!("div")
+/// }
+/// );
+/// # }
+#[macro_export]
+macro_rules! expanded_name {
+ ("", $local: tt) => {
+ $crate::interface::ExpandedName {
+ ns: &ns!(),
+ local: &local_name!($local),
+ }
+ };
+ ($ns: ident $local: tt) => {
+ $crate::interface::ExpandedName {
+ ns: &ns!($ns),
+ local: &local_name!($local),
+ }
+ };
+}
+
+pub mod tree_builder;
+
+/// A fully qualified name (with a namespace), used to depict names of tags and attributes.
+///
+/// Namespaces can be used to differentiate between similar XML fragments. For example:
+///
+/// ```text
+/// // HTML
+/// <table>
+/// <tr>
+/// <td>Apples</td>
+/// <td>Bananas</td>
+/// </tr>
+/// </table>
+///
+/// // Furniture XML
+/// <table>
+/// <name>African Coffee Table</name>
+/// <width>80</width>
+/// <length>120</length>
+/// </table>
+/// ```
+///
+/// Without XML namespaces, we can't use those two fragments in the same document
+/// at the same time. However if we declare a namespace we could instead say:
+///
+/// ```text
+///
+/// // Furniture XML
+/// <furn:table xmlns:furn="https://furniture.rs">
+/// <furn:name>African Coffee Table</furn:name>
+/// <furn:width>80</furn:width>
+/// <furn:length>120</furn:length>
+/// </furn:table>
+/// ```
+///
+/// and bind the prefix `furn` to a different namespace.
+///
+/// For this reason we parse names that contain a colon in the following way:
+///
+/// ```text
+/// <furn:table>
+/// | |
+/// | +- local name
+/// |
+/// prefix (when resolved gives namespace_url `https://furniture.rs`)
+/// ```
+///
+/// NOTE: `Prefix`, `LocalName` and `Prefix` are all derivative of
+/// `string_cache::atom::Atom` and `Atom` implements `Deref<str>`.
+///
+#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone)]
+#[cfg_attr(feature = "heap_size", derive(HeapSizeOf))]
+pub struct QualName {
+ /// The prefix of qualified (e.g. `furn` in `<furn:table>` above).
+ /// Optional (since some namespaces can be empty or inferred), and
+ /// only useful for namespace resolution (since different prefix
+ /// can still resolve to same namespace)
+ ///
+ /// ```
+ ///
+ /// # fn main() {
+ /// use markup5ever::{QualName, Namespace, LocalName, Prefix};
+ ///
+ /// let qual = QualName::new(
+ /// Some(Prefix::from("furn")),
+ /// Namespace::from("https://furniture.rs"),
+ /// LocalName::from("table"),
+ /// );
+ ///
+ /// assert_eq!("furn", &qual.prefix.unwrap());
+ ///
+ /// # }
+ /// ```
+ pub prefix: Option<Prefix>,
+ /// The namespace after resolution (e.g. `https://furniture.rs` in example above).
+ ///
+ /// ```
+ /// # use markup5ever::{QualName, Namespace, LocalName, Prefix};
+ ///
+ /// # fn main() {
+ /// # let qual = QualName::new(
+ /// # Some(Prefix::from("furn")),
+ /// # Namespace::from("https://furniture.rs"),
+ /// # LocalName::from("table"),
+ /// # );
+ ///
+ /// assert_eq!("https://furniture.rs", &qual.ns);
+ /// # }
+ /// ```
+ ///
+ /// When matching namespaces used by HTML we can use `ns!` macro.
+ /// Although keep in mind that ns! macro only works with namespaces
+ /// that are present in HTML spec (like `html`, `xmlns`, `svg`, etc.).
+ ///
+ /// ```
+ /// #[macro_use] extern crate markup5ever;
+ ///
+ /// # use markup5ever::{QualName, Namespace, LocalName, Prefix};
+ ///
+ /// let html_table = QualName::new(
+ /// None,
+ /// ns!(html),
+ /// LocalName::from("table"),
+ /// );
+ ///
+ /// assert!(
+ /// match html_table.ns {
+ /// ns!(html) => true,
+ /// _ => false,
+ /// }
+ /// );
+ ///
+ /// ```
+ pub ns: Namespace,
+ /// The local name (e.g. `table` in `<furn:table>` above).
+ ///
+ /// ```
+ /// # use markup5ever::{QualName, Namespace, LocalName, Prefix};
+ ///
+ /// # fn main() {
+ /// # let qual = QualName::new(
+ /// # Some(Prefix::from("furn")),
+ /// # Namespace::from("https://furniture.rs"),
+ /// # LocalName::from("table"),
+ /// # );
+ ///
+ /// assert_eq!("table", &qual.local);
+ /// # }
+ /// ```
+ /// When matching local name we can also use the `local_name!` macro:
+ ///
+ /// ```
+ /// #[macro_use] extern crate markup5ever;
+ ///
+ /// # use markup5ever::{QualName, Namespace, LocalName, Prefix};
+ ///
+ /// # let qual = QualName::new(
+ /// # Some(Prefix::from("furn")),
+ /// # Namespace::from("https://furniture.rs"),
+ /// # LocalName::from("table"),
+ /// # );
+ ///
+ /// // Initialize qual to furniture example
+ ///
+ /// assert!(
+ /// match qual.local {
+ /// local_name!("table") => true,
+ /// _ => false,
+ /// }
+ /// );
+ ///
+ /// ```
+ pub local: LocalName,
+}
+
+impl QualName {
+ /// Basic constructor function.
+ ///
+ /// First let's try it for the following example where `QualName`
+ /// is defined as:
+ /// ```text
+ /// <furn:table> <!-- namespace url is https://furniture.rs -->
+ /// ```
+ ///
+ /// Given this definition, we can define `QualName` using strings.
+ ///
+ /// ```
+ /// use markup5ever::{QualName, Namespace, LocalName, Prefix};
+ ///
+ /// # fn main() {
+ /// let qual_name = QualName::new(
+ /// Some(Prefix::from("furn")),
+ /// Namespace::from("https://furniture.rs"),
+ /// LocalName::from("table"),
+ /// );
+ /// # }
+ /// ```
+ ///
+ /// If we were instead to construct this element instead:
+ ///
+ /// ```text
+ ///
+ /// <table>
+ /// ^^^^^---- no prefix and thus default html namespace
+ ///
+ /// ```
+ ///
+ /// Or could define it using macros, like so:
+ ///
+ /// ```
+ /// #[macro_use] extern crate markup5ever;
+ /// use markup5ever::{QualName, Namespace, LocalName, Prefix};
+ ///
+ /// # fn main() {
+ /// let qual_name = QualName::new(
+ /// None,
+ /// ns!(html),
+ /// local_name!("table")
+ /// );
+ /// # }
+ /// ```
+ ///
+ /// Let's analyse the above example.
+ /// Since we have no prefix its value is None. Second we have html namespace.
+ /// In html5ever html namespaces are supported out of the box,
+ /// we can write `ns!(html)` instead of typing `Namespace::from("http://www.w3.org/1999/xhtml")`.
+ /// Local name is also one of the HTML elements local names, so can
+ /// use `local_name!("table")` macro.
+ ///
+ #[inline]
+ pub fn new(prefix: Option<Prefix>, ns: Namespace, local: LocalName) -> QualName {
+ QualName {
+ prefix,
+ ns,
+ local,
+ }
+ }
+
+ /// Take a reference of `self` as an `ExpandedName`, dropping the unresolved prefix.
+ ///
+ /// In XML and HTML prefixes are only used to extract the relevant namespace URI.
+ /// Expanded name only contains resolved namespace and tag name, which are only
+ /// relevant parts of an XML or HTML tag and attribute name respectively.
+ ///
+ /// In lieu of our XML Namespace example
+ ///
+ /// ```text
+ /// <furn:table> <!-- namespace url is https://furniture.rs -->
+ /// ```
+ /// For it the expanded name would become roughly equivalent to:
+ ///
+ /// ```text
+ /// ExpandedName {
+ /// ns: "https://furniture.rs",
+ /// local: "table",
+ /// }
+ /// ```
+ ///
+ #[inline]
+ pub fn expanded(&self) -> ExpandedName {
+ ExpandedName {
+ ns: &self.ns,
+ local: &self.local,
+ }
+ }
+}
+
+/// A tag attribute, e.g. `class="test"` in `<div class="test" ...>`.
+///
+/// The namespace on the attribute name is almost always ns!("").
+/// The tokenizer creates all attributes this way, but the tree
+/// builder will adjust certain attribute names inside foreign
+/// content (MathML, SVG).
+#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug)]
+pub struct Attribute {
+ /// The name of the attribute (e.g. the `class` in `<div class="test">`)
+ pub name: QualName,
+ /// The value of the attribute (e.g. the `"test"` in `<div class="test">`)
+ pub value: StrTendril,
+}
+
+#[cfg(test)]
+mod tests {
+ use super::Namespace;
+
+ #[test]
+ fn ns_macro() {
+ assert_eq!(ns!(), Namespace::from(""));
+
+ assert_eq!(ns!(html), Namespace::from("http://www.w3.org/1999/xhtml"));
+ assert_eq!(
+ ns!(xml),
+ Namespace::from("http://www.w3.org/XML/1998/namespace")
+ );
+ assert_eq!(ns!(xmlns), Namespace::from("http://www.w3.org/2000/xmlns/"));
+ assert_eq!(ns!(xlink), Namespace::from("http://www.w3.org/1999/xlink"));
+ assert_eq!(ns!(svg), Namespace::from("http://www.w3.org/2000/svg"));
+ assert_eq!(
+ ns!(mathml),
+ Namespace::from("http://www.w3.org/1998/Math/MathML")
+ );
+ }
+}
diff --git a/vendor/markup5ever/interface/tree_builder.rs b/vendor/markup5ever/interface/tree_builder.rs
new file mode 100644
index 000000000..43361f360
--- /dev/null
+++ b/vendor/markup5ever/interface/tree_builder.rs
@@ -0,0 +1,253 @@
+// Copyright 2014-2017 The html5ever Project Developers. See the
+// COPYRIGHT file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! This module contains functionality for managing the DOM, including adding/removing nodes.
+//!
+//! It can be used by a parser to create the DOM graph structure in memory.
+
+use crate::interface::{Attribute, ExpandedName, QualName};
+use std::borrow::Cow;
+use tendril::StrTendril;
+
+pub use self::NodeOrText::{AppendNode, AppendText};
+pub use self::QuirksMode::{LimitedQuirks, NoQuirks, Quirks};
+
+/// Something which can be inserted into the DOM.
+///
+/// Adjacent sibling text nodes are merged into a single node, so
+/// the sink may not want to allocate a `Handle` for each.
+pub enum NodeOrText<Handle> {
+ AppendNode(Handle),
+ AppendText(StrTendril),
+}
+
+/// A document's quirks mode, for compatibility with old browsers. See [quirks mode on wikipedia]
+/// for more information.
+///
+/// [quirks mode on wikipedia]: https://en.wikipedia.org/wiki/Quirks_mode
+#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug)]
+pub enum QuirksMode {
+ /// Full quirks mode
+ Quirks,
+ /// Almost standards mode
+ LimitedQuirks,
+ /// Standards mode
+ NoQuirks,
+}
+
+/// Whether to interrupt further parsing of the current input until
+/// the next explicit resumption of the tokenizer, or continue without
+/// any interruption.
+#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug)]
+pub enum NextParserState {
+ /// Stop further parsing.
+ Suspend,
+ /// Continue without interruptions.
+ Continue,
+}
+
+/// Special properties of an element, useful for tagging elements with this information.
+#[derive(Default)]
+pub struct ElementFlags {
+ /// A document fragment should be created, associated with the element,
+ /// and returned in TreeSink::get_template_contents.
+ ///
+ /// See [template-contents in the whatwg spec][whatwg template-contents].
+ ///
+ /// [whatwg template-contents]: https://html.spec.whatwg.org/multipage/#template-contents
+ pub template: bool,
+
+ /// This boolean should be recorded with the element and returned
+ /// in TreeSink::is_mathml_annotation_xml_integration_point
+ ///
+ /// See [html-integration-point in the whatwg spec][whatwg integration-point].
+ ///
+ /// [whatwg integration-point]: https://html.spec.whatwg.org/multipage/#html-integration-point
+ pub mathml_annotation_xml_integration_point: bool,
+
+ // Prevent construction from outside module
+ _private: (),
+}
+
+/// A constructor for an element.
+///
+/// # Examples
+///
+/// Create an element like `<div class="test-class-name"></div>`:
+pub fn create_element<Sink>(sink: &mut Sink, name: QualName, attrs: Vec<Attribute>) -> Sink::Handle
+where
+ Sink: TreeSink,
+{
+ let mut flags = ElementFlags::default();
+ match name.expanded() {
+ expanded_name!(html "template") => flags.template = true,
+ expanded_name!(mathml "annotation-xml") => {
+ flags.mathml_annotation_xml_integration_point = attrs.iter().any(|attr| {
+ attr.name.expanded() == expanded_name!("", "encoding") &&
+ (attr.value.eq_ignore_ascii_case("text/html") ||
+ attr.value.eq_ignore_ascii_case("application/xhtml+xml"))
+ })
+ },
+ _ => {},
+ }
+ sink.create_element(name, attrs, flags)
+}
+
+/// Methods a parser can use to create the DOM. The DOM provider implements this trait.
+///
+/// Having this as a trait potentially allows multiple implementations of the DOM to be used with
+/// the same parser.
+pub trait TreeSink {
+ /// `Handle` is a reference to a DOM node. The tree builder requires
+ /// that a `Handle` implements `Clone` to get another reference to
+ /// the same node.
+ type Handle: Clone;
+
+ /// The overall result of parsing.
+ ///
+ /// This should default to Self, but default associated types are not stable yet.
+ /// [rust-lang/rust#29661](https://github.com/rust-lang/rust/issues/29661)
+ type Output;
+
+ /// Consume this sink and return the overall result of parsing.
+ ///
+ /// TODO:This should default to `fn finish(self) -> Self::Output { self }`,
+ /// but default associated types are not stable yet.
+ /// [rust-lang/rust#29661](https://github.com/rust-lang/rust/issues/29661)
+ fn finish(self) -> Self::Output;
+
+ /// Signal a parse error.
+ fn parse_error(&mut self, msg: Cow<'static, str>);
+
+ /// Get a handle to the `Document` node.
+ fn get_document(&mut self) -> Self::Handle;
+
+ /// What is the name of this element?
+ ///
+ /// Should never be called on a non-element node;
+ /// feel free to `panic!`.
+ fn elem_name<'a>(&'a self, target: &'a Self::Handle) -> ExpandedName<'a>;
+
+ /// Create an element.
+ ///
+ /// When creating a template element (`name.ns.expanded() == expanded_name!(html "template")`),
+ /// an associated document fragment called the "template contents" should
+ /// also be created. Later calls to self.get_template_contents() with that
+ /// given element return it.
+ /// See [the template element in the whatwg spec][whatwg template].
+ ///
+ /// [whatwg template]: https://html.spec.whatwg.org/multipage/#the-template-element
+ fn create_element(
+ &mut self,
+ name: QualName,
+ attrs: Vec<Attribute>,
+ flags: ElementFlags,
+ ) -> Self::Handle;
+
+ /// Create a comment node.
+ fn create_comment(&mut self, text: StrTendril) -> Self::Handle;
+
+ /// Create a Processing Instruction node.
+ fn create_pi(&mut self, target: StrTendril, data: StrTendril) -> Self::Handle;
+
+ /// Append a node as the last child of the given node. If this would
+ /// produce adjacent sibling text nodes, it should concatenate the text
+ /// instead.
+ ///
+ /// The child node will not already have a parent.
+ fn append(&mut self, parent: &Self::Handle, child: NodeOrText<Self::Handle>);
+
+ /// When the insertion point is decided by the existence of a parent node of the
+ /// element, we consider both possibilities and send the element which will be used
+ /// if a parent node exists, along with the element to be used if there isn't one.
+ fn append_based_on_parent_node(
+ &mut self,
+ element: &Self::Handle,
+ prev_element: &Self::Handle,
+ child: NodeOrText<Self::Handle>,
+ );
+
+ /// Append a `DOCTYPE` element to the `Document` node.
+ fn append_doctype_to_document(
+ &mut self,
+ name: StrTendril,
+ public_id: StrTendril,
+ system_id: StrTendril,
+ );
+
+ /// Mark a HTML `<script>` as "already started".
+ fn mark_script_already_started(&mut self, _node: &Self::Handle) {}
+
+ /// Indicate that a node was popped off the stack of open elements.
+ fn pop(&mut self, _node: &Self::Handle) {}
+
+ /// Get a handle to a template's template contents. The tree builder
+ /// promises this will never be called with something else than
+ /// a template element.
+ fn get_template_contents(&mut self, target: &Self::Handle) -> Self::Handle;
+
+ /// Do two handles refer to the same node?
+ fn same_node(&self, x: &Self::Handle, y: &Self::Handle) -> bool;
+
+ /// Set the document's quirks mode.
+ fn set_quirks_mode(&mut self, mode: QuirksMode);
+
+ /// Append a node as the sibling immediately before the given node.
+ ///
+ /// The tree builder promises that `sibling` is not a text node. However its
+ /// old previous sibling, which would become the new node's previous sibling,
+ /// could be a text node. If the new node is also a text node, the two should
+ /// be merged, as in the behavior of `append`.
+ ///
+ /// NB: `new_node` may have an old parent, from which it should be removed.
+ fn append_before_sibling(&mut self, sibling: &Self::Handle, new_node: NodeOrText<Self::Handle>);
+
+ /// Add each attribute to the given element, if no attribute with that name
+ /// already exists. The tree builder promises this will never be called
+ /// with something else than an element.
+ fn add_attrs_if_missing(&mut self, target: &Self::Handle, attrs: Vec<Attribute>);
+
+ /// Associate the given form-associatable element with the form element
+ fn associate_with_form(
+ &mut self,
+ _target: &Self::Handle,
+ _form: &Self::Handle,
+ _nodes: (&Self::Handle, Option<&Self::Handle>),
+ ) {
+ }
+
+ /// Detach the given node from its parent.
+ fn remove_from_parent(&mut self, target: &Self::Handle);
+
+ /// Remove all the children from node and append them to new_parent.
+ fn reparent_children(&mut self, node: &Self::Handle, new_parent: &Self::Handle);
+
+ /// Returns true if the adjusted current node is an HTML integration point
+ /// and the token is a start tag.
+ fn is_mathml_annotation_xml_integration_point(&self, _handle: &Self::Handle) -> bool {
+ false
+ }
+
+ /// Called whenever the line number changes.
+ fn set_current_line(&mut self, _line_number: u64) {}
+
+ /// Indicate that a `script` element is complete.
+ fn complete_script(&mut self, _node: &Self::Handle) -> NextParserState {
+ NextParserState::Continue
+ }
+}
+
+/// Trace hooks for a garbage-collected DOM.
+pub trait Tracer {
+ type Handle;
+
+ /// Upon a call to `trace_handles`, the tree builder will call this method
+ /// for each handle in its internal state.
+ fn trace_handle(&self, node: &Self::Handle);
+}