From 6e06a1353c16c285610ff4bf44380c9a9d9ab76f Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Wed, 5 Nov 2014 16:50:13 -0800 Subject: [PATCH 1/4] Rename LoadIframeUrlMsg to CreateIFrameAndLoadUrlMsg This better reflects what the message does. --- components/compositing/constellation.rs | 38 ++++++++++++---------- components/msg/constellation_msg.rs | 2 +- components/script/dom/htmliframeelement.rs | 4 +-- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/components/compositing/constellation.rs b/components/compositing/constellation.rs index 7a7204dfdaf..513433ed780 100644 --- a/components/compositing/constellation.rs +++ b/components/compositing/constellation.rs @@ -18,9 +18,9 @@ use script_traits::{ScriptControlChan, ScriptTaskFactory}; use servo_msg::compositor_msg::LayerId; use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, FailureMsg, Failure, FrameRectMsg}; use servo_msg::constellation_msg::{IFrameSandboxState, IFrameUnsandboxed, InitLoadUrlMsg}; -use servo_msg::constellation_msg::{LoadCompleteMsg, LoadIframeUrlMsg, LoadUrlMsg, Msg}; -use servo_msg::constellation_msg::{LoadData, NavigateMsg, NavigationType, PipelineId}; -use servo_msg::constellation_msg::{RendererReadyMsg, ResizedWindowMsg, SubpageId, WindowSizeData}; +use servo_msg::constellation_msg::{LoadCompleteMsg, LoadUrlMsg, LoadData, Msg, NavigateMsg}; +use servo_msg::constellation_msg::{NavigationType, PipelineId, RendererReadyMsg, ResizedWindowMsg}; +use servo_msg::constellation_msg::{ScriptLoadedURLInIFrameMsg, SubpageId, WindowSizeData}; use servo_msg::constellation_msg; use servo_net::image_cache_task::{ImageCacheTask, ImageCacheTaskClient}; use servo_net::resource_task::ResourceTask; @@ -382,9 +382,12 @@ impl Constellation { debug!("constellation got frame rect message"); self.handle_frame_rect_msg(pipeline_id, subpage_id, Rect::from_untyped(&rect)); } - LoadIframeUrlMsg(url, source_pipeline_id, subpage_id, sandbox) => { + ScriptLoadedURLInIFrameMsg(url, source_pipeline_id, subpage_id, sandbox) => { debug!("constellation got iframe URL load message"); - self.handle_load_iframe_url_msg(url, source_pipeline_id, subpage_id, sandbox); + self.handle_script_loaded_url_in_iframe_msg(url, + source_pipeline_id, + subpage_id, + sandbox); } // Load a new page, usually -- but not always -- from a mouse click or typed url // If there is already a pending page (self.pending_frames), it will not be overridden; @@ -593,21 +596,20 @@ impl Constellation { } - fn handle_load_iframe_url_msg(&mut self, - url: Url, - source_pipeline_id: PipelineId, - subpage_id: SubpageId, - sandbox: IFrameSandboxState) { - // A message from the script associated with pipeline_id that it has - // parsed an iframe during html parsing. This iframe will result in a - // new pipeline being spawned and a frame tree being added to pipeline_id's - // frame tree's children. This message is never the result of a link clicked - // or a new url entered. - // Start by finding the frame trees matching the pipeline id, + // The script task associated with pipeline_id has loaded a URL in an iframe via script. This + // will result in a new pipeline being spawned and a frame tree being added to + // source_pipeline_id's frame tree's children. This message is never the result of a page + // navigation. + fn handle_script_loaded_url_in_iframe_msg(&mut self, + url: Url, + source_pipeline_id: PipelineId, + subpage_id: SubpageId, + sandbox: IFrameSandboxState) { + // Start by finding the frame trees matching the pipeline id, // and add the new pipeline to their sub frames. let frame_trees = self.find_all(source_pipeline_id); if frame_trees.is_empty() { - fail!("Constellation: source pipeline id of LoadIframeUrlMsg is not in + fail!("Constellation: source pipeline id of ScriptLoadedURLInIFrameMsg is not in navigation context, nor is it in a pending frame. This should be impossible."); } @@ -617,7 +619,7 @@ impl Constellation { // Compare the pipeline's url to the new url. If the origin is the same, // then reuse the script task in creating the new pipeline let source_pipeline = self.pipelines.find(&source_pipeline_id).expect("Constellation: - source Id of LoadIframeUrlMsg does have an associated pipeline in + source Id of ScriptLoadedURLInIFrameMsg does have an associated pipeline in constellation. This should be impossible.").clone(); let source_url = source_pipeline.load_data.url.clone(); diff --git a/components/msg/constellation_msg.rs b/components/msg/constellation_msg.rs index 00357752ee1..fbdb437327c 100644 --- a/components/msg/constellation_msg.rs +++ b/components/msg/constellation_msg.rs @@ -58,7 +58,7 @@ pub enum Msg { LoadCompleteMsg(PipelineId, Url), FrameRectMsg(PipelineId, SubpageId, Rect), LoadUrlMsg(PipelineId, LoadData), - LoadIframeUrlMsg(Url, PipelineId, SubpageId, IFrameSandboxState), + ScriptLoadedURLInIFrameMsg(Url, PipelineId, SubpageId, IFrameSandboxState), NavigateMsg(NavigationDirection), RendererReadyMsg(PipelineId), ResizedWindowMsg(WindowSizeData), diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 737f3340ecf..902ee4ee6ea 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -23,7 +23,7 @@ use page::IterablePage; use servo_msg::constellation_msg::{PipelineId, SubpageId}; use servo_msg::constellation_msg::{IFrameSandboxed, IFrameUnsandboxed}; -use servo_msg::constellation_msg::{ConstellationChan, LoadIframeUrlMsg}; +use servo_msg::constellation_msg::{ConstellationChan, ScriptLoadedURLInIFrameMsg}; use servo_util::str::DOMString; use std::ascii::StrAsciiExt; @@ -125,7 +125,7 @@ impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> { // https://github.com/servo/servo/issues/3738 // We can't handle dynamic frame tree changes in the compositor right now. let ConstellationChan(ref chan) = page.constellation_chan; - chan.send(LoadIframeUrlMsg(url, page.id, subpage_id, sandboxed)); + chan.send(ScriptLoadedURLInIFrameMsg(url, page.id, subpage_id, sandboxed)); } } } From a10e261ffd81512f26a7b8efdde9398b2d319130 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Wed, 5 Nov 2014 17:00:06 -0800 Subject: [PATCH 2/4] Small fix to variable name This is a more accurate name for the script pipeline. --- components/compositing/constellation.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/compositing/constellation.rs b/components/compositing/constellation.rs index 513433ed780..20d3196ee3f 100644 --- a/components/compositing/constellation.rs +++ b/components/compositing/constellation.rs @@ -628,7 +628,7 @@ impl Constellation { source_url.port() == url.port()) && sandbox == IFrameUnsandboxed; // FIXME(tkuehn): Need to follow the standardized spec for checking same-origin // Reuse the script task if the URL is same-origin - let new_pipeline = if same_script { + let script_pipeline = if same_script { debug!("Constellation: loading same-origin iframe at {:?}", url); Some(source_pipeline.clone()) } else { @@ -639,7 +639,7 @@ impl Constellation { let pipeline = self.new_pipeline( next_pipeline_id, Some(subpage_id), - new_pipeline, + script_pipeline, LoadData::new(url) ); From 750bedab810f4b2fe8fc9c47798e120c997a4234 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Wed, 5 Nov 2014 17:42:17 -0800 Subject: [PATCH 3/4] Add some factory methods for frame tree types --- components/compositing/constellation.rs | 59 +++++++++++++------------ 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/components/compositing/constellation.rs b/components/compositing/constellation.rs index 20d3196ee3f..2360315f6a3 100644 --- a/components/compositing/constellation.rs +++ b/components/compositing/constellation.rs @@ -85,6 +85,19 @@ struct FrameTree { pub children: RefCell>, } +impl FrameTree { + fn new(pipeline: Rc, parent_pipeline: Option>) -> FrameTree { + FrameTree { + pipeline: pipeline.clone(), + parent: match parent_pipeline { + Some(ref pipeline) => RefCell::new(Some(pipeline.clone())), + None => RefCell::new(None), + }, + children: RefCell::new(vec!()), + } + } +} + #[deriving(Clone)] struct ChildFrameTree { frame_tree: Rc, @@ -93,6 +106,15 @@ struct ChildFrameTree { pub rect: Option>, } +impl ChildFrameTree { + fn new(frame_tree: Rc, rect: Option>) -> ChildFrameTree { + ChildFrameTree { + frame_tree: frame_tree, + rect: rect, + } + } +} + pub struct SendableFrameTree { pub pipeline: CompositionPipeline, pub children: Vec, @@ -481,11 +503,7 @@ impl Constellation { self.pending_frames.push(FrameChange{ before: Some(pipeline_id), - after: Rc::new(FrameTree { - pipeline: pipeline.clone(), - parent: RefCell::new(None), - children: RefCell::new(vec!()), - }), + after: Rc::new(FrameTree::new(pipeline.clone(), None)), navigation_type: constellation_msg::Load, }); @@ -498,11 +516,7 @@ impl Constellation { self.pending_frames.push(FrameChange { before: None, - after: Rc::new(FrameTree { - pipeline: pipeline.clone(), - parent: RefCell::new(None), - children: RefCell::new(vec!()), - }), + after: Rc::new(FrameTree::new(pipeline.clone(), None)), navigation_type: constellation_msg::Load, }); self.pipelines.insert(pipeline.id, pipeline); @@ -645,14 +659,9 @@ impl Constellation { let rect = self.pending_sizes.pop(&(source_pipeline_id, subpage_id)); for frame_tree in frame_trees.iter() { - frame_tree.children.borrow_mut().push(ChildFrameTree { - frame_tree: Rc::new(FrameTree { - pipeline: pipeline.clone(), - parent: RefCell::new(Some(source_pipeline.clone())), - children: RefCell::new(vec!()), - }), - rect: rect, - }); + frame_tree.children.borrow_mut().push(ChildFrameTree::new( + Rc::new(FrameTree::new(pipeline.clone(), Some(source_pipeline.clone()))), + rect)); } self.pipelines.insert(pipeline.id, pipeline); } @@ -686,13 +695,9 @@ impl Constellation { let pipeline = self.new_pipeline(next_pipeline_id, subpage_id, None, load_data); - self.pending_frames.push(FrameChange{ + self.pending_frames.push(FrameChange { before: Some(source_id), - after: Rc::new(FrameTree { - pipeline: pipeline.clone(), - parent: parent, - children: RefCell::new(vec!()), - }), + after: Rc::new(FrameTree::new(pipeline.clone(), parent.borrow().clone())), navigation_type: constellation_msg::Load, }); self.pipelines.insert(pipeline.id, pipeline); @@ -816,10 +821,8 @@ impl Constellation { let parent = next_frame_tree.find(parent.id).expect( "Constellation: pending frame has a parent frame that is not active. This is a bug."); - parent.children.borrow_mut().push(ChildFrameTree { - frame_tree: to_add.clone(), - rect: rect, - }); + parent.children.borrow_mut().push(ChildFrameTree::new(to_add.clone(), + rect)); } } } From fbb1e0c6b848303be79d2f30ce6257d70a8e38da Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Mon, 10 Nov 2014 11:34:44 -0800 Subject: [PATCH 4/4] Send incremental frame tree updates to the compositor This allows the compositor to add frames after the call to SetIds, where the initial frame tree is created. There are still some issues preventing proper late frame creation, but this prevents crashes when it happens. Fixes #3738. --- components/compositing/compositor.rs | 46 +++++++++-- components/compositing/compositor_task.rs | 5 +- components/compositing/constellation.rs | 89 +++++++++++++++++++--- components/compositing/headless.rs | 6 +- components/script/dom/htmliframeelement.rs | 12 +-- 5 files changed, 130 insertions(+), 28 deletions(-) diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index eb0301e9208..50a47af45a4 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -4,12 +4,13 @@ use compositor_layer::{CompositorData, CompositorLayer, DoesntWantScrollEvents}; use compositor_layer::{ScrollPositionChanged, WantsScrollEvents}; -use compositor_task::{Msg, CompositorTask, Exit, ChangeReadyState, SetIds, LayerProperties}; -use compositor_task::{GetGraphicsMetadata, CreateOrUpdateRootLayer, CreateOrUpdateDescendantLayer}; -use compositor_task::{SetLayerOrigin, Paint, ScrollFragmentPoint, LoadComplete}; -use compositor_task::{ShutdownComplete, ChangeRenderState, RenderMsgDiscarded, ScrollTimeout}; -use compositor_task::{CompositorEventListener, CompositorProxy, CompositorReceiver}; -use constellation::SendableFrameTree; +use compositor_task::{ChangeReadyState, ChangeRenderState, CompositorEventListener}; +use compositor_task::{CompositorProxy, CompositorReceiver, CompositorTask}; +use compositor_task::{CreateOrUpdateDescendantLayer, CreateOrUpdateRootLayer, Exit}; +use compositor_task::{FrameTreeUpdateMsg, GetGraphicsMetadata, LayerProperties}; +use compositor_task::{LoadComplete, Msg, Paint, RenderMsgDiscarded, ScrollFragmentPoint}; +use compositor_task::{ScrollTimeout, SetIds, SetLayerOrigin, ShutdownComplete}; +use constellation::{SendableFrameTree, FrameTreeDiff}; use pipeline::CompositionPipeline; use scrolling::ScrollingTimerProxy; use windowing; @@ -267,6 +268,11 @@ impl IOCompositor { new_constellation_chan); } + (FrameTreeUpdateMsg(frame_tree_diff, response_channel), NotShuttingDown) => { + self.update_frame_tree(&frame_tree_diff); + response_channel.send(()); + } + (CreateOrUpdateRootLayer(layer_properties), NotShuttingDown) => { self.create_or_update_root_layer(layer_properties); } @@ -446,6 +452,34 @@ impl IOCompositor { return root_layer; } + fn update_frame_tree(&mut self, frame_tree_diff: &FrameTreeDiff) { + let layer_properties = LayerProperties { + pipeline_id: frame_tree_diff.pipeline.id, + epoch: Epoch(0), + id: LayerId::null(), + rect: Rect::zero(), + background_color: azure_hl::Color::new(0., 0., 0., 0.), + scroll_policy: Scrollable, + }; + let root_layer = CompositorData::new_layer(frame_tree_diff.pipeline.clone(), + layer_properties, + WantsScrollEvents, + opts::get().tile_size); + + match frame_tree_diff.rect { + Some(ref frame_rect) => { + *root_layer.masks_to_bounds.borrow_mut() = true; + + let frame_rect = frame_rect.to_untyped(); + *root_layer.bounds.borrow_mut() = Rect::from_untyped(&frame_rect); + } + None => {} + } + + let parent_layer = self.find_pipeline_root_layer(frame_tree_diff.parent_pipeline.id); + parent_layer.add_child(root_layer); + } + fn find_pipeline_root_layer(&self, pipeline_id: PipelineId) -> Rc> { match self.find_layer_with_pipeline_and_layer_id(pipeline_id, LayerId::null()) { Some(ref layer) => layer.clone(), diff --git a/components/compositing/compositor_task.rs b/components/compositing/compositor_task.rs index 5fe2c4bb57a..cfbb5acb2a6 100644 --- a/components/compositing/compositor_task.rs +++ b/components/compositing/compositor_task.rs @@ -5,7 +5,7 @@ //! Communication with the compositor task. pub use windowing; -pub use constellation::SendableFrameTree; +pub use constellation::{SendableFrameTree, FrameTreeDiff}; use compositor; use headless; @@ -189,6 +189,8 @@ pub enum Msg { RenderMsgDiscarded, /// Sets the channel to the current layout and render tasks, along with their id SetIds(SendableFrameTree, Sender<()>, ConstellationChan), + /// Sends an updated version of the frame tree. + FrameTreeUpdateMsg(FrameTreeDiff, Sender<()>), /// The load of a page for a given URL has completed. LoadComplete(PipelineId, Url), /// Indicates that the scrolling timeout with the given starting timestamp has happened and a @@ -211,6 +213,7 @@ impl Show for Msg { ChangeRenderState(..) => write!(f, "ChangeRenderState"), RenderMsgDiscarded(..) => write!(f, "RenderMsgDiscarded"), SetIds(..) => write!(f, "SetIds"), + FrameTreeUpdateMsg(..) => write!(f, "FrameTreeUpdateMsg"), LoadComplete(..) => write!(f, "LoadComplete"), ScrollTimeout(..) => write!(f, "ScrollTimeout"), } diff --git a/components/compositing/constellation.rs b/components/compositing/constellation.rs index 2360315f6a3..7bbf1ebb5fb 100644 --- a/components/compositing/constellation.rs +++ b/components/compositing/constellation.rs @@ -4,7 +4,7 @@ use pipeline::{Pipeline, CompositionPipeline}; -use compositor_task::{CompositorProxy, LoadComplete, ShutdownComplete, SetLayerOrigin, SetIds}; +use compositor_task::{CompositorProxy, FrameTreeUpdateMsg, LoadComplete, ShutdownComplete, SetLayerOrigin, SetIds}; use devtools_traits::DevtoolsControlChan; use geom::rect::{Rect, TypedRect}; use geom::scale_factor::ScaleFactor; @@ -29,7 +29,7 @@ use servo_util::geometry::{PagePx, ViewportPx}; use servo_util::opts; use servo_util::task::spawn_named; use servo_util::time::TimeProfilerChan; -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; use std::collections::hashmap::{HashMap, HashSet}; use std::io; use std::mem::replace; @@ -83,6 +83,7 @@ struct FrameTree { pub pipeline: Rc, pub parent: RefCell>>, pub children: RefCell>, + pub has_compositor_layer: Cell, } impl FrameTree { @@ -94,6 +95,7 @@ impl FrameTree { None => RefCell::new(None), }, children: RefCell::new(vec!()), + has_compositor_layer: Cell::new(false), } } } @@ -130,6 +132,16 @@ enum ReplaceResult { OriginalNode(Rc), } +/// A struct that triggers the addition of a new frame to a previously existing frame tree. +pub struct FrameTreeDiff { + /// The parent pipeline of the new frame. + pub parent_pipeline: CompositionPipeline, + /// The pipeline of the new frame itself. + pub pipeline: CompositionPipeline, + /// The frame rect of the new frame used for positioning its compositor layer. + pub rect: Option>, +} + impl FrameTree { fn to_sendable(&self) -> SendableFrameTree { let sendable_frame_tree = SendableFrameTree { @@ -744,21 +756,22 @@ impl Constellation { } + fn pipeline_is_in_current_frame(&self, pipeline_id: PipelineId) -> bool { + self.current_frame().iter() + .any(|current_frame| current_frame.contains(pipeline_id)) + } + fn handle_renderer_ready_msg(&mut self, pipeline_id: PipelineId) { debug!("Renderer {:?} ready to send paint msg", pipeline_id); // This message could originate from a pipeline in the navigation context or // from a pending frame. The only time that we will grant paint permission is // when the message originates from a pending frame or the current frame. - for current_frame in self.current_frame().iter() { - // Messages originating in the current frame are not navigations; - // they may come from a page load in a subframe. - if current_frame.contains(pipeline_id) { - for frame in current_frame.iter() { - frame.pipeline.grant_paint_permission(); - } - return; - } + // Messages originating in the current frame are not navigations; + // they may come from a page load in a subframe. + if self.pipeline_is_in_current_frame(pipeline_id) { + self.create_compositor_layer_for_iframe_if_necessary(pipeline_id); + return; } // Find the pending frame change whose new pipeline id is pipeline_id. @@ -916,11 +929,65 @@ impl Constellation { Ok(()) => { let mut iter = frame_tree.iter(); for frame in iter { + frame.has_compositor_layer.set(true); frame.pipeline.grant_paint_permission(); } } Err(()) => {} // message has been discarded, probably shutting down } } + + fn find_child_parent_pair_in_frame_tree(&self, + frame_tree: Rc, + child_pipeline_id: PipelineId) + -> Option<(ChildFrameTree, Rc)> { + for child in frame_tree.children.borrow().iter() { + let child_frame_tree = child.frame_tree.clone(); + if child.frame_tree.pipeline.id == child_pipeline_id { + return Some((ChildFrameTree::new(child_frame_tree, child.rect), + frame_tree.clone())); + } + let result = self.find_child_parent_pair_in_frame_tree(child_frame_tree, + child_pipeline_id); + if result.is_some() { + return result; + } + } + None + } + + fn create_compositor_layer_for_iframe_if_necessary(&mut self, pipeline_id: PipelineId) { + let current_frame_tree = match self.current_frame() { + &Some(ref tree) => tree.clone(), + &None => return, + }; + + let (child, parent) = + match self.find_child_parent_pair_in_frame_tree(current_frame_tree, pipeline_id) { + Some(pair) => pair, + None => return, + }; + + if child.frame_tree.has_compositor_layer.get() { + child.frame_tree.pipeline.grant_paint_permission(); + return; + } + + let sendable_frame_tree_diff = FrameTreeDiff { + parent_pipeline: parent.pipeline.to_sendable(), + pipeline: child.frame_tree.pipeline.to_sendable(), + rect: child.rect, + }; + + let (chan, port) = channel(); + self.compositor_proxy.send(FrameTreeUpdateMsg(sendable_frame_tree_diff, chan)); + match port.recv_opt() { + Ok(()) => { + child.frame_tree.has_compositor_layer.set(true); + child.frame_tree.pipeline.grant_paint_permission(); + } + Err(()) => {} // The message has been discarded, we are probably shutting down. + } + } } diff --git a/components/compositing/headless.rs b/components/compositing/headless.rs index 648b71034e0..eaeb09eb7da 100644 --- a/components/compositing/headless.rs +++ b/components/compositing/headless.rs @@ -5,7 +5,7 @@ use compositor_task::{GetGraphicsMetadata, CreateOrUpdateRootLayer, CreateOrUpdateDescendantLayer}; use compositor_task::{Exit, ChangeReadyState, LoadComplete, Paint, ScrollFragmentPoint, SetIds}; use compositor_task::{SetLayerOrigin, ShutdownComplete, ChangeRenderState, RenderMsgDiscarded}; -use compositor_task::{CompositorEventListener, CompositorReceiver, ScrollTimeout}; +use compositor_task::{CompositorEventListener, CompositorReceiver, ScrollTimeout, FrameTreeUpdateMsg}; use windowing::WindowEvent; use geom::scale_factor::ScaleFactor; @@ -92,6 +92,10 @@ impl CompositorEventListener for NullCompositor { response_chan.send(()); } + FrameTreeUpdateMsg(_, response_channel) => { + response_channel.send(()); + } + // Explicitly list ignored messages so that when we add a new one, // we'll notice and think about whether it needs a response, like // SetIds. diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 902ee4ee6ea..3312925e2ff 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -4,7 +4,6 @@ use dom::attr::Attr; use dom::attr::AttrHelpers; -use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyStateValues}; use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding; use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding::HTMLIFrameElementMethods; use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast}; @@ -16,7 +15,7 @@ use dom::element::{HTMLIFrameElementTypeId, Element}; use dom::element::AttributeHandlers; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{Node, NodeHelpers, ElementNodeTypeId, window_from_node, document_from_node}; +use dom::node::{Node, NodeHelpers, ElementNodeTypeId, window_from_node}; use dom::virtualmethods::VirtualMethods; use dom::window::Window; use page::IterablePage; @@ -120,13 +119,8 @@ impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> { subpage_id: subpage_id, })); - let doc = document_from_node(self).root(); - if doc.ReadyState() == DocumentReadyStateValues::Loading { - // https://github.com/servo/servo/issues/3738 - // We can't handle dynamic frame tree changes in the compositor right now. - let ConstellationChan(ref chan) = page.constellation_chan; - chan.send(ScriptLoadedURLInIFrameMsg(url, page.id, subpage_id, sandboxed)); - } + let ConstellationChan(ref chan) = page.constellation_chan; + chan.send(ScriptLoadedURLInIFrameMsg(url, page.id, subpage_id, sandboxed)); } }