diff options
Diffstat (limited to 'components/script/script_thread.rs')
-rw-r--r-- | components/script/script_thread.rs | 190 |
1 files changed, 110 insertions, 80 deletions
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index bd65780dc19..16fd866f1b9 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -93,7 +93,7 @@ use canvas_traits::webgl::WebGLPipeline; use crossbeam_channel::{unbounded, Receiver, Sender}; use devtools_traits::CSSError; use devtools_traits::{DevtoolScriptControlMsg, DevtoolsPageInfo}; -use devtools_traits::{ScriptToDevtoolsControlMsg, WorkerId}; +use devtools_traits::{NavigationState, ScriptToDevtoolsControlMsg, WorkerId}; use embedder_traits::{EmbedderMsg, EventLoopWaker}; use euclid::default::{Point2D, Rect}; use euclid::Vector2D; @@ -133,17 +133,15 @@ use script_traits::CompositorEvent::{ CompositionEvent, KeyboardEvent, MouseButtonEvent, MouseMoveEvent, ResizeEvent, TouchEvent, WheelEvent, }; -use script_traits::StructuredSerializedData; -use script_traits::{CompositorEvent, ConstellationControlMsg}; use script_traits::{ - DiscardBrowsingContext, DocumentActivity, EventResult, HistoryEntryReplacement, + CompositorEvent, ConstellationControlMsg, DiscardBrowsingContext, DocumentActivity, + EventResult, HistoryEntryReplacement, InitialScriptState, JsEvalResult, LayoutMsg, LoadData, + LoadOrigin, MediaSessionActionType, MouseButton, MouseEventType, NewLayoutInfo, Painter, + ProgressiveWebMetricType, ScriptMsg, ScriptThreadFactory, ScriptToConstellationChan, + StructuredSerializedData, TimerSchedulerMsg, TouchEventType, TouchId, TransitionEventType, + UntrustedNodeAddress, UpdatePipelineIdReason, WebrenderIpcSender, WheelDelta, WindowSizeData, + WindowSizeType, }; -use script_traits::{InitialScriptState, JsEvalResult, LayoutMsg, LoadData, LoadOrigin}; -use script_traits::{MediaSessionActionType, MouseButton, MouseEventType, NewLayoutInfo}; -use script_traits::{Painter, ProgressiveWebMetricType, ScriptMsg, ScriptThreadFactory}; -use script_traits::{ScriptToConstellationChan, TimerSchedulerMsg}; -use script_traits::{TouchEventType, TouchId, UntrustedNodeAddress, WheelDelta}; -use script_traits::{UpdatePipelineIdReason, WebrenderIpcSender, WindowSizeData, WindowSizeType}; use servo_atoms::Atom; use servo_config::opts; use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl}; @@ -949,6 +947,7 @@ impl ScriptThread { /// Step 13 of https://html.spec.whatwg.org/multipage/#navigate pub fn navigate( + browsing_context: BrowsingContextId, pipeline_id: PipelineId, mut load_data: LoadData, replace: HistoryEntryReplacement, @@ -987,6 +986,12 @@ impl ScriptThread { .queue(task, global.upcast()) .expect("Enqueing navigate js task on the DOM manipulation task source failed"); } else { + if let Some(ref sender) = script_thread.devtools_chan { + let _ = sender.send(ScriptToDevtoolsControlMsg::Navigate( + browsing_context, NavigationState::Start(load_data.url.clone()) + )); + } + script_thread .script_sender .send((pipeline_id, ScriptMsg::LoadUrl(load_data, replace))) @@ -1668,46 +1673,43 @@ impl ScriptThread { fn message_to_pipeline(&self, msg: &MixedMessage) -> Option<PipelineId> { use script_traits::ConstellationControlMsg::*; match *msg { - MixedMessage::FromConstellation(ref inner_msg) => { - match *inner_msg { - StopDelayingLoadEventsMode(id) => Some(id), - NavigationResponse(id, _) => Some(id), - AttachLayout(ref new_layout_info) => Some(new_layout_info.new_pipeline_id), - Resize(id, ..) => Some(id), - ResizeInactive(id, ..) => Some(id), - UnloadDocument(id) => Some(id), - ExitPipeline(id, ..) => Some(id), - ExitScriptThread => None, - SendEvent(id, ..) => Some(id), - Viewport(id, ..) => Some(id), - SetScrollState(id, ..) => Some(id), - GetTitle(id) => Some(id), - SetDocumentActivity(id, ..) => Some(id), - ChangeFrameVisibilityStatus(id, ..) => Some(id), - NotifyVisibilityChange(id, ..) => Some(id), - NavigateIframe(id, ..) => Some(id), - PostMessage { target: id, .. } => Some(id), - UpdatePipelineId(_, _, _, id, _) => Some(id), - UpdateHistoryState(id, ..) => Some(id), - RemoveHistoryStates(id, ..) => Some(id), - FocusIFrame(id, ..) => Some(id), - WebDriverScriptCommand(id, ..) => Some(id), - TickAllAnimations(id) => Some(id), - // FIXME https://github.com/servo/servo/issues/15079 - TransitionEnd(..) => None, - WebFontLoaded(id) => Some(id), - DispatchIFrameLoadEvent { - target: _, - parent: id, - child: _, - } => Some(id), - DispatchStorageEvent(id, ..) => Some(id), - ReportCSSError(id, ..) => Some(id), - Reload(id, ..) => Some(id), - PaintMetric(..) => None, - ExitFullScreen(id, ..) => Some(id), - MediaSessionAction(..) => None, - } + MixedMessage::FromConstellation(ref inner_msg) => match *inner_msg { + StopDelayingLoadEventsMode(id) => Some(id), + NavigationResponse(id, _) => Some(id), + AttachLayout(ref new_layout_info) => Some(new_layout_info.new_pipeline_id), + Resize(id, ..) => Some(id), + ResizeInactive(id, ..) => Some(id), + UnloadDocument(id) => Some(id), + ExitPipeline(id, ..) => Some(id), + ExitScriptThread => None, + SendEvent(id, ..) => Some(id), + Viewport(id, ..) => Some(id), + SetScrollState(id, ..) => Some(id), + GetTitle(id) => Some(id), + SetDocumentActivity(id, ..) => Some(id), + ChangeFrameVisibilityStatus(id, ..) => Some(id), + NotifyVisibilityChange(id, ..) => Some(id), + NavigateIframe(id, ..) => Some(id), + PostMessage { target: id, .. } => Some(id), + UpdatePipelineId(_, _, _, id, _) => Some(id), + UpdateHistoryState(id, ..) => Some(id), + RemoveHistoryStates(id, ..) => Some(id), + FocusIFrame(id, ..) => Some(id), + WebDriverScriptCommand(id, ..) => Some(id), + TickAllAnimations(id) => Some(id), + TransitionEvent { .. } => None, + WebFontLoaded(id) => Some(id), + DispatchIFrameLoadEvent { + target: _, + parent: id, + child: _, + } => Some(id), + DispatchStorageEvent(id, ..) => Some(id), + ReportCSSError(id, ..) => Some(id), + Reload(id, ..) => Some(id), + PaintMetric(..) => None, + ExitFullScreen(id, ..) => Some(id), + MediaSessionAction(..) => None, }, MixedMessage::FromDevtools(_) => None, MixedMessage::FromScript(ref inner_msg) => match *inner_msg { @@ -1896,8 +1898,20 @@ impl ScriptThread { ConstellationControlMsg::TickAllAnimations(pipeline_id) => { self.handle_tick_all_animations(pipeline_id) }, - ConstellationControlMsg::TransitionEnd(unsafe_node, name, duration) => { - self.handle_transition_event(unsafe_node, name, duration) + ConstellationControlMsg::TransitionEvent { + pipeline_id, + event_type, + node, + property_name, + elapsed_time, + } => { + self.handle_transition_event( + pipeline_id, + event_type, + node, + property_name, + elapsed_time, + ); }, ConstellationControlMsg::WebFontLoaded(pipeline_id) => { self.handle_web_font_loaded(pipeline_id) @@ -2899,56 +2913,69 @@ impl ScriptThread { document.run_the_animation_frame_callbacks(); } - /// Handles firing of transition events. + /// Handles firing of transition-related events. + /// + /// TODO(mrobinson): Add support for more events. fn handle_transition_event( &self, + pipeline_id: PipelineId, + event_type: TransitionEventType, unsafe_node: UntrustedNodeAddress, - name: String, - duration: f64, + property_name: String, + elapsed_time: f64, ) { let js_runtime = self.js_runtime.rt(); let node = unsafe { from_untrusted_node_address(js_runtime, unsafe_node) }; - let idx = self + let node_index = self .transitioning_nodes .borrow() .iter() .position(|n| &**n as *const _ == &*node as *const _); - match idx { - Some(idx) => { - self.transitioning_nodes.borrow_mut().remove(idx); - }, + let node_index = match node_index { + Some(node_index) => node_index, None => { // If no index is found, we can't know whether this node is safe to use. // It's better not to fire a DOM event than crash. warn!("Ignoring transition end notification for unknown node."); return; }, - } - - let window = window_from_node(&*node); - - // Not quite the right thing - see #13865. - node.dirty(NodeDamage::NodeStyleDamaged); + }; - if let Some(el) = node.downcast::<Element>() { - if !el.has_css_layout_box() { - return; - } + if self.closed_pipelines.borrow().contains(&pipeline_id) { + warn!("Ignoring transition event for closed pipeline."); + return; } - let init = TransitionEventInit { + let event_atom = match event_type { + TransitionEventType::TransitionRun => atom!("transitionrun"), + TransitionEventType::TransitionEnd => { + // Not quite the right thing - see #13865. + node.dirty(NodeDamage::NodeStyleDamaged); + self.transitioning_nodes.borrow_mut().remove(node_index); + atom!("transitionend") + }, + TransitionEventType::TransitionCancel => { + self.transitioning_nodes.borrow_mut().remove(node_index); + atom!("transitioncancel") + }, + }; + + let event_init = TransitionEventInit { parent: EventInit { bubbles: true, cancelable: false, }, - propertyName: DOMString::from(name), - elapsedTime: Finite::new(duration as f32).unwrap(), - // FIXME: Handle pseudo-elements properly + propertyName: DOMString::from(property_name), + elapsedTime: Finite::new(elapsed_time as f32).unwrap(), + // TODO: Handle pseudo-elements properly pseudoElement: DOMString::new(), }; - let transition_event = TransitionEvent::new(&window, atom!("transitionend"), &init); - transition_event.upcast::<Event>().fire(node.upcast()); + + let window = window_from_node(&*node); + TransitionEvent::new(&window, event_atom, &event_init) + .upcast::<Event>() + .fire(node.upcast()); } /// Handles a Web font being loaded. Does nothing if the page no longer exists. @@ -3321,7 +3348,7 @@ impl ScriptThread { self.notify_devtools( document.Title(), final_url.clone(), - (incomplete.pipeline_id, None), + (incomplete.browsing_context_id, incomplete.pipeline_id, None), ); let parse_input = DOMString::new(); @@ -3352,7 +3379,7 @@ impl ScriptThread { &self, title: DOMString, url: ServoUrl, - ids: (PipelineId, Option<WorkerId>), + (bc, p, w): (BrowsingContextId, PipelineId, Option<WorkerId>), ) { if let Some(ref chan) = self.devtools_chan { let page_info = DevtoolsPageInfo { @@ -3360,11 +3387,14 @@ impl ScriptThread { url: url, }; chan.send(ScriptToDevtoolsControlMsg::NewGlobal( - ids, + (bc, p, w), self.devtools_sender.clone(), - page_info, + page_info.clone(), )) .unwrap(); + + let state = NavigationState::Stop(p, page_info); + let _ = chan.send(ScriptToDevtoolsControlMsg::Navigate(bc, state)); } } |