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

Synchronous script loading during HTML parsing #3721

Merged
merged 5 commits into from Oct 29, 2014
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Switch to synchronous script loading

This removes the old code for asyncronously loading scripts during HTML
parsing and then executing them afterward.

Fixes #3356.
  • Loading branch information
mbrubeck committed Oct 29, 2014
commit fe123ad07ce048c11c2820481c9fd54ce296202d
@@ -55,7 +55,7 @@ use dom::range::Range;
use dom::treewalker::TreeWalker;
use dom::uievent::UIEvent;
use dom::window::{Window, WindowHelpers};
use parse::html::build_element_from_tag;
use parse::html::{build_element_from_tag, ScriptCreated};
use servo_util::namespace;
use servo_util::str::{DOMString, split_html_space_chars};

@@ -529,7 +529,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> {
}
let local_name = local_name.as_slice().to_ascii_lower();
let name = QualName::new(ns!(HTML), Atom::from_slice(local_name.as_slice()));
Ok(build_element_from_tag(name, None, self))
Ok(build_element_from_tag(name, None, self, ScriptCreated))
}

// http://dom.spec.whatwg.org/#dom-document-createelementns
@@ -574,7 +574,8 @@ impl<'a> DocumentMethods for JSRef<'a, Document> {

if ns == ns!(HTML) {
let name = QualName::new(ns!(HTML), Atom::from_slice(local_name_from_qname));
Ok(build_element_from_tag(name, prefix_from_qname.map(|s| s.to_string()), self))
Ok(build_element_from_tag(name, prefix_from_qname.map(|s| s.to_string()), self,
ScriptCreated))
} else {
Ok(Element::new(local_name_from_qname.to_string(), ns,
prefix_from_qname.map(|s| s.to_string()), self))
@@ -2,23 +2,27 @@
* 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::attr::Attr;
use dom::attr::AttrHelpers;
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
use dom::bindings::codegen::Bindings::HTMLScriptElementBinding;
use dom::bindings::codegen::Bindings::HTMLScriptElementBinding::HTMLScriptElementMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::InheritTypes::HTMLScriptElementDerived;
use dom::bindings::codegen::InheritTypes::{ElementCast, NodeCast};
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, NodeCast};
use dom::bindings::js::{JSRef, Temporary, OptionalRootable};
use dom::bindings::utils::{Reflectable, Reflector};
use dom::document::Document;
use dom::element::{HTMLScriptElementTypeId, Element, AttributeHandlers};
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::node::{Node, NodeHelpers, ElementNodeTypeId, window_from_node};
use dom::virtualmethods::VirtualMethods;
use dom::window::WindowHelpers;

use encoding::all::UTF_8;
use encoding::types::{Encoding, DecodeReplace};
use parse::html::{ElementCreator, ParserCreated};
use servo_net::resource_task::load_whole_resource;
use servo_util::str::{DOMString, HTML_SPACE_CHARACTERS, StaticStringVec};
use std::cell::Cell;
@@ -53,20 +57,20 @@ impl HTMLScriptElementDerived for EventTarget {

impl HTMLScriptElement {
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>,
parser_inserted: bool) -> HTMLScriptElement {
creator: ElementCreator) -> HTMLScriptElement {
HTMLScriptElement {
htmlelement: HTMLElement::new_inherited(HTMLScriptElementTypeId, localName, prefix, document),
already_started: Cell::new(false),
parser_inserted: Cell::new(parser_inserted),
non_blocking: Cell::new(!parser_inserted),
parser_inserted: Cell::new(creator == ParserCreated),
non_blocking: Cell::new(creator != ParserCreated),
ready_to_be_parser_executed: Cell::new(false),
}
}

#[allow(unrooted_must_root)]
pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>,
parser_inserted: bool) -> Temporary<HTMLScriptElement> {
let element = HTMLScriptElement::new_inherited(localName, prefix, document, parser_inserted);
creator: ElementCreator) -> Temporary<HTMLScriptElement> {
let element = HTMLScriptElement::new_inherited(localName, prefix, document, creator);
Node::reflect_node(box element, document, HTMLScriptElementBinding::Wrap)
}
}
@@ -77,6 +81,9 @@ pub trait HTMLScriptElementHelpers {

/// Prepare a script, steps 6 and 7.
fn is_javascript(self) -> bool;

/// Set the "already started" flag (<https://whatwg.org/html/#already-started>)
fn mark_already_started(self);
}

/// Supported script types as defined by
@@ -232,6 +239,50 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> {
}
}
}

fn mark_already_started(self) {
self.already_started.set(true);
}
}

impl<'a> VirtualMethods for JSRef<'a, HTMLScriptElement> {
fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> {
let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
Some(htmlelement as &VirtualMethods)
}

fn after_set_attr(&self, attr: JSRef<Attr>) {
match self.super_type() {
Some(ref s) => s.after_set_attr(attr),
_ => (),
}
let node: JSRef<Node> = NodeCast::from_ref(*self);
if attr.local_name() == &atom!("src") && !self.parser_inserted.get() && node.is_in_doc() {
self.prepare();
}
}

fn child_inserted(&self, child: JSRef<Node>) {
match self.super_type() {
Some(ref s) => s.child_inserted(child),
_ => (),
}
let node: JSRef<Node> = NodeCast::from_ref(*self);
if !self.parser_inserted.get() && node.is_in_doc() {
self.prepare();
}
}

fn bind_to_tree(&self, tree_in_doc: bool) {
match self.super_type() {
Some(ref s) => s.bind_to_tree(tree_in_doc),
_ => ()
}

if tree_in_doc && !self.parser_inserted.get() {
self.prepare();
}
}
}

