diff --git a/components/compositing/constellation.rs b/components/compositing/constellation.rs index 656a254d40e8..29af08a2c8ad 100644 --- a/components/compositing/constellation.rs +++ b/components/compositing/constellation.rs @@ -29,8 +29,8 @@ use msg::constellation_msg::Msg as ConstellationMsg; use msg::constellation_msg::WebDriverCommandMsg; use msg::constellation_msg::{FrameId, PipelineExitType, PipelineId}; use msg::constellation_msg::{IFrameSandboxState, MozBrowserEvent, NavigationDirection}; -use msg::constellation_msg::{Key, KeyModifiers, KeyState, LoadData}; -use msg::constellation_msg::{SubpageId, WindowSizeData}; +use msg::constellation_msg::{Key, KeyModifiers, KeyState, LoadData, WindowSizeData}; +use msg::constellation_msg::{PipelineNamespaceId, PipelineIdNamespace}; use msg::constellation_msg::{self, ConstellationChan, Failure}; use msg::webdriver_msg; use net_traits::image_cache_task::ImageCacheTask; @@ -94,18 +94,12 @@ pub struct Constellation { /// Maps from pipeline ID to the frame that contains it. pipeline_to_frame_map: HashMap, - /// Maps from a (parent pipeline, subpage) to the actual child pipeline ID. - subpage_map: HashMap<(PipelineId, SubpageId), PipelineId>, - /// A channel through which messages can be sent to the font cache. font_cache_task: FontCacheTask, /// ID of the root frame. root_frame_id: Option, - /// The next free ID to assign to a pipeline. - next_pipeline_id: PipelineId, - /// The next free ID to assign to a frame. next_frame_id: FrameId, @@ -136,6 +130,9 @@ pub struct Constellation { /// A list of in-process senders to `WebGLPaintTask`s. webgl_paint_tasks: Vec>, + + /// Next namespace id for pipeline id generation, + next_namespace_id: PipelineNamespaceId, } /// State needed to construct a constellation. @@ -256,9 +253,7 @@ impl Constellation { pipelines: HashMap::new(), frames: HashMap::new(), pipeline_to_frame_map: HashMap::new(), - subpage_map: HashMap::new(), pending_frames: vec!(), - next_pipeline_id: PipelineId(0), root_frame_id: None, next_frame_id: FrameId(0), focus_pipeline_id: None, @@ -280,7 +275,9 @@ impl Constellation { webdriver: WebDriverData::new(), canvas_paint_tasks: Vec::new(), webgl_paint_tasks: Vec::new(), + next_namespace_id: PipelineNamespaceId(1), }; + PipelineIdNamespace::install(PipelineNamespaceId(0)); constellation.run(); }); constellation_chan @@ -297,20 +294,16 @@ impl Constellation { /// Helper function for creating a pipeline fn new_pipeline(&mut self, - parent_info: Option<(PipelineId, SubpageId)>, + new_pipeline_id: PipelineId, + parent_pipeline_id: Option, initial_window_rect: Option>, script_channel: Option>, - load_data: LoadData) - -> PipelineId { - let pipeline_id = self.next_pipeline_id; - let PipelineId(ref mut i) = self.next_pipeline_id; - *i += 1; - + load_data: LoadData) { let spawning_paint_only = script_channel.is_some(); let (pipeline, mut pipeline_content) = Pipeline::create::(InitialPipelineState { - id: pipeline_id, - parent_info: parent_info, + id: new_pipeline_id, + parent_info: parent_pipeline_id, constellation_chan: self.chan.clone(), compositor_proxy: self.compositor_proxy.clone_compositor_proxy(), devtools_chan: self.devtools_chan.clone(), @@ -324,8 +317,12 @@ impl Constellation { script_chan: script_channel, load_data: load_data, device_pixel_ratio: self.window_size.device_pixel_ratio, + pipeline_namespace_id: self.next_namespace_id, }); + let PipelineNamespaceId(namespace_id) = self.next_namespace_id; + self.next_namespace_id = PipelineNamespaceId(namespace_id + 1); + // TODO(pcwalton): In multiprocess mode, send that `PipelineContent` instance over to // the content process and call this over there. if spawning_paint_only { @@ -334,9 +331,8 @@ impl Constellation { pipeline_content.start_all::(); } - assert!(!self.pipelines.contains_key(&pipeline_id)); - self.pipelines.insert(pipeline_id, pipeline); - pipeline_id + assert!(!self.pipelines.contains_key(&new_pipeline_id)); + self.pipelines.insert(new_pipeline_id, pipeline); } // Push a new (loading) pipeline to the list of pending frame changes @@ -398,23 +394,22 @@ impl Constellation { } // A layout assigned a size and position to a subframe. This needs to be reflected by // all frame trees in the navigation context containing the subframe. - ConstellationMsg::FrameRect(pipeline_id, subpage_id, rect) => { + ConstellationMsg::FrameRect(pipeline_id, rect) => { debug!("constellation got frame rect message"); - self.handle_frame_rect_msg(pipeline_id, subpage_id, Rect::from_untyped(&rect)); + self.handle_frame_rect_msg(pipeline_id, Rect::from_untyped(&rect)); } ConstellationMsg::ScriptLoadedURLInIFrame(url, - source_pipeline_id, - new_subpage_id, - old_subpage_id, + parent_pipeline_id, + new_pipeline_id, + old_pipeline_id, sandbox) => { - debug!("constellation got iframe URL load message {:?} {:?} {:?}", - source_pipeline_id, - old_subpage_id, - new_subpage_id); + debug!("constellation got iframe URL load message {:?} {:?}", + old_pipeline_id, + new_pipeline_id); self.handle_script_loaded_url_in_iframe_msg(url, - source_pipeline_id, - new_subpage_id, - old_subpage_id, + parent_pipeline_id, + new_pipeline_id, + old_pipeline_id, sandbox); } ConstellationMsg::SetCursor(cursor) => self.handle_set_cursor_msg(cursor), @@ -443,9 +438,9 @@ impl Constellation { self.handle_dom_load(pipeline_id) } // Handle a forward or back request - ConstellationMsg::Navigate(pipeline_info, direction) => { + ConstellationMsg::Navigate(pipeline_id, direction) => { debug!("constellation got navigation message"); - self.handle_navigate_msg(pipeline_info, direction); + self.handle_navigate_msg(pipeline_id, direction); } // Notification that painting has finished and is requesting permission to paint. ConstellationMsg::PainterReady(pipeline_id) => { @@ -464,21 +459,21 @@ impl Constellation { debug!("constellation got get-pipeline-title message"); self.handle_get_pipeline_title_msg(pipeline_id); } - ConstellationMsg::MozBrowserEvent(pipeline_id, - subpage_id, + ConstellationMsg::MozBrowserEvent(parent_pipeline_id, + pipeline_id, event) => { debug!("constellation got mozbrowser event message"); - self.handle_mozbrowser_event_msg(pipeline_id, - subpage_id, + self.handle_mozbrowser_event_msg(parent_pipeline_id, + pipeline_id, event); } ConstellationMsg::GetPipeline(frame_id, resp_chan) => { debug!("constellation got get root pipeline message"); self.handle_get_pipeline(frame_id, resp_chan); } - ConstellationMsg::GetFrame(parent_pipeline_id, subpage_id, resp_chan) => { + ConstellationMsg::GetFrame(pipeline_id, resp_chan) => { debug!("constellation got get root pipeline message"); - self.handle_get_frame(parent_pipeline_id, subpage_id, resp_chan); + self.handle_get_frame(pipeline_id, resp_chan); } ConstellationMsg::Focus(pipeline_id) => { debug!("constellation got focus message"); @@ -513,9 +508,9 @@ impl Constellation { let is_ready = self.handle_is_ready_to_save_image(pipeline_states); self.compositor_proxy.send(CompositorMsg::IsReadyToSaveImageReply(is_ready)); } - ConstellationMsg::RemoveIFrame(containing_pipeline_id, subpage_id) => { + ConstellationMsg::RemoveIFrame(pipeline_id) => { debug!("constellation got remove iframe message"); - self.handle_remove_iframe_msg(containing_pipeline_id, subpage_id); + self.handle_remove_iframe_msg(pipeline_id); } ConstellationMsg::NewFavicon(url) => { debug!("constellation got new favicon message"); @@ -558,7 +553,7 @@ impl Constellation { fn handle_failure_msg(&mut self, pipeline_id: PipelineId, - parent_info: Option<(PipelineId, SubpageId)>) { + parent_info: Option) { debug!("handling failure message from pipeline {:?}, {:?}", pipeline_id, parent_info); if opts::get().hard_fail { @@ -586,38 +581,40 @@ impl Constellation { debug!("creating replacement pipeline for about:failure"); let window_rect = self.pipeline(pipeline_id).rect; - let new_pipeline_id = - self.new_pipeline(parent_info, - window_rect, - None, - LoadData::new(Url::parse("about:failure").unwrap())); + let new_pipeline_id = PipelineId::new(); + self.new_pipeline(new_pipeline_id, + parent_info, + window_rect, + None, + LoadData::new(Url::parse("about:failure").unwrap())); self.push_pending_frame(new_pipeline_id, Some(pipeline_id)); } fn handle_init_load(&mut self, url: Url) { let window_rect = Rect::new(Point2D::zero(), self.window_size.visible_viewport); - let root_pipeline_id = - self.new_pipeline(None, Some(window_rect), None, LoadData::new(url.clone())); + let root_pipeline_id = PipelineId::nil(); + self.new_pipeline(root_pipeline_id, None, Some(window_rect), None, LoadData::new(url.clone())); self.handle_load_start_msg(&root_pipeline_id); self.push_pending_frame(root_pipeline_id, None); self.compositor_proxy.send(CompositorMsg::ChangePageUrl(root_pipeline_id, url)); } - fn handle_frame_rect_msg(&mut self, containing_pipeline_id: PipelineId, subpage_id: SubpageId, + fn handle_frame_rect_msg(&mut self, pipeline_id: PipelineId, rect: TypedRect) { // Store the new rect inside the pipeline let (pipeline_id, script_chan) = { // Find the pipeline that corresponds to this rectangle. It's possible that this // pipeline may have already exited before we process this message, so just // early exit if that occurs. - let pipeline_id = self.subpage_map.get(&(containing_pipeline_id, subpage_id)).map(|id| *id); - let pipeline = match pipeline_id { - Some(pipeline_id) => self.mut_pipeline(pipeline_id), + let pipeline = self.pipelines.get_mut(&pipeline_id); + match pipeline { + Some(pipeline) => { + pipeline.rect = Some(rect); + (pipeline.id, pipeline.script_chan.clone()) + } None => return, - }; - pipeline.rect = Some(rect); - (pipeline.id, pipeline.script_chan.clone()) + } }; script_chan.send(ConstellationControlMsg::Resize(pipeline_id, WindowSizeData { @@ -642,14 +639,14 @@ impl Constellation { // page navigation. fn handle_script_loaded_url_in_iframe_msg(&mut self, url: Url, - containing_pipeline_id: PipelineId, - new_subpage_id: SubpageId, - old_subpage_id: Option, + parent_pipeline_id: PipelineId, + new_pipeline_id: PipelineId, + old_pipeline_id: Option, sandbox: IFrameSandboxState) { // 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 script_chan = { - let source_pipeline = self.pipeline(containing_pipeline_id); + let source_pipeline = self.pipeline(parent_pipeline_id); let source_url = source_pipeline.url.clone(); @@ -671,17 +668,14 @@ impl Constellation { }; // Create the new pipeline, attached to the parent and push to pending frames - let old_pipeline_id = old_subpage_id.map(|old_subpage_id| { - self.find_subpage(containing_pipeline_id, old_subpage_id).id - }); let window_rect = old_pipeline_id.and_then(|old_pipeline_id| { self.pipeline(old_pipeline_id).rect }); - let new_pipeline_id = self.new_pipeline(Some((containing_pipeline_id, new_subpage_id)), - window_rect, - script_chan, - LoadData::new(url)); - self.subpage_map.insert((containing_pipeline_id, new_subpage_id), new_pipeline_id); + self.new_pipeline(new_pipeline_id, + Some(parent_pipeline_id), + window_rect, + script_chan, + LoadData::new(url)); self.push_pending_frame(new_pipeline_id, old_pipeline_id); } @@ -714,14 +708,14 @@ impl Constellation { // the new load. The framing element must be notified about the // requested change so it can update its internal state. match self.pipeline(source_id).parent_info { - Some((parent_pipeline_id, subpage_id)) => { + Some(parent_pipeline_id) => { self.handle_load_start_msg(&source_id); // Message the constellation to find the script task for this iframe // and issue an iframe load through there. let parent_pipeline = self.pipeline(parent_pipeline_id); let script_channel = &parent_pipeline.script_chan; - script_channel.send(ConstellationControlMsg::Navigate(parent_pipeline_id, - subpage_id, + script_channel.send(ConstellationControlMsg::Navigate(source_id, + parent_pipeline_id, load_data)).unwrap(); Some(source_id) } @@ -740,7 +734,8 @@ impl Constellation { // Create the new pipeline let window_rect = self.pipeline(source_id).rect; - let new_pipeline_id = self.new_pipeline(None, window_rect, None, load_data); + let new_pipeline_id = PipelineId::new(); + self.new_pipeline(new_pipeline_id, None, window_rect, None, load_data); self.push_pending_frame(new_pipeline_id, Some(source_id)); // Send message to ScriptTask that will suspend all timers @@ -789,14 +784,13 @@ impl Constellation { } fn handle_navigate_msg(&mut self, - pipeline_info: Option<(PipelineId, SubpageId)>, + pipeline_id: Option, direction: constellation_msg::NavigationDirection) { debug!("received message to navigate {:?}", direction); // Get the frame id associated with the pipeline that sent // the navigate message, or use root frame id by default. - let frame_id = pipeline_info.map_or(self.root_frame_id, |(containing_pipeline_id, subpage_id)| { - let pipeline_id = self.find_subpage(containing_pipeline_id, subpage_id).id; + let frame_id = pipeline_id.map_or(self.root_frame_id, |pipeline_id| { self.pipeline_to_frame_map.get(&pipeline_id).map(|id| *id) }).unwrap(); @@ -855,14 +849,14 @@ impl Constellation { self.revoke_paint_permission(prev_pipeline_id); self.send_frame_tree_and_grant_paint_permission(); - // Update the owning iframe to point to the new subpage id. + // Update the owning iframe to point to the new pipeline id. // This makes things like contentDocument work correctly. - if let Some((parent_pipeline_id, subpage_id)) = pipeline_info { + if let Some(pipeline_id) = pipeline_id { + let parent_pipeline_id = self.pipeline(pipeline_id).parent_info.unwrap(); let script_chan = &self.pipeline(parent_pipeline_id).script_chan; - let (_, new_subpage_id) = self.pipeline(next_pipeline_id).parent_info.unwrap(); - script_chan.send(ConstellationControlMsg::UpdateSubpageId(parent_pipeline_id, - subpage_id, - new_subpage_id)).unwrap(); + script_chan.send(ConstellationControlMsg::UpdatePipelineId(parent_pipeline_id, + prev_pipeline_id, + next_pipeline_id)).unwrap(); // If this is an iframe, send a mozbrowser location change event. // This is the result of a back/forward navigation. @@ -903,14 +897,14 @@ impl Constellation { fn handle_mozbrowser_event_msg(&mut self, containing_pipeline_id: PipelineId, - subpage_id: SubpageId, + pipeline_id: PipelineId, event: MozBrowserEvent) { assert!(prefs::get_pref("dom.mozbrowser.enabled").as_boolean().unwrap_or(false)); // Find the script channel for the given parent pipeline, // and pass the event to that script task. let pipeline = self.pipeline(containing_pipeline_id); - pipeline.trigger_mozbrowser_event(subpage_id, event); + pipeline.trigger_mozbrowser_event(pipeline_id, event); } fn handle_get_pipeline(&mut self, frame_id: Option, @@ -926,21 +920,18 @@ impl Constellation { } fn handle_get_frame(&mut self, - containing_pipeline_id: PipelineId, - subpage_id: SubpageId, + pipeline_id: PipelineId, resp_chan: IpcSender>) { - let frame_id = self.subpage_map.get(&(containing_pipeline_id, subpage_id)).and_then( - |x| self.pipeline_to_frame_map.get(&x)).map(|x| *x); + let frame_id = self.pipeline_to_frame_map.get(&pipeline_id).map(|x| *x); resp_chan.send(frame_id).unwrap(); } fn focus_parent_pipeline(&self, pipeline_id: PipelineId) { // Send a message to the parent of the provided pipeline (if it exists) // telling it to mark the iframe element as focused. - if let Some((containing_pipeline_id, subpage_id)) = self.pipeline(pipeline_id).parent_info { + if let Some(containing_pipeline_id) = self.pipeline(pipeline_id).parent_info { let pipeline = self.pipeline(containing_pipeline_id); - let event = ConstellationControlMsg::FocusIFrame(containing_pipeline_id, - subpage_id); + let event = ConstellationControlMsg::FocusIFrame(containing_pipeline_id, pipeline_id); pipeline.script_chan.send(event).unwrap(); self.focus_parent_pipeline(containing_pipeline_id); @@ -954,8 +945,7 @@ impl Constellation { self.focus_parent_pipeline(pipeline_id); } - fn handle_remove_iframe_msg(&mut self, containing_pipeline_id: PipelineId, subpage_id: SubpageId) { - let pipeline_id = self.find_subpage(containing_pipeline_id, subpage_id).id; + fn handle_remove_iframe_msg(&mut self, pipeline_id: PipelineId) { let frame_id = self.pipeline_to_frame_map.get(&pipeline_id).map(|id| *id); match frame_id { Some(frame_id) => { @@ -1073,7 +1063,7 @@ impl Constellation { // If a child frame, add it to the parent pipeline. Otherwise // it must surely be the root frame being created! match self.pipeline(frame_change.new_pipeline_id).parent_info { - Some((parent_id, _)) => { + Some(parent_id) => { self.mut_pipeline(parent_id).add_child(frame_id); } None => { @@ -1297,7 +1287,7 @@ impl Constellation { self.frames.remove(&frame_id).unwrap(); - if let Some((parent_pipeline_id, _)) = parent_info { + if let Some(parent_pipeline_id) = parent_info { let parent_pipeline = self.mut_pipeline(parent_pipeline_id); parent_pipeline.remove_child(frame_id); } @@ -1325,11 +1315,6 @@ impl Constellation { let pipeline = self.pipelines.remove(&pipeline_id).unwrap(); - // If a child pipeline, remove from subpage map - if let Some(info) = pipeline.parent_info { - self.subpage_map.remove(&info); - } - // Remove assocation between this pipeline and its holding frame self.pipeline_to_frame_map.remove(&pipeline_id); @@ -1401,15 +1386,15 @@ impl Constellation { let event_info = { let pipeline = self.pipeline(pipeline_id); - pipeline.parent_info.map(|(containing_pipeline_id, subpage_id)| { - (containing_pipeline_id, subpage_id, pipeline.url.serialize()) + pipeline.parent_info.map(|containing_pipeline_id| { + (containing_pipeline_id, pipeline.url.serialize()) }) }; // If this is an iframe, then send the event with new url - if let Some((containing_pipeline_id, subpage_id, url)) = event_info { + if let Some((containing_pipeline_id, url)) = event_info { let parent_pipeline = self.pipeline(containing_pipeline_id); - parent_pipeline.trigger_mozbrowser_event(subpage_id, MozBrowserEvent::LocationChange(url)); + parent_pipeline.trigger_mozbrowser_event(pipeline_id, MozBrowserEvent::LocationChange(url)); } } } @@ -1450,11 +1435,4 @@ impl Constellation { fn mut_pipeline(&mut self, pipeline_id: PipelineId) -> &mut Pipeline { self.pipelines.get_mut(&pipeline_id).expect("unable to find pipeline - this is a bug") } - - fn find_subpage(&mut self, containing_pipeline_id: PipelineId, subpage_id: SubpageId) -> &mut Pipeline { - let pipeline_id = *self.subpage_map - .get(&(containing_pipeline_id, subpage_id)) - .expect("no subpage pipeline_id"); - self.mut_pipeline(pipeline_id) - } } diff --git a/components/compositing/pipeline.rs b/components/compositing/pipeline.rs index 73cabc1d35e1..a2138ee85e96 100644 --- a/components/compositing/pipeline.rs +++ b/components/compositing/pipeline.rs @@ -13,8 +13,8 @@ use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use ipc_channel::router::ROUTER; use layers::geometry::DevicePixel; use layout_traits::{LayoutControlChan, LayoutTaskFactory}; -use msg::constellation_msg::{ConstellationChan, Failure, FrameId, PipelineId, SubpageId}; -use msg::constellation_msg::{LoadData, MozBrowserEvent, PipelineExitType, WindowSizeData}; +use msg::constellation_msg::{ConstellationChan, Failure, FrameId, PipelineId}; +use msg::constellation_msg::{LoadData, MozBrowserEvent, PipelineExitType, PipelineNamespaceId, WindowSizeData}; use net_traits::ResourceTask; use net_traits::image_cache_task::ImageCacheTask; use net_traits::storage_task::StorageTask; @@ -35,7 +35,7 @@ use util::prefs; /// A uniquely-identifiable pipeline of script task, layout task, and paint task. pub struct Pipeline { pub id: PipelineId, - pub parent_info: Option<(PipelineId, SubpageId)>, + pub parent_info: Option, pub script_chan: Sender, /// A channel to layout, for performing reflows and shutdown. pub layout_chan: LayoutControlChan, @@ -68,7 +68,7 @@ pub struct InitialPipelineState { pub id: PipelineId, /// The subpage ID of this pipeline to create in its pipeline parent. /// If `None`, this is the root. - pub parent_info: Option<(PipelineId, SubpageId)>, + pub parent_info: Option, /// A channel to the associated constellation. pub constellation_chan: ConstellationChan, /// A channel to the compositor. @@ -96,6 +96,8 @@ pub struct InitialPipelineState { pub script_chan: Option>, /// Information about the page to load. pub load_data: LoadData, + /// The namespace ID to use for creating new pipeline IDs. + pub pipeline_namespace_id: PipelineNamespaceId, } impl Pipeline { @@ -137,12 +139,11 @@ impl Pipeline { let (script_chan, script_port) = match state.script_chan { Some(script_chan) => { - let (containing_pipeline_id, subpage_id) = - state.parent_info.expect("script_pipeline != None but subpage_id == None"); + let containing_pipeline_id = + state.parent_info.expect("script_pipeline != None but parent id == None"); let new_layout_info = NewLayoutInfo { containing_pipeline_id: containing_pipeline_id, new_pipeline_id: state.id, - subpage_id: subpage_id, load_data: state.load_data.clone(), paint_chan: box layout_to_paint_chan.clone() as Box, failure: failure, @@ -194,13 +195,14 @@ impl Pipeline { pipeline_port: pipeline_port, paint_shutdown_chan: paint_shutdown_chan, layout_shutdown_chan: layout_shutdown_chan, + pipeline_namespace_id: state.pipeline_namespace_id, }; (pipeline, pipeline_content) } pub fn new(id: PipelineId, - parent_info: Option<(PipelineId, SubpageId)>, + parent_info: Option, script_chan: Sender, layout_chan: LayoutControlChan, chrome_to_paint_chan: Sender, @@ -287,12 +289,12 @@ impl Pipeline { } pub fn trigger_mozbrowser_event(&self, - subpage_id: SubpageId, - event: MozBrowserEvent) { + pipeline_id: PipelineId, + event: MozBrowserEvent) { assert!(prefs::get_pref("dom.mozbrowser.enabled").as_boolean().unwrap_or(false)); let event = ConstellationControlMsg::MozBrowserEvent(self.id, - subpage_id, + pipeline_id, event); self.script_chan.send(event).unwrap(); } @@ -300,7 +302,7 @@ impl Pipeline { pub struct PipelineContent { id: PipelineId, - parent_info: Option<(PipelineId, SubpageId)>, + parent_info: Option, constellation_chan: ConstellationChan, compositor_proxy: Box, devtools_chan: Option>, @@ -322,6 +324,7 @@ pub struct PipelineContent { paint_shutdown_chan: Sender<()>, pipeline_port: Option>, layout_shutdown_chan: Sender<()>, + pipeline_namespace_id: PipelineNamespaceId, } impl PipelineContent { @@ -354,6 +357,7 @@ impl PipelineContent { mem_profiler_chan: self.mem_profiler_chan.clone(), devtools_chan: self.devtools_chan, window_size: self.window_size, + pipeline_namespace_id: self.pipeline_namespace_id, }, &layout_pair, self.load_data.clone()); LayoutTaskFactory::create(None::<&mut LTF>, diff --git a/components/devtools/lib.rs b/components/devtools/lib.rs index c0049b31ad33..1dad9f710c28 100644 --- a/components/devtools/lib.rs +++ b/components/devtools/lib.rs @@ -433,7 +433,7 @@ fn run_server(sender: Sender, //TODO: Get pipeline_id from NetworkEventMessage after fixing the send in http_loader // For now, the id of the first pipeline is passed handle_network_event(actors.clone(), connections, &actor_pipelines, &mut actor_requests, - &actor_workers, PipelineId(0), request_id, network_event); + &actor_workers, PipelineId::nil(), request_id, network_event); }, Ok(DevtoolsControlMsg::FromChrome(ChromeToDevtoolsControlMsg::ServerExitMsg)) | Err(RecvError) => break diff --git a/components/gfx/paint_task.rs b/components/gfx/paint_task.rs index 3c139fafaaa2..30aaacdf5041 100644 --- a/components/gfx/paint_task.rs +++ b/components/gfx/paint_task.rs @@ -175,7 +175,7 @@ impl PaintTask where C: PaintListener + Send + 'static { canvas_map: HashMap::new() }; - let reporter_name = format!("paint-reporter-{}", id.0); + let reporter_name = format!("paint-reporter-{:?}", id); mem_profiler_chan.run_with_memory_reporting(|| { paint_task.start(); }, reporter_name, chrome_to_paint_chan, ChromeToPaintMsg::CollectReports); diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 4bc788c0ce71..a79b1d248e53 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -1372,12 +1372,10 @@ impl FragmentDisplayListBuilding for Fragment { Size2D::new(content_size.width.to_f32_px(), content_size.height.to_f32_px())); - debug!("finalizing position and size of iframe for {:?},{:?}", - iframe_fragment.pipeline_id, - iframe_fragment.subpage_id); + debug!("finalizing position and size of iframe for {:?}", + iframe_fragment.pipeline_id); let ConstellationChan(ref chan) = layout_context.shared.constellation_chan; chan.send(ConstellationMsg::FrameRect(iframe_fragment.pipeline_id, - iframe_fragment.subpage_id, iframe_rect)).unwrap(); } diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index c6cea07b77b7..af235e72d3fc 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -22,7 +22,7 @@ use inline::{InlineMetrics, LAST_FRAGMENT_OF_ELEMENT}; use ipc_channel::ipc::IpcSender; use layout_debug; use model::{self, IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto, specified}; -use msg::constellation_msg::{ConstellationChan, Msg, PipelineId, SubpageId}; +use msg::constellation_msg::{ConstellationChan, Msg, PipelineId}; use net_traits::image::base::Image; use net_traits::image_cache_task::UsePlaceholder; use rustc_serialize::{Encodable, Encoder}; @@ -576,17 +576,14 @@ impl ReplacedImageFragmentInfo { pub struct IframeFragmentInfo { /// The pipeline ID of this iframe. pub pipeline_id: PipelineId, - /// The subpage ID of this iframe. - pub subpage_id: SubpageId, } impl IframeFragmentInfo { /// Creates the information specific to an iframe fragment. pub fn new(node: &ThreadSafeLayoutNode) -> IframeFragmentInfo { - let (pipeline_id, subpage_id) = node.iframe_pipeline_and_subpage_ids(); + let pipeline_id = node.iframe_pipeline_id(); IframeFragmentInfo { pipeline_id: pipeline_id, - subpage_id: subpage_id, } } @@ -2219,7 +2216,6 @@ impl Fragment { SpecificFragmentInfo::Iframe(ref iframe_info) => { let ConstellationChan(ref chan) = constellation_chan; chan.send(Msg::FrameRect(iframe_info.pipeline_id, - iframe_info.subpage_id, Rect::zero())).unwrap(); } _ => {} diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index c5f9c3710351..3c936a0d1067 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -275,7 +275,7 @@ impl LayoutTaskFactory for LayoutTask { time_profiler_chan, mem_profiler_chan.clone()); - let reporter_name = format!("layout-reporter-{}", id.0); + let reporter_name = format!("layout-reporter-{:?}", id); mem_profiler_chan.run_with_memory_reporting(|| { layout.start(); }, reporter_name, layout_chan.0, Msg::CollectReports); diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index 17102f0095d8..3769103708e3 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -37,7 +37,7 @@ use gfx::display_list::OpaqueNode; use gfx::text::glyph::CharIndex; use incremental::RestyleDamage; use ipc_channel::ipc::IpcSender; -use msg::constellation_msg::{PipelineId, SubpageId}; +use msg::constellation_msg::PipelineId; use opaque_node::OpaqueNodeMethods; use script::dom::attr::AttrValue; use script::dom::bindings::codegen::InheritTypes::{CharacterDataCast, ElementCast}; @@ -1013,12 +1013,11 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { /// If this node is an iframe element, returns its pipeline and subpage IDs. If this node is /// not an iframe element, fails. - pub fn iframe_pipeline_and_subpage_ids(&self) -> (PipelineId, SubpageId) { + pub fn iframe_pipeline_id(&self) -> PipelineId { unsafe { let iframe_element = HTMLIFrameElementCast::to_layout_js(self.get_jsmanaged()) .expect("not an iframe element!"); - ((*iframe_element.unsafe_get()).containing_page_pipeline_id().unwrap(), - (*iframe_element.unsafe_get()).subpage_id().unwrap()) + (*iframe_element.unsafe_get()).pipeline_id().unwrap() } } } diff --git a/components/msg/constellation_msg.rs b/components/msg/constellation_msg.rs index ab244707c283..edccb3170f27 100644 --- a/components/msg/constellation_msg.rs +++ b/components/msg/constellation_msg.rs @@ -16,6 +16,8 @@ use ipc_channel::ipc::IpcSender; use layers::geometry::DevicePixel; use offscreen_gl_context::GLContextAttributes; use png::Image; +use serde::{Deserializer, Serializer}; +use std::cell::RefCell; use std::collections::HashMap; use std::sync::mpsc::{Receiver, Sender, channel}; use style_traits::viewport::ViewportConstraints; @@ -45,7 +47,7 @@ pub enum IFrameSandboxState { #[derive(Clone, Copy, Deserialize, Serialize)] pub struct Failure { pub pipeline_id: PipelineId, - pub parent_info: Option<(PipelineId, SubpageId)>, + pub parent_info: Option, } #[derive(Copy, Clone, Deserialize, Serialize, HeapSizeOf)] @@ -221,10 +223,10 @@ pub enum Msg { LoadComplete(PipelineId), /// Dispatched after the DOM load event has fired on a document DOMLoad(PipelineId), - FrameRect(PipelineId, SubpageId, Rect), + FrameRect(PipelineId, Rect), LoadUrl(PipelineId, LoadData), - ScriptLoadedURLInIFrame(Url, PipelineId, SubpageId, Option, IFrameSandboxState), - Navigate(Option<(PipelineId, SubpageId)>, NavigationDirection), + ScriptLoadedURLInIFrame(Url, PipelineId, PipelineId, Option, IFrameSandboxState), + Navigate(Option, NavigationDirection), PainterReady(PipelineId), ResizedWindow(WindowSizeData), KeyEvent(Key, KeyState, KeyModifiers), @@ -234,7 +236,7 @@ pub enum Msg { /// Requests that the constellation inform the compositor of the a cursor change. SetCursor(Cursor), /// Dispatch a mozbrowser event to a given iframe. Only available in experimental mode. - MozBrowserEvent(PipelineId, SubpageId, MozBrowserEvent), + MozBrowserEvent(PipelineId, PipelineId, MozBrowserEvent), /// Indicates whether this pipeline is currently running animations. ChangeRunningAnimationsState(PipelineId, AnimationState), /// Requests that the constellation instruct layout to begin a new tick of the animation. @@ -243,8 +245,8 @@ pub enum Msg { /// id, or for the root frame if this is None, over a provided channel GetPipeline(Option, IpcSender>), /// Request that the constellation send the FrameId corresponding to the document - /// with the provided parent pipeline id and subpage id - GetFrame(PipelineId, SubpageId, IpcSender>), + /// with the provided pipeline id + GetFrame(PipelineId, IpcSender>), /// Notifies the constellation that this frame has received focus. Focus(PipelineId), /// Requests that the constellation retrieve the current contents of the clipboard @@ -258,7 +260,7 @@ pub enum Msg { /// Query the constellation to see if the current compositor output is stable IsReadyToSaveImage(HashMap), /// Notification that this iframe should be removed. - RemoveIFrame(PipelineId, SubpageId), + RemoveIFrame(PipelineId), /// Favicon detected NewFavicon(Url), /// tag finished parsing @@ -385,6 +387,45 @@ pub enum NavigationDirection { Back, } +#[derive(Clone, PartialEq, Eq, Copy, Hash, Debug, Deserialize, Serialize, HeapSizeOf)] +pub struct PipelineNamespaceId(pub u32); + +#[derive(Clone, PartialEq, Eq, Copy, Hash, Debug, Deserialize, Serialize, HeapSizeOf)] +pub struct PipelineIndex(u32); + +pub struct PipelineIdNamespace { + id: PipelineNamespaceId, + next_index: PipelineIndex, +} + +impl PipelineIdNamespace { + pub fn install(namespace_id: PipelineNamespaceId) { + PIPELINE_NAMESPACE.with(|tls| { + let mut namespace = tls.borrow_mut(); + assert!(namespace.is_none()); + + *namespace = Some(PipelineIdNamespace { + id: namespace_id, + next_index: PipelineIndex(1), + }); + }); + } + + fn next(&mut self) -> PipelineId { + let pipeline_id = PipelineId { + namespace_id: self.id, + index: self.next_index, + }; + + let PipelineIndex(current_index) = self.next_index; + self.next_index = PipelineIndex(current_index + 1); + + pipeline_id + } +} + +thread_local!(pub static PIPELINE_NAMESPACE: RefCell> = RefCell::new(None)); + #[derive(Clone, PartialEq, Eq, Copy, Hash, Debug, Deserialize, Serialize)] pub struct FrameId(pub u32); @@ -392,10 +433,10 @@ pub struct FrameId(pub u32); pub struct WorkerId(pub u32); #[derive(Clone, PartialEq, Eq, Copy, Hash, Debug, Deserialize, Serialize, HeapSizeOf)] -pub struct PipelineId(pub u32); - -#[derive(Clone, PartialEq, Eq, Copy, Hash, Debug, Deserialize, Serialize, HeapSizeOf)] -pub struct SubpageId(pub u32); +pub struct PipelineId { + namespace_id: PipelineNamespaceId, + index: PipelineIndex +} // The type of pipeline exit. During complete shutdowns, pipelines do not have to // release resources automatically released on process termination. @@ -404,3 +445,20 @@ pub enum PipelineExitType { PipelineOnly, Complete, } + +impl PipelineId { + pub fn new() -> PipelineId { + PIPELINE_NAMESPACE.with(|tls| { + let mut namespace = tls.borrow_mut(); + let mut namespace = namespace.as_mut().expect("No namespace set for this thread!"); + namespace.next() + }) + } + + pub fn nil() -> PipelineId { + PipelineId { + namespace_id: PipelineNamespaceId(0), + index: PipelineIndex(0), + } + } +} diff --git a/components/msg/lib.rs b/components/msg/lib.rs index 995b1bc55870..f839a603d99f 100644 --- a/components/msg/lib.rs +++ b/components/msg/lib.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #![feature(custom_derive, plugin)] +#![feature(const_fn)] #![plugin(serde_macros, plugins)] #[macro_use] diff --git a/components/msg/webdriver_msg.rs b/components/msg/webdriver_msg.rs index db0fccac228c..63ac4aa7ffd4 100644 --- a/components/msg/webdriver_msg.rs +++ b/components/msg/webdriver_msg.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use constellation_msg::{PipelineId, SubpageId}; +use constellation_msg::PipelineId; use ipc_channel::ipc::IpcSender; use rustc_serialize::json::{Json, ToJson}; use url::Url; @@ -16,7 +16,7 @@ pub enum WebDriverScriptCommand { GetActiveElement(IpcSender>), GetElementTagName(String, IpcSender>), GetElementText(String, IpcSender>), - GetFrameId(WebDriverFrameId, IpcSender, ()>>), + GetFrameId(WebDriverFrameId, IpcSender, ()>>), GetUrl(IpcSender), GetTitle(IpcSender) } diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 94d3ad97c934..0f8a04c27872 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -51,7 +51,7 @@ use js::rust::Runtime; use layout_interface::{LayoutChan, LayoutRPC}; use libc; use msg::constellation_msg::ConstellationChan; -use msg::constellation_msg::{PipelineId, SubpageId, WindowSizeData, WorkerId}; +use msg::constellation_msg::{PipelineId, WindowSizeData, WorkerId}; use net_traits::image::base::Image; use net_traits::image_cache_task::{ImageCacheChan, ImageCacheTask}; use net_traits::storage_task::StorageType; @@ -281,7 +281,7 @@ no_jsmanaged_fields!(PropertyDeclarationBlock); no_jsmanaged_fields!(HashSet); // These three are interdependent, if you plan to put jsmanaged data // in one of these make sure it is propagated properly to containing structs -no_jsmanaged_fields!(SubpageId, WindowSizeData, PipelineId); +no_jsmanaged_fields!(WindowSizeData, PipelineId); no_jsmanaged_fields!(WorkerId); no_jsmanaged_fields!(QuirksMode); no_jsmanaged_fields!(Runtime); diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index db4c72af8dc4..d7d9f2bce855 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -77,7 +77,7 @@ use msg::compositor_msg::ScriptToCompositorMsg; use msg::constellation_msg::AnimationState; use msg::constellation_msg::Msg as ConstellationMsg; use msg::constellation_msg::{ALT, CONTROL, SHIFT, SUPER}; -use msg::constellation_msg::{ConstellationChan, FocusType, Key, KeyModifiers, KeyState, MozBrowserEvent, SubpageId}; +use msg::constellation_msg::{ConstellationChan, FocusType, Key, KeyModifiers, KeyState, MozBrowserEvent, PipelineId}; use net_traits::ControlMsg::{GetCookiesForUrl, SetCookiesForUrl}; use net_traits::CookieSource::NonHTTP; use net_traits::{AsyncResponseTarget, Metadata, PendingAsyncLoad}; @@ -865,10 +865,10 @@ impl Document { if htmliframeelement::mozbrowser_enabled() { let window = self.window.root(); - if let Some((containing_pipeline_id, subpage_id)) = window.r().parent_info() { + if let Some(containing_pipeline_id) = window.r().parent_pipeline() { let ConstellationChan(ref chan) = window.r().constellation_chan(); let event = ConstellationMsg::MozBrowserEvent(containing_pipeline_id, - subpage_id, + window.r().pipeline(), event); chan.send(event).unwrap(); } @@ -973,10 +973,10 @@ impl Document { } /// Find an iframe element in the document. - pub fn find_iframe(&self, subpage_id: SubpageId) -> Option> { + pub fn find_iframe(&self, pipeline_id: PipelineId) -> Option> { NodeCast::from_ref(self).traverse_preorder() .filter_map(HTMLIFrameElementCast::to_root) - .find(|node| node.r().subpage_id() == Some(subpage_id)) + .find(|node| node.r().pipeline_id() == Some(pipeline_id)) } } diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 8e0016f4bb08..56d8da3faf01 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -28,7 +28,7 @@ use js::jsapi::{JSAutoCompartment, JSAutoRequest, RootedValue}; use js::jsval::UndefinedValue; use msg::constellation_msg::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed}; use msg::constellation_msg::Msg as ConstellationMsg; -use msg::constellation_msg::{ConstellationChan, MozBrowserEvent, NavigationDirection, PipelineId, SubpageId}; +use msg::constellation_msg::{ConstellationChan, MozBrowserEvent, NavigationDirection, PipelineId}; use page::IterablePage; use std::ascii::AsciiExt; use std::borrow::ToOwned; @@ -57,8 +57,7 @@ enum SandboxAllowance { #[dom_struct] pub struct HTMLIFrameElement { htmlelement: HTMLElement, - subpage_id: Cell>, - containing_page_pipeline_id: Cell>, + pipeline_id: Cell>, sandbox: Cell>, } @@ -91,12 +90,11 @@ impl HTMLIFrameElement { }) } - pub fn generate_new_subpage_id(&self) -> (SubpageId, Option) { - let old_subpage_id = self.subpage_id.get(); - let win = window_from_node(self); - let subpage_id = win.r().get_next_subpage_id(); - self.subpage_id.set(Some(subpage_id)); - (subpage_id, old_subpage_id) + pub fn generate_new_pipeline_id(&self) -> (PipelineId, Option) { + let old_pipeline_id = self.pipeline_id.get(); + let new_pipeline_id = PipelineId::new(); + self.pipeline_id.set(Some(new_pipeline_id)); + (new_pipeline_id, old_pipeline_id) } pub fn navigate_child_browsing_context(&self, url: Url) { @@ -108,15 +106,13 @@ impl HTMLIFrameElement { let window = window_from_node(self); let window = window.r(); - let (new_subpage_id, old_subpage_id) = self.generate_new_subpage_id(); - - self.containing_page_pipeline_id.set(Some(window.pipeline())); + let (new_pipeline_id, old_pipeline_id) = self.generate_new_pipeline_id(); let ConstellationChan(ref chan) = window.constellation_chan(); chan.send(ConstellationMsg::ScriptLoadedURLInIFrame(url, window.pipeline(), - new_subpage_id, - old_subpage_id, + new_pipeline_id, + old_pipeline_id, sandboxed)).unwrap(); if mozbrowser_enabled() { @@ -158,8 +154,8 @@ impl HTMLIFrameElement { } } - pub fn update_subpage_id(&self, new_subpage_id: SubpageId) { - self.subpage_id.set(Some(new_subpage_id)); + pub fn update_pipeline_id(&self, new_pipeline_id: PipelineId) { + self.pipeline_id.set(Some(new_pipeline_id)); } #[allow(unsafe_code)] @@ -190,8 +186,7 @@ impl HTMLIFrameElement { HTMLIFrameElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLIFrameElement, localName, prefix, document), - subpage_id: Cell::new(None), - containing_page_pipeline_id: Cell::new(None), + pipeline_id: Cell::new(None), sandbox: Cell::new(None), } } @@ -204,14 +199,8 @@ impl HTMLIFrameElement { Node::reflect_node(box element, document, HTMLIFrameElementBinding::Wrap) } - #[inline] - pub fn containing_page_pipeline_id(&self) -> Option { - self.containing_page_pipeline_id.get() - } - - #[inline] - pub fn subpage_id(&self) -> Option { - self.subpage_id.get() + pub fn pipeline_id(&self) -> Option { + self.pipeline_id.get() } } @@ -222,10 +211,9 @@ pub fn Navigate(iframe: &HTMLIFrameElement, direction: NavigationDirection) -> F let window = window_from_node(iframe); let window = window.r(); - let pipeline_info = Some((iframe.containing_page_pipeline_id().unwrap(), - iframe.subpage_id().unwrap())); + let pipeline_id = iframe.pipeline_id().unwrap(); let ConstellationChan(ref chan) = window.constellation_chan(); - let msg = ConstellationMsg::Navigate(pipeline_info, direction); + let msg = ConstellationMsg::Navigate(Some(pipeline_id), direction); chan.send(msg).unwrap(); } @@ -263,13 +251,13 @@ impl HTMLIFrameElementMethods for HTMLIFrameElement { // https://html.spec.whatwg.org/multipage/#dom-iframe-contentwindow fn GetContentWindow(&self) -> Option> { - self.subpage_id.get().and_then(|subpage_id| { + self.pipeline_id.get().and_then(|pipeline_id| { let window = window_from_node(self); let window = window.r(); let children = window.page().children.borrow(); children.iter().find(|page| { let window = page.window(); - window.r().subpage() == Some(subpage_id) + window.r().pipeline() == pipeline_id }).map(|page| page.window()) }) } @@ -408,24 +396,20 @@ impl VirtualMethods for HTMLIFrameElement { } // https://html.spec.whatwg.org/multipage/#a-browsing-context-is-discarded - match (self.containing_page_pipeline_id(), self.subpage_id()) { - (Some(containing_pipeline_id), Some(subpage_id)) => { - let window = window_from_node(self); - let window = window.r(); - - let ConstellationChan(ref chan) = window.constellation_chan(); - let msg = ConstellationMsg::RemoveIFrame(containing_pipeline_id, - subpage_id); - chan.send(msg).unwrap(); - - // Resetting the subpage id to None is required here so that - // if this iframe is subsequently re-added to the document - // the load doesn't think that it's a navigation, but instead - // a new iframe. Without this, the constellation gets very - // confused. - self.subpage_id.set(None); - } - _ => {} + if let Some(pipeline_id) = self.pipeline_id() { + let window = window_from_node(self); + let window = window.r(); + + let ConstellationChan(ref chan) = window.constellation_chan(); + let msg = ConstellationMsg::RemoveIFrame(pipeline_id); + chan.send(msg).unwrap(); + + // Resetting the pipeline id to None is required here so that + // if this iframe is subsequently re-added to the document + // the load doesn't think that it's a navigation, but instead + // a new iframe. Without this, the constellation gets very + // confused. + self.pipeline_id.set(None); } } } diff --git a/components/script/dom/servohtmlparser.rs b/components/script/dom/servohtmlparser.rs index fd8547683471..fe7364104e22 100644 --- a/components/script/dom/servohtmlparser.rs +++ b/components/script/dom/servohtmlparser.rs @@ -26,7 +26,7 @@ use html5ever::tree_builder::{NodeOrText, TreeBuilder, TreeBuilderOpts}; use hyper::header::ContentType; use hyper::mime::{Mime, SubLevel, TopLevel}; use js::jsapi::JSTracer; -use msg::constellation_msg::{PipelineId, SubpageId}; +use msg::constellation_msg::PipelineId; use net_traits::{AsyncResponseListener, Metadata}; use network_listener::PreInvoke; use parse::Parser; @@ -73,8 +73,6 @@ pub struct ParserContext { is_image_document: Cell, /// The pipeline associated with this document. id: PipelineId, - /// The subpage associated with this document. - subpage: Option, /// The target event loop for the response notifications. script_chan: Box, /// The URL for this document. @@ -82,13 +80,12 @@ pub struct ParserContext { } impl ParserContext { - pub fn new(id: PipelineId, subpage: Option, script_chan: Box, + pub fn new(id: PipelineId, script_chan: Box, url: Url) -> ParserContext { ParserContext { parser: RefCell::new(None), is_image_document: Cell::new(false), id: id, - subpage: subpage, script_chan: script_chan, url: url, } @@ -99,8 +96,7 @@ impl AsyncResponseListener for ParserContext { fn headers_available(&self, metadata: Metadata) { let content_type = metadata.content_type.clone(); - let parser = ScriptTask::page_fetch_complete(self.id.clone(), self.subpage.clone(), - metadata); + let parser = ScriptTask::page_fetch_complete(self.id.clone(), metadata); let parser = match parser { Some(parser) => parser, None => return, diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 4cec46c7814c..10ca49ebbd48 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -43,7 +43,7 @@ use layout_interface::{ContentBoxResponse, ContentBoxesResponse, ResolvedStyleRe use layout_interface::{LayoutChan, LayoutRPC, Msg, Reflow, ReflowGoal, ReflowQueryType}; use libc; use msg::compositor_msg::{LayerId, ScriptToCompositorMsg}; -use msg::constellation_msg::{ConstellationChan, LoadData, PipelineId, SubpageId, WindowSizeData, WorkerId}; +use msg::constellation_msg::{ConstellationChan, LoadData, PipelineId, WindowSizeData, WorkerId}; use msg::webdriver_msg::{WebDriverJSError, WebDriverJSResult}; use net_traits::ResourceTask; use net_traits::image_cache_task::{ImageCacheChan, ImageCacheTask}; @@ -151,8 +151,6 @@ pub struct Window { /// page changes. devtools_wants_updates: Cell, - next_subpage_id: Cell, - /// Pending resize event, if any. resize_event: Cell>, @@ -160,7 +158,7 @@ pub struct Window { id: PipelineId, /// Subpage id associated with this page, if any. - parent_info: Option<(PipelineId, SubpageId)>, + parent_info: Option, /// Unique id for last reflow request; used for confirming completion reply. last_reflow_id: Cell, @@ -257,11 +255,7 @@ impl Window { self.id } - pub fn subpage(&self) -> Option { - self.parent_info.map(|p| p.1) - } - - pub fn parent_info(&self) -> Option<(PipelineId, SubpageId)> { + pub fn parent_pipeline(&self) -> Option { self.parent_info } @@ -1126,13 +1120,6 @@ impl Window { WindowProxyHandler(self.dom_static.windowproxy_handler.0) } - pub fn get_next_subpage_id(&self) -> SubpageId { - let subpage_id = self.next_subpage_id.get(); - let SubpageId(id_num) = subpage_id; - self.next_subpage_id.set(SubpageId(id_num + 1)); - subpage_id - } - pub fn layout_is_idle(&self) -> bool { self.layout_join_port.borrow().is_none() } @@ -1269,7 +1256,7 @@ impl Window { constellation_chan: ConstellationChan, layout_chan: LayoutChan, id: PipelineId, - parent_info: Option<(PipelineId, SubpageId)>, + parent_info: Option, window_size: Option) -> Root { let layout_rpc: Box = { @@ -1312,7 +1299,6 @@ impl Window { fragment_name: DOMRefCell::new(None), last_reflow_id: Cell::new(0), resize_event: Cell::new(None), - next_subpage_id: Cell::new(SubpageId(0)), layout_chan: layout_chan, layout_rpc: layout_rpc, layout_join_port: DOMRefCell::new(None), diff --git a/components/script/script_task.rs b/components/script/script_task.rs index a935e4b91f58..4353d5ff3f99 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -66,7 +66,7 @@ use msg::compositor_msg::{LayerId, ScriptToCompositorMsg}; use msg::constellation_msg::Msg as ConstellationMsg; use msg::constellation_msg::{ConstellationChan, FocusType, LoadData}; use msg::constellation_msg::{MozBrowserEvent, PipelineExitType, PipelineId}; -use msg::constellation_msg::{SubpageId, WindowSizeData, WorkerId}; +use msg::constellation_msg::{PipelineIdNamespace, WindowSizeData, WorkerId}; use msg::webdriver_msg::WebDriverScriptCommand; use net_traits::LoadData as NetLoadData; use net_traits::image_cache_task::{ImageCacheChan, ImageCacheResult, ImageCacheTask}; @@ -128,7 +128,7 @@ struct InProgressLoad { /// The pipeline which requested this load. pipeline_id: PipelineId, /// The parent pipeline and child subpage associated with this load, if any. - parent_info: Option<(PipelineId, SubpageId)>, + parent_info: Option, /// The current window size associated with this pipeline. window_size: Option, /// Channel to the layout task associated with this pipeline. @@ -142,7 +142,7 @@ struct InProgressLoad { impl InProgressLoad { /// Create a new InProgressLoad object. fn new(id: PipelineId, - parent_info: Option<(PipelineId, SubpageId)>, + parent_info: Option, layout_chan: LayoutChan, window_size: Option, url: Url) -> InProgressLoad { @@ -467,6 +467,7 @@ impl ScriptTaskFactory for ScriptTask { let (script_chan, script_port) = channel(); let layout_chan = LayoutChan(layout_chan.sender()); let failure_info = state.failure_info; + let pipeline_namespace_id = state.pipeline_namespace_id; spawn_named_with_send_on_failure(format!("ScriptTask {:?}", state.id), task_state::SCRIPT, move || { let roots = RootCollection::new(); let _stack_roots_tls = StackRootTLS::new(&roots); @@ -479,6 +480,7 @@ impl ScriptTaskFactory for ScriptTask { let script_task = ScriptTask::new(state, script_port, chan); + PipelineIdNamespace::install(pipeline_namespace_id); SCRIPT_TASK_ROOT.with(|root| { *root.borrow_mut() = Some(&script_task as *const _); @@ -490,7 +492,7 @@ impl ScriptTaskFactory for ScriptTask { load_data.url.clone()); script_task.start_page_load(new_load, load_data); - let reporter_name = format!("script-reporter-{}", id.0); + let reporter_name = format!("script-reporter-{:?}", id); mem_profiler_chan.run_with_memory_reporting(|| { script_task.start(); }, reporter_name, channel_for_reporter, CommonScriptMsg::CollectReports); @@ -558,11 +560,11 @@ unsafe extern "C" fn shadow_check_callback(_cx: *mut JSContext, } impl ScriptTask { - pub fn page_fetch_complete(id: PipelineId, subpage: Option, metadata: Metadata) + pub fn page_fetch_complete(id: PipelineId, metadata: Metadata) -> Option> { SCRIPT_TASK_ROOT.with(|root| { let script_task = unsafe { &*root.borrow().unwrap() }; - script_task.handle_page_fetch_complete(id, subpage, metadata) + script_task.handle_page_fetch_complete(id, metadata) }) } @@ -906,8 +908,8 @@ impl ScriptTask { match msg { ConstellationControlMsg::AttachLayout(_) => panic!("should have handled AttachLayout already"), - ConstellationControlMsg::Navigate(pipeline_id, subpage_id, load_data) => - self.handle_navigate(pipeline_id, Some(subpage_id), load_data), + ConstellationControlMsg::Navigate(pipeline_id, parent_pipeline_id, load_data) => + self.handle_navigate(pipeline_id, Some(parent_pipeline_id), load_data), ConstellationControlMsg::SendEvent(id, event) => self.handle_event(id, event), ConstellationControlMsg::ReflowComplete(id, reflow_id) => @@ -927,17 +929,19 @@ impl ScriptTask { ConstellationControlMsg::Thaw(pipeline_id) => self.handle_thaw_msg(pipeline_id), ConstellationControlMsg::MozBrowserEvent(parent_pipeline_id, - subpage_id, + pipeline_id, event) => self.handle_mozbrowser_event_msg(parent_pipeline_id, - subpage_id, + pipeline_id, event), - ConstellationControlMsg::UpdateSubpageId(containing_pipeline_id, - old_subpage_id, - new_subpage_id) => - self.handle_update_subpage_id(containing_pipeline_id, old_subpage_id, new_subpage_id), - ConstellationControlMsg::FocusIFrame(containing_pipeline_id, subpage_id) => - self.handle_focus_iframe_msg(containing_pipeline_id, subpage_id), + ConstellationControlMsg::UpdatePipelineId(parent_pipeline_id, + old_pipeline_id, + new_pipeline_id) => + self.handle_update_pipeline_id(parent_pipeline_id, + old_pipeline_id, + new_pipeline_id), + ConstellationControlMsg::FocusIFrame(containing_pipeline_id, pipeline_id) => + self.handle_focus_iframe_msg(containing_pipeline_id, pipeline_id), ConstellationControlMsg::WebDriverScriptCommand(pipeline_id, msg) => self.handle_webdriver_msg(pipeline_id, msg), ConstellationControlMsg::TickAllAnimations(pipeline_id) => @@ -1128,7 +1132,6 @@ impl ScriptTask { let NewLayoutInfo { containing_pipeline_id, new_pipeline_id, - subpage_id, load_data, paint_chan, failure, @@ -1168,7 +1171,7 @@ impl ScriptTask { .unwrap(); // Kick off the fetch for the new resource. - let new_load = InProgressLoad::new(new_pipeline_id, Some((containing_pipeline_id, subpage_id)), + let new_load = InProgressLoad::new(new_pipeline_id, Some(containing_pipeline_id), layout_chan, parent_window.r().window_size(), load_data.url.clone()); self.start_page_load(new_load, load_data); @@ -1313,12 +1316,12 @@ impl ScriptTask { fn handle_focus_iframe_msg(&self, parent_pipeline_id: PipelineId, - subpage_id: SubpageId) { + pipeline_id: PipelineId) { let borrowed_page = self.root_page(); let page = borrowed_page.find(parent_pipeline_id).unwrap(); let doc = page.document(); - let frame_element = doc.find_iframe(subpage_id); + let frame_element = doc.find_iframe(pipeline_id); if let Some(ref frame_element) = frame_element { let element = ElementCast::from_ref(frame_element.r()); @@ -1332,13 +1335,13 @@ impl ScriptTask { /// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserloadstart fn handle_mozbrowser_event_msg(&self, parent_pipeline_id: PipelineId, - subpage_id: SubpageId, + pipeline_id: PipelineId, event: MozBrowserEvent) { let borrowed_page = self.root_page(); let frame_element = borrowed_page.find(parent_pipeline_id).and_then(|page| { let doc = page.document(); - doc.find_iframe(subpage_id) + doc.find_iframe(pipeline_id) }); if let Some(ref frame_element) = frame_element { @@ -1346,18 +1349,18 @@ impl ScriptTask { } } - fn handle_update_subpage_id(&self, - containing_pipeline_id: PipelineId, - old_subpage_id: SubpageId, - new_subpage_id: SubpageId) { + fn handle_update_pipeline_id(&self, + parent_pipeline_id: PipelineId, + old_pipeline_id: PipelineId, + new_pipeline_id: PipelineId) { let borrowed_page = self.root_page(); - let frame_element = borrowed_page.find(containing_pipeline_id).and_then(|page| { + let frame_element = borrowed_page.find(parent_pipeline_id).and_then(|page| { let doc = page.document(); - doc.find_iframe(old_subpage_id) + doc.find_iframe(old_pipeline_id) }); - frame_element.r().unwrap().update_subpage_id(new_subpage_id); + frame_element.r().unwrap().update_pipeline_id(new_pipeline_id); } /// Handles a notification that reflow completed. @@ -1401,10 +1404,10 @@ impl ScriptTask { /// We have received notification that the response associated with a load has completed. /// Kick off the document and frame tree creation process using the result. - fn handle_page_fetch_complete(&self, id: PipelineId, subpage: Option, + fn handle_page_fetch_complete(&self, id: PipelineId, metadata: Metadata) -> Option> { let idx = self.incomplete_loads.borrow().iter().position(|load| { - load.pipeline_id == id && load.parent_info.map(|info| info.1) == subpage + load.pipeline_id == id }); // The matching in progress load structure may not exist if // the pipeline exited before the page load completed. @@ -1499,7 +1502,7 @@ impl ScriptTask { // existing one. let root_page_exists = self.page.borrow().is_some(); - let frame_element = incomplete.parent_info.and_then(|(parent_id, subpage_id)| { + let frame_element = incomplete.parent_info.and_then(|parent_id| { // The root page may not exist yet, if the parent of this frame // exists in a different script task. let borrowed_page = self.page.borrow(); @@ -1514,7 +1517,7 @@ impl ScriptTask { borrowed_page.as_ref().and_then(|borrowed_page| { borrowed_page.find(parent_id).and_then(|page| { let doc = page.document(); - doc.find_iframe(subpage_id) + doc.find_iframe(incomplete.pipeline_id) }) }) }); @@ -1524,7 +1527,7 @@ impl ScriptTask { if !root_page_exists { // We have a new root frame tree. *self.page.borrow_mut() = Some(page.clone()); - } else if let Some((parent, _)) = incomplete.parent_info { + } else if let Some(parent) = incomplete.parent_info { // We have a new child frame. let parent_page = self.root_page(); // TODO(gw): This find will fail when we are sharing script tasks @@ -1781,7 +1784,10 @@ impl ScriptTask { /// https://html.spec.whatwg.org/multipage/#navigating-across-documents /// The entry point for content to notify that a new load has been requested /// for the given pipeline (specifically the "navigate" algorithm). - fn handle_navigate(&self, pipeline_id: PipelineId, subpage_id: Option, load_data: LoadData) { + fn handle_navigate(&self, + pipeline_id: PipelineId, + parent_pipeline_id: Option, + load_data: LoadData) { // Step 8. { let nurl = &load_data.url; @@ -1803,12 +1809,12 @@ impl ScriptTask { } } - match subpage_id { - Some(subpage_id) => { + match parent_pipeline_id { + Some(parent_pipeline_id) => { let borrowed_page = self.root_page(); - let iframe = borrowed_page.find(pipeline_id).and_then(|page| { + let iframe = borrowed_page.find(parent_pipeline_id).and_then(|page| { let doc = page.document(); - doc.find_iframe(subpage_id) + doc.find_iframe(pipeline_id) }); if let Some(iframe) = iframe.r() { iframe.navigate_child_browsing_context(load_data.url); @@ -1853,12 +1859,11 @@ impl ScriptTask { /// argument until a notification is received that the fetch is complete. fn start_page_load(&self, incomplete: InProgressLoad, mut load_data: LoadData) { let id = incomplete.pipeline_id.clone(); - let subpage = incomplete.parent_info.clone().map(|p| p.1); let script_chan = self.chan.clone(); let resource_task = self.resource_task.clone(); - let context = Arc::new(Mutex::new(ParserContext::new(id, subpage, script_chan.clone(), + let context = Arc::new(Mutex::new(ParserContext::new(id, script_chan.clone(), load_data.url.clone()))); let (action_sender, action_receiver) = ipc::channel().unwrap(); let listener = box NetworkListener { diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs index 15b31ff63e74..49de9a145a91 100644 --- a/components/script/webdriver_handlers.rs +++ b/components/script/webdriver_handlers.rs @@ -17,7 +17,7 @@ use ipc_channel::ipc::IpcSender; use js::jsapi::JSContext; use js::jsapi::{HandleValue, RootedValue}; use js::jsval::UndefinedValue; -use msg::constellation_msg::{PipelineId, SubpageId}; +use msg::constellation_msg::PipelineId; use msg::webdriver_msg::{WebDriverFrameId, WebDriverJSError, WebDriverJSResult, WebDriverJSValue}; use page::Page; use script_task::get_page; @@ -85,7 +85,7 @@ pub fn handle_execute_async_script(page: &Rc, pub fn handle_get_frame_id(page: &Rc, pipeline: PipelineId, webdriver_frame_id: WebDriverFrameId, - reply: IpcSender, ()>>) { + reply: IpcSender, ()>>) { let window = match webdriver_frame_id { WebDriverFrameId::Short(_) => { // This isn't supported yet @@ -108,8 +108,8 @@ pub fn handle_get_frame_id(page: &Rc, } }; - let frame_id = window.map(|x| x.and_then(|x| x.r().parent_info())); - reply.send(frame_id).unwrap() + let pipeline_id = window.map(|x| x.map(|x| x.r().pipeline())); + reply.send(pipeline_id).unwrap() } pub fn handle_find_element_css(page: &Rc, _pipeline: PipelineId, selector: String, diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index ba0f25d42e0f..0c1a2692d8a6 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -28,8 +28,8 @@ use ipc_channel::ipc::{IpcReceiver, IpcSender}; use libc::c_void; use msg::compositor_msg::{Epoch, LayerId, ScriptToCompositorMsg}; use msg::constellation_msg::{ConstellationChan, Failure, PipelineId, WindowSizeData}; -use msg::constellation_msg::{Key, KeyModifiers, KeyState, LoadData, SubpageId}; -use msg::constellation_msg::{MozBrowserEvent, PipelineExitType}; +use msg::constellation_msg::{Key, KeyModifiers, KeyState, LoadData}; +use msg::constellation_msg::{MozBrowserEvent, PipelineExitType, PipelineNamespaceId}; use msg::webdriver_msg::WebDriverScriptCommand; use net_traits::ResourceTask; use net_traits::image_cache_task::ImageCacheTask; @@ -69,8 +69,6 @@ pub struct NewLayoutInfo { pub containing_pipeline_id: PipelineId, /// Id of the newly-created pipeline. pub new_pipeline_id: PipelineId, - /// Id of the new frame associated with this pipeline. - pub subpage_id: SubpageId, /// Network request data which will be initiated by the script task. pub load_data: LoadData, /// The paint channel, cast to `Box`. @@ -125,13 +123,13 @@ pub enum ConstellationControlMsg { /// Notifies script task to resume all its timers Thaw(PipelineId), /// Notifies script task that a url should be loaded in this iframe. - Navigate(PipelineId, SubpageId, LoadData), + Navigate(PipelineId, PipelineId, LoadData), /// Requests the script task forward a mozbrowser event to an iframe it owns - MozBrowserEvent(PipelineId, SubpageId, MozBrowserEvent), - /// Updates the current subpage id of a given iframe - UpdateSubpageId(PipelineId, SubpageId, SubpageId), + MozBrowserEvent(PipelineId, PipelineId, MozBrowserEvent), + /// Updates the current pipeline id of a given iframe + UpdatePipelineId(PipelineId, PipelineId, PipelineId), /// Set an iframe to be focused. Used when an element in an iframe gains focus. - FocusIFrame(PipelineId, SubpageId), + FocusIFrame(PipelineId, PipelineId), /// Passes a webdriver command to the script task for execution WebDriverScriptCommand(PipelineId, WebDriverScriptCommand), /// Notifies script task that all animations are done @@ -182,7 +180,7 @@ pub struct InitialScriptState { pub id: PipelineId, /// The subpage ID of this pipeline to create in its pipeline parent. /// If `None`, this is the root. - pub parent_info: Option<(PipelineId, SubpageId)>, + pub parent_info: Option, /// The compositor. pub compositor: IpcSender, /// A channel with which messages can be sent to us (the script task). @@ -207,6 +205,8 @@ pub struct InitialScriptState { pub devtools_chan: Option>, /// Information about the initial window size. pub window_size: Option, + /// The ID of the namespace to use when creating pipeline IDs. + pub pipeline_namespace_id: PipelineNamespaceId, } /// This trait allows creating a `ScriptTask` without depending on the `script` diff --git a/components/webdriver_server/lib.rs b/components/webdriver_server/lib.rs index 22776126a942..57580b56295a 100644 --- a/components/webdriver_server/lib.rs +++ b/components/webdriver_server/lib.rs @@ -450,10 +450,10 @@ impl Handler { } let frame = match receiver.recv().unwrap() { - Ok(Some((pipeline_id, subpage_id))) => { + Ok(Some(pipeline_id)) => { let (sender, receiver) = ipc::channel().unwrap(); let ConstellationChan(ref const_chan) = self.constellation_chan; - const_chan.send(ConstellationMsg::GetFrame(pipeline_id, subpage_id, sender)).unwrap(); + const_chan.send(ConstellationMsg::GetFrame(pipeline_id, sender)).unwrap(); receiver.recv().unwrap() }, Ok(None) => None,