servo: Merge #15189 - Implement microtask checkpoints (from jdm:microtasks); r=nox

This generalizes the work previously done for Promise job callbacks. There is now a microtask queue that correctly processes all queued microtasks after each turn of the event loop, as well as after a scripted callback finishes executing, and after a classic script executes.

---
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #4283
- [X] There are tests for these changes

Source-Repo: https://github.com/servo/servo
Source-Revision: cbcafd18f4cb5973948b081b4c104d99735e2789
This commit is contained in:
Josh Matthews
2017-02-03 07:53:17 -08:00
parent 908e301a06
commit 22c551f228
11 changed files with 339 additions and 292 deletions

View File

@@ -486,11 +486,7 @@ impl HTMLScriptElement {
document.set_current_script(Some(self));
// Step 5.a.2.
let window = window_from_node(self);
let line_number = if script.external { 1 } else { self.line_number as u32 };
rooted!(in(window.get_cx()) let mut rval = UndefinedValue());
window.upcast::<GlobalScope>().evaluate_script_on_global_with_result(
&script.text, script.url.as_str(), rval.handle_mut(), line_number);
self.run_a_classic_script(&script);
// Step 6.
document.set_current_script(old_script.r());
@@ -506,6 +502,24 @@ impl HTMLScriptElement {
}
}
// https://html.spec.whatwg.org/multipage/#run-a-classic-script
pub fn run_a_classic_script(&self, script: &ClassicScript) {
// TODO use a settings object rather than this element's document/window
// Step 2
let document = document_from_node(self);
if !document.is_fully_active() || !document.is_scripting_enabled() {
return;
}
// Steps 4-10
let window = window_from_node(self);
let line_number = if script.external { 1 } else { self.line_number as u32 };
rooted!(in(window.get_cx()) let mut rval = UndefinedValue());
let global = window.upcast::<GlobalScope>();
global.evaluate_script_on_global_with_result(
&script.text, script.url.as_str(), rval.handle_mut(), line_number);
}
pub fn queue_error_event(&self) {
let window = window_from_node(self);
window.dom_manipulation_task_source().queue_simple_event(self.upcast(), atom!("error"), &window);