diff options
author | Tim Kuehn <tkuehn@cmu.edu> | 2013-06-28 16:45:56 -0700 |
---|---|---|
committer | Tim Kuehn <tkuehn@cmu.edu> | 2013-07-02 17:26:30 -0700 |
commit | a6eaffcd93c27fdec4f67eb0ebeeca7269fee013 (patch) | |
tree | e60223997b6d302f21e8bdc5f871dc8ea244c321 /src | |
parent | d17a1f2ad731f45286613d5651ce070cbc9bd286 (diff) | |
download | servo-a6eaffcd93c27fdec4f67eb0ebeeca7269fee013.tar.gz servo-a6eaffcd93c27fdec4f67eb0ebeeca7269fee013.zip |
forward/back navigation with shift+backspace and backspace
script caches last loaded url -- currently no caching policy
naive caching of render layers for near-instant forward/back
handling evicted pipelines is currently broken
Diffstat (limited to 'src')
-rw-r--r-- | src/components/gfx/render_task.rs | 23 | ||||
-rw-r--r-- | src/components/main/compositing/mod.rs | 21 | ||||
-rw-r--r-- | src/components/main/constellation.rs | 122 | ||||
-rw-r--r-- | src/components/main/layout/layout_task.rs | 1 | ||||
-rw-r--r-- | src/components/main/layout/text.rs | 2 | ||||
-rw-r--r-- | src/components/main/pipeline.rs | 19 | ||||
-rw-r--r-- | src/components/main/platform/common/glut_windowing.rs | 41 | ||||
-rw-r--r-- | src/components/main/windowing.rs | 12 | ||||
-rw-r--r-- | src/components/msg/compositor.rs | 2 | ||||
-rw-r--r-- | src/components/msg/constellation.rs | 5 | ||||
-rw-r--r-- | src/components/script/dom/characterdata.rs | 2 | ||||
-rw-r--r-- | src/components/script/dom/node.rs | 2 | ||||
-rw-r--r-- | src/components/script/html/cssparse.rs | 1 | ||||
-rw-r--r-- | src/components/script/script_task.rs | 55 | ||||
-rw-r--r-- | src/components/util/time.rs | 2 | ||||
m--------- | src/support/alert/rust-alert | 0 |
16 files changed, 213 insertions, 97 deletions
diff --git a/src/components/gfx/render_task.rs b/src/components/gfx/render_task.rs index db0083d5876..b0fed806ef2 100644 --- a/src/components/gfx/render_task.rs +++ b/src/components/gfx/render_task.rs @@ -21,7 +21,6 @@ use render_context::RenderContext; use std::cell::Cell; use std::comm::{Chan, Port, SharedChan}; use std::uint; -use std::util::replace; use servo_util::time::{ProfilerChan, profile}; use servo_util::time; @@ -73,7 +72,7 @@ priv struct RenderTask<C> { /// A token that grants permission to send paint messages to compositor compositor_token: Option<~CompositorToken>, /// Cached copy of last layers rendered - next_paint_msg: Option<(LayerBufferSet, Size2D<uint>)>, + last_paint_msg: Option<(LayerBufferSet, Size2D<uint>)>, } impl<C: RenderListener + Owned> RenderTask<C> { @@ -108,7 +107,7 @@ impl<C: RenderListener + Owned> RenderTask<C> { constellation_chan: constellation_chan.take(), compositor_token: None, - next_paint_msg: None, + last_paint_msg: None, }; render_task.start(); @@ -129,11 +128,9 @@ impl<C: RenderListener + Owned> RenderTask<C> { } TokenBestowMsg(token) => { self.compositor_token = Some(token); - let next_paint_msg = replace(&mut self.next_paint_msg, None); - match next_paint_msg { - Some((layer_buffer_set, layer_size)) => { - println("retrieving cached paint msg"); - self.compositor.paint(layer_buffer_set, layer_size); + match self.last_paint_msg { + Some((ref layer_buffer_set, ref layer_size)) => { + self.compositor.paint(layer_buffer_set.clone(), *layer_size); self.compositor.set_render_state(IdleRenderState); } None => {} @@ -162,7 +159,7 @@ impl<C: RenderListener + Owned> RenderTask<C> { } self.compositor.set_render_state(RenderingRenderState); - do profile(time::RenderingCategory, self.profiler_chan.clone()) { + do time::profile(time::RenderingCategory, self.profiler_chan.clone()) { let tile_size = self.opts.tile_size; // FIXME: Try not to create a new array here. @@ -235,12 +232,10 @@ impl<C: RenderListener + Owned> RenderTask<C> { debug!("render_task: returning surface"); if self.compositor_token.is_some() { - self.compositor.paint(layer_buffer_set, render_layer.size); - } - else { - println("caching paint msg"); - self.next_paint_msg = Some((layer_buffer_set, render_layer.size)); + self.compositor.paint(layer_buffer_set.clone(), render_layer.size); } + debug!("caching paint msg"); + self.last_paint_msg = Some((layer_buffer_set, render_layer.size)); self.compositor.set_render_state(IdleRenderState); } } diff --git a/src/components/main/compositing/mod.rs b/src/components/main/compositing/mod.rs index 873c46a645a..e8a847e5c30 100644 --- a/src/components/main/compositing/mod.rs +++ b/src/components/main/compositing/mod.rs @@ -4,12 +4,14 @@ use platform::{Application, Window}; use script::dom::event::{Event, ClickEvent, MouseDownEvent, MouseUpEvent, ResizeEvent}; -use script::script_task::{LoadMsg, SendEventMsg}; +use script::script_task::{LoadMsg, NavigateMsg, SendEventMsg}; use script::layout_interface::{LayoutChan, RouteScriptMsg}; use windowing::{ApplicationMethods, WindowMethods, WindowMouseEvent, WindowClickEvent}; use windowing::{WindowMouseDownEvent, WindowMouseUpEvent}; + use servo_msg::compositor::{RenderListener, LayerBufferSet, RenderState}; use servo_msg::compositor::{ReadyState, ScriptListener}; +use servo_msg::constellation; use gfx::render_task::{RenderChan, ReRenderMsg}; use azure::azure_hl::{DataSourceSurface, DrawTarget, SourceSurfaceMethods, current_gl_context}; @@ -32,6 +34,7 @@ use servo_util::{time, url}; use servo_util::time::profile; use servo_util::time::ProfilerChan; +pub use windowing; /// The implementation of the layers-based compositor. #[deriving(Clone)] @@ -180,13 +183,22 @@ impl CompositorTask { let update_layout_callbacks: @fn(LayoutChan) = |layout_chan: LayoutChan| { let layout_chan_clone = layout_chan.clone(); + do window.set_navigation_callback |direction| { + let direction = match direction { + windowing::Forward => constellation::Forward, + windowing::Back => constellation::Back, + }; + layout_chan_clone.send(RouteScriptMsg(NavigateMsg(direction))); + } + + let layout_chan_clone = layout_chan.clone(); // Hook the windowing system's resize callback up to the resize rate limiter. do window.set_resize_callback |width, height| { let new_size = Size2D(width as int, height as int); if *window_size != new_size { debug!("osmain: window resized to %ux%u", width, height); *window_size = new_size; - layout_chan_clone.chan.send(RouteScriptMsg(SendEventMsg(ResizeEvent(width, height)))); + layout_chan_clone.send(RouteScriptMsg(SendEventMsg(ResizeEvent(width, height)))); } else { debug!("osmain: dropping window resize since size is still %ux%u", width, height); } @@ -197,7 +209,7 @@ impl CompositorTask { // When the user enters a new URL, load it. do window.set_load_url_callback |url_string| { debug!("osmain: loading URL `%s`", url_string); - layout_chan_clone.chan.send(RouteScriptMsg(LoadMsg(url::make_url(url_string.to_str(), None)))); + layout_chan_clone.send(RouteScriptMsg(LoadMsg(url::make_url(url_string.to_str(), None)))); } let layout_chan_clone = layout_chan.clone(); @@ -229,7 +241,7 @@ impl CompositorTask { event = MouseUpEvent(button, world_mouse_point(layer_mouse_point)); } } - layout_chan_clone.chan.send(RouteScriptMsg(SendEventMsg(event))); + layout_chan_clone.send(RouteScriptMsg(SendEventMsg(event))); } }; @@ -410,6 +422,7 @@ impl CompositorTask { window.set_needs_display() } + // Enter the main event loop. while !*done { // Check for new messages coming from the rendering task. diff --git a/src/components/main/constellation.rs b/src/components/main/constellation.rs index bed38b8739f..c522bb033ef 100644 --- a/src/components/main/constellation.rs +++ b/src/components/main/constellation.rs @@ -12,14 +12,15 @@ use gfx::opts::Opts; use gfx::render_task::{TokenBestowMsg, TokenProcureMsg}; use pipeline::Pipeline; use servo_msg::compositor::{CompositorToken}; -use servo_msg::constellation::{ConstellationChan, ExitMsg, LoadUrlMsg, Msg, RendererReadyMsg}; -use servo_msg::constellation::TokenSurrenderMsg; -use script::script_task::{ExecuteMsg, LoadMsg}; +use servo_msg::constellation::{ConstellationChan, ExitMsg, LoadUrlMsg, Msg, NavigateMsg}; +use servo_msg::constellation::{Forward, Back, RendererReadyMsg, TokenSurrenderMsg}; +use script::script_task::ExecuteMsg; use servo_net::image_cache_task::{ImageCacheTask, ImageCacheTaskClient}; use servo_net::resource_task::ResourceTask; use servo_net::resource_task; use servo_util::time::ProfilerChan; use std::hashmap::HashMap; +use std::util::replace; pub struct Constellation { chan: ConstellationChan, @@ -30,12 +31,20 @@ pub struct Constellation { pipelines: HashMap<uint, Pipeline>, navigation_context: NavigationContext, next_id: uint, - current_token_holder: Option<uint>, - loading: Option<uint>, + current_token_bearer: Option<uint>, + next_token_bearer: Option<(uint, NavigationType)>, + compositor_token: Option<~CompositorToken>, profiler_chan: ProfilerChan, opts: Opts, } +/// Represents the two different ways to which a page can be navigated +enum NavigationType { + Load, // entered or clicked on a url + Navigate, // browser forward/back buttons +} + +/// Stores the ID's of the pipelines previous and next in the browser's history pub struct NavigationContext { previous: ~[uint], next: ~[uint], @@ -52,18 +61,16 @@ impl NavigationContext { } pub fn back(&mut self) -> uint { - do self.current.mutate |id| { - self.next.push(id); - self.previous.pop() - } + self.next.push(self.current.get()); + self.current = Some(self.previous.pop()); + debug!("previous: %? next: %? current: %?", self.previous, self.next, self.current); self.current.get() } pub fn forward(&mut self) -> uint { - do self.current.mutate |id| { - self.previous.push(id); - self.next.pop() - } + self.previous.push(self.current.get()); + self.current = Some(self.next.pop()); + debug!("previous: %? next: %? current: %?", self.previous, self.next, self.current); self.current.get() } @@ -102,8 +109,9 @@ impl Constellation { pipelines: HashMap::new(), navigation_context: NavigationContext::new(), next_id: 0, - current_token_holder: None, - loading: None, + current_token_bearer: None, + next_token_bearer: None, + compositor_token: Some(~CompositorToken::new()), profiler_chan: profiler_chan.clone(), opts: opts.take(), }; @@ -122,17 +130,19 @@ impl Constellation { } } + /// Helper function for getting a unique pipeline ID fn get_next_id(&mut self) -> uint { let id = self.next_id; self.next_id = id + 1; id } + /// Handles loading pages, navigation, and granting access to the compositor fn handle_request(&mut self, request: Msg) -> bool { match request { LoadUrlMsg(url) => { let pipeline_id = self.get_next_id(); - let pipeline = Pipeline::create(pipeline_id, + let mut pipeline = Pipeline::create(pipeline_id, self.chan.clone(), self.compositor_chan.clone(), self.image_cache_task.clone(), @@ -142,23 +152,41 @@ impl Constellation { if url.path.ends_with(".js") { pipeline.script_chan.send(ExecuteMsg(url)); } else { - pipeline.script_chan.send(LoadMsg(url)); - self.loading = Some(pipeline_id); + pipeline.load(url); + self.next_token_bearer = Some((pipeline_id, Load)); } self.pipelines.insert(pipeline_id, pipeline); } + NavigateMsg(direction) => { + debug!("received message to navigate %?", direction); + let destination_id = match direction { + Forward => { + if self.navigation_context.next.is_empty() { + debug!("no next page to navigate to"); + return true + } + self.navigation_context.forward() + } + Back => { + if self.navigation_context.previous.is_empty() { + debug!("no previous page to navigate to"); + return true + } + self.navigation_context.back() + } + }; + debug!("navigating to pipeline %u", destination_id); + self.pipelines.get(&destination_id).reload(); + self.next_token_bearer = Some((destination_id, Navigate)); + self.procure_or_bestow(); + } + RendererReadyMsg(pipeline_id) => { - let loading = self.loading.clone(); - do loading.map() |&id| { + let next_token_bearer = self.next_token_bearer; + for next_token_bearer.iter().advance |&(id, _)| { if pipeline_id == id { - match self.current_token_holder { - Some(ref id) => { - let current_holder = self.pipelines.get(id); - current_holder.render_chan.send(TokenProcureMsg); - } - None => self.bestow_compositor_token(id, ~CompositorToken::new()) - } + self.procure_or_bestow(); } }; } @@ -166,9 +194,9 @@ impl Constellation { TokenSurrenderMsg(token) => { self.remove_active_pipeline(); let token = Cell::new(token); - let loading = self.loading; - do loading.map |&id| { - self.bestow_compositor_token(id, token.take()); + let next_token_bearer = self.next_token_bearer; + for next_token_bearer.iter().advance |&(id, nav_type)| { + self.bestow_compositor_token(id, token.take(), nav_type); }; } @@ -186,23 +214,45 @@ impl Constellation { true } + /// Either procures the token, sends the token to next bearer, or does nothing if waiting for token surrender. + fn procure_or_bestow(&mut self) { + let current_token_bearer = replace(&mut self.current_token_bearer, None); + match current_token_bearer { + Some(ref id) => { + let pipeline = self.pipelines.get(id); + pipeline.render_chan.send(TokenProcureMsg); + } + None => { + let compositor_token = replace(&mut self.compositor_token, None); + for compositor_token.iter().advance |&token| { + let (id, nav_type) = self.next_token_bearer.get(); + self.bestow_compositor_token(id, token, nav_type); + } + } + }; + } + fn remove_active_pipeline(&mut self) { // FIXME(tkuehn): currently, pipelines are not removed at all -// do self.current_token_holder.map |id| { +// do self.current_token_bearer.map |id| { // self.pipelines.pop(id).unwrap().exit(); // }; - self.current_token_holder = None; + self.current_token_bearer = None; } - fn bestow_compositor_token(&mut self, id: uint, compositor_token: ~CompositorToken) { + fn bestow_compositor_token(&mut self, id: uint, compositor_token: ~CompositorToken, navigation_type: NavigationType) { let pipeline = self.pipelines.get(&id); pipeline.render_chan.send(TokenBestowMsg(compositor_token)); self.compositor_chan.send(SetLayoutChan(pipeline.layout_chan.clone())); self.compositor_chan.send(SetRenderChan(pipeline.render_chan.clone())); - self.current_token_holder = Some(id); - self.loading = None; - self.navigation_context.navigate(id); + self.current_token_bearer = Some(id); + self.next_token_bearer = None; + // Don't navigate on Navigate type, because that is handled by forward/back + match navigation_type { + Load => self.navigation_context.navigate(id), + _ => {} + } } } diff --git a/src/components/main/layout/layout_task.rs b/src/components/main/layout/layout_task.rs index cab29204559..0f93798af10 100644 --- a/src/components/main/layout/layout_task.rs +++ b/src/components/main/layout/layout_task.rs @@ -141,6 +141,7 @@ impl LayoutTask { } } RouteScriptMsg(script_msg) => { + debug!("layout: routing %? to script task", script_msg); self.route_script_msg(script_msg); } ExitMsg => { diff --git a/src/components/main/layout/text.rs b/src/components/main/layout/text.rs index b6b3e43eb99..59093ed70ff 100644 --- a/src/components/main/layout/text.rs +++ b/src/components/main/layout/text.rs @@ -234,7 +234,7 @@ impl TextRunScanner { for clump.eachi |i| { let range = new_ranges[i - self.clump.begin()]; if range.length() == 0 { - error!("Elided an `UnscannedTextbox` because it was zero-length after \ + debug!("Elided an `UnscannedTextbox` because it was zero-length after \ compression; %s", in_boxes[i].debug_str()); loop diff --git a/src/components/main/pipeline.rs b/src/components/main/pipeline.rs index 0a801d7d577..dcb14569c4c 100644 --- a/src/components/main/pipeline.rs +++ b/src/components/main/pipeline.rs @@ -2,13 +2,14 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use extra::net::url::Url; use compositing::CompositorChan; use gfx::render_task::{RenderChan, RenderTask}; use gfx::render_task; use gfx::opts::Opts; use layout::layout_task::LayoutTask; use script::layout_interface::LayoutChan; -use script::layout_interface; +use script::script_task::LoadMsg; use servo_msg::constellation::{ConstellationChan}; use script::script_task::{ScriptTask, ScriptChan, ScriptMsg}; use script::script_task; @@ -23,6 +24,8 @@ pub struct Pipeline { script_chan: ScriptChan, layout_chan: LayoutChan, render_chan: RenderChan, + /// The most recently loaded url + url: Option<Url>, } impl Pipeline { @@ -90,12 +93,24 @@ impl Pipeline { script_chan: script_chan, layout_chan: layout_chan, render_chan: render_chan, + url: None, + } + } + + pub fn load(&mut self, url: Url) { + self.url = Some(url.clone()); + self.script_chan.send(LoadMsg(url)); + } + + pub fn reload(&self) { + for self.url.iter().advance |&url| { + self.script_chan.send(LoadMsg(url)); } } pub fn exit(&self) { + // Script task handles shutting down layout, as well self.script_chan.send(script_task::ExitMsg); - self.layout_chan.send(layout_interface::ExitMsg); let (response_port, response_chan) = comm::stream(); self.render_chan.send(render_task::ExitMsg(response_chan)); diff --git a/src/components/main/platform/common/glut_windowing.rs b/src/components/main/platform/common/glut_windowing.rs index a47fab68acc..da07fa99ef0 100644 --- a/src/components/main/platform/common/glut_windowing.rs +++ b/src/components/main/platform/common/glut_windowing.rs @@ -9,7 +9,7 @@ use windowing::{ApplicationMethods, CompositeCallback, LoadUrlCallback, MouseCallback}; use windowing::{ResizeCallback, ScrollCallback, WindowMethods, WindowMouseEvent, WindowClickEvent}; -use windowing::{WindowMouseDownEvent, WindowMouseUpEvent, ZoomCallback}; +use windowing::{WindowMouseDownEvent, WindowMouseUpEvent, ZoomCallback, Forward, Back, NavigationCallback}; use alert::{Alert, AlertMethods}; use std::libc::c_int; @@ -17,7 +17,8 @@ use geom::point::Point2D; use geom::size::Size2D; use servo_msg::compositor::{IdleRenderState, RenderState, RenderingRenderState}; use servo_msg::compositor::{FinishedLoading, Loading, PerformingLayout, ReadyState}; -use glut::glut::{ACTIVE_CTRL, DOUBLE, HAVE_PRECISE_MOUSE_WHEEL, WindowHeight, WindowWidth}; +use glut::glut::{ACTIVE_CTRL, ACTIVE_SHIFT, DOUBLE, HAVE_PRECISE_MOUSE_WHEEL, WindowHeight}; +use glut::glut::WindowWidth; use glut::glut; use glut::machack; @@ -44,6 +45,7 @@ pub struct Window { mouse_callback: Option<MouseCallback>, scroll_callback: Option<ScrollCallback>, zoom_callback: Option<ZoomCallback>, + navigation_callback: Option<NavigationCallback>, drag_origin: Point2D<c_int>, @@ -72,6 +74,7 @@ impl WindowMethods<Application> for Window { mouse_callback: None, scroll_callback: None, zoom_callback: None, + navigation_callback: None, drag_origin: Point2D(0 as c_int, 0), @@ -177,6 +180,11 @@ impl WindowMethods<Application> for Window { self.zoom_callback = Some(new_zoom_callback) } + /// Registers a callback to be run when backspace or shift-backspace is pressed. + pub fn set_navigation_callback(&mut self, new_navigation_callback: NavigationCallback) { + self.navigation_callback = Some(new_navigation_callback) + } + /// Spins the event loop. pub fn check_loop(@mut self) { glut::check_loop() @@ -226,20 +234,33 @@ impl Window { /// Helper function to handle keyboard events. fn handle_key(&self, key: u8) { - debug!("got key: %d", key as int); + debug!("got key: %?", key); + let modifiers = glut::get_modifiers(); match key { - 12 => self.load_url(), // Ctrl+L - k if k == ('=' as u8) && (glut::get_modifiers() & ACTIVE_CTRL) != 0 => { // Ctrl++ + 12 => self.load_url(), // Ctrl+L + 31 if (modifiers & ACTIVE_CTRL) != 0 => { // Ctrl+- for self.zoom_callback.iter().advance |&callback| { - callback(0.1); + callback(-0.1); } } - k if k == 31 && (glut::get_modifiers() & ACTIVE_CTRL) != 0 => { // Ctrl+- - for self.zoom_callback.iter().advance |&callback| { - callback(-0.1); + 127 => { + for self.navigation_callback.iter().advance |&callback| { + if (modifiers & ACTIVE_SHIFT) != 0 { // Shift+Backspace + callback(Forward); + } + else { + callback(Back); + } + } + } + c => match c as char { + '=' if (modifiers & ACTIVE_CTRL) != 0 => { // Ctrl++ + for self.zoom_callback.iter().advance |&callback| { + callback(0.1); + } } + _ => {} } - _ => {} } } diff --git a/src/components/main/windowing.rs b/src/components/main/windowing.rs index 56a6cbcb0ab..dc9f5472b6c 100644 --- a/src/components/main/windowing.rs +++ b/src/components/main/windowing.rs @@ -14,6 +14,11 @@ pub enum WindowMouseEvent { WindowMouseUpEvent(uint, Point2D<f32>), } +pub enum WindowNavigateMsg { + Forward, + Back, +} + /// Type of the function that is called when the screen is to be redisplayed. pub type CompositeCallback = @fn(); @@ -29,9 +34,12 @@ pub type MouseCallback = @fn(WindowMouseEvent); /// Type of the function that is called when the user scrolls. pub type ScrollCallback = @fn(Point2D<f32>); -///Type of the function that is called when the user zooms. +/// Type of the function that is called when the user zooms. pub type ZoomCallback = @fn(f32); +/// Type of the function that is called when the user clicks backspace or shift-backspace +pub type NavigationCallback = @fn(WindowNavigateMsg); + /// Methods for an abstract Application. pub trait ApplicationMethods { fn new() -> Self; @@ -57,6 +65,8 @@ pub trait WindowMethods<A> { pub fn set_scroll_callback(&mut self, new_scroll_callback: ScrollCallback); /// Registers a callback to run when the user zooms. pub fn set_zoom_callback(&mut self, new_zoom_callback: ZoomCallback); + /// Registers a callback to run when the user presses backspace or shift-backspace. + pub fn set_navigation_callback(&mut self, new_navigation_callback: NavigationCallback); /// Spins the event loop. pub fn check_loop(@mut self); diff --git a/src/components/msg/compositor.rs b/src/components/msg/compositor.rs index 6d8fe2ecc50..d677cdfdaf1 100644 --- a/src/components/msg/compositor.rs +++ b/src/components/msg/compositor.rs @@ -8,6 +8,7 @@ use geom::rect::Rect; use geom::size::Size2D; use std::util::NonCopyable; +#[deriving(Clone)] pub struct LayerBuffer { draw_target: DrawTarget, @@ -23,6 +24,7 @@ pub struct LayerBuffer { /// A set of layer buffers. This is an atomic unit used to switch between the front and back /// buffers. +#[deriving(Clone)] pub struct LayerBufferSet { buffers: ~[LayerBuffer] } diff --git a/src/components/msg/constellation.rs b/src/components/msg/constellation.rs index b0b97ba528a..aa6442a525d 100644 --- a/src/components/msg/constellation.rs +++ b/src/components/msg/constellation.rs @@ -27,8 +27,13 @@ impl ConstellationChan { pub enum Msg { LoadUrlMsg(Url), + NavigateMsg(NavigationDirection), ExitMsg(Chan<()>), RendererReadyMsg(uint), TokenSurrenderMsg(~CompositorToken), } +pub enum NavigationDirection { + Forward, + Back, +} diff --git a/src/components/script/dom/characterdata.rs b/src/components/script/dom/characterdata.rs index 91838432f6b..9d77d3b64ee 100644 --- a/src/components/script/dom/characterdata.rs +++ b/src/components/script/dom/characterdata.rs @@ -7,8 +7,6 @@ use dom::bindings::utils::{DOMString, null_string, str}; use dom::node::{Node, NodeTypeId, ScriptView}; -use std::str; - pub struct CharacterData { parent: Node<ScriptView>, data: DOMString diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index d415288bfa2..c573f9912fb 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -367,7 +367,7 @@ impl<View> AbstractNode<View> { pub fn dump_indent(&self, indent: uint) { let mut s = ~""; for uint::range(0u, indent) |_i| { - s += ~" "; + s += " "; } s += self.debug_str(); diff --git a/src/components/script/html/cssparse.rs b/src/components/script/html/cssparse.rs index 1278ba47f6c..95a600682ac 100644 --- a/src/components/script/html/cssparse.rs +++ b/src/components/script/html/cssparse.rs @@ -8,7 +8,6 @@ use std::cell::Cell; use std::comm; use std::comm::Port; use std::task; -use std::str; use newcss::stylesheet::Stylesheet; use newcss::util::DataStream; use servo_net::resource_task::{ResourceTask, ProgressMsg, Load, Payload, Done}; diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs index 00b5611caba..8acee44e891 100644 --- a/src/components/script/script_task.rs +++ b/src/components/script/script_task.rs @@ -19,7 +19,9 @@ use layout_interface::{LayoutChan, MatchSelectorsDocumentDamage, QueryMsg, Reflo use layout_interface::{ReflowDocumentDamage, ReflowForDisplay, ReflowForScriptQuery, ReflowGoal}; use layout_interface::ReflowMsg; use layout_interface; -use servo_msg::constellation::{ConstellationChan, LoadUrlMsg, RendererReadyMsg}; +use servo_msg::constellation::{ConstellationChan, LoadUrlMsg, NavigationDirection}; +use servo_msg::constellation::RendererReadyMsg; +use servo_msg::constellation; use std::cast::transmute; use std::cell::Cell; @@ -53,6 +55,8 @@ pub enum ScriptMsg { LoadMsg(Url), /// Executes a standalone script. ExecuteMsg(Url), + /// Instructs the script task to send a navigate message to the constellation. + NavigateMsg(NavigationDirection), /// Sends a DOM event. SendEventMsg(Event), /// Fires a JavaScript timeout. @@ -136,6 +140,11 @@ pub struct ScriptTask { window_size: Size2D<uint>, /// What parts of the document are dirty, if any. damage: Option<DocumentDamage>, + + /// Cached copy of the most recent url loaded by the script + /// TODO(tkuehn): this currently does not follow any particular caching policy + /// and simply caches pages forever (!). + last_loaded_url: Option<Url>, } fn global_script_context_key(_: @ScriptTask) {} @@ -212,6 +221,8 @@ impl ScriptTask { window_size: Size2D(800u, 600), damage: None, + + last_loaded_url: None, }; // Indirection for Rust Issue #6248, dynamic freeze scope artifically extended let script_task_ptr = { @@ -264,31 +275,18 @@ impl ScriptTask { /// Handles an incoming control message. fn handle_msg(&mut self) -> bool { match self.script_port.recv() { - LoadMsg(url) => { - self.load(url); - true - } - ExecuteMsg(url) => { - self.handle_execute_msg(url); - true - } - SendEventMsg(event) => { - self.handle_event(event); - true - } - FireTimerMsg(timer_data) => { - self.handle_fire_timer_msg(timer_data); - true - } - ReflowCompleteMsg => { - self.handle_reflow_complete_msg(); - true - } + LoadMsg(url) => self.load(url), + ExecuteMsg(url) => self.handle_execute_msg(url), + SendEventMsg(event) => self.handle_event(event), + FireTimerMsg(timer_data) => self.handle_fire_timer_msg(timer_data), + NavigateMsg(direction) => self.handle_navigate_msg(direction), + ReflowCompleteMsg => self.handle_reflow_complete_msg(), ExitMsg => { self.handle_exit_msg(); - false + return false } } + true } /// Handles a request to execute a script. @@ -337,6 +335,11 @@ impl ScriptTask { self.compositor.set_ready_state(FinishedLoading); } + /// Handles a navigate forward or backward message. + fn handle_navigate_msg(&self, direction: NavigationDirection) { + self.constellation_chan.send(constellation::NavigateMsg(direction)); + } + /// Handles a request to exit the script task and shut down layout. fn handle_exit_msg(&mut self) { self.join_layout(); @@ -350,6 +353,9 @@ impl ScriptTask { /// The entry point to document loading. Defines bindings, sets up the window and document /// objects, parses HTML and CSS, and kicks off initial layout. fn load(&mut self, url: Url) { + for self.last_loaded_url.iter().advance |&last_loaded_url| { + if url == last_loaded_url { return; } + } // Define the script DOM bindings. // // FIXME: Can this be done earlier, to save the flag? @@ -362,7 +368,7 @@ impl ScriptTask { // Parse HTML. // // Note: We can parse the next document in parallel with any previous documents. - let html_parsing_result = hubbub_html_parser::parse_html(copy url, + let html_parsing_result = hubbub_html_parser::parse_html(url.clone(), self.resource_task.clone(), self.image_cache_task.clone()); @@ -396,7 +402,7 @@ impl ScriptTask { self.root_frame = Some(Frame { document: document, window: window, - url: url + url: url.clone(), }); // Perform the initial reflow. @@ -416,6 +422,7 @@ impl ScriptTask { ~"???", 1); } + self.last_loaded_url = Some(url); } /// Sends a ping to layout and waits for the response. The response will arrive when the diff --git a/src/components/util/time.rs b/src/components/util/time.rs index 00e222baaeb..ac94abcfb7a 100644 --- a/src/components/util/time.rs +++ b/src/components/util/time.rs @@ -152,7 +152,7 @@ impl Profiler { priv fn print_buckets(&mut self) { println(fmt!("%31s %15s %15s %15s %15s %15s", - "_category (ms)_", "_mean (ms)_", "_median (ms)_", + "_category_", "_mean (ms)_", "_median (ms)_", "_min (ms)_", "_max (ms)_", "_bucket size_")); for self.buckets.mut_iter().advance |bucket| { match *bucket { diff --git a/src/support/alert/rust-alert b/src/support/alert/rust-alert -Subproject 502ec156da38860a4dff911cf8f33f388a0a188 +Subproject 68875af396cb583e670dd5caad99431dac62f8d |