rusteerio 0.0.0-stage → 0.1.1

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 +114 -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,2136 @@
1
+ use crate::entities::try_read_character_reference;
2
+ use crate::machine_helper::{
3
+ cont, emit_current_tag_and_switch_to, enter_state, eof, error, error_immediate, exit_state,
4
+ mutate_character_reference, read_byte, reconsume_in, reconsume_in_return_state, switch_to,
5
+ ControlToken,
6
+ };
7
+ use crate::read_helper::{fast_read_char, slow_read_byte};
8
+ use crate::utils::{ctostr, noncharacter_pat, surrogate_pat, with_lowercase_str};
9
+ use crate::{Emitter, Error, Reader, Tokenizer};
10
+
11
+ macro_rules! define_state {
12
+ ($state:ident, $slf:ident, $($body:tt)*) => {
13
+ #[allow(non_snake_case)]
14
+ pub(crate) mod $state {
15
+ use super::*;
16
+
17
+ #[inline(always)]
18
+ pub(crate) fn run<R: Reader, E: Emitter>($slf: &mut Tokenizer<R, E>) -> Result<ControlToken<R, E>, R::Error> {
19
+ $($body)*
20
+ }
21
+ }
22
+ };
23
+ }
24
+
25
+ pub(crate) mod states {
26
+ use super::*;
27
+
28
+ define_state!(Data, slf, {
29
+ slf.emitter.init_string();
30
+ fast_read_char!(
31
+ slf,
32
+ match xs {
33
+ Some(b"&") => {
34
+ enter_state!(slf, CharacterReference, false)
35
+ }
36
+ Some(b"<") => {
37
+ slf.emitter.start_open_tag();
38
+ switch_to!(slf, TagOpen)?.inline_next_state(slf)
39
+ }
40
+ Some(b"\0") => {
41
+ error!(slf, Error::UnexpectedNullCharacter);
42
+ slf.emitter.emit_string(b"\0");
43
+ cont!()
44
+ }
45
+ Some(xs) => {
46
+ slf.emitter.emit_string(xs);
47
+ cont!()
48
+ }
49
+ None => {
50
+ eof!()
51
+ }
52
+ }
53
+ )
54
+ });
55
+
56
+ define_state!(RcData, slf, {
57
+ slf.emitter.init_string();
58
+ fast_read_char!(
59
+ slf,
60
+ match xs {
61
+ Some(b"&") => {
62
+ enter_state!(slf, CharacterReference, false)
63
+ }
64
+ Some(b"<") => {
65
+ slf.emitter.start_open_tag();
66
+ switch_to!(slf, RcDataLessThanSign)
67
+ }
68
+ Some(b"\0") => {
69
+ error!(slf, Error::UnexpectedNullCharacter);
70
+ slf.emitter.emit_string("\u{fffd}".as_bytes());
71
+ cont!()
72
+ }
73
+ Some(xs) => {
74
+ slf.emitter.emit_string(xs);
75
+ cont!()
76
+ }
77
+ None => {
78
+ eof!()
79
+ }
80
+ }
81
+ )
82
+ });
83
+
84
+ define_state!(RawText, slf, {
85
+ fast_read_char!(
86
+ slf,
87
+ match xs {
88
+ Some(b"<") => {
89
+ slf.emitter.start_open_tag();
90
+ switch_to!(slf, RawTextLessThanSign)
91
+ }
92
+ Some(b"\0") => {
93
+ error!(slf, Error::UnexpectedNullCharacter);
94
+ slf.emitter.emit_string("\u{fffd}".as_bytes());
95
+ cont!()
96
+ }
97
+ Some(xs) => {
98
+ slf.emitter.emit_string(xs);
99
+ cont!()
100
+ }
101
+ None => {
102
+ eof!()
103
+ }
104
+ }
105
+ )
106
+ });
107
+
108
+ define_state!(ScriptData, slf, {
109
+ fast_read_char!(
110
+ slf,
111
+ match xs {
112
+ Some(b"<") => {
113
+ slf.emitter.start_open_tag();
114
+ switch_to!(slf, ScriptDataLessThanSign)
115
+ }
116
+ Some(b"\0") => {
117
+ error!(slf, Error::UnexpectedNullCharacter);
118
+ slf.emitter.emit_string("\u{fffd}".as_bytes());
119
+ cont!()
120
+ }
121
+ Some(xs) => {
122
+ slf.emitter.emit_string(xs);
123
+ cont!()
124
+ }
125
+ None => {
126
+ eof!()
127
+ }
128
+ }
129
+ )
130
+ });
131
+
132
+ define_state!(PlainText, slf, {
133
+ fast_read_char!(
134
+ slf,
135
+ match xs {
136
+ Some(b"\0") => {
137
+ error!(slf, Error::UnexpectedNullCharacter);
138
+ slf.emitter.emit_string("\u{fffd}".as_bytes());
139
+ cont!()
140
+ }
141
+ Some(xs) => {
142
+ slf.emitter.emit_string(xs);
143
+ cont!()
144
+ }
145
+ None => {
146
+ eof!()
147
+ }
148
+ }
149
+ )
150
+ });
151
+
152
+ define_state!(TagOpen, slf, {
153
+ slow_read_byte!(
154
+ slf,
155
+ match c {
156
+ Some(b'!') => {
157
+ switch_to!(slf, MarkupDeclarationOpen)
158
+ }
159
+ Some(b'/') => {
160
+ switch_to!(slf, EndTagOpen)?.inline_next_state(slf)
161
+ }
162
+ Some(x) if x.is_ascii_alphabetic() => {
163
+ slf.emitter.init_start_tag();
164
+ reconsume_in!(slf, Some(x), TagName)?.inline_next_state(slf)
165
+ }
166
+ c @ Some(b'?') => {
167
+ error!(slf, Error::UnexpectedQuestionMarkInsteadOfTagName);
168
+ slf.emitter.init_comment();
169
+ reconsume_in!(slf, c, BogusComment)
170
+ }
171
+ None => {
172
+ error!(slf, Error::EofBeforeTagName);
173
+ slf.emitter.emit_string(b"<");
174
+ eof!()
175
+ }
176
+ c @ Some(_) => {
177
+ error!(slf, Error::InvalidFirstCharacterOfTagName);
178
+ slf.emitter.move_position(-1);
179
+ slf.emitter.emit_string(b"<");
180
+ slf.emitter.move_position(1);
181
+ reconsume_in!(slf, c, Data)
182
+ }
183
+ }
184
+ )
185
+ });
186
+
187
+ define_state!(EndTagOpen, slf, {
188
+ slow_read_byte!(
189
+ slf,
190
+ match c {
191
+ Some(x) if x.is_ascii_alphabetic() => {
192
+ slf.emitter.init_end_tag();
193
+ reconsume_in!(slf, Some(x), TagName)
194
+ }
195
+ Some(b'>') => {
196
+ error!(slf, Error::MissingEndTagName);
197
+ switch_to!(slf, Data)
198
+ }
199
+ None => {
200
+ error!(slf, Error::EofBeforeTagName);
201
+ slf.emitter.emit_string(b"</");
202
+ eof!()
203
+ }
204
+ Some(x) => {
205
+ error!(slf, Error::InvalidFirstCharacterOfTagName);
206
+ slf.emitter.init_comment();
207
+ reconsume_in!(slf, Some(x), BogusComment)
208
+ }
209
+ }
210
+ )
211
+ });
212
+
213
+ define_state!(TagName, slf, {
214
+ fast_read_char!(
215
+ slf,
216
+ match xs {
217
+ Some(b"\t" | b"\x0A" | b"\x0C" | b" ") => {
218
+ switch_to!(slf, BeforeAttributeName)
219
+ }
220
+ Some(b"/") => {
221
+ switch_to!(slf, SelfClosingStartTag)
222
+ }
223
+ Some(b">") => {
224
+ // candidate for inline_next_state except it'd be cyclic
225
+ emit_current_tag_and_switch_to!(slf, Data)
226
+ }
227
+ Some(b"\0") => {
228
+ error!(slf, Error::UnexpectedNullCharacter);
229
+ slf.emitter.push_tag_name("\u{fffd}".as_bytes());
230
+ cont!()
231
+ }
232
+ Some(xs) => {
233
+ let emitter = &mut slf.emitter;
234
+ with_lowercase_str(xs, |x| {
235
+ emitter.push_tag_name(x);
236
+ });
237
+
238
+ cont!()
239
+ }
240
+ None => {
241
+ error!(slf, Error::EofInTag);
242
+ eof!()
243
+ }
244
+ }
245
+ )
246
+ });
247
+
248
+ define_state!(RcDataLessThanSign, slf, {
249
+ slow_read_byte!(
250
+ slf,
251
+ match c {
252
+ Some(b'/') => {
253
+ slf.machine_helper.temporary_buffer.clear();
254
+ switch_to!(slf, RcDataEndTagOpen)
255
+ }
256
+ c => {
257
+ slf.emitter.move_position(-1);
258
+ slf.emitter.emit_string(b"<");
259
+ slf.emitter.move_position(1);
260
+ reconsume_in!(slf, c, RcData)
261
+ }
262
+ }
263
+ )
264
+ });
265
+
266
+ define_state!(RcDataEndTagOpen, slf, {
267
+ slow_read_byte!(
268
+ slf,
269
+ match c {
270
+ Some(x) if x.is_ascii_alphabetic() => {
271
+ slf.emitter.init_end_tag();
272
+ reconsume_in!(slf, Some(x), RcDataEndTagName)
273
+ }
274
+ c => {
275
+ slf.emitter.move_position(-1);
276
+ slf.emitter.emit_string(b"</");
277
+ slf.emitter.move_position(1);
278
+ reconsume_in!(slf, c, RcData)
279
+ }
280
+ }
281
+ )
282
+ });
283
+
284
+ define_state!(RcDataEndTagName, slf, {
285
+ slow_read_byte!(
286
+ slf,
287
+ match c {
288
+ Some(b'\t' | b'\x0A' | b'\x0C' | b' ')
289
+ if slf.emitter.current_is_appropriate_end_tag_token() =>
290
+ {
291
+ switch_to!(slf, BeforeAttributeName)
292
+ }
293
+ Some(b'/') if slf.emitter.current_is_appropriate_end_tag_token() => {
294
+ switch_to!(slf, SelfClosingStartTag)
295
+ }
296
+ Some(b'>') if slf.emitter.current_is_appropriate_end_tag_token() => {
297
+ emit_current_tag_and_switch_to!(slf, Data)
298
+ }
299
+ Some(x) if x.is_ascii_alphabetic() => {
300
+ slf.emitter.push_tag_name(&[x.to_ascii_lowercase()]);
301
+ slf.machine_helper.temporary_buffer.push(x);
302
+ cont!()
303
+ }
304
+ c => {
305
+ slf.emitter.move_position(-1);
306
+ slf.emitter.emit_string(b"</");
307
+ slf.machine_helper.flush_buffer_characters(&mut slf.emitter);
308
+ slf.emitter.move_position(1);
309
+ reconsume_in!(slf, c, RcData)
310
+ }
311
+ }
312
+ )
313
+ });
314
+
315
+ define_state!(RawTextLessThanSign, slf, {
316
+ slow_read_byte!(
317
+ slf,
318
+ match c {
319
+ Some(b'/') => {
320
+ slf.machine_helper.temporary_buffer.clear();
321
+ switch_to!(slf, RawTextEndTagOpen)
322
+ }
323
+ c => {
324
+ slf.emitter.move_position(-1);
325
+ slf.emitter.emit_string(b"<");
326
+ slf.emitter.move_position(1);
327
+ reconsume_in!(slf, c, RawText)
328
+ }
329
+ }
330
+ )
331
+ });
332
+
333
+ define_state!(RawTextEndTagOpen, slf, {
334
+ slow_read_byte!(
335
+ slf,
336
+ match c {
337
+ Some(x) if x.is_ascii_alphabetic() => {
338
+ slf.emitter.init_end_tag();
339
+ reconsume_in!(slf, Some(x), RawTextEndTagName)
340
+ }
341
+ c => {
342
+ slf.emitter.move_position(-1);
343
+ slf.emitter.emit_string(b"</");
344
+ slf.emitter.move_position(1);
345
+ reconsume_in!(slf, c, RawText)
346
+ }
347
+ }
348
+ )
349
+ });
350
+
351
+ define_state!(RawTextEndTagName, slf, {
352
+ slow_read_byte!(
353
+ slf,
354
+ match c {
355
+ Some(b'\t' | b'\x0A' | b'\x0C' | b' ')
356
+ if slf.emitter.current_is_appropriate_end_tag_token() =>
357
+ {
358
+ switch_to!(slf, BeforeAttributeName)
359
+ }
360
+ Some(b'/') if slf.emitter.current_is_appropriate_end_tag_token() => {
361
+ switch_to!(slf, SelfClosingStartTag)
362
+ }
363
+ Some(b'>') if slf.emitter.current_is_appropriate_end_tag_token() => {
364
+ emit_current_tag_and_switch_to!(slf, Data)
365
+ }
366
+ Some(x) if x.is_ascii_alphabetic() => {
367
+ slf.emitter.push_tag_name(&[x.to_ascii_lowercase()]);
368
+ slf.machine_helper.temporary_buffer.push(x);
369
+ cont!()
370
+ }
371
+ c => {
372
+ slf.emitter.move_position(-1);
373
+ slf.emitter.emit_string(b"</");
374
+ slf.machine_helper.flush_buffer_characters(&mut slf.emitter);
375
+ slf.emitter.move_position(1);
376
+ reconsume_in!(slf, c, RawText)
377
+ }
378
+ }
379
+ )
380
+ });
381
+
382
+ define_state!(ScriptDataLessThanSign, slf, {
383
+ slow_read_byte!(
384
+ slf,
385
+ match c {
386
+ Some(b'/') => {
387
+ slf.machine_helper.temporary_buffer.clear();
388
+ switch_to!(slf, ScriptDataEndTagOpen)
389
+ }
390
+ Some(b'!') => {
391
+ slf.emitter.emit_string(b"<!");
392
+ switch_to!(slf, ScriptDataEscapeStart)
393
+ }
394
+ c => {
395
+ slf.emitter.move_position(-1);
396
+ slf.emitter.emit_string(b"<");
397
+ slf.emitter.move_position(1);
398
+ reconsume_in!(slf, c, ScriptData)
399
+ }
400
+ }
401
+ )
402
+ });
403
+
404
+ define_state!(ScriptDataEndTagOpen, slf, {
405
+ slow_read_byte!(
406
+ slf,
407
+ match c {
408
+ Some(x) if x.is_ascii_alphabetic() => {
409
+ slf.emitter.init_end_tag();
410
+ reconsume_in!(slf, Some(x), ScriptDataEndTagName)
411
+ }
412
+ c => {
413
+ slf.emitter.move_position(-1);
414
+ slf.emitter.emit_string(b"</");
415
+ slf.emitter.move_position(1);
416
+ reconsume_in!(slf, c, ScriptData)
417
+ }
418
+ }
419
+ )
420
+ });
421
+
422
+ define_state!(ScriptDataEndTagName, slf, {
423
+ slow_read_byte!(
424
+ slf,
425
+ match c {
426
+ Some(b'\t' | b'\x0A' | b'\x0C' | b' ')
427
+ if slf.emitter.current_is_appropriate_end_tag_token() =>
428
+ {
429
+ switch_to!(slf, BeforeAttributeName)
430
+ }
431
+ Some(b'/') if slf.emitter.current_is_appropriate_end_tag_token() => {
432
+ switch_to!(slf, SelfClosingStartTag)
433
+ }
434
+ Some(b'>') if slf.emitter.current_is_appropriate_end_tag_token() => {
435
+ emit_current_tag_and_switch_to!(slf, Data)
436
+ }
437
+ Some(x) if x.is_ascii_alphabetic() => {
438
+ slf.emitter.push_tag_name(&[x.to_ascii_lowercase()]);
439
+ slf.machine_helper.temporary_buffer.push(x);
440
+ cont!()
441
+ }
442
+ c => {
443
+ slf.emitter.move_position(-1);
444
+ slf.emitter.emit_string(b"</");
445
+ slf.machine_helper.flush_buffer_characters(&mut slf.emitter);
446
+ slf.emitter.move_position(1);
447
+ reconsume_in!(slf, c, ScriptData)
448
+ }
449
+ }
450
+ )
451
+ });
452
+
453
+ define_state!(ScriptDataEscapeStart, slf, {
454
+ slow_read_byte!(
455
+ slf,
456
+ match c {
457
+ Some(b'-') => {
458
+ slf.emitter.emit_string(b"-");
459
+ switch_to!(slf, ScriptDataEscapeStartDash)
460
+ }
461
+ c => {
462
+ reconsume_in!(slf, c, ScriptData)
463
+ }
464
+ }
465
+ )
466
+ });
467
+
468
+ define_state!(ScriptDataEscapeStartDash, slf, {
469
+ slow_read_byte!(
470
+ slf,
471
+ match c {
472
+ Some(b'-') => {
473
+ slf.emitter.emit_string(b"-");
474
+ switch_to!(slf, ScriptDataEscapedDashDash)
475
+ }
476
+ c => {
477
+ reconsume_in!(slf, c, ScriptData)
478
+ }
479
+ }
480
+ )
481
+ });
482
+
483
+ define_state!(ScriptDataEscaped, slf, {
484
+ fast_read_char!(
485
+ slf,
486
+ match xs {
487
+ Some(b"-") => {
488
+ slf.emitter.emit_string(b"-");
489
+ switch_to!(slf, ScriptDataEscapedDash)
490
+ }
491
+ Some(b"<") => {
492
+ slf.emitter.start_open_tag();
493
+ switch_to!(slf, ScriptDataEscapedLessThanSign)
494
+ }
495
+ Some(b"\0") => {
496
+ error!(slf, Error::UnexpectedNullCharacter);
497
+ slf.emitter.emit_string("\u{fffd}".as_bytes());
498
+ cont!()
499
+ }
500
+ Some(xs) => {
501
+ slf.emitter.emit_string(xs);
502
+ cont!()
503
+ }
504
+ None => {
505
+ error!(slf, Error::EofInScriptHtmlCommentLikeText);
506
+ eof!()
507
+ }
508
+ }
509
+ )
510
+ });
511
+
512
+ define_state!(ScriptDataEscapedDash, slf, {
513
+ slow_read_byte!(
514
+ slf,
515
+ match c {
516
+ Some(b'-') => {
517
+ slf.emitter.emit_string(b"-");
518
+ switch_to!(slf, ScriptDataEscapedDashDash)
519
+ }
520
+ Some(b'<') => {
521
+ slf.emitter.start_open_tag();
522
+ switch_to!(slf, ScriptDataEscapedLessThanSign)
523
+ }
524
+ Some(b'\0') => {
525
+ error!(slf, Error::UnexpectedNullCharacter);
526
+ slf.emitter.emit_string("\u{fffd}".as_bytes());
527
+ switch_to!(slf, ScriptDataEscaped)
528
+ }
529
+ Some(x) => {
530
+ slf.emitter.emit_string(&[x]);
531
+ switch_to!(slf, ScriptDataEscaped)
532
+ }
533
+ None => {
534
+ error!(slf, Error::EofInScriptHtmlCommentLikeText);
535
+ eof!()
536
+ }
537
+ }
538
+ )
539
+ });
540
+
541
+ define_state!(ScriptDataEscapedDashDash, slf, {
542
+ slow_read_byte!(
543
+ slf,
544
+ match c {
545
+ Some(b'-') => {
546
+ slf.emitter.emit_string(b"-");
547
+ cont!()
548
+ }
549
+ Some(b'<') => {
550
+ slf.emitter.start_open_tag();
551
+ switch_to!(slf, ScriptDataEscapedLessThanSign)
552
+ }
553
+ Some(b'>') => {
554
+ slf.emitter.emit_string(b">");
555
+ switch_to!(slf, ScriptData)
556
+ }
557
+ Some(b'\0') => {
558
+ error!(slf, Error::UnexpectedNullCharacter);
559
+ slf.emitter.emit_string("\u{fffd}".as_bytes());
560
+ switch_to!(slf, ScriptDataEscaped)
561
+ }
562
+ Some(x) => {
563
+ slf.emitter.emit_string(&[x]);
564
+ switch_to!(slf, ScriptDataEscaped)
565
+ }
566
+ None => {
567
+ error!(slf, Error::EofInScriptHtmlCommentLikeText);
568
+ eof!()
569
+ }
570
+ }
571
+ )
572
+ });
573
+
574
+ define_state!(ScriptDataEscapedLessThanSign, slf, {
575
+ slow_read_byte!(
576
+ slf,
577
+ match c {
578
+ Some(b'/') => {
579
+ slf.machine_helper.temporary_buffer.clear();
580
+ switch_to!(slf, ScriptDataEscapedEndTagOpen)
581
+ }
582
+ Some(x) if x.is_ascii_alphabetic() => {
583
+ slf.machine_helper.temporary_buffer.clear();
584
+ slf.emitter.emit_string(b"<");
585
+ reconsume_in!(slf, Some(x), ScriptDataDoubleEscapeStart)
586
+ }
587
+ c => {
588
+ slf.emitter.move_position(-1);
589
+ slf.emitter.emit_string(b"<");
590
+ slf.emitter.move_position(1);
591
+ reconsume_in!(slf, c, ScriptDataEscaped)
592
+ }
593
+ }
594
+ )
595
+ });
596
+
597
+ define_state!(ScriptDataEscapedEndTagOpen, slf, {
598
+ slow_read_byte!(
599
+ slf,
600
+ match c {
601
+ Some(x) if x.is_ascii_alphabetic() => {
602
+ slf.emitter.init_end_tag();
603
+ reconsume_in!(slf, Some(x), ScriptDataEscapedEndTagName)
604
+ }
605
+ c => {
606
+ slf.emitter.move_position(-1);
607
+ slf.emitter.emit_string(b"</");
608
+ slf.emitter.move_position(1);
609
+ reconsume_in!(slf, c, ScriptDataEscaped)
610
+ }
611
+ }
612
+ )
613
+ });
614
+
615
+ define_state!(ScriptDataEscapedEndTagName, slf, {
616
+ slow_read_byte!(
617
+ slf,
618
+ match c {
619
+ Some(b'\t' | b'\x0A' | b'\x0C' | b' ')
620
+ if slf.emitter.current_is_appropriate_end_tag_token() =>
621
+ {
622
+ switch_to!(slf, BeforeAttributeName)
623
+ }
624
+ Some(b'/') if slf.emitter.current_is_appropriate_end_tag_token() => {
625
+ switch_to!(slf, SelfClosingStartTag)
626
+ }
627
+ Some(b'>') if slf.emitter.current_is_appropriate_end_tag_token() => {
628
+ emit_current_tag_and_switch_to!(slf, Data)
629
+ }
630
+ Some(x) if x.is_ascii_alphabetic() => {
631
+ slf.emitter.push_tag_name(&[x.to_ascii_lowercase()]);
632
+ slf.machine_helper.temporary_buffer.extend(&[x]);
633
+ cont!()
634
+ }
635
+ c => {
636
+ slf.emitter.move_position(-1);
637
+ slf.emitter.emit_string(b"</");
638
+ slf.machine_helper.flush_buffer_characters(&mut slf.emitter);
639
+ slf.emitter.move_position(1);
640
+ reconsume_in!(slf, c, ScriptDataEscaped)
641
+ }
642
+ }
643
+ )
644
+ });
645
+
646
+ define_state!(ScriptDataDoubleEscapeStart, slf, {
647
+ slow_read_byte!(
648
+ slf,
649
+ match c {
650
+ Some(x @ (b'\t' | b'\x0A' | b'\x0C' | b' ' | b'/' | b'>')) => {
651
+ slf.emitter.emit_string(&[x]);
652
+ if slf.machine_helper.temporary_buffer == b"script" {
653
+ switch_to!(slf, ScriptDataDoubleEscaped)
654
+ } else {
655
+ switch_to!(slf, ScriptDataEscaped)
656
+ }
657
+ }
658
+ Some(x) if x.is_ascii_alphabetic() => {
659
+ slf.machine_helper
660
+ .temporary_buffer
661
+ .push(x.to_ascii_lowercase());
662
+ slf.emitter.emit_string(&[x]);
663
+ cont!()
664
+ }
665
+ c => {
666
+ reconsume_in!(slf, c, ScriptDataEscaped)
667
+ }
668
+ }
669
+ )
670
+ });
671
+
672
+ define_state!(ScriptDataDoubleEscaped, slf, {
673
+ fast_read_char!(
674
+ slf,
675
+ match xs {
676
+ Some(b"-") => {
677
+ slf.emitter.emit_string(b"-");
678
+ switch_to!(slf, ScriptDataDoubleEscapedDash)
679
+ }
680
+ Some(b"<") => {
681
+ slf.emitter.emit_string(b"<");
682
+ switch_to!(slf, ScriptDataDoubleEscapedLessThanSign)
683
+ }
684
+ Some(b"\0") => {
685
+ error!(slf, Error::UnexpectedNullCharacter);
686
+ slf.emitter.emit_string("\u{fffd}".as_bytes());
687
+ cont!()
688
+ }
689
+ Some(xs) => {
690
+ slf.emitter.emit_string(xs);
691
+ cont!()
692
+ }
693
+ None => {
694
+ error!(slf, Error::EofInScriptHtmlCommentLikeText);
695
+ eof!()
696
+ }
697
+ }
698
+ )
699
+ });
700
+
701
+ define_state!(ScriptDataDoubleEscapedDash, slf, {
702
+ slow_read_byte!(
703
+ slf,
704
+ match c {
705
+ Some(b'-') => {
706
+ slf.emitter.emit_string(b"-");
707
+ switch_to!(slf, ScriptDataDoubleEscapedDashDash)
708
+ }
709
+ Some(b'<') => {
710
+ slf.emitter.emit_string(b"<");
711
+ switch_to!(slf, ScriptDataDoubleEscapedLessThanSign)
712
+ }
713
+ Some(b'\0') => {
714
+ error!(slf, Error::UnexpectedNullCharacter);
715
+ slf.emitter.emit_string("\u{fffd}".as_bytes());
716
+ switch_to!(slf, ScriptDataDoubleEscaped)
717
+ }
718
+ Some(x) => {
719
+ slf.emitter.emit_string(&[x]);
720
+ switch_to!(slf, ScriptDataDoubleEscaped)
721
+ }
722
+ None => {
723
+ error!(slf, Error::EofInScriptHtmlCommentLikeText);
724
+ eof!()
725
+ }
726
+ }
727
+ )
728
+ });
729
+
730
+ define_state!(ScriptDataDoubleEscapedDashDash, slf, {
731
+ slow_read_byte!(
732
+ slf,
733
+ match c {
734
+ Some(b'-') => {
735
+ slf.emitter.emit_string(b"-");
736
+ cont!()
737
+ }
738
+ Some(b'<') => {
739
+ slf.emitter.emit_string(b"<");
740
+ switch_to!(slf, ScriptDataDoubleEscapedLessThanSign)
741
+ }
742
+ Some(b'>') => {
743
+ slf.emitter.emit_string(b">");
744
+ switch_to!(slf, ScriptData)
745
+ }
746
+ Some(b'\0') => {
747
+ error!(slf, Error::UnexpectedNullCharacter);
748
+ slf.emitter.emit_string("\u{fffd}".as_bytes());
749
+ switch_to!(slf, ScriptDataDoubleEscaped)
750
+ }
751
+ Some(x) => {
752
+ slf.emitter.emit_string(&[x]);
753
+ switch_to!(slf, ScriptDataDoubleEscaped)
754
+ }
755
+ None => {
756
+ error!(slf, Error::EofInScriptHtmlCommentLikeText);
757
+ eof!()
758
+ }
759
+ }
760
+ )
761
+ });
762
+
763
+ define_state!(ScriptDataDoubleEscapedLessThanSign, slf, {
764
+ slow_read_byte!(
765
+ slf,
766
+ match c {
767
+ Some(b'/') => {
768
+ slf.machine_helper.temporary_buffer.clear();
769
+ slf.emitter.emit_string(b"/");
770
+ switch_to!(slf, ScriptDataDoubleEscapeEnd)
771
+ }
772
+ c => {
773
+ reconsume_in!(slf, c, ScriptDataDoubleEscaped)
774
+ }
775
+ }
776
+ )
777
+ });
778
+
779
+ define_state!(ScriptDataDoubleEscapeEnd, slf, {
780
+ slow_read_byte!(
781
+ slf,
782
+ match c {
783
+ Some(x @ (b'\t' | b'\x0A' | b'\x0C' | b' ' | b'/' | b'>')) => {
784
+ slf.emitter.emit_string(&[x]);
785
+
786
+ if slf.machine_helper.temporary_buffer == b"script" {
787
+ switch_to!(slf, ScriptDataEscaped)
788
+ } else {
789
+ switch_to!(slf, ScriptDataDoubleEscaped)
790
+ }
791
+ }
792
+ Some(x) if x.is_ascii_alphabetic() => {
793
+ slf.machine_helper
794
+ .temporary_buffer
795
+ .push(x.to_ascii_lowercase());
796
+ slf.emitter.emit_string(&[x]);
797
+ cont!()
798
+ }
799
+ c => {
800
+ reconsume_in!(slf, c, ScriptDataDoubleEscaped)
801
+ }
802
+ }
803
+ )
804
+ });
805
+
806
+ define_state!(BeforeAttributeName, slf, {
807
+ slow_read_byte!(
808
+ slf,
809
+ match c {
810
+ Some(b'\t' | b'\x0A' | b'\x0C' | b' ') => cont!(),
811
+ c @ (Some(b'/' | b'>') | None) => {
812
+ reconsume_in!(slf, c, AfterAttributeName)?.inline_next_state(slf)
813
+ }
814
+ Some(b'=') => {
815
+ error!(slf, Error::UnexpectedEqualsSignBeforeAttributeName);
816
+ slf.emitter.init_attribute();
817
+ slf.emitter.push_attribute_name(b"=");
818
+ switch_to!(slf, AttributeName)
819
+ }
820
+ Some(x) => {
821
+ slf.emitter.init_attribute();
822
+ reconsume_in!(slf, Some(x), AttributeName)?.inline_next_state(slf)
823
+ }
824
+ }
825
+ )
826
+ });
827
+
828
+ define_state!(AttributeName, slf, {
829
+ fast_read_char!(
830
+ slf,
831
+ match xs {
832
+ Some(b"\t" | b"\x0A" | b"\x0C" | b" " | b"/" | b">") => {
833
+ reconsume_in!(slf, Some(xs.unwrap()[0]), AfterAttributeName)
834
+ }
835
+ Some(b"=") => {
836
+ switch_to!(slf, BeforeAttributeValue)?.inline_next_state(slf)
837
+ }
838
+ Some(b"\0") => {
839
+ error!(slf, Error::UnexpectedNullCharacter);
840
+ slf.emitter.push_attribute_name("\u{fffd}".as_bytes());
841
+ cont!()
842
+ }
843
+ Some(b"\"" | b"'" | b"<") => {
844
+ error!(slf, Error::UnexpectedCharacterInAttributeName);
845
+ slf.emitter.push_attribute_name(xs.unwrap());
846
+ cont!()
847
+ }
848
+ Some(xs) => {
849
+ let emitter = &mut slf.emitter;
850
+ with_lowercase_str(xs, |xs| {
851
+ emitter.push_attribute_name(xs);
852
+ });
853
+ cont!()
854
+ }
855
+ None => {
856
+ reconsume_in!(slf, None, AfterAttributeName)
857
+ }
858
+ }
859
+ )
860
+ });
861
+
862
+ define_state!(AfterAttributeName, slf, {
863
+ slow_read_byte!(
864
+ slf,
865
+ match c {
866
+ Some(b'\t' | b'\x0A' | b'\x0C' | b' ') => cont!(),
867
+ Some(b'/') => {
868
+ switch_to!(slf, SelfClosingStartTag)
869
+ }
870
+ Some(b'=') => {
871
+ switch_to!(slf, BeforeAttributeValue)
872
+ }
873
+ Some(b'>') => {
874
+ emit_current_tag_and_switch_to!(slf, Data)
875
+ }
876
+ None => {
877
+ error!(slf, Error::EofInTag);
878
+ eof!()
879
+ }
880
+ Some(x) => {
881
+ slf.emitter.init_attribute();
882
+ reconsume_in!(slf, Some(x), AttributeName)
883
+ }
884
+ }
885
+ )
886
+ });
887
+
888
+ define_state!(BeforeAttributeValue, slf, {
889
+ slow_read_byte!(
890
+ slf,
891
+ match c {
892
+ Some(b'\t' | b'\x0A' | b'\x0C' | b' ') => cont!(),
893
+ Some(b'"') => {
894
+ slf.emitter.init_attribute_value();
895
+ switch_to!(slf, AttributeValueDoubleQuoted)?.inline_next_state(slf)
896
+ }
897
+ Some(b'\'') => {
898
+ slf.emitter.init_attribute_value();
899
+ switch_to!(slf, AttributeValueSingleQuoted)
900
+ }
901
+ Some(b'>') => {
902
+ error!(slf, Error::MissingAttributeValue);
903
+ emit_current_tag_and_switch_to!(slf, Data)
904
+ }
905
+ c => {
906
+ slf.emitter.init_attribute_value();
907
+ reconsume_in!(slf, c, AttributeValueUnquoted)
908
+ }
909
+ }
910
+ )
911
+ });
912
+
913
+ define_state!(AttributeValueDoubleQuoted, slf, {
914
+ fast_read_char!(
915
+ slf,
916
+ match xs {
917
+ Some(b"\"") => {
918
+ switch_to!(slf, AfterAttributeValueQuoted)?.inline_next_state(slf)
919
+ }
920
+ Some(b"&") => {
921
+ enter_state!(slf, CharacterReference, true)
922
+ }
923
+ Some(b"\0") => {
924
+ error!(slf, Error::UnexpectedNullCharacter);
925
+ slf.emitter.push_attribute_value("\u{fffd}".as_bytes());
926
+ cont!()
927
+ }
928
+ Some(xs) => {
929
+ slf.emitter.push_attribute_value(xs);
930
+ cont!()
931
+ }
932
+ None => {
933
+ error!(slf, Error::EofInTag);
934
+ eof!()
935
+ }
936
+ }
937
+ )
938
+ });
939
+
940
+ define_state!(AttributeValueSingleQuoted, slf, {
941
+ fast_read_char!(
942
+ slf,
943
+ match xs {
944
+ Some(b"'") => {
945
+ switch_to!(slf, AfterAttributeValueQuoted)
946
+ }
947
+ Some(b"&") => {
948
+ enter_state!(slf, CharacterReference, true)
949
+ }
950
+ Some(b"\0") => {
951
+ error!(slf, Error::UnexpectedNullCharacter);
952
+ slf.emitter.push_attribute_value("\u{fffd}".as_bytes());
953
+ cont!()
954
+ }
955
+ Some(xs) => {
956
+ slf.emitter.push_attribute_value(xs);
957
+ cont!()
958
+ }
959
+ None => {
960
+ error!(slf, Error::EofInTag);
961
+ eof!()
962
+ }
963
+ }
964
+ )
965
+ });
966
+
967
+ define_state!(AttributeValueUnquoted, slf, {
968
+ fast_read_char!(
969
+ slf,
970
+ match xs {
971
+ Some(b"\t" | b"\x0A" | b"\x0C" | b" ") => {
972
+ switch_to!(slf, BeforeAttributeName)
973
+ }
974
+ Some(b"&") => {
975
+ enter_state!(slf, CharacterReference, true)
976
+ }
977
+ Some(b">") => {
978
+ emit_current_tag_and_switch_to!(slf, Data)
979
+ }
980
+ Some(b"\0") => {
981
+ error!(slf, Error::UnexpectedNullCharacter);
982
+ slf.emitter.push_attribute_value("\u{fffd}".as_bytes());
983
+ cont!()
984
+ }
985
+ Some(b"\"" | b"'" | b"<" | b"=" | b"\x60") => {
986
+ error!(slf, Error::UnexpectedCharacterInUnquotedAttributeValue);
987
+ slf.emitter.push_attribute_value(xs.unwrap());
988
+ cont!()
989
+ }
990
+ Some(xs) => {
991
+ slf.emitter.push_attribute_value(xs);
992
+ cont!()
993
+ }
994
+ None => {
995
+ error!(slf, Error::EofInTag);
996
+ eof!()
997
+ }
998
+ }
999
+ )
1000
+ });
1001
+
1002
+ define_state!(AfterAttributeValueQuoted, slf, {
1003
+ slow_read_byte!(
1004
+ slf,
1005
+ match c {
1006
+ c @ (Some(b'\t' | b'\x0A' | b'\x0C' | b' ' | b'/' | b'>') | None) => {
1007
+ reconsume_in!(slf, c, BeforeAttributeName)?.inline_next_state(slf)
1008
+ }
1009
+ c => {
1010
+ error!(slf, Error::MissingWhitespaceBetweenAttributes);
1011
+ reconsume_in!(slf, c, BeforeAttributeName)
1012
+ }
1013
+ }
1014
+ )
1015
+ });
1016
+
1017
+ define_state!(SelfClosingStartTag, slf, {
1018
+ slow_read_byte!(
1019
+ slf,
1020
+ match c {
1021
+ Some(b'>') => {
1022
+ slf.emitter.set_self_closing();
1023
+ emit_current_tag_and_switch_to!(slf, Data)
1024
+ }
1025
+ None => {
1026
+ error!(slf, Error::EofInTag);
1027
+ eof!()
1028
+ }
1029
+ Some(x) => {
1030
+ error_immediate!(slf, Error::UnexpectedSolidusInTag);
1031
+ reconsume_in!(slf, Some(x), BeforeAttributeName)
1032
+ }
1033
+ }
1034
+ )
1035
+ });
1036
+
1037
+ define_state!(BogusComment, slf, {
1038
+ fast_read_char!(
1039
+ slf,
1040
+ match xs {
1041
+ Some(b">") => {
1042
+ slf.emitter.emit_current_comment();
1043
+ switch_to!(slf, Data)
1044
+ }
1045
+ Some(b"\0") => {
1046
+ error!(slf, Error::UnexpectedNullCharacter);
1047
+ slf.emitter.push_comment("\u{fffd}".as_bytes());
1048
+ cont!()
1049
+ }
1050
+ Some(xs) => {
1051
+ slf.emitter.push_comment(xs);
1052
+ cont!()
1053
+ }
1054
+ None => {
1055
+ slf.emitter.emit_current_comment();
1056
+ eof!()
1057
+ }
1058
+ }
1059
+ )
1060
+ });
1061
+
1062
+ define_state!(MarkupDeclarationOpen, slf, {
1063
+ slow_read_byte!(
1064
+ slf,
1065
+ match c {
1066
+ Some(b'-') if slf.try_read_string("-", true)? => {
1067
+ slf.emitter.init_comment();
1068
+ switch_to!(slf, CommentStart)
1069
+ }
1070
+ Some(b'd' | b'D') if slf.try_read_string("octype", false)? => {
1071
+ switch_to!(slf, Doctype)
1072
+ }
1073
+ Some(b'[') if slf.try_read_string("CDATA[", true)? => {
1074
+ if slf
1075
+ .emitter
1076
+ .adjusted_current_node_present_but_not_in_html_namespace()
1077
+ {
1078
+ switch_to!(slf, CdataSection)
1079
+ } else {
1080
+ error!(slf, Error::CdataInHtmlContent);
1081
+
1082
+ slf.emitter.init_comment();
1083
+ slf.emitter.push_comment(b"[CDATA[");
1084
+ switch_to!(slf, BogusComment)
1085
+ }
1086
+ }
1087
+ c => {
1088
+ error!(slf, Error::IncorrectlyOpenedComment);
1089
+ slf.emitter.init_comment();
1090
+ reconsume_in!(slf, c, BogusComment)
1091
+ }
1092
+ }
1093
+ )
1094
+ });
1095
+
1096
+ define_state!(CommentStart, slf, {
1097
+ slow_read_byte!(
1098
+ slf,
1099
+ match c {
1100
+ Some(b'-') => {
1101
+ switch_to!(slf, CommentStartDash)
1102
+ }
1103
+ Some(b'>') => {
1104
+ error!(slf, Error::AbruptClosingOfEmptyComment);
1105
+ slf.emitter.emit_current_comment();
1106
+ switch_to!(slf, Data)
1107
+ }
1108
+ c => {
1109
+ reconsume_in!(slf, c, Comment)
1110
+ }
1111
+ }
1112
+ )
1113
+ });
1114
+
1115
+ define_state!(CommentStartDash, slf, {
1116
+ slow_read_byte!(
1117
+ slf,
1118
+ match c {
1119
+ Some(b'-') => {
1120
+ switch_to!(slf, CommentEnd)
1121
+ }
1122
+ Some(b'>') => {
1123
+ error!(slf, Error::AbruptClosingOfEmptyComment);
1124
+ slf.emitter.emit_current_comment();
1125
+ switch_to!(slf, Data)
1126
+ }
1127
+ None => {
1128
+ error!(slf, Error::EofInComment);
1129
+ slf.emitter.emit_current_comment();
1130
+ eof!()
1131
+ }
1132
+ c @ Some(_) => {
1133
+ slf.emitter.push_comment(b"-");
1134
+ reconsume_in!(slf, c, Comment)
1135
+ }
1136
+ }
1137
+ )
1138
+ });
1139
+
1140
+ define_state!(Comment, slf, {
1141
+ fast_read_char!(
1142
+ slf,
1143
+ match xs {
1144
+ Some(b"<") => {
1145
+ slf.emitter.push_comment(b"<");
1146
+ switch_to!(slf, CommentLessThanSign)
1147
+ }
1148
+ Some(b"-") => {
1149
+ switch_to!(slf, CommentEndDash)
1150
+ }
1151
+ Some(b"\0") => {
1152
+ error!(slf, Error::UnexpectedNullCharacter);
1153
+ slf.emitter.push_comment("\u{fffd}".as_bytes());
1154
+ cont!()
1155
+ }
1156
+ Some(xs) => {
1157
+ slf.emitter.push_comment(xs);
1158
+ cont!()
1159
+ }
1160
+ None => {
1161
+ error!(slf, Error::EofInComment);
1162
+ slf.emitter.emit_current_comment();
1163
+ eof!()
1164
+ }
1165
+ }
1166
+ )
1167
+ });
1168
+
1169
+ define_state!(CommentLessThanSign, slf, {
1170
+ slow_read_byte!(
1171
+ slf,
1172
+ match c {
1173
+ Some(b'!') => {
1174
+ slf.emitter.push_comment(b"!");
1175
+ switch_to!(slf, CommentLessThanSignBang)
1176
+ }
1177
+ Some(b'<') => {
1178
+ slf.emitter.push_comment(b"<");
1179
+ cont!()
1180
+ }
1181
+ c => {
1182
+ reconsume_in!(slf, c, Comment)
1183
+ }
1184
+ }
1185
+ )
1186
+ });
1187
+
1188
+ define_state!(CommentLessThanSignBang, slf, {
1189
+ slow_read_byte!(
1190
+ slf,
1191
+ match c {
1192
+ Some(b'-') => {
1193
+ switch_to!(slf, CommentLessThanSignBangDash)
1194
+ }
1195
+ c => {
1196
+ reconsume_in!(slf, c, Comment)
1197
+ }
1198
+ }
1199
+ )
1200
+ });
1201
+
1202
+ define_state!(CommentLessThanSignBangDash, slf, {
1203
+ slow_read_byte!(
1204
+ slf,
1205
+ match c {
1206
+ Some(b'-') => {
1207
+ switch_to!(slf, CommentLessThanSignBangDashDash)
1208
+ }
1209
+ c => {
1210
+ reconsume_in!(slf, c, CommentEndDash)
1211
+ }
1212
+ }
1213
+ )
1214
+ });
1215
+
1216
+ define_state!(CommentLessThanSignBangDashDash, slf, {
1217
+ slow_read_byte!(
1218
+ slf,
1219
+ match c {
1220
+ c @ (Some(b'>') | None) => {
1221
+ reconsume_in!(slf, c, CommentEnd)
1222
+ }
1223
+ c => {
1224
+ error!(slf, Error::NestedComment);
1225
+ reconsume_in!(slf, c, CommentEnd)
1226
+ }
1227
+ }
1228
+ )
1229
+ });
1230
+
1231
+ define_state!(CommentEndDash, slf, {
1232
+ slow_read_byte!(
1233
+ slf,
1234
+ match c {
1235
+ Some(b'-') => {
1236
+ switch_to!(slf, CommentEnd)
1237
+ }
1238
+ None => {
1239
+ error!(slf, Error::EofInComment);
1240
+ slf.emitter.emit_current_comment();
1241
+ eof!()
1242
+ }
1243
+ c => {
1244
+ slf.emitter.push_comment(b"-");
1245
+ reconsume_in!(slf, c, Comment)
1246
+ }
1247
+ }
1248
+ )
1249
+ });
1250
+
1251
+ define_state!(CommentEnd, slf, {
1252
+ slow_read_byte!(
1253
+ slf,
1254
+ match c {
1255
+ Some(b'>') => {
1256
+ slf.emitter.emit_current_comment();
1257
+ switch_to!(slf, Data)
1258
+ }
1259
+ Some(b'!') => {
1260
+ switch_to!(slf, CommentEndBang)
1261
+ }
1262
+ Some(b'-') => {
1263
+ slf.emitter.push_comment(b"-");
1264
+ cont!()
1265
+ }
1266
+ None => {
1267
+ error!(slf, Error::EofInComment);
1268
+ slf.emitter.emit_current_comment();
1269
+ eof!()
1270
+ }
1271
+ c @ Some(_) => {
1272
+ slf.emitter.push_comment(b"--");
1273
+ reconsume_in!(slf, c, Comment)
1274
+ }
1275
+ }
1276
+ )
1277
+ });
1278
+
1279
+ define_state!(CommentEndBang, slf, {
1280
+ slow_read_byte!(
1281
+ slf,
1282
+ match c {
1283
+ Some(b'-') => {
1284
+ slf.emitter.push_comment(b"--!");
1285
+ switch_to!(slf, CommentEndDash)
1286
+ }
1287
+ Some(b'>') => {
1288
+ error!(slf, Error::IncorrectlyClosedComment);
1289
+ slf.emitter.emit_current_comment();
1290
+ switch_to!(slf, Data)
1291
+ }
1292
+ None => {
1293
+ error!(slf, Error::EofInComment);
1294
+ slf.emitter.emit_current_comment();
1295
+ eof!()
1296
+ }
1297
+ c @ Some(_) => {
1298
+ slf.emitter.push_comment(b"--!");
1299
+ reconsume_in!(slf, c, Comment)
1300
+ }
1301
+ }
1302
+ )
1303
+ });
1304
+
1305
+ define_state!(Doctype, slf, {
1306
+ slow_read_byte!(
1307
+ slf,
1308
+ match c {
1309
+ Some(b'\t' | b'\x0A' | b'\x0C' | b' ') => {
1310
+ switch_to!(slf, BeforeDoctypeName)
1311
+ }
1312
+ c @ Some(b'>') => {
1313
+ reconsume_in!(slf, c, BeforeDoctypeName)
1314
+ }
1315
+ None => {
1316
+ error!(slf, Error::EofInDoctype);
1317
+ slf.emitter.init_doctype();
1318
+ slf.emitter.set_force_quirks();
1319
+ slf.emitter.emit_current_doctype();
1320
+ eof!()
1321
+ }
1322
+ c @ Some(_) => {
1323
+ error!(slf, Error::MissingWhitespaceBeforeDoctypeName);
1324
+ reconsume_in!(slf, c, BeforeDoctypeName)
1325
+ }
1326
+ }
1327
+ )
1328
+ });
1329
+
1330
+ define_state!(BeforeDoctypeName, slf, {
1331
+ slow_read_byte!(
1332
+ slf,
1333
+ match c {
1334
+ Some(b'\t' | b'\x0A' | b'\x0C' | b' ') => cont!(),
1335
+ Some(b'\0') => {
1336
+ error!(slf, Error::UnexpectedNullCharacter);
1337
+ slf.emitter.init_doctype();
1338
+ slf.emitter.push_doctype_name("\u{fffd}".as_bytes());
1339
+ switch_to!(slf, DoctypeName)
1340
+ }
1341
+ Some(b'>') => {
1342
+ error!(slf, Error::MissingDoctypeName);
1343
+ slf.emitter.init_doctype();
1344
+ slf.emitter.set_force_quirks();
1345
+ slf.emitter.emit_current_doctype();
1346
+ switch_to!(slf, Data)
1347
+ }
1348
+ None => {
1349
+ error!(slf, Error::EofInDoctype);
1350
+ slf.emitter.init_doctype();
1351
+ slf.emitter.set_force_quirks();
1352
+ slf.emitter.emit_current_doctype();
1353
+ eof!()
1354
+ }
1355
+ Some(x) => {
1356
+ slf.emitter.init_doctype();
1357
+ slf.emitter.push_doctype_name(&[x.to_ascii_lowercase()]);
1358
+ switch_to!(slf, DoctypeName)
1359
+ }
1360
+ }
1361
+ )
1362
+ });
1363
+
1364
+ define_state!(DoctypeName, slf, {
1365
+ fast_read_char!(
1366
+ slf,
1367
+ match xs {
1368
+ Some(b"\t" | b"\x0A" | b"\x0C" | b" ") => {
1369
+ switch_to!(slf, AfterDoctypeName)
1370
+ }
1371
+ Some(b">") => {
1372
+ slf.emitter.emit_current_doctype();
1373
+ switch_to!(slf, Data)
1374
+ }
1375
+ Some(b"\0") => {
1376
+ error!(slf, Error::UnexpectedNullCharacter);
1377
+ slf.emitter.push_doctype_name("\u{fffd}".as_bytes());
1378
+ cont!()
1379
+ }
1380
+ Some(xs) => {
1381
+ let emitter = &mut slf.emitter;
1382
+ with_lowercase_str(xs, |x| {
1383
+ emitter.push_doctype_name(x);
1384
+ });
1385
+ cont!()
1386
+ }
1387
+ None => {
1388
+ error!(slf, Error::EofInDoctype);
1389
+ slf.emitter.set_force_quirks();
1390
+ slf.emitter.emit_current_doctype();
1391
+ eof!()
1392
+ }
1393
+ }
1394
+ )
1395
+ });
1396
+
1397
+ define_state!(AfterDoctypeName, slf, {
1398
+ slow_read_byte!(
1399
+ slf,
1400
+ match c {
1401
+ Some(b'\t' | b'\x0A' | b'\x0C' | b' ') => cont!(),
1402
+ Some(b'>') => {
1403
+ slf.emitter.emit_current_doctype();
1404
+ switch_to!(slf, Data)
1405
+ }
1406
+ None => {
1407
+ error!(slf, Error::EofInDoctype);
1408
+ slf.emitter.set_force_quirks();
1409
+ slf.emitter.emit_current_doctype();
1410
+ eof!()
1411
+ }
1412
+ Some(b'p' | b'P') if slf.try_read_string("ublic", false)? => {
1413
+ switch_to!(slf, AfterDoctypePublicKeyword)
1414
+ }
1415
+ Some(b's' | b'S') if slf.try_read_string("ystem", false)? => {
1416
+ switch_to!(slf, AfterDoctypeSystemKeyword)
1417
+ }
1418
+ c @ Some(_) => {
1419
+ error!(slf, Error::InvalidCharacterSequenceAfterDoctypeName);
1420
+ slf.emitter.set_force_quirks();
1421
+ reconsume_in!(slf, c, BogusDoctype)
1422
+ }
1423
+ }
1424
+ )
1425
+ });
1426
+
1427
+ define_state!(AfterDoctypePublicKeyword, slf, {
1428
+ slow_read_byte!(
1429
+ slf,
1430
+ match c {
1431
+ Some(b'\t' | b'\x0A' | b'\x0C' | b' ') => {
1432
+ switch_to!(slf, BeforeDoctypePublicIdentifier)
1433
+ }
1434
+ Some(b'"') => {
1435
+ error!(slf, Error::MissingWhitespaceAfterDoctypePublicKeyword);
1436
+ slf.emitter.set_doctype_public_identifier(b"");
1437
+ switch_to!(slf, DoctypePublicIdentifierDoubleQuoted)
1438
+ }
1439
+ Some(b'\'') => {
1440
+ error!(slf, Error::MissingWhitespaceAfterDoctypePublicKeyword);
1441
+ slf.emitter.set_doctype_public_identifier(b"");
1442
+ switch_to!(slf, DoctypePublicIdentifierSingleQuoted)
1443
+ }
1444
+ Some(b'>') => {
1445
+ error!(slf, Error::MissingDoctypePublicIdentifier);
1446
+ slf.emitter.set_force_quirks();
1447
+ slf.emitter.emit_current_doctype();
1448
+ switch_to!(slf, Data)
1449
+ }
1450
+ None => {
1451
+ error!(slf, Error::EofInDoctype);
1452
+ slf.emitter.set_force_quirks();
1453
+ slf.emitter.emit_current_doctype();
1454
+ eof!()
1455
+ }
1456
+ c @ Some(_) => {
1457
+ error!(slf, Error::MissingQuoteBeforeDoctypePublicIdentifier);
1458
+ slf.emitter.set_force_quirks();
1459
+ reconsume_in!(slf, c, BogusDoctype)
1460
+ }
1461
+ }
1462
+ )
1463
+ });
1464
+
1465
+ define_state!(BeforeDoctypePublicIdentifier, slf, {
1466
+ slow_read_byte!(
1467
+ slf,
1468
+ match c {
1469
+ Some(b'\t' | b'\x0A' | b'\x0C' | b' ') => cont!(),
1470
+ Some(b'"') => {
1471
+ slf.emitter.set_doctype_public_identifier(b"");
1472
+ switch_to!(slf, DoctypePublicIdentifierDoubleQuoted)
1473
+ }
1474
+ Some(b'\'') => {
1475
+ slf.emitter.set_doctype_public_identifier(b"");
1476
+ switch_to!(slf, DoctypePublicIdentifierSingleQuoted)
1477
+ }
1478
+ Some(b'>') => {
1479
+ error!(slf, Error::MissingDoctypePublicIdentifier);
1480
+ slf.emitter.set_force_quirks();
1481
+ slf.emitter.emit_current_doctype();
1482
+ switch_to!(slf, Data)
1483
+ }
1484
+ None => {
1485
+ error!(slf, Error::EofInDoctype);
1486
+ slf.emitter.set_force_quirks();
1487
+ slf.emitter.emit_current_doctype();
1488
+ eof!()
1489
+ }
1490
+ c @ Some(_) => {
1491
+ error!(slf, Error::MissingQuoteBeforeDoctypePublicIdentifier);
1492
+ slf.emitter.set_force_quirks();
1493
+ reconsume_in!(slf, c, BogusDoctype)
1494
+ }
1495
+ }
1496
+ )
1497
+ });
1498
+
1499
+ define_state!(DoctypePublicIdentifierDoubleQuoted, slf, {
1500
+ fast_read_char!(
1501
+ slf,
1502
+ match xs {
1503
+ Some(b"\"") => {
1504
+ switch_to!(slf, AfterDoctypePublicIdentifier)
1505
+ }
1506
+ Some(b"\0") => {
1507
+ error!(slf, Error::UnexpectedNullCharacter);
1508
+ slf.emitter
1509
+ .push_doctype_public_identifier("\u{fffd}".as_bytes());
1510
+ cont!()
1511
+ }
1512
+ Some(b">") => {
1513
+ error!(slf, Error::AbruptDoctypePublicIdentifier);
1514
+ slf.emitter.set_force_quirks();
1515
+ slf.emitter.emit_current_doctype();
1516
+ switch_to!(slf, Data)
1517
+ }
1518
+ Some(xs) => {
1519
+ slf.emitter.push_doctype_public_identifier(xs);
1520
+ cont!()
1521
+ }
1522
+ None => {
1523
+ error!(slf, Error::EofInDoctype);
1524
+ slf.emitter.set_force_quirks();
1525
+ slf.emitter.emit_current_doctype();
1526
+ eof!()
1527
+ }
1528
+ }
1529
+ )
1530
+ });
1531
+
1532
+ define_state!(DoctypePublicIdentifierSingleQuoted, slf, {
1533
+ fast_read_char!(
1534
+ slf,
1535
+ match xs {
1536
+ Some(b"'") => {
1537
+ switch_to!(slf, AfterDoctypePublicIdentifier)
1538
+ }
1539
+ Some(b"\0") => {
1540
+ error!(slf, Error::UnexpectedNullCharacter);
1541
+ slf.emitter
1542
+ .push_doctype_public_identifier("\u{fffd}".as_bytes());
1543
+ cont!()
1544
+ }
1545
+ Some(b">") => {
1546
+ error!(slf, Error::AbruptDoctypePublicIdentifier);
1547
+ slf.emitter.set_force_quirks();
1548
+ slf.emitter.emit_current_doctype();
1549
+ switch_to!(slf, Data)
1550
+ }
1551
+ Some(xs) => {
1552
+ slf.emitter.push_doctype_public_identifier(xs);
1553
+ cont!()
1554
+ }
1555
+ None => {
1556
+ error!(slf, Error::EofInDoctype);
1557
+ slf.emitter.set_force_quirks();
1558
+ slf.emitter.emit_current_doctype();
1559
+ eof!()
1560
+ }
1561
+ }
1562
+ )
1563
+ });
1564
+
1565
+ define_state!(AfterDoctypePublicIdentifier, slf, {
1566
+ slow_read_byte!(
1567
+ slf,
1568
+ match c {
1569
+ Some(b'\t' | b'\x0A' | b'\x0C' | b' ') => {
1570
+ switch_to!(slf, BetweenDoctypePublicAndSystemIdentifiers)
1571
+ }
1572
+ Some(b'>') => {
1573
+ slf.emitter.emit_current_doctype();
1574
+ switch_to!(slf, Data)
1575
+ }
1576
+ Some(b'"') => {
1577
+ error!(
1578
+ slf,
1579
+ Error::MissingWhitespaceBetweenDoctypePublicAndSystemIdentifiers
1580
+ );
1581
+ slf.emitter.set_doctype_system_identifier(b"");
1582
+ switch_to!(slf, DoctypeSystemIdentifierDoubleQuoted)
1583
+ }
1584
+ Some(b'\'') => {
1585
+ error!(
1586
+ slf,
1587
+ Error::MissingWhitespaceBetweenDoctypePublicAndSystemIdentifiers
1588
+ );
1589
+ slf.emitter.set_doctype_system_identifier(b"");
1590
+ switch_to!(slf, DoctypeSystemIdentifierSingleQuoted)
1591
+ }
1592
+ None => {
1593
+ error!(slf, Error::EofInDoctype);
1594
+ slf.emitter.set_force_quirks();
1595
+ slf.emitter.emit_current_doctype();
1596
+ eof!()
1597
+ }
1598
+ c @ Some(_) => {
1599
+ error!(slf, Error::MissingQuoteBeforeDoctypeSystemIdentifier);
1600
+ slf.emitter.set_force_quirks();
1601
+ reconsume_in!(slf, c, BogusDoctype)
1602
+ }
1603
+ }
1604
+ )
1605
+ });
1606
+
1607
+ define_state!(BetweenDoctypePublicAndSystemIdentifiers, slf, {
1608
+ slow_read_byte!(
1609
+ slf,
1610
+ match c {
1611
+ Some(b'\t' | b'\x0A' | b'\x0C' | b' ') => cont!(),
1612
+ Some(b'>') => {
1613
+ slf.emitter.emit_current_doctype();
1614
+ switch_to!(slf, Data)
1615
+ }
1616
+ Some(b'"') => {
1617
+ slf.emitter.set_doctype_system_identifier(b"");
1618
+ switch_to!(slf, DoctypeSystemIdentifierDoubleQuoted)
1619
+ }
1620
+ Some(b'\'') => {
1621
+ slf.emitter.set_doctype_system_identifier(b"");
1622
+ switch_to!(slf, DoctypeSystemIdentifierSingleQuoted)
1623
+ }
1624
+ None => {
1625
+ error!(slf, Error::EofInDoctype);
1626
+ slf.emitter.set_force_quirks();
1627
+ slf.emitter.emit_current_doctype();
1628
+ eof!()
1629
+ }
1630
+ c @ Some(_) => {
1631
+ error!(slf, Error::MissingQuoteBeforeDoctypeSystemIdentifier);
1632
+ slf.emitter.set_force_quirks();
1633
+ reconsume_in!(slf, c, BogusDoctype)
1634
+ }
1635
+ }
1636
+ )
1637
+ });
1638
+
1639
+ define_state!(AfterDoctypeSystemKeyword, slf, {
1640
+ slow_read_byte!(
1641
+ slf,
1642
+ match c {
1643
+ Some(b'\t' | b'\x0A' | b'\x0C' | b' ') => {
1644
+ switch_to!(slf, BeforeDoctypeSystemIdentifier)
1645
+ }
1646
+ Some(b'"') => {
1647
+ error!(slf, Error::MissingWhitespaceAfterDoctypeSystemKeyword);
1648
+ slf.emitter.set_doctype_system_identifier(b"");
1649
+ switch_to!(slf, DoctypeSystemIdentifierDoubleQuoted)
1650
+ }
1651
+ Some(b'\'') => {
1652
+ error!(slf, Error::MissingWhitespaceAfterDoctypeSystemKeyword);
1653
+ slf.emitter.set_doctype_system_identifier(b"");
1654
+ switch_to!(slf, DoctypeSystemIdentifierSingleQuoted)
1655
+ }
1656
+ Some(b'>') => {
1657
+ error!(slf, Error::MissingDoctypeSystemIdentifier);
1658
+ slf.emitter.set_force_quirks();
1659
+ slf.emitter.emit_current_doctype();
1660
+ switch_to!(slf, Data)
1661
+ }
1662
+ None => {
1663
+ error!(slf, Error::EofInDoctype);
1664
+ slf.emitter.set_force_quirks();
1665
+ slf.emitter.emit_current_doctype();
1666
+ eof!()
1667
+ }
1668
+ c @ Some(_) => {
1669
+ error!(slf, Error::MissingQuoteBeforeDoctypeSystemIdentifier);
1670
+ slf.emitter.set_force_quirks();
1671
+ reconsume_in!(slf, c, BogusDoctype)
1672
+ }
1673
+ }
1674
+ )
1675
+ });
1676
+
1677
+ define_state!(BeforeDoctypeSystemIdentifier, slf, {
1678
+ slow_read_byte!(
1679
+ slf,
1680
+ match c {
1681
+ Some(b'\t' | b'\x0A' | b'\x0C' | b' ') => cont!(),
1682
+ Some(b'"') => {
1683
+ slf.emitter.set_doctype_system_identifier(b"");
1684
+ switch_to!(slf, DoctypeSystemIdentifierDoubleQuoted)
1685
+ }
1686
+ Some(b'\'') => {
1687
+ slf.emitter.set_doctype_system_identifier(b"");
1688
+ switch_to!(slf, DoctypeSystemIdentifierSingleQuoted)
1689
+ }
1690
+ Some(b'>') => {
1691
+ error!(slf, Error::MissingDoctypeSystemIdentifier);
1692
+ slf.emitter.set_force_quirks();
1693
+ slf.emitter.emit_current_doctype();
1694
+ switch_to!(slf, Data)
1695
+ }
1696
+ None => {
1697
+ error!(slf, Error::EofInDoctype);
1698
+ slf.emitter.set_force_quirks();
1699
+ slf.emitter.emit_current_doctype();
1700
+ eof!()
1701
+ }
1702
+ c @ Some(_) => {
1703
+ error!(slf, Error::MissingQuoteBeforeDoctypeSystemIdentifier);
1704
+ slf.emitter.set_force_quirks();
1705
+ reconsume_in!(slf, c, BogusDoctype)
1706
+ }
1707
+ }
1708
+ )
1709
+ });
1710
+
1711
+ define_state!(DoctypeSystemIdentifierDoubleQuoted, slf, {
1712
+ fast_read_char!(
1713
+ slf,
1714
+ match xs {
1715
+ Some(b"\"") => {
1716
+ switch_to!(slf, AfterDoctypeSystemIdentifier)
1717
+ }
1718
+ Some(b"\0") => {
1719
+ error!(slf, Error::UnexpectedNullCharacter);
1720
+ slf.emitter
1721
+ .push_doctype_system_identifier("\u{fffd}".as_bytes());
1722
+ cont!()
1723
+ }
1724
+ Some(b">") => {
1725
+ error!(slf, Error::AbruptDoctypeSystemIdentifier);
1726
+ slf.emitter.set_force_quirks();
1727
+ slf.emitter.emit_current_doctype();
1728
+ switch_to!(slf, Data)
1729
+ }
1730
+ Some(xs) => {
1731
+ slf.emitter.push_doctype_system_identifier(xs);
1732
+ cont!()
1733
+ }
1734
+ None => {
1735
+ error!(slf, Error::EofInDoctype);
1736
+ slf.emitter.set_force_quirks();
1737
+ slf.emitter.emit_current_doctype();
1738
+ eof!()
1739
+ }
1740
+ }
1741
+ )
1742
+ });
1743
+
1744
+ define_state!(DoctypeSystemIdentifierSingleQuoted, slf, {
1745
+ fast_read_char!(
1746
+ slf,
1747
+ match xs {
1748
+ Some(b"\'") => {
1749
+ switch_to!(slf, AfterDoctypeSystemIdentifier)
1750
+ }
1751
+ Some(b"\0") => {
1752
+ error!(slf, Error::UnexpectedNullCharacter);
1753
+ slf.emitter
1754
+ .push_doctype_system_identifier("\u{fffd}".as_bytes());
1755
+ cont!()
1756
+ }
1757
+ Some(b">") => {
1758
+ error!(slf, Error::AbruptDoctypeSystemIdentifier);
1759
+ slf.emitter.set_force_quirks();
1760
+ slf.emitter.emit_current_doctype();
1761
+ switch_to!(slf, Data)
1762
+ }
1763
+ Some(xs) => {
1764
+ slf.emitter.push_doctype_system_identifier(xs);
1765
+ cont!()
1766
+ }
1767
+ None => {
1768
+ error!(slf, Error::EofInDoctype);
1769
+ slf.emitter.set_force_quirks();
1770
+ slf.emitter.emit_current_doctype();
1771
+ eof!()
1772
+ }
1773
+ }
1774
+ )
1775
+ });
1776
+
1777
+ define_state!(AfterDoctypeSystemIdentifier, slf, {
1778
+ slow_read_byte!(
1779
+ slf,
1780
+ match c {
1781
+ Some(b'\t' | b'\x0A' | b'\x0C' | b' ') => cont!(),
1782
+ Some(b'>') => {
1783
+ slf.emitter.emit_current_doctype();
1784
+ switch_to!(slf, Data)
1785
+ }
1786
+ None => {
1787
+ error!(slf, Error::EofInDoctype);
1788
+ slf.emitter.set_force_quirks();
1789
+ slf.emitter.emit_current_doctype();
1790
+ eof!()
1791
+ }
1792
+ c @ Some(_) => {
1793
+ error!(slf, Error::UnexpectedCharacterAfterDoctypeSystemIdentifier);
1794
+ reconsume_in!(slf, c, BogusDoctype)
1795
+ }
1796
+ }
1797
+ )
1798
+ });
1799
+
1800
+ define_state!(BogusDoctype, slf, {
1801
+ fast_read_char!(
1802
+ slf,
1803
+ match xs {
1804
+ Some(b">") => {
1805
+ slf.emitter.emit_current_doctype();
1806
+ switch_to!(slf, Data)
1807
+ }
1808
+ Some(b"\0") => {
1809
+ error!(slf, Error::UnexpectedNullCharacter);
1810
+ cont!()
1811
+ }
1812
+ Some(_xs) => {
1813
+ cont!()
1814
+ }
1815
+ None => {
1816
+ slf.emitter.emit_current_doctype();
1817
+ eof!()
1818
+ }
1819
+ }
1820
+ )
1821
+ });
1822
+
1823
+ define_state!(CdataSection, slf, {
1824
+ fast_read_char!(
1825
+ slf,
1826
+ match xs {
1827
+ Some(b"]") => {
1828
+ switch_to!(slf, CdataSectionBracket)
1829
+ }
1830
+ Some(xs) => {
1831
+ slf.emitter.emit_string(xs);
1832
+ cont!()
1833
+ }
1834
+ None => {
1835
+ error!(slf, Error::EofInCdata);
1836
+ eof!()
1837
+ }
1838
+ }
1839
+ )
1840
+ });
1841
+
1842
+ define_state!(CdataSectionBracket, slf, {
1843
+ slow_read_byte!(
1844
+ slf,
1845
+ match c {
1846
+ Some(b']') => {
1847
+ switch_to!(slf, CdataSectionEnd)
1848
+ }
1849
+ c => {
1850
+ slf.emitter.emit_string(b"]");
1851
+ reconsume_in!(slf, c, CdataSection)
1852
+ }
1853
+ }
1854
+ )
1855
+ });
1856
+
1857
+ define_state!(CdataSectionEnd, slf, {
1858
+ slow_read_byte!(
1859
+ slf,
1860
+ match c {
1861
+ Some(b']') => {
1862
+ slf.emitter.emit_string(b"]");
1863
+ cont!()
1864
+ }
1865
+ Some(b'>') => {
1866
+ switch_to!(slf, Data)
1867
+ }
1868
+ c => {
1869
+ slf.emitter.emit_string(b"]]");
1870
+ reconsume_in!(slf, c, CdataSection)
1871
+ }
1872
+ }
1873
+ )
1874
+ });
1875
+
1876
+ define_state!(CharacterReference, slf, {
1877
+ slf.machine_helper.temporary_buffer.clear();
1878
+ slf.machine_helper.temporary_buffer.push(b'&');
1879
+
1880
+ slow_read_byte!(
1881
+ slf,
1882
+ match c {
1883
+ Some(x) if x.is_ascii_alphanumeric() => {
1884
+ reconsume_in!(slf, Some(x), NamedCharacterReference)
1885
+ }
1886
+ Some(b'#') => {
1887
+ slf.machine_helper.temporary_buffer.push(b'#');
1888
+ switch_to!(slf, NumericCharacterReference)
1889
+ }
1890
+ c => {
1891
+ // since c is not part of the flushed characters, we temporarily undo the
1892
+ // move_position done by slow_read_byte, then redo it, then let reconsume
1893
+ // re-undo the redo.
1894
+ //
1895
+ // 1. move_position(-1) // revert slow_read_byte
1896
+ // 2. flush code points
1897
+ // 3. move_position(1)
1898
+ // 4. reconsume: move_position(-1)
1899
+ slf.emitter.move_position(-1);
1900
+ slf.machine_helper
1901
+ .flush_code_points_consumed_as_character_reference(&mut slf.emitter);
1902
+ slf.emitter.move_position(1);
1903
+ reconsume_in_return_state!(slf, c)
1904
+ }
1905
+ }
1906
+ )
1907
+ });
1908
+
1909
+ define_state!(NamedCharacterReference, slf, {
1910
+ let c = read_byte!(slf)?;
1911
+
1912
+ let char_ref = match c {
1913
+ Some(x) => try_read_character_reference(x as char, |x| slf.try_read_string(x, true))?
1914
+ .map(|char_ref| (x, char_ref)),
1915
+
1916
+ None => None,
1917
+ };
1918
+
1919
+ if let Some((x, char_ref)) = char_ref {
1920
+ let char_ref_name_last_character = char_ref.name.chars().last();
1921
+ let next_character = read_byte!(slf)?;
1922
+
1923
+ if !slf.machine_helper.is_consumed_as_part_of_an_attribute()
1924
+ || char_ref_name_last_character == Some(';')
1925
+ || !matches!(next_character, Some(x) if x == b'=' || x.is_ascii_alphanumeric())
1926
+ {
1927
+ if char_ref_name_last_character != Some(';') {
1928
+ error!(slf, Error::MissingSemicolonAfterCharacterReference);
1929
+ }
1930
+
1931
+ slf.machine_helper.temporary_buffer.clear();
1932
+ slf.machine_helper
1933
+ .temporary_buffer
1934
+ .extend(char_ref.characters.as_bytes());
1935
+ } else {
1936
+ slf.machine_helper.temporary_buffer.extend(&[x]);
1937
+ slf.machine_helper
1938
+ .temporary_buffer
1939
+ .extend(char_ref.name.as_bytes());
1940
+ }
1941
+
1942
+ slf.emitter.move_position(-1);
1943
+ slf.machine_helper
1944
+ .flush_code_points_consumed_as_character_reference(&mut slf.emitter);
1945
+ slf.emitter.move_position(1);
1946
+ reconsume_in_return_state!(slf, next_character)
1947
+ } else {
1948
+ slf.emitter.move_position(-1);
1949
+ slf.machine_helper
1950
+ .flush_code_points_consumed_as_character_reference(&mut slf.emitter);
1951
+ slf.emitter.move_position(1);
1952
+ reconsume_in!(slf, c, AmbiguousAmpersand)
1953
+ }
1954
+ });
1955
+
1956
+ define_state!(AmbiguousAmpersand, slf, {
1957
+ slow_read_byte!(
1958
+ slf,
1959
+ match c {
1960
+ Some(x) if x.is_ascii_alphanumeric() => {
1961
+ if slf.machine_helper.is_consumed_as_part_of_an_attribute() {
1962
+ slf.emitter.push_attribute_value(&[x]);
1963
+ } else {
1964
+ slf.emitter.emit_string(&[x]);
1965
+ }
1966
+
1967
+ cont!()
1968
+ }
1969
+ c @ Some(b';') => {
1970
+ error!(slf, Error::UnknownNamedCharacterReference);
1971
+ reconsume_in_return_state!(slf, c)
1972
+ }
1973
+ c => {
1974
+ reconsume_in_return_state!(slf, c)
1975
+ }
1976
+ }
1977
+ )
1978
+ });
1979
+
1980
+ define_state!(NumericCharacterReference, slf, {
1981
+ slf.machine_helper.character_reference_code = 0;
1982
+
1983
+ slow_read_byte!(
1984
+ slf,
1985
+ match c {
1986
+ Some(x @ (b'x' | b'X')) => {
1987
+ slf.machine_helper.temporary_buffer.push(x);
1988
+ switch_to!(slf, HexadecimalCharacterReferenceStart)
1989
+ }
1990
+ Some(x @ b'0'..=b'9') => {
1991
+ reconsume_in!(slf, Some(x), DecimalCharacterReference)
1992
+ }
1993
+ c => {
1994
+ error!(slf, Error::AbsenceOfDigitsInNumericCharacterReference);
1995
+ slf.emitter.move_position(-1);
1996
+ slf.machine_helper
1997
+ .flush_code_points_consumed_as_character_reference(&mut slf.emitter);
1998
+ slf.emitter.move_position(1);
1999
+ reconsume_in_return_state!(slf, c)
2000
+ }
2001
+ }
2002
+ )
2003
+ });
2004
+
2005
+ define_state!(HexadecimalCharacterReferenceStart, slf, {
2006
+ slow_read_byte!(
2007
+ slf,
2008
+ match c {
2009
+ c @ Some(b'0'..=b'9' | b'A'..=b'F' | b'a'..=b'f') => {
2010
+ reconsume_in!(slf, c, HexadecimalCharacterReference)
2011
+ }
2012
+ c => {
2013
+ error!(slf, Error::AbsenceOfDigitsInNumericCharacterReference);
2014
+ slf.emitter.move_position(-1);
2015
+ slf.machine_helper
2016
+ .flush_code_points_consumed_as_character_reference(&mut slf.emitter);
2017
+ slf.emitter.move_position(1);
2018
+ reconsume_in_return_state!(slf, c)
2019
+ }
2020
+ }
2021
+ )
2022
+ });
2023
+
2024
+ define_state!(HexadecimalCharacterReference, slf, {
2025
+ slow_read_byte!(
2026
+ slf,
2027
+ match c {
2028
+ Some(x @ b'0'..=b'9') => {
2029
+ mutate_character_reference!(slf, *16 + x - 0x0030);
2030
+ cont!()
2031
+ }
2032
+ Some(x @ b'A'..=b'F') => {
2033
+ mutate_character_reference!(slf, *16 + x - 0x0037);
2034
+ cont!()
2035
+ }
2036
+ Some(x @ b'a'..=b'f') => {
2037
+ mutate_character_reference!(slf, *16 + x - 0x0057);
2038
+ cont!()
2039
+ }
2040
+ Some(b';') => {
2041
+ switch_to!(slf, NumericCharacterReferenceEnd)
2042
+ }
2043
+ c => {
2044
+ error!(slf, Error::MissingSemicolonAfterCharacterReference);
2045
+ reconsume_in!(slf, c, NumericCharacterReferenceEnd)
2046
+ }
2047
+ }
2048
+ )
2049
+ });
2050
+
2051
+ define_state!(DecimalCharacterReference, slf, {
2052
+ slow_read_byte!(
2053
+ slf,
2054
+ match c {
2055
+ Some(x @ b'0'..=b'9') => {
2056
+ mutate_character_reference!(slf, *10 + x - 0x0030);
2057
+ cont!()
2058
+ }
2059
+ Some(b';') => {
2060
+ switch_to!(slf, NumericCharacterReferenceEnd)
2061
+ }
2062
+ c => {
2063
+ error!(slf, Error::MissingSemicolonAfterCharacterReference);
2064
+ reconsume_in!(slf, c, NumericCharacterReferenceEnd)
2065
+ }
2066
+ }
2067
+ )
2068
+ });
2069
+
2070
+ define_state!(NumericCharacterReferenceEnd, slf, {
2071
+ match slf.machine_helper.character_reference_code {
2072
+ 0x00 => {
2073
+ error!(slf, Error::NullCharacterReference);
2074
+ slf.machine_helper.character_reference_code = 0xfffd;
2075
+ }
2076
+ 0x0011_0000.. => {
2077
+ error!(slf, Error::CharacterReferenceOutsideUnicodeRange);
2078
+ slf.machine_helper.character_reference_code = 0xfffd;
2079
+ }
2080
+ surrogate_pat!() => {
2081
+ error!(slf, Error::SurrogateCharacterReference);
2082
+ slf.machine_helper.character_reference_code = 0xfffd;
2083
+ }
2084
+ // noncharacter
2085
+ noncharacter_pat!() => {
2086
+ error!(slf, Error::NoncharacterCharacterReference);
2087
+ }
2088
+ // 0x000d, or a control that is not whitespace
2089
+ x @ (0x000d | 0x0d | 0x0000..=0x001f | 0x007f..=0x009f)
2090
+ if !matches!(x, 0x0009 | 0x000a | 0x000c | 0x0020) =>
2091
+ {
2092
+ error!(slf, Error::ControlCharacterReference);
2093
+ slf.machine_helper.character_reference_code = match x {
2094
+ 0x80 => 0x20AC, // EURO SIGN (€)
2095
+ 0x82 => 0x201A, // SINGLE LOW-9 QUOTATION MARK (‚)
2096
+ 0x83 => 0x0192, // LATIN SMALL LETTER F WITH HOOK (ƒ)
2097
+ 0x84 => 0x201E, // DOUBLE LOW-9 QUOTATION MARK („)
2098
+ 0x85 => 0x2026, // HORIZONTAL ELLIPSIS (…)
2099
+ 0x86 => 0x2020, // DAGGER (†)
2100
+ 0x87 => 0x2021, // DOUBLE DAGGER (‡)
2101
+ 0x88 => 0x02C6, // MODIFIER LETTER CIRCUMFLEX ACCENT (ˆ)
2102
+ 0x89 => 0x2030, // PER MILLE SIGN (‰)
2103
+ 0x8A => 0x0160, // LATIN CAPITAL LETTER S WITH CARON (Š)
2104
+ 0x8B => 0x2039, // SINGLE LEFT-POINTING ANGLE QUOTATION MARK (‹)
2105
+ 0x8C => 0x0152, // LATIN CAPITAL LIGATURE OE (Œ)
2106
+ 0x8E => 0x017D, // LATIN CAPITAL LETTER Z WITH CARON (Ž)
2107
+ 0x91 => 0x2018, // LEFT SINGLE QUOTATION MARK (‘)
2108
+ 0x92 => 0x2019, // RIGHT SINGLE QUOTATION MARK (’)
2109
+ 0x93 => 0x201C, // LEFT DOUBLE QUOTATION MARK (“)
2110
+ 0x94 => 0x201D, // RIGHT DOUBLE QUOTATION MARK (”)
2111
+ 0x95 => 0x2022, // BULLET (•)
2112
+ 0x96 => 0x2013, // EN DASH (–)
2113
+ 0x97 => 0x2014, // EM DASH (—)
2114
+ 0x98 => 0x02DC, // SMALL TILDE (˜)
2115
+ 0x99 => 0x2122, // TRADE MARK SIGN (™)
2116
+ 0x9A => 0x0161, // LATIN SMALL LETTER S WITH CARON (š)
2117
+ 0x9B => 0x203A, // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (›)
2118
+ 0x9C => 0x0153, // LATIN SMALL LIGATURE OE (œ)
2119
+ 0x9E => 0x017E, // LATIN SMALL LETTER Z WITH CARON (ž)
2120
+ 0x9F => 0x0178, // LATIN CAPITAL LETTER Y WITH DIAERESIS (Ÿ)
2121
+ _ => slf.machine_helper.character_reference_code,
2122
+ };
2123
+ }
2124
+ _ => (),
2125
+ }
2126
+
2127
+ slf.machine_helper.temporary_buffer.clear();
2128
+ slf.machine_helper.temporary_buffer.extend(
2129
+ ctostr!(std::char::from_u32(slf.machine_helper.character_reference_code).unwrap())
2130
+ .as_bytes(),
2131
+ );
2132
+ slf.machine_helper
2133
+ .flush_code_points_consumed_as_character_reference(&mut slf.emitter);
2134
+ exit_state!(slf)
2135
+ });
2136
+ }