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 #[macro_use]
11 extern crate html5ever;
12 
13 use std::borrow::Cow;
14 use std::collections::HashMap;
15 use std::default::Default;
16 use std::io;
17 
18 use html5ever::parse_document;
19 use html5ever::tendril::*;
20 use html5ever::tree_builder::{
21     AppendNode, AppendText, ElementFlags, NodeOrText, QuirksMode, TreeSink,
22 };
23 use html5ever::{Attribute, ExpandedName, QualName};
24 
25 struct Sink {
26     next_id: usize,
27     names: HashMap<usize, QualName>,
28 }
29 
30 impl Sink {
get_id(&mut self) -> usize31     fn get_id(&mut self) -> usize {
32         let id = self.next_id;
33         self.next_id += 2;
34         id
35     }
36 }
37 
38 impl TreeSink for Sink {
39     type Handle = usize;
40     type Output = Self;
finish(self) -> Self41     fn finish(self) -> Self {
42         self
43     }
44 
parse_error(&mut self, msg: Cow<'static, str>)45     fn parse_error(&mut self, msg: Cow<'static, str>) {
46         println!("Parse error: {}", msg);
47     }
48 
get_document(&mut self) -> usize49     fn get_document(&mut self) -> usize {
50         0
51     }
52 
get_template_contents(&mut self, target: &usize) -> usize53     fn get_template_contents(&mut self, target: &usize) -> usize {
54         if let Some(expanded_name!(html "template")) = self.names.get(target).map(|n| n.expanded())
55         {
56             target + 1
57         } else {
58             panic!("not a template element")
59         }
60     }
61 
set_quirks_mode(&mut self, mode: QuirksMode)62     fn set_quirks_mode(&mut self, mode: QuirksMode) {
63         println!("Set quirks mode to {:?}", mode);
64     }
65 
same_node(&self, x: &usize, y: &usize) -> bool66     fn same_node(&self, x: &usize, y: &usize) -> bool {
67         x == y
68     }
69 
elem_name(&self, target: &usize) -> ExpandedName70     fn elem_name(&self, target: &usize) -> ExpandedName {
71         self.names.get(target).expect("not an element").expanded()
72     }
73 
create_element(&mut self, name: QualName, _: Vec<Attribute>, _: ElementFlags) -> usize74     fn create_element(&mut self, name: QualName, _: Vec<Attribute>, _: ElementFlags) -> usize {
75         let id = self.get_id();
76         println!("Created {:?} as {}", name, id);
77         self.names.insert(id, name);
78         id
79     }
80 
create_comment(&mut self, text: StrTendril) -> usize81     fn create_comment(&mut self, text: StrTendril) -> usize {
82         let id = self.get_id();
83         println!("Created comment \"{}\" as {}", escape_default(&text), id);
84         id
85     }
86 
87     #[allow(unused_variables)]
create_pi(&mut self, target: StrTendril, value: StrTendril) -> usize88     fn create_pi(&mut self, target: StrTendril, value: StrTendril) -> usize {
89         unimplemented!()
90     }
91 
append(&mut self, parent: &usize, child: NodeOrText<usize>)92     fn append(&mut self, parent: &usize, child: NodeOrText<usize>) {
93         match child {
94             AppendNode(n) => println!("Append node {} to {}", n, parent),
95             AppendText(t) => println!("Append text to {}: \"{}\"", parent, escape_default(&t)),
96         }
97     }
98 
append_before_sibling(&mut self, sibling: &usize, new_node: NodeOrText<usize>)99     fn append_before_sibling(&mut self, sibling: &usize, new_node: NodeOrText<usize>) {
100         match new_node {
101             AppendNode(n) => println!("Append node {} before {}", n, sibling),
102             AppendText(t) => println!("Append text before {}: \"{}\"", sibling, escape_default(&t)),
103         }
104     }
105 
append_based_on_parent_node( &mut self, element: &Self::Handle, prev_element: &Self::Handle, child: NodeOrText<Self::Handle>, )106     fn append_based_on_parent_node(
107         &mut self,
108         element: &Self::Handle,
109         prev_element: &Self::Handle,
110         child: NodeOrText<Self::Handle>,
111     ) {
112         self.append_before_sibling(element, child);
113     }
114 
append_doctype_to_document( &mut self, name: StrTendril, public_id: StrTendril, system_id: StrTendril, )115     fn append_doctype_to_document(
116         &mut self,
117         name: StrTendril,
118         public_id: StrTendril,
119         system_id: StrTendril,
120     ) {
121         println!("Append doctype: {} {} {}", name, public_id, system_id);
122     }
123 
add_attrs_if_missing(&mut self, target: &usize, attrs: Vec<Attribute>)124     fn add_attrs_if_missing(&mut self, target: &usize, attrs: Vec<Attribute>) {
125         assert!(self.names.contains_key(target), "not an element");
126         println!("Add missing attributes to {}:", target);
127         for attr in attrs.into_iter() {
128             println!("    {:?} = {}", attr.name, attr.value);
129         }
130     }
131 
associate_with_form( &mut self, _target: &usize, _form: &usize, _nodes: (&usize, Option<&usize>), )132     fn associate_with_form(
133         &mut self,
134         _target: &usize,
135         _form: &usize,
136         _nodes: (&usize, Option<&usize>),
137     ) {
138         // No form owner support.
139     }
140 
remove_from_parent(&mut self, target: &usize)141     fn remove_from_parent(&mut self, target: &usize) {
142         println!("Remove {} from parent", target);
143     }
144 
reparent_children(&mut self, node: &usize, new_parent: &usize)145     fn reparent_children(&mut self, node: &usize, new_parent: &usize) {
146         println!("Move children from {} to {}", node, new_parent);
147     }
148 
mark_script_already_started(&mut self, node: &usize)149     fn mark_script_already_started(&mut self, node: &usize) {
150         println!("Mark script {} as already started", node);
151     }
152 
set_current_line(&mut self, line_number: u64)153     fn set_current_line(&mut self, line_number: u64) {
154         println!("Set current line to {}", line_number);
155     }
156 
pop(&mut self, elem: &usize)157     fn pop(&mut self, elem: &usize) {
158         println!("Popped element {}", elem);
159     }
160 }
161 
162 // FIXME: Copy of str::escape_default from std, which is currently unstable
escape_default(s: &str) -> String163 pub fn escape_default(s: &str) -> String {
164     s.chars().flat_map(|c| c.escape_default()).collect()
165 }
166 
main()167 fn main() {
168     let sink = Sink {
169         next_id: 1,
170         names: HashMap::new(),
171     };
172     let stdin = io::stdin();
173     parse_document(sink, Default::default())
174         .from_utf8()
175         .read_from(&mut stdin.lock())
176         .unwrap();
177 }
178