diff options
Diffstat (limited to 'components/servo/lib.rs')
-rw-r--r-- | components/servo/lib.rs | 159 |
1 files changed, 101 insertions, 58 deletions
diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 8109f23e3f9..107f5e14c0f 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -2,14 +2,26 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +// Servo, the mighty web browser engine from the future. +// +// This is a very simple library that wires all of Servo's components +// together as type `Browser`, along with a generic client +// implementing the `WindowMethods` trait, to create a working web +// browser. +// +// The `Browser` type is responsible for configuring a +// `Constellation`, which does the heavy lifting of coordinating all +// of Servo's internal subsystems, including the `ScriptTask` and the +// `LayoutTask`, as well maintains the navigation context. +// +// The `Browser` is fed events from a generic type that implements the +// `WindowMethods` trait. #![feature(libc, rustc_private, thread_local)] #![cfg_attr(not(test), feature(path))] -#[macro_use] -extern crate log; - extern crate compositing; extern crate devtools; +extern crate devtools_traits; extern crate net; extern crate net_traits; extern crate msg; @@ -26,57 +38,64 @@ extern crate webdriver_server; use compositing::CompositorEventListener; use compositing::windowing::WindowEvent; -#[cfg(not(test))] use compositing::windowing::WindowMethods; -#[cfg(not(test))] use compositing::{CompositorProxy, CompositorTask, Constellation}; -#[cfg(not(test))] + use msg::constellation_msg::Msg as ConstellationMsg; -#[cfg(not(test))] use msg::constellation_msg::ConstellationChan; -#[cfg(not(test))] + use script::dom::bindings::codegen::RegisterBindings; -#[cfg(not(test))] use net::image_cache_task::{ImageCacheTaskFactory, LoadPlaceholder}; -#[cfg(not(test))] use net::storage_task::StorageTaskFactory; -#[cfg(not(test))] use net::resource_task::new_resource_task; -#[cfg(not(test))] use net_traits::image_cache_task::ImageCacheTask; -#[cfg(not(test))] use net_traits::storage_task::StorageTask; -#[cfg(not(test))] + use gfx::font_cache_task::FontCacheTask; -#[cfg(not(test))] use profile::mem; -#[cfg(not(test))] use profile::time; -#[cfg(not(test))] use util::opts; -#[cfg(not(test))] use util::taskpool::TaskPool; -#[cfg(not(test))] use std::rc::Rc; +use std::sync::mpsc::Sender; pub struct Browser { compositor: Box<CompositorEventListener + 'static>, } +/// The in-process interface to Servo. +/// +/// It does everything necessary to render the web, primarily +/// orchestrating the interaction between JavaScript, CSS layout, +/// rendering, and the client window. +/// +/// Clients create a `Browser` for a given reference-counted type +/// implementing `WindowMethods`, which is the bridge to whatever +/// application Servo is embedded in. Clients then create an event +/// loop to pump messages between the embedding application and +/// various browser components. impl Browser { - #[cfg(not(test))] pub fn new<Window>(window: Option<Rc<Window>>) -> Browser where Window: WindowMethods + 'static { - use std::env; - ::util::opts::set_experimental_enabled(opts::get().enable_experimental); + + // Global configuration options, parsed from the command line. let opts = opts::get(); + + // Create the global vtables used by the (generated) DOM + // bindings to implement JS proxies. RegisterBindings::RegisterProxyHandlers(); + // Use this thread pool to load-balance simple tasks, such as + // image decoding. let shared_task_pool = TaskPool::new(8); + // Get both endpoints of a special channel for communication between + // the client window and the compositor. This channel is unique because + // messages to client may need to pump a platform-specific event loop + // to deliver the message. let (compositor_proxy, compositor_receiver) = WindowMethods::create_compositor_channel(&window); let time_profiler_chan = time::Profiler::create(opts.time_profiler_period); @@ -89,46 +108,18 @@ impl Browser { webdriver_server::start_server(port); } - // Create a Servo instance. - let resource_task = new_resource_task(opts.user_agent.clone()); - - // If we are emitting an output file, then we need to block on - // image load or we risk emitting an output file missing the - // image. - let image_cache_task: ImageCacheTask = if opts.output_file.is_some() { - ImageCacheTaskFactory::new_sync(resource_task.clone(), shared_task_pool, - time_profiler_chan.clone(), LoadPlaceholder::Preload) - } else { - ImageCacheTaskFactory::new(resource_task.clone(), shared_task_pool, - time_profiler_chan.clone(), LoadPlaceholder::Preload) - }; - - let font_cache_task = FontCacheTask::new(resource_task.clone()); - let storage_task: StorageTask = StorageTaskFactory::new(); - - let constellation_chan = Constellation::<layout::layout_task::LayoutTask, - script::script_task::ScriptTask>::start( + // Create the constellation, which maintains the engine + // pipelines, including the script and layout threads, as well + // as the navigation context. + let constellation_chan = create_constellation(opts.clone(), compositor_proxy.clone_compositor_proxy(), - resource_task, - image_cache_task, - font_cache_task, time_profiler_chan.clone(), - mem_profiler_chan.clone(), devtools_chan, - storage_task); - - // Send the URL command to the constellation. - let cwd = env::current_dir().unwrap(); - let url = match url::Url::parse(&opts.url) { - Ok(url) => url, - Err(url::ParseError::RelativeUrlWithoutBase) - => url::Url::from_file_path(&*cwd.join(&opts.url)).unwrap(), - Err(_) => panic!("URL parsing failed"), - }; - - let ConstellationChan(ref chan) = constellation_chan; - chan.send(ConstellationMsg::InitLoadUrl(url)).unwrap(); + mem_profiler_chan.clone(), + shared_task_pool); + // The compositor coordinates with the client window to create the final + // rendered page and display it somewhere. let compositor = CompositorTask::create(window, compositor_proxy, compositor_receiver, @@ -161,3 +152,55 @@ impl Browser { self.compositor.shutdown(); } } +fn create_constellation(opts: opts::Opts, + compositor_proxy: Box<CompositorProxy+Send>, + time_profiler_chan: time::ProfilerChan, + devtools_chan: Option<Sender<devtools_traits::DevtoolsControlMsg>>, + mem_profiler_chan: mem::ProfilerChan, + shared_task_pool: TaskPool) -> ConstellationChan { + use std::env; + + // Create a Servo instance. + let resource_task = new_resource_task(opts.user_agent.clone()); + + // If we are emitting an output file, then we need to block on + // image load or we risk emitting an output file missing the + // image. + let image_cache_task: ImageCacheTask = if opts.output_file.is_some() { + ImageCacheTaskFactory::new_sync(resource_task.clone(), shared_task_pool, + time_profiler_chan.clone(), LoadPlaceholder::Preload) + } else { + ImageCacheTaskFactory::new(resource_task.clone(), shared_task_pool, + time_profiler_chan.clone(), LoadPlaceholder::Preload) + }; + + let font_cache_task = FontCacheTask::new(resource_task.clone()); + let storage_task: StorageTask = StorageTaskFactory::new(); + + let constellation_chan = Constellation::<layout::layout_task::LayoutTask, + script::script_task::ScriptTask>::start( + compositor_proxy.clone_compositor_proxy(), + resource_task, + image_cache_task, + font_cache_task, + time_profiler_chan.clone(), + mem_profiler_chan.clone(), + devtools_chan, + storage_task); + + // Send the URL command to the constellation. + let cwd = env::current_dir().unwrap(); + let url = match url::Url::parse(&opts.url) { + Ok(url) => url, + Err(url::ParseError::RelativeUrlWithoutBase) + => url::Url::from_file_path(&*cwd.join(&opts.url)).unwrap(), + Err(_) => panic!("URL parsing failed"), + }; + + { + let ConstellationChan(ref chan) = constellation_chan; + chan.send(ConstellationMsg::InitLoadUrl(url)).unwrap(); + } + + constellation_chan +} |