queue event instead of immediately fire

created checks to see if parser is in use before event dispatch

changed tests to expect crash and added async style test
This commit is contained in:
ddh 2017-11-20 23:07:10 +00:00
parent 462409ada5
commit 79d896d474
9 changed files with 72 additions and 3 deletions

View file

@ -1885,6 +1885,13 @@ impl Document {
self.current_parser.get()
}
pub fn can_invoke_script(&self) -> bool {
match self.get_current_parser() {
Some(parser) => parser.parser_is_not_active(),
None => true,
}
}
/// Iterate over all iframes in the document.
pub fn iter_iframes(&self) -> impl Iterator<Item=DomRoot<HTMLIFrameElement>> {
self.upcast::<Node>()

View file

@ -315,10 +315,21 @@ impl EventTarget {
pub fn dispatch_event_with_target(&self,
target: &EventTarget,
event: &Event) -> EventStatus {
if let Some(window) = target.global().downcast::<Window>() {
if window.has_document() {
assert!(window.Document().can_invoke_script());
}
};
event.dispatch(self, Some(target))
}
pub fn dispatch_event(&self, event: &Event) -> EventStatus {
if let Some(window) = self.global().downcast::<Window>() {
if window.has_document() {
assert!(window.Document().can_invoke_script());
}
};
event.dispatch(self, None)
}

View file

@ -12,7 +12,6 @@ use dom::bindings::root::{DomRoot, MutNullableDom};
use dom::cssstylesheet::CSSStyleSheet;
use dom::document::Document;
use dom::element::{Element, ElementCreator};
use dom::eventtarget::EventTarget;
use dom::htmlelement::HTMLElement;
use dom::node::{ChildrenMutation, Node, UnbindContext, document_from_node, window_from_node};
use dom::stylesheet::StyleSheet as DOMStyleSheet;
@ -105,9 +104,10 @@ impl HTMLStyleElement {
let sheet = Arc::new(sheet);
// No subresource loads were triggered, just fire the load event now.
// No subresource loads were triggered, queue load event
if self.pending_loads.get() == 0 {
self.upcast::<EventTarget>().fire_event(atom!("load"));
let window = window_from_node(self);
window.dom_manipulation_task_source().queue_simple_event(self.upcast(), atom!("load"), &window);
}
self.set_stylesheet(sheet);

View file

@ -102,6 +102,10 @@ enum LastChunkState {
}
impl ServoParser {
pub fn parser_is_not_active(&self) -> bool {
self.can_write() || self.tokenizer.try_borrow_mut().is_ok()
}
pub fn parse_html_document(document: &Document, input: DOMString, url: ServoUrl) {
let parser = if PREFS.get("dom.servoparser.async_html_tokenizer.enabled").as_boolean().unwrap() {
ServoParser::new(document,

View file

@ -1048,6 +1048,10 @@ impl Window {
self.navigation_start_precise.get()
}
pub fn has_document(&self) -> bool {
self.document.get().is_some()
}
/// Cancels all the tasks associated with that window.
///
/// This sets the current `ignore_further_async_events` sentinel value to

View file

@ -314573,6 +314573,12 @@
{}
]
],
"html/semantics/document-metadata/the-style-element/style_load_async.html": [
[
"/html/semantics/document-metadata/the-style-element/style_load_async.html",
{}
]
],
"html/semantics/document-metadata/the-style-element/style_media.html": [
[
"/html/semantics/document-metadata/the-style-element/style_media.html",
@ -539856,6 +539862,10 @@
"77a9ee6e0d58d2aa905423f3b6f9d55492ed8eb9",
"testharness"
],
"html/semantics/document-metadata/the-style-element/style_load_async.html": [
"09e5519ec1a2d1f8b044f9d1309cf36695d4631d",
"testharness"
],
"html/semantics/document-metadata/the-style-element/style_media.html": [
"3d608438361d8bec5726feb468a3c2fbd5b7cb7d",
"testharness"

View file

@ -0,0 +1,4 @@
[microtasks-and-constructors.html]
expected: CRASH
bug: https://github.com/servo/servo/issues/19392

View file

@ -0,0 +1,4 @@
[parser-fallsback-to-unknown-element.html]
expected: CRASH
bug: https://github.com/servo/servo/issues/19392

View file

@ -0,0 +1,25 @@
<!doctype html>
<html>
<meta charset="utf-8">
<title>Style load event should be async</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
var t = async_test("style load should be async");
var sync = true;
function check() {
assert_false(sync);
t.done();
}
</script>
<style onload="t.step(check)">
</style>
<script>
sync = false
</script>
<body>
<div id="log"></div>
<div id="test"></div>
</body>
</html>