diff --git a/components/constellation/browsingcontext.rs b/components/constellation/browsingcontext.rs index 4926bbcf7dd..329a3ef20a0 100644 --- a/components/constellation/browsingcontext.rs +++ b/components/constellation/browsingcontext.rs @@ -34,11 +34,11 @@ pub struct BrowsingContext { impl BrowsingContext { /// Create a new browsing context. /// Note this just creates the browsing context, it doesn't add it to the constellation's set of browsing contexts. - pub fn new(id: BrowsingContextId, - top_level_id: TopLevelBrowsingContextId, - pipeline_id: PipelineId) - -> BrowsingContext - { + pub fn new( + id: BrowsingContextId, + top_level_id: TopLevelBrowsingContextId, + pipeline_id: PipelineId, + ) -> BrowsingContext { let mut pipelines = HashSet::new(); pipelines.insert(pipeline_id); BrowsingContext { @@ -84,19 +84,25 @@ impl<'a> Iterator for FullyActiveBrowsingContextsIterator<'a> { let browsing_context = match self.browsing_contexts.get(&browsing_context_id) { Some(browsing_context) => browsing_context, None => { - warn!("BrowsingContext {:?} iterated after closure.", browsing_context_id); + warn!( + "BrowsingContext {:?} iterated after closure.", + browsing_context_id + ); continue; }, }; let pipeline = match self.pipelines.get(&browsing_context.pipeline_id) { Some(pipeline) => pipeline, None => { - warn!("Pipeline {:?} iterated after closure.", browsing_context.pipeline_id); + warn!( + "Pipeline {:?} iterated after closure.", + browsing_context.pipeline_id + ); continue; }, }; self.stack.extend(pipeline.children.iter()); - return Some(browsing_context) + return Some(browsing_context); } } } @@ -126,15 +132,20 @@ impl<'a> Iterator for AllBrowsingContextsIterator<'a> { let browsing_context = match self.browsing_contexts.get(&browsing_context_id) { Some(browsing_context) => browsing_context, None => { - warn!("BrowsingContext {:?} iterated after closure.", browsing_context_id); + warn!( + "BrowsingContext {:?} iterated after closure.", + browsing_context_id + ); continue; }, }; - let child_browsing_context_ids = browsing_context.pipelines.iter() + let child_browsing_context_ids = browsing_context + .pipelines + .iter() .filter_map(|pipeline_id| pipelines.get(&pipeline_id)) .flat_map(|pipeline| pipeline.children.iter()); self.stack.extend(child_browsing_context_ids); - return Some(browsing_context) + return Some(browsing_context); } } } diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 83341d154bd..8eb00583932 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -438,7 +438,9 @@ impl FromScriptLogger { /// Create a new constellation logger. pub fn new(script_to_constellation_chan: ScriptToConstellationChan) -> FromScriptLogger { FromScriptLogger { - script_to_constellation_chan: Arc::new(ReentrantMutex::new(script_to_constellation_chan)) + script_to_constellation_chan: Arc::new(ReentrantMutex::new( + script_to_constellation_chan, + )), } } @@ -458,7 +460,10 @@ impl Log for FromScriptLogger { debug!("Sending log entry {:?}.", entry); let thread_name = thread::current().name().map(ToOwned::to_owned); let msg = FromScriptMsg::LogEntry(thread_name, entry); - let chan = self.script_to_constellation_chan.lock().unwrap_or_else(|err| err.into_inner()); + let chan = self + .script_to_constellation_chan + .lock() + .unwrap_or_else(|err| err.into_inner()); let _ = chan.send(msg); } } @@ -477,7 +482,7 @@ impl FromCompositorLogger { /// Create a new constellation logger. pub fn new(constellation_chan: Sender) -> FromCompositorLogger { FromCompositorLogger { - constellation_chan: Arc::new(ReentrantMutex::new(constellation_chan)) + constellation_chan: Arc::new(ReentrantMutex::new(constellation_chan)), } } @@ -498,7 +503,10 @@ impl Log for FromCompositorLogger { let top_level_id = TopLevelBrowsingContextId::installed(); let thread_name = thread::current().name().map(ToOwned::to_owned); let msg = FromCompositorMsg::LogEntry(top_level_id, thread_name, entry); - let chan = self.constellation_chan.lock().unwrap_or_else(|err| err.into_inner()); + let chan = self + .constellation_chan + .lock() + .unwrap_or_else(|err| err.into_inner()); let _ = chan.send(msg); } } @@ -514,14 +522,10 @@ fn log_entry(record: &Record) -> Option { match record.level() { Level::Error if thread::panicking() => Some(LogEntry::Panic( format!("{}", record.args()), - format!("{:?}", Backtrace::new()) - )), - Level::Error => Some(LogEntry::Error( - format!("{}", record.args()) - )), - Level::Warn => Some(LogEntry::Warn( - format!("{}", record.args()) + format!("{:?}", Backtrace::new()), )), + Level::Error => Some(LogEntry::Error(format!("{}", record.args()))), + Level::Warn => Some(LogEntry::Warn(format!("{}", record.args()))), _ => None, } } @@ -532,111 +536,130 @@ const WARNINGS_BUFFER_SIZE: usize = 32; /// Route an ipc receiver to an mpsc receiver, preserving any errors. /// This is the same as `route_ipc_receiver_to_new_mpsc_receiver`, /// but does not panic on deserializtion errors. -fn route_ipc_receiver_to_new_mpsc_receiver_preserving_errors(ipc_receiver: IpcReceiver) - -> Receiver> - where T: for<'de> Deserialize<'de> + Serialize + Send + 'static +fn route_ipc_receiver_to_new_mpsc_receiver_preserving_errors( + ipc_receiver: IpcReceiver, +) -> Receiver> +where + T: for<'de> Deserialize<'de> + Serialize + Send + 'static, { - let (mpsc_sender, mpsc_receiver) = channel(); - ROUTER.add_route(ipc_receiver.to_opaque(), Box::new(move |message| { - drop(mpsc_sender.send(message.to::())) - })); - mpsc_receiver + let (mpsc_sender, mpsc_receiver) = channel(); + ROUTER.add_route( + ipc_receiver.to_opaque(), + Box::new(move |message| drop(mpsc_sender.send(message.to::()))), + ); + mpsc_receiver } impl Constellation - where LTF: LayoutThreadFactory, - STF: ScriptThreadFactory +where + LTF: LayoutThreadFactory, + STF: ScriptThreadFactory, { /// Create a new constellation thread. - pub fn start(state: InitialConstellationState) -> (Sender, IpcSender) { + pub fn start( + state: InitialConstellationState, + ) -> (Sender, IpcSender) { let (compositor_sender, compositor_receiver) = channel(); // service worker manager to communicate with constellation let (swmanager_sender, swmanager_receiver) = ipc::channel().expect("ipc channel failure"); let sw_mgr_clone = swmanager_sender.clone(); - thread::Builder::new().name("Constellation".to_owned()).spawn(move || { - let (ipc_script_sender, ipc_script_receiver) = ipc::channel().expect("ipc channel failure"); - let script_receiver = route_ipc_receiver_to_new_mpsc_receiver_preserving_errors(ipc_script_receiver); + thread::Builder::new() + .name("Constellation".to_owned()) + .spawn(move || { + let (ipc_script_sender, ipc_script_receiver) = + ipc::channel().expect("ipc channel failure"); + let script_receiver = + route_ipc_receiver_to_new_mpsc_receiver_preserving_errors(ipc_script_receiver); - let (ipc_layout_sender, ipc_layout_receiver) = ipc::channel().expect("ipc channel failure"); - let layout_receiver = route_ipc_receiver_to_new_mpsc_receiver_preserving_errors(ipc_layout_receiver); + let (ipc_layout_sender, ipc_layout_receiver) = + ipc::channel().expect("ipc channel failure"); + let layout_receiver = + route_ipc_receiver_to_new_mpsc_receiver_preserving_errors(ipc_layout_receiver); - let (network_listener_sender, network_listener_receiver) = channel(); + let (network_listener_sender, network_listener_receiver) = channel(); - let swmanager_receiver = route_ipc_receiver_to_new_mpsc_receiver_preserving_errors(swmanager_receiver); + let swmanager_receiver = + route_ipc_receiver_to_new_mpsc_receiver_preserving_errors(swmanager_receiver); - PipelineNamespace::install(PipelineNamespaceId(0)); + PipelineNamespace::install(PipelineNamespaceId(0)); - let mut constellation: Constellation = Constellation { - script_sender: ipc_script_sender, - layout_sender: ipc_layout_sender, - script_receiver: script_receiver, - compositor_receiver: compositor_receiver, - layout_receiver: layout_receiver, - network_listener_sender: network_listener_sender, - network_listener_receiver: network_listener_receiver, - embedder_proxy: state.embedder_proxy, - compositor_proxy: state.compositor_proxy, - active_browser_id: None, - debugger_chan: state.debugger_chan, - devtools_chan: state.devtools_chan, - bluetooth_thread: state.bluetooth_thread, - public_resource_threads: state.public_resource_threads, - private_resource_threads: state.private_resource_threads, - font_cache_thread: state.font_cache_thread, - swmanager_chan: None, - swmanager_receiver: swmanager_receiver, - swmanager_sender: sw_mgr_clone, - event_loops: HashMap::new(), - joint_session_histories: HashMap::new(), - pipelines: HashMap::new(), - browsing_contexts: HashMap::new(), - pending_changes: vec!(), - // We initialize the namespace at 1, since we reserved namespace 0 for the constellation - next_pipeline_namespace_id: PipelineNamespaceId(1), - focus_pipeline_id: None, - time_profiler_chan: state.time_profiler_chan, - mem_profiler_chan: state.mem_profiler_chan, - window_size: WindowSizeData { - initial_viewport: opts::get().initial_window_size.to_f32() * - TypedScale::new(1.0), - device_pixel_ratio: - TypedScale::new(opts::get().device_pixels_per_px.unwrap_or(1.0)), - }, - phantom: PhantomData, - clipboard_ctx: if state.supports_clipboard { - match ClipboardContext::new() { - Ok(c) => Some(c), - Err(e) => { - warn!("Error creating clipboard context ({})", e); - None + let mut constellation: Constellation = Constellation { + script_sender: ipc_script_sender, + layout_sender: ipc_layout_sender, + script_receiver: script_receiver, + compositor_receiver: compositor_receiver, + layout_receiver: layout_receiver, + network_listener_sender: network_listener_sender, + network_listener_receiver: network_listener_receiver, + embedder_proxy: state.embedder_proxy, + compositor_proxy: state.compositor_proxy, + active_browser_id: None, + debugger_chan: state.debugger_chan, + devtools_chan: state.devtools_chan, + bluetooth_thread: state.bluetooth_thread, + public_resource_threads: state.public_resource_threads, + private_resource_threads: state.private_resource_threads, + font_cache_thread: state.font_cache_thread, + swmanager_chan: None, + swmanager_receiver: swmanager_receiver, + swmanager_sender: sw_mgr_clone, + event_loops: HashMap::new(), + joint_session_histories: HashMap::new(), + pipelines: HashMap::new(), + browsing_contexts: HashMap::new(), + pending_changes: vec![], + // We initialize the namespace at 1, since we reserved namespace 0 for the constellation + next_pipeline_namespace_id: PipelineNamespaceId(1), + focus_pipeline_id: None, + time_profiler_chan: state.time_profiler_chan, + mem_profiler_chan: state.mem_profiler_chan, + window_size: WindowSizeData { + initial_viewport: opts::get().initial_window_size.to_f32() * + TypedScale::new(1.0), + device_pixel_ratio: TypedScale::new( + opts::get().device_pixels_per_px.unwrap_or(1.0), + ), + }, + phantom: PhantomData, + clipboard_ctx: if state.supports_clipboard { + match ClipboardContext::new() { + Ok(c) => Some(c), + Err(e) => { + warn!("Error creating clipboard context ({})", e); + None + }, + } + } else { + None + }, + webdriver: WebDriverData::new(), + scheduler_chan: TimerScheduler::start(), + document_states: HashMap::new(), + webrender_document: state.webrender_document, + webrender_api_sender: state.webrender_api_sender, + shutting_down: false, + handled_warnings: VecDeque::new(), + random_pipeline_closure: opts::get().random_pipeline_closure_probability.map( + |prob| { + let seed = opts::get() + .random_pipeline_closure_seed + .unwrap_or_else(random); + let rng = ServoRng::from_seed(&[seed]); + warn!("Randomly closing pipelines."); + info!("Using seed {} for random pipeline closure.", seed); + (rng, prob) }, - } - } else { - None - }, - webdriver: WebDriverData::new(), - scheduler_chan: TimerScheduler::start(), - document_states: HashMap::new(), - webrender_document: state.webrender_document, - webrender_api_sender: state.webrender_api_sender, - shutting_down: false, - handled_warnings: VecDeque::new(), - random_pipeline_closure: opts::get().random_pipeline_closure_probability.map(|prob| { - let seed = opts::get().random_pipeline_closure_seed.unwrap_or_else(random); - let rng = ServoRng::from_seed(&[seed]); - warn!("Randomly closing pipelines."); - info!("Using seed {} for random pipeline closure.", seed); - (rng, prob) - }), - webgl_threads: state.webgl_threads, - webvr_chan: state.webvr_chan, - canvas_chan: CanvasPaintThread::start(), - }; + ), + webgl_threads: state.webgl_threads, + webvr_chan: state.webvr_chan, + canvas_chan: CanvasPaintThread::start(), + }; - constellation.run(); - }).expect("Thread spawning failed"); + constellation.run(); + }) + .expect("Thread spawning failed"); (compositor_sender, swmanager_sender) } @@ -661,21 +684,28 @@ impl Constellation } /// Helper function for creating a pipeline - fn new_pipeline(&mut self, - pipeline_id: PipelineId, - browsing_context_id: BrowsingContextId, - top_level_browsing_context_id: TopLevelBrowsingContextId, - parent_info: Option, - initial_window_size: Option>, - // TODO: we have to provide ownership of the LoadData - // here, because it will be send on an ipc channel, - // and ipc channels take onership of their data. - // https://github.com/servo/ipc-channel/issues/138 - load_data: LoadData, - sandbox: IFrameSandboxState, - is_private: bool) { - if self.shutting_down { return; } - debug!("Creating new pipeline {} in browsing context {}.", pipeline_id, browsing_context_id); + fn new_pipeline( + &mut self, + pipeline_id: PipelineId, + browsing_context_id: BrowsingContextId, + top_level_browsing_context_id: TopLevelBrowsingContextId, + parent_info: Option, + initial_window_size: Option>, + // TODO: we have to provide ownership of the LoadData + // here, because it will be send on an ipc channel, + // and ipc channels take onership of their data. + // https://github.com/servo/ipc-channel/issues/138 + load_data: LoadData, + sandbox: IFrameSandboxState, + is_private: bool, + ) { + if self.shutting_down { + return; + } + debug!( + "Creating new pipeline {} in browsing context {}.", + pipeline_id, browsing_context_id + ); let (event_loop, host) = match sandbox { IFrameSandboxState::IFrameSandboxed => (None, None), @@ -686,7 +716,9 @@ impl Constellation match reg_host(&load_data.url) { None => (None, None), Some(host) => { - let event_loop = self.event_loops.get(&top_level_browsing_context_id) + let event_loop = self + .event_loops + .get(&top_level_browsing_context_id) .and_then(|map| map.get(&host)) .and_then(|weak| weak.upgrade()); match event_loop { @@ -695,11 +727,14 @@ impl Constellation } }, } - } else if let Some(parent) = parent_info - .and_then(|pipeline_id| self.pipelines.get(&pipeline_id)) { + } else if let Some(parent) = + parent_info.and_then(|pipeline_id| self.pipelines.get(&pipeline_id)) + { (Some(parent.event_loop.clone()), None) - } else if let Some(creator) = load_data.creator_pipeline_id - .and_then(|pipeline_id| self.pipelines.get(&pipeline_id)) { + } else if let Some(creator) = load_data + .creator_pipeline_id + .and_then(|pipeline_id| self.pipelines.get(&pipeline_id)) + { (Some(creator.event_loop.clone()), None) } else { (None, None) @@ -717,7 +752,9 @@ impl Constellation .and_then(|parent_pipeline_id| self.pipelines.get(&parent_pipeline_id)) .map(|pipeline| pipeline.visible); - let prev_visibility = self.browsing_contexts.get(&browsing_context_id) + let prev_visibility = self + .browsing_contexts + .get(&browsing_context_id) .and_then(|browsing_context| self.pipelines.get(&browsing_context.pipeline_id)) .map(|pipeline| pipeline.visible) .or(parent_visibility); @@ -750,8 +787,11 @@ impl Constellation webrender_api_sender: self.webrender_api_sender.clone(), webrender_document: self.webrender_document, is_private, - webgl_chan: self.webgl_threads.as_ref().map(|threads| threads.pipeline()), - webvr_chan: self.webvr_chan.clone() + webgl_chan: self + .webgl_threads + .as_ref() + .map(|threads| threads.pipeline()), + webvr_chan: self.webvr_chan.clone(), }); let pipeline = match result { @@ -760,8 +800,12 @@ impl Constellation }; if let Some(host) = host { - debug!("Adding new host entry {} for top-level browsing context {}.", host, top_level_browsing_context_id); - self.event_loops.entry(top_level_browsing_context_id) + debug!( + "Adding new host entry {} for top-level browsing context {}.", + host, top_level_browsing_context_id + ); + self.event_loops + .entry(top_level_browsing_context_id) .or_insert_with(HashMap::new) .insert(host, Rc::downgrade(&pipeline.event_loop)); } @@ -771,45 +815,55 @@ impl Constellation } /// Get an iterator for the fully active browsing contexts in a subtree. - fn fully_active_descendant_browsing_contexts_iter(&self, browsing_context_id: BrowsingContextId) - -> FullyActiveBrowsingContextsIterator - { + fn fully_active_descendant_browsing_contexts_iter( + &self, + browsing_context_id: BrowsingContextId, + ) -> FullyActiveBrowsingContextsIterator { FullyActiveBrowsingContextsIterator { - stack: vec!(browsing_context_id), + stack: vec![browsing_context_id], pipelines: &self.pipelines, browsing_contexts: &self.browsing_contexts, } } /// Get an iterator for the fully active browsing contexts in a tree. - fn fully_active_browsing_contexts_iter(&self, top_level_browsing_context_id: TopLevelBrowsingContextId) - -> FullyActiveBrowsingContextsIterator - { - self.fully_active_descendant_browsing_contexts_iter(BrowsingContextId::from(top_level_browsing_context_id)) + fn fully_active_browsing_contexts_iter( + &self, + top_level_browsing_context_id: TopLevelBrowsingContextId, + ) -> FullyActiveBrowsingContextsIterator { + self.fully_active_descendant_browsing_contexts_iter(BrowsingContextId::from( + top_level_browsing_context_id, + )) } /// Get an iterator for the browsing contexts in a subtree. - fn all_descendant_browsing_contexts_iter(&self, browsing_context_id: BrowsingContextId) - -> AllBrowsingContextsIterator - { + fn all_descendant_browsing_contexts_iter( + &self, + browsing_context_id: BrowsingContextId, + ) -> AllBrowsingContextsIterator { AllBrowsingContextsIterator { - stack: vec!(browsing_context_id), + stack: vec![browsing_context_id], pipelines: &self.pipelines, browsing_contexts: &self.browsing_contexts, } } /// Create a new browsing context and update the internal bookkeeping. - fn new_browsing_context(&mut self, - browsing_context_id: BrowsingContextId, - top_level_id: TopLevelBrowsingContextId, - pipeline_id: PipelineId) { + fn new_browsing_context( + &mut self, + browsing_context_id: BrowsingContextId, + top_level_id: TopLevelBrowsingContextId, + pipeline_id: PipelineId, + ) { debug!("Creating new browsing context {}", browsing_context_id); let browsing_context = BrowsingContext::new(browsing_context_id, top_level_id, pipeline_id); - self.browsing_contexts.insert(browsing_context_id, browsing_context); + self.browsing_contexts + .insert(browsing_context_id, browsing_context); // If a child browsing_context, add it to the parent pipeline. - let parent_info = self.pipelines.get(&pipeline_id) + let parent_info = self + .pipelines + .get(&pipeline_id) .and_then(|pipeline| pipeline.parent_info); if let Some(parent_id) = parent_info { if let Some(parent) = self.pipelines.get_mut(&parent_id) { @@ -873,9 +927,7 @@ impl Constellation }; match request { - Request::Compositor(message) => { - self.handle_request_from_compositor(message) - }, + Request::Compositor(message) => self.handle_request_from_compositor(message), Request::Script(message) => { self.handle_request_from_script(message); }, @@ -887,7 +939,7 @@ impl Constellation }, Request::FromSWManager(message) => { self.handle_request_from_swmanager(message); - } + }, } } @@ -912,7 +964,7 @@ impl Constellation SWManagerMsg::OwnSender(sw_sender) => { // store service worker manager for communicating with it. self.swmanager_chan = Some(sw_sender); - } + }, } } @@ -921,15 +973,16 @@ impl Constellation match message { FromCompositorMsg::Exit => { self.handle_exit(); - } + }, FromCompositorMsg::GetBrowsingContext(pipeline_id, resp_chan) => { self.handle_get_browsing_context(pipeline_id, resp_chan); - } + }, FromCompositorMsg::GetPipeline(browsing_context_id, resp_chan) => { self.handle_get_pipeline(browsing_context_id, resp_chan); - } + }, FromCompositorMsg::GetFocusTopLevelBrowsingContext(resp_chan) => { - let focus_browsing_context = self.focus_pipeline_id + let focus_browsing_context = self + .focus_pipeline_id .and_then(|pipeline_id| self.pipelines.get(&pipeline_id)) .map(|pipeline| pipeline.top_level_browsing_context_id) .filter(|&top_level_browsing_context_id| { @@ -938,10 +991,10 @@ impl Constellation self.browsing_contexts.contains_key(&browsing_context_id) }); let _ = resp_chan.send(focus_browsing_context); - } + }, FromCompositorMsg::KeyEvent(ch, key, state, modifiers) => { self.handle_key_msg(ch, key, state, modifiers); - } + }, // Load a new page from a typed url // If there is already a pending page (self.pending_changes), it will not be overridden; // However, if the id is not encompassed by another change, it will be. @@ -950,10 +1003,20 @@ impl Constellation let ctx_id = BrowsingContextId::from(top_level_browsing_context_id); let pipeline_id = match self.browsing_contexts.get(&ctx_id) { Some(ctx) => ctx.pipeline_id, - None => return warn!("LoadUrl for unknow browsing context: {:?}", top_level_browsing_context_id), + None => { + return warn!( + "LoadUrl for unknow browsing context: {:?}", + top_level_browsing_context_id + ) + }, }; - self.handle_load_url_msg(top_level_browsing_context_id, pipeline_id, load_data, false); - } + self.handle_load_url_msg( + top_level_browsing_context_id, + pipeline_id, + load_data, + false, + ); + }, FromCompositorMsg::IsReadyToSaveImage(pipeline_states) => { let is_ready = self.handle_is_ready_to_save_image(pipeline_states); debug!("Ready to save image {:?}.", is_ready); @@ -961,20 +1024,21 @@ impl Constellation println!("got ready to save image query, result is {:?}", is_ready); } let is_ready = is_ready == ReadyToSave::Ready; - self.compositor_proxy.send(ToCompositorMsg::IsReadyToSaveImageReply(is_ready)); + self.compositor_proxy + .send(ToCompositorMsg::IsReadyToSaveImageReply(is_ready)); if opts::get().is_running_problem_test { println!("sent response"); } - } + }, // Create a new top level browsing context. Will use response_chan to return // the browsing context id. FromCompositorMsg::NewBrowser(url, response_chan) => { self.handle_new_top_level_browsing_context(url, response_chan); - } + }, // Close a top level browsing context. FromCompositorMsg::CloseBrowser(top_level_browsing_context_id) => { self.handle_close_top_level_browsing_context(top_level_browsing_context_id); - } + }, // Panic a top level browsing context. FromCompositorMsg::SendError(top_level_browsing_context_id, error) => { debug!("constellation got SendError message"); @@ -983,114 +1047,119 @@ impl Constellation } else { warn!("constellation got a SendError message without top level id"); } - } + }, // Send frame tree to WebRender. Make it visible. FromCompositorMsg::SelectBrowser(top_level_browsing_context_id) => { self.send_frame_tree(top_level_browsing_context_id); - } + }, // Handle a forward or back request FromCompositorMsg::TraverseHistory(top_level_browsing_context_id, direction) => { self.handle_traverse_history_msg(top_level_browsing_context_id, direction); - } + }, FromCompositorMsg::WindowSize(top_level_browsing_context_id, new_size, size_type) => { self.handle_window_size_msg(top_level_browsing_context_id, new_size, size_type); - } + }, FromCompositorMsg::TickAnimation(pipeline_id, tick_type) => { self.handle_tick_animation(pipeline_id, tick_type) - } + }, FromCompositorMsg::WebDriverCommand(command) => { self.handle_webdriver_msg(command); - } + }, FromCompositorMsg::Reload(top_level_browsing_context_id) => { self.handle_reload_msg(top_level_browsing_context_id); - } + }, FromCompositorMsg::LogEntry(top_level_browsing_context_id, thread_name, entry) => { self.handle_log_entry(top_level_browsing_context_id, thread_name, entry); - } + }, FromCompositorMsg::WebVREvents(pipeline_ids, events) => { self.handle_webvr_events(pipeline_ids, events); - } + }, FromCompositorMsg::ForwardEvent(destination_pipeline_id, event) => { self.forward_event(destination_pipeline_id, event); - } - FromCompositorMsg::SetCursor(cursor) => { - self.handle_set_cursor_msg(cursor) - } + }, + FromCompositorMsg::SetCursor(cursor) => self.handle_set_cursor_msg(cursor), } } fn handle_request_from_script(&mut self, message: (PipelineId, FromScriptMsg)) { let (source_pipeline_id, content) = message; - debug!("constellation got {:?} message from pipeline {}", content, source_pipeline_id); + debug!( + "constellation got {:?} message from pipeline {}", + content, source_pipeline_id + ); - let source_top_ctx_id = match self.pipelines.get(&source_pipeline_id) - .map(|pipeline| pipeline.top_level_browsing_context_id) { - None => return warn!("ScriptMsg from closed pipeline {:?}.", source_pipeline_id), - Some(ctx) => ctx, + let source_top_ctx_id = match self + .pipelines + .get(&source_pipeline_id) + .map(|pipeline| pipeline.top_level_browsing_context_id) + { + None => return warn!("ScriptMsg from closed pipeline {:?}.", source_pipeline_id), + Some(ctx) => ctx, }; match content { FromScriptMsg::ForwardToEmbedder(embedder_msg) => { - self.embedder_proxy.send((Some(source_top_ctx_id), embedder_msg)); - } + self.embedder_proxy + .send((Some(source_top_ctx_id), embedder_msg)); + }, FromScriptMsg::PipelineExited => { self.handle_pipeline_exited(source_pipeline_id); - } + }, FromScriptMsg::DiscardDocument => { self.handle_discard_document(source_top_ctx_id, source_pipeline_id); - } + }, FromScriptMsg::DiscardTopLevelBrowsingContext => { self.handle_close_top_level_browsing_context(source_top_ctx_id); - } + }, FromScriptMsg::InitiateNavigateRequest(req_init, cancel_chan) => { self.handle_navigate_request(source_pipeline_id, req_init, cancel_chan); - } + }, FromScriptMsg::ScriptLoadedURLInIFrame(load_info) => { self.handle_script_loaded_url_in_iframe_msg(load_info); - } + }, FromScriptMsg::ScriptNewIFrame(load_info, layout_sender) => { self.handle_script_new_iframe(load_info, layout_sender); - } + }, FromScriptMsg::ChangeRunningAnimationsState(animation_state) => { self.handle_change_running_animations_state(source_pipeline_id, animation_state) - } + }, // Load a new page from a mouse click // If there is already a pending page (self.pending_changes), it will not be overridden; // However, if the id is not encompassed by another change, it will be. FromScriptMsg::LoadUrl(load_data, replace) => { self.handle_load_url_msg(source_top_ctx_id, source_pipeline_id, load_data, replace); - } + }, FromScriptMsg::AbortLoadUrl => { self.handle_abort_load_url_msg(source_pipeline_id); - } + }, // A page loaded has completed all parsing, script, and reflow messages have been sent. FromScriptMsg::LoadComplete => { self.handle_load_complete_msg(source_top_ctx_id, source_pipeline_id) - } + }, // Handle navigating to a fragment FromScriptMsg::NavigatedToFragment(new_url, replacement_enabled) => { self.handle_navigated_to_fragment(source_pipeline_id, new_url, replacement_enabled); - } + }, // Handle a forward or back request FromScriptMsg::TraverseHistory(direction) => { self.handle_traverse_history_msg(source_top_ctx_id, direction); - } + }, // Handle a push history state request. FromScriptMsg::PushHistoryState(history_state_id, url) => { self.handle_push_history_state_msg(source_pipeline_id, history_state_id, url); - } + }, FromScriptMsg::ReplaceHistoryState(history_state_id, url) => { self.handle_replace_history_state_msg(source_pipeline_id, history_state_id, url); - } + }, // Handle a joint session history length request. FromScriptMsg::JointSessionHistoryLength(sender) => { self.handle_joint_session_history_length(source_top_ctx_id, sender); - } + }, // Notification that the new document is ready to become active FromScriptMsg::ActivateDocument => { self.handle_activate_document_msg(source_pipeline_id); - } + }, // Update pipeline url after redirections FromScriptMsg::SetFinalUrl(final_url) => { // The script may have finished loading after we already started shutting down. @@ -1099,102 +1168,125 @@ impl Constellation } else { warn!("constellation got set final url message for dead pipeline"); } - } + }, FromScriptMsg::PostMessage(browsing_context_id, origin, data) => { self.handle_post_message_msg(browsing_context_id, origin, data); - } + }, FromScriptMsg::Focus => { self.handle_focus_msg(source_pipeline_id); - } + }, FromScriptMsg::GetClipboardContents(sender) => { let contents = match self.clipboard_ctx { - Some(ref mut ctx) => match ctx.get_contents() { - Ok(c) => c, - Err(e) => { - warn!("Error getting clipboard contents ({}), defaulting to empty string", e); - "".to_owned() - }, + Some(ref mut ctx) => { + match ctx.get_contents() { + Ok(c) => c, + Err(e) => { + warn!("Error getting clipboard contents ({}), defaulting to empty string", e); + "".to_owned() + }, + } }, None => "".to_owned(), }; if let Err(e) = sender.send(contents.to_owned()) { warn!("Failed to send clipboard ({})", e); } - } + }, FromScriptMsg::SetClipboardContents(s) => { if let Some(ref mut ctx) = self.clipboard_ctx { if let Err(e) = ctx.set_contents(s) { warn!("Error setting clipboard contents ({})", e); } } - } + }, FromScriptMsg::SetVisible(visible) => { self.handle_set_visible_msg(source_pipeline_id, visible); - } + }, FromScriptMsg::VisibilityChangeComplete(visible) => { self.handle_visibility_change_complete(source_pipeline_id, visible); - } + }, FromScriptMsg::RemoveIFrame(browsing_context_id, sender) => { let removed_pipeline_ids = self.handle_remove_iframe_msg(browsing_context_id); if let Err(e) = sender.send(removed_pipeline_ids) { warn!("Error replying to remove iframe ({})", e); } - } + }, FromScriptMsg::CreateCanvasPaintThread(size, sender) => { self.handle_create_canvas_paint_thread_msg(&size, sender) - } + }, FromScriptMsg::SetDocumentState(state) => { self.document_states.insert(source_pipeline_id, state); - } + }, FromScriptMsg::GetClientWindow(send) => { - self.compositor_proxy.send(ToCompositorMsg::GetClientWindow(send)); - } + self.compositor_proxy + .send(ToCompositorMsg::GetClientWindow(send)); + }, FromScriptMsg::GetScreenSize(send) => { - self.compositor_proxy.send(ToCompositorMsg::GetScreenSize(send)); - } + self.compositor_proxy + .send(ToCompositorMsg::GetScreenSize(send)); + }, FromScriptMsg::GetScreenAvailSize(send) => { - self.compositor_proxy.send(ToCompositorMsg::GetScreenAvailSize(send)); - } + self.compositor_proxy + .send(ToCompositorMsg::GetScreenAvailSize(send)); + }, FromScriptMsg::LogEntry(thread_name, entry) => { self.handle_log_entry(Some(source_top_ctx_id), thread_name, entry); - } - FromScriptMsg::TouchEventProcessed(result) => { - self.compositor_proxy.send(ToCompositorMsg::TouchEventProcessed(result)) - } + }, + FromScriptMsg::TouchEventProcessed(result) => self + .compositor_proxy + .send(ToCompositorMsg::TouchEventProcessed(result)), FromScriptMsg::GetBrowsingContextId(pipeline_id, sender) => { - let result = self.pipelines.get(&pipeline_id).map(|pipeline| pipeline.browsing_context_id); + let result = self + .pipelines + .get(&pipeline_id) + .map(|pipeline| pipeline.browsing_context_id); if let Err(e) = sender.send(result) { warn!("Sending reply to get browsing context failed ({:?}).", e); } - } + }, FromScriptMsg::GetParentInfo(pipeline_id, sender) => { - let result = self.pipelines.get(&pipeline_id).and_then(|pipeline| pipeline.parent_info); + let result = self + .pipelines + .get(&pipeline_id) + .and_then(|pipeline| pipeline.parent_info); if let Err(e) = sender.send(result) { warn!("Sending reply to get parent info failed ({:?}).", e); } - } + }, FromScriptMsg::GetChildBrowsingContextId(browsing_context_id, index, sender) => { - let result = self.browsing_contexts.get(&browsing_context_id) + let result = self + .browsing_contexts + .get(&browsing_context_id) .and_then(|bc| self.pipelines.get(&bc.pipeline_id)) .and_then(|pipeline| pipeline.children.get(index)) .map(|maybe_bcid| *maybe_bcid); if let Err(e) = sender.send(result) { - warn!("Sending reply to get child browsing context ID failed ({:?}).", e); + warn!( + "Sending reply to get child browsing context ID failed ({:?}).", + e + ); } - } + }, FromScriptMsg::RegisterServiceWorker(scope_things, scope) => { self.handle_register_serviceworker(scope_things, scope); - } + }, FromScriptMsg::ForwardDOMMessage(msg_vec, scope_url) => { if let Some(ref mgr) = self.swmanager_chan { let _ = mgr.send(ServiceWorkerMsg::ForwardDOMMessage(msg_vec, scope_url)); } else { warn!("Unable to forward DOMMessage for postMessage call"); } - } + }, FromScriptMsg::BroadcastStorageEvent(storage, url, key, old_value, new_value) => { - self.handle_broadcast_storage_event(source_pipeline_id, storage, url, key, old_value, new_value); - } + self.handle_broadcast_storage_event( + source_pipeline_id, + storage, + url, + key, + old_value, + new_value, + ); + }, } } @@ -1203,21 +1295,19 @@ impl Constellation match message { FromLayoutMsg::ChangeRunningAnimationsState(pipeline_id, animation_state) => { self.handle_change_running_animations_state(pipeline_id, animation_state) - } + }, // Layout sends new sizes for all subframes. This needs to be reflected by all // frame trees in the navigation context containing the subframe. FromLayoutMsg::IFrameSizes(iframe_sizes) => { self.handle_iframe_size_msg(iframe_sizes); - } + }, FromLayoutMsg::PendingPaintMetric(pipeline_id, epoch) => { self.handle_pending_paint_metric(pipeline_id, epoch); - } - FromLayoutMsg::SetCursor(cursor) => { - self.handle_set_cursor_msg(cursor) - } + }, + FromLayoutMsg::SetCursor(cursor) => self.handle_set_cursor_msg(cursor), FromLayoutMsg::ViewportConstrained(pipeline_id, constraints) => { self.handle_viewport_constrained_msg(pipeline_id, constraints); - } + }, } } @@ -1229,16 +1319,31 @@ impl Constellation } } - fn handle_broadcast_storage_event(&self, pipeline_id: PipelineId, storage: StorageType, url: ServoUrl, - key: Option, old_value: Option, new_value: Option) { + fn handle_broadcast_storage_event( + &self, + pipeline_id: PipelineId, + storage: StorageType, + url: ServoUrl, + key: Option, + old_value: Option, + new_value: Option, + ) { let origin = url.origin(); for pipeline in self.pipelines.values() { if (pipeline.id != pipeline_id) && (pipeline.url.origin() == origin) { let msg = ConstellationControlMsg::DispatchStorageEvent( - pipeline.id, storage, url.clone(), key.clone(), old_value.clone(), new_value.clone() + pipeline.id, + storage, + url.clone(), + key.clone(), + old_value.clone(), + new_value.clone(), ); if let Err(err) = pipeline.event_loop.send(msg) { - warn!("Failed to broadcast storage event to pipeline {} ({:?}).", pipeline.id, err); + warn!( + "Failed to broadcast storage event to pipeline {} ({:?}).", + pipeline.id, err + ); } } } @@ -1246,33 +1351,51 @@ impl Constellation fn handle_exit(&mut self) { // TODO: add a timer, which forces shutdown if threads aren't responsive. - if self.shutting_down { return; } + if self.shutting_down { + return; + } self.shutting_down = true; self.mem_profiler_chan.send(mem::ProfilerMsg::Exit); // Close the top-level browsing contexts - let browsing_context_ids: Vec = self.browsing_contexts.values() + let browsing_context_ids: Vec = self + .browsing_contexts + .values() .filter(|browsing_context| browsing_context.is_top_level()) .map(|browsing_context| browsing_context.id) .collect(); for browsing_context_id in browsing_context_ids { - debug!("Removing top-level browsing context {}.", browsing_context_id); + debug!( + "Removing top-level browsing context {}.", + browsing_context_id + ); self.close_browsing_context(browsing_context_id, ExitPipelineMode::Normal); } // Close any pending changes and pipelines while let Some(pending) = self.pending_changes.pop() { - debug!("Removing pending browsing context {}.", pending.browsing_context_id); + debug!( + "Removing pending browsing context {}.", + pending.browsing_context_id + ); self.close_browsing_context(pending.browsing_context_id, ExitPipelineMode::Normal); debug!("Removing pending pipeline {}.", pending.new_pipeline_id); - self.close_pipeline(pending.new_pipeline_id, DiscardBrowsingContext::Yes, ExitPipelineMode::Normal); + self.close_pipeline( + pending.new_pipeline_id, + DiscardBrowsingContext::Yes, + ExitPipelineMode::Normal, + ); } // In case there are browsing contexts which weren't attached, we close them. - let browsing_context_ids: Vec = self.browsing_contexts.keys().cloned().collect(); + let browsing_context_ids: Vec = + self.browsing_contexts.keys().cloned().collect(); for browsing_context_id in browsing_context_ids { - debug!("Removing detached browsing context {}.", browsing_context_id); + debug!( + "Removing detached browsing context {}.", + browsing_context_id + ); self.close_browsing_context(browsing_context_id, ExitPipelineMode::Normal); } @@ -1280,7 +1403,11 @@ impl Constellation let pipeline_ids: Vec = self.pipelines.keys().cloned().collect(); for pipeline_id in pipeline_ids { debug!("Removing detached pipeline {}.", pipeline_id); - self.close_pipeline(pipeline_id, DiscardBrowsingContext::Yes, ExitPipelineMode::Normal); + self.close_pipeline( + pipeline_id, + DiscardBrowsingContext::Yes, + ExitPipelineMode::Normal, + ); } } @@ -1289,10 +1416,14 @@ impl Constellation // so we can safely block on other threads, without worrying about deadlock. // Channels to receive signals when threads are done exiting. let (core_sender, core_receiver) = ipc::channel().expect("Failed to create IPC channel!"); - let (storage_sender, storage_receiver) = ipc::channel().expect("Failed to create IPC channel!"); + let (storage_sender, storage_receiver) = + ipc::channel().expect("Failed to create IPC channel!"); debug!("Exiting core resource threads."); - if let Err(e) = self.public_resource_threads.send(net_traits::CoreResourceMsg::Exit(core_sender)) { + if let Err(e) = self + .public_resource_threads + .send(net_traits::CoreResourceMsg::Exit(core_sender)) + { warn!("Exit resource thread failed ({})", e); } @@ -1309,7 +1440,10 @@ impl Constellation } debug!("Exiting storage resource threads."); - if let Err(e) = self.public_resource_threads.send(StorageThreadMsg::Exit(storage_sender)) { + if let Err(e) = self + .public_resource_threads + .send(StorageThreadMsg::Exit(storage_sender)) + { warn!("Exit storage thread failed ({})", e); } @@ -1356,7 +1490,8 @@ impl Constellation } debug!("Asking compositor to complete shutdown."); - self.compositor_proxy.send(ToCompositorMsg::ShutdownComplete); + self.compositor_proxy + .send(ToCompositorMsg::ShutdownComplete); } fn handle_pipeline_exited(&mut self, pipeline_id: PipelineId) { @@ -1367,7 +1502,9 @@ impl Constellation fn handle_send_error(&mut self, pipeline_id: PipelineId, err: IpcError) { // Treat send error the same as receiving a panic message error!("Pipeline {} send error ({}).", pipeline_id, err); - let top_level_browsing_context_id = self.pipelines.get(&pipeline_id) + let top_level_browsing_context_id = self + .pipelines + .get(&pipeline_id) .map(|pipeline| pipeline.top_level_browsing_context_id); if let Some(top_level_browsing_context_id) = top_level_browsing_context_id { let reason = format!("Send failed ({})", err); @@ -1375,11 +1512,12 @@ impl Constellation } } - fn handle_panic(&mut self, - top_level_browsing_context_id: TopLevelBrowsingContextId, - reason: String, - backtrace: Option) - { + fn handle_panic( + &mut self, + top_level_browsing_context_id: TopLevelBrowsingContextId, + reason: String, + backtrace: Option, + ) { if opts::get().hard_fail { // It's quite difficult to make Servo exit cleanly if some threads have failed. // Hard fail exists for test runners so we crash and that's good enough. @@ -1387,11 +1525,17 @@ impl Constellation process::exit(1); } - debug!("Panic handler for top-level browsing context {}: {}.", top_level_browsing_context_id, reason); + debug!( + "Panic handler for top-level browsing context {}: {}.", + top_level_browsing_context_id, reason + ); let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id); - self.embedder_proxy.send((Some(top_level_browsing_context_id), EmbedderMsg::Panic(reason, backtrace))); + self.embedder_proxy.send(( + Some(top_level_browsing_context_id), + EmbedderMsg::Panic(reason, backtrace), + )); let (window_size, pipeline_id) = { let browsing_context = self.browsing_contexts.get(&browsing_context_id); @@ -1407,9 +1551,11 @@ impl Constellation (pipeline_url, parent_info) }; - self.close_browsing_context_children(browsing_context_id, - DiscardBrowsingContext::No, - ExitPipelineMode::Force); + self.close_browsing_context_children( + browsing_context_id, + DiscardBrowsingContext::No, + ExitPipelineMode::Force, + ); let failure_url = ServoUrl::parse("about:failure").expect("infallible"); @@ -1424,8 +1570,16 @@ impl Constellation let new_pipeline_id = PipelineId::new(); let load_data = LoadData::new(failure_url, None, None, None); let sandbox = IFrameSandboxState::IFrameSandboxed; - self.new_pipeline(new_pipeline_id, browsing_context_id, top_level_browsing_context_id, parent_info, - window_size, load_data.clone(), sandbox, false); + self.new_pipeline( + new_pipeline_id, + browsing_context_id, + top_level_browsing_context_id, + parent_info, + window_size, + load_data.clone(), + sandbox, + false, + ); self.add_pending_change(SessionHistoryChange { top_level_browsing_context_id: top_level_browsing_context_id, browsing_context_id: browsing_context_id, @@ -1434,17 +1588,20 @@ impl Constellation }); } - fn handle_log_entry(&mut self, - top_level_browsing_context_id: Option, - thread_name: Option, - entry: LogEntry) - { + fn handle_log_entry( + &mut self, + top_level_browsing_context_id: Option, + thread_name: Option, + entry: LogEntry, + ) { debug!("Received log entry {:?}.", entry); match (entry, top_level_browsing_context_id) { (LogEntry::Panic(reason, backtrace), Some(top_level_browsing_context_id)) => { self.handle_panic(top_level_browsing_context_id, reason, Some(backtrace)); }, - (LogEntry::Panic(reason, _), _) | (LogEntry::Error(reason), _) | (LogEntry::Warn(reason), _) => { + (LogEntry::Panic(reason, _), _) | + (LogEntry::Error(reason), _) | + (LogEntry::Warn(reason), _) => { // VecDeque::truncate is unstable if WARNINGS_BUFFER_SIZE <= self.handled_warnings.len() { self.handled_warnings.pop_front(); @@ -1459,9 +1616,11 @@ impl Constellation match self.pipelines.get_mut(&id) { Some(ref pipeline) => { // Notify script thread - let _ = pipeline.event_loop.send(ConstellationControlMsg::WebVREvents(id, events.clone())); + let _ = pipeline + .event_loop + .send(ConstellationControlMsg::WebVREvents(id, events.clone())); }, - None => warn!("constellation got webvr event for dead pipeline") + None => warn!("constellation got webvr event for dead pipeline"), } } } @@ -1470,9 +1629,12 @@ impl Constellation let msg = ConstellationControlMsg::SendEvent(destination_pipeline_id, event); let result = match self.pipelines.get(&destination_pipeline_id) { None => { - debug!("Pipeline {:?} got event after closure.", destination_pipeline_id); + debug!( + "Pipeline {:?} got event after closure.", + destination_pipeline_id + ); return; - } + }, Some(pipeline) => pipeline.event_loop.send(msg), }; if let Err(e) = result { @@ -1480,12 +1642,19 @@ impl Constellation } } - fn handle_new_top_level_browsing_context(&mut self, url: ServoUrl, reply: IpcSender) { + fn handle_new_top_level_browsing_context( + &mut self, + url: ServoUrl, + reply: IpcSender, + ) { let window_size = self.window_size.initial_viewport; let pipeline_id = PipelineId::new(); let top_level_browsing_context_id = TopLevelBrowsingContextId::new(); if let Err(e) = reply.send(top_level_browsing_context_id) { - warn!("Failed to send newly created top level browsing context ({}).", e); + warn!( + "Failed to send newly created top level browsing context ({}).", + e + ); } let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id); let load_data = LoadData::new(url.clone(), None, None, None); @@ -1493,15 +1662,18 @@ impl Constellation if self.focus_pipeline_id.is_none() { self.focus_pipeline_id = Some(pipeline_id); } - self.joint_session_histories.insert(top_level_browsing_context_id, JointSessionHistory::new()); - self.new_pipeline(pipeline_id, - browsing_context_id, - top_level_browsing_context_id, - None, - Some(window_size), - load_data.clone(), - sandbox, - false); + self.joint_session_histories + .insert(top_level_browsing_context_id, JointSessionHistory::new()); + self.new_pipeline( + pipeline_id, + browsing_context_id, + top_level_browsing_context_id, + None, + Some(window_size), + load_data.clone(), + sandbox, + false, + ); self.add_pending_change(SessionHistoryChange { top_level_browsing_context_id: top_level_browsing_context_id, browsing_context_id: browsing_context_id, @@ -1510,13 +1682,18 @@ impl Constellation }); } - fn handle_close_top_level_browsing_context(&mut self, top_level_browsing_context_id: TopLevelBrowsingContextId) { + fn handle_close_top_level_browsing_context( + &mut self, + top_level_browsing_context_id: TopLevelBrowsingContextId, + ) { let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id); self.close_browsing_context(browsing_context_id, ExitPipelineMode::Normal); } - fn handle_iframe_size_msg(&mut self, - iframe_sizes: Vec<(BrowsingContextId, TypedSize2D)>) { + fn handle_iframe_size_msg( + &mut self, + iframe_sizes: Vec<(BrowsingContextId, TypedSize2D)>, + ) { for (browsing_context_id, size) in iframe_sizes { let window_size = WindowSizeData { initial_viewport: size, @@ -1542,22 +1719,30 @@ impl Constellation }; let result = match self.pipelines.get(&parent_id) { Some(parent) => parent.event_loop.send(msg), - None => return warn!("Parent {} browsing context loaded after closure.", parent_id), + None => { + return warn!( + "Parent {} browsing context loaded after closure.", + parent_id + ) + }, }; if let Err(e) = result { self.handle_send_error(parent_id, e); } } - fn handle_navigate_request(&self, - id: PipelineId, - req_init: RequestInit, - cancel_chan: IpcReceiver<()>) { + fn handle_navigate_request( + &self, + id: PipelineId, + req_init: RequestInit, + cancel_chan: IpcReceiver<()>, + ) { let listener = NetworkListener::new( - req_init, - id, - self.public_resource_threads.clone(), - self.network_listener_sender.clone()); + req_init, + id, + self.public_resource_threads.clone(), + self.network_listener_sender.clone(), + ); listener.initiate_fetch(Some(cancel_chan)); } @@ -1568,12 +1753,18 @@ impl Constellation // page navigation. fn handle_script_loaded_url_in_iframe_msg(&mut self, load_info: IFrameLoadInfoWithData) { let (load_data, window_size, is_private) = { - let old_pipeline = load_info.old_pipeline_id + let old_pipeline = load_info + .old_pipeline_id .and_then(|old_pipeline_id| self.pipelines.get(&old_pipeline_id)); let source_pipeline = match self.pipelines.get(&load_info.info.parent_pipeline_id) { Some(source_pipeline) => source_pipeline, - None => return warn!("Script loaded url in closed iframe {}.", load_info.info.parent_pipeline_id), + None => { + return warn!( + "Script loaded url in closed iframe {}.", + load_info.info.parent_pipeline_id + ) + }, }; // If no url is specified, reload. @@ -1589,28 +1780,33 @@ impl Constellation let is_private = load_info.info.is_private || source_pipeline.is_private; - let window_size = self.browsing_contexts.get(&load_info.info.browsing_context_id) + let window_size = self + .browsing_contexts + .get(&load_info.info.browsing_context_id) .and_then(|browsing_context| browsing_context.size); (load_data, window_size, is_private) }; let replace = if load_info.info.replace { - self.browsing_contexts.get(&load_info.info.browsing_context_id) + self.browsing_contexts + .get(&load_info.info.browsing_context_id) .map(|browsing_context| NeedsToReload::No(browsing_context.pipeline_id)) } else { None }; // Create the new pipeline, attached to the parent and push to pending changes - self.new_pipeline(load_info.info.new_pipeline_id, - load_info.info.browsing_context_id, - load_info.info.top_level_browsing_context_id, - Some(load_info.info.parent_pipeline_id), - window_size, - load_data.clone(), - load_info.sandbox, - is_private); + self.new_pipeline( + load_info.info.new_pipeline_id, + load_info.info.browsing_context_id, + load_info.info.top_level_browsing_context_id, + Some(load_info.info.parent_pipeline_id), + window_size, + load_data.clone(), + load_info.sandbox, + is_private, + ); self.add_pending_change(SessionHistoryChange { top_level_browsing_context_id: load_info.info.top_level_browsing_context_id, browsing_context_id: load_info.info.browsing_context_id, @@ -1619,9 +1815,11 @@ impl Constellation }); } - fn handle_script_new_iframe(&mut self, - load_info: IFrameLoadInfo, - layout_sender: IpcSender) { + fn handle_script_new_iframe( + &mut self, + load_info: IFrameLoadInfo, + layout_sender: IpcSender, + ) { let IFrameLoadInfo { parent_pipeline_id, new_pipeline_id, @@ -1644,17 +1842,19 @@ impl Constellation let script_sender = parent_pipeline.event_loop.clone(); - Pipeline::new(new_pipeline_id, - browsing_context_id, - top_level_browsing_context_id, - Some(parent_pipeline_id), - script_sender, - layout_sender, - self.compositor_proxy.clone(), - is_private || parent_pipeline.is_private, - url, - parent_pipeline.visible, - load_data) + Pipeline::new( + new_pipeline_id, + browsing_context_id, + top_level_browsing_context_id, + Some(parent_pipeline_id), + script_sender, + layout_sender, + self.compositor_proxy.clone(), + is_private || parent_pipeline.is_private, + url, + parent_pipeline.visible, + load_data, + ) }; assert!(!self.pipelines.contains_key(&new_pipeline_id)); @@ -1669,18 +1869,25 @@ impl Constellation } fn handle_pending_paint_metric(&self, pipeline_id: PipelineId, epoch: Epoch) { - self.compositor_proxy.send(ToCompositorMsg::PendingPaintMetric(pipeline_id, epoch)) + self.compositor_proxy + .send(ToCompositorMsg::PendingPaintMetric(pipeline_id, epoch)) } fn handle_set_cursor_msg(&mut self, cursor: CursorKind) { - self.embedder_proxy.send((None, EmbedderMsg::SetCursor(cursor))) + self.embedder_proxy + .send((None, EmbedderMsg::SetCursor(cursor))) } - fn handle_change_running_animations_state(&mut self, - pipeline_id: PipelineId, - animation_state: AnimationState) { - self.compositor_proxy.send(ToCompositorMsg::ChangeRunningAnimationsState(pipeline_id, - animation_state)) + fn handle_change_running_animations_state( + &mut self, + pipeline_id: PipelineId, + animation_state: AnimationState, + ) { + self.compositor_proxy + .send(ToCompositorMsg::ChangeRunningAnimationsState( + pipeline_id, + animation_state, + )) } fn handle_tick_animation(&mut self, pipeline_id: PipelineId, tick_type: AnimationTickType) { @@ -1689,32 +1896,49 @@ impl Constellation let msg = ConstellationControlMsg::TickAllAnimations(pipeline_id); match self.pipelines.get(&pipeline_id) { Some(pipeline) => pipeline.event_loop.send(msg), - None => return warn!("Pipeline {:?} got script tick after closure.", pipeline_id), + None => { + return warn!("Pipeline {:?} got script tick after closure.", pipeline_id) + }, } - } + }, AnimationTickType::Layout => { let msg = LayoutControlMsg::TickAnimations; match self.pipelines.get(&pipeline_id) { Some(pipeline) => pipeline.layout_chan.send(msg), - None => return warn!("Pipeline {:?} got layout tick after closure.", pipeline_id), + None => { + return warn!("Pipeline {:?} got layout tick after closure.", pipeline_id) + }, } - } + }, }; if let Err(e) = result { self.handle_send_error(pipeline_id, e); } } - fn handle_load_url_msg(&mut self, top_level_browsing_context_id: TopLevelBrowsingContextId, source_id: PipelineId, - load_data: LoadData, replace: bool) { + fn handle_load_url_msg( + &mut self, + top_level_browsing_context_id: TopLevelBrowsingContextId, + source_id: PipelineId, + load_data: LoadData, + replace: bool, + ) { self.load_url(top_level_browsing_context_id, source_id, load_data, replace); } - fn load_url(&mut self, top_level_browsing_context_id: TopLevelBrowsingContextId, source_id: PipelineId, - load_data: LoadData, replace: bool) -> Option { + fn load_url( + &mut self, + top_level_browsing_context_id: TopLevelBrowsingContextId, + source_id: PipelineId, + load_data: LoadData, + replace: bool, + ) -> Option { // Allow the embedder to handle the url itself let (chan, port) = ipc::channel().expect("Failed to create IPC channel!"); - let msg = (Some(top_level_browsing_context_id), EmbedderMsg::AllowNavigation(load_data.url.clone(), chan)); + let msg = ( + Some(top_level_browsing_context_id), + EmbedderMsg::AllowNavigation(load_data.url.clone(), chan), + ); self.embedder_proxy.send(msg); if let Ok(false) = port.recv() { return None; @@ -1732,20 +1956,25 @@ impl Constellation None => { warn!("Pipeline {} loaded after closure.", source_id); return None; - } + }, }; match parent_info { Some(parent_pipeline_id) => { // Find the script thread for the pipeline containing the iframe // and issue an iframe load through there. - let msg = ConstellationControlMsg::Navigate(parent_pipeline_id, - browsing_context_id, - load_data, - replace); + let msg = ConstellationControlMsg::Navigate( + parent_pipeline_id, + browsing_context_id, + load_data, + replace, + ); let result = match self.pipelines.get(&parent_pipeline_id) { Some(parent_pipeline) => parent_pipeline.event_loop.send(msg), None => { - warn!("Pipeline {:?} child loaded after closure", parent_pipeline_id); + warn!( + "Pipeline {:?} child loaded after closure", + parent_pipeline_id + ); return None; }, }; @@ -1753,7 +1982,7 @@ impl Constellation self.handle_send_error(parent_pipeline_id, e); } None - } + }, None => { // Make sure no pending page would be overridden. for change in &self.pending_changes { @@ -1775,26 +2004,36 @@ impl Constellation // changes would be overridden by changing the subframe associated with source_id. // Create the new pipeline - let (top_level_id, window_size, pipeline_id) = match self.browsing_contexts.get(&browsing_context_id) { - Some(context) => (context.top_level_id, context.size, context.pipeline_id), - None => { - warn!("Browsing context {} loaded after closure.", browsing_context_id); - return None; - } - }; + let (top_level_id, window_size, pipeline_id) = + match self.browsing_contexts.get(&browsing_context_id) { + Some(context) => (context.top_level_id, context.size, context.pipeline_id), + None => { + warn!( + "Browsing context {} loaded after closure.", + browsing_context_id + ); + return None; + }, + }; - let replace = if replace { Some(NeedsToReload::No(pipeline_id)) } else { None }; + let replace = if replace { + Some(NeedsToReload::No(pipeline_id)) + } else { + None + }; let new_pipeline_id = PipelineId::new(); let sandbox = IFrameSandboxState::IFrameUnsandboxed; - self.new_pipeline(new_pipeline_id, - browsing_context_id, - top_level_id, - None, - window_size, - load_data.clone(), - sandbox, - false); + self.new_pipeline( + new_pipeline_id, + browsing_context_id, + top_level_id, + None, + window_size, + load_data.clone(), + sandbox, + false, + ); self.add_pending_change(SessionHistoryChange { top_level_browsing_context_id: top_level_id, browsing_context_id: browsing_context_id, @@ -1802,32 +2041,49 @@ impl Constellation replace, }); Some(new_pipeline_id) - } + }, } } fn handle_abort_load_url_msg(&mut self, new_pipeline_id: PipelineId) { - let pending_index = self.pending_changes.iter().rposition(|change| { - change.new_pipeline_id == new_pipeline_id - }); + let pending_index = self + .pending_changes + .iter() + .rposition(|change| change.new_pipeline_id == new_pipeline_id); // If it is found, remove it from the pending changes. if let Some(pending_index) = pending_index { self.pending_changes.remove(pending_index); - self.close_pipeline(new_pipeline_id, DiscardBrowsingContext::No, ExitPipelineMode::Normal); + self.close_pipeline( + new_pipeline_id, + DiscardBrowsingContext::No, + ExitPipelineMode::Normal, + ); } } - fn handle_load_start_msg(&mut self, top_level_browsing_context_id: TopLevelBrowsingContextId, - pipeline_id: PipelineId) { - if self.pipelines.get(&pipeline_id).and_then(|p| p.parent_info).is_none() { + fn handle_load_start_msg( + &mut self, + top_level_browsing_context_id: TopLevelBrowsingContextId, + pipeline_id: PipelineId, + ) { + if self + .pipelines + .get(&pipeline_id) + .and_then(|p| p.parent_info) + .is_none() + { // Notify embedder top level document started loading. - self.embedder_proxy.send((Some(top_level_browsing_context_id), EmbedderMsg::LoadStart)); + self.embedder_proxy + .send((Some(top_level_browsing_context_id), EmbedderMsg::LoadStart)); } } - fn handle_load_complete_msg(&mut self, top_level_browsing_context_id: TopLevelBrowsingContextId, - pipeline_id: PipelineId) { + fn handle_load_complete_msg( + &mut self, + top_level_browsing_context_id: TopLevelBrowsingContextId, + pipeline_id: PipelineId, + ) { let mut webdriver_reset = false; if let Some((expected_pipeline_id, ref reply_chan)) = self.webdriver.load_channel { debug!("Sending load to WebDriver"); @@ -1844,31 +2100,48 @@ impl Constellation // has finished loading. // We need to make sure the pipeline that has finished loading is the current // pipeline and that no pending pipeline will replace the current one. - let pipeline_is_top_level_pipeline = self.browsing_contexts + let pipeline_is_top_level_pipeline = self + .browsing_contexts .get(&BrowsingContextId::from(top_level_browsing_context_id)) .map(|ctx| ctx.pipeline_id == pipeline_id) .unwrap_or(false); if pipeline_is_top_level_pipeline { // Is there any pending pipeline that will replace the current top level pipeline - let current_top_level_pipeline_will_be_replaced = self.pending_changes.iter() + let current_top_level_pipeline_will_be_replaced = self + .pending_changes + .iter() .any(|change| change.browsing_context_id == top_level_browsing_context_id); if !current_top_level_pipeline_will_be_replaced { // Notify embedder and compositor top level document finished loading. - self.compositor_proxy.send(ToCompositorMsg::LoadComplete(top_level_browsing_context_id)); - self.embedder_proxy.send((Some(top_level_browsing_context_id), EmbedderMsg::LoadComplete)); + self.compositor_proxy + .send(ToCompositorMsg::LoadComplete(top_level_browsing_context_id)); + self.embedder_proxy.send(( + Some(top_level_browsing_context_id), + EmbedderMsg::LoadComplete, + )); } } self.handle_subframe_loaded(pipeline_id); } - fn handle_navigated_to_fragment(&mut self, pipeline_id: PipelineId, new_url: ServoUrl, replacement_enabled: bool) { + fn handle_navigated_to_fragment( + &mut self, + pipeline_id: PipelineId, + new_url: ServoUrl, + replacement_enabled: bool, + ) { let (top_level_browsing_context_id, old_url) = match self.pipelines.get_mut(&pipeline_id) { Some(pipeline) => { let old_url = replace(&mut pipeline.url, new_url.clone()); (pipeline.top_level_browsing_context_id, old_url) - } - None => return warn!("Pipeline {} navigated to fragment after closure", pipeline_id), + }, + None => { + return warn!( + "Pipeline {} navigated to fragment after closure", + pipeline_id + ) + }, }; if !replacement_enabled { @@ -1877,15 +2150,17 @@ impl Constellation new_url, old_url, }; - self.get_joint_session_history(top_level_browsing_context_id).push_diff(diff); + self.get_joint_session_history(top_level_browsing_context_id) + .push_diff(diff); self.notify_history_changed(top_level_browsing_context_id); } } - fn handle_traverse_history_msg(&mut self, - top_level_browsing_context_id: TopLevelBrowsingContextId, - direction: TraversalDirection) - { + fn handle_traverse_history_msg( + &mut self, + top_level_browsing_context_id: TopLevelBrowsingContextId, + direction: TraversalDirection, + ) { let mut browsing_context_changes = HashMap::::new(); let mut pipeline_changes = HashMap::, ServoUrl)>::new(); let mut url_to_load = HashMap::::new(); @@ -1899,10 +2174,19 @@ impl Constellation return warn!("Cannot traverse that far into the future."); } - for diff in session_history.future.drain(future_length - forward..).rev() { + for diff in session_history + .future + .drain(future_length - forward..) + .rev() + { match diff { - SessionHistoryDiff::BrowsingContextDiff { browsing_context_id, ref new_reloader, .. } => { - browsing_context_changes.insert(browsing_context_id, new_reloader.clone()); + SessionHistoryDiff::BrowsingContextDiff { + browsing_context_id, + ref new_reloader, + .. + } => { + browsing_context_changes + .insert(browsing_context_id, new_reloader.clone()); }, SessionHistoryDiff::PipelineDiff { ref pipeline_reloader, @@ -1911,7 +2195,10 @@ impl Constellation .. } => match *pipeline_reloader { NeedsToReload::No(pipeline_id) => { - pipeline_changes.insert(pipeline_id, (Some(new_history_state_id), new_url.clone())); + pipeline_changes.insert( + pipeline_id, + (Some(new_history_state_id), new_url.clone()), + ); }, NeedsToReload::Yes(pipeline_id, ..) => { url_to_load.insert(pipeline_id, new_url.clone()); @@ -1923,7 +2210,9 @@ impl Constellation .. } => match *pipeline_reloader { NeedsToReload::No(pipeline_id) => { - let state = pipeline_changes.get(&pipeline_id).and_then(|change| change.0); + let state = pipeline_changes + .get(&pipeline_id) + .and_then(|change| change.0); pipeline_changes.insert(pipeline_id, (state, new_url.clone())); }, NeedsToReload::Yes(pipeline_id, ..) => { @@ -1943,8 +2232,13 @@ impl Constellation for diff in session_history.past.drain(past_length - back..).rev() { match diff { - SessionHistoryDiff::BrowsingContextDiff { browsing_context_id, ref old_reloader, .. } => { - browsing_context_changes.insert(browsing_context_id, old_reloader.clone()); + SessionHistoryDiff::BrowsingContextDiff { + browsing_context_id, + ref old_reloader, + .. + } => { + browsing_context_changes + .insert(browsing_context_id, old_reloader.clone()); }, SessionHistoryDiff::PipelineDiff { ref pipeline_reloader, @@ -1953,7 +2247,10 @@ impl Constellation .. } => match *pipeline_reloader { NeedsToReload::No(pipeline_id) => { - pipeline_changes.insert(pipeline_id, (old_history_state_id, old_url.clone())); + pipeline_changes.insert( + pipeline_id, + (old_history_state_id, old_url.clone()), + ); }, NeedsToReload::Yes(pipeline_id, ..) => { url_to_load.insert(pipeline_id, old_url.clone()); @@ -1965,7 +2262,9 @@ impl Constellation .. } => match *pipeline_reloader { NeedsToReload::No(pipeline_id) => { - let state = pipeline_changes.get(&pipeline_id).and_then(|change| change.0); + let state = pipeline_changes + .get(&pipeline_id) + .and_then(|change| change.0); pipeline_changes.insert(pipeline_id, (state, old_url.clone())); }, NeedsToReload::Yes(pipeline_id, ..) => { @@ -1975,7 +2274,7 @@ impl Constellation } session_history.future.push(diff); } - } + }, } } @@ -1998,41 +2297,57 @@ impl Constellation self.update_frame_tree_if_active(top_level_browsing_context_id); } - fn update_browsing_context(&mut self, browsing_context_id: BrowsingContextId, new_reloader: NeedsToReload) { + fn update_browsing_context( + &mut self, + browsing_context_id: BrowsingContextId, + new_reloader: NeedsToReload, + ) { let new_pipeline_id = match new_reloader { NeedsToReload::No(pipeline_id) => pipeline_id, NeedsToReload::Yes(pipeline_id, load_data) => { - debug!("Reloading document {} in browsing context {}.", pipeline_id, browsing_context_id); + debug!( + "Reloading document {} in browsing context {}.", + pipeline_id, browsing_context_id + ); // TODO: Save the sandbox state so it can be restored here. let sandbox = IFrameSandboxState::IFrameUnsandboxed; let new_pipeline_id = PipelineId::new(); let (top_level_id, parent_info, window_size, is_private) = - match self.browsing_contexts.get(&browsing_context_id) - { - Some(browsing_context) => match self.pipelines.get(&browsing_context.pipeline_id) { - Some(pipeline) => ( - browsing_context.top_level_id, - pipeline.parent_info, - browsing_context.size, - pipeline.is_private - ), - None => ( - browsing_context.top_level_id, - None, - browsing_context.size, - false - ), - }, - None => return warn!("No browsing context to traverse!"), - }; - self.new_pipeline(new_pipeline_id, browsing_context_id, top_level_id, parent_info, - window_size, load_data.clone(), sandbox, is_private); + match self.browsing_contexts.get(&browsing_context_id) { + Some(browsing_context) => { + match self.pipelines.get(&browsing_context.pipeline_id) { + Some(pipeline) => ( + browsing_context.top_level_id, + pipeline.parent_info, + browsing_context.size, + pipeline.is_private, + ), + None => ( + browsing_context.top_level_id, + None, + browsing_context.size, + false, + ), + } + }, + None => return warn!("No browsing context to traverse!"), + }; + self.new_pipeline( + new_pipeline_id, + browsing_context_id, + top_level_id, + parent_info, + window_size, + load_data.clone(), + sandbox, + is_private, + ); self.add_pending_change(SessionHistoryChange { top_level_browsing_context_id: top_level_id, browsing_context_id: browsing_context_id, new_pipeline_id: new_pipeline_id, - replace: Some(NeedsToReload::Yes(pipeline_id, load_data.clone())) + replace: Some(NeedsToReload::Yes(pipeline_id, load_data.clone())), }); return; }, @@ -2045,20 +2360,35 @@ impl Constellation old_pipeline_id }, None => { - return warn!("Browsing context {} was closed during traversal", browsing_context_id); - } + return warn!( + "Browsing context {} was closed during traversal", + browsing_context_id + ); + }, }; - let parent_info = self.pipelines.get(&old_pipeline_id).and_then(|pipeline| pipeline.parent_info); + let parent_info = self + .pipelines + .get(&old_pipeline_id) + .and_then(|pipeline| pipeline.parent_info); self.update_activity(old_pipeline_id); self.update_activity(new_pipeline_id); if let Some(parent_pipeline_id) = parent_info { - let msg = ConstellationControlMsg::UpdatePipelineId(parent_pipeline_id, browsing_context_id, - new_pipeline_id, UpdatePipelineIdReason::Traversal); + let msg = ConstellationControlMsg::UpdatePipelineId( + parent_pipeline_id, + browsing_context_id, + new_pipeline_id, + UpdatePipelineIdReason::Traversal, + ); let result = match self.pipelines.get(&parent_pipeline_id) { - None => return warn!("Pipeline {} child traversed after closure", parent_pipeline_id), + None => { + return warn!( + "Pipeline {} child traversed after closure", + parent_pipeline_id + ) + }, Some(pipeline) => pipeline.event_loop.send(msg), }; if let Err(e) = result { @@ -2067,11 +2397,25 @@ impl Constellation } } - fn update_pipeline(&mut self, pipeline_id: PipelineId, history_state_id: Option, url: ServoUrl) { + fn update_pipeline( + &mut self, + pipeline_id: PipelineId, + history_state_id: Option, + url: ServoUrl, + ) { let result = match self.pipelines.get_mut(&pipeline_id) { - None => return warn!("Pipeline {} history state updated after closure", pipeline_id), + None => { + return warn!( + "Pipeline {} history state updated after closure", + pipeline_id + ) + }, Some(pipeline) => { - let msg = ConstellationControlMsg::UpdateHistoryState(pipeline_id, history_state_id, url.clone()); + let msg = ConstellationControlMsg::UpdateHistoryState( + pipeline_id, + history_state_id, + url.clone(), + ); pipeline.history_state_id = history_state_id; pipeline.url = url; pipeline.event_loop.send(msg) @@ -2082,11 +2426,14 @@ impl Constellation } } - fn handle_joint_session_history_length(&self, - top_level_browsing_context_id: TopLevelBrowsingContextId, - sender: IpcSender) - { - let length = self.joint_session_histories.get(&top_level_browsing_context_id) + fn handle_joint_session_history_length( + &self, + top_level_browsing_context_id: TopLevelBrowsingContextId, + sender: IpcSender, + ) { + let length = self + .joint_session_histories + .get(&top_level_browsing_context_id) .map(JointSessionHistory::history_length) .unwrap_or(1); let _ = sender.send(length as u32); @@ -2096,18 +2443,28 @@ impl Constellation &mut self, pipeline_id: PipelineId, history_state_id: HistoryStateId, - url: ServoUrl) - { - let (top_level_browsing_context_id, old_state_id, old_url) = match self.pipelines.get_mut(&pipeline_id) { - Some(pipeline) => { - let old_history_state_id = pipeline.history_state_id; - let old_url = replace(&mut pipeline.url, url.clone()); - pipeline.history_state_id = Some(history_state_id); - pipeline.history_states.insert(history_state_id); - (pipeline.top_level_browsing_context_id, old_history_state_id, old_url) - } - None => return warn!("Push history state {} for closed pipeline {}", history_state_id, pipeline_id), - }; + url: ServoUrl, + ) { + let (top_level_browsing_context_id, old_state_id, old_url) = + match self.pipelines.get_mut(&pipeline_id) { + Some(pipeline) => { + let old_history_state_id = pipeline.history_state_id; + let old_url = replace(&mut pipeline.url, url.clone()); + pipeline.history_state_id = Some(history_state_id); + pipeline.history_states.insert(history_state_id); + ( + pipeline.top_level_browsing_context_id, + old_history_state_id, + old_url, + ) + }, + None => { + return warn!( + "Push history state {} for closed pipeline {}", + history_state_id, pipeline_id + ) + }, + }; let diff = SessionHistoryDiff::PipelineDiff { pipeline_reloader: NeedsToReload::No(pipeline_id), @@ -2116,7 +2473,8 @@ impl Constellation old_history_state_id: old_state_id, old_url: old_url, }; - self.get_joint_session_history(top_level_browsing_context_id).push_diff(diff); + self.get_joint_session_history(top_level_browsing_context_id) + .push_diff(diff); self.notify_history_changed(top_level_browsing_context_id); } @@ -2124,15 +2482,20 @@ impl Constellation &mut self, pipeline_id: PipelineId, history_state_id: HistoryStateId, - url: ServoUrl) - { + url: ServoUrl, + ) { let top_level_browsing_context_id = match self.pipelines.get_mut(&pipeline_id) { Some(pipeline) => { pipeline.history_state_id = Some(history_state_id); pipeline.url = url.clone(); pipeline.top_level_browsing_context_id - } - None => return warn!("Replace history state {} for closed pipeline {}", history_state_id, pipeline_id), + }, + None => { + return warn!( + "Replace history state {} for closed pipeline {}", + history_state_id, pipeline_id + ) + }, }; let session_history = self.get_joint_session_history(top_level_browsing_context_id); @@ -2148,7 +2511,9 @@ impl Constellation let msg = ConstellationControlMsg::SendEvent(pipeline_id, event); let result = match self.pipelines.get(&pipeline_id) { Some(pipeline) => pipeline.event_loop.send(msg), - None => return debug!("Pipeline {:?} got key event after closure.", pipeline_id), + None => { + return debug!("Pipeline {:?} got key event after closure.", pipeline_id) + }, }; if let Err(e) = result { self.handle_send_error(pipeline_id, e); @@ -2157,7 +2522,7 @@ impl Constellation None => { let event = (None, EmbedderMsg::KeyEvent(ch, key, state, mods)); self.embedder_proxy.clone().send(event); - } + }, } } @@ -2165,7 +2530,12 @@ impl Constellation let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id); let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) { Some(browsing_context) => browsing_context.pipeline_id, - None => return warn!("Browsing context {} got reload event after closure.", browsing_context_id), + None => { + return warn!( + "Browsing context {} got reload event after closure.", + browsing_context_id + ) + }, }; let msg = ConstellationControlMsg::Reload(pipeline_id); let result = match self.pipelines.get(&pipeline_id) { @@ -2177,13 +2547,19 @@ impl Constellation } } - fn handle_post_message_msg(&mut self, - browsing_context_id: BrowsingContextId, - origin: Option, - data: Vec) - { + fn handle_post_message_msg( + &mut self, + browsing_context_id: BrowsingContextId, + origin: Option, + data: Vec, + ) { let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) { - None => return warn!("postMessage to closed browsing_context {}.", browsing_context_id), + None => { + return warn!( + "postMessage to closed browsing_context {}.", + browsing_context_id + ) + }, Some(browsing_context) => browsing_context.pipeline_id, }; let msg = ConstellationControlMsg::PostMessage(pipeline_id, origin, data); @@ -2196,12 +2572,19 @@ impl Constellation } } - fn handle_get_pipeline(&mut self, - browsing_context_id: BrowsingContextId, - resp_chan: IpcSender>) { - let current_pipeline_id = self.browsing_contexts.get(&browsing_context_id) + fn handle_get_pipeline( + &mut self, + browsing_context_id: BrowsingContextId, + resp_chan: IpcSender>, + ) { + let current_pipeline_id = self + .browsing_contexts + .get(&browsing_context_id) .map(|browsing_context| browsing_context.pipeline_id); - let pipeline_id_loaded = self.pending_changes.iter().rev() + let pipeline_id_loaded = self + .pending_changes + .iter() + .rev() .find(|x| x.browsing_context_id == browsing_context_id) .map(|x| x.new_pipeline_id) .or(current_pipeline_id); @@ -2210,10 +2593,15 @@ impl Constellation } } - fn handle_get_browsing_context(&mut self, - pipeline_id: PipelineId, - resp_chan: IpcSender>) { - let browsing_context_id = self.pipelines.get(&pipeline_id).map(|pipeline| pipeline.browsing_context_id); + fn handle_get_browsing_context( + &mut self, + pipeline_id: PipelineId, + resp_chan: IpcSender>, + ) { + let browsing_context_id = self + .pipelines + .get(&pipeline_id) + .map(|pipeline| pipeline.browsing_context_id); if let Err(e) = resp_chan.send(browsing_context_id) { warn!("Failed get_browsing_context response ({}).", e); } @@ -2249,9 +2637,14 @@ impl Constellation self.focus_parent_pipeline(pipeline_id); } - fn handle_remove_iframe_msg(&mut self, browsing_context_id: BrowsingContextId) -> Vec { - let result = self.all_descendant_browsing_contexts_iter(browsing_context_id) - .flat_map(|browsing_context| browsing_context.pipelines.iter().cloned()).collect(); + fn handle_remove_iframe_msg( + &mut self, + browsing_context_id: BrowsingContextId, + ) -> Vec { + let result = self + .all_descendant_browsing_contexts_iter(browsing_context_id) + .flat_map(|browsing_context| browsing_context.pipelines.iter().cloned()) + .collect(); self.close_browsing_context(browsing_context_id, ExitPipelineMode::Normal); result } @@ -2259,11 +2652,18 @@ impl Constellation fn handle_set_visible_msg(&mut self, pipeline_id: PipelineId, visible: bool) { let browsing_context_id = match self.pipelines.get(&pipeline_id) { Some(pipeline) => pipeline.browsing_context_id, - None => return warn!("No browsing context associated with pipeline {:?}", pipeline_id), + None => { + return warn!( + "No browsing context associated with pipeline {:?}", + pipeline_id + ) + }, }; - let child_pipeline_ids: Vec = self.all_descendant_browsing_contexts_iter(browsing_context_id) - .flat_map(|browsing_context| browsing_context.pipelines.iter().cloned()).collect(); + let child_pipeline_ids: Vec = self + .all_descendant_browsing_contexts_iter(browsing_context_id) + .flat_map(|browsing_context| browsing_context.pipelines.iter().cloned()) + .collect(); for id in child_pipeline_ids { if let Some(pipeline) = self.pipelines.get_mut(&id) { @@ -2278,9 +2678,11 @@ impl Constellation Some(pipeline) => (pipeline.browsing_context_id, pipeline.parent_info), }; if let Some(parent_pipeline_id) = parent_pipeline_info { - let visibility_msg = ConstellationControlMsg::NotifyVisibilityChange(parent_pipeline_id, - browsing_context_id, - visibility); + let visibility_msg = ConstellationControlMsg::NotifyVisibilityChange( + parent_pipeline_id, + browsing_context_id, + visibility, + ); let result = match self.pipelines.get(&parent_pipeline_id) { None => return warn!("Parent pipeline {:?} closed", parent_pipeline_id), Some(parent_pipeline) => parent_pipeline.event_loop.send(visibility_msg), @@ -2293,21 +2695,21 @@ impl Constellation } fn handle_create_canvas_paint_thread_msg( - &mut self, - size: &Size2D, - response_sender: IpcSender<(IpcSender, CanvasId)>) { + &mut self, + size: &Size2D, + response_sender: IpcSender<(IpcSender, CanvasId)>, + ) { let webrender_api = self.webrender_api_sender.clone(); let sender = self.canvas_chan.clone(); - let (canvas_id_sender, canvas_id_receiver) = ipc::channel::().expect("ipc channel failure"); + let (canvas_id_sender, canvas_id_receiver) = + ipc::channel::().expect("ipc channel failure"); - if let Err(e) = sender.send( - CanvasMsg::Create( - canvas_id_sender, - *size, - webrender_api, - opts::get().enable_canvas_antialiasing - ) - ) { + if let Err(e) = sender.send(CanvasMsg::Create( + canvas_id_sender, + *size, + webrender_api, + opts::get().enable_canvas_antialiasing, + )) { return warn!("Create canvas paint thread failed ({})", e); } let canvas_id = match canvas_id_receiver.recv() { @@ -2324,11 +2726,14 @@ impl Constellation // and pass the event to that script thread. match msg { WebDriverCommandMsg::GetWindowSize(_, reply) => { - let _ = reply.send(self.window_size); + let _ = reply.send(self.window_size); }, WebDriverCommandMsg::SetWindowSize(top_level_browsing_context_id, size, reply) => { self.webdriver.resize_channel = Some(reply); - self.embedder_proxy.send((Some(top_level_browsing_context_id), EmbedderMsg::ResizeTo(size))); + self.embedder_proxy.send(( + Some(top_level_browsing_context_id), + EmbedderMsg::ResizeTo(size), + )); }, WebDriverCommandMsg::LoadUrl(top_level_browsing_context_id, load_data, reply) => { self.load_url_for_webdriver(top_level_browsing_context_id, load_data, reply, false); @@ -2336,18 +2741,35 @@ impl Constellation WebDriverCommandMsg::Refresh(top_level_browsing_context_id, reply) => { let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id); let load_data = match self.browsing_contexts.get(&browsing_context_id) { - Some(browsing_context) => match self.pipelines.get(&browsing_context.pipeline_id) { - Some(pipeline) => pipeline.load_data.clone(), - None => return warn!("Pipeline {} refresh after closure.", browsing_context.pipeline_id), + Some(browsing_context) => { + match self.pipelines.get(&browsing_context.pipeline_id) { + Some(pipeline) => pipeline.load_data.clone(), + None => { + return warn!( + "Pipeline {} refresh after closure.", + browsing_context.pipeline_id + ) + }, + } + }, + None => { + return warn!( + "Browsing context {} Refresh after closure.", + browsing_context_id + ) }, - None => return warn!("Browsing context {} Refresh after closure.", browsing_context_id), }; self.load_url_for_webdriver(top_level_browsing_context_id, load_data, reply, true); - } + }, WebDriverCommandMsg::ScriptCommand(browsing_context_id, cmd) => { let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) { Some(browsing_context) => browsing_context.pipeline_id, - None => return warn!("Browsing context {} ScriptCommand after closure.", browsing_context_id), + None => { + return warn!( + "Browsing context {} ScriptCommand after closure.", + browsing_context_id + ) + }, }; let control_msg = ConstellationControlMsg::WebDriverScriptCommand(pipeline_id, cmd); let result = match self.pipelines.get(&pipeline_id) { @@ -2361,7 +2783,12 @@ impl Constellation WebDriverCommandMsg::SendKeys(browsing_context_id, cmd) => { let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) { Some(browsing_context) => browsing_context.pipeline_id, - None => return warn!("Browsing context {} SendKeys after closure.", browsing_context_id), + None => { + return warn!( + "Browsing context {} SendKeys after closure.", + browsing_context_id + ) + }, }; let event_loop = match self.pipelines.get(&pipeline_id) { Some(pipeline) => pipeline.event_loop.clone(), @@ -2376,7 +2803,8 @@ impl Constellation } }, WebDriverCommandMsg::TakeScreenshot(_, reply) => { - self.compositor_proxy.send(ToCompositorMsg::CreatePng(reply)); + self.compositor_proxy + .send(ToCompositorMsg::CreatePng(reply)); }, } } @@ -2387,32 +2815,55 @@ impl Constellation // the current entry and the future entries. // LoadData of inner frames are ignored and replaced with the LoadData of the parent. - let session_history = match self.joint_session_histories.get(&top_level_browsing_context_id) { + let session_history = match self + .joint_session_histories + .get(&top_level_browsing_context_id) + { Some(session_history) => session_history, - None => return warn!("Session history does not exist for {}", top_level_browsing_context_id), + None => { + return warn!( + "Session history does not exist for {}", + top_level_browsing_context_id + ) + }, }; let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id); let browsing_context = match self.browsing_contexts.get(&browsing_context_id) { Some(browsing_context) => browsing_context, - None => return warn!("notify_history_changed error after top-level browsing context closed."), + None => { + return warn!( + "notify_history_changed error after top-level browsing context closed." + ) + }, }; let current_load_data = match self.pipelines.get(&browsing_context.pipeline_id) { Some(pipeline) => pipeline.load_data.clone(), - None => return warn!("Pipeline {} refresh after closure.", browsing_context.pipeline_id), + None => { + return warn!( + "Pipeline {} refresh after closure.", + browsing_context.pipeline_id + ) + }, }; // If LoadData was ignored, use the LoadData of the previous SessionHistoryEntry, which // is the LoadData of the parent browsing context. - let resolve_load_data_future = |previous_load_data: &mut LoadData, diff: &SessionHistoryDiff| { - match *diff { - SessionHistoryDiff::BrowsingContextDiff { browsing_context_id, ref new_reloader, .. } => { + let resolve_load_data_future = + |previous_load_data: &mut LoadData, diff: &SessionHistoryDiff| match *diff { + SessionHistoryDiff::BrowsingContextDiff { + browsing_context_id, + ref new_reloader, + .. + } => { if browsing_context_id == top_level_browsing_context_id { let load_data = match *new_reloader { - NeedsToReload::No(pipeline_id) => match self.pipelines.get(&pipeline_id) { - Some(pipeline) => pipeline.load_data.clone(), - None => previous_load_data.clone(), + NeedsToReload::No(pipeline_id) => { + match self.pipelines.get(&pipeline_id) { + Some(pipeline) => pipeline.load_data.clone(), + None => previous_load_data.clone(), + } }, NeedsToReload::Yes(_, ref load_data) => load_data.clone(), }; @@ -2423,17 +2874,22 @@ impl Constellation } }, _ => Some(previous_load_data.clone()), - } - }; + }; - let resolve_load_data_past = |previous_load_data: &mut LoadData, diff: &SessionHistoryDiff| { - match *diff { - SessionHistoryDiff::BrowsingContextDiff { browsing_context_id, ref old_reloader, .. } => { + let resolve_load_data_past = + |previous_load_data: &mut LoadData, diff: &SessionHistoryDiff| match *diff { + SessionHistoryDiff::BrowsingContextDiff { + browsing_context_id, + ref old_reloader, + .. + } => { if browsing_context_id == top_level_browsing_context_id { let load_data = match *old_reloader { - NeedsToReload::No(pipeline_id) => match self.pipelines.get(&pipeline_id) { - Some(pipeline) => pipeline.load_data.clone(), - None => previous_load_data.clone(), + NeedsToReload::No(pipeline_id) => { + match self.pipelines.get(&pipeline_id) { + Some(pipeline) => pipeline.load_data.clone(), + None => previous_load_data.clone(), + } }, NeedsToReload::Yes(_, ref load_data) => load_data.clone(), }; @@ -2444,11 +2900,14 @@ impl Constellation } }, _ => Some(previous_load_data.clone()), - } - }; + }; - let mut entries: Vec = session_history.past.iter().rev() - .scan(current_load_data.clone(), &resolve_load_data_past).collect(); + let mut entries: Vec = session_history + .past + .iter() + .rev() + .scan(current_load_data.clone(), &resolve_load_data_past) + .collect(); entries.reverse(); @@ -2456,31 +2915,53 @@ impl Constellation entries.push(current_load_data.clone()); - entries.extend(session_history.future.iter().rev() - .scan(current_load_data.clone(), &resolve_load_data_future)); + entries.extend( + session_history + .future + .iter() + .rev() + .scan(current_load_data.clone(), &resolve_load_data_future), + ); let urls = entries.iter().map(|entry| entry.url.clone()).collect(); - let msg = (Some(top_level_browsing_context_id), EmbedderMsg::HistoryChanged(urls, current_index)); + let msg = ( + Some(top_level_browsing_context_id), + EmbedderMsg::HistoryChanged(urls, current_index), + ); self.embedder_proxy.send(msg); } - fn load_url_for_webdriver(&mut self, - top_level_browsing_context_id: TopLevelBrowsingContextId, - load_data: LoadData, - reply: IpcSender, - replace: bool) - { + fn load_url_for_webdriver( + &mut self, + top_level_browsing_context_id: TopLevelBrowsingContextId, + load_data: LoadData, + reply: IpcSender, + replace: bool, + ) { let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id); let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) { Some(browsing_context) => browsing_context.pipeline_id, - None => return warn!("Webdriver load for closed browsing context {}.", browsing_context_id), + None => { + return warn!( + "Webdriver load for closed browsing context {}.", + browsing_context_id + ) + }, }; - if let Some(new_pipeline_id) = self.load_url(top_level_browsing_context_id, pipeline_id, load_data, replace) { + if let Some(new_pipeline_id) = self.load_url( + top_level_browsing_context_id, + pipeline_id, + load_data, + replace, + ) { self.webdriver.load_channel = Some((new_pipeline_id, reply)); } } fn change_session_history(&mut self, change: SessionHistoryChange) { - debug!("Setting browsing context {} to be pipeline {}.", change.browsing_context_id, change.new_pipeline_id); + debug!( + "Setting browsing context {} to be pipeline {}.", + change.browsing_context_id, change.new_pipeline_id + ); // If the currently focused pipeline is the one being changed (or a child // of the pipeline being changed) then update the focus pipeline to be @@ -2489,26 +2970,28 @@ impl Constellation self.focus_pipeline_id = Some(change.new_pipeline_id); } - - let (old_pipeline_id, top_level_id) = match self.browsing_contexts.get_mut(&change.browsing_context_id) { - Some(browsing_context) => { - debug!("Adding pipeline to existing browsing context."); - let old_pipeline_id = browsing_context.pipeline_id; - browsing_context.pipelines.insert(change.new_pipeline_id); - browsing_context.update_current_entry(change.new_pipeline_id); - (Some(old_pipeline_id), Some(browsing_context.top_level_id)) - }, - None => { - debug!("Adding pipeline to new browsing context."); - (None, None) - } - }; + let (old_pipeline_id, top_level_id) = + match self.browsing_contexts.get_mut(&change.browsing_context_id) { + Some(browsing_context) => { + debug!("Adding pipeline to existing browsing context."); + let old_pipeline_id = browsing_context.pipeline_id; + browsing_context.pipelines.insert(change.new_pipeline_id); + browsing_context.update_current_entry(change.new_pipeline_id); + (Some(old_pipeline_id), Some(browsing_context.top_level_id)) + }, + None => { + debug!("Adding pipeline to new browsing context."); + (None, None) + }, + }; match old_pipeline_id { None => { - self.new_browsing_context(change.browsing_context_id, + self.new_browsing_context( + change.browsing_context_id, change.top_level_browsing_context_id, - change.new_pipeline_id); + change.new_pipeline_id, + ); self.update_activity(change.new_pipeline_id); self.notify_history_changed(change.top_level_browsing_context_id); }, @@ -2516,19 +2999,27 @@ impl Constellation // https://html.spec.whatwg.org/multipage/#unload-a-document self.unload_document(old_pipeline_id); // Deactivate the old pipeline, and activate the new one. - let (pipelines_to_close, states_to_close) = if let Some(replace_reloader) = change.replace { - let session_history = self.joint_session_histories - .entry(change.top_level_browsing_context_id).or_insert(JointSessionHistory::new()); - session_history.replace_reloader(replace_reloader.clone(), - NeedsToReload::No(change.new_pipeline_id)); + let (pipelines_to_close, states_to_close) = if let Some(replace_reloader) = + change.replace + { + let session_history = self + .joint_session_histories + .entry(change.top_level_browsing_context_id) + .or_insert(JointSessionHistory::new()); + session_history.replace_reloader( + replace_reloader.clone(), + NeedsToReload::No(change.new_pipeline_id), + ); match replace_reloader { NeedsToReload::No(pipeline_id) => (Some(vec![pipeline_id]), None), NeedsToReload::Yes(..) => (None, None), } } else { - let session_history = self.joint_session_histories - .entry(change.top_level_browsing_context_id).or_insert(JointSessionHistory::new()); + let session_history = self + .joint_session_histories + .entry(change.top_level_browsing_context_id) + .or_insert(JointSessionHistory::new()); let diff = SessionHistoryDiff::BrowsingContextDiff { browsing_context_id: change.browsing_context_id, new_reloader: NeedsToReload::No(change.new_pipeline_id), @@ -2547,9 +3038,14 @@ impl Constellation pipelines_to_close.push(pipeline_id); } }, - SessionHistoryDiff::PipelineDiff { pipeline_reloader, new_history_state_id, .. } => { + SessionHistoryDiff::PipelineDiff { + pipeline_reloader, + new_history_state_id, + .. + } => { if let Some(pipeline_id) = pipeline_reloader.alive_pipeline_id() { - let states = states_to_close.entry(pipeline_id).or_insert(Vec::new()); + let states = + states_to_close.entry(pipeline_id).or_insert(Vec::new()); states.push(new_history_state_id); } }, @@ -2567,7 +3063,12 @@ impl Constellation for (pipeline_id, states) in states_to_close { let msg = ConstellationControlMsg::RemoveHistoryStates(pipeline_id, states); let result = match self.pipelines.get(&pipeline_id) { - None => return warn!("Pipeline {} removed history states after closure", pipeline_id), + None => { + return warn!( + "Pipeline {} removed history states after closure", + pipeline_id + ) + }, Some(pipeline) => pipeline.event_loop.send(msg), }; if let Err(e) = result { @@ -2578,12 +3079,16 @@ impl Constellation if let Some(pipelines_to_close) = pipelines_to_close { for pipeline_id in pipelines_to_close { - self.close_pipeline(pipeline_id, DiscardBrowsingContext::No, ExitPipelineMode::Normal); + self.close_pipeline( + pipeline_id, + DiscardBrowsingContext::No, + ExitPipelineMode::Normal, + ); } } self.notify_history_changed(change.top_level_browsing_context_id); - } + }, } if let Some(top_level_id) = top_level_id { @@ -2598,12 +3103,18 @@ impl Constellation let pipelines_to_evict = { let session_history = self.get_joint_session_history(top_level_browsing_context_id); - let history_length = PREFS.get("session-history.max-length").as_u64().unwrap_or(20) as usize; + let history_length = PREFS + .get("session-history.max-length") + .as_u64() + .unwrap_or(20) as usize; // The past is stored with older entries at the front. // We reverse the iter so that newer entries are at the front and then // skip _n_ entries and evict the remaining entries. - let mut pipelines_to_evict = session_history.past.iter().rev() + let mut pipelines_to_evict = session_history + .past + .iter() + .rev() .map(|diff| diff.alive_old_pipeline()) .skip(history_length) .filter_map(|maybe_pipeline| maybe_pipeline) @@ -2611,10 +3122,15 @@ impl Constellation // The future is stored with oldest entries front, so we must // reverse the iterator like we do for the `past`. - pipelines_to_evict.extend(session_history.future.iter().rev() - .map(|diff| diff.alive_new_pipeline()) - .skip(history_length) - .filter_map(|maybe_pipeline| maybe_pipeline)); + pipelines_to_evict.extend( + session_history + .future + .iter() + .rev() + .map(|diff| diff.alive_new_pipeline()) + .skip(history_length) + .filter_map(|maybe_pipeline| maybe_pipeline), + ); pipelines_to_evict }; @@ -2631,7 +3147,11 @@ impl Constellation }; dead_pipelines.push((evicted_id, NeedsToReload::Yes(evicted_id, load_data))); - self.close_pipeline(evicted_id, DiscardBrowsingContext::No, ExitPipelineMode::Normal); + self.close_pipeline( + evicted_id, + DiscardBrowsingContext::No, + ExitPipelineMode::Normal, + ); } let session_history = self.get_joint_session_history(top_level_browsing_context_id); @@ -2648,17 +3168,22 @@ impl Constellation if let Some(pipeline) = self.pipelines.get(&pipeline_id) { if let Some(parent_pipeline_id) = pipeline.parent_info { if let Some(parent_pipeline) = self.pipelines.get(&parent_pipeline_id) { - let msg = ConstellationControlMsg::UpdatePipelineId(parent_pipeline_id, - pipeline.browsing_context_id, pipeline_id, UpdatePipelineIdReason::Navigation); + let msg = ConstellationControlMsg::UpdatePipelineId( + parent_pipeline_id, + pipeline.browsing_context_id, + pipeline_id, + UpdatePipelineIdReason::Navigation, + ); let _ = parent_pipeline.event_loop.send(msg); } } } // Find the pending change whose new pipeline id is pipeline_id. - let pending_index = self.pending_changes.iter().rposition(|change| { - change.new_pipeline_id == pipeline_id - }); + let pending_index = self + .pending_changes + .iter() + .rposition(|change| change.new_pipeline_id == pipeline_id); // If it is found, remove it from the pending changes, and make it // the active document of its frame. @@ -2669,12 +3194,16 @@ impl Constellation } /// Called when the window is resized. - fn handle_window_size_msg(&mut self, - top_level_browsing_context_id: Option, - new_size: WindowSizeData, - size_type: WindowSizeType) - { - debug!("handle_window_size_msg: {:?}", new_size.initial_viewport.to_untyped()); + fn handle_window_size_msg( + &mut self, + top_level_browsing_context_id: Option, + new_size: WindowSizeData, + size_type: WindowSizeType, + ) { + debug!( + "handle_window_size_msg: {:?}", + new_size.initial_viewport.to_untyped() + ); if let Some(top_level_browsing_context_id) = top_level_browsing_context_id { let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id); @@ -2689,10 +3218,16 @@ impl Constellation } /// Handle updating actual viewport / zoom due to @viewport rules - fn handle_viewport_constrained_msg(&mut self, - pipeline_id: PipelineId, - constraints: ViewportConstraints) { - self.compositor_proxy.send(ToCompositorMsg::ViewportConstrained(pipeline_id, constraints)); + fn handle_viewport_constrained_msg( + &mut self, + pipeline_id: PipelineId, + constraints: ViewportConstraints, + ) { + self.compositor_proxy + .send(ToCompositorMsg::ViewportConstrained( + pipeline_id, + constraints, + )); } /// Checks the state of all script and layout pipelines to see if they are idle @@ -2700,14 +3235,18 @@ impl Constellation /// to check if the output image is "stable" and can be written as a screenshot /// for reftests. /// Since this function is only used in reftests, we do not harden it against panic. - fn handle_is_ready_to_save_image(&mut self, pipeline_states: HashMap) -> ReadyToSave { + fn handle_is_ready_to_save_image( + &mut self, + pipeline_states: HashMap, + ) -> ReadyToSave { // Note that this function can panic, due to ipc-channel creation failure. // avoiding this panic would require a mechanism for dealing // with low-resource scenarios. // // If there is no focus browsing context yet, the initial page has // not loaded, so there is nothing to save yet. - let top_level_browsing_context_id = self.focus_pipeline_id + let top_level_browsing_context_id = self + .focus_pipeline_id .and_then(|pipeline_id| self.pipelines.get(&pipeline_id)) .map(|pipeline| pipeline.top_level_browsing_context_id); let top_level_browsing_context_id = match top_level_browsing_context_id { @@ -2728,9 +3267,14 @@ impl Constellation // matches what the compositor has painted. If all these conditions // are met, then the output image should not change and a reftest // screenshot can safely be written. - for browsing_context in self.fully_active_browsing_contexts_iter(top_level_browsing_context_id) { + for browsing_context in + self.fully_active_browsing_contexts_iter(top_level_browsing_context_id) + { let pipeline_id = browsing_context.pipeline_id; - debug!("Checking readiness of browsing context {}, pipeline {}.", browsing_context.id, pipeline_id); + debug!( + "Checking readiness of browsing context {}, pipeline {}.", + browsing_context.id, pipeline_id + ); let pipeline = match self.pipelines.get(&pipeline_id) { None => { @@ -2758,10 +3302,10 @@ impl Constellation // See if this pipeline has reached idle script state yet. match self.document_states.get(&browsing_context.pipeline_id) { - Some(&DocumentState::Idle) => {} + Some(&DocumentState::Idle) => {}, Some(&DocumentState::Pending) | None => { return ReadyToSave::DocumentLoading; - } + }, } // Check the visible rectangle for this pipeline. If the constellation has received a @@ -2790,16 +3334,18 @@ impl Constellation } match epoch_receiver.recv() { Err(e) => warn!("Failed to receive current epoch ({}).", e), - Ok(layout_thread_epoch) => if layout_thread_epoch != *compositor_epoch { - return ReadyToSave::EpochMismatch; + Ok(layout_thread_epoch) => { + if layout_thread_epoch != *compositor_epoch { + return ReadyToSave::EpochMismatch; + } }, } - } + }, None => { // The compositor doesn't know about this pipeline yet. // Assume it hasn't rendered yet. return ReadyToSave::PipelineUnknown; - } + }, } } } @@ -2813,7 +3359,9 @@ impl Constellation let mut ancestor_id = pipeline_id; loop { if let Some(ancestor) = self.pipelines.get(&ancestor_id) { - if let Some(browsing_context) = self.browsing_contexts.get(&ancestor.browsing_context_id) { + if let Some(browsing_context) = + self.browsing_contexts.get(&ancestor.browsing_context_id) + { if browsing_context.pipeline_id == ancestor_id { if let Some(parent_id) = ancestor.parent_info { ancestor_id = parent_id; @@ -2857,11 +3405,12 @@ impl Constellation /// Handle updating the size of a browsing context. /// This notifies every pipeline in the context of the new size. - fn resize_browsing_context(&mut self, - new_size: WindowSizeData, - size_type: WindowSizeType, - browsing_context_id: BrowsingContextId) - { + fn resize_browsing_context( + &mut self, + new_size: WindowSizeData, + size_type: WindowSizeType, + browsing_context_id: BrowsingContextId, + ) { if let Some(browsing_context) = self.browsing_contexts.get_mut(&browsing_context_id) { browsing_context.size = Some(new_size.initial_viewport); } @@ -2877,16 +3426,20 @@ impl Constellation let _ = pipeline.event_loop.send(ConstellationControlMsg::Resize( pipeline.id, new_size, - size_type + size_type, )); - let pipelines = browsing_context.pipelines.iter() + let pipelines = browsing_context + .pipelines + .iter() .filter(|pipeline_id| **pipeline_id != pipeline.id) .filter_map(|pipeline_id| self.pipelines.get(&pipeline_id)); for pipeline in pipelines { - let _ = pipeline.event_loop.send(ConstellationControlMsg::ResizeInactive( - pipeline.id, - new_size - )); + let _ = pipeline + .event_loop + .send(ConstellationControlMsg::ResizeInactive( + pipeline.id, + new_size, + )); } } @@ -2894,24 +3447,35 @@ impl Constellation for change in &self.pending_changes { let pipeline_id = change.new_pipeline_id; let pipeline = match self.pipelines.get(&pipeline_id) { - None => { warn!("Pending pipeline {:?} is closed", pipeline_id); continue; } + None => { + warn!("Pending pipeline {:?} is closed", pipeline_id); + continue; + }, Some(pipeline) => pipeline, }; if pipeline.browsing_context_id == browsing_context_id { let _ = pipeline.event_loop.send(ConstellationControlMsg::Resize( pipeline.id, new_size, - size_type + size_type, )); } } } // Close a browsing context (and all children) - fn close_browsing_context(&mut self, browsing_context_id: BrowsingContextId, exit_mode: ExitPipelineMode) { + fn close_browsing_context( + &mut self, + browsing_context_id: BrowsingContextId, + exit_mode: ExitPipelineMode, + ) { debug!("Closing browsing context {}.", browsing_context_id); - self.close_browsing_context_children(browsing_context_id, DiscardBrowsingContext::Yes, exit_mode); + self.close_browsing_context_children( + browsing_context_id, + DiscardBrowsingContext::Yes, + exit_mode, + ); let browsing_context = match self.browsing_contexts.remove(&browsing_context_id) { None => return warn!("Closing browsing context {:?} twice.", browsing_context_id), @@ -2927,12 +3491,19 @@ impl Constellation self.event_loops.remove(&browsing_context.top_level_id); } - let parent_info = self.pipelines.get(&browsing_context.pipeline_id) + let parent_info = self + .pipelines + .get(&browsing_context.pipeline_id) .and_then(|pipeline| pipeline.parent_info); if let Some(parent_pipeline_id) = parent_info { match self.pipelines.get_mut(&parent_pipeline_id) { - None => return warn!("Pipeline {:?} child closed after parent.", parent_pipeline_id), + None => { + return warn!( + "Pipeline {:?} child closed after parent.", + parent_pipeline_id + ) + }, Some(parent_pipeline) => parent_pipeline.remove_child(browsing_context_id), }; } @@ -2940,17 +3511,20 @@ impl Constellation } // Close the children of a browsing context - fn close_browsing_context_children(&mut self, - browsing_context_id: BrowsingContextId, - dbc: DiscardBrowsingContext, - exit_mode: ExitPipelineMode) - { + fn close_browsing_context_children( + &mut self, + browsing_context_id: BrowsingContextId, + dbc: DiscardBrowsingContext, + exit_mode: ExitPipelineMode, + ) { debug!("Closing browsing context children {}.", browsing_context_id); // Store information about the pipelines to be closed. Then close the // pipelines, before removing ourself from the browsing_contexts hash map. This // ordering is vital - so that if close_pipeline() ends up closing // any child browsing contexts, they can be removed from the parent browsing context correctly. - let mut pipelines_to_close: Vec = self.pending_changes.iter() + let mut pipelines_to_close: Vec = self + .pending_changes + .iter() .filter(|change| change.browsing_context_id == browsing_context_id) .map(|change| change.new_pipeline_id) .collect(); @@ -2967,17 +3541,27 @@ impl Constellation } // Discard the pipeline for a given document, udpdate the joint session history. - fn handle_discard_document(&mut self, - top_level_browsing_context_id: TopLevelBrowsingContextId, - pipeline_id: PipelineId) { + fn handle_discard_document( + &mut self, + top_level_browsing_context_id: TopLevelBrowsingContextId, + pipeline_id: PipelineId, + ) { let load_data = match self.pipelines.get(&pipeline_id) { Some(pipeline) => pipeline.load_data.clone(), - None => return + None => return, }; self.joint_session_histories - .entry(top_level_browsing_context_id).or_insert(JointSessionHistory::new()) - .replace_reloader(NeedsToReload::No(pipeline_id), NeedsToReload::Yes(pipeline_id, load_data)); - self.close_pipeline(pipeline_id, DiscardBrowsingContext::No, ExitPipelineMode::Normal); + .entry(top_level_browsing_context_id) + .or_insert(JointSessionHistory::new()) + .replace_reloader( + NeedsToReload::No(pipeline_id), + NeedsToReload::Yes(pipeline_id, load_data), + ); + self.close_pipeline( + pipeline_id, + DiscardBrowsingContext::No, + ExitPipelineMode::Normal, + ); } // Send a message to script requesting the document associated with this pipeline runs the 'unload' algorithm. @@ -2989,11 +3573,19 @@ impl Constellation } // Close all pipelines at and beneath a given browsing context - fn close_pipeline(&mut self, pipeline_id: PipelineId, dbc: DiscardBrowsingContext, exit_mode: ExitPipelineMode) { + fn close_pipeline( + &mut self, + pipeline_id: PipelineId, + dbc: DiscardBrowsingContext, + exit_mode: ExitPipelineMode, + ) { debug!("Closing pipeline {:?}.", pipeline_id); // Sever connection to browsing context - let browsing_context_id = self.pipelines.get(&pipeline_id).map(|pipeline| pipeline.browsing_context_id); + let browsing_context_id = self + .pipelines + .get(&pipeline_id) + .map(|pipeline| pipeline.browsing_context_id); if let Some(browsing_context) = browsing_context_id .and_then(|browsing_context_id| self.browsing_contexts.get_mut(&browsing_context_id)) { @@ -3005,7 +3597,7 @@ impl Constellation // ordering is vital - so that if close_browsing_context() ends up closing // any child pipelines, they can be removed from the parent pipeline correctly. let browsing_contexts_to_close = { - let mut browsing_contexts_to_close = vec!(); + let mut browsing_contexts_to_close = vec![]; if let Some(pipeline) = self.pipelines.get(&pipeline_id) { browsing_contexts_to_close.extend_from_slice(&pipeline.children); @@ -3027,9 +3619,10 @@ impl Constellation }; // Remove this pipeline from pending changes if it hasn't loaded yet. - let pending_index = self.pending_changes.iter().position(|change| { - change.new_pipeline_id == pipeline_id - }); + let pending_index = self + .pending_changes + .iter() + .position(|change| change.new_pipeline_id == pipeline_id); if let Some(pending_index) = pending_index { self.pending_changes.remove(pending_index); } @@ -3045,7 +3638,9 @@ impl Constellation // Randomly close a pipeline -if --random-pipeline-closure-probability is set fn maybe_close_random_pipeline(&mut self) { match self.random_pipeline_closure { - Some((ref mut rng, probability)) => if probability <= rng.gen::() { return }, + Some((ref mut rng, probability)) => if probability <= rng.gen::() { + return; + }, _ => return, }; // In order to get repeatability, we sort the pipeline ids. @@ -3054,8 +3649,12 @@ impl Constellation if let Some((ref mut rng, probability)) = self.random_pipeline_closure { if let Some(pipeline_id) = rng.choose(&*pipeline_ids) { if let Some(pipeline) = self.pipelines.get(pipeline_id) { - if self.pending_changes.iter().any(|change| change.new_pipeline_id == pipeline.id) && - probability <= rng.gen::() { + if self + .pending_changes + .iter() + .any(|change| change.new_pipeline_id == pipeline.id) && + probability <= rng.gen::() + { // We tend not to close pending pipelines, as that almost always // results in pipelines being closed early in their lifecycle, // and not stressing the constellation as much. @@ -3072,39 +3671,57 @@ impl Constellation } } - fn get_joint_session_history(&mut self, top_level_id: TopLevelBrowsingContextId) -> &mut JointSessionHistory { - self.joint_session_histories.entry(top_level_id).or_insert(JointSessionHistory::new()) + fn get_joint_session_history( + &mut self, + top_level_id: TopLevelBrowsingContextId, + ) -> &mut JointSessionHistory { + self.joint_session_histories + .entry(top_level_id) + .or_insert(JointSessionHistory::new()) } // Convert a browsing context to a sendable form to pass to the compositor - fn browsing_context_to_sendable(&self, browsing_context_id: BrowsingContextId) -> Option { - self.browsing_contexts.get(&browsing_context_id).and_then(|browsing_context| { - self.pipelines.get(&browsing_context.pipeline_id).map(|pipeline| { - let mut frame_tree = SendableFrameTree { - pipeline: pipeline.to_sendable(), - size: browsing_context.size, - children: vec!(), - }; + fn browsing_context_to_sendable( + &self, + browsing_context_id: BrowsingContextId, + ) -> Option { + self.browsing_contexts + .get(&browsing_context_id) + .and_then(|browsing_context| { + self.pipelines + .get(&browsing_context.pipeline_id) + .map(|pipeline| { + let mut frame_tree = SendableFrameTree { + pipeline: pipeline.to_sendable(), + size: browsing_context.size, + children: vec![], + }; - for child_browsing_context_id in &pipeline.children { - if let Some(child) = self.browsing_context_to_sendable(*child_browsing_context_id) { - frame_tree.children.push(child); - } - } + for child_browsing_context_id in &pipeline.children { + if let Some(child) = + self.browsing_context_to_sendable(*child_browsing_context_id) + { + frame_tree.children.push(child); + } + } - frame_tree + frame_tree + }) }) - }) } /// Re-send the frame tree to the compositor. - fn update_frame_tree_if_active(&mut self, top_level_browsing_context_id: TopLevelBrowsingContextId) { + fn update_frame_tree_if_active( + &mut self, + top_level_browsing_context_id: TopLevelBrowsingContextId, + ) { // Only send the frame tree if it's the active one or if no frame tree // has been sent yet. - if self.active_browser_id.is_none() || Some(top_level_browsing_context_id) == self.active_browser_id { + if self.active_browser_id.is_none() || + Some(top_level_browsing_context_id) == self.active_browser_id + { self.send_frame_tree(top_level_browsing_context_id); } - } /// Send the current frame tree to compositor @@ -3115,9 +3732,13 @@ impl Constellation // Note that this function can panic, due to ipc-channel creation failure. // avoiding this panic would require a mechanism for dealing // with low-resource scenarios. - debug!("Sending frame tree for browsing context {}.", browsing_context_id); + debug!( + "Sending frame tree for browsing context {}.", + browsing_context_id + ); if let Some(frame_tree) = self.browsing_context_to_sendable(browsing_context_id) { - self.compositor_proxy.send(ToCompositorMsg::SetFrameTree(frame_tree)); + self.compositor_proxy + .send(ToCompositorMsg::SetFrameTree(frame_tree)); } } diff --git a/components/constellation/event_loop.rs b/components/constellation/event_loop.rs index 8d611144bce..7506e029570 100644 --- a/components/constellation/event_loop.rs +++ b/components/constellation/event_loop.rs @@ -20,7 +20,9 @@ pub struct EventLoop { impl Drop for EventLoop { fn drop(&mut self) { - let _ = self.script_chan.send(ConstellationControlMsg::ExitScriptThread); + let _ = self + .script_chan + .send(ConstellationControlMsg::ExitScriptThread); } } @@ -43,4 +45,3 @@ impl EventLoop { self.script_chan.clone() } } - diff --git a/components/constellation/lib.rs b/components/constellation/lib.rs index 1fd6662d405..1af7a3bfc4a 100644 --- a/components/constellation/lib.rs +++ b/components/constellation/lib.rs @@ -32,7 +32,8 @@ extern crate net; extern crate net_traits; extern crate profile_traits; extern crate script_traits; -#[macro_use] extern crate serde; +#[macro_use] +extern crate serde; extern crate servo_config; extern crate servo_rand; extern crate servo_remutex; diff --git a/components/constellation/network_listener.rs b/components/constellation/network_listener.rs index a6adf9a4c5c..823fca4608c 100644 --- a/components/constellation/network_listener.rs +++ b/components/constellation/network_listener.rs @@ -27,17 +27,19 @@ pub struct NetworkListener { } impl NetworkListener { - pub fn new(req_init: RequestInit, - pipeline_id: PipelineId, - resource_threads: ResourceThreads, - sender: Sender<(PipelineId, FetchResponseMsg)>) -> NetworkListener { + pub fn new( + req_init: RequestInit, + pipeline_id: PipelineId, + resource_threads: ResourceThreads, + sender: Sender<(PipelineId, FetchResponseMsg)>, + ) -> NetworkListener { NetworkListener { res_init: None, req_init, pipeline_id, resource_threads, sender, - should_send: false + should_send: false, } } @@ -55,35 +57,40 @@ impl NetworkListener { let msg = match self.res_init { Some(ref res_init_) => CoreResourceMsg::FetchRedirect( - self.req_init.clone(), - res_init_.clone(), - ipc_sender, None), + self.req_init.clone(), + res_init_.clone(), + ipc_sender, + None, + ), None => { set_default_accept(Destination::Document, &mut listener.req_init.headers); set_default_accept_language(&mut listener.req_init.headers); CoreResourceMsg::Fetch( - listener.req_init.clone(), - FetchChannels::ResponseMsg(ipc_sender, cancel_chan)) - } + listener.req_init.clone(), + FetchChannels::ResponseMsg(ipc_sender, cancel_chan), + ) + }, }; - ROUTER.add_route(ipc_receiver.to_opaque(), Box::new(move |message| { - let msg = message.to(); - match msg { - Ok(FetchResponseMsg::ProcessResponse(res)) => listener.check_redirect(res), - Ok(msg_) => listener.send(msg_), - Err(e) => warn!("Error while receiving network listener message: {}", e), - }; - })); + ROUTER.add_route( + ipc_receiver.to_opaque(), + Box::new(move |message| { + let msg = message.to(); + match msg { + Ok(FetchResponseMsg::ProcessResponse(res)) => listener.check_redirect(res), + Ok(msg_) => listener.send(msg_), + Err(e) => warn!("Error while receiving network listener message: {}", e), + }; + }), + ); if let Err(e) = self.resource_threads.sender().send(msg) { warn!("Resource thread unavailable ({})", e); } } - fn check_redirect(&mut self, - message: Result<(FetchMetadata), NetworkError>) { + fn check_redirect(&mut self, message: Result<(FetchMetadata), NetworkError>) { match message { Ok(res_metadata) => { let metadata = match res_metadata { @@ -118,20 +125,23 @@ impl NetworkListener { // Response should be processed by script thread. self.should_send = true; self.send(FetchResponseMsg::ProcessResponse(Ok(res_metadata.clone()))); - } + }, }; }, Err(e) => { self.should_send = true; self.send(FetchResponseMsg::ProcessResponse(Err(e))) - } + }, }; } fn send(&mut self, msg: FetchResponseMsg) { if self.should_send { if let Err(e) = self.sender.send((self.pipeline_id, msg)) { - warn!("Failed to forward network message to pipeline {}: {:?}", self.pipeline_id, e); + warn!( + "Failed to forward network message to pipeline {}: {:?}", + self.pipeline_id, e + ); } } } diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs index 548ef249cdc..50d2911a535 100644 --- a/components/constellation/pipeline.rs +++ b/components/constellation/pipeline.rs @@ -190,23 +190,21 @@ impl Pipeline { /// Starts a layout thread, and possibly a script thread, in /// a new process if requested. pub fn spawn(state: InitialPipelineState) -> Result - where LTF: LayoutThreadFactory, - STF: ScriptThreadFactory + where + LTF: LayoutThreadFactory, + STF: ScriptThreadFactory, { // Note: we allow channel creation to panic, since recovering from this // probably requires a general low-memory strategy. - let (pipeline_chan, pipeline_port) = ipc::channel() - .expect("Pipeline main chan"); + let (pipeline_chan, pipeline_port) = ipc::channel().expect("Pipeline main chan"); let (layout_content_process_shutdown_chan, layout_content_process_shutdown_port) = ipc::channel().expect("Pipeline layout content shutdown chan"); let device_pixel_ratio = state.device_pixel_ratio; - let window_size = state.window_size.map(|size| { - WindowSizeData { - initial_viewport: size, - device_pixel_ratio: device_pixel_ratio, - } + let window_size = state.window_size.map(|size| WindowSizeData { + initial_viewport: size, + device_pixel_ratio: device_pixel_ratio, }); let url = state.load_data.url.clone(); @@ -221,31 +219,42 @@ impl Pipeline { load_data: state.load_data.clone(), window_size: window_size, pipeline_port: pipeline_port, - content_process_shutdown_chan: Some(layout_content_process_shutdown_chan.clone()), + content_process_shutdown_chan: Some( + layout_content_process_shutdown_chan.clone(), + ), layout_threads: PREFS.get("layout.threads").as_u64().expect("count") as usize, }; - if let Err(e) = script_chan.send(ConstellationControlMsg::AttachLayout(new_layout_info)) { + if let Err(e) = + script_chan.send(ConstellationControlMsg::AttachLayout(new_layout_info)) + { warn!("Sending to script during pipeline creation failed ({})", e); } script_chan - } + }, None => { let (script_chan, script_port) = ipc::channel().expect("Pipeline script chan"); // Route messages coming from content to devtools as appropriate. let script_to_devtools_chan = state.devtools_chan.as_ref().map(|devtools_chan| { - let (script_to_devtools_chan, script_to_devtools_port) = ipc::channel() - .expect("Pipeline script to devtools chan"); + let (script_to_devtools_chan, script_to_devtools_port) = + ipc::channel().expect("Pipeline script to devtools chan"); let devtools_chan = (*devtools_chan).clone(); - ROUTER.add_route(script_to_devtools_port.to_opaque(), Box::new(move |message| { - match message.to::() { - Err(e) => error!("Cast to ScriptToDevtoolsControlMsg failed ({}).", e), - Ok(message) => if let Err(e) = devtools_chan.send(DevtoolsControlMsg::FromScript(message)) { - warn!("Sending to devtools failed ({})", e) + ROUTER.add_route( + script_to_devtools_port.to_opaque(), + Box::new( + move |message| match message.to::() { + Err(e) => { + error!("Cast to ScriptToDevtoolsControlMsg failed ({}).", e) + }, + Ok(message) => if let Err(e) = + devtools_chan.send(DevtoolsControlMsg::FromScript(message)) + { + warn!("Sending to devtools failed ({})", e) + }, }, - } - })); + ), + ); script_to_devtools_chan }); @@ -295,36 +304,39 @@ impl Pipeline { } EventLoop::new(script_chan) - } + }, }; - Ok(Pipeline::new(state.id, - state.browsing_context_id, - state.top_level_browsing_context_id, - state.parent_info, - script_chan, - pipeline_chan, - state.compositor_proxy, - state.is_private, - url, - state.prev_visibility.unwrap_or(true), - state.load_data)) + Ok(Pipeline::new( + state.id, + state.browsing_context_id, + state.top_level_browsing_context_id, + state.parent_info, + script_chan, + pipeline_chan, + state.compositor_proxy, + state.is_private, + url, + state.prev_visibility.unwrap_or(true), + state.load_data, + )) } /// Creates a new `Pipeline`, after the script and layout threads have been /// spawned. - pub fn new(id: PipelineId, - browsing_context_id: BrowsingContextId, - top_level_browsing_context_id: TopLevelBrowsingContextId, - parent_info: Option, - event_loop: Rc, - layout_chan: IpcSender, - compositor_proxy: CompositorProxy, - is_private: bool, - url: ServoUrl, - visible: bool, - load_data: LoadData) - -> Pipeline { + pub fn new( + id: PipelineId, + browsing_context_id: BrowsingContextId, + top_level_browsing_context_id: TopLevelBrowsingContextId, + parent_info: Option, + event_loop: Rc, + layout_chan: IpcSender, + compositor_proxy: CompositorProxy, + is_private: bool, + url: ServoUrl, + visible: bool, + load_data: LoadData, + ) -> Pipeline { let pipeline = Pipeline { id: id, browsing_context_id: browsing_context_id, @@ -334,7 +346,7 @@ impl Pipeline { layout_chan: layout_chan, compositor_proxy: compositor_proxy, url: url, - children: vec!(), + children: vec![], running_animations: false, visible: visible, is_private: is_private, @@ -359,7 +371,8 @@ impl Pipeline { // It's OK for the constellation to block on the compositor, // since the compositor never blocks on the constellation. if let Ok((sender, receiver)) = ipc::channel() { - self.compositor_proxy.send(CompositorMsg::PipelineExited(self.id, sender)); + self.compositor_proxy + .send(CompositorMsg::PipelineExited(self.id, sender)); if let Err(e) = receiver.recv() { warn!("Sending exit message failed ({}).", e); } @@ -410,15 +423,25 @@ impl Pipeline { /// Remove a child browsing context. pub fn remove_child(&mut self, browsing_context_id: BrowsingContextId) { - match self.children.iter().position(|id| *id == browsing_context_id) { - None => return warn!("Pipeline remove child already removed ({:?}).", browsing_context_id), + match self + .children + .iter() + .position(|id| *id == browsing_context_id) + { + None => { + return warn!( + "Pipeline remove child already removed ({:?}).", + browsing_context_id + ) + }, Some(index) => self.children.remove(index), }; } /// Notify the script thread that this pipeline is visible. fn notify_visibility(&self) { - let script_msg = ConstellationControlMsg::ChangeFrameVisibilityStatus(self.id, self.visible); + let script_msg = + ConstellationControlMsg::ChangeFrameVisibilityStatus(self.id, self.visible); let compositor_msg = CompositorMsg::PipelineVisibilityChanged(self.id, self.visible); let err = self.event_loop.send(script_msg); if let Err(e) = err { @@ -435,7 +458,6 @@ impl Pipeline { self.visible = visible; self.notify_visibility(); } - } /// Creating a new pipeline may require creating a new event loop. @@ -477,57 +499,69 @@ pub struct UnprivilegedPipelineContent { impl UnprivilegedPipelineContent { pub fn start_all(self, wait_for_completion: bool) - where LTF: LayoutThreadFactory, - STF: ScriptThreadFactory + where + LTF: LayoutThreadFactory, + STF: ScriptThreadFactory, { let image_cache = Arc::new(ImageCacheImpl::new(self.webrender_api_sender.create_api())); - let paint_time_metrics = PaintTimeMetrics::new(self.id, - self.time_profiler_chan.clone(), - self.layout_to_constellation_chan.clone(), - self.script_chan.clone(), - self.load_data.url.clone()); - let layout_pair = STF::create(InitialScriptState { - id: self.id, - browsing_context_id: self.browsing_context_id, - top_level_browsing_context_id: self.top_level_browsing_context_id, - parent_info: self.parent_info, - control_chan: self.script_chan.clone(), - control_port: self.script_port, - script_to_constellation_chan: self.script_to_constellation_chan.clone(), - layout_to_constellation_chan: self.layout_to_constellation_chan.clone(), - scheduler_chan: self.scheduler_chan, - bluetooth_thread: self.bluetooth_thread, - resource_threads: self.resource_threads, - image_cache: image_cache.clone(), - time_profiler_chan: self.time_profiler_chan.clone(), - 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, - content_process_shutdown_chan: self.script_content_process_shutdown_chan, - webgl_chan: self.webgl_chan, - webvr_chan: self.webvr_chan, - webrender_document: self.webrender_document, - }, self.load_data.clone()); + let paint_time_metrics = PaintTimeMetrics::new( + self.id, + self.time_profiler_chan.clone(), + self.layout_to_constellation_chan.clone(), + self.script_chan.clone(), + self.load_data.url.clone(), + ); + let layout_pair = STF::create( + InitialScriptState { + id: self.id, + browsing_context_id: self.browsing_context_id, + top_level_browsing_context_id: self.top_level_browsing_context_id, + parent_info: self.parent_info, + control_chan: self.script_chan.clone(), + control_port: self.script_port, + script_to_constellation_chan: self.script_to_constellation_chan.clone(), + layout_to_constellation_chan: self.layout_to_constellation_chan.clone(), + scheduler_chan: self.scheduler_chan, + bluetooth_thread: self.bluetooth_thread, + resource_threads: self.resource_threads, + image_cache: image_cache.clone(), + time_profiler_chan: self.time_profiler_chan.clone(), + 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, + content_process_shutdown_chan: self.script_content_process_shutdown_chan, + webgl_chan: self.webgl_chan, + webvr_chan: self.webvr_chan, + webrender_document: self.webrender_document, + }, + self.load_data.clone(), + ); - LTF::create(self.id, - self.top_level_browsing_context_id, - self.load_data.url, - self.parent_info.is_some(), - layout_pair, - self.pipeline_port, - self.layout_to_constellation_chan, - self.script_chan, - image_cache.clone(), - self.font_cache_thread, - self.time_profiler_chan, - self.mem_profiler_chan, - Some(self.layout_content_process_shutdown_chan), - self.webrender_api_sender, - self.webrender_document, - self.prefs.get("layout.threads").expect("exists").value() - .as_u64().expect("count") as usize, - paint_time_metrics); + LTF::create( + self.id, + self.top_level_browsing_context_id, + self.load_data.url, + self.parent_info.is_some(), + layout_pair, + self.pipeline_port, + self.layout_to_constellation_chan, + self.script_chan, + image_cache.clone(), + self.font_cache_thread, + self.time_profiler_chan, + self.mem_profiler_chan, + Some(self.layout_content_process_shutdown_chan), + self.webrender_api_sender, + self.webrender_document, + self.prefs + .get("layout.threads") + .expect("exists") + .value() + .as_u64() + .expect("count") as usize, + paint_time_metrics, + ); if wait_for_completion { let _ = self.script_content_process_shutdown_port.recv(); @@ -543,12 +577,17 @@ impl UnprivilegedPipelineContent { impl CommandMethods for sandbox::Command { fn arg(&mut self, arg: T) - where T: AsRef { + where + T: AsRef, + { self.arg(arg); } fn env(&mut self, key: T, val: U) - where T: AsRef, U: AsRef { + where + T: AsRef, + U: AsRef, + { self.env(key, val); } } @@ -556,8 +595,7 @@ impl UnprivilegedPipelineContent { // Note that this function can panic, due to process creation, // avoiding this panic would require a mechanism for dealing // with low-resource scenarios. - let (server, token) = - IpcOneShotServer::>::new() + let (server, token) = IpcOneShotServer::>::new() .expect("Failed to create IPC one-shot server."); // If there is a sandbox, use the `gaol` API to create the child process. @@ -570,11 +608,12 @@ impl UnprivilegedPipelineContent { .start(&mut command) .expect("Failed to start sandboxed child process!"); } else { - let path_to_self = env::current_exe() - .expect("Failed to get current executor."); + let path_to_self = env::current_exe().expect("Failed to get current executor."); let mut child_process = process::Command::new(path_to_self); self.setup_common(&mut child_process, token); - let _ = child_process.spawn().expect("Failed to start unsandboxed child process!"); + let _ = child_process + .spawn() + .expect("Failed to start unsandboxed child process!"); } let (_receiver, sender) = server.accept().expect("Server failed to accept."); @@ -618,7 +657,7 @@ impl UnprivilegedPipelineContent { pub fn swmanager_senders(&self) -> SWManagerSenders { SWManagerSenders { swmanager_sender: self.swmanager_thread.clone(), - resource_sender: self.resource_threads.sender() + resource_sender: self.resource_threads.sender(), } } } @@ -627,21 +666,29 @@ impl UnprivilegedPipelineContent { trait CommandMethods { /// A command line argument. fn arg(&mut self, arg: T) - where T: AsRef; + where + T: AsRef; /// An environment variable. fn env(&mut self, key: T, val: U) - where T: AsRef, U: AsRef; + where + T: AsRef, + U: AsRef; } impl CommandMethods for process::Command { fn arg(&mut self, arg: T) - where T: AsRef { + where + T: AsRef, + { self.arg(arg); } fn env(&mut self, key: T, val: U) - where T: AsRef, U: AsRef { + where + T: AsRef, + U: AsRef, + { self.env(key, val); } } diff --git a/components/constellation/sandboxing.rs b/components/constellation/sandboxing.rs index 29999a97ed1..84ff3cd4bce 100644 --- a/components/constellation/sandboxing.rs +++ b/components/constellation/sandboxing.rs @@ -16,24 +16,31 @@ pub fn content_process_sandbox_profile() -> Profile { Operation::FileReadAll(PathPattern::Subpath(PathBuf::from("/Library/Fonts"))), Operation::FileReadAll(PathPattern::Subpath(PathBuf::from("/System/Library/Fonts"))), Operation::FileReadAll(PathPattern::Subpath(PathBuf::from( - "/System/Library/Frameworks/ApplicationServices.framework"))), + "/System/Library/Frameworks/ApplicationServices.framework", + ))), Operation::FileReadAll(PathPattern::Subpath(PathBuf::from( - "/System/Library/Frameworks/CoreGraphics.framework"))), + "/System/Library/Frameworks/CoreGraphics.framework", + ))), Operation::FileReadMetadata(PathPattern::Literal(PathBuf::from("/"))), Operation::FileReadMetadata(PathPattern::Literal(PathBuf::from("/Library"))), Operation::FileReadMetadata(PathPattern::Literal(PathBuf::from("/System"))), Operation::FileReadMetadata(PathPattern::Literal(PathBuf::from("/etc"))), Operation::SystemInfoRead, Operation::PlatformSpecific(platform::macos::Operation::MachLookup( - b"com.apple.FontServer".to_vec())), + b"com.apple.FontServer".to_vec(), + )), ]; - operations.extend(resources::sandbox_access_files().into_iter().map(|p| { - Operation::FileReadAll(PathPattern::Literal(p)) - })); - operations.extend(resources::sandbox_access_files_dirs().into_iter().map(|p| { - Operation::FileReadAll(PathPattern::Subpath(p)) - })); + operations.extend( + resources::sandbox_access_files() + .into_iter() + .map(|p| Operation::FileReadAll(PathPattern::Literal(p))), + ); + operations.extend( + resources::sandbox_access_files_dirs() + .into_iter() + .map(|p| Operation::FileReadAll(PathPattern::Subpath(p))), + ); Profile::new(operations).expect("Failed to create sandbox profile!") } @@ -41,17 +48,20 @@ pub fn content_process_sandbox_profile() -> Profile { /// Our content process sandbox profile on Linux. As restrictive as possible. #[cfg(not(target_os = "macos"))] pub fn content_process_sandbox_profile() -> Profile { - let mut operations = vec![ - Operation::FileReadAll(PathPattern::Literal(PathBuf::from("/dev/urandom"))), - ]; + let mut operations = vec![Operation::FileReadAll(PathPattern::Literal(PathBuf::from( + "/dev/urandom", + )))]; - operations.extend(resources::sandbox_access_files().into_iter().map(|p| { - Operation::FileReadAll(PathPattern::Literal(p)) - })); - operations.extend(resources::sandbox_access_files_dirs().into_iter().map(|p| { - Operation::FileReadAll(PathPattern::Subpath(p)) - })); + operations.extend( + resources::sandbox_access_files() + .into_iter() + .map(|p| Operation::FileReadAll(PathPattern::Literal(p))), + ); + operations.extend( + resources::sandbox_access_files_dirs() + .into_iter() + .map(|p| Operation::FileReadAll(PathPattern::Subpath(p))), + ); Profile::new(operations).expect("Failed to create sandbox profile!") } - diff --git a/components/constellation/session_history.rs b/components/constellation/session_history.rs index adfa7cf347f..aa550fac0fb 100644 --- a/components/constellation/session_history.rs +++ b/components/constellation/session_history.rs @@ -44,20 +44,37 @@ impl JointSessionHistory { } } - pub fn replace_history_state(&mut self, pipeline_id: PipelineId, history_state_id: HistoryStateId, url: ServoUrl) { - if let Some(SessionHistoryDiff::PipelineDiff { ref mut new_history_state_id, ref mut new_url, .. }) = - self.past.iter_mut().find(|diff| match diff { - SessionHistoryDiff::PipelineDiff { pipeline_reloader: NeedsToReload::No(id), .. } => pipeline_id == *id, - _ => false, + pub fn replace_history_state( + &mut self, + pipeline_id: PipelineId, + history_state_id: HistoryStateId, + url: ServoUrl, + ) { + if let Some(SessionHistoryDiff::PipelineDiff { + ref mut new_history_state_id, + ref mut new_url, + .. + }) = self.past.iter_mut().find(|diff| match diff { + SessionHistoryDiff::PipelineDiff { + pipeline_reloader: NeedsToReload::No(id), + .. + } => pipeline_id == *id, + _ => false, }) { *new_history_state_id = history_state_id; *new_url = url.clone(); } - if let Some(SessionHistoryDiff::PipelineDiff { ref mut old_history_state_id, ref mut old_url, .. }) = - self.future.iter_mut().find(|diff| match diff { - SessionHistoryDiff::PipelineDiff { pipeline_reloader: NeedsToReload::No(id), .. } => pipeline_id == *id, - _ => false, + if let Some(SessionHistoryDiff::PipelineDiff { + ref mut old_history_state_id, + ref mut old_url, + .. + }) = self.future.iter_mut().find(|diff| match diff { + SessionHistoryDiff::PipelineDiff { + pipeline_reloader: NeedsToReload::No(id), + .. + } => pipeline_id == *id, + _ => false, }) { *old_history_state_id = Some(history_state_id); *old_url = url; @@ -65,21 +82,19 @@ impl JointSessionHistory { } pub fn remove_entries_for_browsing_context(&mut self, context_id: BrowsingContextId) { - self.past.retain(|diff| { - match diff { - SessionHistoryDiff::BrowsingContextDiff { browsing_context_id, .. } => { - *browsing_context_id != context_id - }, - _ => true, - } + self.past.retain(|diff| match diff { + SessionHistoryDiff::BrowsingContextDiff { + browsing_context_id, + .. + } => *browsing_context_id != context_id, + _ => true, }); - self.future.retain(|diff| { - match diff { - SessionHistoryDiff::BrowsingContextDiff { browsing_context_id, .. } => { - *browsing_context_id != context_id - }, - _ => true, - } + self.future.retain(|diff| match diff { + SessionHistoryDiff::BrowsingContextDiff { + browsing_context_id, + .. + } => *browsing_context_id != context_id, + _ => true, }); } } @@ -132,23 +147,18 @@ impl NeedsToReload { impl PartialEq for NeedsToReload { fn eq(&self, other: &NeedsToReload) -> bool { match *self { - NeedsToReload::No(pipeline_id) => { - match *other { - NeedsToReload::No(other_pipeline_id) => pipeline_id == other_pipeline_id, - _ => false, - } + NeedsToReload::No(pipeline_id) => match *other { + NeedsToReload::No(other_pipeline_id) => pipeline_id == other_pipeline_id, + _ => false, + }, + NeedsToReload::Yes(pipeline_id, _) => match *other { + NeedsToReload::Yes(other_pipeline_id, _) => pipeline_id == other_pipeline_id, + _ => false, }, - NeedsToReload::Yes(pipeline_id, _) => { - match *other { - NeedsToReload::Yes(other_pipeline_id, _) => pipeline_id == other_pipeline_id, - _ => false, - } - } } } } - /// Represents a the difference between two adjacent session history entries. #[derive(Debug)] pub enum SessionHistoryDiff { @@ -185,11 +195,11 @@ impl SessionHistoryDiff { /// Returns the old pipeline id if that pipeline is still alive, otherwise returns `None` pub fn alive_old_pipeline(&self) -> Option { match *self { - SessionHistoryDiff::BrowsingContextDiff { ref old_reloader, .. } => { - match *old_reloader { - NeedsToReload::No(pipeline_id) => Some(pipeline_id), - NeedsToReload::Yes(..) => None, - } + SessionHistoryDiff::BrowsingContextDiff { + ref old_reloader, .. + } => match *old_reloader { + NeedsToReload::No(pipeline_id) => Some(pipeline_id), + NeedsToReload::Yes(..) => None, }, _ => None, } @@ -198,20 +208,28 @@ impl SessionHistoryDiff { /// Returns the new pipeline id if that pipeline is still alive, otherwise returns `None` pub fn alive_new_pipeline(&self) -> Option { match *self { - SessionHistoryDiff::BrowsingContextDiff { ref new_reloader, .. } => { - match *new_reloader { - NeedsToReload::No(pipeline_id) => Some(pipeline_id), - NeedsToReload::Yes(..) => None, - } + SessionHistoryDiff::BrowsingContextDiff { + ref new_reloader, .. + } => match *new_reloader { + NeedsToReload::No(pipeline_id) => Some(pipeline_id), + NeedsToReload::Yes(..) => None, }, _ => None, } } /// Replaces all occurances of the replaced pipeline with a new pipeline - pub fn replace_reloader(&mut self, replaced_reloader: &NeedsToReload, reloader: &NeedsToReload) { + pub fn replace_reloader( + &mut self, + replaced_reloader: &NeedsToReload, + reloader: &NeedsToReload, + ) { match *self { - SessionHistoryDiff::BrowsingContextDiff { ref mut old_reloader, ref mut new_reloader, .. } => { + SessionHistoryDiff::BrowsingContextDiff { + ref mut old_reloader, + ref mut new_reloader, + .. + } => { if *old_reloader == *replaced_reloader { *old_reloader = reloader.clone(); } @@ -219,12 +237,18 @@ impl SessionHistoryDiff { *new_reloader = reloader.clone(); } }, - SessionHistoryDiff::PipelineDiff { ref mut pipeline_reloader, .. } => { + SessionHistoryDiff::PipelineDiff { + ref mut pipeline_reloader, + .. + } => { if *pipeline_reloader == *replaced_reloader { *pipeline_reloader = reloader.clone(); } }, - SessionHistoryDiff::HashDiff { ref mut pipeline_reloader, .. } => { + SessionHistoryDiff::HashDiff { + ref mut pipeline_reloader, + .. + } => { if *pipeline_reloader == *replaced_reloader { *pipeline_reloader = reloader.clone(); } diff --git a/components/constellation/timer_scheduler.rs b/components/constellation/timer_scheduler.rs index 2ed0005957e..989ea77e0af 100644 --- a/components/constellation/timer_scheduler.rs +++ b/components/constellation/timer_scheduler.rs @@ -75,7 +75,10 @@ impl TimerScheduler { Ok(TimerSchedulerMsg::Request(req)) => { let TimerEventRequest(_, _, _, delay) = req; let schedule = Instant::now() + Duration::from_millis(delay.get()); - let event = ScheduledEvent { request: req, for_time: schedule }; + let event = ScheduledEvent { + request: req, + for_time: schedule, + }; scheduled_events.push(event); }, // If there is no incoming event, park the thread, @@ -86,8 +89,7 @@ impl TimerScheduler { Some(event) => thread::park_timeout(event.for_time - now), }, // If the channel is closed or we are shutting down, we are done. - Ok(TimerSchedulerMsg::Exit) | - Err(Disconnected) => break, + Ok(TimerSchedulerMsg::Exit) | Err(Disconnected) => break, } } // This thread can terminate if the req_ipc_sender is dropped. @@ -109,7 +111,7 @@ impl TimerScheduler { let mut shutting_down = false; match req { TimerSchedulerMsg::Exit => shutting_down = true, - _ => {} + _ => {}, } let _ = req_sender.send(req); timeout_thread.unpark();