diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 43a4473689ec..cd411fa366fd 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -1475,7 +1475,7 @@ impl Document { update_with_current_time_ms(&self.dom_content_loaded_event_start); self.window().dom_manipulation_task_source().queue_event(self.upcast(), atom!("DOMContentLoaded"), - EventBubbles::Bubbles, EventCancelable::NotCancelable); + EventBubbles::Bubbles, EventCancelable::NotCancelable, Some(self.window().get_runnable_wrapper())); self.window().reflow(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery, ReflowReason::DOMContentLoaded); diff --git a/components/script/dom/event.rs b/components/script/dom/event.rs index 9174fa2cb3d5..f7d8a9e9e628 100644 --- a/components/script/dom/event.rs +++ b/components/script/dom/event.rs @@ -26,7 +26,7 @@ pub enum EventPhase { Bubbling = EventConstants::BUBBLING_PHASE, } -#[derive(PartialEq, HeapSizeOf)] +#[derive(PartialEq, HeapSizeOf, Clone, Copy)] pub enum EventBubbles { Bubbles, DoesNotBubble @@ -50,7 +50,7 @@ impl From for EventBubbles { } } -#[derive(PartialEq, HeapSizeOf)] +#[derive(PartialEq, HeapSizeOf, Clone, Copy)] pub enum EventCancelable { Cancelable, NotCancelable diff --git a/components/script/dom/htmldetailselement.rs b/components/script/dom/htmldetailselement.rs index 07c85ed6e2ea..ebc762b61e91 100644 --- a/components/script/dom/htmldetailselement.rs +++ b/components/script/dom/htmldetailselement.rs @@ -79,7 +79,7 @@ impl VirtualMethods for HTMLDetailsElement { element: details, toggle_number: counter }; - let _ = task_source.queue(DOMManipulationTask::Runnable(runnable)); + let _ = task_source.queue(DOMManipulationTask(runnable)); } } } diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index 90baba4ebb1a..baca32f38f8f 100644 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -484,7 +484,7 @@ impl HTMLFormElement { }; // Step 3 - window.dom_manipulation_task_source().queue(DOMManipulationTask::Runnable(nav)).unwrap(); + window.dom_manipulation_task_source().queue(DOMManipulationTask(nav)).unwrap(); } /// Interactively validate the constraints of form elements diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 27152ca93f4c..e96d5ec2161c 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -183,7 +183,7 @@ impl HTMLImageElement { src: src.into(), }); let task = window.dom_manipulation_task_source(); - let _ = task.queue(DOMManipulationTask::Runnable(runnable)); + let _ = task.queue(DOMManipulationTask(runnable)); } } } diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 7cfe19ba7897..2a7f78c5e7cf 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -242,7 +242,7 @@ impl HTMLMediaElement { elem: Trusted::new(self), }; let win = window_from_node(self); - let _ = win.dom_manipulation_task_source().queue(DOMManipulationTask::Runnable(box task)); + let _ = win.dom_manipulation_task_source().queue(DOMManipulationTask(box task)); } // https://html.spec.whatwg.org/multipage/#internal-pause-steps step 2.2 @@ -266,13 +266,13 @@ impl HTMLMediaElement { elem: Trusted::new(self), }; let win = window_from_node(self); - let _ = win.dom_manipulation_task_source().queue(DOMManipulationTask::Runnable(box task)); + let _ = win.dom_manipulation_task_source().queue(DOMManipulationTask(box task)); } fn queue_fire_simple_event(&self, type_: &'static str) { let win = window_from_node(self); let task = FireSimpleEventTask::new(self, type_); - let _ = win.dom_manipulation_task_source().queue(DOMManipulationTask::Runnable(box task)); + let _ = win.dom_manipulation_task_source().queue(DOMManipulationTask(box task)); } fn fire_simple_event(&self, type_: &str) { @@ -497,7 +497,7 @@ impl HTMLMediaElement { fn queue_dedicated_media_source_failure_steps(&self) { let _ = window_from_node(self).dom_manipulation_task_source().queue( - DOMManipulationTask::Runnable(box DedicatedMediaSourceFailureTask::new(self))); + DOMManipulationTask(box DedicatedMediaSourceFailureTask::new(self))); } // https://html.spec.whatwg.org/multipage/#dedicated-media-source-failure-steps diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index e4ce7fb068f3..669f0d984a21 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -459,12 +459,15 @@ impl HTMLScriptElement { if external { self.dispatch_load_event(); } else { - window.dom_manipulation_task_source().queue_simple_event(self.upcast(), atom!("load")); + window.dom_manipulation_task_source().queue_simple_event(self.upcast(), atom!("load"), + Some(window.get_runnable_wrapper())); } } pub fn queue_error_event(&self) { - window_from_node(self).dom_manipulation_task_source().queue_simple_event(self.upcast(), atom!("error")); + let window = window_from_node(self); + window.dom_manipulation_task_source().queue_simple_event(self.upcast(), atom!("error"), + Some(window.get_runnable_wrapper())); } pub fn dispatch_before_script_execute_event(&self) -> bool { diff --git a/components/script/dom/storage.rs b/components/script/dom/storage.rs index d927c5ba2130..d44f96840274 100644 --- a/components/script/dom/storage.rs +++ b/components/script/dom/storage.rs @@ -161,7 +161,7 @@ impl Storage { let global_ref = global_root.r(); let task_source = global_ref.as_window().dom_manipulation_task_source(); let trusted_storage = Trusted::new(self); - task_source.queue(DOMManipulationTask::Runnable( + task_source.queue(DOMManipulationTask( box StorageEventRunnable::new(trusted_storage, key, old_value, new_value))).unwrap(); } } diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 8a7fc82f52ef..2a98fc56b7d5 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -1221,7 +1221,7 @@ impl ScriptThread { // https://html.spec.whatwg.org/multipage/#the-end step 7 let handler = box DocumentProgressHandler::new(Trusted::new(doc)); - self.dom_manipulation_task_source.queue(DOMManipulationTask::Runnable(handler)).unwrap(); + self.dom_manipulation_task_source.queue(DOMManipulationTask(handler)).unwrap(); self.constellation_chan.send(ConstellationMsg::LoadComplete(pipeline)).unwrap(); } diff --git a/components/script/task_source/dom_manipulation.rs b/components/script/task_source/dom_manipulation.rs index a1c06f2c09ee..eaee2b90af07 100644 --- a/components/script/task_source/dom_manipulation.rs +++ b/components/script/task_source/dom_manipulation.rs @@ -5,7 +5,7 @@ use dom::bindings::refcounted::Trusted; use dom::event::{EventBubbles, EventCancelable}; use dom::eventtarget::EventTarget; -use script_thread::{MainThreadScriptMsg, Runnable, ScriptThread}; +use script_thread::{MainThreadScriptMsg, Runnable, RunnableWrapper, ScriptThread}; use std::result::Result; use std::sync::mpsc::Sender; use string_cache::Atom; @@ -25,46 +25,86 @@ impl DOMManipulationTaskSource { target: &EventTarget, name: Atom, bubbles: EventBubbles, - cancelable: EventCancelable) { + cancelable: EventCancelable, + wrapper: Option) { let target = Trusted::new(target); - let _ = self.0.send(MainThreadScriptMsg::DOMManipulation(DOMManipulationTask::FireEvent( - target, name, bubbles, cancelable))); + let runnable = match wrapper { + Some(wrapper) => { + wrapper.wrap_runnable(EventRunnable { + target: target, + name: name, + bubbles: bubbles, + cancelable: cancelable, + }) + }, + None => { + box EventRunnable { + target: target, + name: name, + bubbles: bubbles, + cancelable: cancelable, + } + } + }; + let _ = self.0.send(MainThreadScriptMsg::DOMManipulation(DOMManipulationTask(runnable))); } - pub fn queue_simple_event(&self, target: &EventTarget, name: Atom) { + pub fn queue_simple_event(&self, target: &EventTarget, name: Atom, wrapper: Option) { let target = Trusted::new(target); - let _ = self.0.send(MainThreadScriptMsg::DOMManipulation(DOMManipulationTask::FireSimpleEvent( - target, name))); + let runnable = match wrapper { + Some(wrapper) => { + wrapper.wrap_runnable(SimpleEventRunnable { + target: target, + name: name, + }) + }, + None => { + box SimpleEventRunnable { + target: target, + name: name, + } + } + }; + let _ = self.0.send(MainThreadScriptMsg::DOMManipulation(DOMManipulationTask(runnable))); } } -pub enum DOMManipulationTask { - // https://dom.spec.whatwg.org/#concept-event-fire - FireEvent(Trusted, Atom, EventBubbles, EventCancelable), - // https://html.spec.whatwg.org/multipage/#fire-a-simple-event - FireSimpleEvent(Trusted, Atom), +struct EventRunnable { + target: Trusted, + name: Atom, + bubbles: EventBubbles, + cancelable: EventCancelable, +} + +impl Runnable for EventRunnable { + fn name(&self) -> &'static str { "EventRunnable" } - Runnable(Box), + fn handler(self: Box) { + let target = self.target.root(); + target.fire_event(&*self.name, self.bubbles, self.cancelable); + } } +struct SimpleEventRunnable { + target: Trusted, + name: Atom, +} + +impl Runnable for SimpleEventRunnable { + fn name(&self) -> &'static str { "SimpleEventRunnable" } + + fn handler(self: Box) { + let target = self.target.root(); + target.fire_simple_event(&*self.name); + } +} + +pub struct DOMManipulationTask(pub Box); + impl DOMManipulationTask { pub fn handle_task(self, script_thread: &ScriptThread) { - use self::DOMManipulationTask::*; - - match self { - FireEvent(element, name, bubbles, cancelable) => { - let target = element.root(); - target.fire_event(&*name, bubbles, cancelable); - } - FireSimpleEvent(element, name) => { - let target = element.root(); - target.fire_simple_event(&*name); - } - Runnable(runnable) => { - if !runnable.is_cancelled() { - runnable.main_thread_handler(script_thread); - } - } + if !self.0.is_cancelled() { + self.0.main_thread_handler(script_thread); } } } diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/change_parentage.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/change_parentage.html.ini deleted file mode 100644 index 5c3ee2555e47..000000000000 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/change_parentage.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[change_parentage.html] - type: testharness - disabled: https://github.com/servo/servo/issues/11703