aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/script_thread.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/script_thread.rs')
-rw-r--r--components/script/script_thread.rs190
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));
}
}