mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Switch to synchronous script loading
This removes the old code for asyncronously loading scripts during HTML parsing and then executing them afterward. Fixes #3356.
This commit is contained in:
parent
65a0d1fe9a
commit
fe123ad07c
39 changed files with 284 additions and 1006 deletions
|
@ -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,12 +2,14 @@
|
|||
* 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;
|
||||
|
@ -15,10 +17,12 @@ 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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue