Skip to content

Commit

Permalink
Move pending input logic to ServoParser
Browse files Browse the repository at this point in the history
  • Loading branch information
nox committed Oct 11, 2016
1 parent 27f245e commit e1a1bf4
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 43 deletions.
32 changes: 11 additions & 21 deletions components/script/dom/servohtmlparser.rs
Expand Up @@ -107,6 +107,7 @@ impl AsyncResponseListener for ParserContext {
};

let parser = parser.r();
let servo_parser = parser.as_servo_parser();
self.parser = Some(match parser {
ParserRef::HTML(parser) => TrustedParser::HTML(
Trusted::new(parser)),
Expand All @@ -118,10 +119,10 @@ impl AsyncResponseListener for ParserContext {
Some(ContentType(Mime(TopLevel::Image, _, _))) => {
self.is_synthesized_document = true;
let page = "<html><body></body></html>".into();
parser.pending_input().borrow_mut().push(page);
servo_parser.push_input_chunk(page);
parser.parse_sync();

let doc = parser.as_servo_parser().document();
let doc = servo_parser.document();
let doc_body = Root::upcast::<Node>(doc.GetBody().unwrap());
let img = HTMLImageElement::new(atom!("img"), None, doc);
img.SetSrc(DOMString::from(self.url.to_string()));
Expand All @@ -131,7 +132,7 @@ impl AsyncResponseListener for ParserContext {
Some(ContentType(Mime(TopLevel::Text, SubLevel::Plain, _))) => {
// https://html.spec.whatwg.org/multipage/#read-text
let page = "<pre>\n".into();
parser.pending_input().borrow_mut().push(page);
servo_parser.push_input_chunk(page);
parser.parse_sync();
parser.set_plaintext_state();
},
Expand All @@ -141,7 +142,7 @@ impl AsyncResponseListener for ParserContext {
let page_bytes = read_resource_file("badcert.html").unwrap();
let page = String::from_utf8(page_bytes).unwrap();
let page = page.replace("${reason}", &reason);
parser.pending_input().borrow_mut().push(page);
servo_parser.push_input_chunk(page);
parser.parse_sync();
}
},
Expand All @@ -156,7 +157,7 @@ impl AsyncResponseListener for ParserContext {
let page = format!("<html><body><p>Unknown content type ({}/{}).</p></body></html>",
toplevel.as_str(), sublevel.as_str());
self.is_synthesized_document = true;
parser.pending_input().borrow_mut().push(page);
servo_parser.push_input_chunk(page);
parser.parse_sync();
},
None => {
Expand Down Expand Up @@ -192,7 +193,7 @@ impl AsyncResponseListener for ParserContext {
let page_bytes = read_resource_file("neterror.html").unwrap();
let page = String::from_utf8(page_bytes).unwrap();
let page = page.replace("${reason}", reason);
parser.pending_input().borrow_mut().push(page);
parser.as_servo_parser().push_input_chunk(page);
parser.parse_sync();
} else if let Err(err) = status {
// TODO(Savago): we should send a notification to callers #5463.
Expand All @@ -217,8 +218,6 @@ pub struct ServoHTMLParser {
servoparser: ServoParser,
#[ignore_heap_size_of = "Defined in html5ever"]
tokenizer: DOMRefCell<Tokenizer>,
/// Input chunks received but not yet passed to the parser.
pending_input: DOMRefCell<Vec<String>>,
/// True if this parser should avoid passing any further data to the tokenizer.
suspended: Cell<bool>,
/// Whether to expect any further input from the associated network request.
Expand All @@ -231,15 +230,15 @@ pub struct ServoHTMLParser {
impl<'a> Parser for &'a ServoHTMLParser {
fn parse_chunk(self, input: String) {
self.upcast().document().set_current_parser(Some(ParserRef::HTML(self)));
self.pending_input.borrow_mut().push(input);
self.upcast().push_input_chunk(input);
if !self.is_suspended() {
self.parse_sync();
}
}

fn finish(self) {
assert!(!self.suspended.get());
assert!(self.pending_input.borrow().is_empty());
assert!(!self.upcast().has_pending_input());

self.tokenizer.borrow_mut().end();
debug!("finished parsing");
Expand Down Expand Up @@ -271,7 +270,6 @@ impl ServoHTMLParser {
let parser = ServoHTMLParser {
servoparser: ServoParser::new_inherited(document),
tokenizer: DOMRefCell::new(tok),
pending_input: DOMRefCell::new(vec!()),
suspended: Cell::new(false),
last_chunk_received: Cell::new(false),
pipeline: pipeline,
Expand Down Expand Up @@ -306,7 +304,6 @@ impl ServoHTMLParser {
let parser = ServoHTMLParser {
servoparser: ServoParser::new_inherited(document),
tokenizer: DOMRefCell::new(tok),
pending_input: DOMRefCell::new(vec!()),
suspended: Cell::new(false),
last_chunk_received: Cell::new(true),
pipeline: None,
Expand All @@ -327,11 +324,6 @@ impl ServoHTMLParser {
pub fn end_tokenizer(&self) {
self.tokenizer.borrow_mut().end()
}

pub fn pending_input(&self) -> &DOMRefCell<Vec<String>> {
&self.pending_input
}

}

impl ServoHTMLParser {
Expand All @@ -352,9 +344,7 @@ impl ServoHTMLParser {
// the parser remains unsuspended.
loop {
self.upcast().document().reflow_if_reflow_timer_expired();
let mut pending_input = self.pending_input.borrow_mut();
if !pending_input.is_empty() {
let chunk = pending_input.remove(0);
if let Some(chunk) = self.upcast().take_next_input_chunk() {
self.tokenizer.borrow_mut().feed(chunk.into());
} else {
self.tokenizer.borrow_mut().run();
Expand All @@ -365,7 +355,7 @@ impl ServoHTMLParser {
return;
}

if pending_input.is_empty() {
if !self.upcast().has_pending_input() {
break;
}
}
Expand Down
21 changes: 21 additions & 0 deletions components/script/dom/servoparser.rs
Expand Up @@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::cell::DOMRefCell;
use dom::bindings::reflector::Reflector;
use dom::bindings::js::JS;
use dom::document::Document;
Expand All @@ -11,17 +12,37 @@ pub struct ServoParser {
reflector: Reflector,
/// The document associated with this parser.
document: JS<Document>,
/// Input chunks received but not yet passed to the parser.
pending_input: DOMRefCell<Vec<String>>,
}

impl ServoParser {
pub fn new_inherited(document: &Document) -> Self {
ServoParser {
reflector: Reflector::new(),
document: JS::from_ref(document),
pending_input: DOMRefCell::new(vec![]),
}
}

pub fn document(&self) -> &Document {
&self.document
}

pub fn has_pending_input(&self) -> bool {
!self.pending_input.borrow().is_empty()
}

pub fn push_input_chunk(&self, chunk: String) {
self.pending_input.borrow_mut().push(chunk);
}

pub fn take_next_input_chunk(&self) -> Option<String> {
let mut pending_input = self.pending_input.borrow_mut();
if pending_input.is_empty() {
None
} else {
Some(pending_input.remove(0))
}
}
}
19 changes: 5 additions & 14 deletions components/script/dom/servoxmlparser.rs
Expand Up @@ -36,8 +36,6 @@ pub struct ServoXMLParser {
servoparser: ServoParser,
#[ignore_heap_size_of = "Defined in xml5ever"]
tokenizer: DOMRefCell<Tokenizer>,
/// Input chunks received but not yet passed to the parser.
pending_input: DOMRefCell<Vec<String>>,
/// True if this parser should avoid passing any further data to the tokenizer.
suspended: Cell<bool>,
/// Whether to expect any further input from the associated network request.
Expand All @@ -50,15 +48,15 @@ pub struct ServoXMLParser {
impl<'a> Parser for &'a ServoXMLParser {
fn parse_chunk(self, input: String) {
self.upcast().document().set_current_parser(Some(ParserRef::XML(self)));
self.pending_input.borrow_mut().push(input);
self.upcast().push_input_chunk(input);
if !self.is_suspended() {
self.parse_sync();
}
}

fn finish(self) {
assert!(!self.suspended.get());
assert!(self.pending_input.borrow().is_empty());
assert!(!self.upcast().has_pending_input());

self.tokenizer.borrow_mut().end();
debug!("finished parsing");
Expand Down Expand Up @@ -87,7 +85,6 @@ impl ServoXMLParser {
let parser = ServoXMLParser {
servoparser: ServoParser::new_inherited(document),
tokenizer: DOMRefCell::new(tok),
pending_input: DOMRefCell::new(vec!()),
suspended: Cell::new(false),
last_chunk_received: Cell::new(false),
pipeline: pipeline,
Expand Down Expand Up @@ -119,10 +116,8 @@ impl ServoXMLParser {
// This parser will continue to parse while there is either pending input or
// the parser remains unsuspended.
loop {
self.upcast().document().reflow_if_reflow_timer_expired();
let mut pending_input = self.pending_input.borrow_mut();
if !pending_input.is_empty() {
let chunk = pending_input.remove(0);
self.upcast().document().reflow_if_reflow_timer_expired();
if let Some(chunk) = self.upcast().take_next_input_chunk() {
self.tokenizer.borrow_mut().feed(chunk.into());
} else {
self.tokenizer.borrow_mut().run();
Expand All @@ -133,7 +128,7 @@ impl ServoXMLParser {
return;
}

if pending_input.is_empty() {
if !self.upcast().has_pending_input() {
break;
}
}
Expand All @@ -143,10 +138,6 @@ impl ServoXMLParser {
}
}

pub fn pending_input(&self) -> &DOMRefCell<Vec<String>> {
&self.pending_input
}

pub fn set_plaintext_state(&self) {
//self.tokenizer.borrow_mut().set_plaintext_state()
}
Expand Down
8 changes: 0 additions & 8 deletions components/script/parse/mod.rs
Expand Up @@ -2,7 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::cell::DOMRefCell;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, Root};
use dom::bindings::refcounted::Trusted;
Expand Down Expand Up @@ -147,13 +146,6 @@ impl<'a> ParserRef<'a> {
}
}

pub fn pending_input(&self) -> &DOMRefCell<Vec<String>> {
match *self {
ParserRef::HTML(parser) => parser.pending_input(),
ParserRef::XML(parser) => parser.pending_input(),
}
}

pub fn set_plaintext_state(&self) {
match *self {
ParserRef::HTML(parser) => parser.set_plaintext_state(),
Expand Down

0 comments on commit e1a1bf4

Please sign in to comment.