From e1a1bf46cadd1787f543ed75d24c35bf2ae79092 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Sat, 8 Oct 2016 15:48:47 +0200 Subject: [PATCH] Move pending input logic to ServoParser --- components/script/dom/servohtmlparser.rs | 32 ++++++++---------------- components/script/dom/servoparser.rs | 21 ++++++++++++++++ components/script/dom/servoxmlparser.rs | 19 ++++---------- components/script/parse/mod.rs | 8 ------ 4 files changed, 37 insertions(+), 43 deletions(-) diff --git a/components/script/dom/servohtmlparser.rs b/components/script/dom/servohtmlparser.rs index 3ed656c2bb4..aa80d387dab 100644 --- a/components/script/dom/servohtmlparser.rs +++ b/components/script/dom/servohtmlparser.rs @@ -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)), @@ -118,10 +119,10 @@ impl AsyncResponseListener for ParserContext { Some(ContentType(Mime(TopLevel::Image, _, _))) => { self.is_synthesized_document = true; let page = "".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::(doc.GetBody().unwrap()); let img = HTMLImageElement::new(atom!("img"), None, doc); img.SetSrc(DOMString::from(self.url.to_string())); @@ -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 = "
\n".into();
-                parser.pending_input().borrow_mut().push(page);
+                servo_parser.push_input_chunk(page);
                 parser.parse_sync();
                 parser.set_plaintext_state();
             },
@@ -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();
                 }
             },
@@ -156,7 +157,7 @@ impl AsyncResponseListener for ParserContext {
                 let page = format!("

Unknown content type ({}/{}).

", 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 => { @@ -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. @@ -217,8 +218,6 @@ pub struct ServoHTMLParser { servoparser: ServoParser, #[ignore_heap_size_of = "Defined in html5ever"] tokenizer: DOMRefCell, - /// Input chunks received but not yet passed to the parser. - pending_input: DOMRefCell>, /// True if this parser should avoid passing any further data to the tokenizer. suspended: Cell, /// Whether to expect any further input from the associated network request. @@ -231,7 +230,7 @@ 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(); } @@ -239,7 +238,7 @@ impl<'a> Parser for &'a ServoHTMLParser { 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"); @@ -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, @@ -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, @@ -327,11 +324,6 @@ impl ServoHTMLParser { pub fn end_tokenizer(&self) { self.tokenizer.borrow_mut().end() } - - pub fn pending_input(&self) -> &DOMRefCell> { - &self.pending_input - } - } impl ServoHTMLParser { @@ -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(); @@ -365,7 +355,7 @@ impl ServoHTMLParser { return; } - if pending_input.is_empty() { + if !self.upcast().has_pending_input() { break; } } diff --git a/components/script/dom/servoparser.rs b/components/script/dom/servoparser.rs index dc50569c3fc..1cdef6de642 100644 --- a/components/script/dom/servoparser.rs +++ b/components/script/dom/servoparser.rs @@ -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; @@ -11,6 +12,8 @@ pub struct ServoParser { reflector: Reflector, /// The document associated with this parser. document: JS, + /// Input chunks received but not yet passed to the parser. + pending_input: DOMRefCell>, } impl ServoParser { @@ -18,10 +21,28 @@ impl ServoParser { 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 { + let mut pending_input = self.pending_input.borrow_mut(); + if pending_input.is_empty() { + None + } else { + Some(pending_input.remove(0)) + } + } } diff --git a/components/script/dom/servoxmlparser.rs b/components/script/dom/servoxmlparser.rs index e5a1d78da7f..dd107c8d3c4 100644 --- a/components/script/dom/servoxmlparser.rs +++ b/components/script/dom/servoxmlparser.rs @@ -36,8 +36,6 @@ pub struct ServoXMLParser { servoparser: ServoParser, #[ignore_heap_size_of = "Defined in xml5ever"] tokenizer: DOMRefCell, - /// Input chunks received but not yet passed to the parser. - pending_input: DOMRefCell>, /// True if this parser should avoid passing any further data to the tokenizer. suspended: Cell, /// Whether to expect any further input from the associated network request. @@ -50,7 +48,7 @@ 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(); } @@ -58,7 +56,7 @@ impl<'a> Parser for &'a ServoXMLParser { 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"); @@ -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, @@ -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(); @@ -133,7 +128,7 @@ impl ServoXMLParser { return; } - if pending_input.is_empty() { + if !self.upcast().has_pending_input() { break; } } @@ -143,10 +138,6 @@ impl ServoXMLParser { } } - pub fn pending_input(&self) -> &DOMRefCell> { - &self.pending_input - } - pub fn set_plaintext_state(&self) { //self.tokenizer.borrow_mut().set_plaintext_state() } diff --git a/components/script/parse/mod.rs b/components/script/parse/mod.rs index 52493d3bb71..30f6bc158a6 100644 --- a/components/script/parse/mod.rs +++ b/components/script/parse/mod.rs @@ -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; @@ -147,13 +146,6 @@ impl<'a> ParserRef<'a> { } } - pub fn pending_input(&self) -> &DOMRefCell> { - 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(),