Skip to content

Commit 288a859

Browse files
committed
Merge pull request #17 from ConnorGBrewster/add_quiescent
Added quiescent for parser interrupting
2 parents a51a6df + ea19798 commit 288a859

File tree

5 files changed

+45
-13
lines changed

5 files changed

+45
-13
lines changed

src/tokenizer/mod.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,8 @@ impl <Sink:TokenSink> XmlTokenizer<Sink> {
315315
}
316316
}
317317

318-
// Run the state machine for as long as we can.
319-
fn run(&mut self) {
318+
/// Run the state machine for as long as we can.
319+
pub fn run(&mut self) {
320320
if self.opts.profile {
321321
loop {
322322
let state = self.state;
@@ -437,11 +437,9 @@ impl <Sink:TokenSink> XmlTokenizer<Sink> {
437437
self.process_token(token);
438438

439439

440-
if self.current_tag_kind == StartTag {
441-
match self.sink.query_state_change() {
442-
None => (),
443-
Some(s) => self.state = s,
444-
}
440+
match self.sink.query_state_change() {
441+
None => (),
442+
Some(s) => self.state = s,
445443
}
446444
}
447445

@@ -661,6 +659,10 @@ impl<Sink: TokenSink> XmlTokenizer<Sink> {
661659

662660
debug!("processing in state {:?}", self.state);
663661
match self.state {
662+
XmlState::Quiescent => {
663+
self.state = XmlState::Data;
664+
return false;
665+
},
664666
//§ data-state
665667
XmlState::Data => loop {
666668
match pop_except_from!(self, small_char_set!('\r' '&' '<')) {
@@ -1054,6 +1056,7 @@ impl<Sink: TokenSink> XmlTokenizer<Sink> {
10541056
debug!("processing EOF in state {:?}", self.state);
10551057
match self.state {
10561058
XmlState::Data
1059+
| XmlState::Quiescent
10571060
=> go!(self: eof),
10581061
XmlState::TagState
10591062
=> go!(self: error_eof; emit '<'; to Data),

src/tokenizer/states.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ pub enum XmlState {
6363
BetweenDoctypePublicAndSystemIdentifiers,
6464
BogusDoctype,
6565
BogusComment,
66+
Quiescent,
6667
}
6768

6869
#[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Hash, Debug)]

src/tree_builder/actions.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
use std::borrow::Cow::Borrowed;
1111
use tendril::{StrTendril, Tendril};
1212
use tokenizer::{Tag, Pi, QName, Doctype};
13-
use tree_builder::interface::{NodeOrText, TreeSink, AppendNode, AppendText};
13+
use tokenizer::states::Quiescent;
14+
use tree_builder::interface::{NextParserState, NodeOrText, TreeSink, AppendNode, AppendText};
1415
use tree_builder::types::{XmlProcessResult, Done};
1516

1617
/// Trait that encapsulates common XML tree actions.
@@ -73,6 +74,9 @@ pub trait XmlTreeBuilderActions<Handle> {
7374

7475
/// Stops parsing of XML file.
7576
fn stop_parsing(&mut self) -> XmlProcessResult;
77+
78+
/// Indicated a `script` element is complete and can be prepared
79+
fn complete_script(&mut self);
7680
}
7781

7882
#[doc(hidden)]
@@ -225,4 +229,11 @@ impl<Handle, Sink> XmlTreeBuilderActions<Handle>
225229
warn!("stop_parsing for XML5 not implemented, full speed ahead!");
226230
Done
227231
}
232+
233+
fn complete_script(&mut self) {
234+
let current = self.pop();
235+
if self.sink.complete_script(current) == NextParserState::Suspend {
236+
self.next_tokenizer_state = Some(Quiescent);
237+
}
238+
}
228239
}

src/tree_builder/interface.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,14 @@ pub trait TreeSink {
8181
name: StrTendril,
8282
public_id: StrTendril,
8383
system_id: StrTendril);
84+
85+
/// Mark a HTML `<script>` as "already started".
86+
fn mark_script_already_started(&mut self, _node: Self::Handle) {}
87+
88+
/// Indicate that a `script` element is complete.
89+
fn complete_script(&mut self, _node: Self::Handle) -> NextParserState {
90+
NextParserState::Continue
91+
}
8492
}
8593

8694
/// Trace hooks for a garbage-collected DOM.

src/tree_builder/rules.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,18 +116,27 @@ impl<Handle, Sink> XmlTreeBuilderStep
116116
self.process_namespaces(&mut tag);
117117
tag
118118
};
119-
self.append_tag(tag)
119+
if tag.name.local == atom!("script") {
120+
self.insert_tag(tag.clone());
121+
self.complete_script();
122+
self.close_tag(tag)
123+
} else {
124+
self.append_tag(tag)
125+
}
120126
},
121127
TagToken(Tag{kind: EndTag, name, attrs}) => {
122128
let tag = {
123-
let mut tag = Tag {
129+
let mut tag = Tag {
124130
kind: EndTag,
125131
name: name,
126132
attrs: attrs,
127-
};
128-
self.process_namespaces(&mut tag);
129-
tag
133+
};
134+
self.process_namespaces(&mut tag);
135+
tag
130136
};
137+
if tag.name.local == atom!("script") {
138+
self.complete_script();
139+
}
131140
let retval = self.close_tag(tag);
132141
if self.no_open_elems() {
133142
self.phase = EndPhase;

0 commit comments

Comments
 (0)