From dabebdfbf5e502e3eef7cb0159b20f0fa5e74f65 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 7 Apr 2017 06:57:08 +0900 Subject: Root nodes for the duration of their CSS transitions. This ensures that we can pass a node address as part of the asynchronous transition end notification, making it safe to fire the corresponding DOM event on the node from the script thread. Without explicitly rooting this node when the transition starts, we risk the node being GCed before the transition is complete. --- components/layout/animation.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'components/layout/animation.rs') diff --git a/components/layout/animation.rs b/components/layout/animation.rs index be6d5baf77c..ebde01323e5 100644 --- a/components/layout/animation.rs +++ b/components/layout/animation.rs @@ -9,7 +9,9 @@ use flow::{self, Flow}; use gfx::display_list::OpaqueNode; use ipc_channel::ipc::IpcSender; use msg::constellation_msg::PipelineId; +use opaque_node::OpaqueNodeMethods; use script_traits::{AnimationState, ConstellationControlMsg, LayoutMsg as ConstellationMsg}; +use script_traits::UntrustedNodeAddress; use std::collections::HashMap; use std::sync::mpsc::Receiver; use style::animation::{Animation, update_style_for_animation}; @@ -24,6 +26,7 @@ pub fn update_animation_state(constellation_chan: &IpcSender, script_chan: &IpcSender, running_animations: &mut HashMap>, expired_animations: &mut HashMap>, + newly_transitioning_nodes: &mut Vec, new_animations_receiver: &Receiver, pipeline_id: PipelineId, timer: &Timer) { @@ -71,7 +74,7 @@ pub fn update_animation_state(constellation_chan: &IpcSender, let mut animations_still_running = vec![]; for mut running_animation in running_animations.drain(..) { let still_running = !running_animation.is_expired() && match running_animation { - Animation::Transition(_, _, started_at, ref frame, _expired) => { + Animation::Transition(_, started_at, ref frame, _expired) => { now < started_at + frame.duration } Animation::Keyframes(_, _, ref mut state) => { @@ -86,8 +89,8 @@ pub fn update_animation_state(constellation_chan: &IpcSender, continue } - if let Animation::Transition(_, unsafe_node, _, ref frame, _) = running_animation { - script_chan.send(ConstellationControlMsg::TransitionEnd(unsafe_node, + if let Animation::Transition(node, _, ref frame, _) = running_animation { + script_chan.send(ConstellationControlMsg::TransitionEnd(node.to_untrusted_node_address(), frame.property_animation .property_name().into(), frame.duration)) @@ -112,6 +115,10 @@ pub fn update_animation_state(constellation_chan: &IpcSender, // Add new running animations. for new_running_animation in new_running_animations { + if new_running_animation.is_transition() { + newly_transitioning_nodes.push(new_running_animation.node().to_untrusted_node_address()); + } + running_animations.entry(*new_running_animation.node()) .or_insert_with(Vec::new) .push(new_running_animation) -- cgit v1.2.3 From c3b9714ab79a8230162605236f7c2f5e247707a7 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Mon, 10 Apr 2017 17:02:25 +1000 Subject: Accumulate transitioning nodes inside the layout context. --- components/layout/animation.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'components/layout/animation.rs') diff --git a/components/layout/animation.rs b/components/layout/animation.rs index ebde01323e5..9b1d0671b9a 100644 --- a/components/layout/animation.rs +++ b/components/layout/animation.rs @@ -26,7 +26,7 @@ pub fn update_animation_state(constellation_chan: &IpcSender, script_chan: &IpcSender, running_animations: &mut HashMap>, expired_animations: &mut HashMap>, - newly_transitioning_nodes: &mut Vec, + mut newly_transitioning_nodes: Option<&mut Vec>, new_animations_receiver: &Receiver, pipeline_id: PipelineId, timer: &Timer) { @@ -115,8 +115,11 @@ pub fn update_animation_state(constellation_chan: &IpcSender, // Add new running animations. for new_running_animation in new_running_animations { - if new_running_animation.is_transition() { - newly_transitioning_nodes.push(new_running_animation.node().to_untrusted_node_address()); + match newly_transitioning_nodes { + Some(ref mut nodes) if new_running_animation.is_transition() => { + nodes.push(new_running_animation.node().to_untrusted_node_address()); + } + _ => () } running_animations.entry(*new_running_animation.node()) -- cgit v1.2.3 From 2ca80a800f8c1f85135bbdb605f69641ae9aa7d0 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Mon, 10 Apr 2017 17:53:46 +1000 Subject: Warn about ignored transitions which can't be rooted. --- components/layout/animation.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'components/layout/animation.rs') diff --git a/components/layout/animation.rs b/components/layout/animation.rs index 9b1d0671b9a..d1673ac44a1 100644 --- a/components/layout/animation.rs +++ b/components/layout/animation.rs @@ -115,11 +115,15 @@ pub fn update_animation_state(constellation_chan: &IpcSender, // Add new running animations. for new_running_animation in new_running_animations { - match newly_transitioning_nodes { - Some(ref mut nodes) if new_running_animation.is_transition() => { - nodes.push(new_running_animation.node().to_untrusted_node_address()); + if new_running_animation.is_transition() { + match newly_transitioning_nodes { + Some(ref mut nodes) => { + nodes.push(new_running_animation.node().to_untrusted_node_address()); + } + None => { + warn!("New transition encountered from compositor-initiated layout."); + } } - _ => () } running_animations.entry(*new_running_animation.node()) -- cgit v1.2.3