impl<'a> HTMLScriptElementMethods for JSRef<'a, HTMLScriptElement> {
@@ -45,7 +45,7 @@ use dom::text::Text;
use dom::virtualmethods::{VirtualMethods, vtable_for};
use dom::window::Window;
use geom::rect::Rect;
use parse::html::build_element_from_tag;
use parse::html::{build_element_from_tag, ScriptCreated};
use layout_interface::{ContentBoxResponse, ContentBoxesResponse, LayoutRPC,
LayoutChan, ReapLayoutDataMsg};
use devtools_traits::NodeInfo;
@@ -1521,7 +1521,7 @@ impl Node {
local: element.local_name().clone()
};
let element = build_element_from_tag(name,
Some(element.prefix().as_slice().to_string()), *document);
Some(element.prefix().as_slice().to_string()), *document, ScriptCreated);
NodeCast::from_temporary(element)
},
TextNodeTypeId => {
@@ -13,7 +13,6 @@ use dom::bindings::js::{JS, JSRef, Temporary};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::node::TrustedNodeAddress;
use dom::document::{Document, DocumentHelpers};
use parse::html::JSMessage;
use parse::Parser;

use servo_util::task_state;
@@ -28,7 +27,6 @@ use html5ever::tree_builder::{TreeBuilder, TreeBuilderOpts};
#[must_root]
#[jstraceable]
pub struct Sink {
pub js_chan: Sender<JSMessage>,
pub base_url: Option<Url>,
pub document: JS<Document>,
}
@@ -55,11 +53,9 @@ impl Parser for ServoHTMLParser{

impl ServoHTMLParser {
#[allow(unrooted_must_root)]
pub fn new(js_chan: Sender<JSMessage>, base_url: Option<Url>, document: JSRef<Document>)
-> Temporary<ServoHTMLParser> {
pub fn new(base_url: Option<Url>, document: JSRef<Document>) -> Temporary<ServoHTMLParser> {
let window = document.window().root();
let sink = Sink {
js_chan: js_chan,
base_url: base_url,
document: JS::from_rooted(document),
};
@@ -18,6 +18,7 @@ use dom::bindings::codegen::InheritTypes::HTMLLinkElementCast;
use dom::bindings::codegen::InheritTypes::HTMLObjectElementCast;
use dom::bindings::codegen::InheritTypes::HTMLOptGroupElementCast;
use dom::bindings::codegen::InheritTypes::HTMLOptionElementCast;
use dom::bindings::codegen::InheritTypes::HTMLScriptElementCast;
use dom::bindings::codegen::InheritTypes::HTMLSelectElementCast;
use dom::bindings::codegen::InheritTypes::HTMLStyleElementCast;
use dom::bindings::codegen::InheritTypes::HTMLTableCellElementCast;
@@ -37,6 +38,7 @@ use dom::element::HTMLLinkElementTypeId;
use dom::element::HTMLObjectElementTypeId;
use dom::element::HTMLOptGroupElementTypeId;
use dom::element::HTMLOptionElementTypeId;
use dom::element::HTMLScriptElementTypeId;
use dom::element::HTMLSelectElementTypeId;
use dom::element::HTMLStyleElementTypeId;
use dom::element::HTMLTableDataCellElementTypeId;
@@ -56,6 +58,7 @@ use dom::htmllinkelement::HTMLLinkElement;
use dom::htmlobjectelement::HTMLObjectElement;
use dom::htmloptgroupelement::HTMLOptGroupElement;
use dom::htmloptionelement::HTMLOptionElement;
use dom::htmlscriptelement::HTMLScriptElement;
use dom::htmlselectelement::HTMLSelectElement;
use dom::htmlstyleelement::HTMLStyleElement;
use dom::htmltablecellelement::HTMLTableCellElement;
@@ -189,6 +192,10 @@ pub fn vtable_for<'a>(node: &'a JSRef<'a, Node>) -> &'a VirtualMethods + 'a {
let element: &'a JSRef<'a, HTMLOptionElement> = HTMLOptionElementCast::to_borrowed_ref(node).unwrap();
element as &'a VirtualMethods + 'a
}
ElementNodeTypeId(HTMLScriptElementTypeId) => {
let element: &'a JSRef<'a, HTMLScriptElement> = HTMLScriptElementCast::to_borrowed_ref(node).unwrap();
element as &'a VirtualMethods + 'a
}
ElementNodeTypeId(HTMLSelectElementTypeId) => {
let element: &'a JSRef<'a, HTMLSelectElement> = HTMLSelectElementCast::to_borrowed_ref(node).unwrap();
element as &'a VirtualMethods + 'a
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.