rusteerio 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. package/CONTRIBUTING.md +73 -0
  2. package/Cargo.lock +1051 -0
  3. package/Cargo.toml +36 -0
  4. package/LICENSE +21 -0
  5. package/README.md +252 -2
  6. package/RELEASING.md +138 -0
  7. package/THIRD_PARTY_NOTICES.md +7443 -0
  8. package/build.rs +3 -0
  9. package/dist/chunk-DKULX6VO.mjs +3185 -0
  10. package/dist/chunk-DKULX6VO.mjs.map +1 -0
  11. package/dist/chunk-OHPGEY3E.mjs +32 -0
  12. package/dist/chunk-OHPGEY3E.mjs.map +1 -0
  13. package/dist/index.cjs +3230 -0
  14. package/dist/index.cjs.map +1 -0
  15. package/dist/index.d.mts +113 -0
  16. package/dist/index.d.ts +113 -0
  17. package/dist/index.mjs +38 -0
  18. package/dist/index.mjs.map +1 -0
  19. package/dist/slim.cjs +2441 -0
  20. package/dist/slim.cjs.map +1 -0
  21. package/dist/slim.d.mts +11 -0
  22. package/dist/slim.d.ts +11 -0
  23. package/dist/slim.mjs +19 -0
  24. package/dist/slim.mjs.map +1 -0
  25. package/dist/types-BP6TpxE5.d.mts +532 -0
  26. package/dist/types-BP6TpxE5.d.ts +532 -0
  27. package/dist/utils.cjs +61 -0
  28. package/dist/utils.cjs.map +1 -0
  29. package/dist/utils.d.mts +13 -0
  30. package/dist/utils.d.ts +13 -0
  31. package/dist/utils.mjs +17 -0
  32. package/dist/utils.mjs.map +1 -0
  33. package/native/src/arena.rs +1781 -0
  34. package/native/src/attributes.rs +923 -0
  35. package/native/src/codec.rs +172 -0
  36. package/native/src/diagnostics.rs +1249 -0
  37. package/native/src/extraction.rs +226 -0
  38. package/native/src/gc.rs +166 -0
  39. package/native/src/hook_sink.rs +727 -0
  40. package/native/src/hook_stream.rs +513 -0
  41. package/native/src/lib.rs +2095 -0
  42. package/native/src/location.rs +392 -0
  43. package/native/src/runtime.rs +189 -0
  44. package/native/src/selector.rs +1287 -0
  45. package/native/src/sink.rs +261 -0
  46. package/native/src/stream.rs +334 -0
  47. package/native/src/tokenizer.rs +355 -0
  48. package/native/src/tracker.rs +232 -0
  49. package/native/vendor/README.md +25 -0
  50. package/native/vendor/html5ever-0.35.0/.cargo_vcs_info.json +6 -0
  51. package/native/vendor/html5ever-0.35.0/Cargo.lock +828 -0
  52. package/native/vendor/html5ever-0.35.0/Cargo.toml +85 -0
  53. package/native/vendor/html5ever-0.35.0/LICENSE-APACHE +201 -0
  54. package/native/vendor/html5ever-0.35.0/LICENSE-MIT +25 -0
  55. package/native/vendor/html5ever-0.35.0/README.md +60 -0
  56. package/native/vendor/html5ever-0.35.0/benches/html5ever.rs +86 -0
  57. package/native/vendor/html5ever-0.35.0/data/bench/lipsum-zh.html +19 -0
  58. package/native/vendor/html5ever-0.35.0/data/bench/lipsum.html +40 -0
  59. package/native/vendor/html5ever-0.35.0/data/bench/medium-fragment.html +24 -0
  60. package/native/vendor/html5ever-0.35.0/data/bench/small-fragment.html +7 -0
  61. package/native/vendor/html5ever-0.35.0/data/bench/strong.html +1 -0
  62. package/native/vendor/html5ever-0.35.0/data/bench/tiny-fragment.html +1 -0
  63. package/native/vendor/html5ever-0.35.0/examples/arena.rs +356 -0
  64. package/native/vendor/html5ever-0.35.0/examples/capi/tokenize.c +74 -0
  65. package/native/vendor/html5ever-0.35.0/examples/noop-tokenize.rs +47 -0
  66. package/native/vendor/html5ever-0.35.0/examples/noop-tree-builder.rs +132 -0
  67. package/native/vendor/html5ever-0.35.0/examples/print-tree-actions.rs +185 -0
  68. package/native/vendor/html5ever-0.35.0/examples/tokenize.rs +111 -0
  69. package/native/vendor/html5ever-0.35.0/src/driver.rs +148 -0
  70. package/native/vendor/html5ever-0.35.0/src/lib.rs +30 -0
  71. package/native/vendor/html5ever-0.35.0/src/macros.rs +34 -0
  72. package/native/vendor/html5ever-0.35.0/src/serialize/mod.rs +255 -0
  73. package/native/vendor/html5ever-0.35.0/src/tokenizer/char_ref/mod.rs +451 -0
  74. package/native/vendor/html5ever-0.35.0/src/tokenizer/interface.rs +99 -0
  75. package/native/vendor/html5ever-0.35.0/src/tokenizer/mod.rs +2305 -0
  76. package/native/vendor/html5ever-0.35.0/src/tokenizer/states.rs +97 -0
  77. package/native/vendor/html5ever-0.35.0/src/tree_builder/data.rs +170 -0
  78. package/native/vendor/html5ever-0.35.0/src/tree_builder/mod.rs +1848 -0
  79. package/native/vendor/html5ever-0.35.0/src/tree_builder/rules.rs +1494 -0
  80. package/native/vendor/html5ever-0.35.0/src/tree_builder/tag_sets.rs +114 -0
  81. package/native/vendor/html5ever-0.35.0/src/tree_builder/types.rs +91 -0
  82. package/native/vendor/html5ever-0.35.0/src/util/str.rs +52 -0
  83. package/native/vendor/html5gum-0.8.4/Cargo.lock +1006 -0
  84. package/native/vendor/html5gum-0.8.4/Cargo.toml +109 -0
  85. package/native/vendor/html5gum-0.8.4/LICENSE +19 -0
  86. package/native/vendor/html5gum-0.8.4/README.md +110 -0
  87. package/native/vendor/html5gum-0.8.4/benches/files/0050.html +2131 -0
  88. package/native/vendor/html5gum-0.8.4/benches/files/6D30.html +1004 -0
  89. package/native/vendor/html5gum-0.8.4/benches/files.rs +32 -0
  90. package/native/vendor/html5gum-0.8.4/benches/patterns.rs +31 -0
  91. package/native/vendor/html5gum-0.8.4/src/arrayvec.rs +29 -0
  92. package/native/vendor/html5gum-0.8.4/src/char_validator.rs +134 -0
  93. package/native/vendor/html5gum-0.8.4/src/emitters/callback.rs +676 -0
  94. package/native/vendor/html5gum-0.8.4/src/emitters/default.rs +207 -0
  95. package/native/vendor/html5gum-0.8.4/src/emitters/emitter.rs +344 -0
  96. package/native/vendor/html5gum-0.8.4/src/emitters/html5ever.rs +306 -0
  97. package/native/vendor/html5gum-0.8.4/src/emitters/mod.rs +25 -0
  98. package/native/vendor/html5gum-0.8.4/src/entities.rs +3342 -0
  99. package/native/vendor/html5gum-0.8.4/src/error.rs +96 -0
  100. package/native/vendor/html5gum-0.8.4/src/htmlstring.rs +130 -0
  101. package/native/vendor/html5gum-0.8.4/src/lib.rs +66 -0
  102. package/native/vendor/html5gum-0.8.4/src/machine.rs +2136 -0
  103. package/native/vendor/html5gum-0.8.4/src/machine_helper.rs +277 -0
  104. package/native/vendor/html5gum-0.8.4/src/read_helper.rs +244 -0
  105. package/native/vendor/html5gum-0.8.4/src/reader.rs +440 -0
  106. package/native/vendor/html5gum-0.8.4/src/span.rs +98 -0
  107. package/native/vendor/html5gum-0.8.4/src/state.rs +16 -0
  108. package/native/vendor/html5gum-0.8.4/src/testutils.rs +71 -0
  109. package/native/vendor/html5gum-0.8.4/src/tokenizer.rs +189 -0
  110. package/native/vendor/html5gum-0.8.4/src/utils.rs +88 -0
  111. package/native/vendor/markup5ever-0.35.0/.cargo_vcs_info.json +6 -0
  112. package/native/vendor/markup5ever-0.35.0/Cargo.toml +45 -0
  113. package/native/vendor/markup5ever-0.35.0/LICENSE-APACHE +201 -0
  114. package/native/vendor/markup5ever-0.35.0/LICENSE-MIT +25 -0
  115. package/native/vendor/markup5ever-0.35.0/interface/mod.rs +422 -0
  116. package/native/vendor/markup5ever-0.35.0/interface/tree_builder.rs +280 -0
  117. package/native/vendor/markup5ever-0.35.0/lib.rs +59 -0
  118. package/native/vendor/markup5ever-0.35.0/serialize.rs +77 -0
  119. package/native/vendor/markup5ever-0.35.0/util/buffer_queue.rs +333 -0
  120. package/native/vendor/markup5ever-0.35.0/util/smallcharset.rs +88 -0
  121. package/package.json +137 -4
  122. package/rusteerio.darwin-arm64.node +0 -0
  123. package/rusteerio.darwin-x64.node +0 -0
  124. package/rusteerio.linux-arm64-gnu.node +0 -0
  125. package/rusteerio.linux-arm64-musl.node +0 -0
  126. package/rusteerio.linux-x64-gnu.node +0 -0
  127. package/rusteerio.linux-x64-musl.node +0 -0
  128. package/rusteerio.win32-arm64-msvc.node +0 -0
  129. package/rusteerio.win32-x64-msvc.node +0 -0
  130. package/scripts/check-native.mjs +15 -0
  131. package/scripts/check-release.mjs +235 -0
  132. package/scripts/fix-declarations.mjs +27 -0
  133. package/scripts/generate-notices.mjs +176 -0
  134. package/scripts/notices/README.md +13 -0
  135. package/scripts/notices/cheerio-MIT.txt +21 -0
  136. package/scripts/notices/html5ever-AUTHORS.txt +20 -0
  137. package/scripts/notices/html5ever-COPYRIGHT.txt +8 -0
  138. package/scripts/notices/html5ever-LICENSE-APACHE.txt +201 -0
  139. package/scripts/notices/html5ever-LICENSE-MIT.txt +25 -0
  140. package/scripts/notices/napi-rs-MIT.txt +43 -0
  141. package/scripts/notices/neon-MIT.txt +19 -0
  142. package/scripts/notices/runtime-01c266bced4a434da005.txt +3 -0
  143. package/scripts/notices/runtime-0a54e647fe54104658b5.txt +14 -0
  144. package/scripts/notices/runtime-0b74dfa0bcee5c420c6b.txt +25 -0
  145. package/scripts/notices/runtime-0d542e0c8804e39aa7f3.txt +177 -0
  146. package/scripts/notices/runtime-0f96a83840e146e43c0e.txt +21 -0
  147. package/scripts/notices/runtime-123a331b5dbf04c30097.txt +25 -0
  148. package/scripts/notices/runtime-172020dbfd5b53a226df.txt +34 -0
  149. package/scripts/notices/runtime-209fbbe0ad52d9235e37.txt +26 -0
  150. package/scripts/notices/runtime-23f18e03dc49df91622f.txt +23 -0
  151. package/scripts/notices/runtime-268872b9816f90fd8e85.txt +220 -0
  152. package/scripts/notices/runtime-35242e7a83f69875e6ed.txt +176 -0
  153. package/scripts/notices/runtime-378f5840b258e2779c39.txt +25 -0
  154. package/scripts/notices/runtime-4108245a1f2df9d4e94d.txt +25 -0
  155. package/scripts/notices/runtime-4455bf75a91154108304.txt +21 -0
  156. package/scripts/notices/runtime-553fffcd9b1cb158bc3e.txt +13 -0
  157. package/scripts/notices/runtime-62c7a1e35f56406896d7.txt +176 -0
  158. package/scripts/notices/runtime-6485b8ed310d3f0340bf.txt +25 -0
  159. package/scripts/notices/runtime-69fef7b0f322a6555415.txt +201 -0
  160. package/scripts/notices/runtime-6df43f6f4b5d4587f3d8.txt +187 -0
  161. package/scripts/notices/runtime-799e9ca9d179295ef372.txt +24 -0
  162. package/scripts/notices/runtime-7b63ecd5f1902af1b637.txt +25 -0
  163. package/scripts/notices/runtime-7bc7d5de2a0b793d4e1a.txt +21 -0
  164. package/scripts/notices/runtime-7e12e5df4bae12cb2158.txt +24 -0
  165. package/scripts/notices/runtime-861399f8c21c042b1105.txt +12 -0
  166. package/scripts/notices/runtime-8ada45cd9f843acf64e4.txt +201 -0
  167. package/scripts/notices/runtime-90eb64f0279b0d9432ac.txt +12 -0
  168. package/scripts/notices/runtime-a60eea817514531668d7.txt +201 -0
  169. package/scripts/notices/runtime-a7c936ff1ed8fa340172.txt +25 -0
  170. package/scripts/notices/runtime-ab6eec6caf0fa5775e41.txt +275 -0
  171. package/scripts/notices/runtime-b1181a40b2a7b25cf66f.txt +19 -0
  172. package/scripts/notices/runtime-b71bd43a069ca0641a9e.txt +25 -0
  173. package/scripts/notices/runtime-c16f8dcf1a368b83be78.txt +201 -0
  174. package/scripts/notices/runtime-c2cfccb812fe482101a8.txt +21 -0
  175. package/scripts/notices/runtime-e99d88d232bf57d70f0f.txt +25 -0
  176. package/scripts/notices/runtime-f32fb3b417a194167cfa.txt +9 -0
  177. package/scripts/notices/runtime-f5062c9a188d81dfe66b.txt +39 -0
  178. package/scripts/notices/runtime-f9070a832833fa7488fd.txt +4 -0
  179. package/scripts/notices/runtime-fab3dd6bdab226f1c086.txt +373 -0
  180. package/scripts/notices/runtime-fba3318d0c600380177e.txt +62 -0
  181. package/scripts/notices/runtime-ff8f68cb076caf8cefe7.txt +25 -0
  182. package/scripts/notices/runtime-ff92bed461f50338dd70.txt +74 -0
  183. package/scripts/notices/runtime.json +1632 -0
  184. package/scripts/notices/sources.json +555 -0
  185. package/scripts/notices/xray-MIT.txt +21 -0
  186. package/src/attributes.ts +271 -0
  187. package/src/codec.ts +74 -0
  188. package/src/dom.ts +87 -0
  189. package/src/extract-plan.ts +97 -0
  190. package/src/extract.ts +130 -0
  191. package/src/hooks.ts +220 -0
  192. package/src/index.ts +223 -0
  193. package/src/io.ts +491 -0
  194. package/src/native.ts +135 -0
  195. package/src/nodes.ts +290 -0
  196. package/src/parse.ts +53 -0
  197. package/src/parser-types.ts +157 -0
  198. package/src/router.ts +327 -0
  199. package/src/selection.ts +566 -0
  200. package/src/slim.ts +12 -0
  201. package/src/transport.ts +104 -0
  202. package/src/types.ts +186 -0
  203. package/src/utils.ts +29 -0
  204. package/src/workers.ts +21 -0
  205. package/tsconfig.json +15 -0
  206. package/tsup.config.ts +16 -0
