Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up the parsers into a single interface #13675

Merged
merged 9 commits into from Oct 11, 2016

Introduce ServoParser::document

  • Loading branch information
nox committed Oct 11, 2016
commit 27f245e6aeb9a690bf6367789045b7ff142a7b63
@@ -121,7 +121,7 @@ impl AsyncResponseListener for ParserContext {
parser.pending_input().borrow_mut().push(page);
parser.parse_sync();

let doc = parser.document();
let doc = parser.as_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()));
@@ -199,7 +199,8 @@ impl AsyncResponseListener for ParserContext {
debug!("Failed to load page URL {}, error: {:?}", self.url, err);
}

parser.r().document().finish_load(LoadType::PageSource(self.url.clone()));
parser.r().as_servo_parser().document()
.finish_load(LoadType::PageSource(self.url.clone()));

parser.r().last_chunk_received().set(true);
if !parser.r().is_suspended() {
@@ -218,8 +219,6 @@ pub struct ServoHTMLParser {
tokenizer: DOMRefCell<Tokenizer>,
/// Input chunks received but not yet passed to the parser.
pending_input: DOMRefCell<Vec<String>>,
/// The document associated with this parser.
document: JS<Document>,
/// 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.
@@ -231,7 +230,7 @@ pub struct ServoHTMLParser {

impl<'a> Parser for &'a ServoHTMLParser {
fn parse_chunk(self, input: String) {
self.document.set_current_parser(Some(ParserRef::HTML(self)));
self.upcast().document().set_current_parser(Some(ParserRef::HTML(self)));
self.pending_input.borrow_mut().push(input);
if !self.is_suspended() {
self.parse_sync();
@@ -245,7 +244,7 @@ impl<'a> Parser for &'a ServoHTMLParser {
self.tokenizer.borrow_mut().end();
debug!("finished parsing");

self.document.set_current_parser(None);
self.upcast().document().set_current_parser(None);

if let Some(pipeline) = self.pipeline {
ScriptThread::parsing_complete(pipeline);
@@ -270,10 +269,9 @@ impl ServoHTMLParser {
let tok = tokenizer::Tokenizer::new(tb, Default::default());

let parser = ServoHTMLParser {
servoparser: ServoParser::new_inherited(),
servoparser: ServoParser::new_inherited(document),
tokenizer: DOMRefCell::new(tok),
pending_input: DOMRefCell::new(vec!()),
document: JS::from_ref(document),
suspended: Cell::new(false),
last_chunk_received: Cell::new(false),
pipeline: pipeline,
@@ -306,10 +304,9 @@ impl ServoHTMLParser {
let tok = tokenizer::Tokenizer::new(tb, tok_opts);

let parser = ServoHTMLParser {
servoparser: ServoParser::new_inherited(),
servoparser: ServoParser::new_inherited(document),
tokenizer: DOMRefCell::new(tok),
pending_input: DOMRefCell::new(vec!()),
document: JS::from_ref(document),
suspended: Cell::new(false),
last_chunk_received: Cell::new(true),
pipeline: None,
@@ -340,21 +337,21 @@ impl ServoHTMLParser {
impl ServoHTMLParser {
pub fn parse_sync(&self) {
let metadata = TimerMetadata {
url: self.document.url().as_str().into(),
url: self.upcast().document().url().as_str().into(),
iframe: TimerMetadataFrameType::RootWindow,
incremental: TimerMetadataReflowType::FirstReflow,
};
profile(ProfilerCategory::ScriptParseHTML,
Some(metadata),
self.document.window().upcast::<GlobalScope>().time_profiler_chan().clone(),
self.upcast().document().window().upcast::<GlobalScope>().time_profiler_chan().clone(),
|| self.do_parse_sync())
}

fn do_parse_sync(&self) {
// This parser will continue to parse while there is either pending input or
// the parser remains unsuspended.
loop {
self.document.reflow_if_reflow_timer_expired();
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);
@@ -379,7 +376,7 @@ impl ServoHTMLParser {
}

pub fn window(&self) -> &Window {
self.document.window()
self.upcast().document().window()
}

pub fn suspend(&self) {
@@ -397,10 +394,6 @@ impl ServoHTMLParser {
self.suspended.get()
}

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

pub fn last_chunk_received(&self) -> &Cell<bool> {
&self.last_chunk_received
}
@@ -3,16 +3,25 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::reflector::Reflector;
use dom::bindings::js::JS;
use dom::document::Document;

#[dom_struct]
pub struct ServoParser {
reflector: Reflector,
/// The document associated with this parser.
document: JS<Document>,
}

impl ServoParser {
pub fn new_inherited() -> Self {
pub fn new_inherited(document: &Document) -> Self {
ServoParser {
reflector: Reflector::new(),
document: JS::from_ref(document),
}
}

pub fn document(&self) -> &Document {
&self.document
}
}
@@ -4,6 +4,7 @@

use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::ServoXMLParserBinding;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, Root};
use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::trace::JSTraceable;
@@ -37,8 +38,6 @@ pub struct ServoXMLParser {
tokenizer: DOMRefCell<Tokenizer>,
/// Input chunks received but not yet passed to the parser.
pending_input: DOMRefCell<Vec<String>>,
/// The document associated with this parser.
document: JS<Document>,
/// 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.
@@ -50,7 +49,7 @@ pub struct ServoXMLParser {

impl<'a> Parser for &'a ServoXMLParser {
fn parse_chunk(self, input: String) {
self.document.set_current_parser(Some(ParserRef::XML(self)));
self.upcast().document().set_current_parser(Some(ParserRef::XML(self)));
self.pending_input.borrow_mut().push(input);
if !self.is_suspended() {
self.parse_sync();
@@ -64,7 +63,7 @@ impl<'a> Parser for &'a ServoXMLParser {
self.tokenizer.borrow_mut().end();
debug!("finished parsing");

self.document.set_current_parser(None);
self.upcast().document().set_current_parser(None);

if let Some(pipeline) = self.pipeline {
ScriptThread::parsing_complete(pipeline);
@@ -86,10 +85,9 @@ impl ServoXMLParser {
let tok = tokenizer::XmlTokenizer::new(tb, Default::default());

let parser = ServoXMLParser {
servoparser: ServoParser::new_inherited(),
servoparser: ServoParser::new_inherited(document),
tokenizer: DOMRefCell::new(tok),
pending_input: DOMRefCell::new(vec!()),
document: JS::from_ref(document),
suspended: Cell::new(false),
last_chunk_received: Cell::new(false),
pipeline: pipeline,
@@ -99,7 +97,7 @@ impl ServoXMLParser {
}

pub fn window(&self) -> &Window {
self.document.window()
self.upcast().document().window()
}

pub fn resume(&self) {
@@ -121,7 +119,7 @@ impl ServoXMLParser {
// This parser will continue to parse while there is either pending input or
// the parser remains unsuspended.
loop {
self.document.reflow_if_reflow_timer_expired();
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);
@@ -157,10 +155,6 @@ impl ServoXMLParser {
self.tokenizer.borrow_mut().end()
}

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

pub fn last_chunk_received(&self) -> &Cell<bool> {
&self.last_chunk_received
}
@@ -3,10 +3,11 @@
* 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;
use dom::document::Document;
use dom::servohtmlparser::ServoHTMLParser;
use dom::servoparser::ServoParser;
use dom::servoxmlparser::ServoXMLParser;
use dom::window::Window;
use std::cell::Cell;
@@ -104,6 +105,13 @@ pub enum ParserRef<'a> {
}

impl<'a> ParserRef<'a> {
pub fn as_servo_parser(&self) -> &ServoParser {
match *self {
ParserRef::HTML(parser) => parser.upcast(),
ParserRef::XML(parser) => parser.upcast(),
}
}

pub fn parse_chunk(&self, input: String) {
match *self {
ParserRef::HTML(parser) => parser.parse_chunk(input),
@@ -160,13 +168,6 @@ impl<'a> ParserRef<'a> {
}
}

pub fn document(&self) -> &Document {
match *self {
ParserRef::HTML(parser) => parser.document(),
ParserRef::XML(parser) => parser.document(),
}
}

pub fn last_chunk_received(&self) -> &Cell<bool> {
match *self {
ParserRef::HTML(parser) => parser.last_chunk_received(),
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.