1 // Copyright 2014-2017 The html5ever Project Developers. See the
2 // COPYRIGHT file at the top-level directory of this distribution.
3 //
4 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7 // option. This file may not be copied, modified, or distributed
8 // except according to those terms.
9 
10 use crate::interface::Attribute;
11 use std::borrow::Cow;
12 use crate::tendril::StrTendril;
13 use crate::tokenizer::states;
14 use crate::LocalName;
15 
16 pub use self::TagKind::{EndTag, StartTag};
17 pub use self::Token::{CharacterTokens, CommentToken, DoctypeToken, TagToken};
18 pub use self::Token::{EOFToken, NullCharacterToken, ParseError};
19 
20 /// A `DOCTYPE` token.
21 // FIXME: already exists in Servo DOM
22 #[derive(PartialEq, Eq, Clone, Debug)]
23 pub struct Doctype {
24     pub name: Option<StrTendril>,
25     pub public_id: Option<StrTendril>,
26     pub system_id: Option<StrTendril>,
27     pub force_quirks: bool,
28 }
29 
30 impl Doctype {
new() -> Doctype31     pub fn new() -> Doctype {
32         Doctype {
33             name: None,
34             public_id: None,
35             system_id: None,
36             force_quirks: false,
37         }
38     }
39 }
40 
41 #[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
42 pub enum TagKind {
43     StartTag,
44     EndTag,
45 }
46 
47 /// A tag token.
48 #[derive(PartialEq, Eq, Clone, Debug)]
49 pub struct Tag {
50     pub kind: TagKind,
51     pub name: LocalName,
52     pub self_closing: bool,
53     pub attrs: Vec<Attribute>,
54 }
55 
56 impl Tag {
57     /// Are the tags equivalent when we don't care about attribute order?
58     /// Also ignores the self-closing flag.
equiv_modulo_attr_order(&self, other: &Tag) -> bool59     pub fn equiv_modulo_attr_order(&self, other: &Tag) -> bool {
60         if (self.kind != other.kind) || (self.name != other.name) {
61             return false;
62         }
63 
64         let mut self_attrs = self.attrs.clone();
65         let mut other_attrs = other.attrs.clone();
66         self_attrs.sort();
67         other_attrs.sort();
68 
69         self_attrs == other_attrs
70     }
71 }
72 
73 #[derive(PartialEq, Eq, Debug)]
74 pub enum Token {
75     DoctypeToken(Doctype),
76     TagToken(Tag),
77     CommentToken(StrTendril),
78     CharacterTokens(StrTendril),
79     NullCharacterToken,
80     EOFToken,
81     ParseError(Cow<'static, str>),
82 }
83 
84 #[derive(Debug, PartialEq)]
85 #[must_use]
86 pub enum TokenSinkResult<Handle> {
87     Continue,
88     Script(Handle),
89     Plaintext,
90     RawData(states::RawKind),
91 }
92 
93 /// Types which can receive tokens from the tokenizer.
94 pub trait TokenSink {
95     type Handle;
96 
97     /// Process a token.
process_token(&mut self, token: Token, line_number: u64) -> TokenSinkResult<Self::Handle>98     fn process_token(&mut self, token: Token, line_number: u64) -> TokenSinkResult<Self::Handle>;
99 
100     // Signal sink that tokenization reached the end.
end(&mut self)101     fn end(&mut self) {}
102 
103     /// Used in the markup declaration open state. By default, this always
104     /// returns false and thus all CDATA sections are tokenized as bogus
105     /// comments.
106     /// https://html.spec.whatwg.org/multipage/#markup-declaration-open-state
adjusted_current_node_present_but_not_in_html_namespace(&self) -> bool107     fn adjusted_current_node_present_but_not_in_html_namespace(&self) -> bool {
108         false
109     }
110 }
111