@@ -0,0 +1,356 @@
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
+ extern crate html5ever;
11
+ extern crate typed_arena;
12
+
13
+ use html5ever::interface::tree_builder::{ElementFlags, NodeOrText, QuirksMode, TreeSink};
14
+ use html5ever::tendril::{StrTendril, TendrilSink};
15
+ use html5ever::{parse_document, Attribute, QualName};
16
+ use std::borrow::Cow;
17
+ use std::cell::{Cell, RefCell};
18
+ use std::collections::HashSet;
19
+ use std::io::{self, Read};
20
+ use std::ptr;
21
+
22
+ /// By using our Sink type, the arena is filled with parsed HTML.
23
+ fn html5ever_parse_slice_into_arena<'a>(bytes: &[u8], arena: Arena<'a>) -> Ref<'a> {
24
+ let sink = Sink {
25
+ arena,
26
+ document: arena.alloc(Node::new(NodeData::Document)),
27
+ quirks_mode: Cell::new(QuirksMode::NoQuirks),
28
+ };
29
+
30
+ parse_document(sink, Default::default())
31
+ .from_utf8()
32
+ .one(bytes)
33
+ }
34
+
35
+ type Arena<'arena> = &'arena typed_arena::Arena<Node<'arena>>;
36
+ type Ref<'arena> = &'arena Node<'arena>;
37
+ type Link<'arena> = Cell<Option<Ref<'arena>>>;
38
+
39
+ /// Sink struct is responsible for handling how the data that comes out of the HTML parsing
40
+ /// unit (TreeBuilder in our case) is handled.
41
+ struct Sink<'arena> {
42
+ arena: Arena<'arena>,
43
+ document: Ref<'arena>,
44
+ quirks_mode: Cell<QuirksMode>,
45
+ }
46
+
47
+ /// DOM node which contains links to other nodes in the tree.
48
+ pub struct Node<'arena> {
49
+ parent: Link<'arena>,
50
+ next_sibling: Link<'arena>,
51
+ previous_sibling: Link<'arena>,
52
+ first_child: Link<'arena>,
53
+ last_child: Link<'arena>,
54
+ data: NodeData<'arena>,
55
+ }
56
+
57
+ /// HTML node data which can be an element, a comment, a string, a DOCTYPE, etc...
58
+ pub enum NodeData<'arena> {
59
+ Document,
60
+ Doctype {
61
+ name: StrTendril,
62
+ public_id: StrTendril,
63
+ system_id: StrTendril,
64
+ },
65
+ Text {
66
+ contents: RefCell<StrTendril>,
67
+ },
68
+ Comment {
69
+ contents: StrTendril,
70
+ },
71
+ Element {
72
+ name: QualName,
73
+ attrs: RefCell<Vec<Attribute>>,
74
+ template_contents: Option<Ref<'arena>>,
75
+ mathml_annotation_xml_integration_point: bool,
76
+ },
77
+ ProcessingInstruction {
78
+ target: StrTendril,
79
+ contents: StrTendril,
80
+ },
81
+ }
82
+
83
+ impl<'arena> Node<'arena> {
84
+ fn new(data: NodeData<'arena>) -> Self {
85
+ Node {
86
+ parent: Cell::new(None),
87
+ previous_sibling: Cell::new(None),
88
+ next_sibling: Cell::new(None),
89
+ first_child: Cell::new(None),
90
+ last_child: Cell::new(None),
91
+ data,
92
+ }
93
+ }
94
+
95
+ fn detach(&self) {
96
+ let parent = self.parent.take();
97
+ let previous_sibling = self.previous_sibling.take();
98
+ let next_sibling = self.next_sibling.take();
99
+
100
+ if let Some(next_sibling) = next_sibling {
101
+ next_sibling.previous_sibling.set(previous_sibling);
102
+ } else if let Some(parent) = parent {
103
+ parent.last_child.set(previous_sibling);
104
+ }
105
+
106
+ if let Some(previous_sibling) = previous_sibling {
107
+ previous_sibling.next_sibling.set(next_sibling);
108
+ } else if let Some(parent) = parent {
109
+ parent.first_child.set(next_sibling);
110
+ }
111
+ }
112
+
113
+ fn append(&'arena self, new_child: &'arena Self) {
114
+ new_child.detach();
115
+ new_child.parent.set(Some(self));
116
+ if let Some(last_child) = self.last_child.take() {
117
+ new_child.previous_sibling.set(Some(last_child));
118
+ debug_assert!(last_child.next_sibling.get().is_none());
119
+ last_child.next_sibling.set(Some(new_child));
120
+ } else {
121
+ debug_assert!(self.first_child.get().is_none());
122
+ self.first_child.set(Some(new_child));
123
+ }
124
+ self.last_child.set(Some(new_child));
125
+ }
126
+
127
+ fn insert_before(&'arena self, new_sibling: &'arena Self) {
128
+ new_sibling.detach();
129
+ new_sibling.parent.set(self.parent.get());
130
+ new_sibling.next_sibling.set(Some(self));
131
+ if let Some(previous_sibling) = self.previous_sibling.take() {
132
+ new_sibling.previous_sibling.set(Some(previous_sibling));
133
+ debug_assert!(ptr::eq::<Node>(
134
+ previous_sibling.next_sibling.get().unwrap(),
135
+ self
136
+ ));
137
+ previous_sibling.next_sibling.set(Some(new_sibling));
138
+ } else if let Some(parent) = self.parent.get() {
139
+ debug_assert!(ptr::eq::<Node>(parent.first_child.get().unwrap(), self));
140
+ parent.first_child.set(Some(new_sibling));
141
+ }
142
+ self.previous_sibling.set(Some(new_sibling));
143
+ }
144
+ }
145
+
146
+ impl<'arena> Sink<'arena> {
147
+ fn new_node(&self, data: NodeData<'arena>) -> Ref<'arena> {
148
+ self.arena.alloc(Node::new(data))
149
+ }
150
+
151
+ fn append_common<P, A>(&self, child: NodeOrText<Ref<'arena>>, previous: P, append: A)
152
+ where
153
+ P: FnOnce() -> Option<Ref<'arena>>,
154
+ A: FnOnce(Ref<'arena>),
155
+ {
156
+ let new_node = match child {
157
+ NodeOrText::AppendText(text) => {
158
+ // Append to an existing Text node if we have one.
159
+ if let Some(&Node {
160
+ data: NodeData::Text { ref contents },
161
+ ..
162
+ }) = previous()
163
+ {
164
+ contents.borrow_mut().push_tendril(&text);
165
+ return;
166
+ }
167
+ self.new_node(NodeData::Text {
168
+ contents: RefCell::new(text),
169
+ })
170
+ },
171
+ NodeOrText::AppendNode(node) => node,
172
+ };
173
+
174
+ append(new_node)
175
+ }
176
+ }
177
+
178
+ /// By implementing the TreeSink trait we determine how the data from the tree building step
179
+ /// is processed. In our case, our data is allocated in the arena and added to the Node data
180
+ /// structure.
181
+ ///
182
+ /// For deeper understating of each function go to the TreeSink declaration.
183
+ impl<'arena> TreeSink for Sink<'arena> {
184
+ type Handle = Ref<'arena>;
185
+ type Output = Ref<'arena>;
186
+ type ElemName<'a>
187
+ = &'a QualName
188
+ where
189
+ Self: 'a;
190
+
191
+ fn finish(self) -> Ref<'arena> {
192
+ self.document
193
+ }
194
+
195
+ fn parse_error(&self, _: Cow<'static, str>) {}
196
+
197
+ fn get_document(&self) -> Ref<'arena> {
198
+ self.document
199
+ }
200
+
201
+ fn set_quirks_mode(&self, mode: QuirksMode) {
202
+ self.quirks_mode.set(mode);
203
+ }
204
+
205
+ fn same_node(&self, x: &Ref<'arena>, y: &Ref<'arena>) -> bool {
206
+ ptr::eq::<Node>(*x, *y)
207
+ }
208
+
209
+ fn elem_name(&self, target: &Ref<'arena>) -> Self::ElemName<'_> {
210
+ match target.data {
211
+ NodeData::Element { ref name, .. } => name,
212
+ _ => panic!("not an element!"),
213
+ }
214
+ }
215
+
216
+ fn get_template_contents(&self, target: &Ref<'arena>) -> Ref<'arena> {
217
+ if let NodeData::Element {
218
+ template_contents: Some(contents),
219
+ ..
220
+ } = target.data
221
+ {
222
+ contents
223
+ } else {
224
+ panic!("not a template element!")
225
+ }
226
+ }
227
+
228
+ fn is_mathml_annotation_xml_integration_point(&self, target: &Ref<'arena>) -> bool {
229
+ if let NodeData::Element {
230
+ mathml_annotation_xml_integration_point,
231
+ ..
232
+ } = target.data
233
+ {
234
+ mathml_annotation_xml_integration_point
235
+ } else {
236
+ panic!("not an element!")
237
+ }
238
+ }
239
+
240
+ fn create_element(
241
+ &self,
242
+ name: QualName,
243
+ attrs: Vec<Attribute>,
244
+ flags: ElementFlags,
245
+ ) -> Ref<'arena> {
246
+ self.new_node(NodeData::Element {
247
+ name,
248
+ attrs: RefCell::new(attrs),
249
+ template_contents: if flags.template {
250
+ Some(self.new_node(NodeData::Document))
251
+ } else {
252
+ None
253
+ },
254
+ mathml_annotation_xml_integration_point: flags.mathml_annotation_xml_integration_point,
255
+ })
256
+ }
257
+
258
+ fn create_comment(&self, text: StrTendril) -> Ref<'arena> {
259
+ self.new_node(NodeData::Comment { contents: text })
260
+ }
261
+
262
+ fn create_pi(&self, target: StrTendril, data: StrTendril) -> Ref<'arena> {
263
+ self.new_node(NodeData::ProcessingInstruction {
264
+ target,
265
+ contents: data,
266
+ })
267
+ }
268
+
269
+ fn append(&self, parent: &Ref<'arena>, child: NodeOrText<Ref<'arena>>) {
270
+ self.append_common(
271
+ child,
272
+ || parent.last_child.get(),
273
+ |new_node| parent.append(new_node),
274
+ )
275
+ }
276
+
277
+ fn append_before_sibling(&self, sibling: &Ref<'arena>, child: NodeOrText<Ref<'arena>>) {
278
+ self.append_common(
279
+ child,
280
+ || sibling.previous_sibling.get(),
281
+ |new_node| sibling.insert_before(new_node),
282
+ )
283
+ }
284
+
285
+ fn append_based_on_parent_node(
286
+ &self,
287
+ element: &Ref<'arena>,
288
+ prev_element: &Ref<'arena>,
289
+ child: NodeOrText<Ref<'arena>>,
290
+ ) {
291
+ if element.parent.get().is_some() {
292
+ self.append_before_sibling(element, child)
293
+ } else {
294
+ self.append(prev_element, child)
295
+ }
296
+ }
297
+
298
+ fn append_doctype_to_document(
299
+ &self,
300
+ name: StrTendril,
301
+ public_id: StrTendril,
302
+ system_id: StrTendril,
303
+ ) {
304
+ self.document.append(self.new_node(NodeData::Doctype {
305
+ name,
306
+ public_id,
307
+ system_id,
308
+ }))
309
+ }
310
+
311
+ fn add_attrs_if_missing(&self, target: &Ref<'arena>, attrs: Vec<Attribute>) {
312
+ let mut existing = if let NodeData::Element { ref attrs, .. } = target.data {
313
+ attrs.borrow_mut()
314
+ } else {
315
+ panic!("not an element")
316
+ };
317
+
318
+ let existing_names = existing
319
+ .iter()
320
+ .map(|e| e.name.clone())
321
+ .collect::<HashSet<_>>();
322
+ existing.extend(
323
+ attrs
324
+ .into_iter()
325
+ .filter(|attr| !existing_names.contains(&attr.name)),
326
+ );
327
+ }
328
+
329
+ fn remove_from_parent(&self, target: &Ref<'arena>) {
330
+ target.detach()
331
+ }
332
+
333
+ fn reparent_children(&self, node: &Ref<'arena>, new_parent: &Ref<'arena>) {
334
+ let mut next_child = node.first_child.get();
335
+ while let Some(child) = next_child {
336
+ debug_assert!(ptr::eq::<Node>(child.parent.get().unwrap(), *node));
337
+ next_child = child.next_sibling.get();
338
+ new_parent.append(child)
339
+ }
340
+ }
341
+ }
342
+
343
+ /// In this example an "arena" is created and filled with the DOM nodes.
344
+ /// "Arena" is a type of allocation in which a block of memory is allocated
345
+ /// and later filled with data, DOM nodes in this case. When the arena is deallocated
346
+ /// it is destroyed with all of its items.
347
+ ///
348
+ /// Further info about arena: https://docs.rs/typed-arena/latest/typed_arena/
349
+ fn main() {
350
+ // Read HTML from the standard input
351
+ let mut bytes = Vec::new();
352
+ io::stdin().read_to_end(&mut bytes).unwrap();
353
+
354
+ let arena = typed_arena::Arena::new();
355
+ html5ever_parse_slice_into_arena(&bytes, &arena);
356
+ }
@@ -0,0 +1,74 @@
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
+ #include <stdio.h>
11
+
12
+ #include "html5ever.h"
13
+
14
+ void put_str(const char *x) {
15
+ fputs(x, stdout);
16
+ }
17
+
18
+ void put_buf(struct h5e_buf text) {
19
+ fwrite(text.data, text.len, 1, stdout);
20
+ }
21
+
22
+ void do_chars(void *user, struct h5e_buf text) {
23
+ put_str("CHARS : ");
24
+ put_buf(text);
25
+ put_str("\n");
26
+ }
27
+
28
+ void do_start_tag(void *user, struct h5e_buf name, int self_closing, size_t num_attrs) {
29
+ put_str("TAG : <");
30
+ put_buf(name);
31
+ if (self_closing) {
32
+ putchar('/');
33
+ }
34
+ put_str(">\n");
35
+ }
36
+
37
+ void do_tag_attr(void *user, struct h5e_buf name, struct h5e_buf value) {
38
+ put_str(" ATTR: ");
39
+ put_buf(name);
40
+ put_str("=\"");
41
+ put_buf(value);
42
+ put_str("\"\n");
43
+ }
44
+
45
+ void do_end_tag(void *user, struct h5e_buf name) {
46
+ put_str("TAG : </");
47
+ put_buf(name);
48
+ put_str(">\n");
49
+ }
50
+
51
+ struct h5e_token_ops ops = {
52
+ .do_chars = do_chars,
53
+ .do_start_tag = do_start_tag,
54
+ .do_tag_attr = do_tag_attr,
55
+ .do_end_tag = do_end_tag,
56
+ };
57
+
58
+ struct h5e_token_sink sink = {
59
+ .ops = &ops,
60
+ .user = NULL,
61
+ };
62
+
63
+ int main(int argc, char *argv[]) {
64
+ if (argc < 2) {
65
+ printf("Usage: %s 'HTML fragment'\n", argv[0]);
66
+ return 1;
67
+ }
68
+
69
+ struct h5e_tokenizer *tok = h5e_tokenizer_new(&sink);
70
+ h5e_tokenizer_feed(tok, h5e_buf_from_cstr(argv[1]));
71
+ h5e_tokenizer_end(tok);
72
+ h5e_tokenizer_free(tok);
73
+ return 0;
74
+ }
@@ -0,0 +1,47 @@
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
+ // Run a single benchmark once. For use with profiling tools.
11
+
12
+ extern crate html5ever;
13
+
14
+ use std::cell::RefCell;
15
+ use std::io;
16
+
17
+ use html5ever::tendril::*;
18
+ use html5ever::tokenizer::{BufferQueue, Token, TokenSink, TokenSinkResult, Tokenizer};
19
+
20
+ /// In our case, our sink only contains a tokens vector
21
+ struct Sink(RefCell<Vec<Token>>);
22
+
23
+ impl TokenSink for Sink {
24
+ type Handle = ();
25
+
26
+ /// Each processed token will be handled by this method
27
+ fn process_token(&self, token: Token, _line_number: u64) -> TokenSinkResult<()> {
28
+ self.0.borrow_mut().push(token);
29
+ TokenSinkResult::Continue
30
+ }
31
+ }
32
+
33
+ /// In this example we implement the TokenSink trait which lets us implement how each
34
+ /// parsed token is treated. In our example we take each token and insert it into a vector.
35
+ fn main() {
36
+ // Read HTML from standard input
37
+ let mut chunk = ByteTendril::new();
38
+ io::stdin().read_to_tendril(&mut chunk).unwrap();
39
+
40
+ let input = BufferQueue::default();
41
+ input.push_back(chunk.try_reinterpret().unwrap());
42
+
43
+ let tok = Tokenizer::new(Sink(RefCell::new(Vec::new())), Default::default());
44
+ let _ = tok.feed(&input);
45
+ assert!(input.is_empty());
46
+ tok.end();
47
+ }
@@ -0,0 +1,132 @@
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::cell::{Cell, RefCell};
15
+ use std::collections::HashMap;
16
+ use std::io;
17
+
18
+ use html5ever::parse_document;
19
+ use html5ever::tendril::*;
20
+ use html5ever::tree_builder::{ElementFlags, NodeOrText, QuirksMode, TreeSink};
21
+ use html5ever::{Attribute, ExpandedName, QualName};
22
+
23
+ struct Sink {
24
+ next_id: Cell<usize>,
25
+ names: RefCell<HashMap<usize, &'static QualName>>,
26
+ }
27
+
28
+ impl Sink {
29
+ fn get_id(&self) -> usize {
30
+ let id = self.next_id.get();
31
+ self.next_id.set(id + 2);
32
+ id
33
+ }
34
+ }
35
+
36
+ /// By implementing the TreeSink trait we determine how the data from the tree building step
37
+ /// is processed. In this case the DOM elements are written into the "names" hashmap.
38
+ ///
39
+ /// For deeper understating of each function go to the TreeSink declaration.
40
+ impl TreeSink for Sink {
41
+ type Handle = usize;
42
+ type Output = Self;
43
+ type ElemName<'a> = ExpandedName<'a>;
44
+ fn finish(self) -> Self {
45
+ self
46
+ }
47
+
48
+ fn get_document(&self) -> usize {
49
+ 0
50
+ }
51
+
52
+ fn get_template_contents(&self, target: &usize) -> usize {
53
+ if let Some(expanded_name!(html "template")) =
54
+ self.names.borrow().get(target).map(|n| n.expanded())
55
+ {
56
+ target + 1
57
+ } else {
58
+ panic!("not a template element")
59
+ }
60
+ }
61
+
62
+ fn same_node(&self, x: &usize, y: &usize) -> bool {
63
+ x == y
64
+ }
65
+
66
+ fn elem_name(&self, target: &usize) -> ExpandedName {
67
+ self.names
68
+ .borrow()
69
+ .get(target)
70
+ .expect("not an element")
71
+ .expanded()
72
+ }
73
+
74
+ fn create_element(&self, name: QualName, _: Vec<Attribute>, _: ElementFlags) -> usize {
75
+ let id = self.get_id();
76
+ // N.B. We intentionally leak memory here to minimize the implementation complexity
77
+ // of this example code. A real implementation would either want to use a real
78
+ // real DOM tree implentation, or else use an arena as the backing store for
79
+ // memory used by the parser.
80
+ self.names
81
+ .borrow_mut()
82
+ .insert(id, Box::leak(Box::new(name)));
83
+ id
84
+ }
85
+
86
+ fn create_comment(&self, _text: StrTendril) -> usize {
87
+ self.get_id()
88
+ }
89
+
90
+ #[allow(unused_variables)]
91
+ fn create_pi(&self, target: StrTendril, value: StrTendril) -> usize {
92
+ unimplemented!()
93
+ }
94
+
95
+ fn append_before_sibling(&self, _sibling: &usize, _new_node: NodeOrText<usize>) {}
96
+
97
+ fn append_based_on_parent_node(
98
+ &self,
99
+ _element: &usize,
100
+ _prev_element: &usize,
101
+ _new_node: NodeOrText<usize>,
102
+ ) {
103
+ }
104
+
105
+ fn parse_error(&self, _msg: Cow<'static, str>) {}
106
+ fn set_quirks_mode(&self, _mode: QuirksMode) {}
107
+ fn append(&self, _parent: &usize, _child: NodeOrText<usize>) {}
108
+
109
+ fn append_doctype_to_document(&self, _: StrTendril, _: StrTendril, _: StrTendril) {}
110
+ fn add_attrs_if_missing(&self, target: &usize, _attrs: Vec<Attribute>) {
111
+ assert!(self.names.borrow().contains_key(target), "not an element");
112
+ }
113
+ fn remove_from_parent(&self, _target: &usize) {}
114
+ fn reparent_children(&self, _node: &usize, _new_parent: &usize) {}
115
+ fn mark_script_already_started(&self, _node: &usize) {}
116
+ }
117
+
118
+ /// In this example we implement the TreeSink trait which takes each parsed elements and insert
119
+ /// it to a hashmap, while each element is given a numeric id.
120
+ fn main() {
121
+ let sink = Sink {
122
+ next_id: Cell::new(1),
123
+ names: RefCell::new(HashMap::new()),
124
+ };
125
+
126
+ // Read HTML from the standard input and parse it
127
+ let stdin = io::stdin();
128
+ parse_document(sink, Default::default())
129
+ .from_utf8()
130
+ .read_from(&mut stdin.lock())
131
+ .unwrap();
132
+ }