diff options
290 files changed, 6716 insertions, 6915 deletions
diff --git a/cargo-nightly-build b/cargo-nightly-build index 0211bdc0da7..eba5c5f63b2 100644 --- a/cargo-nightly-build +++ b/cargo-nightly-build @@ -1 +1 @@ -2014-12-18 +2015-01-09 diff --git a/components/canvas/canvas_paint_task.rs b/components/canvas/canvas_paint_task.rs index 6f9898c4c26..73941e03343 100644 --- a/components/canvas/canvas_paint_task.rs +++ b/components/canvas/canvas_paint_task.rs @@ -8,9 +8,10 @@ use geom::rect::Rect; use geom::size::Size2D; use servo_util::task::spawn_named; -use std::comm; +use std::borrow::ToOwned; +use std::sync::mpsc::{channel, Sender}; -#[deriving(Clone)] +#[derive(Clone)] pub enum CanvasMsg { FillRect(Rect<f32>), ClearRect(Rect<f32>), @@ -38,12 +39,12 @@ impl CanvasPaintTask { } pub fn start(size: Size2D<i32>) -> Sender<CanvasMsg> { - let (chan, port) = comm::channel::<CanvasMsg>(); - spawn_named("CanvasTask", proc() { + let (chan, port) = channel::<CanvasMsg>(); + spawn_named("CanvasTask".to_owned(), move || { let mut painter = CanvasPaintTask::new(size); loop { - match port.recv() { + match port.recv().unwrap() { CanvasMsg::FillRect(ref rect) => painter.fill_rect(rect), CanvasMsg::StrokeRect(ref rect) => painter.stroke_rect(rect), CanvasMsg::ClearRect(ref rect) => painter.clear_rect(rect), @@ -80,7 +81,7 @@ impl CanvasPaintTask { fn send_pixel_contents(&mut self, chan: Sender<Vec<u8>>) { self.drawtarget.snapshot().get_data_surface().with_data(|element| { - chan.send(element.to_vec()); + chan.send(element.to_vec()).unwrap(); }) } } diff --git a/components/compositing/Cargo.toml b/components/compositing/Cargo.toml index 6fb0ed57ca1..6c8864b4e8c 100644 --- a/components/compositing/Cargo.toml +++ b/components/compositing/Cargo.toml @@ -43,9 +43,6 @@ git = "https://github.com/servo/rust-layers" [dependencies.png] git = "https://github.com/servo/rust-png" -[dependencies.url] -git = "https://github.com/servo/rust-url" - [dependencies.core_graphics] git = "https://github.com/servo/rust-core-graphics" @@ -55,5 +52,6 @@ git = "https://github.com/servo/rust-core-text" [dependencies.gleam] git = "https://github.com/servo/gleam" -[dependencies.time] -git = "https://github.com/rust-lang/time" +[dependencies] +url = "*" +time = "*"
\ No newline at end of file diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index df0d505ad4e..ceee0b2f869 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -41,11 +41,12 @@ use servo_util::opts; use servo_util::time::{TimeProfilerCategory, profile, TimeProfilerChan}; use servo_util::{memory, time}; use std::collections::HashMap; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::path::Path; -use std::num::FloatMath; +use std::num::Float; use std::rc::Rc; use std::slice::bytes::copy_memory; +use std::sync::mpsc::Sender; use time::{precise_time_ns, precise_time_s}; use url::Url; @@ -71,7 +72,7 @@ pub struct IOCompositor<Window: WindowMethods> { scene: Scene<CompositorData>, /// The application window size. - window_size: TypedSize2D<DevicePixel, uint>, + window_size: TypedSize2D<DevicePixel, u32>, /// "Mobile-style" zoom that does not reflow the page. viewport_zoom: ScaleFactor<PagePx, ViewportPx, f32>, @@ -134,14 +135,14 @@ pub struct ScrollEvent { cursor: TypedPoint2D<DevicePixel,i32>, } -#[deriving(PartialEq)] +#[derive(PartialEq)] enum CompositionRequest { NoCompositingNecessary, CompositeOnScrollTimeout(u64), CompositeNow, } -#[deriving(Copy, PartialEq, Show)] +#[derive(Copy, PartialEq, Show)] enum ShutdownState { NotShuttingDown, ShuttingDown, @@ -250,8 +251,8 @@ impl<Window: WindowMethods> IOCompositor<Window> { (Msg::Exit(chan), _) => { debug!("shutting down the constellation"); let ConstellationChan(ref con_chan) = self.constellation_chan; - con_chan.send(ConstellationMsg::Exit); - chan.send(()); + con_chan.send(ConstellationMsg::Exit).unwrap(); + chan.send(()).unwrap(); self.shutdown_state = ShutdownState::ShuttingDown; } @@ -292,13 +293,13 @@ impl<Window: WindowMethods> IOCompositor<Window> { (Msg::ChangeLayerPipelineAndRemoveChildren(old_pipeline, new_pipeline, response_channel), ShutdownState::NotShuttingDown) => { self.handle_change_layer_pipeline_and_remove_children(old_pipeline, new_pipeline); - response_channel.send(()); + response_channel.send(()).unwrap(); } (Msg::CreateRootLayerForPipeline(parent_pipeline, pipeline, rect, response_channel), ShutdownState::NotShuttingDown) => { self.handle_create_root_layer_for_pipeline(parent_pipeline, pipeline, rect); - response_channel.send(()); + response_channel.send(()).unwrap(); } (Msg::CreateOrUpdateBaseLayer(layer_properties), ShutdownState::NotShuttingDown) => { @@ -311,7 +312,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { } (Msg::GetGraphicsMetadata(chan), ShutdownState::NotShuttingDown) => { - chan.send(Some(self.window.native_metadata())); + chan.send(Some(self.window.native_metadata())).unwrap(); } (Msg::SetLayerOrigin(pipeline_id, layer_id, origin), @@ -419,12 +420,12 @@ impl<Window: WindowMethods> IOCompositor<Window> { Some(ref details) => { match details.pipeline { Some(ref pipeline) => pipeline, - None => panic!("Compositor layer has an unitialized pipeline ({}).", + None => panic!("Compositor layer has an unitialized pipeline ({:?}).", pipeline_id), } } - None => panic!("Compositor layer has an unknown pipeline ({}).", pipeline_id), + None => panic!("Compositor layer has an unknown pipeline ({:?}).", pipeline_id), } } @@ -459,7 +460,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { if !self.has_paint_msg_tracking() { return; } - debug!("add_outstanding_paint_msg {}", self.outstanding_paint_msgs); + debug!("add_outstanding_paint_msg {:?}", self.outstanding_paint_msgs); self.outstanding_paint_msgs += count; } @@ -478,7 +479,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { frame_tree: &SendableFrameTree, response_chan: Sender<()>, new_constellation_chan: ConstellationChan) { - response_chan.send(()); + response_chan.send(()).unwrap(); self.root_pipeline = Some(frame_tree.pipeline.clone()); @@ -546,7 +547,8 @@ impl<Window: WindowMethods> IOCompositor<Window> { let root_layer = match self.find_pipeline_root_layer(old_pipeline.id) { Some(root_layer) => root_layer, None => { - debug!("Ignoring ChangeLayerPipelineAndRemoveChildren message for pipeline ({}) shutting down.", + debug!("Ignoring ChangeLayerPipelineAndRemoveChildren message \ + for pipeline ({:?}) shutting down.", old_pipeline.id); return; } @@ -555,6 +557,9 @@ impl<Window: WindowMethods> IOCompositor<Window> { root_layer.clear_all_tiles(self); root_layer.children().clear(); + debug_assert!(root_layer.extra_data.borrow().pipeline_id == old_pipeline.id); + root_layer.extra_data.borrow_mut().pipeline_id = new_pipeline.id; + let new_pipeline_id = new_pipeline.id; self.get_or_create_pipeline_details(new_pipeline_id).pipeline = Some(new_pipeline); } @@ -578,7 +583,8 @@ impl<Window: WindowMethods> IOCompositor<Window> { let parent_layer = match self.find_pipeline_root_layer(pipeline_id) { Some(root_layer) => root_layer, None => { - debug!("Ignoring FrameTreeUpdate message for pipeline ({}) shutting down.", + debug!("Ignoring FrameTreeUpdate message for pipeline ({:?}) \ + shutting down.", pipeline_id); return; } @@ -608,7 +614,8 @@ impl<Window: WindowMethods> IOCompositor<Window> { let root_layer = match self.find_pipeline_root_layer(pipeline_id) { Some(root_layer) => root_layer, None => { - debug!("Ignoring CreateOrUpdateBaseLayer message for pipeline ({}) shutting down.", + debug!("Ignoring CreateOrUpdateBaseLayer message for pipeline \ + ({:?}) shutting down.", pipeline_id); return; } @@ -666,7 +673,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { device_pixel_ratio: dppx, initial_viewport: initial_viewport, visible_viewport: visible_viewport, - })); + })).unwrap() } pub fn move_layer(&self, @@ -720,7 +727,8 @@ impl<Window: WindowMethods> IOCompositor<Window> { Some(ref layer) => { layer.bounds.borrow_mut().origin = Point2D::from_untyped(&new_origin) } - None => panic!("Compositor received SetLayerOrigin for nonexistent layer: {}", pipeline_id), + None => panic!("Compositor received SetLayerOrigin for nonexistent \ + layer: {:?}", pipeline_id), }; self.send_buffer_requests_for_all_layers(); @@ -741,14 +749,14 @@ impl<Window: WindowMethods> IOCompositor<Window> { let pipeline = self.get_pipeline(pipeline_id); let message = PaintMsg::UnusedBuffer(new_layer_buffer_set.buffers); - let _ = pipeline.paint_chan.send_opt(message); + let _ = pipeline.paint_chan.send(message); } fn assign_painted_buffers_to_layer(&mut self, layer: Rc<Layer<CompositorData>>, new_layer_buffer_set: Box<LayerBufferSet>, epoch: Epoch) { - debug!("compositor received new frame at size {}x{}", + debug!("compositor received new frame at size {:?}x{:?}", self.window_size.width.get(), self.window_size.height.get()); @@ -826,14 +834,14 @@ impl<Window: WindowMethods> IOCompositor<Window> { WindowEvent::Quit => { debug!("shutting down the constellation for WindowEvent::Quit"); let ConstellationChan(ref chan) = self.constellation_chan; - chan.send(ConstellationMsg::Exit); + chan.send(ConstellationMsg::Exit).unwrap(); self.shutdown_state = ShutdownState::ShuttingDown; } } } - fn on_resize_window_event(&mut self, new_size: TypedSize2D<DevicePixel, uint>) { - debug!("compositor resizing to {}", new_size.to_untyped()); + fn on_resize_window_event(&mut self, new_size: TypedSize2D<DevicePixel, u32>) { + debug!("compositor resizing to {:?}", new_size.to_untyped()); // A size change could also mean a resolution change. let new_hidpi_factor = self.window.hidpi_factor(); @@ -864,7 +872,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { let msg = ConstellationMsg::LoadUrl(root_pipeline_id, LoadData::new(Url::parse(url_string.as_slice()).unwrap())); let ConstellationChan(ref chan) = self.constellation_chan; - chan.send(msg); + chan.send(msg).unwrap() } fn on_mouse_window_event_class(&self, mouse_window_event: MouseWindowEvent) { @@ -983,12 +991,12 @@ impl<Window: WindowMethods> IOCompositor<Window> { windowing::WindowNavigateMsg::Back => NavigationDirection::Back, }; let ConstellationChan(ref chan) = self.constellation_chan; - chan.send(ConstellationMsg::Navigate(direction)) + chan.send(ConstellationMsg::Navigate(direction)).unwrap() } fn on_key_event(&self, key: Key, state: KeyState, modifiers: KeyModifiers) { let ConstellationChan(ref chan) = self.constellation_chan; - chan.send(ConstellationMsg::KeyEvent(key, state, modifiers)) + chan.send(ConstellationMsg::KeyEvent(key, state, modifiers)).unwrap() } fn convert_buffer_requests_to_pipeline_requests_map(&self, @@ -1005,7 +1013,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { entry.into_mut() } Vacant(entry) => { - entry.set(Vec::new()) + entry.insert(Vec::new()) } }; @@ -1032,7 +1040,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { let unused_buffers = self.scene.collect_unused_buffers(); if unused_buffers.len() != 0 { let message = PaintMsg::UnusedBuffer(unused_buffers); - let _ = pipeline.paint_chan.send_opt(message); + let _ = pipeline.paint_chan.send(message); } }, None => {} @@ -1045,7 +1053,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { layer.bounds.borrow().size.to_untyped()); let pipeline = self.get_pipeline(layer.get_pipeline_id()); let ScriptControlChan(ref chan) = pipeline.script_chan; - chan.send(ConstellationControlMsg::Viewport(pipeline.id.clone(), layer_rect)); + chan.send(ConstellationControlMsg::Viewport(pipeline.id.clone(), layer_rect)).unwrap(); } for kid in layer.children().iter() { @@ -1081,7 +1089,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { let mut num_paint_msgs_sent = 0; for (pipeline_id, requests) in pipeline_requests.into_iter() { num_paint_msgs_sent += 1; - let _ = self.get_pipeline(pipeline_id).paint_chan.send_opt(PaintMsg::Paint(requests)); + let _ = self.get_pipeline(pipeline_id).paint_chan.send(PaintMsg::Paint(requests)); } self.add_outstanding_paint_msg(num_paint_msgs_sent); @@ -1122,7 +1130,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { let mut framebuffer_ids = vec!(); let mut texture_ids = vec!(); - let (width, height) = (self.window_size.width.get(), self.window_size.height.get()); + let (width, height) = (self.window_size.width.get() as usize, self.window_size.height.get() as usize); if output_image { framebuffer_ids = gl::gen_framebuffers(1); @@ -1166,8 +1174,8 @@ impl<Window: WindowMethods> IOCompositor<Window> { }); if output_image { - let path = - from_str::<Path>(opts::get().output_file.as_ref().unwrap().as_slice()).unwrap(); + let path: Path = + opts::get().output_file.as_ref().unwrap().as_slice().parse().unwrap(); let mut pixels = gl::read_pixels(0, 0, width as gl::GLsizei, height as gl::GLsizei, @@ -1198,7 +1206,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { debug!("shutting down the constellation after generating an output file"); let ConstellationChan(ref chan) = self.constellation_chan; - chan.send(ConstellationMsg::Exit); + chan.send(ConstellationMsg::Exit).unwrap(); self.shutdown_state = ShutdownState::ShuttingDown; } @@ -1390,10 +1398,10 @@ impl<Window> CompositorEventListener for IOCompositor<Window> where Window: Wind // Tell the profiler, memory profiler, and scrolling timer to shut down. let TimeProfilerChan(ref time_profiler_chan) = self.time_profiler_chan; - time_profiler_chan.send(time::TimeProfilerMsg::Exit); + time_profiler_chan.send(time::TimeProfilerMsg::Exit).unwrap(); let MemoryProfilerChan(ref memory_profiler_chan) = self.memory_profiler_chan; - memory_profiler_chan.send(memory::MemoryProfilerMsg::Exit); + memory_profiler_chan.send(memory::MemoryProfilerMsg::Exit).unwrap(); self.scrolling_timer.shutdown(); } @@ -1408,6 +1416,6 @@ impl<Window> CompositorEventListener for IOCompositor<Window> where Window: Wind Some(ref root_pipeline) => root_pipeline.id, }; let ConstellationChan(ref chan) = self.constellation_chan; - chan.send(ConstellationMsg::GetPipelineTitle(root_pipeline_id)); + chan.send(ConstellationMsg::GetPipelineTitle(root_pipeline_id)).unwrap(); } } diff --git a/components/compositing/compositor_layer.rs b/components/compositing/compositor_layer.rs index 1510ea51fb4..d9f5ba21ca2 100644 --- a/components/compositing/compositor_layer.rs +++ b/components/compositing/compositor_layer.rs @@ -21,7 +21,6 @@ use script_traits::{ScriptControlChan, ConstellationControlMsg}; use servo_msg::compositor_msg::{Epoch, LayerId, ScrollPolicy}; use servo_msg::constellation_msg::PipelineId; use std::num::Float; -use std::num::FloatMath; use std::rc::Rc; pub struct CompositorData { @@ -68,24 +67,25 @@ impl CompositorData { } } -pub trait CompositorLayer<Window: WindowMethods> { +pub trait CompositorLayer { fn update_layer_except_bounds(&self, layer_properties: LayerProperties); fn update_layer(&self, layer_properties: LayerProperties); - fn add_buffers(&self, - compositor: &IOCompositor<Window>, - new_buffers: Box<LayerBufferSet>, - epoch: Epoch) - -> bool; + fn add_buffers<Window>(&self, + compositor: &IOCompositor<Window>, + new_buffers: Box<LayerBufferSet>, + epoch: Epoch) + -> bool + where Window: WindowMethods; /// Destroys all layer tiles, sending the buffers back to the painter to be destroyed or /// reused. - fn clear(&self, compositor: &IOCompositor<Window>); + fn clear<Window>(&self, compositor: &IOCompositor<Window>) where Window: WindowMethods; /// Destroys tiles for this layer and all descendent layers, sending the buffers back to the /// painter to be destroyed or reused. - fn clear_all_tiles(&self, compositor: &IOCompositor<Window>); + fn clear_all_tiles<Window>(&self, compositor: &IOCompositor<Window>) where Window: WindowMethods; /// Destroys all tiles of all layers, including children, *without* sending them back to the /// painter. You must call this only when the paint task is destined to be going down; @@ -107,14 +107,16 @@ pub trait CompositorLayer<Window: WindowMethods> { // Takes in a MouseWindowEvent, determines if it should be passed to children, and // sends the event off to the appropriate pipeline. NB: the cursor position is in // page coordinates. - fn send_mouse_event(&self, - compositor: &IOCompositor<Window>, - event: MouseWindowEvent, - cursor: TypedPoint2D<LayerPixel, f32>); + fn send_mouse_event<Window>(&self, + compositor: &IOCompositor<Window>, + event: MouseWindowEvent, + cursor: TypedPoint2D<LayerPixel, f32>) + where Window: WindowMethods; - fn send_mouse_move_event(&self, - compositor: &IOCompositor<Window>, - cursor: TypedPoint2D<LayerPixel, f32>); + fn send_mouse_move_event<Window>(&self, + compositor: &IOCompositor<Window>, + cursor: TypedPoint2D<LayerPixel, f32>) + where Window: WindowMethods; fn clamp_scroll_offset_and_scroll_layer(&self, new_offset: TypedPoint2D<LayerPixel, f32>) @@ -131,7 +133,7 @@ pub trait CompositorLayer<Window: WindowMethods> { fn get_pipeline_id(&self) -> PipelineId; } -#[deriving(Copy, PartialEq, Clone)] +#[derive(Copy, PartialEq, Clone)] pub enum WantsScrollEventsFlag { WantsScrollEvents, DoesntWantScrollEvents, @@ -167,14 +169,14 @@ fn calculate_content_size_for_layer(layer: &Layer<CompositorData>) }).size } -#[deriving(PartialEq)] +#[derive(PartialEq)] pub enum ScrollEventResult { ScrollEventUnhandled, ScrollPositionChanged, ScrollPositionUnchanged, } -impl<Window: WindowMethods> CompositorLayer<Window> for Layer<CompositorData> { +impl CompositorLayer for Layer<CompositorData> { fn update_layer_except_bounds(&self, layer_properties: LayerProperties) { self.extra_data.borrow_mut().epoch = layer_properties.epoch; self.extra_data.borrow_mut().scroll_policy = layer_properties.scroll_policy; @@ -199,18 +201,19 @@ impl<Window: WindowMethods> CompositorLayer<Window> for Layer<CompositorData> { // // If the epoch of the message does not match the layer's epoch, the message is ignored, the // layer buffer set is consumed, and None is returned. - fn add_buffers(&self, - compositor: &IOCompositor<Window>, - new_buffers: Box<LayerBufferSet>, - epoch: Epoch) - -> bool { + fn add_buffers<Window>(&self, + compositor: &IOCompositor<Window>, + new_buffers: Box<LayerBufferSet>, + epoch: Epoch) + -> bool + where Window: WindowMethods { if self.extra_data.borrow().epoch != epoch { - debug!("add_buffers: compositor epoch mismatch: {} != {}, id: {}", + debug!("add_buffers: compositor epoch mismatch: {:?} != {:?}, id: {:?}", self.extra_data.borrow().epoch, epoch, self.get_pipeline_id()); let pipeline = compositor.get_pipeline(self.get_pipeline_id()); - let _ = pipeline.paint_chan.send_opt(PaintMsg::UnusedBuffer(new_buffers.buffers)); + let _ = pipeline.paint_chan.send(PaintMsg::UnusedBuffer(new_buffers.buffers)); return false; } @@ -221,13 +224,13 @@ impl<Window: WindowMethods> CompositorLayer<Window> for Layer<CompositorData> { let unused_buffers = self.collect_unused_buffers(); if !unused_buffers.is_empty() { // send back unused buffers let pipeline = compositor.get_pipeline(self.get_pipeline_id()); - let _ = pipeline.paint_chan.send_opt(PaintMsg::UnusedBuffer(unused_buffers)); + let _ = pipeline.paint_chan.send(PaintMsg::UnusedBuffer(unused_buffers)); } return true; } - fn clear(&self, compositor: &IOCompositor<Window>) { + fn clear<Window>(&self, compositor: &IOCompositor<Window>) where Window: WindowMethods { let mut buffers = self.collect_buffers(); if !buffers.is_empty() { @@ -239,13 +242,15 @@ impl<Window: WindowMethods> CompositorLayer<Window> for Layer<CompositorData> { } let pipeline = compositor.get_pipeline(self.get_pipeline_id()); - let _ = pipeline.paint_chan.send_opt(PaintMsg::UnusedBuffer(buffers)); + let _ = pipeline.paint_chan.send(PaintMsg::UnusedBuffer(buffers)); } } /// Destroys tiles for this layer and all descendent layers, sending the buffers back to the /// painter to be destroyed or reused. - fn clear_all_tiles(&self, compositor: &IOCompositor<Window>) { + fn clear_all_tiles<Window>(&self, + compositor: &IOCompositor<Window>) + where Window: WindowMethods { self.clear(compositor); for kid in self.children().iter() { kid.clear_all_tiles(compositor); @@ -325,10 +330,11 @@ impl<Window: WindowMethods> CompositorLayer<Window> for Layer<CompositorData> { } } - fn send_mouse_event(&self, - compositor: &IOCompositor<Window>, - event: MouseWindowEvent, - cursor: TypedPoint2D<LayerPixel, f32>) { + fn send_mouse_event<Window>(&self, + compositor: &IOCompositor<Window>, + event: MouseWindowEvent, + cursor: TypedPoint2D<LayerPixel, f32>) + where Window: WindowMethods { let event_point = cursor.to_untyped(); let message = match event { MouseWindowEvent::Click(button, _) => @@ -341,16 +347,17 @@ impl<Window: WindowMethods> CompositorLayer<Window> for Layer<CompositorData> { let pipeline = compositor.get_pipeline(self.get_pipeline_id()); let ScriptControlChan(ref chan) = pipeline.script_chan; - let _ = chan.send_opt(ConstellationControlMsg::SendEvent(pipeline.id.clone(), message)); + let _ = chan.send(ConstellationControlMsg::SendEvent(pipeline.id.clone(), message)); } - fn send_mouse_move_event(&self, - compositor: &IOCompositor<Window>, - cursor: TypedPoint2D<LayerPixel, f32>) { + fn send_mouse_move_event<Window>(&self, + compositor: &IOCompositor<Window>, + cursor: TypedPoint2D<LayerPixel, f32>) + where Window: WindowMethods { let message = MouseMoveEvent(cursor.to_untyped()); let pipeline = compositor.get_pipeline(self.get_pipeline_id()); let ScriptControlChan(ref chan) = pipeline.script_chan; - let _ = chan.send_opt(ConstellationControlMsg::SendEvent(pipeline.id.clone(), message)); + let _ = chan.send(ConstellationControlMsg::SendEvent(pipeline.id.clone(), message)); } fn scroll_layer_and_all_child_layers(&self, new_offset: TypedPoint2D<LayerPixel, f32>) diff --git a/components/compositing/compositor_task.rs b/components/compositing/compositor_task.rs index 3ff651da281..2fba8bfa0f6 100644 --- a/components/compositing/compositor_task.rs +++ b/components/compositing/compositor_task.rs @@ -26,7 +26,7 @@ use servo_util::cursor::Cursor; use servo_util::geometry::PagePx; use servo_util::memory::MemoryProfilerChan; use servo_util::time::TimeProfilerChan; -use std::comm::{channel, Sender, Receiver}; +use std::sync::mpsc::{channel, Sender, Receiver}; use std::fmt::{Error, Formatter, Show}; use std::rc::Rc; @@ -42,7 +42,7 @@ pub trait CompositorProxy : 'static + Send { /// The port that the compositor receives messages on. As above, this is a trait supplied by the /// Servo port. -pub trait CompositorReceiver for Sized? : 'static { +pub trait CompositorReceiver : 'static { /// Receives the next message inbound for the compositor. This must not block. fn try_recv_compositor_msg(&mut self) -> Option<Msg>; /// Synchronously waits for, and returns, the next message inbound for the compositor. @@ -58,7 +58,7 @@ impl CompositorReceiver for Receiver<Msg> { } } fn recv_compositor_msg(&mut self) -> Msg { - self.recv() + self.recv().unwrap() } } @@ -79,7 +79,7 @@ impl ScriptListener for Box<CompositorProxy+'static+Send> { fn close(&mut self) { let (chan, port) = channel(); self.send(Msg::Exit(chan)); - port.recv(); + port.recv().unwrap(); } fn dup(&mut self) -> Box<ScriptListener+'static> { @@ -98,7 +98,7 @@ impl ScriptListener for Box<CompositorProxy+'static+Send> { } /// Information about each layer that the compositor keeps. -#[deriving(Copy)] +#[derive(Copy)] pub struct LayerProperties { pub pipeline_id: PipelineId, pub epoch: Epoch, @@ -129,7 +129,7 @@ impl PaintListener for Box<CompositorProxy+'static+Send> { fn get_graphics_metadata(&mut self) -> Option<NativeGraphicsMetadata> { let (chan, port) = channel(); self.send(Msg::GetGraphicsMetadata(chan)); - port.recv() + port.recv().unwrap() } fn assign_painted_buffers(&mut self, diff --git a/components/compositing/constellation.rs b/components/compositing/constellation.rs index fca671550b1..981fde200ce 100644 --- a/components/compositing/constellation.rs +++ b/components/compositing/constellation.rs @@ -17,7 +17,7 @@ use libc; use script_traits::{CompositorEvent, ConstellationControlMsg}; use script_traits::{ScriptControlChan, ScriptTaskFactory}; use servo_msg::compositor_msg::LayerId; -use servo_msg::constellation_msg::{mod, ConstellationChan, Failure}; +use servo_msg::constellation_msg::{self, ConstellationChan, Failure}; use servo_msg::constellation_msg::{IFrameSandboxState, NavigationDirection}; use servo_msg::constellation_msg::{Key, KeyState, KeyModifiers}; use servo_msg::constellation_msg::{LoadData, NavigationType}; @@ -33,11 +33,13 @@ use servo_util::geometry::{PagePx, ViewportPx}; use servo_util::opts; use servo_util::task::spawn_named; use servo_util::time::TimeProfilerChan; +use std::borrow::ToOwned; use std::cell::{Cell, RefCell}; use std::collections::{HashMap, HashSet}; use std::io; use std::mem::replace; use std::rc::Rc; +use std::sync::mpsc::{Receiver, channel}; use url::Url; /// Maintains the pipelines and navigation context and grants permission to composite. @@ -90,7 +92,7 @@ pub struct Constellation<LTF, STF> { } /// A unique ID used to identify a frame. -#[deriving(Copy)] +#[derive(Copy)] pub struct FrameId(u32); /// One frame in the hierarchy. @@ -124,7 +126,7 @@ impl FrameTree { } } -#[deriving(Clone)] +#[derive(Clone)] struct ChildFrameTree { frame_tree: Rc<FrameTree>, /// Clipping rect representing the size and position, in page coordinates, of the visible @@ -233,7 +235,8 @@ struct FrameTreeIterator { stack: Vec<Rc<FrameTree>>, } -impl Iterator<Rc<FrameTree>> for FrameTreeIterator { +impl Iterator for FrameTreeIterator { + type Item = Rc<FrameTree>; fn next(&mut self) -> Option<Rc<FrameTree>> { match self.stack.pop() { Some(next) => { @@ -293,7 +296,7 @@ impl NavigationContext { /// Loads a new set of page frames, returning all evicted frame trees fn load(&mut self, frame_tree: Rc<FrameTree>, compositor_proxy: &mut CompositorProxy) -> Vec<Rc<FrameTree>> { - debug!("navigating to {}", frame_tree.pipeline.borrow().id); + debug!("navigating to {:?}", frame_tree.pipeline.borrow().id); let evicted = replace(&mut self.next, vec!()); match self.current.take() { Some(current) => self.previous.push(current), @@ -349,7 +352,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { -> ConstellationChan { let (constellation_port, constellation_chan) = ConstellationChan::new(); let constellation_chan_clone = constellation_chan.clone(); - spawn_named("Constellation", proc() { + spawn_named("Constellation".to_owned(), move || { let mut constellation: Constellation<LTF, STF> = Constellation { chan: constellation_chan_clone, request_port: constellation_port, @@ -379,7 +382,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { fn run(&mut self) { loop { - let request = self.request_port.recv(); + let request = self.request_port.recv().unwrap(); if !self.handle_request(request) { break; } @@ -516,17 +519,17 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { pipeline.exit(PipelineExitType::Complete); } self.image_cache_task.exit(); - self.resource_task.send(resource_task::ControlMsg::Exit); + self.resource_task.send(resource_task::ControlMsg::Exit).unwrap(); self.devtools_chan.as_ref().map(|chan| { - chan.send(devtools_traits::ServerExitMsg); + chan.send(devtools_traits::ServerExitMsg).unwrap(); }); - self.storage_task.send(StorageTaskMsg::Exit); + self.storage_task.send(StorageTaskMsg::Exit).unwrap(); self.font_cache_task.exit(); self.compositor_proxy.send(CompositorMsg::ShutdownComplete); } fn handle_failure_msg(&mut self, pipeline_id: PipelineId, subpage_id: Option<SubpageId>) { - debug!("handling failure message from pipeline {}, {}", pipeline_id, subpage_id); + debug!("handling failure message from pipeline {:?}, {:?}", pipeline_id, subpage_id); if opts::get().hard_fail { // It's quite difficult to make Servo exit cleanly if some tasks have failed. @@ -603,11 +606,11 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { fn handle_frame_rect_msg(&mut self, pipeline_id: PipelineId, subpage_id: SubpageId, rect: TypedRect<PagePx, f32>) { - debug!("Received frame rect {} from {}, {}", rect, pipeline_id, subpage_id); + debug!("Received frame rect {:?} from {:?}, {:?}", rect, pipeline_id, subpage_id); let mut already_sent = HashSet::new(); // Returns true if a child frame tree's subpage id matches the given subpage id - let subpage_eq = |child_frame_tree: & &mut ChildFrameTree| { + let subpage_eq = |&:child_frame_tree: & &mut ChildFrameTree| { child_frame_tree.frame_tree.pipeline.borrow(). subpage_id.expect("Constellation: child frame does not have a subpage id. This should not be possible.") @@ -678,7 +681,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { visible_viewport: rect.size, initial_viewport: rect.size * ScaleFactor(1.0), device_pixel_ratio: device_pixel_ratio, - })); + })).unwrap(); compositor_proxy.send(CompositorMsg::SetLayerOrigin( pipeline.id, LayerId::null(), @@ -696,7 +699,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { old_subpage_id: SubpageId) { let existing_tree = match frame_tree.find_with_subpage_id(Some(old_subpage_id)) { Some(existing_tree) => existing_tree.clone(), - None => panic!("Tried to update non-existing frame tree with pipeline={} subpage={}", + None => panic!("Tried to update non-existing frame tree with pipeline={:?} subpage={:?}", new_pipeline.id, old_subpage_id), }; @@ -715,7 +718,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { old_pipeline.to_sendable(), new_pipeline.to_sendable(), chan)); - let _ = port.recv_opt(); + let _ = port.recv(); } fn create_or_update_child_pipeline(&mut self, @@ -769,10 +772,10 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { // FIXME(tkuehn): Need to follow the standardized spec for checking same-origin // Reuse the script task if the URL is same-origin let script_pipeline = if same_script { - debug!("Constellation: loading same-origin iframe at {}", url); + debug!("Constellation: loading same-origin iframe at {:?}", url); Some(source_pipeline.clone()) } else { - debug!("Constellation: loading cross-origin iframe at {}", url); + debug!("Constellation: loading cross-origin iframe at {:?}", url); None }; @@ -800,7 +803,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { fn handle_load_url_msg(&mut self, source_id: PipelineId, load_data: LoadData) { let url = load_data.url.to_string(); - debug!("Constellation: received message to load {}", url); + debug!("Constellation: received message to load {:?}", url); // Make sure no pending page would be overridden. let source_frame = self.current_frame().as_ref().unwrap().find(source_id).expect( "Constellation: received a LoadUrl message from a pipeline_id associated @@ -836,7 +839,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { } fn handle_navigate_msg(&mut self, direction: constellation_msg::NavigationDirection) { - debug!("received message to navigate {}", direction); + debug!("received message to navigate {:?}", direction); // TODO(tkuehn): what is the "critical point" beyond which pending frames // should not be cleared? Currently, the behavior is that forward/back @@ -872,7 +875,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { for frame in destination_frame.iter() { frame.pipeline.borrow().load(); } - self.grant_paint_permission(destination_frame, NavigationType::Navigate); + self.send_frame_tree_and_grant_paint_permission(destination_frame); } @@ -885,7 +888,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { self.current_frame().as_ref().map(|frame| { let ScriptControlChan(ref chan) = frame.pipeline.borrow().script_chan; chan.send(ConstellationControlMsg::SendEvent( - frame.pipeline.borrow().id, CompositorEvent::KeyEvent(key, state, mods))); + frame.pipeline.borrow().id, CompositorEvent::KeyEvent(key, state, mods))).unwrap(); }); } @@ -894,13 +897,13 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { None => self.compositor_proxy.send(CompositorMsg::ChangePageTitle(pipeline_id, None)), Some(pipeline) => { let ScriptControlChan(ref script_channel) = pipeline.script_chan; - script_channel.send(ConstellationControlMsg::GetTitle(pipeline_id)); + script_channel.send(ConstellationControlMsg::GetTitle(pipeline_id)).unwrap(); } } } fn handle_painter_ready_msg(&mut self, pipeline_id: PipelineId) { - debug!("Painter {} ready to send paint msg", pipeline_id); + debug!("Painter {:?} ready to send paint msg", pipeline_id); // This message could originate from a pipeline in the navigation context or // from a pending frame. The only time that we will grant paint permission is // when the message originates from a pending frame or the current frame. @@ -920,7 +923,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { }); match pending_index { Some(pending_index) => { - let frame_change = self.pending_frames.swap_remove(pending_index).unwrap(); + let frame_change = self.pending_frames.swap_remove(pending_index); let to_add = frame_change.after.clone(); // Create the next frame tree that will be given to the compositor @@ -934,7 +937,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { // If there are frames to revoke permission from, do so now. match frame_change.before { Some(revoke_id) if self.current_frame().is_some() => { - debug!("Constellation: revoking permission from {}", revoke_id); + debug!("Constellation: revoking permission from {:?}", revoke_id); let current_frame = self.current_frame().as_ref().unwrap(); let to_revoke = current_frame.find(revoke_id).expect( @@ -951,7 +954,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { let mut flag = false; { if to_add.parent.borrow().is_some() { - debug!("Constellation: replacing {} with {} in {}", + debug!("Constellation: replacing {:?} with {:?} in {:?}", revoke_id, to_add.pipeline.borrow().id, next_frame_tree.pipeline.borrow().id); flag = true; @@ -978,7 +981,9 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { } } - self.grant_paint_permission(next_frame_tree, frame_change.navigation_type); + self.send_frame_tree_and_grant_paint_permission(next_frame_tree.clone()); + self.handle_evicted_frames_for_load_navigation(next_frame_tree, + frame_change.navigation_type); }, None => (), } @@ -991,7 +996,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { debug!("constellation sending resize message to active frame"); let pipeline = &*frame_tree.pipeline.borrow();; let ScriptControlChan(ref chan) = pipeline.script_chan; - let _ = chan.send_opt(ConstellationControlMsg::Resize(pipeline.id, new_size)); + let _ = chan.send(ConstellationControlMsg::Resize(pipeline.id, new_size)); already_seen.insert(pipeline.id); } for frame_tree in self.navigation_context.previous.iter() @@ -1000,7 +1005,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { if !already_seen.contains(&pipeline.id) { debug!("constellation sending resize message to inactive frame"); let ScriptControlChan(ref chan) = pipeline.script_chan; - let _ = chan.send_opt(ConstellationControlMsg::ResizeInactive(pipeline.id, new_size)); + let _ = chan.send(ConstellationControlMsg::ResizeInactive(pipeline.id, new_size)); already_seen.insert(pipeline.id); } } @@ -1010,10 +1015,10 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { for change in self.pending_frames.iter() { let frame_tree = &change.after; if frame_tree.parent.borrow().is_none() { - debug!("constellation sending resize message to pending outer frame ({})", + debug!("constellation sending resize message to pending outer frame ({:?})", frame_tree.pipeline.borrow().id); let ScriptControlChan(ref chan) = frame_tree.pipeline.borrow().script_chan; - let _ = chan.send_opt(ConstellationControlMsg::Resize( + let _ = chan.send(ConstellationControlMsg::Resize( frame_tree.pipeline.borrow().id, new_size)); } } @@ -1032,8 +1037,8 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { } } - fn handle_evicted_frames(&mut self, evicted: Vec<Rc<FrameTree>>) { - for frame_tree in evicted.into_iter() { + fn handle_evicted_frames(&mut self, evicted_frames: Vec<Rc<FrameTree>>) { + for frame_tree in evicted_frames.into_iter() { if !self.navigation_context.contains(frame_tree.pipeline.borrow().id) { self.close_pipelines(frame_tree); } else { @@ -1044,41 +1049,39 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { } } - // Grants a frame tree permission to paint; optionally updates navigation to reflect a new page - fn grant_paint_permission(&mut self, frame_tree: Rc<FrameTree>, navigation_type: NavigationType) { - // Give permission to paint to the new frame and all child frames - self.set_ids(&frame_tree); + fn handle_evicted_frames_for_load_navigation(&mut self, + frame_tree: Rc<FrameTree>, + navigation_type: NavigationType) { // Don't call navigation_context.load() on a Navigate type (or None, as in the case of - // parsed iframes that finish loading) + // parsed iframes that finish loading). match navigation_type { NavigationType::Load => { - debug!("evicting old frames due to load"); - let evicted = self.navigation_context.load(frame_tree, - &mut *self.compositor_proxy); - self.handle_evicted_frames(evicted); - } - _ => { - debug!("ignoring non-load navigation type"); + debug!("Evicting frames for NavigationType::Load"); + let evicted_frames = self.navigation_context.load(frame_tree, + &mut *self.compositor_proxy); + self.handle_evicted_frames(evicted_frames); } + _ => {} } } - fn set_ids(&mut self, frame_tree: &Rc<FrameTree>) { - let (chan, port) = channel(); + // Grants a frame tree permission to paint; optionally updates navigation to reflect a new page + fn send_frame_tree_and_grant_paint_permission(&mut self, frame_tree: Rc<FrameTree>) { debug!("Constellation sending SetFrameTree"); + let (chan, port) = channel(); self.compositor_proxy.send(CompositorMsg::SetFrameTree(frame_tree.to_sendable(), chan, self.chan.clone())); - match port.recv_opt() { - Ok(()) => { - let mut iter = frame_tree.iter(); - for frame in iter { - frame.has_compositor_layer.set(true); - frame.pipeline.borrow().grant_paint_permission(); - } - } - Err(()) => {} // message has been discarded, probably shutting down + if port.recv().is_err() { + debug!("Compositor has discarded SetFrameTree"); + return; // Our message has been discarded, probably shutting down. + } + + let mut iter = frame_tree.iter(); + for frame in iter { + frame.has_compositor_layer.set(true); + frame.pipeline.borrow().grant_paint_permission(); } } @@ -1125,12 +1128,12 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> { child.frame_tree.pipeline.borrow().to_sendable(), child.rect, chan)); - match port.recv_opt() { + match port.recv() { Ok(()) => { child.frame_tree.has_compositor_layer.set(true); child.frame_tree.pipeline.borrow().grant_paint_permission(); } - Err(()) => {} // The message has been discarded, we are probably shutting down. + Err(_) => {} // The message has been discarded, we are probably shutting down. } } } diff --git a/components/compositing/headless.rs b/components/compositing/headless.rs index 86188636260..4fdfe094806 100644 --- a/components/compositing/headless.rs +++ b/components/compositing/headless.rs @@ -60,7 +60,7 @@ impl NullCompositor { initial_viewport: TypedSize2D(640_f32, 480_f32), visible_viewport: TypedSize2D(640_f32, 480_f32), device_pixel_ratio: ScaleFactor(1.0), - })); + })).unwrap(); } compositor @@ -73,8 +73,8 @@ impl CompositorEventListener for NullCompositor { Msg::Exit(chan) => { debug!("shutting down the constellation"); let ConstellationChan(ref con_chan) = self.constellation_chan; - con_chan.send(ConstellationMsg::Exit); - chan.send(()); + con_chan.send(ConstellationMsg::Exit).unwrap(); + chan.send(()).unwrap(); } Msg::ShutdownComplete => { @@ -83,19 +83,19 @@ impl CompositorEventListener for NullCompositor { } Msg::GetGraphicsMetadata(chan) => { - chan.send(None); + chan.send(None).unwrap(); } Msg::SetFrameTree(_, response_chan, _) => { - response_chan.send(()); + response_chan.send(()).unwrap(); } Msg::ChangeLayerPipelineAndRemoveChildren(_, _, response_channel) => { - response_channel.send(()); + response_channel.send(()).unwrap(); } Msg::CreateRootLayerForPipeline(_, _, _, response_channel) => { - response_channel.send(()); + response_channel.send(()).unwrap(); } // Explicitly list ignored messages so that when we add a new one, diff --git a/components/compositing/lib.rs b/components/compositing/lib.rs index fee2fbf1671..ff9a0ebcf1a 100644 --- a/components/compositing/lib.rs +++ b/components/compositing/lib.rs @@ -2,13 +2,15 @@ * 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/. */ -#![feature(globs, phase, macro_rules)] +#![feature(box_syntax, plugin)] +#![feature(int_uint)] #![deny(unused_imports)] #![deny(unused_variables)] #![allow(missing_copy_implementations)] +#![allow(unstable)] -#[phase(plugin, link)] +#[macro_use] extern crate log; extern crate azure; @@ -21,7 +23,7 @@ extern crate png; extern crate script_traits; extern crate "msg" as servo_msg; extern crate "net" as servo_net; -#[phase(plugin, link)] +#[macro_use] extern crate "util" as servo_util; extern crate gleam; diff --git a/components/compositing/pipeline.rs b/components/compositing/pipeline.rs index c8a054d16ef..a1dd6b3c24b 100644 --- a/components/compositing/pipeline.rs +++ b/components/compositing/pipeline.rs @@ -18,6 +18,7 @@ use servo_net::resource_task::ResourceTask; use servo_net::storage_task::StorageTask; use servo_util::time::TimeProfilerChan; use std::rc::Rc; +use std::sync::mpsc::{Receiver, channel}; /// A uniquely-identifiable pipeline of script task, layout task, and paint task. pub struct Pipeline { @@ -35,7 +36,7 @@ pub struct Pipeline { } /// The subset of the pipeline that is needed for layer composition. -#[deriving(Clone)] +#[derive(Clone)] pub struct CompositionPipeline { pub id: PipelineId, pub script_chan: ScriptControlChan, @@ -99,7 +100,7 @@ impl Pipeline { }; let ScriptControlChan(ref chan) = spipe.script_chan; - chan.send(ConstellationControlMsg::AttachLayout(new_layout_info)); + chan.send(ConstellationControlMsg::AttachLayout(new_layout_info)).unwrap(); spipe.script_chan.clone() } }; @@ -161,41 +162,42 @@ impl Pipeline { pub fn load(&self) { let ScriptControlChan(ref chan) = self.script_chan; - chan.send(ConstellationControlMsg::Load(self.id, self.load_data.clone())); + chan.send(ConstellationControlMsg::Load(self.id, self.load_data.clone())).unwrap(); } pub fn grant_paint_permission(&self) { - let _ = self.paint_chan.send_opt(PaintMsg::PaintPermissionGranted); + let _ = self.paint_chan.send(PaintMsg::PaintPermissionGranted); } pub fn revoke_paint_permission(&self) { debug!("pipeline revoking paint channel paint permission"); - let _ = self.paint_chan.send_opt(PaintMsg::PaintPermissionRevoked); + let _ = self.paint_chan.send(PaintMsg::PaintPermissionRevoked); } pub fn exit(&self, exit_type: PipelineExitType) { - debug!("pipeline {} exiting", self.id); + debug!("pipeline {:?} exiting", self.id); // Script task handles shutting down layout, and layout handles shutting down the painter. // For now, if the script task has failed, we give up on clean shutdown. let ScriptControlChan(ref chan) = self.script_chan; - if chan.send_opt(ConstellationControlMsg::ExitPipeline(self.id, exit_type)).is_ok() { + if chan.send(ConstellationControlMsg::ExitPipeline(self.id, exit_type)).is_ok() { // Wait until all slave tasks have terminated and run destructors // NOTE: We don't wait for script task as we don't always own it - let _ = self.paint_shutdown_port.recv_opt(); - let _ = self.layout_shutdown_port.recv_opt(); + let _ = self.paint_shutdown_port.recv(); + let _ = self.layout_shutdown_port.recv(); } } pub fn force_exit(&self) { let ScriptControlChan(ref script_channel) = self.script_chan; - let _ = script_channel.send_opt( + let _ = script_channel.send( ConstellationControlMsg::ExitPipeline(self.id, - PipelineExitType::PipelineOnly)); - let _ = self.paint_chan.send_opt(PaintMsg::Exit(None, PipelineExitType::PipelineOnly)); + PipelineExitType::PipelineOnly)).unwrap(); + let _ = self.paint_chan.send(PaintMsg::Exit(None, PipelineExitType::PipelineOnly)); let LayoutControlChan(ref layout_channel) = self.layout_chan; - let _ = layout_channel.send_opt(LayoutControlMsg::ExitNowMsg(PipelineExitType::PipelineOnly)); + let _ = layout_channel.send( + LayoutControlMsg::ExitNowMsg(PipelineExitType::PipelineOnly)).unwrap(); } pub fn to_sendable(&self) -> CompositionPipeline { diff --git a/components/compositing/scrolling.rs b/components/compositing/scrolling.rs index 8649ac1d9a4..24b57f90449 100644 --- a/components/compositing/scrolling.rs +++ b/components/compositing/scrolling.rs @@ -7,7 +7,8 @@ use compositor_task::{CompositorProxy, Msg}; use std::io::timer; -use std::task::TaskBuilder; +use std::sync::mpsc::{Receiver, Sender, channel}; +use std::thread::Builder; use std::time::duration::Duration; use time; @@ -33,7 +34,7 @@ enum ToScrollingTimerMsg { impl ScrollingTimerProxy { pub fn new(compositor_proxy: Box<CompositorProxy+Send>) -> ScrollingTimerProxy { let (to_scrolling_timer_sender, to_scrolling_timer_receiver) = channel(); - TaskBuilder::new().spawn(proc() { + Builder::new().spawn(move || { let mut scrolling_timer = ScrollingTimer { compositor_proxy: compositor_proxy, receiver: to_scrolling_timer_receiver, @@ -46,18 +47,18 @@ impl ScrollingTimerProxy { } pub fn scroll_event_processed(&mut self, timestamp: u64) { - self.sender.send(ToScrollingTimerMsg::ScrollEventProcessedMsg(timestamp)) + self.sender.send(ToScrollingTimerMsg::ScrollEventProcessedMsg(timestamp)).unwrap() } pub fn shutdown(&mut self) { - self.sender.send(ToScrollingTimerMsg::ExitMsg); + self.sender.send(ToScrollingTimerMsg::ExitMsg).unwrap() } } impl ScrollingTimer { pub fn run(&mut self) { loop { - match self.receiver.recv_opt() { + match self.receiver.recv() { Ok(ToScrollingTimerMsg::ScrollEventProcessedMsg(timestamp)) => { let target = timestamp as i64 + TIMEOUT; let delta = target - (time::precise_time_ns() as i64); diff --git a/components/compositing/windowing.rs b/components/compositing/windowing.rs index eae46c2d5fb..50b0a0ae64a 100644 --- a/components/compositing/windowing.rs +++ b/components/compositing/windowing.rs @@ -18,21 +18,21 @@ use servo_util::geometry::ScreenPx; use std::fmt::{Error, Formatter, Show}; use std::rc::Rc; -#[deriving(Clone)] +#[derive(Clone)] pub enum MouseWindowEvent { Click(uint, TypedPoint2D<DevicePixel, f32>), MouseDown(uint, TypedPoint2D<DevicePixel, f32>), MouseUp(uint, TypedPoint2D<DevicePixel, f32>), } -#[deriving(Clone)] +#[derive(Clone)] pub enum WindowNavigateMsg { Forward, Back, } /// Events that the windowing system sends to Servo. -#[deriving(Clone)] +#[derive(Clone)] pub enum WindowEvent { /// Sent when no message has arrived, but the event loop was kicked for some reason (perhaps /// by another Servo subsystem). @@ -48,7 +48,7 @@ pub enum WindowEvent { /// context when this message is sent. InitializeCompositing, /// Sent when the window is resized. - Resize(TypedSize2D<DevicePixel, uint>), + Resize(TypedSize2D<DevicePixel, u32>), /// Sent when a new URL is to be loaded. LoadUrl(String), /// Sent when a mouse hit test is to be performed. @@ -92,7 +92,7 @@ impl Show for WindowEvent { pub trait WindowMethods { /// Returns the size of the window in hardware pixels. - fn framebuffer_size(&self) -> TypedSize2D<DevicePixel, uint>; + fn framebuffer_size(&self) -> TypedSize2D<DevicePixel, u32>; /// Returns the size of the window in density-independent "px" units. fn size(&self) -> TypedSize2D<ScreenPx, f32>; /// Presents the window to the screen (perhaps by page flipping). diff --git a/components/devtools/actor.rs b/components/devtools/actor.rs index 87c3d45f139..2b4f408cd45 100644 --- a/components/devtools/actor.rs +++ b/components/devtools/actor.rs @@ -4,13 +4,11 @@ /// General actor system infrastructure. -use std::any::{Any, AnyRefExt, AnyMutRefExt}; +use std::any::Any; use std::collections::HashMap; use std::cell::{Cell, RefCell}; -use std::intrinsics::TypeId; use std::io::TcpStream; -use std::mem::{transmute, transmute_copy, replace}; -use std::raw::TraitObject; +use std::mem::replace; use serialize::json; /// A common trait for all devtools actors that encompasses an immutable name @@ -25,46 +23,6 @@ pub trait Actor : Any { fn name(&self) -> String; } -impl<'a> AnyMutRefExt<'a> for &'a mut (Actor + 'a) { - fn downcast_mut<T: 'static>(self) -> Option<&'a mut T> { - if self.is::<T>() { - unsafe { - // Get the raw representation of the trait object - let to: TraitObject = transmute_copy(&self); - - // Extract the data pointer - Some(transmute(to.data)) - } - } else { - None - } - } -} - -impl<'a> AnyRefExt<'a> for &'a (Actor + 'a) { - fn is<T: 'static>(self) -> bool { - // This implementation is only needed so long as there's a Rust bug that - // prevents downcast_ref from giving realistic return values. - let t = TypeId::of::<T>(); - let boxed: TypeId = (*self).get_type_id(); - t == boxed - } - - fn downcast_ref<T: 'static>(self) -> Option<&'a T> { - if self.is::<T>() { - unsafe { - // Get the raw representation of the trait object - let to: TraitObject = transmute_copy(&self); - - // Extract the data pointer - Some(transmute(to.data)) - } - } else { - None - } - } -} - /// A list of known, owned actors. pub struct ActorRegistry { actors: HashMap<String, Box<Actor+Send+Sized>>, @@ -130,20 +88,14 @@ impl ActorRegistry { /// Find an actor by registered name pub fn find<'a, T: 'static>(&'a self, name: &str) -> &'a T { - //FIXME: Rust bug forces us to implement bogus Any for Actor since downcast_ref currently - // fails for unknown reasons. - /*let actor: &Actor+Send+Sized = *self.actors.find(&name.to_string()).unwrap(); - (actor as &Any).downcast_ref::<T>().unwrap()*/ - self.actors.get(&name.to_string()).unwrap().downcast_ref::<T>().unwrap() + let actor: &Any = self.actors.get(&name.to_string()).unwrap(); + actor.downcast_ref::<T>().unwrap() } /// Find an actor by registered name pub fn find_mut<'a, T: 'static>(&'a mut self, name: &str) -> &'a mut T { - //FIXME: Rust bug forces us to implement bogus Any for Actor since downcast_ref currently - // fails for unknown reasons. - /*let actor: &mut Actor+Send+Sized = *self.actors.find_mut(&name.to_string()).unwrap(); - (actor as &mut Any).downcast_mut::<T>().unwrap()*/ - self.actors.get_mut(&name.to_string()).unwrap().downcast_mut::<T>().unwrap() + let actor: &mut Any = self.actors.get_mut(&name.to_string()).unwrap(); + actor.downcast_mut::<T>().unwrap() } /// Attempt to process a message as directed by its `to` property. If the actor is not diff --git a/components/devtools/actors/console.rs b/components/devtools/actors/console.rs index 5628506d5af..246357a4230 100644 --- a/components/devtools/actors/console.rs +++ b/components/devtools/actors/console.rs @@ -13,18 +13,19 @@ use devtools_traits::{EvaluateJS, NullValue, VoidValue, NumberValue, StringValue use devtools_traits::{ActorValue, DevtoolScriptControlMsg}; use servo_msg::constellation_msg::PipelineId; -use collections::TreeMap; +use collections::BTreeMap; use core::cell::RefCell; -use serialize::json::{mod, Json, ToJson}; +use serialize::json::{self, Json, ToJson}; use std::io::TcpStream; use std::num::Float; +use std::sync::mpsc::{channel, Sender}; -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct StartedListenersTraits { customNetworkRequest: bool, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct StartedListenersReply { from: String, nativeConsoleAPI: bool, @@ -32,13 +33,13 @@ struct StartedListenersReply { traits: StartedListenersTraits, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] #[allow(dead_code)] struct ConsoleAPIMessage { _type: String, //FIXME: should this be __type__ instead? } -#[deriving(Encodable)] +#[derive(RustcEncodable)] #[allow(dead_code)] struct PageErrorMessage { _type: String, //FIXME: should this be __type__ instead? @@ -56,7 +57,7 @@ struct PageErrorMessage { private: bool, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] #[allow(dead_code)] struct LogMessage { _type: String, //FIXME: should this be __type__ instead? @@ -64,7 +65,7 @@ struct LogMessage { message: String, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] #[allow(dead_code)] enum ConsoleMessageType { ConsoleAPIType(ConsoleAPIMessage), @@ -72,26 +73,26 @@ enum ConsoleMessageType { LogMessageType(LogMessage), } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct GetCachedMessagesReply { from: String, messages: Vec<json::Object>, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct StopListenersReply { from: String, stoppedListeners: Vec<String>, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct AutocompleteReply { from: String, matches: Vec<String>, matchProp: String, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct EvaluateJSReply { from: String, input: String, @@ -220,28 +221,28 @@ impl Actor for ConsoleActor { "evaluateJS" => { let input = msg.get(&"text".to_string()).unwrap().as_string().unwrap().to_string(); let (chan, port) = channel(); - self.script_chan.send(EvaluateJS(self.pipeline, input.clone(), chan)); + self.script_chan.send(EvaluateJS(self.pipeline, input.clone(), chan)).unwrap(); //TODO: extract conversion into protocol module or some other useful place - let result = match try!(port.recv_opt()) { + let result = match try!(port.recv().map_err(|_| ())) { VoidValue => { - let mut m = TreeMap::new(); + let mut m = BTreeMap::new(); m.insert("type".to_string(), "undefined".to_string().to_json()); Json::Object(m) } NullValue => { - let mut m = TreeMap::new(); + let mut m = BTreeMap::new(); m.insert("type".to_string(), "null".to_string().to_json()); Json::Object(m) } BooleanValue(val) => val.to_json(), NumberValue(val) => { if val.is_nan() { - let mut m = TreeMap::new(); + let mut m = BTreeMap::new(); m.insert("type".to_string(), "NaN".to_string().to_json()); Json::Object(m) } else if val.is_infinite() { - let mut m = TreeMap::new(); + let mut m = BTreeMap::new(); if val < 0. { m.insert("type".to_string(), "-Infinity".to_string().to_json()); } else { @@ -249,7 +250,7 @@ impl Actor for ConsoleActor { } Json::Object(m) } else if val == Float::neg_zero() { - let mut m = TreeMap::new(); + let mut m = BTreeMap::new(); m.insert("type".to_string(), "-0".to_string().to_json()); Json::Object(m) } else { @@ -259,7 +260,7 @@ impl Actor for ConsoleActor { StringValue(s) => s.to_json(), ActorValue(s) => { //TODO: make initial ActorValue message include these properties. - let mut m = TreeMap::new(); + let mut m = BTreeMap::new(); m.insert("type".to_string(), "object".to_string().to_json()); m.insert("class".to_string(), "???".to_string().to_json()); m.insert("actor".to_string(), s.to_json()); @@ -276,9 +277,9 @@ impl Actor for ConsoleActor { input: input, result: result, timestamp: 0, - exception: Json::Object(TreeMap::new()), + exception: Json::Object(BTreeMap::new()), exceptionMessage: "".to_string(), - helperResult: Json::Object(TreeMap::new()), + helperResult: Json::Object(BTreeMap::new()), }; stream.write_json_packet(&msg); true diff --git a/components/devtools/actors/inspector.rs b/components/devtools/actors/inspector.rs index ac3b51cf34f..77ee81d1bce 100644 --- a/components/devtools/actors/inspector.rs +++ b/components/devtools/actors/inspector.rs @@ -10,11 +10,12 @@ use devtools_traits::{GetLayout, NodeInfo, ModifyAttribute}; use actor::{Actor, ActorRegistry}; use protocol::JsonPacketStream; -use collections::TreeMap; +use collections::BTreeMap; use servo_msg::constellation_msg::PipelineId; -use serialize::json::{mod, Json, ToJson}; +use serialize::json::{self, Json, ToJson}; use std::cell::RefCell; use std::io::TcpStream; +use std::sync::mpsc::{channel, Sender}; use std::num::Float; pub struct InspectorActor { @@ -26,13 +27,13 @@ pub struct InspectorActor { pub pipeline: PipelineId, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct GetHighlighterReply { highligter: HighlighterMsg, // sic. from: String, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct HighlighterMsg { actor: String, } @@ -47,12 +48,12 @@ pub struct NodeActor { pipeline: PipelineId, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct ShowBoxModelReply { from: String, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct HideBoxModelReply { from: String, } @@ -89,7 +90,7 @@ impl Actor for HighlighterActor { } } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct ModifyAttributeReply{ from: String, } @@ -114,7 +115,8 @@ impl Actor for NodeActor { self.script_chan.send(ModifyAttribute(self.pipeline, registry.actor_to_script(target.to_string()), - modifications)); + modifications)) + .unwrap(); let reply = ModifyAttributeReply{ from: self.name(), }; @@ -127,26 +129,26 @@ impl Actor for NodeActor { } } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct GetWalkerReply { from: String, walker: WalkerMsg, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct WalkerMsg { actor: String, root: NodeActorMsg, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct AttrMsg { namespace: String, name: String, value: String, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct NodeActorMsg { actor: String, baseURI: String, @@ -243,23 +245,23 @@ struct WalkerActor { pipeline: PipelineId, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct QuerySelectorReply { from: String, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct DocumentElementReply { from: String, node: NodeActorMsg, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct ClearPseudoclassesReply { from: String, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct ChildrenReply { hasFirst: bool, hasLast: bool, @@ -288,8 +290,8 @@ impl Actor for WalkerActor { "documentElement" => { let (tx, rx) = channel(); - self.script_chan.send(GetDocumentElement(self.pipeline, tx)); - let doc_elem_info = rx.recv(); + self.script_chan.send(GetDocumentElement(self.pipeline, tx)).unwrap(); + let doc_elem_info = rx.recv().unwrap(); let node = doc_elem_info.encode(registry, true, self.script_chan.clone(), self.pipeline); let msg = DocumentElementReply { @@ -313,8 +315,9 @@ impl Actor for WalkerActor { let (tx, rx) = channel(); self.script_chan.send(GetChildren(self.pipeline, registry.actor_to_script(target.to_string()), - tx)); - let children = rx.recv(); + tx)) + .unwrap(); + let children = rx.recv().unwrap(); let msg = ChildrenReply { hasFirst: true, @@ -333,13 +336,13 @@ impl Actor for WalkerActor { } } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct GetPageStyleReply { from: String, pageStyle: PageStyleMsg, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct PageStyleMsg { actor: String, } @@ -350,7 +353,7 @@ struct PageStyleActor { pipeline: PipelineId, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct GetAppliedReply { entries: Vec<AppliedEntry>, rules: Vec<AppliedRule>, @@ -358,13 +361,13 @@ struct GetAppliedReply { from: String, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct GetComputedReply { computed: Vec<uint>, //XXX all css props from: String, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct AppliedEntry { rule: String, pseudoElement: Json, @@ -372,7 +375,7 @@ struct AppliedEntry { matchedSelectors: Vec<String>, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct AppliedRule { actor: String, __type__: uint, @@ -383,7 +386,7 @@ struct AppliedRule { parentStyleSheet: String, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct AppliedSheet { actor: String, href: String, @@ -395,7 +398,7 @@ struct AppliedSheet { ruleCount: uint, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct GetLayoutReply { width: int, height: int, @@ -403,7 +406,7 @@ struct GetLayoutReply { from: String, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] #[allow(dead_code)] struct AutoMargins { top: String, @@ -450,9 +453,10 @@ impl Actor for PageStyleActor { let target = msg.get(&"node".to_string()).unwrap().as_string().unwrap(); let (tx, rx) = channel(); self.script_chan.send(GetLayout(self.pipeline, - registry.actor_to_script(target.to_string()), - tx)); - let (width, height) = rx.recv(); + registry.actor_to_script(target.to_string()), + tx)) + .unwrap(); + let (width, height) = rx.recv().unwrap(); let auto_margins = msg.get(&"autoMargins".to_string()).unwrap().as_boolean().unwrap(); @@ -463,7 +467,7 @@ impl Actor for PageStyleActor { height: height.round() as int, autoMargins: if auto_margins { //TODO: real values like processMargins in http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/styles.js - let mut m = TreeMap::new(); + let mut m = BTreeMap::new(); m.insert("top".to_string(), "auto".to_string().to_json()); m.insert("bottom".to_string(), "auto".to_string().to_json()); m.insert("left".to_string(), "auto".to_string().to_json()); @@ -507,8 +511,8 @@ impl Actor for InspectorActor { } let (tx, rx) = channel(); - self.script_chan.send(GetRootNode(self.pipeline, tx)); - let root_info = rx.recv(); + self.script_chan.send(GetRootNode(self.pipeline, tx)).unwrap(); + let root_info = rx.recv().unwrap(); let node = root_info.encode(registry, false, self.script_chan.clone(), self.pipeline); diff --git a/components/devtools/actors/root.rs b/components/devtools/actors/root.rs index da0e33d7c7d..cd9084c0282 100644 --- a/components/devtools/actors/root.rs +++ b/components/devtools/actors/root.rs @@ -13,28 +13,28 @@ use protocol::JsonPacketStream; use serialize::json; use std::io::TcpStream; -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct ActorTraits { sources: bool, highlightable: bool, customHighlighters: Vec<String>, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct ErrorReply { from: String, error: String, message: String, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct ListTabsReply { from: String, selected: uint, tabs: Vec<TabActorMsg>, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct RootActorMsg { from: String, applicationType: String, diff --git a/components/devtools/actors/tab.rs b/components/devtools/actors/tab.rs index 519e3e48128..69450cd4b32 100644 --- a/components/devtools/actors/tab.rs +++ b/components/devtools/actors/tab.rs @@ -13,10 +13,10 @@ use protocol::JsonPacketStream; use serialize::json; use std::io::TcpStream; -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct TabTraits; -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct TabAttachedReply { from: String, __type__: String, @@ -26,24 +26,24 @@ struct TabAttachedReply { traits: TabTraits, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct TabDetachedReply { from: String, __type__: String, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct ReconfigureReply { from: String } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct ListFramesReply { from: String, frames: Vec<FrameMsg>, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct FrameMsg { id: uint, url: String, @@ -51,7 +51,7 @@ struct FrameMsg { parentID: uint, } -#[deriving(Encodable)] +#[derive(RustcEncodable)] pub struct TabActorMsg { actor: String, title: String, diff --git a/components/devtools/lib.rs b/components/devtools/lib.rs index 7e09a53c65e..f653dd289ce 100644 --- a/components/devtools/lib.rs +++ b/components/devtools/lib.rs @@ -10,17 +10,19 @@ #![crate_name = "devtools"] #![crate_type = "rlib"] +#![feature(int_uint, box_syntax)] + #![allow(non_snake_case)] #![allow(missing_copy_implementations)] +#![allow(unstable)] -#![feature(phase)] - -#[phase(plugin, link)] +#[macro_use] extern crate log; extern crate collections; extern crate core; extern crate devtools_traits; +extern crate "serialize" as rustc_serialize; extern crate serialize; extern crate "msg" as servo_msg; extern crate "util" as servo_util; @@ -36,10 +38,11 @@ use devtools_traits::{ServerExitMsg, DevtoolsControlMsg, NewGlobal, DevtoolScrip use servo_msg::constellation_msg::PipelineId; use servo_util::task::spawn_named; +use std::borrow::ToOwned; use std::cell::RefCell; use std::collections::HashMap; -use std::comm; -use std::comm::{Disconnected, Empty}; +use std::sync::mpsc::{channel, Receiver, Sender}; +use std::sync::mpsc::TryRecvError::{Disconnected, Empty}; use std::io::{TcpListener, TcpStream}; use std::io::{Acceptor, Listener, TimedOut}; use std::sync::{Arc, Mutex}; @@ -56,8 +59,8 @@ mod protocol; /// Spin up a devtools server that listens for connections on the specified port. pub fn start_server(port: u16) -> Sender<DevtoolsControlMsg> { - let (sender, receiver) = comm::channel(); - spawn_named("Devtools", proc() { + let (sender, receiver) = channel(); + spawn_named("Devtools".to_owned(), move || { run_server(receiver, port) }); sender @@ -91,7 +94,7 @@ fn run_server(receiver: Receiver<DevtoolsControlMsg>, port: u16) { fn handle_client(actors: Arc<Mutex<ActorRegistry>>, mut stream: TcpStream) { println!("connection established to {}", stream.peer_name().unwrap()); { - let actors = actors.lock(); + let actors = actors.lock().unwrap(); let msg = actors.find::<RootActor>("root").encodable(); stream.write_json_packet(&msg); } @@ -99,8 +102,9 @@ fn run_server(receiver: Receiver<DevtoolsControlMsg>, port: u16) { 'outer: loop { match stream.read_json_packet() { Ok(json_packet) => { - match actors.lock().handle_message(json_packet.as_object().unwrap(), - &mut stream) { + let mut actors = actors.lock().unwrap(); + match actors.handle_message(json_packet.as_object().unwrap(), + &mut stream) { Ok(()) => {}, Err(()) => { println!("error: devtools actor stopped responding"); @@ -126,7 +130,7 @@ fn run_server(receiver: Receiver<DevtoolsControlMsg>, port: u16) { sender: Sender<DevtoolScriptControlMsg>, actor_pipelines: &mut HashMap<PipelineId, String>, page_info: DevtoolsPageInfo) { - let mut actors = actors.lock(); + let mut actors = actors.lock().unwrap(); //TODO: move all this actor creation into a constructor method on TabActor let (tab, console, inspector) = { @@ -184,7 +188,7 @@ fn run_server(receiver: Receiver<DevtoolsControlMsg>, port: u16) { Ok(stream) => { let actors = actors.clone(); accepted_connections.push(stream.clone()); - spawn_named("DevtoolsClientHandler", proc() { + spawn_named("DevtoolsClientHandler".to_owned(), move || { // connection succeeded handle_client(actors, stream.clone()) }) diff --git a/components/devtools/protocol.rs b/components/devtools/protocol.rs index df9078c7bf1..149c3a301d2 100644 --- a/components/devtools/protocol.rs +++ b/components/devtools/protocol.rs @@ -12,12 +12,12 @@ use std::io::{IoError, OtherIoError, EndOfFile, TcpStream, IoResult}; use std::num; pub trait JsonPacketStream { - fn write_json_packet<'a, T: Encodable<json::Encoder<'a>,IoError>>(&mut self, obj: &T); + fn write_json_packet<'a, T: Encodable>(&mut self, obj: &T); fn read_json_packet(&mut self) -> IoResult<Json>; } impl JsonPacketStream for TcpStream { - fn write_json_packet<'a, T: Encodable<json::Encoder<'a>,IoError>>(&mut self, obj: &T) { + fn write_json_packet<'a, T: Encodable>(&mut self, obj: &T) { let s = json::encode(obj).replace("__type__", "type"); println!("<- {}", s); self.write_str(s.len().to_string().as_slice()).unwrap(); diff --git a/components/devtools_traits/lib.rs b/components/devtools_traits/lib.rs index 158a01272f6..14c6c59b56c 100644 --- a/components/devtools_traits/lib.rs +++ b/components/devtools_traits/lib.rs @@ -9,9 +9,10 @@ #![crate_name = "devtools_traits"] #![crate_type = "rlib"] +#![feature(int_uint)] + #![allow(non_snake_case)] #![allow(missing_copy_implementations)] -#![feature(globs)] extern crate "msg" as servo_msg; extern crate serialize; @@ -27,6 +28,8 @@ use servo_msg::constellation_msg::PipelineId; use servo_util::str::DOMString; use url::Url; +use std::sync::mpsc::{Sender, Receiver}; + pub type DevtoolsControlChan = Sender<DevtoolsControlMsg>; pub type DevtoolsControlPort = Receiver<DevtoolScriptControlMsg>; @@ -99,14 +102,14 @@ pub enum ScriptDevtoolControlMsg { ReportConsoleMsg(String), } -#[deriving(Encodable)] +#[derive(Encodable)] pub struct Modification{ pub attributeName: String, pub newValue: Option<String>, } -impl<D:Decoder<E>, E> Decodable<D, E> for Modification { - fn decode(d: &mut D) -> Result<Modification, E> { +impl Decodable for Modification { + fn decode<D: Decoder>(d: &mut D) -> Result<Modification, D::Error> { d.read_struct("Modification", 2u, |d| Ok(Modification { attributeName: try!(d.read_struct_field("attributeName", 0u, |d| Decodable::decode(d))), diff --git a/components/gfx/Cargo.toml b/components/gfx/Cargo.toml index dbdd1246897..a0d0c47670f 100644 --- a/components/gfx/Cargo.toml +++ b/components/gfx/Cargo.toml @@ -38,9 +38,6 @@ git = "https://github.com/servo/rust-stb-image" [dependencies.png] git = "https://github.com/servo/rust-png" -[dependencies.url] -git = "https://github.com/servo/rust-url" - [dependencies.harfbuzz] git = "https://github.com/servo/rust-harfbuzz" @@ -62,5 +59,6 @@ git = "https://github.com/servo/rust-core-text" [dependencies.script_traits] path = "../script_traits" -[dependencies.time] -git = "https://github.com/rust-lang/time" +[dependencies] +url = "*" +time = "*"
\ No newline at end of file diff --git a/components/gfx/buffer_map.rs b/components/gfx/buffer_map.rs index 9c1197ec8b2..c33617a7c9e 100644 --- a/components/gfx/buffer_map.rs +++ b/components/gfx/buffer_map.rs @@ -3,12 +3,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use std::collections::HashMap; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; use geom::size::Size2D; use layers::platform::surface::NativePaintingGraphicsContext; use layers::layers::LayerBuffer; -use std::hash::Hash; -use std::hash::sip::SipState; +use std::hash::{Hash, Hasher, Writer}; use std::mem; /// This is a struct used to store buffers when they are not in use. @@ -27,11 +26,11 @@ pub struct BufferMap { } /// A key with which to store buffers. It is based on the size of the buffer. -#[deriving(Eq, Copy)] -struct BufferKey([uint, ..2]); +#[derive(Eq, Copy)] +struct BufferKey([uint; 2]); -impl Hash for BufferKey { - fn hash(&self, state: &mut SipState) { +impl<H: Hasher+Writer> Hash<H> for BufferKey { + fn hash(&self, state: &mut H) { let BufferKey(ref bytes) = *self; bytes.as_slice().hash(state); } @@ -91,7 +90,7 @@ impl BufferMap { entry.into_mut().buffers.push(new_buffer); } Vacant(entry) => { - entry.set(BufferValue { + entry.insert(BufferValue { buffers: vec!(new_buffer), last_action: *counter, }); diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs index 6ede4546b6b..36dc2c6b1b8 100644 --- a/components/gfx/display_list/mod.rs +++ b/components/gfx/display_list/mod.rs @@ -25,7 +25,7 @@ use text::glyph::CharIndex; use text::TextRun; use azure::azure::AzFloat; -use collections::dlist::{mod, DList}; +use collections::dlist::{self, DList}; use geom::{Point2D, Rect, SideOffsets2D, Size2D, Matrix2D}; use geom::num::Zero; use libc::uintptr_t; @@ -34,11 +34,11 @@ use servo_msg::compositor_msg::LayerId; use servo_net::image::base::Image; use servo_util::cursor::Cursor; use servo_util::dlist as servo_dlist; -use servo_util::geometry::{mod, Au, MAX_RECT, ZERO_RECT}; +use servo_util::geometry::{self, Au, MAX_RECT, ZERO_RECT}; use servo_util::range::Range; use servo_util::smallvec::{SmallVec, SmallVec8}; use std::fmt; -use std::slice::Items; +use std::slice::Iter; use std::sync::Arc; use style::ComputedValues; use style::computed_values::{border_style, cursor, filter, mix_blend_mode, pointer_events}; @@ -60,7 +60,7 @@ pub static BOX_SHADOW_INFLATION_FACTOR: i32 = 3; /// Because the script task's GC does not trace layout, node data cannot be safely stored in layout /// data structures. Also, layout code tends to be faster when the DOM is not being accessed, for /// locality reasons. Using `OpaqueNode` enforces this invariant. -#[deriving(Clone, PartialEq, Copy)] +#[derive(Clone, PartialEq, Copy)] pub struct OpaqueNode(pub uintptr_t); impl OpaqueNode { @@ -356,7 +356,7 @@ impl StackingContext { result: &mut Vec<DisplayItemMetadata>, topmost_only: bool, mut iterator: I) - where I: Iterator<&'a DisplayItem> { + where I: Iterator<Item=&'a DisplayItem> { for item in iterator { // TODO(pcwalton): Use a precise algorithm here. This will allow us to properly hit // test elements with `border-radius`, for example. @@ -473,7 +473,7 @@ pub fn find_stacking_context_with_layer_id(this: &Arc<StackingContext>, layer_id } /// One drawing command in the list. -#[deriving(Clone)] +#[derive(Clone)] pub enum DisplayItem { SolidColorClass(Box<SolidColorDisplayItem>), TextClass(Box<TextDisplayItem>), @@ -485,7 +485,7 @@ pub enum DisplayItem { } /// Information common to all display items. -#[deriving(Clone)] +#[derive(Clone)] pub struct BaseDisplayItem { /// The boundaries of the display item, in layer coordinates. pub bounds: Rect<Au>, @@ -512,7 +512,7 @@ impl BaseDisplayItem { /// A clipping region for a display item. Currently, this can describe rectangles, rounded /// rectangles (for `border-radius`), or arbitrary intersections of the two. Arbitrary transforms /// are not supported because those are handled by the higher-level `StackingContext` abstraction. -#[deriving(Clone, PartialEq, Show)] +#[derive(Clone, PartialEq, Show)] pub struct ClippingRegion { /// The main rectangular region. This does not include any corners. pub main: Rect<Au>, @@ -526,7 +526,7 @@ pub struct ClippingRegion { /// A complex clipping region. These don't as easily admit arbitrary intersection operations, so /// they're stored in a list over to the side. Currently a complex clipping region is just a /// rounded rectangle, but the CSS WGs will probably make us throw more stuff in here eventually. -#[deriving(Clone, PartialEq, Show)] +#[derive(Clone, PartialEq, Show)] pub struct ComplexClippingRegion { /// The boundaries of the rectangle. pub rect: Rect<Au>, @@ -637,7 +637,7 @@ impl ClippingRegion { /// Metadata attached to each display item. This is useful for performing auxiliary tasks with /// the display list involving hit testing: finding the originating DOM node and determining the /// cursor to use when the element is hovered over. -#[deriving(Clone, Copy)] +#[derive(Clone, Copy)] pub struct DisplayItemMetadata { /// The DOM node from which this display item originated. pub node: OpaqueNode, @@ -666,14 +666,14 @@ impl DisplayItemMetadata { } /// Paints a solid color. -#[deriving(Clone)] +#[derive(Clone)] pub struct SolidColorDisplayItem { pub base: BaseDisplayItem, pub color: Color, } /// Paints text. -#[deriving(Clone)] +#[derive(Clone)] pub struct TextDisplayItem { /// Fields common to all display items. pub base: BaseDisplayItem, @@ -691,7 +691,7 @@ pub struct TextDisplayItem { pub orientation: TextOrientation, } -#[deriving(Clone, Eq, PartialEq)] +#[derive(Clone, Eq, PartialEq)] pub enum TextOrientation { Upright, SidewaysLeft, @@ -699,7 +699,7 @@ pub enum TextOrientation { } /// Paints an image. -#[deriving(Clone)] +#[derive(Clone)] pub struct ImageDisplayItem { pub base: BaseDisplayItem, pub image: Arc<Box<Image>>, @@ -711,7 +711,7 @@ pub struct ImageDisplayItem { } /// Paints a gradient. -#[deriving(Clone)] +#[derive(Clone)] pub struct GradientDisplayItem { /// Fields common to all display items. pub base: BaseDisplayItem, @@ -727,7 +727,7 @@ pub struct GradientDisplayItem { } /// Paints a border. -#[deriving(Clone)] +#[derive(Clone)] pub struct BorderDisplayItem { /// Fields common to all display items. pub base: BaseDisplayItem, @@ -750,7 +750,7 @@ pub struct BorderDisplayItem { /// Information about the border radii. /// /// TODO(pcwalton): Elliptical radii. -#[deriving(Clone, Default, PartialEq, Show, Copy)] +#[derive(Clone, Default, PartialEq, Show, Copy)] pub struct BorderRadii<T> { pub top_left: T, pub top_right: T, @@ -768,7 +768,7 @@ impl<T> BorderRadii<T> where T: PartialEq + Zero { } /// Paints a line segment. -#[deriving(Clone)] +#[derive(Clone)] pub struct LineDisplayItem { pub base: BaseDisplayItem, @@ -780,7 +780,7 @@ pub struct LineDisplayItem { } /// Paints a box shadow per CSS-BACKGROUNDS. -#[deriving(Clone)] +#[derive(Clone)] pub struct BoxShadowDisplayItem { /// Fields common to all display items. pub base: BaseDisplayItem, @@ -806,10 +806,11 @@ pub struct BoxShadowDisplayItem { pub enum DisplayItemIterator<'a> { Empty, - Parent(dlist::Items<'a,DisplayItem>), + Parent(dlist::Iter<'a,DisplayItem>), } -impl<'a> Iterator<&'a DisplayItem> for DisplayItemIterator<'a> { +impl<'a> Iterator for DisplayItemIterator<'a> { + type Item = &'a DisplayItem; #[inline] fn next(&mut self) -> Option<&'a DisplayItem> { match *self { @@ -836,14 +837,14 @@ impl DisplayItem { } DisplayItem::TextClass(ref text) => { - debug!("Drawing text at {}.", text.base.bounds); + debug!("Drawing text at {:?}.", text.base.bounds); paint_context.draw_text(&**text); } DisplayItem::ImageClass(ref image_item) => { // FIXME(pcwalton): This is a really inefficient way to draw a tiled image; use a // brush instead. - debug!("Drawing image at {}.", image_item.base.bounds); + debug!("Drawing image at {:?}.", image_item.base.bounds); let mut y_offset = Au(0); while y_offset < image_item.base.bounds.size.height { @@ -926,13 +927,13 @@ impl DisplayItem { for _ in range(0, level) { indent.push_str("| ") } - println!("{}+ {}", indent, self); + println!("{}+ {:?}", indent, self); } } impl fmt::Show for DisplayItem { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} @ {} ({:x})", + write!(f, "{} @ {:?} ({:x})", match *self { DisplayItem::SolidColorClass(_) => "SolidColor", DisplayItem::TextClass(_) => "Text", diff --git a/components/gfx/display_list/optimizer.rs b/components/gfx/display_list/optimizer.rs index f9b738a1d73..735cae422ba 100644 --- a/components/gfx/display_list/optimizer.rs +++ b/components/gfx/display_list/optimizer.rs @@ -8,7 +8,7 @@ use display_list::{DisplayItem, DisplayList, StackingContext}; use collections::dlist::DList; use geom::rect::Rect; -use servo_util::geometry::{mod, Au}; +use servo_util::geometry::{self, Au}; use std::sync::Arc; /// Transforms a display list to produce a visually-equivalent, but cheaper-to-paint, one. @@ -44,7 +44,7 @@ impl DisplayListOptimizer { fn add_in_bounds_display_items<'a,I>(&self, result_list: &mut DList<DisplayItem>, mut display_items: I) - where I: Iterator<&'a DisplayItem> { + where I: Iterator<Item=&'a DisplayItem> { for display_item in display_items { if self.visible_rect.intersects(&display_item.base().bounds) && display_item.base().clip.might_intersect_rect(&self.visible_rect) { @@ -57,7 +57,7 @@ impl DisplayListOptimizer { fn add_in_bounds_stacking_contexts<'a,I>(&self, result_list: &mut DList<Arc<StackingContext>>, mut stacking_contexts: I) - where I: Iterator<&'a Arc<StackingContext>> { + where I: Iterator<Item=&'a Arc<StackingContext>> { for stacking_context in stacking_contexts { let overflow = stacking_context.overflow.translate(&stacking_context.bounds.origin); if self.visible_rect.intersects(&overflow) { diff --git a/components/gfx/filters.rs b/components/gfx/filters.rs index a1cc25d2bd0..948f2cdfc3d 100644 --- a/components/gfx/filters.rs +++ b/components/gfx/filters.rs @@ -9,7 +9,7 @@ use azure::azure_hl::{ColorMatrixAttribute, ColorMatrixInput, CompositeInput, Dr use azure::azure_hl::{FilterNode, FilterType, LinearTransferAttribute, LinearTransferInput}; use azure::azure_hl::{Matrix5x4, TableTransferAttribute, TableTransferInput}; -use std::num::FloatMath; +use std::num::Float; use style::computed_values::filter; /// Creates a filter pipeline from a set of CSS filters. Returns the destination end of the filter diff --git a/components/gfx/font.rs b/components/gfx/font.rs index 3c6379988bc..cfc79b6248c 100644 --- a/components/gfx/font.rs +++ b/components/gfx/font.rs @@ -3,17 +3,18 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use geom::{Point2D, Rect, Size2D}; +use std::borrow::ToOwned; use std::mem; use std::slice; use std::rc::Rc; use std::cell::RefCell; -use servo_util::cache::{Cache, HashCache}; +use servo_util::cache::HashCache; use servo_util::smallvec::{SmallVec, SmallVec8}; use style::computed_values::{font_variant, font_weight}; use style::style_structs::Font as FontStyle; use std::sync::Arc; -use collections::hash::Hash; +use std::hash::Hash; use platform::font_context::FontContextHandle; use platform::font::{FontHandle, FontTable}; use servo_util::geometry::Au; @@ -65,10 +66,10 @@ impl FontTableTagConversions for FontTableTag { } pub trait FontTableMethods { - fn with_buffer(&self, |*const u8, uint|); + fn with_buffer<F>(&self, F) where F: FnOnce(*const u8, uint); } -#[deriving(Clone, Show)] +#[derive(Clone, Show)] pub struct FontMetrics { pub underline_size: Au, pub underline_offset: Au, @@ -100,7 +101,6 @@ pub struct Font { } bitflags! { - #[deriving(Copy)] flags ShapingFlags: u8 { #[doc="Set if the text is entirely whitespace."] const IS_WHITESPACE_SHAPING_FLAG = 0x01, @@ -112,7 +112,7 @@ bitflags! { } /// Various options that control text shaping. -#[deriving(Clone, Eq, PartialEq, Hash, Copy)] +#[derive(Clone, Eq, PartialEq, Hash, Copy)] pub struct ShapingOptions { /// Spacing to add between each letter. Corresponds to the CSS 2.1 `letter-spacing` property. /// NB: You will probably want to set the `IGNORE_LIGATURES_SHAPING_FLAG` if this is non-null. @@ -124,45 +124,34 @@ pub struct ShapingOptions { } /// An entry in the shape cache. -#[deriving(Clone, Eq, PartialEq, Hash)] +#[derive(Clone, Eq, PartialEq, Hash)] pub struct ShapeCacheEntry { text: String, options: ShapingOptions, } -#[deriving(Clone, Eq, PartialEq, Hash)] -struct ShapeCacheEntryRef<'a> { - text: &'a str, - options: &'a ShapingOptions, -} - -impl<'a> Equiv<ShapeCacheEntry> for ShapeCacheEntryRef<'a> { - fn equiv(&self, other: &ShapeCacheEntry) -> bool { - self.text == other.text.as_slice() && *self.options == other.options - } -} - impl Font { pub fn shape_text(&mut self, text: &str, options: &ShapingOptions) -> Arc<GlyphStore> { self.make_shaper(options); + //FIXME: find the equivalent of Equiv and the old ShapeCacheEntryRef let shaper = &self.shaper; - let lookup_key = ShapeCacheEntryRef { - text: text, - options: options, + let lookup_key = ShapeCacheEntry { + text: text.to_owned(), + options: options.clone(), }; - match self.shape_cache.find_equiv(&lookup_key) { + match self.shape_cache.find(&lookup_key) { None => {} - Some(glyphs) => return (*glyphs).clone(), + Some(glyphs) => return glyphs.clone(), } - let mut glyphs = GlyphStore::new(text.char_len() as int, + let mut glyphs = GlyphStore::new(text.chars().count() as int, options.flags.contains(IS_WHITESPACE_SHAPING_FLAG)); shaper.as_ref().unwrap().shape_text(text, options, &mut glyphs); let glyphs = Arc::new(glyphs); self.shape_cache.insert(ShapeCacheEntry { - text: text.into_string(), + text: text.to_owned(), options: *options, }, glyphs.clone()); glyphs diff --git a/components/gfx/font_cache_task.rs b/components/gfx/font_cache_task.rs index 4321cd5e613..ac7648e1821 100644 --- a/components/gfx/font_cache_task.rs +++ b/components/gfx/font_cache_task.rs @@ -9,8 +9,10 @@ use platform::font_list::get_last_resort_font_families; use platform::font_context::FontContextHandle; use collections::str::Str; +use std::borrow::ToOwned; use std::collections::HashMap; use std::sync::Arc; +use std::sync::mpsc::{Sender, Receiver, channel}; use font_template::{FontTemplate, FontTemplateDescriptor}; use platform::font_template::FontTemplateData; use servo_net::resource_task::{ResourceTask, load_whole_resource}; @@ -79,11 +81,15 @@ pub enum Command { Exit(Sender<()>), } +unsafe impl Send for Command {} + /// Reply messages sent from the font cache task to the FontContext caller. pub enum Reply { GetFontTemplateReply(Option<Arc<FontTemplateData>>), } +unsafe impl Send for Reply {} + /// The font cache task itself. It maintains a list of reference counted /// font templates that are currently in use. struct FontCache { @@ -108,7 +114,7 @@ fn add_generic_font(generic_fonts: &mut HashMap<LowercaseString, LowercaseString impl FontCache { fn run(&mut self) { loop { - let msg = self.port.recv(); + let msg = self.port.recv().unwrap(); match msg { Command::GetFontTemplate(family, descriptor, result) => { @@ -137,13 +143,13 @@ impl FontCache { family.add_template(url.to_string().as_slice(), Some(bytes)); }, Err(_) => { - debug!("Failed to load web font: family={} url={}", family_name, url); + debug!("Failed to load web font: family={:?} url={}", family_name, url); } } } Source::Local(ref local_family_name) => { let family = &mut self.web_families[family_name]; - get_variations_for_family(local_family_name.as_slice(), |path| { + get_variations_for_family(local_family_name.as_slice(), |&mut:path| { family.add_template(path.as_slice(), None); }); } @@ -185,7 +191,7 @@ impl FontCache { let s = &mut self.local_families[*family_name]; if s.templates.len() == 0 { - get_variations_for_family(family_name.as_slice(), |path| { + get_variations_for_family(family_name.as_slice(), |&mut:path| { s.add_template(path.as_slice(), None); }); } @@ -243,7 +249,7 @@ impl FontCache { /// The public interface to the font cache task, used exclusively by /// the per-thread/task FontContext structures. -#[deriving(Clone)] +#[derive(Clone)] pub struct FontCacheTask { chan: Sender<Command>, } @@ -252,7 +258,7 @@ impl FontCacheTask { pub fn new(resource_task: ResourceTask) -> FontCacheTask { let (chan, port) = channel(); - spawn_named("FontCacheTask", proc() { + spawn_named("FontCacheTask".to_owned(), move || { // TODO: Allow users to specify these. let mut generic_fonts = HashMap::with_capacity(5); add_generic_font(&mut generic_fonts, "serif", "Times New Roman"); @@ -285,7 +291,7 @@ impl FontCacheTask { let (response_chan, response_port) = channel(); self.chan.send(Command::GetFontTemplate(family, desc, response_chan)); - let reply = response_port.recv(); + let reply = response_port.recv().unwrap(); match reply { Reply::GetFontTemplateReply(data) => { @@ -300,7 +306,7 @@ impl FontCacheTask { let (response_chan, response_port) = channel(); self.chan.send(Command::GetLastResortFontTemplate(desc, response_chan)); - let reply = response_port.recv(); + let reply = response_port.recv().unwrap(); match reply { Reply::GetFontTemplateReply(data) => { diff --git a/components/gfx/font_context.rs b/components/gfx/font_context.rs index f39381b3d69..34e92b21540 100644 --- a/components/gfx/font_context.rs +++ b/components/gfx/font_context.rs @@ -17,6 +17,7 @@ use servo_util::smallvec::{SmallVec, SmallVec8}; use servo_util::geometry::Au; use servo_util::arc_ptr_eq; +use std::borrow::ToOwned; use std::rc::Rc; use std::cell::RefCell; use std::sync::Arc; @@ -168,7 +169,7 @@ impl FontContext { if !cache_hit { let font_template = self.font_cache_task.get_font_template(family.name() - .into_string(), + .to_owned(), desc.clone()); match font_template { Some(font_template) => { @@ -178,14 +179,14 @@ impl FontContext { style.font_variant); let layout_font = Rc::new(RefCell::new(layout_font)); self.layout_font_cache.push(LayoutFontCacheEntry { - family: family.name().into_string(), + family: family.name().to_owned(), font: Some(layout_font.clone()), }); fonts.push(layout_font); } None => { self.layout_font_cache.push(LayoutFontCacheEntry { - family: family.name().into_string(), + family: family.name().to_owned(), font: None, }); } diff --git a/components/gfx/font_template.rs b/components/gfx/font_template.rs index 2ee658009f8..d90df2b3bdb 100644 --- a/components/gfx/font_template.rs +++ b/components/gfx/font_template.rs @@ -7,6 +7,7 @@ use platform::font_context::FontContextHandle; use platform::font::FontHandle; use platform::font_template::FontTemplateData; +use std::borrow::ToOwned; use std::sync::{Arc, Weak}; use font::FontHandleMethods; @@ -14,7 +15,7 @@ use font::FontHandleMethods; /// This is very basic at the moment and needs to be /// expanded or refactored when we support more of the /// font styling parameters. -#[deriving(Clone, Copy)] +#[derive(Clone, Copy)] pub struct FontTemplateDescriptor { pub weight: font_weight::T, pub italic: bool, @@ -68,7 +69,7 @@ impl FontTemplate { }; FontTemplate { - identifier: identifier.into_string(), + identifier: identifier.to_owned(), descriptor: None, weak_ref: maybe_weak_ref, strong_ref: maybe_strong_ref, diff --git a/components/gfx/lib.rs b/components/gfx/lib.rs index d90a7185d8a..5f1eae371df 100644 --- a/components/gfx/lib.rs +++ b/components/gfx/lib.rs @@ -2,14 +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/. */ -#![feature(globs, macro_rules, phase, unsafe_destructor, default_type_params)] +#![feature(unsafe_destructor, int_uint, plugin, box_syntax)] #![deny(unused_imports)] #![deny(unused_variables)] #![allow(missing_copy_implementations)] +#![allow(unstable)] -#![feature(phase)] -#[phase(plugin, link)] +#[macro_use] extern crate log; extern crate azure; @@ -17,16 +17,15 @@ extern crate collections; extern crate geom; extern crate layers; extern crate libc; -extern crate rustrt; extern crate stb_image; extern crate png; extern crate script_traits; -extern crate serialize; +extern crate "serialize" as rustc_serialize; extern crate unicode; -#[phase(plugin)] +#[no_link] #[plugin] extern crate "plugins" as servo_plugins; extern crate "net" as servo_net; -#[phase(plugin, link)] +#[macro_use] extern crate "util" as servo_util; extern crate "msg" as servo_msg; extern crate style; diff --git a/components/gfx/paint_context.rs b/components/gfx/paint_context.rs index 4866a7aed00..2a4925beb83 100644 --- a/components/gfx/paint_context.rs +++ b/components/gfx/paint_context.rs @@ -32,7 +32,7 @@ use servo_util::range::Range; use std::default::Default; use std::f32; use std::mem; -use std::num::{Float, FloatMath}; +use std::num::Float; use std::ptr; use style::computed_values::{border_style, filter, mix_blend_mode}; use std::sync::Arc; @@ -54,7 +54,7 @@ pub struct PaintContext<'a> { pub transient_clip: Option<ClippingRegion>, } -#[deriving(Copy)] +#[derive(Copy)] enum Direction { Top, Left, @@ -62,7 +62,7 @@ enum Direction { Bottom } -#[deriving(Copy)] +#[derive(Copy)] enum DashSize { DottedBorder = 1, DashedBorder = 3 @@ -608,7 +608,7 @@ impl<'a> PaintContext<'a> { let rect = bounds.to_azure_rect(); let draw_opts = DrawOptions::new(1u as AzFloat, 0 as uint16_t); let mut stroke_opts = StrokeOptions::new(0u as AzFloat, 10u as AzFloat); - let mut dash: [AzFloat, ..2] = [0u as AzFloat, 0u as AzFloat]; + let mut dash: [AzFloat; 2] = [0u as AzFloat, 0u as AzFloat]; stroke_opts.set_cap_style(AZ_CAP_BUTT as u8); @@ -1149,7 +1149,7 @@ impl ScaledFontExtensionMethods for ScaledFont { let target = rctx.get_draw_target(); let pattern = ColorPattern::new(color); let azure_pattern = pattern.azure_color_pattern; - assert!(azure_pattern.is_not_null()); + assert!(!azure_pattern.is_null()); let fields = if antialias { 0x0200 diff --git a/components/gfx/paint_task.rs b/components/gfx/paint_task.rs index efb1182a795..21eff70f32f 100644 --- a/components/gfx/paint_task.rs +++ b/components/gfx/paint_task.rs @@ -5,7 +5,7 @@ //! The task that handles all painting. use buffer_map::BufferMap; -use display_list::{mod, StackingContext}; +use display_list::{self, StackingContext}; use font_cache_task::FontCacheTask; use font_context::FontContext; use paint_context::PaintContext; @@ -31,13 +31,13 @@ use servo_util::smallvec::SmallVec; use servo_util::task::spawn_named_with_send_on_failure; use servo_util::task_state; use servo_util::time::{TimeProfilerChan, TimeProfilerCategory, profile}; -use std::comm::{Receiver, Sender, channel}; use std::mem; -use std::task::TaskBuilder; +use std::thread::Builder; use std::sync::Arc; +use std::sync::mpsc::{Receiver, Sender, channel}; /// Information about a hardware graphics layer that layout sends to the painting task. -#[deriving(Clone)] +#[derive(Clone)] pub struct PaintLayer { /// A per-pipeline ID describing this layer that should be stable across reflows. pub id: LayerId, @@ -74,7 +74,7 @@ pub enum Msg { Exit(Option<Sender<()>>, PipelineExitType), } -#[deriving(Clone)] +#[derive(Clone)] pub struct PaintChan(Sender<Msg>); impl PaintChan { @@ -84,13 +84,12 @@ impl PaintChan { } pub fn send(&self, msg: Msg) { - let &PaintChan(ref chan) = self; - assert!(chan.send_opt(msg).is_ok(), "PaintChan.send: paint port closed") + assert!(self.send_opt(msg).is_ok(), "PaintChan.send: paint port closed") } pub fn send_opt(&self, msg: Msg) -> Result<(), Msg> { let &PaintChan(ref chan) = self; - chan.send_opt(msg) + chan.send(msg).map_err(|e| e.0) } } @@ -132,7 +131,7 @@ macro_rules! native_graphics_context( ($task:expr) => ( $task.native_graphics_context.as_ref().expect("Need a graphics context to do painting") ) -) +); impl<C> PaintTask<C> where C: PaintListener + Send { pub fn create(id: PipelineId, @@ -144,7 +143,7 @@ impl<C> PaintTask<C> where C: PaintListener + Send { time_profiler_chan: TimeProfilerChan, shutdown_chan: Sender<()>) { let ConstellationChan(c) = constellation_chan.clone(); - spawn_named_with_send_on_failure("PaintTask", task_state::PAINT, proc() { + spawn_named_with_send_on_failure("PaintTask", task_state::PAINT, move |:| { { // Ensures that the paint task and graphics context are destroyed before the // shutdown message. @@ -196,7 +195,7 @@ impl<C> PaintTask<C> where C: PaintListener + Send { let mut exit_response_channel : Option<Sender<()>> = None; let mut waiting_for_compositor_buffers_to_exit = false; loop { - match self.port.recv() { + match self.port.recv().unwrap() { Msg::PaintInit(stacking_context) => { self.root_stacking_context = Some(stacking_context.clone()); @@ -226,7 +225,7 @@ impl<C> PaintTask<C> where C: PaintListener + Send { if self.epoch == epoch { self.paint(&mut replies, buffer_requests, scale, layer_id); } else { - debug!("painter epoch mismatch: {} != {}", self.epoch, epoch); + debug!("painter epoch mismatch: {:?} != {:?}", self.epoch, epoch); } } @@ -336,7 +335,7 @@ impl<C> PaintTask<C> where C: PaintListener + Send { mut tiles: Vec<BufferRequest>, scale: f32, layer_id: LayerId) { - profile(TimeProfilerCategory::Painting, None, self.time_profiler_chan.clone(), || { + profile(TimeProfilerCategory::Painting, None, self.time_profiler_chan.clone(), |:| { // Bail out if there is no appropriate stacking context. let stacking_context = if let Some(ref stacking_context) = self.root_stacking_context { match display_list::find_stacking_context_with_layer_id(stacking_context, @@ -360,10 +359,10 @@ impl<C> PaintTask<C> where C: PaintListener + Send { stacking_context.clone(), scale); } - let new_buffers = Vec::from_fn(tile_count, |i| { + let new_buffers = (0..tile_count).map(|&mut :i| { let thread_id = i % self.worker_threads.len(); self.worker_threads[thread_id].get_painted_tile_buffer() - }); + }).collect(); let layer_buffer_set = box LayerBufferSet { buffers: new_buffers, @@ -425,13 +424,13 @@ impl WorkerThreadProxy { } else { opts::get().layout_threads }; - Vec::from_fn(thread_count, |_| { + (0..thread_count).map(|&:_| { let (from_worker_sender, from_worker_receiver) = channel(); let (to_worker_sender, to_worker_receiver) = channel(); let native_graphics_metadata = native_graphics_metadata.clone(); let font_cache_task = font_cache_task.clone(); let time_profiler_chan = time_profiler_chan.clone(); - TaskBuilder::new().spawn(proc() { + Builder::new().spawn(move || { let mut worker_thread = WorkerThread::new(from_worker_sender, to_worker_receiver, native_graphics_metadata, @@ -443,7 +442,7 @@ impl WorkerThreadProxy { receiver: from_worker_receiver, sender: to_worker_sender, } - }) + }).collect() } fn paint_tile(&mut self, @@ -451,17 +450,17 @@ impl WorkerThreadProxy { layer_buffer: Option<Box<LayerBuffer>>, stacking_context: Arc<StackingContext>, scale: f32) { - self.sender.send(MsgToWorkerThread::PaintTile(tile, layer_buffer, stacking_context, scale)) + self.sender.send(MsgToWorkerThread::PaintTile(tile, layer_buffer, stacking_context, scale)).unwrap() } fn get_painted_tile_buffer(&mut self) -> Box<LayerBuffer> { - match self.receiver.recv() { + match self.receiver.recv().unwrap() { MsgFromWorkerThread::PaintedTile(layer_buffer) => layer_buffer, } } fn exit(&mut self) { - self.sender.send(MsgToWorkerThread::Exit) + self.sender.send(MsgToWorkerThread::Exit).unwrap() } } @@ -493,7 +492,7 @@ impl WorkerThread { fn main(&mut self) { loop { - match self.receiver.recv() { + match self.receiver.recv().unwrap() { MsgToWorkerThread::Exit => break, MsgToWorkerThread::PaintTile(tile, layer_buffer, stacking_context, scale) => { let draw_target = self.optimize_and_paint_tile(&tile, stacking_context, scale); @@ -501,7 +500,7 @@ impl WorkerThread { layer_buffer, draw_target, scale); - self.sender.send(MsgFromWorkerThread::PaintedTile(buffer)) + self.sender.send(MsgFromWorkerThread::PaintedTile(buffer)).unwrap() } } } @@ -582,7 +581,7 @@ impl WorkerThread { // GPU painting mode, so that it doesn't have to recreate it. if !opts::get().gpu_painting { let mut buffer = layer_buffer.unwrap(); - draw_target.snapshot().get_data_surface().with_data(|data| { + draw_target.snapshot().get_data_surface().with_data(|&mut:data| { buffer.native_surface.upload(native_graphics_context!(self), data); debug!("painting worker thread uploading to native surface {}", buffer.native_surface.get_id()); diff --git a/components/gfx/platform/freetype/font.rs b/components/gfx/platform/freetype/font.rs index e2a5525aea0..2e13a4f39aa 100644 --- a/components/gfx/platform/freetype/font.rs +++ b/components/gfx/platform/freetype/font.rs @@ -8,6 +8,7 @@ use font::{FontHandleMethods, FontMetrics, FontTableMethods}; use font::{FontTableTag, FractionalPixel}; use servo_util::geometry::Au; use servo_util::geometry; +use servo_util::str::c_str_to_string; use platform::font_context::FontContextHandle; use text::glyph::GlyphId; use text::util::{float_to_fixed, fixed_to_float}; @@ -25,11 +26,10 @@ use freetype::freetype::{FT_SizeRec, FT_UInt, FT_Size_Metrics, struct_FT_Vector_ use freetype::freetype::{ft_sfnt_os2}; use freetype::tt_os2::TT_OS2; +use libc::c_char; use std::mem; use std::num::Float; use std::ptr; -use std::string::String; - use std::sync::Arc; fn float_to_fixed_ft(f: f64) -> i32 { @@ -43,7 +43,7 @@ fn fixed_to_float_ft(f: i32) -> f64 { pub struct FontTable; impl FontTableMethods for FontTable { - fn with_buffer(&self, _blk: |*const u8, uint|) { + fn with_buffer<F>(&self, _blk: F) where F: FnOnce(*const u8, uint) { panic!() } } @@ -59,7 +59,7 @@ pub struct FontHandle { #[unsafe_destructor] impl Drop for FontHandle { fn drop(&mut self) { - assert!(self.face.is_not_null()); + assert!(!self.face.is_null()); unsafe { if !FT_Done_Face(self.face).succeeded() { panic!("FT_Done_Face failed"); @@ -121,10 +121,14 @@ impl FontHandleMethods for FontHandle { self.font_data.clone() } fn family_name(&self) -> String { - unsafe { String::from_raw_buf(&*(*self.face).family_name as *const i8 as *const u8) } + unsafe { + c_str_to_string((*self.face).family_name as *const c_char) + } } fn face_name(&self) -> String { - unsafe { String::from_raw_buf(&*FT_Get_Postscript_Name(self.face) as *const i8 as *const u8) } + unsafe { + c_str_to_string(FT_Get_Postscript_Name(self.face) as *const c_char) + } } fn is_italic(&self) -> bool { unsafe { (*self.face).style_flags & FT_STYLE_FLAG_ITALIC != 0 } @@ -136,7 +140,7 @@ impl FontHandleMethods for FontHandle { } else { unsafe { let os2 = FT_Get_Sfnt_Table(self.face, ft_sfnt_os2) as *mut TT_OS2; - let valid = os2.is_not_null() && (*os2).version != 0xffff; + let valid = !os2.is_null() && (*os2).version != 0xffff; if valid { let weight =(*os2).usWeightClass; match weight { @@ -158,9 +162,8 @@ impl FontHandleMethods for FontHandle { } } - fn glyph_index(&self, - codepoint: char) -> Option<GlyphId> { - assert!(self.face.is_not_null()); + fn glyph_index(&self, codepoint: char) -> Option<GlyphId> { + assert!(!self.face.is_null()); unsafe { let idx = FT_Get_Char_Index(self.face, codepoint as FT_ULong); return if idx != 0 as FT_UInt { @@ -173,8 +176,8 @@ impl FontHandleMethods for FontHandle { } fn glyph_h_kerning(&self, first_glyph: GlyphId, second_glyph: GlyphId) - -> FractionalPixel { - assert!(self.face.is_not_null()); + -> FractionalPixel { + assert!(!self.face.is_null()); let mut delta = struct_FT_Vector_ { x: 0, y: 0 }; unsafe { FT_Get_Kerning(self.face, first_glyph, second_glyph, FT_KERNING_DEFAULT, &mut delta); @@ -182,15 +185,14 @@ impl FontHandleMethods for FontHandle { fixed_to_float_ft(delta.x as i32) } - fn glyph_h_advance(&self, - glyph: GlyphId) -> Option<FractionalPixel> { - assert!(self.face.is_not_null()); + fn glyph_h_advance(&self, glyph: GlyphId) -> Option<FractionalPixel> { + assert!(!self.face.is_null()); unsafe { let res = FT_Load_Glyph(self.face, glyph as FT_UInt, 0); if res.succeeded() { let void_glyph = (*self.face).glyph; let slot: FT_GlyphSlot = mem::transmute(void_glyph); - assert!(slot.is_not_null()); + assert!(!slot.is_null()); let advance = (*slot).metrics.horiAdvance; debug!("h_advance for {} is {}", glyph, advance); let advance = advance as i32; @@ -227,7 +229,7 @@ impl FontHandleMethods for FontHandle { let mut x_height = geometry::from_pt(0.0); unsafe { let os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2) as *mut TT_OS2; - let valid = os2.is_not_null() && (*os2).version != 0xffff; + let valid = !os2.is_null() && (*os2).version != 0xffff; if valid { strikeout_size = self.font_units_to_au((*os2).yStrikeoutSize as f64); strikeout_offset = self.font_units_to_au((*os2).yStrikeoutPosition as f64); @@ -255,7 +257,7 @@ impl FontHandleMethods for FontHandle { line_gap: height, }; - debug!("Font metrics (@{} pt): {}", geometry::to_pt(em_size), metrics); + debug!("Font metrics (@{} pt): {:?}", geometry::to_pt(em_size), metrics); return metrics; } diff --git a/components/gfx/platform/freetype/font_context.rs b/components/gfx/platform/freetype/font_context.rs index 7ff3b136189..1c58233f0f7 100644 --- a/components/gfx/platform/freetype/font_context.rs +++ b/components/gfx/platform/freetype/font_context.rs @@ -37,19 +37,19 @@ extern fn ft_realloc(_mem: FT_Memory, _cur_size: c_long, new_size: c_long, block } } -#[deriving(Clone)] +#[derive(Clone)] pub struct FreeTypeLibraryHandle { pub ctx: FT_Library, } -#[deriving(Clone)] +#[derive(Clone)] pub struct FontContextHandle { pub ctx: Rc<FreeTypeLibraryHandle>, } impl Drop for FreeTypeLibraryHandle { fn drop(&mut self) { - assert!(self.ctx.is_not_null()); + assert!(!self.ctx.is_null()); unsafe { FT_Done_FreeType(self.ctx) }; } } diff --git a/components/gfx/platform/freetype/font_list.rs b/components/gfx/platform/freetype/font_list.rs index bd62b725d9e..fbe354556c4 100644 --- a/components/gfx/platform/freetype/font_list.rs +++ b/components/gfx/platform/freetype/font_list.rs @@ -20,16 +20,19 @@ use fontconfig::fontconfig::{ FcObjectSetAdd, FcPatternGetInteger }; +use servo_util::str::c_str_to_string; + use libc; -use libc::c_int; +use libc::{c_int, c_char}; +use std::borrow::ToOwned; +use std::ffi::CString; use std::ptr; -use std::string::String; static FC_FAMILY: &'static [u8] = b"family\0"; static FC_FILE: &'static [u8] = b"file\0"; static FC_INDEX: &'static [u8] = b"index\0"; -pub fn get_available_families(callback: |String|) { +pub fn get_available_families<F>(mut callback: F) where F: FnMut(String) { unsafe { let config = FcConfigGetCurrent(); let fontSet = FcConfigGetFonts(config, FcSetSystem); @@ -37,8 +40,8 @@ pub fn get_available_families(callback: |String|) { let font = (*fontSet).fonts.offset(i); let mut family: *mut FcChar8 = ptr::null_mut(); let mut v: c_int = 0; - while FcPatternGetString(*font, FC_FAMILY.as_ptr() as *mut i8, v, &mut family) == FcResultMatch { - let family_name = String::from_raw_buf(family as *const i8 as *const u8); + while FcPatternGetString(*font, FC_FAMILY.as_ptr() as *mut c_char, v, &mut family) == FcResultMatch { + let family_name = c_str_to_string(family as *const c_char); callback(family_name); v += 1; } @@ -46,24 +49,26 @@ pub fn get_available_families(callback: |String|) { } } -pub fn get_variations_for_family(family_name: &str, callback: |String|) { +pub fn get_variations_for_family<F>(family_name: &str, mut callback: F) + where F: FnMut(String) +{ debug!("getting variations for {}", family_name); unsafe { let config = FcConfigGetCurrent(); let mut font_set = FcConfigGetFonts(config, FcSetSystem); let font_set_array_ptr = &mut font_set; let pattern = FcPatternCreate(); - assert!(pattern.is_not_null()); - let mut family_name_c = family_name.to_c_str(); - let family_name = family_name_c.as_mut_ptr(); - let ok = FcPatternAddString(pattern, FC_FAMILY.as_ptr() as *mut i8, family_name as *mut FcChar8); + assert!(!pattern.is_null()); + let family_name_c = CString::from_slice(family_name.as_bytes()); + let family_name = family_name_c.as_ptr(); + let ok = FcPatternAddString(pattern, FC_FAMILY.as_ptr() as *mut c_char, family_name as *mut FcChar8); assert!(ok != 0); let object_set = FcObjectSetCreate(); - assert!(object_set.is_not_null()); + assert!(!object_set.is_null()); - FcObjectSetAdd(object_set, FC_FILE.as_ptr() as *mut i8); - FcObjectSetAdd(object_set, FC_INDEX.as_ptr() as *mut i8); + FcObjectSetAdd(object_set, FC_FILE.as_ptr() as *mut c_char); + FcObjectSetAdd(object_set, FC_INDEX.as_ptr() as *mut c_char); let matches = FcFontSetList(config, font_set_array_ptr, 1, pattern, object_set); @@ -72,13 +77,13 @@ pub fn get_variations_for_family(family_name: &str, callback: |String|) { for i in range(0, (*matches).nfont as int) { let font = (*matches).fonts.offset(i); let mut file: *mut FcChar8 = ptr::null_mut(); - let file = if FcPatternGetString(*font, FC_FILE.as_ptr() as *mut i8, 0, &mut file) == FcResultMatch { - String::from_raw_buf(file as *const i8 as *const u8) + let file = if FcPatternGetString(*font, FC_FILE.as_ptr() as *mut c_char, 0, &mut file) == FcResultMatch { + c_str_to_string(file as *const c_char) } else { panic!(); }; let mut index: libc::c_int = 0; - let index = if FcPatternGetInteger(*font, FC_INDEX.as_ptr() as *mut i8, 0, &mut index) == FcResultMatch { + let index = if FcPatternGetInteger(*font, FC_INDEX.as_ptr() as *mut c_char, 0, &mut index) == FcResultMatch { index } else { panic!(); @@ -97,8 +102,8 @@ pub fn get_variations_for_family(family_name: &str, callback: |String|) { } pub fn get_system_default_family(generic_name: &str) -> Option<String> { - let mut generic_name_c = generic_name.to_c_str(); - let generic_name_ptr = generic_name_c.as_mut_ptr(); + let generic_name_c = CString::from_slice(generic_name.as_bytes()); + let generic_name_ptr = generic_name_c.as_ptr(); unsafe { let pattern = FcNameParse(generic_name_ptr as *mut FcChar8); @@ -111,8 +116,8 @@ pub fn get_system_default_family(generic_name: &str) -> Option<String> { let family_name = if result == FcResultMatch { let mut match_string: *mut FcChar8 = ptr::null_mut(); - FcPatternGetString(family_match, FC_FAMILY.as_ptr() as *mut i8, 0, &mut match_string); - let result = String::from_raw_buf(match_string as *const i8 as *const u8); + FcPatternGetString(family_match, FC_FAMILY.as_ptr() as *mut c_char, 0, &mut match_string); + let result = c_str_to_string(match_string as *const c_char); FcPatternDestroy(family_match); Some(result) } else { @@ -127,13 +132,13 @@ pub fn get_system_default_family(generic_name: &str) -> Option<String> { #[cfg(target_os="linux")] pub fn get_last_resort_font_families() -> Vec<String> { vec!( - "Fira Sans".into_string(), - "DejaVu Sans".into_string(), - "Arial".into_string() + "Fira Sans".to_owned(), + "DejaVu Sans".to_owned(), + "Arial".to_owned() ) } #[cfg(target_os="android")] pub fn get_last_resort_font_families() -> Vec<String> { - vec!("Roboto".into_string()) + vec!("Roboto".to_owned()) } diff --git a/components/gfx/platform/freetype/font_template.rs b/components/gfx/platform/freetype/font_template.rs index 79da895b52f..f2be1ad6d14 100644 --- a/components/gfx/platform/freetype/font_template.rs +++ b/components/gfx/platform/freetype/font_template.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use std::borrow::ToOwned; use std::io; use std::io::File; @@ -29,7 +30,7 @@ impl FontTemplateData { FontTemplateData { bytes: bytes, - identifier: identifier.into_string(), + identifier: identifier.to_owned(), } } } diff --git a/components/gfx/platform/macos/font.rs b/components/gfx/platform/macos/font.rs index 2e3aae29dc7..db168c657e6 100644 --- a/components/gfx/platform/macos/font.rs +++ b/components/gfx/platform/macos/font.rs @@ -47,7 +47,7 @@ impl FontTable { } impl FontTableMethods for FontTable { - fn with_buffer(&self, blk: |*const u8, uint|) { + fn with_buffer<F>(&self, blk: F) where F: FnOnce(*const u8, uint) { blk(self.data.bytes().as_ptr(), self.data.len() as uint); } } @@ -112,8 +112,8 @@ impl FontHandleMethods for FontHandle { } fn glyph_index(&self, codepoint: char) -> Option<GlyphId> { - let characters: [UniChar, ..1] = [codepoint as UniChar]; - let mut glyphs: [CGGlyph, ..1] = [0 as CGGlyph]; + let characters: [UniChar; 1] = [codepoint as UniChar]; + let mut glyphs: [CGGlyph; 1] = [0 as CGGlyph]; let count: CFIndex = 1; let result = self.ctfont.get_glyphs_for_characters(&characters[0], @@ -179,7 +179,7 @@ impl FontHandleMethods for FontHandle { average_advance: average_advance, line_gap: Au::from_frac_px(line_gap), }; - debug!("Font metrics (@{} pt): {}", self.ctfont.pt_size() as f64, metrics); + debug!("Font metrics (@{} pt): {:?}", self.ctfont.pt_size() as f64, metrics); return metrics; } diff --git a/components/gfx/platform/macos/font_context.rs b/components/gfx/platform/macos/font_context.rs index e65381c3bbc..e35aadb9910 100644 --- a/components/gfx/platform/macos/font_context.rs +++ b/components/gfx/platform/macos/font_context.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#[deriving(Clone)] +#[derive(Clone)] pub struct FontContextHandle { ctx: () } diff --git a/components/gfx/platform/macos/font_list.rs b/components/gfx/platform/macos/font_list.rs index 4a10b0ee463..4e327cea1b8 100644 --- a/components/gfx/platform/macos/font_list.rs +++ b/components/gfx/platform/macos/font_list.rs @@ -6,9 +6,11 @@ use core_foundation::base::TCFType; use core_foundation::string::{CFString, CFStringRef}; use core_text::font_descriptor::{CTFontDescriptor, CTFontDescriptorRef}; use core_text; + +use std::borrow::ToOwned; use std::mem; -pub fn get_available_families(callback: |String|) { +pub fn get_available_families<F>(mut callback: F) where F: FnMut(String) { let family_names = core_text::font_collection::get_family_names(); for strref in family_names.iter() { let family_name_ref: CFStringRef = unsafe { mem::transmute(strref) }; @@ -18,7 +20,7 @@ pub fn get_available_families(callback: |String|) { } } -pub fn get_variations_for_family(family_name: &str, callback: |String|) { +pub fn get_variations_for_family<F>(family_name: &str, mut callback: F) where F: FnMut(String) { debug!("Looking for faces of family: {}", family_name); let family_collection = @@ -42,5 +44,5 @@ pub fn get_system_default_family(_generic_name: &str) -> Option<String> { } pub fn get_last_resort_font_families() -> Vec<String> { - vec!("Arial Unicode MS".into_string(), "Arial".into_string()) + vec!("Arial Unicode MS".to_owned(), "Arial".to_owned()) } diff --git a/components/gfx/platform/macos/font_template.rs b/components/gfx/platform/macos/font_template.rs index 9bb6b753a11..c6eb84d9746 100644 --- a/components/gfx/platform/macos/font_template.rs +++ b/components/gfx/platform/macos/font_template.rs @@ -7,6 +7,8 @@ use core_graphics::font::CGFont; use core_text::font::CTFont; use core_text; +use std::borrow::ToOwned; + /// Platform specific font representation for mac. /// The identifier is a PostScript font name. The /// CTFont object is cached here for use by the @@ -16,6 +18,9 @@ pub struct FontTemplateData { pub identifier: String, } +unsafe impl Send for FontTemplateData {} +unsafe impl Sync for FontTemplateData {} + impl FontTemplateData { pub fn new(identifier: &str, font_data: Option<Vec<u8>>) -> FontTemplateData { let ctfont = match font_data { @@ -34,7 +39,7 @@ impl FontTemplateData { FontTemplateData { ctfont: ctfont, - identifier: identifier.into_string(), + identifier: identifier.to_owned(), } } } diff --git a/components/gfx/text/glyph.rs b/components/gfx/text/glyph.rs index 06e16c04a79..be4b2d3c4d4 100644 --- a/components/gfx/text/glyph.rs +++ b/components/gfx/text/glyph.rs @@ -7,10 +7,11 @@ use servo_util::range; use servo_util::range::{Range, RangeIndex, EachIndex}; use servo_util::geometry::Au; -use std::cmp::PartialOrd; +use std::cmp::{Ordering, PartialOrd}; use std::iter::repeat; -use std::num::NumCast; +use std::num::{ToPrimitive, NumCast}; use std::mem; +use std::ops::{Add, Sub, Mul, Neg, Div, Rem, BitAnd, BitOr, BitXor, Shl, Shr, Not}; use std::u16; use std::vec::Vec; use geom::point::Point2D; @@ -23,7 +24,7 @@ use geom::point::Point2D; /// In the uncommon case (multiple glyphs per unicode character, large glyph index/advance, or /// glyph offsets), we pack the glyph count into GlyphEntry, and store the other glyph information /// in DetailedGlyphStore. -#[deriving(Clone, Show, Copy)] +#[derive(Clone, Show, Copy)] struct GlyphEntry { value: u32, } @@ -88,7 +89,7 @@ impl GlyphEntry { pub type GlyphId = u32; // TODO: unify with bit flags? -#[deriving(PartialEq, Copy)] +#[derive(PartialEq, Copy)] pub enum BreakType { None, Normal, @@ -252,7 +253,7 @@ impl GlyphEntry { // Stores data for a detailed glyph, in the case that several glyphs // correspond to one character, or the glyph's data couldn't be packed. -#[deriving(Clone, Show, Copy)] +#[derive(Clone, Show, Copy)] struct DetailedGlyph { id: GlyphId, // glyph's advance, in the text's direction (RTL or RTL) @@ -271,7 +272,7 @@ impl DetailedGlyph { } } -#[deriving(PartialEq, Clone, Eq, Show, Copy)] +#[derive(PartialEq, Clone, Eq, Show, Copy)] struct DetailedGlyphRecord { // source string offset/GlyphEntry offset in the TextRun entry_offset: CharIndex, @@ -320,7 +321,7 @@ impl<'a> DetailedGlyphStore { detail_offset: self.detail_buffer.len() as int, }; - debug!("Adding entry[off={}] for detailed glyphs: {}", entry_offset, glyphs); + debug!("Adding entry[off={:?}] for detailed glyphs: {:?}", entry_offset, glyphs); /* TODO: don't actually assert this until asserts are compiled in/out based on severity, debug/release, etc. This assertion @@ -340,7 +341,7 @@ impl<'a> DetailedGlyphStore { fn get_detailed_glyphs_for_entry(&'a self, entry_offset: CharIndex, count: u16) -> &'a [DetailedGlyph] { - debug!("Requesting detailed glyphs[n={}] for entry[off={}]", count, entry_offset); + debug!("Requesting detailed glyphs[n={}] for entry[off={:?}]", count, entry_offset); // FIXME: Is this right? --pcwalton // TODO: should fix this somewhere else @@ -398,9 +399,9 @@ impl<'a> DetailedGlyphStore { let mut mut_records : Vec<DetailedGlyphRecord> = unsorted_records; mut_records.sort_by(|a, b| { if a < b { - Less + Ordering::Less } else { - Greater + Ordering::Greater } }); let mut sorted_records = mut_records; @@ -412,7 +413,7 @@ impl<'a> DetailedGlyphStore { // This struct is used by GlyphStore clients to provide new glyph data. // It should be allocated on the stack and passed by reference to GlyphStore. -#[deriving(Copy)] +#[derive(Copy)] pub struct GlyphData { id: GlyphId, advance: Au, @@ -445,7 +446,7 @@ impl GlyphData { // through glyphs (either for a particular TextRun offset, or all glyphs). // Rather than eagerly assembling and copying glyph data, it only retrieves // values as they are needed from the GlyphStore, using provided offsets. -#[deriving(Copy)] +#[derive(Copy)] pub enum GlyphInfo<'a> { Simple(&'a GlyphStore, CharIndex), Detail(&'a GlyphStore, CharIndex, u16), @@ -514,7 +515,7 @@ pub struct GlyphStore { } int_range_index! { - #[deriving(Encodable)] + #[derive(RustcEncodable)] #[doc = "An index that refers to a character in a text run. This could \ point to the middle of a glyph."] struct CharIndex(int) @@ -580,11 +581,11 @@ impl<'a> GlyphStore { let entry = match first_glyph_data.is_missing { true => GlyphEntry::missing(glyph_count), false => { - let glyphs_vec = Vec::from_fn(glyph_count as uint, |i| { + let glyphs_vec: Vec<DetailedGlyph> = (0..glyph_count as uint).map(|&:i| { DetailedGlyph::new(data_for_glyphs[i].id, data_for_glyphs[i].advance, data_for_glyphs[i].offset) - }); + }).collect(); self.detail_store.add_detailed_glyphs_for_entry(i, glyphs_vec.as_slice()); GlyphEntry::complex(first_glyph_data.cluster_start, @@ -593,7 +594,7 @@ impl<'a> GlyphStore { } }.adapt_character_flags_of_entry(self.entry_buffer[i.to_uint()]); - debug!("Adding multiple glyphs[idx={}, count={}]: {}", i, glyph_count, entry); + debug!("Adding multiple glyphs[idx={:?}, count={}]: {:?}", i, glyph_count, entry); self.entry_buffer[i.to_uint()] = entry; } @@ -603,7 +604,7 @@ impl<'a> GlyphStore { assert!(i < self.char_len()); let entry = GlyphEntry::complex(cluster_start, ligature_start, 0); - debug!("adding spacer for chracter without associated glyph[idx={}]", i); + debug!("adding spacer for chracter without associated glyph[idx={:?}]", i); self.entry_buffer[i.to_uint()] = entry; } @@ -725,7 +726,9 @@ impl<'a> GlyphIterator<'a> { } } -impl<'a> Iterator<(CharIndex, GlyphInfo<'a>)> for GlyphIterator<'a> { +impl<'a> Iterator for GlyphIterator<'a> { + type Item = (CharIndex, GlyphInfo<'a>); + // I tried to start with something simpler and apply FlatMap, but the // inability to store free variables in the FlatMap struct was problematic. // @@ -740,7 +743,7 @@ impl<'a> Iterator<(CharIndex, GlyphInfo<'a>)> for GlyphIterator<'a> { self.next_glyph_range() } else { // No glyph range. Look at next character. - self.char_range.next().and_then(|i| { + self.char_range.next().and_then(|:i| { self.char_index = i; assert!(i < self.store.char_len()); let entry = self.store.entry_buffer[i.to_uint()]; diff --git a/components/gfx/text/shaping/harfbuzz.rs b/components/gfx/text/shaping/harfbuzz.rs index fb5d83b6457..98b287ba086 100644 --- a/components/gfx/text/shaping/harfbuzz.rs +++ b/components/gfx/text/shaping/harfbuzz.rs @@ -78,11 +78,11 @@ impl ShapedGlyphData { let mut glyph_count = 0; let glyph_infos = RUST_hb_buffer_get_glyph_infos(buffer, &mut glyph_count); let glyph_count = glyph_count as int; - assert!(glyph_infos.is_not_null()); + assert!(!glyph_infos.is_null()); let mut pos_count = 0; let pos_infos = RUST_hb_buffer_get_glyph_positions(buffer, &mut pos_count); let pos_count = pos_count as int; - assert!(pos_infos.is_not_null()); + assert!(!pos_infos.is_null()); assert!(glyph_count == pos_count); ShapedGlyphData { @@ -160,13 +160,13 @@ pub struct Shaper { impl Drop for Shaper { fn drop(&mut self) { unsafe { - assert!(self.hb_face.is_not_null()); + assert!(!self.hb_face.is_null()); RUST_hb_face_destroy(self.hb_face); - assert!(self.hb_font.is_not_null()); + assert!(!self.hb_font.is_null()); RUST_hb_font_destroy(self.hb_font); - assert!(self.hb_funcs.is_not_null()); + assert!(!self.hb_funcs.is_null()); RUST_hb_font_funcs_destroy(self.hb_funcs); } } @@ -274,7 +274,7 @@ impl Shaper { let glyph_data = ShapedGlyphData::new(buffer); let glyph_count = glyph_data.len(); let byte_max = text.len() as int; - let char_max = text.char_len() as int; + let char_max = text.chars().count() as int; // GlyphStore records are indexed by character, not byte offset. // so, we must be careful to increment this when saving glyph entries. @@ -536,7 +536,7 @@ extern fn glyph_func(_: *mut hb_font_t, _: *mut c_void) -> hb_bool_t { let font: *const Font = font_data as *const Font; - assert!(font.is_not_null()); + assert!(!font.is_null()); unsafe { match (*font).glyph_index(char::from_u32(unicode).unwrap()) { @@ -555,7 +555,7 @@ extern fn glyph_h_advance_func(_: *mut hb_font_t, _: *mut c_void) -> hb_position_t { let font: *mut Font = font_data as *mut Font; - assert!(font.is_not_null()); + assert!(!font.is_null()); unsafe { let advance = (*font).glyph_h_advance(glyph as GlyphId); @@ -570,7 +570,7 @@ extern fn glyph_h_kerning_func(_: *mut hb_font_t, _: *mut c_void) -> hb_position_t { let font: *mut Font = font_data as *mut Font; - assert!(font.is_not_null()); + assert!(!font.is_null()); unsafe { let advance = (*font).glyph_h_kerning(first_glyph as GlyphId, second_glyph as GlyphId); @@ -587,8 +587,8 @@ extern fn get_font_table_func(_: *mut hb_face_t, // NB: These asserts have security implications. let font_and_shaping_options: *const FontAndShapingOptions = user_data as *const FontAndShapingOptions; - assert!(font_and_shaping_options.is_not_null()); - assert!((*font_and_shaping_options).font.is_not_null()); + assert!(!font_and_shaping_options.is_null()); + assert!(!(*font_and_shaping_options).font.is_null()); // TODO(Issue #197): reuse font table data, which will change the unsound trickery here. match (*(*font_and_shaping_options).font).get_table_for_tag(tag as FontTableTag) { @@ -606,7 +606,7 @@ extern fn get_font_table_func(_: *mut hb_face_t, destroy_blob_func); }); - assert!(blob.is_not_null()); + assert!(!blob.is_null()); blob } } diff --git a/components/gfx/text/text_run.rs b/components/gfx/text/text_run.rs index 8b8230a94cc..f98d47fe547 100644 --- a/components/gfx/text/text_run.rs +++ b/components/gfx/text/text_run.rs @@ -8,12 +8,13 @@ use platform::font_template::FontTemplateData; use servo_util::geometry::Au; use servo_util::range::Range; use servo_util::vec::{Comparator, FullBinarySearchMethods}; -use std::slice::Items; +use std::cmp::Ordering; +use std::slice::Iter; use std::sync::Arc; use text::glyph::{CharIndex, GlyphStore}; /// A single "paragraph" of text in one font size and style. -#[deriving(Clone)] +#[derive(Clone)] pub struct TextRun { pub text: Arc<String>, pub font_template: Arc<FontTemplateData>, @@ -24,7 +25,7 @@ pub struct TextRun { } /// A single series of glyphs within a text run. -#[deriving(Clone)] +#[derive(Clone)] pub struct GlyphRun { /// The glyphs. pub glyph_store: Arc<GlyphStore>, @@ -33,7 +34,7 @@ pub struct GlyphRun { } pub struct NaturalWordSliceIterator<'a> { - glyph_iter: Items<'a, GlyphRun>, + glyph_iter: Iter<'a, GlyphRun>, range: Range<CharIndex>, } @@ -42,11 +43,11 @@ struct CharIndexComparator; impl Comparator<CharIndex,GlyphRun> for CharIndexComparator { fn compare(&self, key: &CharIndex, value: &GlyphRun) -> Ordering { if *key < value.range.begin() { - Less + Ordering::Less } else if *key >= value.range.end() { - Greater + Ordering::Greater } else { - Equal + Ordering::Equal } } } @@ -72,7 +73,9 @@ impl<'a> TextRunSlice<'a> { } } -impl<'a> Iterator<TextRunSlice<'a>> for NaturalWordSliceIterator<'a> { +impl<'a> Iterator for NaturalWordSliceIterator<'a> { + type Item = TextRunSlice<'a>; + // inline(always) due to the inefficient rt failures messing up inline heuristics, I think. #[inline(always)] fn next(&mut self) -> Option<TextRunSlice<'a>> { @@ -100,11 +103,13 @@ impl<'a> Iterator<TextRunSlice<'a>> for NaturalWordSliceIterator<'a> { pub struct CharacterSliceIterator<'a> { glyph_run: Option<&'a GlyphRun>, - glyph_run_iter: Items<'a, GlyphRun>, + glyph_run_iter: Iter<'a, GlyphRun>, range: Range<CharIndex>, } -impl<'a> Iterator<TextRunSlice<'a>> for CharacterSliceIterator<'a> { +impl<'a> Iterator for CharacterSliceIterator<'a> { + type Item = TextRunSlice<'a>; + // inline(always) due to the inefficient rt failures messing up inline heuristics, I think. #[inline(always)] fn next(&mut self) -> Option<TextRunSlice<'a>> { @@ -139,7 +144,9 @@ pub struct LineIterator<'a> { slices: NaturalWordSliceIterator<'a>, } -impl<'a> Iterator<Range<CharIndex>> for LineIterator<'a> { +impl<'a> Iterator for LineIterator<'a> { + type Item = Range<CharIndex>; + fn next(&mut self) -> Option<Range<CharIndex>> { // Loop until we hit whitespace and are in a clump. loop { @@ -310,9 +317,9 @@ impl<'a> TextRun { } pub fn min_width_for_range(&self, range: &Range<CharIndex>) -> Au { - debug!("iterating outer range {}", range); + debug!("iterating outer range {:?}", range); self.natural_word_slices_in_range(range).fold(Au(0), |max_piece_width, slice| { - debug!("iterated on {}[{}]", slice.offset, slice.range); + debug!("iterated on {:?}[{:?}]", slice.offset, slice.range); Au::max(max_piece_width, self.advance_for_range(&slice.range)) }) } diff --git a/components/gfx/text/util.rs b/components/gfx/text/util.rs index 24c916a1ba1..4b8f5041143 100644 --- a/components/gfx/text/util.rs +++ b/components/gfx/text/util.rs @@ -4,7 +4,7 @@ use text::glyph::CharIndex; -#[deriving(PartialEq, Eq, Copy)] +#[derive(PartialEq, Eq, Copy)] pub enum CompressionMode { CompressNone, CompressWhitespace, diff --git a/components/layout/Cargo.toml b/components/layout/Cargo.toml index d24261495e1..fb3796577e6 100644 --- a/components/layout/Cargo.toml +++ b/components/layout/Cargo.toml @@ -7,6 +7,9 @@ authors = ["The Servo Project Developers"] name = "layout" path = "lib.rs" +[dependencies.canvas] +path = "../canvas" + [dependencies.gfx] path = "../gfx" @@ -37,9 +40,6 @@ git = "https://github.com/servo/rust-cssparser" [dependencies.geom] git = "https://github.com/servo/rust-geom" -[dependencies.url] -git = "https://github.com/servo/rust-url" - [dependencies.string_cache] git = "https://github.com/servo/string-cache" @@ -48,3 +48,4 @@ git = "https://github.com/servo/string-cache" [dependencies] encoding = "0.2" +url = "*"
\ No newline at end of file diff --git a/components/layout/block.rs b/components/layout/block.rs index f91f079f6bf..d1ffc16a111 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -32,7 +32,7 @@ use context::LayoutContext; use css::node_style::StyledNode; use display_list_builder::{BlockFlowDisplayListBuilding, FragmentDisplayListBuilding}; use floats::{ClearType, FloatKind, Floats, PlacementInfo}; -use flow::{mod, AbsolutePositionInfo, BaseFlow, ForceNonfloatedFlag, FlowClass, Flow}; +use flow::{self, AbsolutePositionInfo, BaseFlow, ForceNonfloatedFlag, FlowClass, Flow}; use flow::{ImmutableFlowUtils, MutableFlowUtils, PreorderFlowTraversal}; use flow::{PostorderFlowTraversal, mut_base}; use flow::{HAS_LEFT_FLOATED_DESCENDANTS, HAS_RIGHT_FLOATED_DESCENDANTS}; @@ -64,7 +64,7 @@ use style::computed_values::{overflow, position}; use std::sync::Arc; /// Information specific to floated blocks. -#[deriving(Clone, Encodable)] +#[derive(Clone, Encodable)] pub struct FloatedBlockInfo { /// The amount of inline size that is available for the float. pub containing_inline_size: Au, @@ -92,7 +92,7 @@ impl FloatedBlockInfo { } /// The solutions for the block-size-and-margins constraint equation. -#[deriving(Copy)] +#[derive(Copy)] struct BSizeConstraintSolution { block_start: Au, _block_end: Au, @@ -366,7 +366,8 @@ impl CandidateBSizeIterator { } } -impl Iterator<MaybeAuto> for CandidateBSizeIterator { +impl Iterator for CandidateBSizeIterator { + type Item = MaybeAuto; fn next(&mut self) -> Option<MaybeAuto> { self.status = match self.status { CandidateBSizeIteratorStatus::Initial => CandidateBSizeIteratorStatus::Trying, @@ -487,13 +488,13 @@ pub enum BlockType { FloatNonReplaced, } -#[deriving(Clone, PartialEq)] +#[derive(Clone, PartialEq)] pub enum MarginsMayCollapseFlag { MarginsMayCollapse, MarginsMayNotCollapse, } -#[deriving(PartialEq)] +#[derive(PartialEq)] enum FormattingContextType { None, Block, @@ -525,7 +526,7 @@ fn propagate_layer_flag_from_child(layers_needed_for_descendants: &mut bool, kid } // A block formatting context. -#[deriving(Encodable)] +#[derive(RustcEncodable)] pub struct BlockFlow { /// Data common to all flows. pub base: BaseFlow, @@ -561,8 +562,8 @@ bitflags! { } } -impl<'a,E,S> Encodable<S,E> for BlockFlowFlags where S: Encoder<E> { - fn encode(&self, e: &mut S) -> Result<(),E> { +impl Encodable for BlockFlowFlags { + fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> { self.bits().encode(e) } } @@ -1905,7 +1906,7 @@ impl Flow for BlockFlow { impl fmt::Show for BlockFlow { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, - "{} - {:x}: frag={} ({})", + "{:?} - {:x}: frag={:?} ({:?})", self.class(), self.base.debug_id(), self.fragment, @@ -1914,7 +1915,7 @@ impl fmt::Show for BlockFlow { } /// The inputs for the inline-sizes-and-margins constraint equation. -#[deriving(Show, Copy)] +#[derive(Show, Copy)] pub struct ISizeConstraintInput { pub computed_inline_size: MaybeAuto, pub inline_start_margin: MaybeAuto, @@ -1947,7 +1948,7 @@ impl ISizeConstraintInput { } /// The solutions for the inline-size-and-margins constraint equation. -#[deriving(Copy, Show)] +#[derive(Copy, Show)] pub struct ISizeConstraintSolution { pub inline_start: Au, pub inline_end: Au, @@ -2560,7 +2561,7 @@ impl ISizeAndMarginsComputer for FloatNonReplaced { let available_inline_size_float = available_inline_size - margin_inline_start - margin_inline_end; let shrink_to_fit = block.get_shrink_to_fit_inline_size(available_inline_size_float); let inline_size = computed_inline_size.specified_or_default(shrink_to_fit); - debug!("assign_inline_sizes_float -- inline_size: {}", inline_size); + debug!("assign_inline_sizes_float -- inline_size: {:?}", inline_size); ISizeConstraintSolution::new(inline_size, margin_inline_start, margin_inline_end) } } @@ -2580,7 +2581,7 @@ impl ISizeAndMarginsComputer for FloatReplaced { MaybeAuto::Specified(w) => w, MaybeAuto::Auto => panic!("FloatReplaced: inline_size should have been computed by now") }; - debug!("assign_inline_sizes_float -- inline_size: {}", inline_size); + debug!("assign_inline_sizes_float -- inline_size: {:?}", inline_size); ISizeConstraintSolution::new(inline_size, margin_inline_start, margin_inline_end) } diff --git a/components/layout/construct.rs b/components/layout/construct.rs index eb90fbf734e..9e14e2244ab 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -31,7 +31,7 @@ use fragment::TableColumnFragmentInfo; use fragment::UnscannedTextFragmentInfo; use incremental::{RECONSTRUCT_FLOW, RestyleDamage}; use inline::InlineFlow; -use list_item::{mod, ListItemFlow}; +use list_item::{self, ListItemFlow}; use parallel; use table_wrapper::TableWrapperFlow; use table::TableFlow; @@ -50,17 +50,18 @@ use script::dom::htmlelement::HTMLElementTypeId; use script::dom::htmlobjectelement::is_image_data; use script::dom::node::NodeTypeId; use servo_util::opts; +use std::borrow::ToOwned; use std::collections::DList; use std::mem; -use std::sync::atomic::Relaxed; +use std::sync::atomic::Ordering; use style::computed_values::{caption_side, display, empty_cells, float, list_style_position}; use style::computed_values::{position}; -use style::{mod, ComputedValues}; +use style::{self, ComputedValues}; use std::sync::Arc; use url::Url; /// The results of flow construction for a DOM node. -#[deriving(Clone)] +#[derive(Clone)] pub enum ConstructionResult { /// This node contributes nothing at all (`display: none`). Alternately, this is what newly /// created nodes have their `ConstructionResult` set to. @@ -89,7 +90,7 @@ impl ConstructionResult { match self { &ConstructionResult::None => 0u, &ConstructionResult::ConstructionItem(_) => 0u, - &ConstructionResult::Flow(ref flow_ref, _) => flow::base(flow_ref.deref()).debug_id(), + &ConstructionResult::Flow(ref flow_ref, _) => flow::base(&**flow_ref).debug_id(), } } } @@ -97,7 +98,7 @@ impl ConstructionResult { /// Represents the output of flow construction for a DOM node that has not yet resulted in a /// complete flow. Construction items bubble up the tree until they find a `Flow` to be attached /// to. -#[deriving(Clone)] +#[derive(Clone)] pub enum ConstructionItem { /// Inline fragments and associated {ib} splits that have not yet found flows. InlineFragments(InlineFragmentsConstructionResult), @@ -108,7 +109,7 @@ pub enum ConstructionItem { } /// Represents inline fragments and {ib} splits that are bubbling up from an inline. -#[deriving(Clone)] +#[derive(Clone)] pub struct InlineFragmentsConstructionResult { /// Any {ib} splits that we're bubbling up. pub splits: DList<InlineBlockSplit>, @@ -146,7 +147,7 @@ pub struct InlineFragmentsConstructionResult { /// C /// ]) /// ``` -#[deriving(Clone)] +#[derive(Clone)] pub struct InlineBlockSplit { /// The inline fragments that precede the flow. pub predecessors: DList<Fragment>, @@ -221,8 +222,8 @@ pub struct FlowConstructor<'a> { impl<'a> FlowConstructor<'a> { /// Creates a new flow constructor. - pub fn new<'a>(layout_context: &'a LayoutContext<'a>) - -> FlowConstructor<'a> { + pub fn new<'b>(layout_context: &'b LayoutContext<'b>) + -> FlowConstructor<'b> { FlowConstructor { layout_context: layout_context, } @@ -375,7 +376,7 @@ impl<'a> FlowConstructor<'a> { ConstructionResult::Flow(kid_flow, kid_abs_descendants) => { // If kid_flow is TableCaptionFlow, kid_flow should be added under // TableWrapperFlow. - if flow.is_table() && kid_flow.deref().is_table_caption() { + if flow.is_table() && kid_flow.is_table_caption() { kid.set_flow_construction_result(ConstructionResult::Flow(kid_flow, Descendants::new())) } else if flow.need_anonymous_flow(&*kid_flow) { @@ -455,7 +456,7 @@ impl<'a> FlowConstructor<'a> { // Add whitespace results. They will be stripped out later on when // between block elements, and retained when between inline elements. let fragment_info = - SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::from_text(" ".into_string())); + SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::from_text(" ".to_owned())); let fragment = Fragment::from_opaque_node_and_style(whitespace_node, whitespace_style, whitespace_damage, @@ -652,7 +653,7 @@ impl<'a> FlowConstructor<'a> { whitespace_damage)) => { // Instantiate the whitespace fragment. let fragment_info = SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::from_text( - " ".into_string())); + " ".to_owned())); let fragment = Fragment::from_opaque_node_and_style(whitespace_node, whitespace_style, whitespace_damage, @@ -814,7 +815,7 @@ impl<'a> FlowConstructor<'a> { for kid in node.children() { match kid.swap_out_construction_result() { ConstructionResult::Flow(mut kid_flow, _) => { - if kid_flow.deref().is_table_caption() && + if kid_flow.is_table_caption() && kid_flow.as_block() .fragment .style() @@ -986,7 +987,7 @@ impl<'a> FlowConstructor<'a> { .list_style_type) { None => None, Some(text) => { - let text = text.into_string(); + let text = text.to_owned(); let mut unscanned_marker_fragments = DList::new(); unscanned_marker_fragments.push_back(Fragment::new_from_specific_info( node, @@ -1149,7 +1150,7 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> { } }; - debug!("building flow for node: {} {} {}", display, float, node.type_id()); + debug!("building flow for node: {:?} {:?} {:?}", display, float, node.type_id()); // Switch on display and floatedness. match (display, float, positioning) { @@ -1376,15 +1377,15 @@ impl FlowConstructionUtils for FlowRef { /// /// This must not be public because only the layout constructor can do this. fn add_new_child(&mut self, mut new_child: FlowRef) { - let base = flow::mut_base(self.deref_mut()); + let base = flow::mut_base(&mut **self); { - let kid_base = flow::mut_base(new_child.deref_mut()); + let kid_base = flow::mut_base(&mut *new_child); kid_base.parallel.parent = parallel::mut_owned_flow_to_unsafe_flow(self); } base.children.push_back(new_child); - let _ = base.parallel.children_count.fetch_add(1, Relaxed); + let _ = base.parallel.children_count.fetch_add(1, Ordering::Relaxed); } /// Finishes a flow. Once a flow is finished, no more child flows or fragments may be added to diff --git a/components/layout/context.rs b/components/layout/context.rs index b329a20221d..e3df7a1a8b5 100644 --- a/components/layout/context.rs +++ b/components/layout/context.rs @@ -28,7 +28,7 @@ struct LocalLayoutContext { style_sharing_candidate_cache: StyleSharingCandidateCache, } -thread_local!(static LOCAL_CONTEXT_KEY: Cell<*mut LocalLayoutContext> = Cell::new(ptr::null_mut())) +thread_local!(static LOCAL_CONTEXT_KEY: Cell<*mut LocalLayoutContext> = Cell::new(ptr::null_mut())); fn create_or_get_local_context(shared_layout_context: &SharedLayoutContext) -> *mut LocalLayoutContext { LOCAL_CONTEXT_KEY.with(|ref r| { @@ -80,6 +80,9 @@ pub struct SharedLayoutContext { pub generation: uint, } +pub struct SharedLayoutContextWrapper(pub *const SharedLayoutContext); +unsafe impl Send for SharedLayoutContextWrapper {} + pub struct LayoutContext<'a> { pub shared: &'a SharedLayoutContext, cached_local_layout_context: *mut LocalLayoutContext, @@ -97,7 +100,7 @@ impl<'a> LayoutContext<'a> { } #[inline(always)] - pub fn font_context<'a>(&'a self) -> &'a mut FontContext { + pub fn font_context<'b>(&'b self) -> &'b mut FontContext { unsafe { let cached_context = &mut *self.cached_local_layout_context; &mut cached_context.font_context @@ -105,7 +108,7 @@ impl<'a> LayoutContext<'a> { } #[inline(always)] - pub fn applicable_declarations_cache<'a>(&'a self) -> &'a mut ApplicableDeclarationsCache { + pub fn applicable_declarations_cache<'b>(&'b self) -> &'b mut ApplicableDeclarationsCache { unsafe { let cached_context = &mut *self.cached_local_layout_context; &mut cached_context.applicable_declarations_cache @@ -113,7 +116,7 @@ impl<'a> LayoutContext<'a> { } #[inline(always)] - pub fn style_sharing_candidate_cache<'a>(&'a self) -> &'a mut StyleSharingCandidateCache { + pub fn style_sharing_candidate_cache<'b>(&'b self) -> &'b mut StyleSharingCandidateCache { unsafe { let cached_context = &mut *self.cached_local_layout_context; &mut cached_context.style_sharing_candidate_cache diff --git a/components/layout/css/matching.rs b/components/layout/css/matching.rs index 8606c575146..0f1931c3efb 100644 --- a/components/layout/css/matching.rs +++ b/components/layout/css/matching.rs @@ -5,20 +5,21 @@ //! High-level interface to CSS selector matching. use css::node_style::StyledNode; -use incremental::{mod, RestyleDamage}; +use incremental::{self, RestyleDamage}; use util::{LayoutDataAccess, LayoutDataWrapper}; use wrapper::{LayoutElement, LayoutNode, TLayoutNode}; use script::dom::node::NodeTypeId; use servo_util::bloom::BloomFilter; -use servo_util::cache::{Cache, LRUCache, SimpleHashCache}; +use servo_util::cache::{LRUCache, SimpleHashCache}; use servo_util::smallvec::{SmallVec, SmallVec16}; use servo_util::arc_ptr_eq; +use std::borrow::ToOwned; use std::mem; -use std::hash::{Hash, sip}; -use std::slice::Items; +use std::hash::{Hash, Hasher, Writer}; +use std::slice::Iter; use string_cache::{Atom, Namespace}; -use style::{mod, PseudoElement, ComputedValues, DeclarationBlock, Stylist, TElement, TNode}; +use style::{self, PseudoElement, ComputedValues, DeclarationBlock, Stylist, TElement, TNode}; use style::{CommonStyleAffectingAttributeMode, CommonStyleAffectingAttributes, cascade}; use std::sync::Arc; @@ -49,7 +50,7 @@ impl ApplicableDeclarations { } } -#[deriving(Clone)] +#[derive(Clone)] pub struct ApplicableDeclarationsCacheEntry { pub declarations: Vec<DeclarationBlock>, } @@ -65,12 +66,13 @@ impl ApplicableDeclarationsCacheEntry { impl PartialEq for ApplicableDeclarationsCacheEntry { fn eq(&self, other: &ApplicableDeclarationsCacheEntry) -> bool { let this_as_query = ApplicableDeclarationsCacheQuery::new(self.declarations.as_slice()); - this_as_query.equiv(other) + this_as_query.eq(other) } } +impl Eq for ApplicableDeclarationsCacheEntry {} -impl Hash for ApplicableDeclarationsCacheEntry { - fn hash(&self, state: &mut sip::SipState) { +impl<H: Hasher+Writer> Hash<H> for ApplicableDeclarationsCacheEntry { + fn hash(&self, state: &mut H) { let tmp = ApplicableDeclarationsCacheQuery::new(self.declarations.as_slice()); tmp.hash(state); } @@ -88,8 +90,8 @@ impl<'a> ApplicableDeclarationsCacheQuery<'a> { } } -impl<'a> Equiv<ApplicableDeclarationsCacheEntry> for ApplicableDeclarationsCacheQuery<'a> { - fn equiv(&self, other: &ApplicableDeclarationsCacheEntry) -> bool { +impl<'a> PartialEq for ApplicableDeclarationsCacheQuery<'a> { + fn eq(&self, other: &ApplicableDeclarationsCacheQuery<'a>) -> bool { if self.declarations.len() != other.declarations.len() { return false } @@ -101,10 +103,17 @@ impl<'a> Equiv<ApplicableDeclarationsCacheEntry> for ApplicableDeclarationsCache return true } } +impl<'a> Eq for ApplicableDeclarationsCacheQuery<'a> {} +impl<'a> PartialEq<ApplicableDeclarationsCacheEntry> for ApplicableDeclarationsCacheQuery<'a> { + fn eq(&self, other: &ApplicableDeclarationsCacheEntry) -> bool { + let other_as_query = ApplicableDeclarationsCacheQuery::new(other.declarations.as_slice()); + self.eq(&other_as_query) + } +} -impl<'a> Hash for ApplicableDeclarationsCacheQuery<'a> { - fn hash(&self, state: &mut sip::SipState) { +impl<'a, H: Hasher+Writer> Hash<H> for ApplicableDeclarationsCacheQuery<'a> { + fn hash(&self, state: &mut H) { for declaration in self.declarations.iter() { let ptr: uint = unsafe { mem::transmute_copy(declaration) @@ -128,7 +137,7 @@ impl ApplicableDeclarationsCache { } fn find(&self, declarations: &[DeclarationBlock]) -> Option<Arc<ComputedValues>> { - match self.cache.find_equiv(&ApplicableDeclarationsCacheQuery::new(declarations)) { + match self.cache.find(&ApplicableDeclarationsCacheQuery::new(declarations)) { None => None, Some(ref values) => Some((*values).clone()), } @@ -167,7 +176,7 @@ fn create_common_style_affecting_attributes_from_element(element: &LayoutElement flags } -#[deriving(Clone)] +#[derive(Clone)] pub struct StyleSharingCandidate { pub style: Arc<ComputedValues>, pub parent_style: Arc<ComputedValues>, @@ -237,7 +246,7 @@ impl StyleSharingCandidate { parent_style: parent_style, local_name: element.get_local_name().clone(), class: element.get_attr(&ns!(""), &atom!("class")) - .map(|string| string.into_string()), + .map(|string| string.to_owned()), link: element.get_link().is_some(), namespace: (*element.get_namespace()).clone(), common_style_affecting_attributes: @@ -320,7 +329,7 @@ impl StyleSharingCandidateCache { } } - pub fn iter<'a>(&'a self) -> Items<'a,(StyleSharingCandidate,())> { + pub fn iter<'a>(&'a self) -> Iter<'a,(StyleSharingCandidate,())> { self.cache.iter() } @@ -607,8 +616,8 @@ impl<'ln> MatchMethods for LayoutNode<'ln> { let mut layout_data_ref = self.mutate_layout_data(); match &mut *layout_data_ref { - &None => panic!("no layout data"), - &Some(ref mut layout_data) => { + &mut None => panic!("no layout data"), + &mut Some(ref mut layout_data) => { match self.type_id() { Some(NodeTypeId::Text) => { // Text nodes get a copy of the parent style. This ensures diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 2e4ae665ea9..1c81e65459b 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -13,7 +13,7 @@ use block::BlockFlow; use canvas::canvas_paint_task::CanvasMsg::SendPixelContents; use context::LayoutContext; -use flow::{mod, Flow, IS_ABSOLUTELY_POSITIONED, NEEDS_LAYER}; +use flow::{self, Flow, IS_ABSOLUTELY_POSITIONED, NEEDS_LAYER}; use fragment::{CoordinateSystem, Fragment, IframeFragmentInfo, ImageFragmentInfo}; use fragment::{ScannedTextFragmentInfo, SpecificFragmentInfo}; use inline::InlineFlow; @@ -40,20 +40,22 @@ use servo_msg::constellation_msg::Msg as ConstellationMsg; use servo_msg::constellation_msg::ConstellationChan; use servo_net::image::holder::ImageHolder; use servo_util::cursor::Cursor; -use servo_util::geometry::{mod, Au, to_px}; +use servo_util::geometry::{self, Au, to_px, to_frac_px}; use servo_util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize}; use servo_util::opts; use std::default::Default; use std::iter::repeat; -use std::num::FloatMath; -use style::computed::{AngleOrCorner, LengthOrPercentage, HorizontalDirection, VerticalDirection}; -use style::computed::{Image, LinearGradient}; +use std::num::Float; +use style::values::specified::{AngleOrCorner, HorizontalDirection, VerticalDirection}; +use style::computed::{Image, LinearGradient, LengthOrPercentage}; use style::computed_values::filter::Filter; use style::computed_values::{background_attachment, background_repeat, border_style, overflow}; use style::computed_values::{position, visibility}; use style::style_structs::Border; use style::{ComputedValues, RGBA}; +use std::num::ToPrimitive; use std::sync::Arc; +use std::sync::mpsc::channel; use url::Url; /// The results of display list building for a single flow. @@ -216,21 +218,51 @@ pub trait FragmentDisplayListBuilding { clip: &ClippingRegion); } +fn handle_overlapping_radii(size: &Size2D<Au>, radii: &BorderRadii<Au>) -> BorderRadii<Au> { + // No two corners' border radii may add up to more than the length of the edge + // between them. To prevent that, all radii are scaled down uniformly. + fn scale_factor(radius_a: Au, radius_b: Au, edge_length: Au) -> f64 { + let required = radius_a + radius_b; + + if required <= edge_length { + 1.0 + } else { + to_frac_px(edge_length) / to_frac_px(required) + } + } + + let top_factor = scale_factor(radii.top_left, radii.top_right, size.width); + let bottom_factor = scale_factor(radii.bottom_left, radii.bottom_right, size.width); + let left_factor = scale_factor(radii.top_left, radii.bottom_left, size.height); + let right_factor = scale_factor(radii.top_right, radii.bottom_right, size.height); + let min_factor = top_factor.min(bottom_factor).min(left_factor).min(right_factor); + if min_factor < 1.0 { + BorderRadii { + top_left: radii.top_left .scale_by(min_factor), + top_right: radii.top_right .scale_by(min_factor), + bottom_left: radii.bottom_left .scale_by(min_factor), + bottom_right: radii.bottom_right.scale_by(min_factor), + } + } else { + *radii + } +} + fn build_border_radius(abs_bounds: &Rect<Au>, border_style: &Border) -> BorderRadii<Au> { // TODO(cgaebel): Support border radii even in the case of multiple border widths. // This is an extension of supporting elliptical radii. For now, all percentage // radii will be relative to the width. - BorderRadii { - top_left: model::specified(border_style.border_top_left_radius.radius, + handle_overlapping_radii(&abs_bounds.size, &BorderRadii { + top_left: model::specified(border_style.border_top_left_radius, abs_bounds.size.width), - top_right: model::specified(border_style.border_top_right_radius.radius, + top_right: model::specified(border_style.border_top_right_radius, abs_bounds.size.width), - bottom_right: model::specified(border_style.border_bottom_right_radius.radius, + bottom_right: model::specified(border_style.border_bottom_right_radius, abs_bounds.size.width), - bottom_left: model::specified(border_style.border_bottom_left_radius.radius, + bottom_left: model::specified(border_style.border_bottom_left_radius, abs_bounds.size.width), - } + }) } impl FragmentDisplayListBuilding for Fragment { @@ -689,7 +721,7 @@ impl FragmentDisplayListBuilding for Fragment { relative_containing_block_size, CoordinateSystem::Self); - debug!("Fragment::build_display_list at rel={}, abs={}, dirty={}, flow origin={}: {}", + debug!("Fragment::build_display_list at rel={:?}, abs={:?}, dirty={:?}, flow origin={:?}: {:?}", self.border_box, stacking_relative_border_box, layout_context.shared.dirty, @@ -879,8 +911,8 @@ impl FragmentDisplayListBuilding for Fragment { let (sender, receiver) = channel::<Vec<u8>>(); let canvas_data = match canvas_fragment_info.renderer { Some(ref renderer) => { - renderer.deref().lock().send(SendPixelContents(sender)); - receiver.recv() + renderer.lock().unwrap().send(SendPixelContents(sender)); + receiver.recv().unwrap() }, None => repeat(0xFFu8).take(width * height * 4).collect(), }; @@ -916,7 +948,7 @@ impl FragmentDisplayListBuilding for Fragment { Size2D(geometry::to_frac_px(content_size.width) as f32, geometry::to_frac_px(content_size.height) as f32)); - debug!("finalizing position and size of iframe for {},{}", + debug!("finalizing position and size of iframe for {:?},{:?}", iframe_fragment.pipeline_id, iframe_fragment.subpage_id); let ConstellationChan(ref chan) = layout_context.shared.constellation_chan; @@ -1226,12 +1258,12 @@ impl InlineFlowDisplayListBuilding for InlineFlow { &self.base.clip); match fragment.specific { SpecificFragmentInfo::InlineBlock(ref mut block_flow) => { - let block_flow = block_flow.flow_ref.deref_mut(); + let block_flow = &mut *block_flow.flow_ref; flow::mut_base(block_flow).display_list_building_result .add_to(&mut *display_list) } SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut block_flow) => { - let block_flow = block_flow.flow_ref.deref_mut(); + let block_flow = &mut *block_flow.flow_ref; flow::mut_base(block_flow).display_list_building_result .add_to(&mut *display_list) } @@ -1276,7 +1308,7 @@ impl ListItemFlowDisplayListBuilding for ListItemFlow { } // A helper data structure for gradients. -#[deriving(Copy)] +#[derive(Copy)] struct StopRun { start_offset: f32, end_offset: f32, @@ -1300,7 +1332,7 @@ fn position_to_offset(position: LengthOrPercentage, Au(total_length): Au) -> f32 } /// "Steps" as defined by CSS 2.1 § E.2. -#[deriving(Clone, PartialEq, Show, Copy)] +#[derive(Clone, PartialEq, Show, Copy)] pub enum StackingLevel { /// The border and backgrounds for the root of this stacking context: steps 1 and 2. BackgroundAndBorders, diff --git a/components/layout/floats.rs b/components/layout/floats.rs index 5d82014f779..10a057f172e 100644 --- a/components/layout/floats.rs +++ b/components/layout/floats.rs @@ -12,7 +12,7 @@ use std::fmt; use style::computed_values::float; /// The kind of float: left or right. -#[deriving(Clone, Encodable, Show, Copy)] +#[derive(Clone, RustcEncodable, Show, Copy)] pub enum FloatKind { Left, Right @@ -29,7 +29,7 @@ impl FloatKind { } /// The kind of clearance: left, right, or both. -#[deriving(Copy)] +#[derive(Copy)] pub enum ClearType { Left, Right, @@ -37,7 +37,7 @@ pub enum ClearType { } /// Information about a single float. -#[deriving(Clone, Copy)] +#[derive(Clone, Copy)] struct Float { /// The boundaries of this float. bounds: LogicalRect<Au>, @@ -47,12 +47,12 @@ struct Float { impl fmt::Show for Float { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "bounds={} kind={}", self.bounds, self.kind) + write!(f, "bounds={:?} kind={:?}", self.bounds, self.kind) } } /// Information about the floats next to a flow. -#[deriving(Clone)] +#[derive(Clone)] struct FloatList { /// Information about each of the floats here. floats: PersistentList<Float>, @@ -77,7 +77,7 @@ impl FloatList { impl fmt::Show for FloatList { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "max_block_start={} floats={}", self.max_block_start, self.floats.len()) + write!(f, "max_block_start={:?} floats={}", self.max_block_start, self.floats.len()) } } @@ -96,7 +96,7 @@ pub struct PlacementInfo { impl fmt::Show for PlacementInfo { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, - "size={} ceiling={} max_inline_size={} kind={}", + "size={:?} ceiling={:?} max_inline_size={:?} kind={:?}", self.size, self.ceiling, self.max_inline_size, @@ -110,7 +110,7 @@ fn range_intersect(block_start_1: Au, block_end_1: Au, block_start_2: Au, block_ /// Encapsulates information about floats. This is optimized to avoid allocation if there are /// no floats, and to avoid copying when translating the list of floats downward. -#[deriving(Clone)] +#[derive(Clone)] pub struct Floats { /// The list of floats. list: FloatList, @@ -125,7 +125,7 @@ impl fmt::Show for Floats { if !self.list.is_present() { write!(f, "[empty]") } else { - write!(f, "offset={} floats={}", self.offset, self.list) + write!(f, "offset={:?} floats={:?}", self.offset, self.list) } } } @@ -166,7 +166,7 @@ impl Floats { let list = &self.list; let block_start = block_start - self.offset.block; - debug!("available_rect: trying to find space at {}", block_start); + debug!("available_rect: trying to find space at {:?}", block_start); // Relevant dimensions for the inline-end-most inline-start float let mut max_inline_start = Au(0) - self.offset.inline; @@ -183,7 +183,7 @@ impl Floats { let float_pos = float.bounds.start; let float_size = float.bounds.size; - debug!("float_pos: {}, float_size: {}", float_pos, float_size); + debug!("float_pos: {:?}, float_size: {:?}", float_pos, float_size); match float.kind { FloatKind::Left if float_pos.i + float_size.inline > max_inline_start && float_pos.b + float_size.block > block_start && @@ -194,7 +194,7 @@ impl Floats { l_block_end = Some(float_pos.b + float_size.block); debug!("available_rect: collision with inline_start float: new \ - max_inline_start is {}", + max_inline_start is {:?}", max_inline_start); } FloatKind::Right if float_pos.i < min_inline_end && @@ -205,7 +205,7 @@ impl Floats { r_block_start = Some(float_pos.b); r_block_end = Some(float_pos.b + float_size.block); debug!("available_rect: collision with inline_end float: new min_inline_end \ - is {}", + is {:?}", min_inline_end); } FloatKind::Left | FloatKind::Right => {} @@ -262,7 +262,7 @@ impl Floats { } } - debug!("add_float: added float with info {}", new_info); + debug!("add_float: added float with info {:?}", new_info); let new_float = Float { bounds: LogicalRect::from_point_size( @@ -303,7 +303,7 @@ impl Floats { /// Given placement information, finds the closest place a fragment can be positioned without /// colliding with any floats. pub fn place_between_floats(&self, info: &PlacementInfo) -> LogicalRect<Au> { - debug!("place_between_floats: Placing object with {}", info.size); + debug!("place_between_floats: Placing object with {:?}", info.size); // If no floats, use this fast path. if !self.list.is_present() { @@ -333,7 +333,7 @@ impl Floats { let maybe_location = self.available_rect(float_b, info.size.block, info.max_inline_size); - debug!("place_float: Got available rect: {} for y-pos: {}", maybe_location, float_b); + debug!("place_float: Got available rect: {:?} for y-pos: {:?}", maybe_location, float_b); match maybe_location { // If there are no floats blocking us, return the current location // TODO(eatkinson): integrate with overflow diff --git a/components/layout/flow.rs b/components/layout/flow.rs index bbfb698a2f3..c87088bf829 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -55,9 +55,10 @@ use servo_util::logical_geometry::{LogicalRect, LogicalSize, WritingMode}; use std::mem; use std::fmt; use std::iter::Zip; +use std::num::FromPrimitive; use std::raw; -use std::sync::atomic::{AtomicUint, SeqCst}; -use std::slice::MutItems; +use std::sync::atomic::{AtomicUint, Ordering}; +use std::slice::IterMut; use style::computed_values::{clear, empty_cells, float, position, text_align}; use style::ComputedValues; use std::sync::Arc; @@ -66,7 +67,7 @@ use std::sync::Arc; /// /// Note that virtual methods have a cost; we should not overuse them in Servo. Consider adding /// methods to `ImmutableFlowUtils` or `MutableFlowUtils` before adding more methods here. -pub trait Flow: fmt::Show + ToString + Sync { +pub trait Flow: fmt::Show + Sync { // RTTI // // TODO(pcwalton): Use Rust's RTTI, once that works. @@ -82,7 +83,7 @@ pub trait Flow: fmt::Show + ToString + Sync { /// If this is a block flow, returns the underlying object. Fails otherwise. fn as_block<'a>(&'a mut self) -> &'a mut BlockFlow { - debug!("called as_block() on a flow of type {}", self.class()); + debug!("called as_block() on a flow of type {:?}", self.class()); panic!("called as_block() on a non-block flow") } @@ -204,10 +205,10 @@ pub trait Flow: fmt::Show + ToString + Sync { fn assign_block_size_for_inorder_child_if_necessary<'a>(&mut self, layout_context: &'a LayoutContext<'a>) -> bool { - let impacted = base(&*self).flags.impacted_by_floats(); + let impacted = base(self).flags.impacted_by_floats(); if impacted { self.assign_block_size(layout_context); - mut_base(&mut *self).restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW); + mut_base(self).restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW); } impacted } @@ -295,7 +296,8 @@ pub trait Flow: fmt::Show + ToString + Sync { /// Returns a layer ID for the given fragment. fn layer_id(&self, fragment_id: uint) -> LayerId { unsafe { - let pointer: uint = mem::transmute(self); + let obj = mem::transmute::<&&Self, &raw::TraitObject>(&self); + let pointer: uint = mem::transmute(obj.data); LayerId(pointer, fragment_id) } } @@ -308,9 +310,9 @@ pub trait Flow: fmt::Show + ToString + Sync { // Base access #[inline(always)] -pub fn base<'a>(this: &'a Flow) -> &'a BaseFlow { +pub fn base<'a, T: ?Sized + Flow>(this: &'a T) -> &'a BaseFlow { unsafe { - let obj = mem::transmute::<&'a Flow, raw::TraitObject>(this); + let obj = mem::transmute::<&&'a T, &'a raw::TraitObject>(&this); mem::transmute::<*mut (), &'a BaseFlow>(obj.data) } } @@ -321,9 +323,9 @@ pub fn imm_child_iter<'a>(flow: &'a Flow) -> FlowListIterator<'a> { } #[inline(always)] -pub fn mut_base<'a>(this: &'a mut Flow) -> &'a mut BaseFlow { +pub fn mut_base<'a, T: ?Sized + Flow>(this: &'a mut T) -> &'a mut BaseFlow { unsafe { - let obj = mem::transmute::<&'a mut Flow, raw::TraitObject>(this); + let obj = mem::transmute::<&&'a mut T, &'a raw::TraitObject>(&this); mem::transmute::<*mut (), &'a mut BaseFlow>(obj.data) } } @@ -423,7 +425,7 @@ pub trait MutableOwnedFlowUtils { fn set_absolute_descendants(&mut self, abs_descendants: AbsDescendants); } -#[deriving(Encodable, PartialEq, Show)] +#[derive(RustcEncodable, PartialEq, Show)] pub enum FlowClass { Block, Inline, @@ -465,7 +467,6 @@ pub trait PostorderFlowTraversal { bitflags! { #[doc = "Flags used in flows."] - #[deriving(Copy)] flags FlowFlags: u16 { // floated descendants flags #[doc = "Whether this flow has descendants that float left in the same block formatting"] @@ -540,7 +541,7 @@ impl FlowFlags { #[inline] pub fn set_text_align(&mut self, value: text_align::T) { *self = (*self & !TEXT_ALIGN) | - FlowFlags::from_bits(value as u16 << TEXT_ALIGN_SHIFT).unwrap(); + FlowFlags::from_bits((value as u16) << TEXT_ALIGN_SHIFT).unwrap(); } #[inline] @@ -592,7 +593,7 @@ impl FlowFlags { /// The Descendants of a flow. /// /// Also, details about their position wrt this flow. -#[deriving(Clone)] +#[derive(Clone)] pub struct Descendants { /// Links to every descendant. This must be private because it is unsafe to leak `FlowRef`s to /// layout. @@ -650,20 +651,21 @@ impl Descendants { pub type AbsDescendants = Descendants; pub struct DescendantIter<'a> { - iter: MutItems<'a, FlowRef>, + iter: IterMut<'a, FlowRef>, } -impl<'a> Iterator<&'a mut (Flow + 'a)> for DescendantIter<'a> { +impl<'a> Iterator for DescendantIter<'a> { + type Item = &'a mut (Flow + 'a); fn next(&mut self) -> Option<&'a mut (Flow + 'a)> { self.iter.next().map(|flow| &mut **flow) } } -pub type DescendantOffsetIter<'a> = Zip<DescendantIter<'a>, MutItems<'a, Au>>; +pub type DescendantOffsetIter<'a> = Zip<DescendantIter<'a>, IterMut<'a, Au>>; /// Information needed to compute absolute (i.e. viewport-relative) flow positions (not to be /// confused with absolutely-positioned flows). -#[deriving(Encodable, Copy)] +#[derive(RustcEncodable, Copy)] pub struct AbsolutePositionInfo { /// The size of the containing block for relatively-positioned descendants. pub relative_containing_block_size: LogicalSize<Au>, @@ -776,33 +778,36 @@ pub struct BaseFlow { pub flags: FlowFlags, } +unsafe impl Send for BaseFlow {} +unsafe impl Sync for BaseFlow {} + impl fmt::Show for BaseFlow { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, - "@ {}, CC {}, ADC {}", + "@ {:?}, CC {}, ADC {}", self.position, - self.parallel.children_count.load(SeqCst), + self.parallel.children_count.load(Ordering::SeqCst), self.abs_descendants.len()) } } -impl<E, S: Encoder<E>> Encodable<S, E> for BaseFlow { - fn encode(&self, e: &mut S) -> Result<(), E> { +impl Encodable for BaseFlow { + fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> { e.emit_struct("base", 0, |e| { - try!(e.emit_struct_field("id", 0, |e| self.debug_id().encode(e))) + try!(e.emit_struct_field("id", 0, |e| self.debug_id().encode(e))); try!(e.emit_struct_field("stacking_relative_position", 1, - |e| self.stacking_relative_position.encode(e))) + |e| self.stacking_relative_position.encode(e))); try!(e.emit_struct_field("intrinsic_inline_sizes", 2, - |e| self.intrinsic_inline_sizes.encode(e))) - try!(e.emit_struct_field("position", 3, |e| self.position.encode(e))) + |e| self.intrinsic_inline_sizes.encode(e))); + try!(e.emit_struct_field("position", 3, |e| self.position.encode(e))); e.emit_struct_field("children", 4, |e| { e.emit_seq(self.children.len(), |e| { for (i, c) in self.children.iter().enumerate() { try!(e.emit_seq_elt(i, |e| { try!(e.emit_struct("flow", 0, |e| { - try!(e.emit_struct_field("class", 0, |e| c.class().encode(e))) + try!(e.emit_struct_field("class", 0, |e| c.class().encode(e))); e.emit_struct_field("data", 1, |e| { match c.class() { FlowClass::Block => c.as_immutable_block().encode(e), @@ -815,9 +820,9 @@ impl<E, S: Encoder<E>> Encodable<S, E> for BaseFlow { _ => { Ok(()) } // TODO: Support captions } }) - })) + })); Ok(()) - })) + })); } Ok(()) }) @@ -830,7 +835,7 @@ impl<E, S: Encoder<E>> Encodable<S, E> for BaseFlow { #[unsafe_destructor] impl Drop for BaseFlow { fn drop(&mut self) { - if self.ref_count.load(SeqCst) != 0 { + if self.ref_count.load(Ordering::SeqCst) != 0 { panic!("Flow destroyed before its ref count hit zero—this is unsafe!") } } @@ -838,7 +843,7 @@ impl Drop for BaseFlow { /// Whether a base flow should be forced to be nonfloated. This can affect e.g. `TableFlow`, which /// is never floated because the table wrapper flow is the floated one. -#[deriving(Clone, PartialEq)] +#[derive(Clone, PartialEq)] pub enum ForceNonfloatedFlag { /// The flow should be floated if the node has a `float` property. FloatIfNecessary, @@ -951,7 +956,7 @@ impl BaseFlow { } if bounds.union(&paint_bounds.bounding_rect()) != bounds { - error!("DisplayList item {} outside of Flow overflow ({})", item, paint_bounds); + error!("DisplayList item {:?} outside of Flow overflow ({:?})", item, paint_bounds); } } } @@ -1125,7 +1130,8 @@ impl<'a> ImmutableFlowUtils for &'a (Flow + 'a) { indent.push_str("| ") } - println!("{}+ {}", indent, self.to_string()); + // TODO: ICE, already fixed in rustc. + //println!("{}+ {:?}", indent, self); for kid in imm_child_iter(self) { kid.dump_with_level(level + 1) diff --git a/components/layout/flow_list.rs b/components/layout/flow_list.rs index c3300e6ab79..4011cd4c400 100644 --- a/components/layout/flow_list.rs +++ b/components/layout/flow_list.rs @@ -15,36 +15,36 @@ pub struct FlowList { } pub struct FlowListIterator<'a> { - it: dlist::Items<'a, FlowRef>, + it: dlist::Iter<'a, FlowRef>, } pub struct MutFlowListIterator<'a> { - it: dlist::MutItems<'a, FlowRef>, + it: dlist::IterMut<'a, FlowRef>, } impl FlowList { /// Provide a reference to the front element, or None if the list is empty #[inline] pub fn front<'a>(&'a self) -> Option<&'a Flow> { - self.flows.front().map(|head| head.deref()) + self.flows.front().map(|head| &**head) } /// Provide a mutable reference to the front element, or None if the list is empty #[inline] pub unsafe fn front_mut<'a>(&'a mut self) -> Option<&'a mut Flow> { - self.flows.front_mut().map(|head| head.deref_mut()) + self.flows.front_mut().map(|head| &mut **head) } /// Provide a reference to the back element, or None if the list is empty #[inline] pub fn back<'a>(&'a self) -> Option<&'a Flow> { - self.flows.back().map(|tail| tail.deref()) + self.flows.back().map(|tail| &**tail) } /// Provide a mutable reference to the back element, or None if the list is empty #[inline] pub unsafe fn back_mut<'a>(&'a mut self) -> Option<&'a mut Flow> { - self.flows.back_mut().map(|tail| tail.deref_mut()) + self.flows.back_mut().map(|tail| &mut **tail) } /// Add an element first in the list @@ -105,10 +105,11 @@ impl FlowList { } } -impl<'a> Iterator<&'a (Flow + 'a)> for FlowListIterator<'a> { +impl<'a> Iterator for FlowListIterator<'a> { + type Item = &'a (Flow + 'a); #[inline] fn next(&mut self) -> Option<&'a (Flow + 'a)> { - self.it.next().map(|x| x.deref()) + self.it.next().map(|x| &**x) } #[inline] @@ -117,10 +118,11 @@ impl<'a> Iterator<&'a (Flow + 'a)> for FlowListIterator<'a> { } } -impl<'a> Iterator<&'a mut (Flow + 'a)> for MutFlowListIterator<'a> { +impl<'a> Iterator for MutFlowListIterator<'a> { + type Item = &'a mut (Flow + 'a); #[inline] fn next(&mut self) -> Option<&'a mut (Flow + 'a)> { - self.it.next().map(|x| x.deref_mut()) + self.it.next().map(|x| &mut **x) } #[inline] diff --git a/components/layout/flow_ref.rs b/components/layout/flow_ref.rs index 67f306d4508..605a7e4ede5 100644 --- a/components/layout/flow_ref.rs +++ b/components/layout/flow_ref.rs @@ -10,15 +10,19 @@ use flow::Flow; use flow; use std::mem; +use std::ops::{Deref, DerefMut}; use std::ptr; use std::raw; -use std::sync::atomic::SeqCst; +use std::sync::atomic::Ordering; #[unsafe_no_drop_flag] pub struct FlowRef { object: raw::TraitObject, } +unsafe impl Send for FlowRef {} +unsafe impl Sync for FlowRef {} + impl FlowRef { pub fn new(mut flow: Box<Flow>) -> FlowRef { unsafe { @@ -33,7 +37,8 @@ impl FlowRef { } } -impl<'a> Deref<Flow + 'a> for FlowRef { +impl<'a> Deref for FlowRef { + type Target = Flow + 'a; fn deref(&self) -> &(Flow + 'a) { unsafe { mem::transmute_copy::<raw::TraitObject, &(Flow + 'a)>(&self.object) @@ -41,7 +46,7 @@ impl<'a> Deref<Flow + 'a> for FlowRef { } } -impl<'a> DerefMut<Flow + 'a> for FlowRef { +impl DerefMut for FlowRef { fn deref_mut<'a>(&mut self) -> &mut (Flow + 'a) { unsafe { mem::transmute_copy::<raw::TraitObject, &mut (Flow + 'a)>(&self.object) @@ -55,7 +60,7 @@ impl Drop for FlowRef { if self.object.vtable.is_null() { return } - if flow::base(&**self).ref_count().fetch_sub(1, SeqCst) > 1 { + if flow::base(&**self).ref_count().fetch_sub(1, Ordering::SeqCst) > 1 { return } let flow_ref: FlowRef = mem::replace(self, FlowRef { @@ -75,7 +80,7 @@ impl Drop for FlowRef { impl Clone for FlowRef { fn clone(&self) -> FlowRef { unsafe { - drop(flow::base(self.deref()).ref_count().fetch_add(1, SeqCst)); + drop(flow::base(&**self).ref_count().fetch_add(1, Ordering::SeqCst)); FlowRef { object: raw::TraitObject { vtable: self.object.vtable, diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 8bad0a288b6..21396838f0c 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -32,15 +32,17 @@ use serialize::{Encodable, Encoder}; use servo_msg::constellation_msg::{PipelineId, SubpageId}; use servo_net::image::holder::ImageHolder; use servo_net::local_image_cache::LocalImageCache; -use servo_util::geometry::{mod, Au, ZERO_POINT}; +use servo_util::geometry::{self, Au, ZERO_POINT}; use servo_util::logical_geometry::{LogicalRect, LogicalSize, LogicalMargin}; use servo_util::range::*; use servo_util::smallvec::SmallVec; use servo_util::str::is_whitespace; use std::cmp::{max, min}; use std::fmt; +use std::num::ToPrimitive; use std::str::FromStr; use std::sync::{Arc, Mutex}; +use std::sync::mpsc::Sender; use string_cache::Atom; use style::{ComputedValues, TElement, TNode, cascade_anonymous}; use style::computed_values::{LengthOrPercentage, LengthOrPercentageOrAuto}; @@ -75,7 +77,7 @@ use url::Url; /// /// FIXME(#2260, pcwalton): This can be slimmed down some by (at least) moving `inline_context` /// to be on `InlineFlow` only. -#[deriving(Clone)] +#[derive(Clone)] pub struct Fragment { /// An opaque reference to the DOM node that this `Fragment` originates from. pub node: OpaqueNode, @@ -111,11 +113,14 @@ pub struct Fragment { pub restyle_damage: RestyleDamage, } -impl<E, S: Encoder<E>> Encodable<S, E> for Fragment { - fn encode(&self, e: &mut S) -> Result<(), E> { +unsafe impl Send for Fragment {} +unsafe impl Sync for Fragment {} + +impl Encodable for Fragment { + fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> { e.emit_struct("fragment", 0, |e| { - try!(e.emit_struct_field("id", 0, |e| self.debug_id().encode(e))) - try!(e.emit_struct_field("border_box", 1, |e| self.border_box.encode(e))) + try!(e.emit_struct_field("id", 0, |e| self.debug_id().encode(e))); + try!(e.emit_struct_field("border_box", 1, |e| self.border_box.encode(e))); e.emit_struct_field("margin", 2, |e| self.margin.encode(e)) }) } @@ -124,7 +129,7 @@ impl<E, S: Encoder<E>> Encodable<S, E> for Fragment { /// Info specific to the kind of fragment. /// /// Keep this enum small. As in, no more than one word. Or pcwalton will yell at you. -#[deriving(Clone)] +#[derive(Clone)] pub enum SpecificFragmentInfo { Generic, Iframe(Box<IframeFragmentInfo>), @@ -164,7 +169,7 @@ impl SpecificFragmentInfo { SpecificFragmentInfo::InlineBlock(ref info) => &info.flow_ref, }; - flow::base(flow.deref()).restyle_damage + flow::base(&**flow).restyle_damage } pub fn get_type(&self) -> &'static str { @@ -191,7 +196,7 @@ impl SpecificFragmentInfo { /// /// FIXME(pcwalton): Stop leaking this `FlowRef` to layout; that is not memory safe because layout /// can clone it. -#[deriving(Clone)] +#[derive(Clone)] pub struct InlineAbsoluteHypotheticalFragmentInfo { pub flow_ref: FlowRef, } @@ -208,7 +213,7 @@ impl InlineAbsoluteHypotheticalFragmentInfo { /// /// FIXME(pcwalton): Stop leaking this `FlowRef` to layout; that is not memory safe because layout /// can clone it. -#[deriving(Clone)] +#[derive(Clone)] pub struct InlineBlockFragmentInfo { pub flow_ref: FlowRef, } @@ -221,7 +226,7 @@ impl InlineBlockFragmentInfo { } } -#[deriving(Clone)] +#[derive(Clone)] pub struct CanvasFragmentInfo { pub replaced_image_fragment_info: ReplacedImageFragmentInfo, pub renderer: Option<Arc<Mutex<Sender<CanvasMsg>>>>, @@ -250,7 +255,7 @@ impl CanvasFragmentInfo { /// A fragment that represents a replaced content image and its accompanying borders, shadows, etc. -#[deriving(Clone)] +#[derive(Clone)] pub struct ImageFragmentInfo { /// The image held within this fragment. pub replaced_image_fragment_info: ReplacedImageFragmentInfo, @@ -309,7 +314,7 @@ impl ImageFragmentInfo { } } -#[deriving(Clone)] +#[derive(Clone)] pub struct ReplacedImageFragmentInfo { pub for_node: UntrustedNodeAddress, pub computed_inline_size: Option<Au>, @@ -479,7 +484,7 @@ impl ReplacedImageFragmentInfo { /// A fragment that represents an inline frame (iframe). This stores the pipeline ID so that the size /// of this iframe can be communicated via the constellation to the iframe's own layout task. -#[deriving(Clone)] +#[derive(Clone)] pub struct IframeFragmentInfo { /// The pipeline ID of this iframe. pub pipeline_id: PipelineId, @@ -502,7 +507,7 @@ impl IframeFragmentInfo { /// may be split into two or more fragments across line breaks. Several `TextFragment`s may /// correspond to a single DOM text node. Split text fragments are implemented by referring to /// subsets of a single `TextRun` object. -#[deriving(Clone)] +#[derive(Clone)] pub struct ScannedTextFragmentInfo { /// The text run that this represents. pub run: Arc<Box<TextRun>>, @@ -543,7 +548,7 @@ impl ScannedTextFragmentInfo { /// Describes how to split a fragment. This is used during line breaking as part of the return /// value of `find_split_info_for_inline_size()`. -#[deriving(Show, Clone)] +#[derive(Show, Clone)] pub struct SplitInfo { // TODO(bjz): this should only need to be a single character index, but both values are // currently needed for splitting in the `inline::try_append_*` functions. @@ -572,7 +577,7 @@ pub struct SplitResult { /// Data for an unscanned text fragment. Unscanned text fragments are the results of flow /// construction that have not yet had their inline-size determined. -#[deriving(Clone)] +#[derive(Clone)] pub struct UnscannedTextFragmentInfo { /// The text inside the fragment. /// @@ -600,7 +605,7 @@ impl UnscannedTextFragmentInfo { } /// A fragment that represents a table column. -#[deriving(Copy, Clone)] +#[derive(Copy, Clone)] pub struct TableColumnFragmentInfo { /// the number of columns a <col> element should span pub span: int, @@ -743,7 +748,7 @@ impl Fragment { /// if called on any other type of fragment. pub fn save_new_line_pos(&mut self) { match &mut self.specific { - &SpecificFragmentInfo::ScannedText(ref mut info) => { + &mut SpecificFragmentInfo::ScannedText(ref mut info) => { if !info.new_line_pos.is_empty() { info.original_new_line_pos = Some(info.new_line_pos.clone()); } @@ -754,7 +759,7 @@ impl Fragment { pub fn restore_new_line_pos(&mut self) { match &mut self.specific { - &SpecificFragmentInfo::ScannedText(ref mut info) => { + &mut SpecificFragmentInfo::ScannedText(ref mut info) => { match info.original_new_line_pos.take() { None => {} Some(new_line_pos) => info.new_line_pos = new_line_pos, @@ -1278,7 +1283,7 @@ impl Fragment { } SpecificFragmentInfo::ScannedText(ref text_fragment_info) => { let mut new_line_pos = text_fragment_info.new_line_pos.clone(); - let cur_new_line_pos = new_line_pos.remove(0).unwrap(); + let cur_new_line_pos = new_line_pos.remove(0); let inline_start_range = Range::new(text_fragment_info.range.begin(), cur_new_line_pos); @@ -1355,7 +1360,7 @@ impl Fragment { max_inline_size: Au, flags: SplitOptions) -> Option<SplitResult> - where I: Iterator<TextRunSlice<'a>> { + where I: Iterator<Item=TextRunSlice<'a>> { let text_fragment_info = if let SpecificFragmentInfo::ScannedText(ref text_fragment_info) = self.specific { text_fragment_info @@ -1368,15 +1373,15 @@ impl Fragment { let mut inline_start_range = Range::new(text_fragment_info.range.begin(), CharIndex(0)); let mut inline_end_range = None; - debug!("calculate_split_position: splitting text fragment (strlen={}, range={}, \ - max_inline_size={})", + debug!("calculate_split_position: splitting text fragment (strlen={}, range={:?}, \ + max_inline_size={:?})", text_fragment_info.run.text.len(), text_fragment_info.range, max_inline_size); for slice in slice_iterator { - debug!("calculate_split_position: considering slice (offset={}, slice range={}, \ - remaining_inline_size={})", + debug!("calculate_split_position: considering slice (offset={:?}, slice range={:?}, \ + remaining_inline_size={:?})", slice.offset, slice.range, remaining_inline_size); @@ -1408,7 +1413,7 @@ impl Fragment { let mut inline_end = slice.text_run_range(); inline_end.extend_to(text_fragment_info.range.end()); inline_end_range = Some(inline_end); - debug!("calculate_split_position: splitting remainder with inline-end range={}", + debug!("calculate_split_position: splitting remainder with inline-end range={:?}", inline_end); } @@ -1610,7 +1615,7 @@ impl Fragment { } SpecificFragmentInfo::InlineBlock(ref info) => { // See CSS 2.1 § 10.8.1. - let block_flow = info.flow_ref.deref().as_immutable_block(); + let block_flow = info.flow_ref.as_immutable_block(); let font_style = self.style.get_font_arc(); let font_metrics = text::font_metrics_for_style(layout_context.font_context(), font_style); @@ -1816,9 +1821,9 @@ impl Fragment { impl fmt::Show for Fragment { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(write!(f, "({} {} ", self.debug_id(), self.specific.get_type())); - try!(write!(f, "bp {}", self.border_padding)); + try!(write!(f, "bp {:?}", self.border_padding)); try!(write!(f, " ")); - try!(write!(f, "m {}", self.margin)); + try!(write!(f, "m {:?}", self.margin)); write!(f, ")") } } @@ -1856,7 +1861,7 @@ pub trait FragmentBorderBoxIterator { /// The coordinate system used in `stacking_relative_border_box()`. See the documentation of that /// method for details. -#[deriving(Clone, PartialEq, Show)] +#[derive(Clone, PartialEq, Show)] pub enum CoordinateSystem { /// The border box returned is relative to the fragment's parent stacking context. Parent, diff --git a/components/layout/incremental.rs b/components/layout/incremental.rs index 6949063d41b..1b89015e6aa 100644 --- a/components/layout/incremental.rs +++ b/components/layout/incremental.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use flow::{mod, Flow}; +use flow::{self, Flow}; use flow::{IS_ABSOLUTELY_POSITIONED}; use std::fmt; @@ -12,7 +12,6 @@ use style::ComputedValues; bitflags! { #[doc = "Individual layout actions that may be necessary after restyling."] - #[deriving(Copy)] flags RestyleDamage: u8 { #[doc = "Repaint the node itself."] #[doc = "Currently unused; need to decide how this propagates."] @@ -125,7 +124,7 @@ macro_rules! add_if_not_equal( $damage.insert($($effect)|*); } }) -) +); pub fn compute_damage(old: &Option<Arc<ComputedValues>>, new: &ComputedValues) -> RestyleDamage { let old: &ComputedValues = diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 67fc65b21e7..aadcd1b310e 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -31,6 +31,8 @@ use servo_util::range::{Range, RangeIndex}; use std::cmp::max; use std::fmt; use std::mem; +use std::num::ToPrimitive; +use std::ops::{Add, Sub, Mul, Div, Rem, Neg, Shl, Shr, Not, BitOr, BitAnd, BitXor}; use std::u16; use style::computed_values::{text_align, vertical_align, white_space}; use style::ComputedValues; @@ -65,7 +67,7 @@ static FONT_SUPERSCRIPT_OFFSET_RATIO: f64 = 0.34; /// with a float or a horizontal wall of the containing block. The block-start /// inline-start corner of the green zone is the same as that of the line, but /// the green zone can be taller and wider than the line itself. -#[deriving(Encodable, Show, Copy)] +#[derive(RustcEncodable, Show, Copy)] pub struct Line { /// A range of line indices that describe line breaks. /// @@ -150,7 +152,7 @@ pub struct Line { } int_range_index! { - #[deriving(Encodable)] + #[derive(RustcEncodable)] #[doc = "The index of a fragment in a flattened vector of DOM elements."] struct FragmentIndex(int) } @@ -256,7 +258,7 @@ impl LineBreaker { mut old_fragment_iter: I, flow: &'a InlineFlow, layout_context: &LayoutContext) - where I: Iterator<Fragment> { + where I: Iterator<Item=Fragment> { loop { // Acquire the next fragment to lay out from the work list or fragment list, as // appropriate. @@ -305,18 +307,18 @@ impl LineBreaker { /// Note that you probably don't want to call this method directly in order to be /// incremental-reflow-safe; try `next_unbroken_fragment` instead. fn next_fragment<I>(&mut self, old_fragment_iter: &mut I) -> Option<Fragment> - where I: Iterator<Fragment> { + where I: Iterator<Item=Fragment> { if self.work_list.is_empty() { return match old_fragment_iter.next() { None => None, Some(fragment) => { - debug!("LineBreaker: working with fragment from flow: {}", fragment); + debug!("LineBreaker: working with fragment from flow: {:?}", fragment); Some(fragment) } } } - debug!("LineBreaker: working with fragment from work list: {}", self.work_list.front()); + debug!("LineBreaker: working with fragment from work list: {:?}", self.work_list.front()); self.work_list.pop_front() } @@ -325,7 +327,7 @@ impl LineBreaker { /// fragment to lay out, undoing line break operations that any previous reflows may have /// performed. You probably want to be using this method instead of `next_fragment`. fn next_unbroken_fragment<I>(&mut self, old_fragment_iter: &mut I) -> Option<Fragment> - where I: Iterator<Fragment> { + where I: Iterator<Item=Fragment> { let mut result = match self.next_fragment(old_fragment_iter) { None => return None, Some(fragment) => fragment, @@ -342,7 +344,7 @@ impl LineBreaker { }; let need_to_merge = match (&mut result.specific, &candidate.specific) { - (&SpecificFragmentInfo::ScannedText(ref mut result_info), + (&mut SpecificFragmentInfo::ScannedText(ref mut result_info), &SpecificFragmentInfo::ScannedText(ref candidate_info)) if arc_ptr_eq(&result_info.run, &candidate_info.run) && result_info.range.end() + CharIndex(1) == candidate_info.range.begin() => { @@ -362,7 +364,7 @@ impl LineBreaker { /// Commits a line to the list. fn flush_current_line(&mut self) { - debug!("LineBreaker: flushing line {}: {}", self.lines.len(), self.pending_line); + debug!("LineBreaker: flushing line {}: {:?}", self.lines.len(), self.pending_line); self.lines.push(self.pending_line); self.cur_b = self.pending_line.bounds.start.b + self.pending_line.bounds.size.block; self.reset_line(); @@ -388,7 +390,7 @@ impl LineBreaker { first_fragment: &Fragment, ceiling: Au) -> (LogicalRect<Au>, Au) { - debug!("LineBreaker: trying to place first fragment of line {}; fragment size: {}, \ + debug!("LineBreaker: trying to place first fragment of line {}; fragment size: {:?}, \ splittable: {}", self.lines.len(), first_fragment.border_box.size, @@ -496,7 +498,7 @@ impl LineBreaker { .expect("LineBreaker: this split case makes no sense!"); let writing_mode = self.floats.writing_mode; - let split_fragment = |split: SplitInfo| { + let split_fragment = |&:split: SplitInfo| { let info = box ScannedTextFragmentInfo::new(run.clone(), split.range, (*in_fragment.newline_positions() @@ -541,7 +543,7 @@ impl LineBreaker { self.pending_line.green_zone = line_bounds.size; } - debug!("LineBreaker: trying to append to line {} (fragment size: {}, green zone: {}): {}", + debug!("LineBreaker: trying to append to line {} (fragment size: {:?}, green zone: {:?}): {:?}", self.lines.len(), fragment.border_box.size, self.pending_line.green_zone, @@ -586,13 +588,13 @@ impl LineBreaker { match fragment.calculate_split_position(available_inline_size, self.pending_line_is_empty()) { None => { - debug!("LineBreaker: fragment was unsplittable; deferring to next line: {}", + debug!("LineBreaker: fragment was unsplittable; deferring to next line: {:?}", fragment); self.work_list.push_front(fragment); return false } Some(split_result) => { - let split_fragment = |split: SplitInfo| { + let split_fragment = |&:split: SplitInfo| { let info = box ScannedTextFragmentInfo::new(split_result.text_run.clone(), split.range, Vec::new(), @@ -657,7 +659,7 @@ impl LineBreaker { } /// Represents a list of inline fragments, including element ranges. -#[deriving(Encodable, Clone)] +#[derive(RustcEncodable, Clone)] pub struct InlineFragments { /// The fragments themselves. pub fragments: Vec<Fragment>, @@ -665,7 +667,7 @@ pub struct InlineFragments { impl fmt::Show for InlineFragments { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.fragments) + write!(f, "{:?}", self.fragments) } } @@ -711,7 +713,7 @@ impl InlineFragments { } /// Flows for inline layout. -#[deriving(Encodable)] +#[derive(RustcEncodable)] pub struct InlineFlow { /// Data common to all flows. pub base: BaseFlow, @@ -966,7 +968,7 @@ impl Flow for InlineFlow { let mut computation = IntrinsicISizesContribution::new(); for fragment in self.fragments.fragments.iter_mut() { - debug!("Flow: measuring {}", *fragment); + debug!("Flow: measuring {:?}", *fragment); computation.union_inline(&fragment.compute_intrinsic_inline_sizes().finish()) } self.base.intrinsic_inline_sizes = computation.finish() @@ -982,7 +984,7 @@ impl Flow for InlineFlow { // TODO: Combine this with `LineBreaker`'s walk in the fragment list, or put this into // `Fragment`. - debug!("InlineFlow::assign_inline_sizes: floats in: {}", self.base.floats); + debug!("InlineFlow::assign_inline_sizes: floats in: {:?}", self.base.floats); self.base.position.size.inline = self.base.block_container_inline_size; @@ -1022,7 +1024,7 @@ impl Flow for InlineFlow { // element to determine its block-size for computing the line's own block-size. // // TODO(pcwalton): Cache the line scanner? - debug!("assign_block_size_inline: floats in: {}", self.base.floats); + debug!("assign_block_size_inline: floats in: {:?}", self.base.floats); // Assign the block-size for the inline fragments. let containing_block_block_size = @@ -1194,14 +1196,14 @@ impl Flow for InlineFlow { &stacking_relative_border_box); match fragment.specific { SpecificFragmentInfo::InlineBlock(ref mut info) => { - flow::mut_base(info.flow_ref.deref_mut()).clip = clip; + flow::mut_base(&mut *info.flow_ref).clip = clip; let block_flow = info.flow_ref.as_block(); block_flow.base.absolute_position_info = self.base.absolute_position_info; block_flow.base.stacking_relative_position = stacking_relative_border_box.origin; } SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut info) => { - flow::mut_base(info.flow_ref.deref_mut()).clip = clip; + flow::mut_base(&mut *info.flow_ref).clip = clip; let block_flow = info.flow_ref.as_block(); block_flow.base.absolute_position_info = self.base.absolute_position_info; block_flow.base.stacking_relative_position = @@ -1254,11 +1256,11 @@ impl Flow for InlineFlow { impl fmt::Show for InlineFlow { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} - {:x} - {}", self.class(), self.base.debug_id(), self.fragments) + write!(f, "{:?} - {:x} - {:?}", self.class(), self.base.debug_id(), self.fragments) } } -#[deriving(Clone)] +#[derive(Clone)] pub struct InlineFragmentContext { pub styles: Vec<Arc<ComputedValues>>, } diff --git a/components/layout/layout_debug.rs b/components/layout/layout_debug.rs index 94ddad456f6..5f0851b1f36 100644 --- a/components/layout/layout_debug.rs +++ b/components/layout/layout_debug.rs @@ -10,13 +10,15 @@ use flow_ref::FlowRef; use flow; use serialize::json; + +use std::borrow::ToOwned; use std::cell::RefCell; use std::io::File; -use std::sync::atomic::{AtomicUint, SeqCst, INIT_ATOMIC_UINT}; +use std::sync::atomic::{AtomicUint, Ordering, ATOMIC_UINT_INIT}; -thread_local!(static STATE_KEY: RefCell<Option<State>> = RefCell::new(None)) +thread_local!(static STATE_KEY: RefCell<Option<State>> = RefCell::new(None)); -static mut DEBUG_ID_COUNTER: AtomicUint = INIT_ATOMIC_UINT; +static mut DEBUG_ID_COUNTER: AtomicUint = ATOMIC_UINT_INIT; pub struct Scope; @@ -29,9 +31,9 @@ macro_rules! layout_debug_scope( layout_debug::Scope } ) -) +); -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct ScopeData { name: String, pre: String, @@ -61,12 +63,12 @@ impl Scope { pub fn new(name: String) -> Scope { STATE_KEY.with(|ref r| { match &mut *r.borrow_mut() { - &Some(ref mut state) => { - let flow_trace = json::encode(&flow::base(state.flow_root.deref())); + &mut Some(ref mut state) => { + let flow_trace = json::encode(&flow::base(&*state.flow_root)); let data = box ScopeData::new(name.clone(), flow_trace); state.scope_stack.push(data); } - &None => {} + &mut None => {} } }); Scope @@ -78,13 +80,13 @@ impl Drop for Scope { fn drop(&mut self) { STATE_KEY.with(|ref r| { match &mut *r.borrow_mut() { - &Some(ref mut state) => { + &mut Some(ref mut state) => { let mut current_scope = state.scope_stack.pop().unwrap(); - current_scope.post = json::encode(&flow::base(state.flow_root.deref())); + current_scope.post = json::encode(&flow::base(&*state.flow_root)); let previous_scope = state.scope_stack.last_mut().unwrap(); previous_scope.children.push(current_scope); } - &None => {} + &mut None => {} } }); } @@ -94,7 +96,7 @@ impl Drop for Scope { /// which are often reallocated but represent essentially the /// same data. pub fn generate_unique_debug_id() -> u16 { - unsafe { DEBUG_ID_COUNTER.fetch_add(1, SeqCst) as u16 } + unsafe { DEBUG_ID_COUNTER.fetch_add(1, Ordering::SeqCst) as u16 } } /// Begin a layout debug trace. If this has not been called, @@ -103,9 +105,9 @@ pub fn begin_trace(flow_root: FlowRef) { assert!(STATE_KEY.with(|ref r| r.borrow().is_none())); STATE_KEY.with(|ref r| { - let flow_trace = json::encode(&flow::base(flow_root.deref())); + let flow_trace = json::encode(&flow::base(&*flow_root)); let state = State { - scope_stack: vec![box ScopeData::new("root".into_string(), flow_trace)], + scope_stack: vec![box ScopeData::new("root".to_owned(), flow_trace)], flow_root: flow_root.clone(), }; *r.borrow_mut() = Some(state); @@ -119,7 +121,7 @@ pub fn end_trace() { let mut task_state = STATE_KEY.with(|ref r| r.borrow_mut().take().unwrap()); assert!(task_state.scope_stack.len() == 1); let mut root_scope = task_state.scope_stack.pop().unwrap(); - root_scope.post = json::encode(&flow::base(task_state.flow_root.deref())); + root_scope.post = json::encode(&flow::base(&*task_state.flow_root)); let result = json::encode(&root_scope); let path = Path::new("layout_trace.json"); diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index b8c2385a557..53491dfdc5e 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -7,13 +7,13 @@ use css::node_style::StyledNode; use construct::ConstructionResult; -use context::SharedLayoutContext; -use flow::{mod, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils}; +use context::{SharedLayoutContext, SharedLayoutContextWrapper}; +use flow::{self, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils}; use flow_ref::FlowRef; use fragment::{Fragment, FragmentBorderBoxIterator}; use incremental::{LayoutDamageComputation, REFLOW, REFLOW_ENTIRE_DOCUMENT, REPAINT}; use layout_debug; -use parallel::{mod, UnsafeFlow}; +use parallel::{self, UnsafeFlow}; use sequential; use util::{LayoutDataAccess, LayoutDataWrapper, OpaqueNodeMethods, ToGfxColor}; use wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode}; @@ -59,8 +59,10 @@ use servo_util::task_state; use servo_util::time::{TimeProfilerCategory, ProfilerMetadata, TimeProfilerChan}; use servo_util::time::{TimerMetadataFrameType, TimerMetadataReflowType, profile}; use servo_util::workqueue::WorkQueue; +use std::borrow::ToOwned; use std::cell::Cell; -use std::comm::{channel, Sender, Receiver, Select}; +use std::ops::{Deref, DerefMut}; +use std::sync::mpsc::{channel, Sender, Receiver, Select}; use std::mem; use std::ptr; use style::computed_values::{filter, mix_blend_mode}; @@ -88,7 +90,7 @@ pub struct LayoutTaskData { pub stylist: Box<Stylist>, /// The workers that we use for parallel operation. - pub parallel_traversal: Option<WorkQueue<*const SharedLayoutContext, UnsafeFlow>>, + pub parallel_traversal: Option<WorkQueue<SharedLayoutContextWrapper, UnsafeFlow>>, /// The dirty rect. Used during display list construction. pub dirty: Rect<Au>, @@ -152,19 +154,17 @@ struct LayoutImageResponder { } impl ImageResponder<UntrustedNodeAddress> for LayoutImageResponder { - fn respond(&self) -> proc(ImageResponseMsg, UntrustedNodeAddress):Send { + fn respond(&self) -> Box<Fn(ImageResponseMsg, UntrustedNodeAddress)+Send> { let id = self.id.clone(); let script_chan = self.script_chan.clone(); - let f: proc(ImageResponseMsg, UntrustedNodeAddress):Send = - proc(_, node_address) { - let ScriptControlChan(chan) = script_chan; - debug!("Dirtying {:x}", node_address as uint); - let mut nodes = SmallVec1::new(); - nodes.vec_push(node_address); - drop(chan.send_opt(ConstellationControlMsg::SendEvent( - id.clone(), CompositorEvent::ReflowEvent(nodes)))) - }; - f + box move |&:_, node_address| { + let ScriptControlChan(ref chan) = script_chan; + debug!("Dirtying {:x}", node_address.0 as uint); + let mut nodes = SmallVec1::new(); + nodes.vec_push(node_address); + drop(chan.send(ConstellationControlMsg::SendEvent( + id, CompositorEvent::ReflowEvent(nodes)))) + } } } @@ -184,7 +184,7 @@ impl LayoutTaskFactory for LayoutTask { time_profiler_chan: TimeProfilerChan, shutdown_chan: Sender<()>) { let ConstellationChan(con_chan) = constellation_chan.clone(); - spawn_named_with_send_on_failure("LayoutTask", task_state::LAYOUT, proc() { + spawn_named_with_send_on_failure("LayoutTask", task_state::LAYOUT, move || { { // Ensures layout task is destroyed before we send shutdown message let sender = chan.sender(); let layout = @@ -218,20 +218,21 @@ enum RWGuard<'a> { Used(MutexGuard<'a, LayoutTaskData>), } -impl<'a> Deref<LayoutTaskData> for RWGuard<'a> { +impl<'a> Deref for RWGuard<'a> { + type Target = LayoutTaskData; fn deref(&self) -> &LayoutTaskData { match *self { - RWGuard::Held(ref x) => x.deref(), - RWGuard::Used(ref x) => x.deref(), + RWGuard::Held(ref x) => &**x, + RWGuard::Used(ref x) => &**x, } } } -impl<'a> DerefMut<LayoutTaskData> for RWGuard<'a> { +impl<'a> DerefMut for RWGuard<'a> { fn deref_mut(&mut self) -> &mut LayoutTaskData { match *self { - RWGuard::Held(ref mut x) => x.deref_mut(), - RWGuard::Used(ref mut x) => x.deref_mut(), + RWGuard::Held(ref mut x) => &mut **x, + RWGuard::Used(ref mut x) => &mut **x, } } } @@ -256,7 +257,7 @@ impl LayoutTask { let device = Device::new(MediaType::Screen, opts::get().initial_window_size.as_f32() * ScaleFactor(1.0)); let parallel_traversal = if opts::get().layout_threads != 1 { Some(WorkQueue::new("LayoutWorker", task_state::LAYOUT, - opts::get().layout_threads, ptr::null())) + opts::get().layout_threads, SharedLayoutContextWrapper(ptr::null()))) } else { None }; @@ -291,7 +292,7 @@ impl LayoutTask { /// Starts listening on the port. fn start(self) { - let mut possibly_locked_rw_data = Some(self.rw_data.lock()); + let mut possibly_locked_rw_data = Some((*self.rw_data).lock().unwrap()); while self.handle_request(&mut possibly_locked_rw_data) { // Loop indefinitely. } @@ -346,14 +347,14 @@ impl LayoutTask { match port_to_read { PortToRead::Pipeline => { - match self.pipeline_port.recv() { + match self.pipeline_port.recv().unwrap() { LayoutControlMsg::ExitNowMsg(exit_type) => { self.handle_script_request(Msg::ExitNow(exit_type), possibly_locked_rw_data) } } }, PortToRead::Script => { - let msg = self.port.recv(); + let msg = self.port.recv().unwrap(); self.handle_script_request(msg, possibly_locked_rw_data) } } @@ -369,7 +370,7 @@ impl LayoutTask { possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) -> RWGuard<'a> { match possibly_locked_rw_data.take() { - None => RWGuard::Used(self.rw_data.lock()), + None => RWGuard::Used((*self.rw_data).lock().unwrap()), Some(x) => RWGuard::Held(x), } } @@ -433,7 +434,7 @@ impl LayoutTask { possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) { response_chan.send(()); loop { - match self.port.recv() { + match self.port.recv().unwrap() { Msg::ReapLayoutData(dead_layout_data) => { unsafe { LayoutTask::handle_reap_layout_data(dead_layout_data) @@ -461,7 +462,7 @@ impl LayoutTask { { let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); - match rw_data.deref_mut().parallel_traversal { + match (&mut *rw_data).parallel_traversal { None => {} Some(ref mut traversal) => traversal.shutdown(), } @@ -469,7 +470,7 @@ impl LayoutTask { } self.paint_chan.send(PaintMsg::Exit(Some(response_chan), exit_type)); - response_port.recv() + response_port.recv().unwrap() } fn handle_load_stylesheet<'a>(&'a self, @@ -498,8 +499,8 @@ impl LayoutTask { // Find all font-face rules and notify the font cache of them. // GWTODO: Need to handle unloading web fonts (when we handle unloading stylesheets!) let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); - iter_font_face_rules(&sheet, &rw_data.stylist.device, |family, src| { - self.font_cache_task.add_web_font(family.into_string(), (*src).clone()); + iter_font_face_rules(&sheet, &rw_data.stylist.device, &|&:family, src| { + self.font_cache_task.add_web_font(family.to_owned(), (*src).clone()); }); rw_data.stylist.add_stylesheet(sheet); LayoutTask::return_rw_data(possibly_locked_rw_data, rw_data); @@ -643,7 +644,7 @@ impl LayoutTask { flow::mut_base(&mut **layout_root).clip = ClippingRegion::from_rect(&data.page_clip_rect); - let rw_data = rw_data.deref_mut(); + let rw_data = &mut **rw_data; match rw_data.parallel_traversal { None => { sequential::build_display_list_for_subtree(layout_root, shared_layout_context); @@ -687,8 +688,8 @@ impl LayoutTask { root_flow.position.size.to_physical(root_flow.writing_mode) }; let mut display_list = box DisplayList::new(); - flow::mut_base(layout_root.deref_mut()).display_list_building_result - .add_to(&mut *display_list); + flow::mut_base(&mut **layout_root).display_list_building_result + .add_to(&mut *display_list); let paint_layer = Arc::new(PaintLayer::new(layout_root.layer_id(0), color, ScrollPolicy::Scrollable)); @@ -733,7 +734,7 @@ impl LayoutTask { { // Reset the image cache. - let mut local_image_cache = rw_data.local_image_cache.lock(); + let mut local_image_cache = rw_data.local_image_cache.lock().unwrap(); local_image_cache.next_round(self.make_on_image_available_cb()); } @@ -747,7 +748,7 @@ impl LayoutTask { rw_data.screen_size = current_screen_size; // Create a layout context for use throughout the following passes. - let mut shared_layout_context = self.build_shared_layout_context(rw_data.deref(), + let mut shared_layout_context = self.build_shared_layout_context(&*rw_data, node, &data.url); @@ -772,7 +773,7 @@ impl LayoutTask { if needs_reflow { self.try_get_layout_root(*node).map( - |mut flow| LayoutTask::reflow_all_nodes(flow.deref_mut())); + |mut flow| LayoutTask::reflow_all_nodes(&mut *flow)); } let mut layout_root = profile(TimeProfilerCategory::LayoutStyleRecalc, @@ -780,7 +781,7 @@ impl LayoutTask { self.time_profiler_chan.clone(), || { // Perform CSS selector matching and flow construction. - let rw_data = rw_data.deref_mut(); + let rw_data = &mut *rw_data; match rw_data.parallel_traversal { None => { sequential::traverse_dom_preorder(*node, &shared_layout_context); @@ -797,10 +798,9 @@ impl LayoutTask { self.profiler_metadata(data), self.time_profiler_chan.clone(), || { - if opts::get().nonincremental_layout || layout_root.deref_mut() - .compute_layout_damage() + if opts::get().nonincremental_layout || layout_root.compute_layout_damage() .contains(REFLOW_ENTIRE_DOCUMENT) { - layout_root.deref_mut().reflow_entire_document() + layout_root.reflow_entire_document() } }); @@ -819,7 +819,7 @@ impl LayoutTask { self.profiler_metadata(data), self.time_profiler_chan.clone(), || { - let rw_data = rw_data.deref_mut(); + let rw_data = &mut *rw_data; match rw_data.parallel_traversal { None => { // Sequential mode. @@ -946,14 +946,14 @@ impl LayoutRPC for LayoutRPCImpl { // need to compare nodes for equality. Thus we can safely work only with `OpaqueNode`. fn content_box(&self) -> ContentBoxResponse { let &LayoutRPCImpl(ref rw_data) = self; - let rw_data = rw_data.lock(); + let rw_data = rw_data.lock().unwrap(); ContentBoxResponse(rw_data.content_box_response) } /// Requests the dimensions of all the content boxes, as in the `getClientRects()` call. fn content_boxes(&self) -> ContentBoxesResponse { let &LayoutRPCImpl(ref rw_data) = self; - let rw_data = rw_data.lock(); + let rw_data = rw_data.lock().unwrap(); ContentBoxesResponse(rw_data.content_boxes_response.clone()) } @@ -962,7 +962,7 @@ impl LayoutRPC for LayoutRPCImpl { let point = Point2D(Au::from_frac_px(point.x as f64), Au::from_frac_px(point.y as f64)); let resp = { let &LayoutRPCImpl(ref rw_data) = self; - let rw_data = rw_data.lock(); + let rw_data = rw_data.lock().unwrap(); match rw_data.stacking_context { None => panic!("no root stacking context!"), Some(ref stacking_context) => { @@ -989,7 +989,7 @@ impl LayoutRPC for LayoutRPCImpl { let point = Point2D(Au::from_frac_px(point.x as f64), Au::from_frac_px(point.y as f64)); { let &LayoutRPCImpl(ref rw_data) = self; - let rw_data = rw_data.lock(); + let rw_data = rw_data.lock().unwrap(); match rw_data.stacking_context { None => panic!("no root stacking context!"), Some(ref stacking_context) => { diff --git a/components/layout/lib.rs b/components/layout/lib.rs index 5fc89dbd82d..17812c262c2 100644 --- a/components/layout/lib.rs +++ b/components/layout/lib.rs @@ -2,14 +2,15 @@ * 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/. */ -#![feature(globs, macro_rules, phase, thread_local, unsafe_destructor)] +#![feature(thread_local, unsafe_destructor, box_syntax, plugin, int_uint)] #![deny(unused_imports)] #![deny(unused_variables)] #![allow(unrooted_must_root)] #![allow(missing_copy_implementations)] +#![allow(unstable)] -#[phase(plugin, link)] +#[macro_use] extern crate log; extern crate cssparser; @@ -19,17 +20,19 @@ extern crate gfx; extern crate layout_traits; extern crate script; extern crate script_traits; +extern crate "serialize" as rustc_serialize; extern crate serialize; extern crate png; extern crate style; -#[phase(plugin)] +#[macro_use] +#[no_link] #[plugin] extern crate "plugins" as servo_plugins; extern crate "net" as servo_net; extern crate "msg" as servo_msg; -#[phase(plugin, link)] +#[macro_use] extern crate "util" as servo_util; -#[phase(plugin)] +#[no_link] #[macro_use] #[plugin] extern crate string_cache_macros; extern crate string_cache; diff --git a/components/layout/list_item.rs b/components/layout/list_item.rs index 296a73454ca..3c4dc8a7fc8 100644 --- a/components/layout/list_item.rs +++ b/components/layout/list_item.rs @@ -24,7 +24,7 @@ use style::computed_values::list_style_type; use std::sync::Arc; /// A block with the CSS `display` property equal to `list-item`. -#[deriving(Show)] +#[derive(Show)] pub struct ListItemFlow { /// Data common to all block flows. pub block_flow: BlockFlow, diff --git a/components/layout/model.rs b/components/layout/model.rs index a031a5b0537..b83585906ad 100644 --- a/components/layout/model.rs +++ b/components/layout/model.rs @@ -18,7 +18,7 @@ use std::cmp::{max, min}; use std::fmt; /// A collapsible margin. See CSS 2.1 § 8.3.1. -#[deriving(Copy)] +#[derive(Copy)] pub struct AdjoiningMargins { /// The value of the greatest positive margin. pub most_positive: Au, @@ -61,7 +61,7 @@ impl AdjoiningMargins { } /// Represents the block-start and block-end margins of a flow with collapsible margins. See CSS 2.1 § 8.3.1. -#[deriving(Copy)] +#[derive(Copy)] pub enum CollapsibleMargins { /// Margins may not collapse with this flow. None(Au, Au), @@ -239,14 +239,14 @@ impl MarginCollapseInfo { } } -#[deriving(Copy)] +#[derive(Copy)] pub enum MarginCollapseState { AccumulatingCollapsibleTopMargin, AccumulatingMarginIn, } /// Intrinsic inline-sizes, which consist of minimum and preferred. -#[deriving(Encodable)] +#[derive(RustcEncodable)] pub struct IntrinsicISizes { /// The *minimum inline-size* of the content. pub minimum_inline_size: Au, @@ -256,7 +256,7 @@ pub struct IntrinsicISizes { impl fmt::Show for IntrinsicISizes { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "min={}, pref={}", self.minimum_inline_size, self.preferred_inline_size) + write!(f, "min={:?}, pref={:?}", self.minimum_inline_size, self.preferred_inline_size) } } @@ -325,7 +325,7 @@ impl IntrinsicISizesContribution { } /// Useful helper data type when computing values for blocks and positioned elements. -#[deriving(Copy, PartialEq, Show)] +#[derive(Copy, PartialEq, Show)] pub enum MaybeAuto { Auto, Specified(Au), @@ -358,7 +358,7 @@ impl MaybeAuto { } #[inline] - pub fn map(&self, mapper: |Au| -> Au) -> MaybeAuto { + pub fn map<F>(&self, mapper: F) -> MaybeAuto where F: FnOnce(Au) -> Au { match *self { MaybeAuto::Auto => MaybeAuto::Auto, MaybeAuto::Specified(value) => MaybeAuto::Specified(mapper(value)), diff --git a/components/layout/parallel.rs b/components/layout/parallel.rs index a6a20ad33ba..05eb9168a04 100644 --- a/components/layout/parallel.rs +++ b/components/layout/parallel.rs @@ -6,7 +6,7 @@ //! //! This code is highly unsafe. Keep this file small and easy to audit. -use context::{LayoutContext, SharedLayoutContext}; +use context::{LayoutContext, SharedLayoutContextWrapper, SharedLayoutContext}; use flow::{Flow, MutableFlowUtils, PreorderFlowTraversal, PostorderFlowTraversal}; use flow; use flow_ref::FlowRef; @@ -23,7 +23,7 @@ use servo_util::time::{TimeProfilerCategory, ProfilerMetadata, TimeProfilerChan, use servo_util::workqueue::{WorkQueue, WorkUnit, WorkerProxy}; use std::mem; use std::ptr; -use std::sync::atomic::{AtomicInt, Relaxed, SeqCst}; +use std::sync::atomic::{AtomicInt, Ordering}; #[allow(dead_code)] fn static_assertion(node: UnsafeLayoutNode) { @@ -81,17 +81,17 @@ impl DomParallelInfo { pub trait ParallelPreorderDomTraversal : PreorderDomTraversal { fn run_parallel(&self, node: UnsafeLayoutNode, - proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeLayoutNode>); + proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeLayoutNode>); #[inline(always)] fn run_parallel_helper(&self, unsafe_node: UnsafeLayoutNode, - proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeLayoutNode>, + proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeLayoutNode>, top_down_func: extern "Rust" fn(UnsafeFlow, - &mut WorkerProxy<*const SharedLayoutContext, + &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeLayoutNode>), bottom_up_func: extern "Rust" fn(UnsafeFlow, - &mut WorkerProxy<*const SharedLayoutContext, + &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlow>)) { // Get a real layout node. let node: LayoutNode = unsafe { @@ -108,7 +108,7 @@ pub trait ParallelPreorderDomTraversal : PreorderDomTraversal { { let mut layout_data_ref = node.mutate_layout_data(); let layout_data = layout_data_ref.as_mut().expect("no layout data"); - layout_data.data.parallel.children_count.store(child_count as int, Relaxed); + layout_data.data.parallel.children_count.store(child_count as int, Ordering::Relaxed); } // Possibly enqueue the children. @@ -141,7 +141,7 @@ trait ParallelPostorderDomTraversal : PostorderDomTraversal { /// fetch-and-subtract the parent's children count. fn run_parallel(&self, mut unsafe_node: UnsafeLayoutNode, - proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeLayoutNode>) { + proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeLayoutNode>) { loop { // Get a real layout node. let node: LayoutNode = unsafe { @@ -151,7 +151,7 @@ trait ParallelPostorderDomTraversal : PostorderDomTraversal { // Perform the appropriate traversal. self.process(node); - let shared_layout_context = unsafe { &**proxy.user_data() }; + let shared_layout_context = unsafe { &*(proxy.user_data().0) }; let layout_context = LayoutContext::new(shared_layout_context); let parent = @@ -173,7 +173,7 @@ trait ParallelPostorderDomTraversal : PostorderDomTraversal { .data .parallel .children_count - .fetch_sub(1, SeqCst) == 1 { + .fetch_sub(1, Ordering::SeqCst) == 1 { // We were the last child of our parent. Construct flows for our parent. } else { // Get out of here and find another node to work on. @@ -216,22 +216,22 @@ trait ParallelPostorderFlowTraversal : PostorderFlowTraversal { /// fetch-and-subtract the parent's children count. fn run_parallel(&self, mut unsafe_flow: UnsafeFlow, - _: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) { + _: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>) { loop { unsafe { // Get a real flow. let flow: &mut FlowRef = mem::transmute(&unsafe_flow); // Perform the appropriate traversal. - if self.should_process(flow.deref_mut()) { - self.process(flow.deref_mut()); + if self.should_process(&mut **flow) { + self.process(&mut **flow); } - let base = flow::mut_base(flow.deref_mut()); + let base = flow::mut_base(&mut **flow); // Reset the count of children for the next layout traversal. - base.parallel.children_count.store(base.children.len() as int, Relaxed); + base.parallel.children_count.store(base.children.len() as int, Ordering::Relaxed); // Possibly enqueue the parent. let unsafe_parent = base.parallel.parent; @@ -244,8 +244,8 @@ trait ParallelPostorderFlowTraversal : PostorderFlowTraversal { // of our parent to finish processing? If so, we can continue // on with our parent; otherwise, we've gotta wait. let parent: &mut FlowRef = mem::transmute(&unsafe_parent); - let parent_base = flow::mut_base(parent.deref_mut()); - if parent_base.parallel.children_count.fetch_sub(1, SeqCst) == 1 { + let parent_base = flow::mut_base(&mut **parent); + if parent_base.parallel.children_count.fetch_sub(1, Ordering::SeqCst) == 1 { // We were the last child of our parent. Reflow our parent. unsafe_flow = unsafe_parent } else { @@ -261,30 +261,30 @@ trait ParallelPostorderFlowTraversal : PostorderFlowTraversal { trait ParallelPreorderFlowTraversal : PreorderFlowTraversal { fn run_parallel(&self, unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>); + proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>); #[inline(always)] fn run_parallel_helper(&self, unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>, + proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>, top_down_func: extern "Rust" fn(UnsafeFlow, - &mut WorkerProxy<*const SharedLayoutContext, + &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlow>), bottom_up_func: extern "Rust" fn(UnsafeFlow, - &mut WorkerProxy<*const SharedLayoutContext, + &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlow>)) { let mut had_children = false; unsafe { // Get a real flow. let flow: &mut FlowRef = mem::transmute(&unsafe_flow); - if self.should_process(flow.deref_mut()) { + if self.should_process(&mut **flow) { // Perform the appropriate traversal. - self.process(flow.deref_mut()); + self.process(&mut **flow); } // Possibly enqueue the children. - for kid in flow::child_iter(flow.deref_mut()) { + for kid in flow::child_iter(&mut **flow) { had_children = true; proxy.push(WorkUnit { fun: top_down_func, @@ -306,7 +306,7 @@ impl<'a> ParallelPostorderFlowTraversal for BubbleISizes<'a> {} impl<'a> ParallelPreorderFlowTraversal for AssignISizes<'a> { fn run_parallel(&self, unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) { + proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>) { self.run_parallel_helper(unsafe_flow, proxy, assign_inline_sizes, @@ -319,7 +319,7 @@ impl<'a> ParallelPostorderFlowTraversal for AssignBSizesAndStoreOverflow<'a> {} impl<'a> ParallelPreorderFlowTraversal for ComputeAbsolutePositions<'a> { fn run_parallel(&self, unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeFlow>) { + proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlow>) { self.run_parallel_helper(unsafe_flow, proxy, compute_absolute_positions, @@ -334,7 +334,7 @@ impl<'a> ParallelPostorderDomTraversal for ConstructFlows<'a> {} impl <'a> ParallelPreorderDomTraversal for RecalcStyleForNode<'a> { fn run_parallel(&self, unsafe_node: UnsafeLayoutNode, - proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeLayoutNode>) { + proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeLayoutNode>) { self.run_parallel_helper(unsafe_node, proxy, recalc_style, @@ -343,8 +343,8 @@ impl <'a> ParallelPreorderDomTraversal for RecalcStyleForNode<'a> { } fn recalc_style(unsafe_node: UnsafeLayoutNode, - proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeLayoutNode>) { - let shared_layout_context = unsafe { &**proxy.user_data() }; + proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeLayoutNode>) { + let shared_layout_context = unsafe { &*(proxy.user_data().0) }; let layout_context = LayoutContext::new(shared_layout_context); let recalc_style_for_node_traversal = RecalcStyleForNode { layout_context: &layout_context, @@ -353,8 +353,8 @@ fn recalc_style(unsafe_node: UnsafeLayoutNode, } fn construct_flows(unsafe_node: UnsafeLayoutNode, - proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeLayoutNode>) { - let shared_layout_context = unsafe { &**proxy.user_data() }; + proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeLayoutNode>) { + let shared_layout_context = unsafe { &*(proxy.user_data().0) }; let layout_context = LayoutContext::new(shared_layout_context); let construct_flows_traversal = ConstructFlows { layout_context: &layout_context, @@ -363,8 +363,8 @@ fn construct_flows(unsafe_node: UnsafeLayoutNode, } fn assign_inline_sizes(unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) { - let shared_layout_context = unsafe { &**proxy.user_data() }; + proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>) { + let shared_layout_context = unsafe { &*(proxy.user_data().0) }; let layout_context = LayoutContext::new(shared_layout_context); let assign_inline_sizes_traversal = AssignISizes { layout_context: &layout_context, @@ -373,8 +373,8 @@ fn assign_inline_sizes(unsafe_flow: UnsafeFlow, } fn assign_block_sizes_and_store_overflow(unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) { - let shared_layout_context = unsafe { &**proxy.user_data() }; + proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>) { + let shared_layout_context = unsafe { &*(proxy.user_data().0) }; let layout_context = LayoutContext::new(shared_layout_context); let assign_block_sizes_traversal = AssignBSizesAndStoreOverflow { layout_context: &layout_context, @@ -383,8 +383,8 @@ fn assign_block_sizes_and_store_overflow(unsafe_flow: UnsafeFlow, } fn compute_absolute_positions(unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeFlow>) { - let shared_layout_context = unsafe { &**proxy.user_data() }; + proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlow>) { + let shared_layout_context = unsafe { &*(proxy.user_data().0) }; let layout_context = LayoutContext::new(shared_layout_context); let compute_absolute_positions_traversal = ComputeAbsolutePositions { layout_context: &layout_context, @@ -393,8 +393,8 @@ fn compute_absolute_positions(unsafe_flow: UnsafeFlow, } fn build_display_list(unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeFlow>) { - let shared_layout_context = unsafe { &**proxy.user_data() }; + proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlow>) { + let shared_layout_context = unsafe { &*(proxy.user_data().0) }; let layout_context = LayoutContext::new(shared_layout_context); let build_display_list_traversal = BuildDisplayList { @@ -406,8 +406,8 @@ fn build_display_list(unsafe_flow: UnsafeFlow, pub fn traverse_dom_preorder(root: LayoutNode, shared_layout_context: &SharedLayoutContext, - queue: &mut WorkQueue<*const SharedLayoutContext, UnsafeLayoutNode>) { - queue.data = shared_layout_context as *const _; + queue: &mut WorkQueue<SharedLayoutContextWrapper, UnsafeLayoutNode>) { + queue.data = SharedLayoutContextWrapper(shared_layout_context as *const _); queue.push(WorkUnit { fun: recalc_style, @@ -416,21 +416,21 @@ pub fn traverse_dom_preorder(root: LayoutNode, queue.run(); - queue.data = ptr::null(); + queue.data = SharedLayoutContextWrapper(ptr::null()); } pub fn traverse_flow_tree_preorder(root: &mut FlowRef, profiler_metadata: ProfilerMetadata, time_profiler_chan: TimeProfilerChan, shared_layout_context: &SharedLayoutContext, - queue: &mut WorkQueue<*const SharedLayoutContext,UnsafeFlow>) { + queue: &mut WorkQueue<SharedLayoutContextWrapper,UnsafeFlow>) { if opts::get().bubble_inline_sizes_separately { let layout_context = LayoutContext::new(shared_layout_context); let bubble_inline_sizes = BubbleISizes { layout_context: &layout_context }; - root.deref_mut().traverse_postorder(&bubble_inline_sizes); + root.traverse_postorder(&bubble_inline_sizes); } - queue.data = shared_layout_context as *const _; + queue.data = SharedLayoutContextWrapper(shared_layout_context as *const _); profile(TimeProfilerCategory::LayoutParallelWarmup, profiler_metadata, time_profiler_chan, || { @@ -442,15 +442,15 @@ pub fn traverse_flow_tree_preorder(root: &mut FlowRef, queue.run(); - queue.data = ptr::null() + queue.data = SharedLayoutContextWrapper(ptr::null()) } pub fn build_display_list_for_subtree(root: &mut FlowRef, profiler_metadata: ProfilerMetadata, time_profiler_chan: TimeProfilerChan, shared_layout_context: &SharedLayoutContext, - queue: &mut WorkQueue<*const SharedLayoutContext,UnsafeFlow>) { - queue.data = shared_layout_context as *const _; + queue: &mut WorkQueue<SharedLayoutContextWrapper,UnsafeFlow>) { + queue.data = SharedLayoutContextWrapper(shared_layout_context as *const _); profile(TimeProfilerCategory::LayoutParallelWarmup, profiler_metadata, time_profiler_chan, || { @@ -462,5 +462,5 @@ pub fn build_display_list_for_subtree(root: &mut FlowRef, queue.run(); - queue.data = ptr::null() + queue.data = SharedLayoutContextWrapper(ptr::null()) } diff --git a/components/layout/sequential.rs b/components/layout/sequential.rs index 1be77041113..ff2bd948c51 100644 --- a/components/layout/sequential.rs +++ b/components/layout/sequential.rs @@ -5,7 +5,7 @@ //! Implements sequential traversals over the DOM and flow trees. use context::{LayoutContext, SharedLayoutContext}; -use flow::{mod, Flow, ImmutableFlowUtils, MutableFlowUtils, PostorderFlowTraversal}; +use flow::{self, Flow, ImmutableFlowUtils, MutableFlowUtils, PostorderFlowTraversal}; use flow::{PreorderFlowTraversal}; use flow_ref::FlowRef; use fragment::FragmentBorderBoxIterator; @@ -59,7 +59,7 @@ pub fn traverse_flow_tree_preorder(root: &mut FlowRef, let layout_context = LayoutContext::new(shared_layout_context); - let root = root.deref_mut(); + let root = &mut **root; if opts::get().bubble_inline_sizes_separately { let bubble_inline_sizes = BubbleISizes { layout_context: &layout_context }; @@ -94,7 +94,7 @@ pub fn build_display_list_for_subtree(root: &mut FlowRef, let compute_absolute_positions = ComputeAbsolutePositions { layout_context: &layout_context }; let build_display_list = BuildDisplayList { layout_context: &layout_context }; - doit(root.deref_mut(), compute_absolute_positions, build_display_list); + doit(&mut **root, compute_absolute_positions, build_display_list); } pub fn iterate_through_flow_tree_fragment_border_boxes(root: &mut FlowRef, @@ -117,5 +117,5 @@ pub fn iterate_through_flow_tree_fragment_border_boxes(root: &mut FlowRef, } } - doit(root.deref_mut(), iterator, &ZERO_POINT); + doit(&mut **root, iterator, &ZERO_POINT); } diff --git a/components/layout/table.rs b/components/layout/table.rs index 0dd9f9caa08..533d5166dbd 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -11,7 +11,7 @@ use block::{ISizeConstraintInput, ISizeConstraintSolution}; use construct::FlowConstructor; use context::LayoutContext; use floats::FloatKind; -use flow::{mod, Flow, FlowClass, IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS}; +use flow::{self, Flow, FlowClass, IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS}; use flow::ImmutableFlowUtils; use fragment::{Fragment, FragmentBorderBoxIterator}; use layout_debug; @@ -32,7 +32,7 @@ use std::sync::Arc; /// A table flow corresponded to the table's internal table fragment under a table wrapper flow. /// The properties `position`, `float`, and `margin-*` are used on the table wrapper fragment, /// not table fragment per CSS 2.1 § 10.5. -#[deriving(Encodable)] +#[derive(RustcEncodable)] pub struct TableFlow { pub block_flow: BlockFlow, @@ -399,7 +399,7 @@ impl Flow for TableFlow { impl fmt::Show for TableFlow { /// Outputs a debugging string describing this table flow. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "TableFlow: {}", self.block_flow) + write!(f, "TableFlow: {:?}", self.block_flow) } } @@ -441,7 +441,7 @@ impl ISizeAndMarginsComputer for InternalTable { /// maximum of 100 pixels and 20% of the table), the preceding constraint means that we must /// potentially store both a specified width *and* a specified percentage, so that the inline-size /// assignment phase of layout will know which one to pick. -#[deriving(Clone, Encodable, Show, Copy)] +#[derive(Clone, RustcEncodable, Show, Copy)] pub struct ColumnIntrinsicInlineSize { /// The preferred intrinsic inline size. pub preferred: Au, @@ -485,7 +485,7 @@ impl ColumnIntrinsicInlineSize { /// /// TODO(pcwalton): There will probably be some `border-collapse`-related info in here too /// eventually. -#[deriving(Encodable, Copy)] +#[derive(RustcEncodable, Copy)] pub struct ColumnComputedInlineSize { /// The computed size of this inline column. pub size: Au, diff --git a/components/layout/table_caption.rs b/components/layout/table_caption.rs index 938bfa0e0d2..d45bd50e91b 100644 --- a/components/layout/table_caption.rs +++ b/components/layout/table_caption.rs @@ -95,6 +95,6 @@ impl Flow for TableCaptionFlow { impl fmt::Show for TableCaptionFlow { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "TableCaptionFlow: {}", self.block_flow) + write!(f, "TableCaptionFlow: {:?}", self.block_flow) } } diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs index 89eea551c73..c80a4135f9f 100644 --- a/components/layout/table_cell.rs +++ b/components/layout/table_cell.rs @@ -22,7 +22,7 @@ use style::{UnsignedIntegerAttribute, ComputedValues}; use std::sync::Arc; /// A table formatting context. -#[deriving(Encodable)] +#[derive(RustcEncodable)] pub struct TableCellFlow { /// Data common to all block flows. pub block_flow: BlockFlow, @@ -176,6 +176,6 @@ impl Flow for TableCellFlow { impl fmt::Show for TableCellFlow { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "TableCellFlow: {}", self.block_flow) + write!(f, "TableCellFlow: {:?}", self.block_flow) } } diff --git a/components/layout/table_colgroup.rs b/components/layout/table_colgroup.rs index 648c1ae125c..f828bcc658a 100644 --- a/components/layout/table_colgroup.rs +++ b/components/layout/table_colgroup.rs @@ -109,7 +109,7 @@ impl Flow for TableColGroupFlow { impl fmt::Show for TableColGroupFlow { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.fragment { - Some(ref rb) => write!(f, "TableColGroupFlow: {}", rb), + Some(ref rb) => write!(f, "TableColGroupFlow: {:?}", rb), None => write!(f, "TableColGroupFlow"), } } diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index 55bc3634efa..eb06b31cfec 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -27,7 +27,7 @@ use style::computed_values::LengthOrPercentageOrAuto; use std::sync::Arc; /// A single row of a table. -#[deriving(Encodable)] +#[derive(RustcEncodable)] pub struct TableRowFlow { pub block_flow: BlockFlow, @@ -39,7 +39,7 @@ pub struct TableRowFlow { } /// Information about the column inline size and span for each cell. -#[deriving(Encodable, Copy)] +#[derive(RustcEncodable, Copy)] pub struct CellIntrinsicInlineSize { /// Inline sizes that this cell contributes to the column. pub column_size: ColumnIntrinsicInlineSize, @@ -329,6 +329,6 @@ impl Flow for TableRowFlow { impl fmt::Show for TableRowFlow { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "TableRowFlow: {}", self.block_flow.fragment) + write!(f, "TableRowFlow: {:?}", self.block_flow.fragment) } } diff --git a/components/layout/table_rowgroup.rs b/components/layout/table_rowgroup.rs index 80647a01a77..00a0f23c1b5 100644 --- a/components/layout/table_rowgroup.rs +++ b/components/layout/table_rowgroup.rs @@ -22,7 +22,7 @@ use style::ComputedValues; use std::sync::Arc; /// A table formatting context. -#[deriving(Encodable)] +#[derive(RustcEncodable)] pub struct TableRowGroupFlow { /// Fields common to all block flows. pub block_flow: BlockFlow, @@ -164,6 +164,6 @@ impl Flow for TableRowGroupFlow { impl fmt::Show for TableRowGroupFlow { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "TableRowGroupFlow: {}", self.block_flow.fragment) + write!(f, "TableRowGroupFlow: {:?}", self.block_flow.fragment) } } diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs index d696de85ddc..6cb69a8b216 100644 --- a/components/layout/table_wrapper.rs +++ b/components/layout/table_wrapper.rs @@ -27,18 +27,19 @@ use geom::{Point2D, Rect}; use servo_util::geometry::Au; use std::cmp::{max, min}; use std::fmt; +use std::ops::Add; use style::{ComputedValues, CSSFloat}; use style::computed_values::{table_layout, LengthOrPercentageOrAuto}; use std::sync::Arc; -#[deriving(Copy, Encodable, Show)] +#[derive(Copy, RustcEncodable, Show)] pub enum TableLayout { Fixed, Auto } /// A table wrapper flow based on a block formatting context. -#[deriving(Encodable)] +#[derive(RustcEncodable)] pub struct TableWrapperFlow { pub block_flow: BlockFlow, @@ -144,11 +145,11 @@ impl TableWrapperFlow { // Compute all the guesses for the column sizes, and sum them. let mut total_guess = AutoLayoutCandidateGuess::new(); let guesses: Vec<AutoLayoutCandidateGuess> = - self.column_intrinsic_inline_sizes.iter().map(|column_intrinsic_inline_size| { + self.column_intrinsic_inline_sizes.iter().map(|&mut:column_intrinsic_inline_size| { let guess = AutoLayoutCandidateGuess::from_column_intrinsic_inline_size( column_intrinsic_inline_size, available_inline_size); - total_guess = total_guess + guess; + total_guess = &total_guess + &guess; guess }).collect(); @@ -383,9 +384,9 @@ impl Flow for TableWrapperFlow { impl fmt::Show for TableWrapperFlow { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.block_flow.base.flags.is_float() { - write!(f, "TableWrapperFlow(Float): {}", self.block_flow.fragment) + write!(f, "TableWrapperFlow(Float): {:?}", self.block_flow.fragment) } else { - write!(f, "TableWrapperFlow: {}", self.block_flow.fragment) + write!(f, "TableWrapperFlow: {:?}", self.block_flow.fragment) } } } @@ -482,9 +483,10 @@ impl AutoLayoutCandidateGuess { } } -impl Add<AutoLayoutCandidateGuess,AutoLayoutCandidateGuess> for AutoLayoutCandidateGuess { +impl<'a> Add for &'a AutoLayoutCandidateGuess { + type Output = AutoLayoutCandidateGuess; #[inline] - fn add(&self, other: &AutoLayoutCandidateGuess) -> AutoLayoutCandidateGuess { + fn add(self, other: &AutoLayoutCandidateGuess) -> AutoLayoutCandidateGuess { AutoLayoutCandidateGuess { minimum_guess: self.minimum_guess + other.minimum_guess, minimum_percentage_guess: @@ -497,7 +499,7 @@ impl Add<AutoLayoutCandidateGuess,AutoLayoutCandidateGuess> for AutoLayoutCandid /// The `CSSFloat` member specifies the weight of the smaller of the two guesses, on a scale from /// 0.0 to 1.0. -#[deriving(Copy, PartialEq, Show)] +#[derive(Copy, PartialEq, Show)] enum SelectedAutoLayoutCandidateGuess { UseMinimumGuess, InterpolateBetweenMinimumGuessAndMinimumPercentageGuess(CSSFloat), diff --git a/components/layout/text.rs b/components/layout/text.rs index f57aee50f7b..ca23fdc12de 100644 --- a/components/layout/text.rs +++ b/components/layout/text.rs @@ -14,7 +14,7 @@ use gfx::font::{RunMetrics, ShapingFlags, ShapingOptions}; use gfx::font_context::FontContext; use gfx::text::glyph::CharIndex; use gfx::text::text_run::TextRun; -use gfx::text::util::{mod, CompressionMode}; +use gfx::text::util::{self, CompressionMode}; use servo_util::dlist; use servo_util::geometry::Au; use servo_util::logical_geometry::{LogicalSize, WritingMode}; @@ -138,7 +138,7 @@ impl TextRunScanner { }; let mut new_line_pos = Vec::new(); - let old_length = CharIndex(run_text.as_slice().char_len() as int); + let old_length = CharIndex(run_text.chars().count() as int); last_whitespace = util::transform_text(in_fragment.as_slice(), compression, last_whitespace, @@ -146,7 +146,7 @@ impl TextRunScanner { &mut new_line_pos); new_line_positions.push(NewLinePositions(new_line_pos)); - let added_chars = CharIndex(run_text.as_slice().char_len() as int) - old_length; + let added_chars = CharIndex(run_text.chars().count() as int) - old_length; new_ranges.push(Range::new(char_total, added_chars)); char_total = char_total + added_chars; } @@ -195,13 +195,13 @@ impl TextRunScanner { let range = *new_ranges.get(logical_offset); if range.is_empty() { debug!("Elided an `SpecificFragmentInfo::UnscannedText` because it was zero-length after \ - compression; {}", + compression; {:?}", old_fragment); continue } let text_size = old_fragment.border_box.size; - let &NewLinePositions(ref mut new_line_positions) = + let &mut NewLinePositions(ref mut new_line_positions) = new_line_positions.get_mut(logical_offset); let new_text_fragment_info = box ScannedTextFragmentInfo::new(run.clone(), diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index bafd242fc31..c76c654dcf5 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -48,7 +48,7 @@ type Generation = uint; /// Since a work-stealing queue is used for styling, sometimes, the bloom filter /// will no longer be the for the parent of the node we're currently on. When /// this happens, the task local bloom filter will be thrown away and rebuilt. -thread_local!(static STYLE_BLOOM: RefCell<Option<(Box<BloomFilter>, UnsafeLayoutNode, Generation)>> = RefCell::new(None)) +thread_local!(static STYLE_BLOOM: RefCell<Option<(Box<BloomFilter>, UnsafeLayoutNode, Generation)>> = RefCell::new(None)); /// Returns the task local bloom filter. /// @@ -74,7 +74,7 @@ fn take_task_local_bloom_filter(parent_node: Option<LayoutNode>, layout_context: // Hey, the cached parent is our parent! We can reuse the bloom filter. if old_node == layout_node_to_unsafe_layout_node(&parent) && old_generation == layout_context.shared.generation { - debug!("[{}] Parent matches (={}). Reusing bloom filter.", tid(), old_node.val0()); + debug!("[{}] Parent matches (={}). Reusing bloom filter.", tid(), old_node.0); bloom_filter.clone() } else { // Oh no. the cached parent is stale. I guess we need a new one. Reuse the existing @@ -120,7 +120,7 @@ fn insert_ancestors_into_bloom_filter(bf: &mut Box<BloomFilter>, /// The recalc-style-for-node traversal, which styles each node and must run before /// layout computation. This computes the styles applied to each node. -#[deriving(Copy)] +#[derive(Copy)] pub struct RecalcStyleForNode<'a> { pub layout_context: &'a LayoutContext<'a>, } @@ -200,7 +200,7 @@ impl<'a> PreorderDomTraversal for RecalcStyleForNode<'a> { // Before running the children, we need to insert our nodes into the bloom // filter. - debug!("[{}] + {:X}", tid(), unsafe_layout_node.val0()); + debug!("[{}] + {:X}", tid(), unsafe_layout_node.0); node.insert_into_bloom_filter(&mut *bf); // NB: flow construction updates the bloom filter on the way up. @@ -209,7 +209,7 @@ impl<'a> PreorderDomTraversal for RecalcStyleForNode<'a> { } /// The flow construction traversal, which builds flows for styled nodes. -#[deriving(Copy)] +#[derive(Copy)] pub struct ConstructFlows<'a> { pub layout_context: &'a LayoutContext<'a>, } @@ -258,7 +258,7 @@ impl<'a> PostorderDomTraversal for ConstructFlows<'a> { match node.layout_parent_node(self.layout_context.shared) { None => { - debug!("[{}] - {:X}, and deleting BF.", tid(), unsafe_layout_node.val0()); + debug!("[{}] - {:X}, and deleting BF.", tid(), unsafe_layout_node.0); // If this is the reflow root, eat the task-local bloom filter. } Some(parent) => { @@ -308,7 +308,7 @@ impl<'a> PostorderFlowTraversal for BubbleISizes<'a> { } /// The assign-inline-sizes traversal. In Gecko this corresponds to `Reflow`. -#[deriving(Copy)] +#[derive(Copy)] pub struct AssignISizes<'a> { pub layout_context: &'a LayoutContext<'a>, } @@ -329,7 +329,7 @@ impl<'a> PreorderFlowTraversal for AssignISizes<'a> { /// layout computation. Determines the final block-sizes for all layout objects, computes /// positions, and computes overflow regions. In Gecko this corresponds to `Reflow` and /// `FinishAndStoreOverflow`. -#[deriving(Copy)] +#[derive(Copy)] pub struct AssignBSizesAndStoreOverflow<'a> { pub layout_context: &'a LayoutContext<'a>, } @@ -354,7 +354,7 @@ impl<'a> PostorderFlowTraversal for AssignBSizesAndStoreOverflow<'a> { } } -#[deriving(Copy)] +#[derive(Copy)] pub struct ComputeAbsolutePositions<'a> { pub layout_context: &'a LayoutContext<'a>, } @@ -366,7 +366,7 @@ impl<'a> PreorderFlowTraversal for ComputeAbsolutePositions<'a> { } } -#[deriving(Copy)] +#[derive(Copy)] pub struct BuildDisplayList<'a> { pub layout_context: &'a LayoutContext<'a>, } diff --git a/components/layout/util.rs b/components/layout/util.rs index 0ba105f20fa..206590d7c23 100644 --- a/components/layout/util.rs +++ b/components/layout/util.rs @@ -64,7 +64,6 @@ impl PrivateLayoutData { } bitflags! { - #[deriving(Copy)] flags LayoutDataFlags: u8 { #[doc="Whether a flow has been newly constructed."] const HAS_NEWLY_CONSTRUCTED_FLOW = 0x01 @@ -77,6 +76,14 @@ pub struct LayoutDataWrapper { pub data: Box<PrivateLayoutData>, } +#[allow(dead_code)] +fn static_assertion(x: Option<LayoutDataWrapper>) { + unsafe { + let _: Option<::script::dom::node::LayoutData> = + ::std::intrinsics::transmute(x); + } +} + /// A trait that allows access to the layout data of a DOM node. pub trait LayoutDataAccess { /// Borrows the layout data without checks. diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index 1dd4be42288..d54af90014a 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -49,8 +49,8 @@ use script::dom::htmlelement::HTMLElementTypeId; use script::dom::htmlcanvaselement::{HTMLCanvasElement, LayoutHTMLCanvasElementHelpers}; use script::dom::htmliframeelement::HTMLIFrameElement; use script::dom::htmlimageelement::LayoutHTMLImageElementHelpers; -use script::dom::htmlinputelement::LayoutHTMLInputElementHelpers; -use script::dom::htmltextareaelement::LayoutHTMLTextAreaElementHelpers; +use script::dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers}; +use script::dom::htmltextareaelement::{HTMLTextAreaElement, LayoutHTMLTextAreaElementHelpers}; use script::dom::node::{Node, NodeTypeId}; use script::dom::node::{LayoutNodeHelpers, RawLayoutNodeHelpers, SharedLayoutData}; use script::dom::node::{HAS_CHANGED, IS_DIRTY, HAS_DIRTY_SIBLINGS, HAS_DIRTY_DESCENDANTS}; @@ -58,8 +58,9 @@ use script::dom::text::Text; use script::layout_interface::LayoutChan; use servo_msg::constellation_msg::{PipelineId, SubpageId}; use servo_util::str::{LengthOrPercentageOrAuto, is_whitespace}; -use std::kinds::marker::ContravariantLifetime; +use std::marker::ContravariantLifetime; use std::mem; +use std::sync::mpsc::Sender; use string_cache::{Atom, Namespace}; use style::computed_values::{content, display, white_space}; use style::{NamespaceConstraint, AttrSelector, IntegerAttribute}; @@ -67,6 +68,7 @@ use style::{LengthAttribute, PropertyDeclarationBlock, SimpleColorAttribute}; use style::{TElement, TElementAttributes, TNode, UnsignedIntegerAttribute}; use url::Url; +use std::borrow::ToOwned; use std::cell::{Ref, RefMut}; /// Allows some convenience methods on generic layout nodes. @@ -160,7 +162,7 @@ pub trait TLayoutNode { /// A wrapper so that layout can access only the methods that it should have access to. Layout must /// only ever see these and must never see instances of `JS`. -#[deriving(Copy)] +#[derive(Copy)] pub struct LayoutNode<'a> { /// The wrapped node. node: JS<Node>, @@ -211,15 +213,20 @@ impl<'ln> TLayoutNode for LayoutNode<'ln> { fn text(&self) -> String { unsafe { - if let Some(text) = TextCast::to_js(self.get_jsmanaged()) { - (*text.unsafe_get()).characterdata().data_for_layout().into_string() - } else if let Some(input) = HTMLInputElementCast::to_js(self.get_jsmanaged()) { - input.get_value_for_layout() - } else if let Some(area) = HTMLTextAreaElementCast::to_js(self.get_jsmanaged()) { - area.get_value_for_layout() - } else { - panic!("not text!") + let text: Option<JS<Text>> = TextCast::to_js(self.get_jsmanaged()); + if let Some(text) = text { + return (*text.unsafe_get()).characterdata().data_for_layout().to_owned(); + } + let input: Option<JS<HTMLInputElement>> = HTMLInputElementCast::to_js(self.get_jsmanaged()); + if let Some(input) = input { + return input.get_value_for_layout(); } + let area: Option<JS<HTMLTextAreaElement>> = HTMLTextAreaElementCast::to_js(self.get_jsmanaged()); + if let Some(area) = area { + return area.get_value_for_layout(); + } + + panic!("not text!") } } } @@ -244,7 +251,7 @@ impl<'ln> LayoutNode<'ln> { } fn debug_str(self) -> String { - format!("{}: changed={} dirty={} dirty_descendants={}", + format!("{:?}: changed={} dirty={} dirty_descendants={}", self.type_id(), self.has_changed(), self.is_dirty(), self.has_dirty_descendants()) } @@ -324,7 +331,7 @@ impl<'ln> LayoutNode<'ln> { pub fn debug_id(self) -> uint { let opaque: OpaqueNode = OpaqueNodeMethods::from_layout_node(&self); - opaque.to_untrusted_node_address() as uint + opaque.to_untrusted_node_address().0 as uint } } @@ -368,10 +375,8 @@ impl<'ln> TNode<'ln, LayoutElement<'ln>> for LayoutNode<'ln> { None => panic!("not an element") }; - let element = &*elem.unsafe_get(); - LayoutElement { - element: mem::transmute(element), + element: &*elem.unsafe_get(), } } } @@ -384,8 +389,8 @@ impl<'ln> TNode<'ln, LayoutElement<'ln>> for LayoutNode<'ln> { self.node_is_document() } - fn match_attr(self, attr: &AttrSelector, test: |&str| -> bool) -> bool { - assert!(self.is_element()) + fn match_attr<F>(self, attr: &AttrSelector, test: F) -> bool where F: Fn(&str) -> bool { + assert!(self.is_element()); let name = if self.is_html_element_in_html_document() { &attr.lower_name } else { @@ -449,7 +454,8 @@ pub struct LayoutNodeChildrenIterator<'a> { current: Option<LayoutNode<'a>>, } -impl<'a> Iterator<LayoutNode<'a>> for LayoutNodeChildrenIterator<'a> { +impl<'a> Iterator for LayoutNodeChildrenIterator<'a> { + type Item = LayoutNode<'a>; fn next(&mut self) -> Option<LayoutNode<'a>> { let node = self.current; self.current = node.and_then(|node| node.next_sibling()); @@ -461,7 +467,8 @@ pub struct LayoutNodeReverseChildrenIterator<'a> { current: Option<LayoutNode<'a>>, } -impl<'a> Iterator<LayoutNode<'a>> for LayoutNodeReverseChildrenIterator<'a> { +impl<'a> Iterator for LayoutNodeReverseChildrenIterator<'a> { + type Item = LayoutNode<'a>; fn next(&mut self) -> Option<LayoutNode<'a>> { let node = self.current; self.current = node.and_then(|node| node.prev_sibling()); @@ -483,7 +490,8 @@ impl<'a> LayoutTreeIterator<'a> { } } -impl<'a> Iterator<LayoutNode<'a>> for LayoutTreeIterator<'a> { +impl<'a> Iterator for LayoutTreeIterator<'a> { + type Item = LayoutNode<'a>; fn next(&mut self) -> Option<LayoutNode<'a>> { let ret = self.stack.pop(); ret.map(|node| self.stack.extend(node.rev_children())); @@ -492,7 +500,7 @@ impl<'a> Iterator<LayoutNode<'a>> for LayoutTreeIterator<'a> { } /// A wrapper around elements that ensures layout can only ever access safe properties. -#[deriving(Copy)] +#[derive(Copy)] pub struct LayoutElement<'le> { element: &'le Element, } @@ -531,7 +539,8 @@ impl<'le> TElement<'le> for LayoutElement<'le> { fn get_link(self) -> Option<&'le str> { // FIXME: This is HTML only. - match NodeCast::from_actual(self.element).type_id_for_layout() { + let node: &Node = NodeCast::from_actual(self.element); + match node.type_id_for_layout() { // http://www.whatwg.org/specs/web-apps/current-work/multipage/selectors.html# // selector-link NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) | @@ -548,7 +557,8 @@ impl<'le> TElement<'le> for LayoutElement<'le> { #[inline] fn get_hover_state(self) -> bool { unsafe { - NodeCast::from_actual(self.element).get_hover_state_for_layout() + let node: &Node = NodeCast::from_actual(self.element); + node.get_hover_state_for_layout() } } @@ -562,14 +572,16 @@ impl<'le> TElement<'le> for LayoutElement<'le> { #[inline] fn get_disabled_state(self) -> bool { unsafe { - NodeCast::from_actual(self.element).get_disabled_state_for_layout() + let node: &Node = NodeCast::from_actual(self.element); + node.get_disabled_state_for_layout() } } #[inline] fn get_enabled_state(self) -> bool { unsafe { - NodeCast::from_actual(self.element).get_enabled_state_for_layout() + let node: &Node = NodeCast::from_actual(self.element); + node.get_enabled_state_for_layout() } } @@ -595,7 +607,7 @@ impl<'le> TElement<'le> for LayoutElement<'le> { } #[inline(always)] - fn each_class(self, callback: |&Atom|) { + fn each_class<F>(self, mut callback: F) where F: FnMut(&Atom) { unsafe { match self.element.get_classes_for_layout() { None => {} @@ -652,14 +664,14 @@ fn get_content(content_list: &content::T) -> String { let iter = &mut value.clone().into_iter().peekable(); match iter.next() { Some(content::ContentItem::StringContent(content)) => content, - _ => "".into_string(), + _ => "".to_owned(), } } - _ => "".into_string(), + _ => "".to_owned(), } } -#[deriving(Copy, PartialEq, Clone)] +#[derive(Copy, PartialEq, Clone)] pub enum PseudoElementType { Normal, Before(display::T), @@ -684,7 +696,7 @@ impl PseudoElementType { /// A thread-safe version of `LayoutNode`, used during flow construction. This type of layout /// node does not allow any parents or siblings of nodes to be accessed, to avoid races. -#[deriving(Copy, Clone)] +#[derive(Copy, Clone)] pub struct ThreadSafeLayoutNode<'ln> { /// The wrapped node. node: LayoutNode<'ln>, @@ -718,7 +730,7 @@ impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> { } unsafe fn get<'a>(&'a self) -> &'a Node { // this change. - mem::transmute::<*mut Node,&'a Node>(self.get_jsmanaged().unsafe_get()) + &*self.get_jsmanaged().unsafe_get() } fn first_child(&self) -> Option<ThreadSafeLayoutNode<'ln>> { @@ -818,7 +830,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { // FIXME(pcwalton): Workaround until Rust gets multiple lifetime parameters on // implementations. ThreadSafeLayoutElement { - element: &mut *element, + element: &*element, } } } @@ -947,7 +959,8 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { pub fn get_input_value(&self) -> String { unsafe { - match HTMLInputElementCast::to_js(self.get_jsmanaged()) { + let input: Option<JS<HTMLInputElement>> = HTMLInputElementCast::to_js(self.get_jsmanaged()); + match input { Some(input) => input.get_value_for_layout(), None => panic!("not an input element!") } @@ -966,7 +979,8 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { pub fn get_unsigned_integer_attribute(self, attribute: UnsignedIntegerAttribute) -> Option<u32> { unsafe { - match ElementCast::to_js(self.get_jsmanaged()) { + let elem: Option<JS<Element>> = ElementCast::to_js(self.get_jsmanaged()); + match elem { Some(element) => { (*element.unsafe_get()).get_unsigned_integer_attribute_for_layout(attribute) } @@ -986,7 +1000,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { pub fn set_restyle_damage(self, damage: RestyleDamage) { let mut layout_data_ref = self.mutate_layout_data(); match &mut *layout_data_ref { - &Some(ref mut layout_data) => layout_data.data.restyle_damage = damage, + &mut Some(ref mut layout_data) => layout_data.data.restyle_damage = damage, _ => panic!("no layout data for this node"), } } @@ -1005,7 +1019,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { pub fn insert_flags(self, new_flags: LayoutDataFlags) { let mut layout_data_ref = self.mutate_layout_data(); match &mut *layout_data_ref { - &Some(ref mut layout_data) => layout_data.data.flags.insert(new_flags), + &mut Some(ref mut layout_data) => layout_data.data.flags.insert(new_flags), _ => panic!("no layout data for this node"), } } @@ -1014,7 +1028,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { pub fn remove_flags(self, flags: LayoutDataFlags) { let mut layout_data_ref = self.mutate_layout_data(); match &mut *layout_data_ref { - &Some(ref mut layout_data) => layout_data.data.flags.remove(flags), + &mut Some(ref mut layout_data) => layout_data.data.flags.remove(flags), _ => panic!("no layout data for this node"), } } @@ -1034,7 +1048,8 @@ pub struct ThreadSafeLayoutNodeChildrenIterator<'a> { parent_node: Option<ThreadSafeLayoutNode<'a>>, } -impl<'a> Iterator<ThreadSafeLayoutNode<'a>> for ThreadSafeLayoutNodeChildrenIterator<'a> { +impl<'a> Iterator for ThreadSafeLayoutNodeChildrenIterator<'a> { + type Item = ThreadSafeLayoutNode<'a>; fn next(&mut self) -> Option<ThreadSafeLayoutNode<'a>> { let node = self.current_node.clone(); diff --git a/components/layout_traits/lib.rs b/components/layout_traits/lib.rs index 178861d7a93..fd3ecd541f9 100644 --- a/components/layout_traits/lib.rs +++ b/components/layout_traits/lib.rs @@ -24,7 +24,7 @@ use servo_net::image_cache_task::ImageCacheTask; use servo_net::resource_task::ResourceTask; use servo_util::time::TimeProfilerChan; use script_traits::{ScriptControlChan, OpaqueScriptLayoutChannel}; -use std::comm::Sender; +use std::sync::mpsc::{Sender, Receiver}; /// Messages sent to the layout task from the constellation pub enum LayoutControlMsg { diff --git a/components/msg/Cargo.toml b/components/msg/Cargo.toml index 460a277a7a7..2bd553491d9 100644 --- a/components/msg/Cargo.toml +++ b/components/msg/Cargo.toml @@ -33,5 +33,5 @@ git = "https://github.com/servo/rust-core-foundation" [dependencies.io_surface] git = "https://github.com/servo/rust-io-surface" -[dependencies.url] -git = "https://github.com/servo/rust-url" +[dependencies] +url = "*"
\ No newline at end of file diff --git a/components/msg/compositor_msg.rs b/components/msg/compositor_msg.rs index a2e3c4d1909..111636c349c 100644 --- a/components/msg/compositor_msg.rs +++ b/components/msg/compositor_msg.rs @@ -14,13 +14,13 @@ use std::fmt; use constellation_msg::PipelineId; /// The status of the painter. -#[deriving(PartialEq, Eq, Clone, Copy)] +#[derive(PartialEq, Eq, Clone, Copy)] pub enum PaintState { Idle, Painting, } -#[deriving(Eq, Ord, PartialEq, PartialOrd, Clone, Show, Copy)] +#[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Show, Copy)] pub enum ReadyState { /// Informs the compositor that nothing has been done yet. Used for setting status Blank, @@ -33,7 +33,7 @@ pub enum ReadyState { } /// A newtype struct for denoting the age of messages; prevents race conditions. -#[deriving(PartialEq, Eq, Show, Copy)] +#[derive(PartialEq, Eq, Show, Copy)] pub struct Epoch(pub uint); impl Epoch { @@ -43,7 +43,7 @@ impl Epoch { } } -#[deriving(Clone, PartialEq, Eq, Copy)] +#[derive(Clone, PartialEq, Eq, Copy)] pub struct LayerId(pub uint, pub uint); impl Show for LayerId { @@ -61,7 +61,7 @@ impl LayerId { } /// The scrolling policy of a layer. -#[deriving(Clone, PartialEq, Eq, Copy)] +#[derive(Clone, PartialEq, Eq, Copy)] pub enum ScrollPolicy { /// These layers scroll when the parent receives a scrolling message. Scrollable, @@ -71,7 +71,7 @@ pub enum ScrollPolicy { /// All layer-specific information that the painting task sends to the compositor other than the /// buffer contents of the layer itself. -#[deriving(Copy)] +#[derive(Copy)] pub struct LayerMetadata { /// An opaque ID. This is usually the address of the flow and index of the box within it. pub id: LayerId, @@ -85,7 +85,7 @@ pub struct LayerMetadata { /// The interface used by the painter to acquire draw targets for each paint frame and /// submit them to be drawn to the display. -pub trait PaintListener for Sized? { +pub trait PaintListener { fn get_graphics_metadata(&mut self) -> Option<NativeGraphicsMetadata>; /// Informs the compositor of the layers for the given pipeline. The compositor responds by diff --git a/components/msg/constellation_msg.rs b/components/msg/constellation_msg.rs index 5cd2a0cce39..658fb6a4e71 100644 --- a/components/msg/constellation_msg.rs +++ b/components/msg/constellation_msg.rs @@ -13,10 +13,10 @@ use hyper::method::Method; use layers::geometry::DevicePixel; use servo_util::cursor::Cursor; use servo_util::geometry::{PagePx, ViewportPx}; -use std::comm::{channel, Sender, Receiver}; +use std::sync::mpsc::{channel, Sender, Receiver}; use url::Url; -#[deriving(Clone)] +#[derive(Clone)] pub struct ConstellationChan(pub Sender<Msg>); impl ConstellationChan { @@ -26,20 +26,20 @@ impl ConstellationChan { } } -#[deriving(PartialEq, Eq, Copy)] +#[derive(PartialEq, Eq, Copy)] pub enum IFrameSandboxState { IFrameSandboxed, IFrameUnsandboxed } // We pass this info to various tasks, so it lives in a separate, cloneable struct. -#[deriving(Clone, Copy)] +#[derive(Clone, Copy)] pub struct Failure { pub pipeline_id: PipelineId, pub subpage_id: Option<SubpageId>, } -#[deriving(Copy)] +#[derive(Copy)] pub struct WindowSizeData { /// The size of the initial layout viewport, before parsing an /// http://www.w3.org/TR/css-device-adapt/#initial-viewport @@ -52,7 +52,7 @@ pub struct WindowSizeData { pub device_pixel_ratio: ScaleFactor<ViewportPx, DevicePixel, f32>, } -#[deriving(PartialEq, Eq, Copy, Clone)] +#[derive(PartialEq, Eq, Copy, Clone)] pub enum KeyState { Pressed, Released, @@ -60,7 +60,7 @@ pub enum KeyState { } //N.B. Straight up copied from glfw-rs -#[deriving(Show, PartialEq, Eq, Copy, Clone)] +#[derive(Show, PartialEq, Eq, Copy, Clone)] pub enum Key { Space, Apostrophe, @@ -186,7 +186,6 @@ pub enum Key { } bitflags! { - #[deriving(Copy)] flags KeyModifiers: u8 { const SHIFT = 0x01, const CONTROL = 0x02, @@ -218,7 +217,7 @@ pub enum Msg { /// Similar to net::resource_task::LoadData /// can be passed to LoadUrl to load a page with GET/POST /// parameters or headers -#[deriving(Clone)] +#[derive(Clone)] pub struct LoadData { pub url: Url, pub method: Method, @@ -238,27 +237,27 @@ impl LoadData { } /// Represents the two different ways to which a page can be navigated -#[deriving(Clone, PartialEq, Eq, Copy, Hash, Show)] +#[derive(Clone, PartialEq, Eq, Copy, Hash, Show)] pub enum NavigationType { Load, // entered or clicked on a url Navigate, // browser forward/back buttons } -#[deriving(Clone, PartialEq, Eq, Copy, Hash, Show)] +#[derive(Clone, PartialEq, Eq, Copy, Hash, Show)] pub enum NavigationDirection { Forward, Back, } -#[deriving(Clone, PartialEq, Eq, Copy, Hash, Show)] +#[derive(Clone, PartialEq, Eq, Copy, Hash, Show)] pub struct PipelineId(pub uint); -#[deriving(Clone, PartialEq, Eq, Copy, Hash, Show)] +#[derive(Clone, PartialEq, Eq, Copy, Hash, Show)] pub struct SubpageId(pub uint); // The type of pipeline exit. During complete shutdowns, pipelines do not have to // release resources automatically released on process termination. -#[deriving(Copy)] +#[derive(Copy)] pub enum PipelineExitType { PipelineOnly, Complete, diff --git a/components/msg/lib.rs b/components/msg/lib.rs index 234fba05361..ba02ce8babd 100644 --- a/components/msg/lib.rs +++ b/components/msg/lib.rs @@ -2,6 +2,8 @@ * 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/. */ +#![feature(int_uint)] + #![deny(unused_imports)] #![deny(unused_variables)] #![allow(missing_copy_implementations)] diff --git a/components/net/Cargo.toml b/components/net/Cargo.toml index 55d0676a71b..18672a756b9 100644 --- a/components/net/Cargo.toml +++ b/components/net/Cargo.toml @@ -23,8 +23,6 @@ git = "https://github.com/servo/rust-png" [dependencies.stb_image] git = "https://github.com/servo/rust-stb-image" -[dependencies.url] -git = "https://github.com/servo/rust-url" - -[dependencies.time] -git = "https://github.com/rust-lang/time" +[dependencies] +url = "*" +time = "*"
\ No newline at end of file diff --git a/components/net/about_loader.rs b/components/net/about_loader.rs index bedb21b573e..bc87727c768 100644 --- a/components/net/about_loader.rs +++ b/components/net/about_loader.rs @@ -10,7 +10,9 @@ use url::Url; use hyper::http::RawStatus; use servo_util::resource_files::resources_dir_path; +use std::borrow::ToOwned; use std::io::fs::PathExtensions; +use std::sync::mpsc::Sender; pub fn factory(mut load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) { let senders = ResponseSenders { @@ -24,7 +26,7 @@ pub fn factory(mut load_data: LoadData, start_chan: Sender<TargetedLoadResponse> content_type: Some(("text".to_string(), "html".to_string())), charset: Some("utf-8".to_string()), headers: None, - status: Some(RawStatus(200, "OK".into_string())) + status: Some(RawStatus(200, "OK".to_owned())) }); chan.send(Done(Ok(()))); return diff --git a/components/net/data_loader.rs b/components/net/data_loader.rs index b24c58e4b71..da58515a7ad 100644 --- a/components/net/data_loader.rs +++ b/components/net/data_loader.rs @@ -10,6 +10,7 @@ use serialize::base64::FromBase64; use hyper::mime::Mime; use url::{percent_decode, SchemeData}; +use std::sync::mpsc::Sender; pub fn factory(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) { // NB: we don't spawn a new task. @@ -59,7 +60,7 @@ fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) { // Parse the content type using rust-http. // FIXME: this can go into an infinite loop! (rust-http #25) - let content_type: Option<Mime> = from_str(ct_str); + let content_type: Option<Mime> = ct_str.parse(); metadata.set_content_type(content_type.as_ref()); let progress_chan = start_sending(senders, metadata); @@ -89,19 +90,19 @@ fn assert_parse(url: &'static str, content_type: Option<(String, String)>, charset: Option<String>, data: Option<Vec<u8>>) { - use std::comm; + use std::sync::mpsc::channel; use url::Url; use sniffer_task; - let (start_chan, start_port) = comm::channel(); + let (start_chan, start_port) = channel(); let sniffer_task = sniffer_task::new_sniffer_task(); load(LoadData::new(Url::parse(url).unwrap(), start_chan), sniffer_task); - let response = start_port.recv(); + let response = start_port.recv().unwrap(); assert_eq!(&response.metadata.content_type, &content_type); assert_eq!(&response.metadata.charset, &charset); - let progress = response.progress_port.recv(); + let progress = response.progress_port.recv().unwrap(); match data { None => { @@ -109,7 +110,7 @@ fn assert_parse(url: &'static str, } Some(dat) => { assert_eq!(progress, Payload(dat)); - assert_eq!(response.progress_port.recv(), Done(Ok(()))); + assert_eq!(response.progress_port.recv().unwrap(), Done(Ok(()))); } } } diff --git a/components/net/fetch/cors_cache.rs b/components/net/fetch/cors_cache.rs index 23a6a8450e5..e3b79b48c24 100644 --- a/components/net/fetch/cors_cache.rs +++ b/components/net/fetch/cors_cache.rs @@ -11,7 +11,7 @@ use hyper::method::Method; use std::ascii::AsciiExt; -use std::comm::{Sender, Receiver, channel}; +use std::sync::mpsc::{Sender, Receiver, channel}; use time; use time::{now, Timespec}; use url::Url; @@ -19,7 +19,7 @@ use url::Url; /// Union type for CORS cache entries /// /// Each entry might pertain to a header or method -#[deriving(Clone)] +#[derive(Clone)] pub enum HeaderOrMethod { HeaderData(String), MethodData(Method) @@ -42,7 +42,7 @@ impl HeaderOrMethod { } /// An entry in the CORS cache -#[deriving(Clone)] +#[derive(Clone)] pub struct CORSCacheEntry { pub origin: Url, pub url: Url, @@ -100,7 +100,7 @@ pub trait CORSCache { } /// A simple, vector-based CORS Cache -#[deriving(Clone)] +#[derive(Clone)] #[unstable = "This might later be replaced with a HashMap-like entity, though that requires a separate Origin struct"] pub struct BasicCORSCache(Vec<CORSCacheEntry>); @@ -207,43 +207,43 @@ impl CORSCache for CORSCacheSender { fn clear (&mut self, request: CacheRequestDetails) { let (tx, rx) = channel(); self.send(CORSCacheTaskMsg::Clear(request, tx)); - let _ = rx.recv_opt(); + let _ = rx.recv(); } fn cleanup(&mut self) { let (tx, rx) = channel(); self.send(CORSCacheTaskMsg::Cleanup(tx)); - let _ = rx.recv_opt(); + let _ = rx.recv(); } fn match_header(&mut self, request: CacheRequestDetails, header_name: &str) -> bool { let (tx, rx) = channel(); self.send(CORSCacheTaskMsg::MatchHeader(request, header_name.to_string(), tx)); - rx.recv_opt().unwrap_or(false) + rx.recv().unwrap_or(false) } fn match_header_and_update(&mut self, request: CacheRequestDetails, header_name: &str, new_max_age: uint) -> bool { let (tx, rx) = channel(); self.send(CORSCacheTaskMsg::MatchHeaderUpdate(request, header_name.to_string(), new_max_age, tx)); - rx.recv_opt().unwrap_or(false) + rx.recv().unwrap_or(false) } fn match_method(&mut self, request: CacheRequestDetails, method: Method) -> bool { let (tx, rx) = channel(); self.send(CORSCacheTaskMsg::MatchMethod(request, method, tx)); - rx.recv_opt().unwrap_or(false) + rx.recv().unwrap_or(false) } fn match_method_and_update(&mut self, request: CacheRequestDetails, method: Method, new_max_age: uint) -> bool { let (tx, rx) = channel(); self.send(CORSCacheTaskMsg::MatchMethodUpdate(request, method, new_max_age, tx)); - rx.recv_opt().unwrap_or(false) + rx.recv().unwrap_or(false) } fn insert(&mut self, entry: CORSCacheEntry) { let (tx, rx) = channel(); self.send(CORSCacheTaskMsg::Insert(entry, tx)); - let _ = rx.recv_opt(); + let _ = rx.recv(); } } @@ -254,7 +254,7 @@ impl CORSCache for CORSCacheSender { /// let task = CORSCacheTask::new(); /// let builder = TaskBuilder::new().named("XHRTask"); /// let mut sender = task.get_sender(); -/// builder.spawn(proc() { task.run() }); +/// builder.spawn(move || { task.run() }); /// sender.insert(CORSCacheEntry::new(/* parameters here */)); /// ``` pub struct CORSCacheTask { @@ -284,7 +284,7 @@ impl CORSCacheTask { /// Send ExitMsg to the associated Sender to exit pub fn run(&mut self) { loop { - match self.receiver.recv() { + match self.receiver.recv().unwrap() { CORSCacheTaskMsg::Clear(request, tx) => { self.cache.clear(request); tx.send(()); diff --git a/components/net/fetch/request.rs b/components/net/fetch/request.rs index 050ed9b892b..1c7b51566ad 100644 --- a/components/net/fetch/request.rs +++ b/components/net/fetch/request.rs @@ -11,7 +11,7 @@ use fetch::cors_cache::CORSCache; use fetch::response::Response; /// A [request context](http://fetch.spec.whatwg.org/#concept-request-context) -#[deriving(Copy)] +#[derive(Copy)] pub enum Context { Audio, Beacon, CSPreport, Download, Embed, Eventsource, Favicon, Fetch, Font, Form, Frame, Hyperlink, IFrame, Image, @@ -21,7 +21,7 @@ pub enum Context { } /// A [request context frame type](http://fetch.spec.whatwg.org/#concept-request-context-frame-type) -#[deriving(Copy)] +#[derive(Copy)] pub enum ContextFrameType { Auxiliary, TopLevel, @@ -37,7 +37,7 @@ pub enum Referer { } /// A [request mode](http://fetch.spec.whatwg.org/#concept-request-mode) -#[deriving(Copy)] +#[derive(Copy)] pub enum RequestMode { SameOrigin, NoCORS, @@ -46,7 +46,7 @@ pub enum RequestMode { } /// Request [credentials mode](http://fetch.spec.whatwg.org/#concept-request-credentials-mode) -#[deriving(Copy)] +#[derive(Copy)] pub enum CredentialsMode { Omit, CredentialsSameOrigin, @@ -54,7 +54,7 @@ pub enum CredentialsMode { } /// [Response tainting](http://fetch.spec.whatwg.org/#concept-request-response-tainting) -#[deriving(Copy)] +#[derive(Copy)] pub enum ResponseTainting { Basic, CORSTainting, diff --git a/components/net/fetch/response.rs b/components/net/fetch/response.rs index 2c1817de338..7380f3e7ad6 100644 --- a/components/net/fetch/response.rs +++ b/components/net/fetch/response.rs @@ -6,10 +6,10 @@ use url::Url; use hyper::status::StatusCode; use hyper::header::Headers; use std::ascii::AsciiExt; -use std::comm::Receiver; +use std::sync::mpsc::Receiver; /// [Response type](http://fetch.spec.whatwg.org/#concept-response-type) -#[deriving(Clone, PartialEq, Copy)] +#[derive(Clone, PartialEq, Copy)] pub enum ResponseType { Basic, CORS, @@ -19,7 +19,7 @@ pub enum ResponseType { } /// [Response termination reason](http://fetch.spec.whatwg.org/#concept-response-termination-reason) -#[deriving(Clone, Copy)] +#[derive(Clone, Copy)] pub enum TerminationReason { EndUserAbort, Fatal, @@ -29,7 +29,7 @@ pub enum TerminationReason { /// The response body can still be pushed to after fetch /// This provides a way to store unfinished response bodies #[unstable = "I haven't yet decided exactly how the interface for this will be"] -#[deriving(Clone)] +#[derive(Clone)] pub enum ResponseBody { Empty, // XXXManishearth is this necessary, or is Done(vec![]) enough? Receiving(Vec<u8>), @@ -50,7 +50,7 @@ pub struct ResponseLoader { } /// A [Response](http://fetch.spec.whatwg.org/#concept-response) as defined by the Fetch spec -#[deriving(Clone)] +#[derive(Clone)] pub struct Response { pub response_type: ResponseType, pub termination_reason: Option<TerminationReason>, @@ -110,7 +110,7 @@ impl Response { ResponseType::Default | ResponseType::Error => unreachable!(), ResponseType::Basic => { let headers = old_headers.iter().filter(|header| { - match header.name().to_ascii_lower().as_slice() { + match header.name().to_ascii_lowercase().as_slice() { "set-cookie" | "set-cookie2" => false, _ => true } @@ -120,7 +120,7 @@ impl Response { }, ResponseType::CORS => { let headers = old_headers.iter().filter(|header| { - match header.name().to_ascii_lower().as_slice() { + match header.name().to_ascii_lowercase().as_slice() { "cache-control" | "content-language" | "content-type" | "expires" | "last-modified" | "Pragma" => false, // XXXManishearth handle Access-Control-Expose-Headers diff --git a/components/net/file_loader.rs b/components/net/file_loader.rs index aa127f806d6..a2233ff54b8 100644 --- a/components/net/file_loader.rs +++ b/components/net/file_loader.rs @@ -5,8 +5,10 @@ use resource_task::{ProgressMsg, Metadata, LoadData, start_sending, TargetedLoadResponse, ResponseSenders}; use resource_task::ProgressMsg::{Payload, Done}; +use std::borrow::ToOwned; use std::io; use std::io::File; +use std::sync::mpsc::Sender; use servo_util::task::spawn_named; static READ_SIZE: uint = 8192; @@ -16,11 +18,11 @@ fn read_all(reader: &mut io::Stream, progress_chan: &Sender<ProgressMsg>) loop { let mut buf = vec!(); match reader.push_at_least(READ_SIZE, READ_SIZE, &mut buf) { - Ok(_) => progress_chan.send(Payload(buf)), + Ok(_) => progress_chan.send(Payload(buf)).unwrap(), Err(e) => match e.kind { io::EndOfFile => { if buf.len() > 0 { - progress_chan.send(Payload(buf)); + progress_chan.send(Payload(buf)).unwrap(); } return Ok(()); } @@ -38,7 +40,7 @@ pub fn factory(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) { eventual_consumer: load_data.consumer, }; let progress_chan = start_sending(senders, Metadata::default(url.clone())); - spawn_named("file_loader", proc() { + spawn_named("file_loader".to_owned(), move || { let file_path: Result<Path, ()> = url.to_file_path(); match file_path { Ok(file_path) => { diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index d8b909f88f3..5f0877cdaa1 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -11,12 +11,16 @@ use hyper::client::Request; use hyper::header::common::{ContentLength, ContentType, Host, Location}; use hyper::method::Method; use hyper::status::StatusClass; +use std::error::Error; use std::io::Reader; +use std::sync::mpsc::Sender; use servo_util::task::spawn_named; use url::{Url, UrlParser}; +use std::borrow::ToOwned; + pub fn factory(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) { - spawn_named("http_loader", proc() load(load_data, start_chan)) + spawn_named("http_loader".to_owned(), move || load(load_data, start_chan)) } fn send_error(url: Url, err: String, senders: ResponseSenders) { @@ -24,7 +28,7 @@ fn send_error(url: Url, err: String, senders: ResponseSenders) { metadata.status = None; match start_sending_opt(senders, metadata) { - Ok(p) => p.send(Done(Err(err))), + Ok(p) => p.send(Done(Err(err))).unwrap(), _ => {} }; } @@ -73,7 +77,7 @@ fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) { let mut req = match Request::new(load_data.method.clone(), url.clone()) { Ok(req) => req, Err(e) => { - send_error(url, e.to_string(), senders); + send_error(url, e.description().to_string(), senders); return; } }; @@ -85,15 +89,15 @@ fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) { // FIXME(seanmonstar): use AcceptEncoding from Hyper once available //if !req.headers.has::<AcceptEncoding>() { // We currently don't support HTTP Compression (FIXME #2587) - req.headers_mut().set_raw("Accept-Encoding".into_string(), vec![b"identity".to_vec()]); + req.headers_mut().set_raw("Accept-Encoding".to_owned(), vec![b"identity".to_vec()]); //} let writer = match load_data.data { Some(ref data) => { - req.headers_mut().set(ContentLength(data.len())); + req.headers_mut().set(ContentLength(data.len() as u64)); let mut writer = match req.start() { Ok(w) => w, Err(e) => { - send_error(url, e.to_string(), senders); + send_error(url, e.description().to_string(), senders); return; } }; @@ -114,7 +118,7 @@ fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) { match req.start() { Ok(w) => w, Err(e) => { - send_error(url, e.to_string(), senders); + send_error(url, e.description().to_string(), senders); return; } } @@ -123,7 +127,7 @@ fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) { let mut response = match writer.send() { Ok(r) => r, Err(e) => { - send_error(url, e.to_string(), senders); + send_error(url, e.description().to_string(), senders); return; } }; @@ -187,7 +191,7 @@ fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) { match response.read(buf.as_mut_slice()) { Ok(len) => { unsafe { buf.set_len(len); } - if progress_chan.send_opt(Payload(buf)).is_err() { + if progress_chan.send(Payload(buf)).is_err() { // The send errors when the receiver is out of scope, // which will happen if the fetch has timed out (or has been aborted) // so we don't need to continue with the loading of the file here. @@ -195,7 +199,7 @@ fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) { } } Err(_) => { - let _ = progress_chan.send_opt(Done(Ok(()))); + let _ = progress_chan.send(Done(Ok(()))); break; } } diff --git a/components/net/image/base.rs b/components/net/image/base.rs index 8192d469fde..78e3a0f1159 100644 --- a/components/net/image/base.rs +++ b/components/net/image/base.rs @@ -11,7 +11,7 @@ use png; pub type Image = png::Image; -static TEST_IMAGE: &'static [u8] = include_bin!("test.jpeg"); +static TEST_IMAGE: &'static [u8] = include_bytes!("test.jpeg"); pub fn test_image_bin() -> Vec<u8> { TEST_IMAGE.iter().map(|&x| x).collect() diff --git a/components/net/image/holder.rs b/components/net/image/holder.rs index 216f362328a..8ec15b02940 100644 --- a/components/net/image/holder.rs +++ b/components/net/image/holder.rs @@ -16,7 +16,7 @@ use url::Url; /// A struct to store image data. The image will be loaded once the first time it is requested, /// and an Arc will be stored. Clones of this Arc are given out on demand. -#[deriving(Clone)] +#[derive(Clone)] pub struct ImageHolder<NodeAddress> { url: Url, image: Option<Arc<Box<Image>>>, @@ -41,7 +41,7 @@ impl<NodeAddress: Send> ImageHolder<NodeAddress> { // should be done as early as possible and decode only once we // are sure that the image will be used. { - let val = holder.local_image_cache.lock(); + let val = holder.local_image_cache.lock().unwrap(); let mut local_image_cache = val; local_image_cache.prefetch(&holder.url); local_image_cache.decode(&holder.url); @@ -81,11 +81,11 @@ impl<NodeAddress: Send> ImageHolder<NodeAddress> { // the image and store it for the future if self.image.is_none() { let port = { - let val = self.local_image_cache.lock(); + let val = self.local_image_cache.lock().unwrap(); let mut local_image_cache = val; local_image_cache.get_image(node_address, &self.url) }; - match port.recv() { + match port.recv().unwrap() { ImageResponseMsg::ImageReady(image) => self.image = Some(image), ImageResponseMsg::ImageNotReady => debug!("image not ready for {}", self.url.serialize()), ImageResponseMsg::ImageFailed => debug!("image decoding failed for {}", self.url.serialize()), diff --git a/components/net/image_cache_task.rs b/components/net/image_cache_task.rs index 46f238b0a00..6bc4875f39a 100644 --- a/components/net/image_cache_task.rs +++ b/components/net/image_cache_task.rs @@ -9,12 +9,12 @@ use resource_task::ProgressMsg::{Payload, Done}; use servo_util::task::spawn_named; use servo_util::taskpool::TaskPool; -use std::comm::{channel, Receiver, Sender}; +use std::borrow::ToOwned; use std::collections::HashMap; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::mem::replace; use std::sync::{Arc, Mutex}; -use serialize::{Encoder, Encodable}; +use std::sync::mpsc::{channel, Receiver, Sender}; use url::Url; pub enum Msg { @@ -48,7 +48,7 @@ pub enum Msg { WaitForStorePrefetched(Sender<()>), } -#[deriving(Clone)] +#[derive(Clone)] pub enum ImageResponseMsg { ImageReady(Arc<Box<Image>>), ImageNotReady, @@ -67,25 +67,17 @@ impl PartialEq for ImageResponseMsg { } } -#[deriving(Clone)] +#[derive(Clone)] pub struct ImageCacheTask { chan: Sender<Msg>, } -impl<E, S: Encoder<E>> Encodable<S, E> for ImageCacheTask { - fn encode(&self, _: &mut S) -> Result<(), E> { - Ok(()) - } -} - -type DecoderFactory = fn() -> (proc(&[u8]) : 'static -> Option<Image>); - impl ImageCacheTask { pub fn new(resource_task: ResourceTask, task_pool: TaskPool) -> ImageCacheTask { let (chan, port) = channel(); let chan_clone = chan.clone(); - spawn_named("ImageCacheTask", proc() { + spawn_named("ImageCacheTask".to_owned(), move || { let mut cache = ImageCache { resource_task: resource_task, port: port, @@ -106,11 +98,11 @@ impl ImageCacheTask { pub fn new_sync(resource_task: ResourceTask, task_pool: TaskPool) -> ImageCacheTask { let (chan, port) = channel(); - spawn_named("ImageCacheTask (sync)", proc() { + spawn_named("ImageCacheTask (sync)".to_owned(), move || { let inner_cache = ImageCacheTask::new(resource_task, task_pool); loop { - let msg: Msg = port.recv(); + let msg: Msg = port.recv().unwrap(); match msg { Msg::GetImage(url, response) => { @@ -146,7 +138,7 @@ struct ImageCache { task_pool: TaskPool, } -#[deriving(Clone)] +#[derive(Clone)] enum ImageState { Init, Prefetching(AfterPrefetch), @@ -156,7 +148,7 @@ enum ImageState { Failed } -#[deriving(Clone)] +#[derive(Clone)] enum AfterPrefetch { DoDecode, DoNotDecode @@ -168,7 +160,7 @@ impl ImageCache { let mut store_prefetched_chan: Option<Sender<()>> = None; loop { - let msg = self.port.recv(); + let msg = self.port.recv().unwrap(); match msg { Msg::Prefetch(url) => self.prefetch(url), @@ -248,7 +240,7 @@ impl ImageCache { let resource_task = self.resource_task.clone(); let url_clone = url.clone(); - spawn_named("ImageCacheTask (prefetch)", proc() { + spawn_named("ImageCacheTask (prefetch)".to_owned(), move || { let url = url_clone; debug!("image_cache_task: started fetch for {}", url.serialize()); @@ -312,7 +304,7 @@ impl ImageCache { let to_cache = self.chan.clone(); let url_clone = url.clone(); - self.task_pool.execute(proc() { + self.task_pool.execute(move || { let url = url_clone; debug!("image_cache_task: started image decode for {}", url.serialize()); let image = load_from_memory(data.as_slice()); @@ -357,10 +349,10 @@ impl ImageCache { } - fn purge_waiters(&mut self, url: Url, f: || -> ImageResponseMsg) { + fn purge_waiters<F>(&mut self, url: Url, f: F) where F: Fn() -> ImageResponseMsg { match self.wait_map.remove(&url) { Some(waiters) => { - let items = waiters.lock(); + let items = waiters.lock().unwrap(); for response in items.iter() { response.send(f()); } @@ -372,11 +364,11 @@ impl ImageCache { fn get_image(&self, url: Url, response: Sender<ImageResponseMsg>) { match self.get_state(&url) { ImageState::Init => panic!("request for image before prefetch"), - ImageState::Prefetching(AfterPrefetch::DoDecode) => response.send(ImageResponseMsg::ImageNotReady), + ImageState::Prefetching(AfterPrefetch::DoDecode) => response.send(ImageResponseMsg::ImageNotReady).unwrap(), ImageState::Prefetching(AfterPrefetch::DoNotDecode) | ImageState::Prefetched(..) => panic!("request for image before decode"), - ImageState::Decoding => response.send(ImageResponseMsg::ImageNotReady), - ImageState::Decoded(image) => response.send(ImageResponseMsg::ImageReady(image)), - ImageState::Failed => response.send(ImageResponseMsg::ImageFailed), + ImageState::Decoding => response.send(ImageResponseMsg::ImageNotReady).unwrap(), + ImageState::Decoded(image) => response.send(ImageResponseMsg::ImageReady(image)).unwrap(), + ImageState::Failed => response.send(ImageResponseMsg::ImageFailed).unwrap(), } } @@ -390,10 +382,10 @@ impl ImageCache { // We don't have this image yet match self.wait_map.entry(url) { Occupied(mut entry) => { - entry.get_mut().lock().push(response); + entry.get_mut().lock().unwrap().push(response); } Vacant(entry) => { - entry.set(Arc::new(Mutex::new(vec!(response)))); + entry.insert(Arc::new(Mutex::new(vec!(response)))); } } } @@ -419,7 +411,7 @@ impl ImageCacheTaskClient for ImageCacheTask { fn exit(&self) { let (response_chan, response_port) = channel(); self.send(Msg::Exit(response_chan)); - response_port.recv(); + response_port.recv().unwrap(); } } @@ -449,9 +441,9 @@ fn load_image_data(url: Url, resource_task: ResourceTask) -> Result<Vec<u8>, ()> let mut image_data = vec!(); - let progress_port = response_port.recv().progress_port; + let progress_port = response_port.recv().unwrap().progress_port; loop { - match progress_port.recv() { + match progress_port.recv().unwrap() { Payload(data) => { image_data.push_all(data.as_slice()); } @@ -466,15 +458,18 @@ fn load_image_data(url: Url, resource_task: ResourceTask) -> Result<Vec<u8>, ()> } -pub fn spawn_listener<A: Send>(f: proc(Receiver<A>):Send) -> Sender<A> { +pub fn spawn_listener<F, A>(f: F) -> Sender<A> + where F: FnOnce(Receiver<A>) + Send, + A: Send +{ let (setup_chan, setup_port) = channel(); - spawn_named("ImageCacheTask (listener)", proc() { + spawn_named("ImageCacheTask (listener)".to_owned(), move || { let (chan, port) = channel(); setup_chan.send(chan); f(port); }); - setup_port.recv() + setup_port.recv().unwrap() } @@ -490,7 +485,7 @@ mod tests { use sniffer_task; use image::base::test_image_bin; use servo_util::taskpool::TaskPool; - use std::comm; + use std::sync::mpsc::{Sender, channel, Receiver}; use url::Url; trait Closure { @@ -540,7 +535,7 @@ mod tests { fn invoke(&self, response: Sender<resource_task::ProgressMsg>) { // Don't send the data until after the client requests // the image - self.wait_port.recv(); + self.wait_port.recv().unwrap(); response.send(Payload(test_image_bin())); response.send(Done(Ok(()))); } @@ -553,16 +548,16 @@ mod tests { fn invoke(&self, response: Sender<resource_task::ProgressMsg>) { // Don't send the data until after the client requests // the image - self.wait_port.recv(); + self.wait_port.recv().unwrap(); response.send(Payload(test_image_bin())); response.send(Done(Err("".to_string()))); } } fn mock_resource_task<T: Closure+Send>(on_load: Box<T>) -> ResourceTask { - spawn_listener(proc(port: Receiver<resource_task::ControlMsg>) { + spawn_listener(move |port: Receiver<resource_task::ControlMsg>| { loop { - match port.recv() { + match port.recv().unwrap() { resource_task::ControlMsg::Load(response) => { let sniffer_task = sniffer_task::new_sniffer_task(); let senders = ResponseSenders { @@ -599,7 +594,7 @@ mod tests { let (chan, port) = channel(); image_cache_task.send(Msg::GetImage(url, chan)); - port.recv(); + port.recv().unwrap(); } #[test] @@ -612,14 +607,14 @@ mod tests { let url = Url::parse("file:///").unwrap(); image_cache_task.send(Prefetch(url)); - url_requested.recv(); + url_requested.recv().unwrap(); image_cache_task.exit(); mock_resource_task.send(resource_task::ControlMsg::Exit); } #[test] fn should_not_request_url_from_resource_task_on_multiple_prefetches() { - let (url_requested_chan, url_requested) = comm::channel(); + let (url_requested_chan, url_requested) = channel(); let mock_resource_task = mock_resource_task(box JustSendOK { url_requested_chan: url_requested_chan}); @@ -628,7 +623,7 @@ mod tests { image_cache_task.send(Prefetch(url.clone())); image_cache_task.send(Prefetch(url)); - url_requested.recv(); + url_requested.recv().unwrap(); image_cache_task.exit(); mock_resource_task.send(resource_task::ControlMsg::Exit); match url_requested.try_recv() { @@ -639,7 +634,7 @@ mod tests { #[test] fn should_return_image_not_ready_if_data_has_not_arrived() { - let (wait_chan, wait_port) = comm::channel(); + let (wait_chan, wait_port) = channel(); let mock_resource_task = mock_resource_task(box WaitSendTestImage{wait_port: wait_port}); @@ -648,9 +643,9 @@ mod tests { image_cache_task.send(Prefetch(url.clone())); image_cache_task.send(Decode(url.clone())); - let (response_chan, response_port) = comm::channel(); + let (response_chan, response_port) = channel(); image_cache_task.send(Msg::GetImage(url, response_chan)); - assert!(response_port.recv() == ImageResponseMsg::ImageNotReady); + assert!(response_port.recv().unwrap() == ImageResponseMsg::ImageNotReady); wait_chan.send(()); image_cache_task.exit(); mock_resource_task.send(resource_task::ControlMsg::Exit); @@ -669,11 +664,11 @@ mod tests { image_cache_task.send(Decode(url.clone())); // Wait until our mock resource task has sent the image to the image cache - join_port.recv(); + join_port.recv().unwrap(); - let (response_chan, response_port) = comm::channel(); + let (response_chan, response_port) = channel(); image_cache_task.send(Msg::GetImage(url, response_chan)); - match response_port.recv() { + match response_port.recv().unwrap() { ImageResponseMsg::ImageReady(_) => (), _ => panic!("bleh") } @@ -695,12 +690,12 @@ mod tests { image_cache_task.send(Decode(url.clone())); // Wait until our mock resource task has sent the image to the image cache - join_port.recv(); + join_port.recv().unwrap(); for _ in range(0u32, 2u32) { - let (response_chan, response_port) = comm::channel(); + let (response_chan, response_port) = channel(); image_cache_task.send(Msg::GetImage(url.clone(), response_chan)); - match response_port.recv() { + match response_port.recv().unwrap() { ImageResponseMsg::ImageReady(_) => (), _ => panic!("bleh") } @@ -712,13 +707,13 @@ mod tests { #[test] fn should_not_request_image_from_resource_task_if_image_is_already_available() { - let (image_bin_sent_chan, image_bin_sent) = comm::channel(); + let (image_bin_sent_chan, image_bin_sent) = channel(); - let (resource_task_exited_chan, resource_task_exited) = comm::channel(); + let (resource_task_exited_chan, resource_task_exited) = channel(); - let mock_resource_task = spawn_listener(proc(port: Receiver<resource_task::ControlMsg>) { + let mock_resource_task = spawn_listener(move |port: Receiver<resource_task::ControlMsg>| { loop { - match port.recv() { + match port.recv().unwrap() { resource_task::ControlMsg::Load(response) => { let sniffer_task = sniffer_task::new_sniffer_task(); let senders = ResponseSenders { @@ -745,14 +740,14 @@ mod tests { image_cache_task.send(Prefetch(url.clone())); // Wait until our mock resource task has sent the image to the image cache - image_bin_sent.recv(); + image_bin_sent.recv().unwrap(); image_cache_task.send(Prefetch(url.clone())); image_cache_task.exit(); mock_resource_task.send(resource_task::ControlMsg::Exit); - resource_task_exited.recv(); + resource_task_exited.recv().unwrap(); // Our resource task should not have received another request for the image // because it's already cached @@ -764,13 +759,13 @@ mod tests { #[test] fn should_not_request_image_from_resource_task_if_image_fetch_already_failed() { - let (image_bin_sent_chan, image_bin_sent) = comm::channel(); + let (image_bin_sent_chan, image_bin_sent) = channel(); - let (resource_task_exited_chan, resource_task_exited) = comm::channel(); + let (resource_task_exited_chan, resource_task_exited) = channel(); - let mock_resource_task = spawn_listener(proc(port: Receiver<resource_task::ControlMsg>) { + let mock_resource_task = spawn_listener(move |port: Receiver<resource_task::ControlMsg>| { loop { - match port.recv() { + match port.recv().unwrap() { resource_task::ControlMsg::Load(response) => { let sniffer_task = sniffer_task::new_sniffer_task(); let senders = ResponseSenders { @@ -798,7 +793,7 @@ mod tests { image_cache_task.send(Decode(url.clone())); // Wait until our mock resource task has sent the image to the image cache - image_bin_sent.recv(); + image_bin_sent.recv().unwrap(); image_cache_task.send(Prefetch(url.clone())); image_cache_task.send(Decode(url.clone())); @@ -806,7 +801,7 @@ mod tests { image_cache_task.exit(); mock_resource_task.send(resource_task::ControlMsg::Exit); - resource_task_exited.recv(); + resource_task_exited.recv().unwrap(); // Our resource task should not have received another request for the image // because it's already cached @@ -829,11 +824,11 @@ mod tests { image_cache_task.send(Decode(url.clone())); // Wait until our mock resource task has sent the image to the image cache - join_port.recv(); + join_port.recv().unwrap(); - let (response_chan, response_port) = comm::channel(); + let (response_chan, response_port) = channel(); image_cache_task.send(Msg::GetImage(url, response_chan)); - match response_port.recv() { + match response_port.recv().unwrap() { ImageResponseMsg::ImageFailed => (), _ => panic!("bleh") } @@ -855,19 +850,19 @@ mod tests { image_cache_task.send(Decode(url.clone())); // Wait until our mock resource task has sent the image to the image cache - join_port.recv(); + join_port.recv().unwrap(); - let (response_chan, response_port) = comm::channel(); + let (response_chan, response_port) = channel(); image_cache_task.send(Msg::GetImage(url.clone(), response_chan)); - match response_port.recv() { + match response_port.recv().unwrap() { ImageResponseMsg::ImageFailed => (), _ => panic!("bleh") } // And ask again, we should get the same response - let (response_chan, response_port) = comm::channel(); + let (response_chan, response_port) = channel(); image_cache_task.send(Msg::GetImage(url, response_chan)); - match response_port.recv() { + match response_port.recv().unwrap() { ImageResponseMsg::ImageFailed => (), _ => panic!("bleh") } @@ -889,13 +884,13 @@ mod tests { image_cache_task.send(Decode(url.clone())); // Wait until our mock resource task has sent the image to the image cache - join_port.recv(); + join_port.recv().unwrap(); // Make the request - let (response_chan, response_port) = comm::channel(); + let (response_chan, response_port) = channel(); image_cache_task.send(Msg::GetImage(url, response_chan)); - match response_port.recv() { + match response_port.recv().unwrap() { ImageResponseMsg::ImageFailed => (), _ => panic!("bleh") } @@ -917,11 +912,11 @@ mod tests { image_cache_task.send(Decode(url.clone())); // Wait until our mock resource task has sent the image to the image cache - join_port.recv(); + join_port.recv().unwrap(); - let (response_chan, response_port) = comm::channel(); + let (response_chan, response_port) = channel(); image_cache_task.send(Msg::WaitForImage(url, response_chan)); - match response_port.recv() { + match response_port.recv().unwrap() { ImageResponseMsg::ImageReady(..) => (), _ => panic!("bleh") } @@ -932,7 +927,7 @@ mod tests { #[test] fn should_return_image_on_wait_if_image_is_not_yet_loaded() { - let (wait_chan, wait_port) = comm::channel(); + let (wait_chan, wait_port) = channel(); let mock_resource_task = mock_resource_task(box WaitSendTestImage {wait_port: wait_port}); @@ -942,12 +937,12 @@ mod tests { image_cache_task.send(Prefetch(url.clone())); image_cache_task.send(Decode(url.clone())); - let (response_chan, response_port) = comm::channel(); + let (response_chan, response_port) = channel(); image_cache_task.send(Msg::WaitForImage(url, response_chan)); wait_chan.send(()); - match response_port.recv() { + match response_port.recv().unwrap() { ImageResponseMsg::ImageReady(..) => (), _ => panic!("bleh") } @@ -958,7 +953,7 @@ mod tests { #[test] fn should_return_image_failed_on_wait_if_image_fails_to_load() { - let (wait_chan, wait_port) = comm::channel(); + let (wait_chan, wait_port) = channel(); let mock_resource_task = mock_resource_task(box WaitSendTestImageErr{wait_port: wait_port}); @@ -968,12 +963,12 @@ mod tests { image_cache_task.send(Prefetch(url.clone())); image_cache_task.send(Decode(url.clone())); - let (response_chan, response_port) = comm::channel(); + let (response_chan, response_port) = channel(); image_cache_task.send(Msg::WaitForImage(url, response_chan)); wait_chan.send(()); - match response_port.recv() { + match response_port.recv().unwrap() { ImageResponseMsg::ImageFailed => (), _ => panic!("bleh") } @@ -992,9 +987,9 @@ mod tests { image_cache_task.send(Prefetch(url.clone())); image_cache_task.send(Decode(url.clone())); - let (response_chan, response_port) = comm::channel(); + let (response_chan, response_port) = channel(); image_cache_task.send(Msg::GetImage(url, response_chan)); - match response_port.recv() { + match response_port.recv().unwrap() { ImageResponseMsg::ImageReady(_) => (), _ => panic!("bleh") } diff --git a/components/net/lib.rs b/components/net/lib.rs index de1335b5c3b..857461aa335 100644 --- a/components/net/lib.rs +++ b/components/net/lib.rs @@ -2,17 +2,20 @@ * 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/. */ -#![feature(default_type_params, globs, phase)] +#![feature(int_uint)] +#![feature(unboxed_closures)] +#![feature(box_syntax)] #![deny(unused_imports)] #![deny(unused_variables)] #![allow(missing_copy_implementations)] +#![allow(unstable)] extern crate collections; extern crate geom; extern crate hyper; extern crate png; -#[phase(plugin, link)] +#[macro_use] extern crate log; extern crate serialize; extern crate "util" as servo_util; @@ -42,7 +45,7 @@ mod sniffer_task; /// An implementation of the [Fetch spec](http://fetch.spec.whatwg.org/) pub mod fetch { - #![allow(dead_code)] // XXXManishearth this is only temporary until the Fetch mod starts being used + #![allow(dead_code, unused)] // XXXManishearth this is only temporary until the Fetch mod starts being used pub mod request; pub mod response; pub mod cors_cache; diff --git a/components/net/local_image_cache.rs b/components/net/local_image_cache.rs index aca13a6d405..8e8fa8da1df 100644 --- a/components/net/local_image_cache.rs +++ b/components/net/local_image_cache.rs @@ -10,14 +10,15 @@ multiple times and thus triggering reflows multiple times. use image_cache_task::{ImageCacheTask, ImageResponseMsg, Msg}; -use std::comm::{Receiver, channel}; +use std::borrow::ToOwned; use std::collections::HashMap; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; +use std::sync::mpsc::{Receiver, channel}; use servo_util::task::spawn_named; use url::Url; pub trait ImageResponder<NodeAddress: Send> { - fn respond(&self) -> proc(ImageResponseMsg, NodeAddress):Send; + fn respond(&self) -> Box<Fn(ImageResponseMsg, NodeAddress)+Send>; } pub struct LocalImageCache<NodeAddress> { @@ -38,7 +39,7 @@ impl<NodeAddress: Send> LocalImageCache<NodeAddress> { } } -#[deriving(Clone)] +#[derive(Clone)] struct ImageState { prefetched: bool, decoded: bool, @@ -117,7 +118,7 @@ impl<NodeAddress: Send> LocalImageCache<NodeAddress> { let (response_chan, response_port) = channel(); self.image_cache_task.send(Msg::GetImage((*url).clone(), response_chan)); - let response = response_port.recv(); + let response = response_port.recv().unwrap(); match response { ImageResponseMsg::ImageNotReady => { // Need to reflow when the image is available @@ -127,13 +128,13 @@ impl<NodeAddress: Send> LocalImageCache<NodeAddress> { // on the image to load and triggering layout let image_cache_task = self.image_cache_task.clone(); assert!(self.on_image_available.is_some()); - let on_image_available: proc(ImageResponseMsg, NodeAddress):Send = + let on_image_available = self.on_image_available.as_ref().unwrap().respond(); let url = (*url).clone(); - spawn_named("LocalImageCache", proc() { + spawn_named("LocalImageCache".to_owned(), move || { let (response_chan, response_port) = channel(); image_cache_task.send(Msg::WaitForImage(url, response_chan)); - on_image_available(response_port.recv(), node_address); + on_image_available(response_port.recv().unwrap(), node_address); }); } _ => () @@ -156,7 +157,7 @@ impl<NodeAddress: Send> LocalImageCache<NodeAddress> { match self.state_map.entry((*url).clone()) { Occupied(entry) => entry.into_mut(), Vacant(entry) => - entry.set(ImageState { + entry.insert(ImageState { prefetched: false, decoded: false, last_request_round: 0, diff --git a/components/net/resource_task.rs b/components/net/resource_task.rs index 9b541455a03..3093df5e56a 100644 --- a/components/net/resource_task.rs +++ b/components/net/resource_task.rs @@ -20,7 +20,8 @@ use hyper::method::Method; use hyper::mime::{Mime, Attr}; use url::Url; -use std::comm::{channel, Receiver, Sender}; +use std::borrow::ToOwned; +use std::sync::mpsc::{channel, Receiver, Sender}; pub enum ControlMsg { /// Request the data associated with a particular URL @@ -28,7 +29,7 @@ pub enum ControlMsg { Exit } -#[deriving(Clone)] +#[derive(Clone)] pub struct LoadData { pub url: Url, pub method: Method, @@ -51,7 +52,7 @@ impl LoadData { } } -#[deriving(Clone)] +#[derive(Clone)] pub struct ResourceCORSData { /// CORS Preflight flag pub preflight: bool, @@ -86,7 +87,7 @@ impl Metadata { charset: None, headers: None, // http://fetch.spec.whatwg.org/#concept-response-status-message - status: Some(RawStatus(200, "OK".into_string())) + status: Some(RawStatus(200, "OK".to_owned())) } } @@ -130,7 +131,7 @@ pub struct ResponseSenders { } /// Messages sent in response to a `Load` message -#[deriving(PartialEq,Show)] +#[derive(PartialEq,Show)] pub enum ProgressMsg { /// Binary data - there may be multiple of these Payload(Vec<u8>), @@ -146,7 +147,7 @@ pub fn start_sending(senders: ResponseSenders, metadata: Metadata) -> Sender<Pro /// For use by loaders in responding to a Load message. pub fn start_sending_opt(senders: ResponseSenders, metadata: Metadata) -> Result<Sender<ProgressMsg>, ()> { let (progress_chan, progress_port) = channel(); - let result = senders.immediate_consumer.send_opt(TargetedLoadResponse { + let result = senders.immediate_consumer.send(TargetedLoadResponse { load_response: LoadResponse { metadata: metadata, progress_port: progress_port, @@ -164,11 +165,11 @@ pub fn load_whole_resource(resource_task: &ResourceTask, url: Url) -> Result<(Metadata, Vec<u8>), String> { let (start_chan, start_port) = channel(); resource_task.send(ControlMsg::Load(LoadData::new(url, start_chan))); - let response = start_port.recv(); + let response = start_port.recv().unwrap(); let mut buf = vec!(); loop { - match response.progress_port.recv() { + match response.progress_port.recv().unwrap() { ProgressMsg::Payload(data) => buf.push_all(data.as_slice()), ProgressMsg::Done(Ok(())) => return Ok((response.metadata, buf)), ProgressMsg::Done(Err(e)) => return Err(e) @@ -183,7 +184,7 @@ pub type ResourceTask = Sender<ControlMsg>; pub fn new_resource_task(user_agent: Option<String>) -> ResourceTask { let (setup_chan, setup_port) = channel(); let sniffer_task = sniffer_task::new_sniffer_task(); - spawn_named("ResourceManager", proc() { + spawn_named("ResourceManager".to_owned(), move || { ResourceManager::new(setup_port, user_agent, sniffer_task).start(); }); setup_chan @@ -209,7 +210,7 @@ impl ResourceManager { impl ResourceManager { fn start(&self) { loop { - match self.from_client.recv() { + match self.from_client.recv().unwrap() { ControlMsg::Load(load_data) => { self.load(load_data) } @@ -228,21 +229,19 @@ impl ResourceManager { eventual_consumer: load_data.consumer.clone(), }; - let loader = match load_data.url.scheme.as_slice() { - "file" => file_loader::factory, - "http" | "https" => http_loader::factory, - "data" => data_loader::factory, - "about" => about_loader::factory, + debug!("resource_task: loading url: {}", load_data.url.serialize()); + match load_data.url.scheme.as_slice() { + "file" => file_loader::factory(load_data, self.sniffer_task.clone()), + "http" | "https" => http_loader::factory(load_data, self.sniffer_task.clone()), + "data" => data_loader::factory(load_data, self.sniffer_task.clone()), + "about" => about_loader::factory(load_data, self.sniffer_task.clone()), _ => { debug!("resource_task: no loader for scheme {}", load_data.url.scheme); start_sending(senders, Metadata::default(load_data.url)) .send(ProgressMsg::Done(Err("no loader for scheme".to_string()))); return } - }; - debug!("resource_task: loading url: {}", load_data.url.serialize()); - - loader(load_data, self.sniffer_task.clone()); + } } } @@ -251,7 +250,7 @@ pub fn load_bytes_iter(resource_task: &ResourceTask, url: Url) -> (Metadata, Pro let (input_chan, input_port) = channel(); resource_task.send(ControlMsg::Load(LoadData::new(url, input_chan))); - let response = input_port.recv(); + let response = input_port.recv().unwrap(); let iter = ProgressMsgPortIterator { progress_port: response.progress_port }; (response.metadata, iter) } @@ -261,9 +260,11 @@ pub struct ProgressMsgPortIterator { progress_port: Receiver<ProgressMsg> } -impl Iterator<Vec<u8>> for ProgressMsgPortIterator { +impl Iterator for ProgressMsgPortIterator { + type Item = Vec<u8>; + fn next(&mut self) -> Option<Vec<u8>> { - match self.progress_port.recv() { + match self.progress_port.recv().unwrap() { ProgressMsg::Payload(data) => Some(data), ProgressMsg::Done(Ok(())) => None, ProgressMsg::Done(Err(e)) => { @@ -286,8 +287,8 @@ fn test_bad_scheme() { let (start_chan, start) = channel(); let url = Url::parse("bogus://whatever").unwrap(); resource_task.send(ControlMsg::Load(LoadData::new(url, start_chan))); - let response = start.recv(); - match response.progress_port.recv() { + let response = start.recv().unwrap(); + match response.progress_port.recv().unwrap() { ProgressMsg::Done(result) => { assert!(result.is_err()) } _ => panic!("bleh") } diff --git a/components/net/sniffer_task.rs b/components/net/sniffer_task.rs index 2fcc0394f52..2b9b2363a0a 100644 --- a/components/net/sniffer_task.rs +++ b/components/net/sniffer_task.rs @@ -3,16 +3,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ //! A task that sniffs data -use std::comm::{channel, Receiver, Sender}; -use std::task::TaskBuilder; +use std::sync::mpsc::{channel, Receiver, Sender}; +use std::thread::Builder; use resource_task::{TargetedLoadResponse}; pub type SnifferTask = Sender<TargetedLoadResponse>; pub fn new_sniffer_task() -> SnifferTask { let(sen, rec) = channel(); - let builder = TaskBuilder::new().named("SnifferManager"); - builder.spawn(proc() { + let builder = Builder::new().name("SnifferManager".to_string()); + builder.spawn(move || { SnifferManager::new(rec).start(); }); sen @@ -33,9 +33,9 @@ impl SnifferManager { impl SnifferManager { fn start(self) { loop { - match self.data_receiver.recv_opt() { + match self.data_receiver.recv() { Ok(snif_data) => { - let _ = snif_data.consumer.send_opt(snif_data.load_response); + let _ = snif_data.consumer.send(snif_data.load_response); } Err(_) => break, } diff --git a/components/net/storage_task.rs b/components/net/storage_task.rs index d83a5c6f43c..ac65fa65bc0 100644 --- a/components/net/storage_task.rs +++ b/components/net/storage_task.rs @@ -2,9 +2,10 @@ * 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 std::comm::{channel, Receiver, Sender}; +use std::borrow::ToOwned; use std::collections::HashMap; -use std::collections::TreeMap; +use std::collections::BTreeMap; +use std::sync::mpsc::{channel, Receiver, Sender}; use url::Url; use servo_util::str::DOMString; @@ -39,14 +40,14 @@ pub enum StorageTaskMsg { pub type StorageTask = Sender<StorageTaskMsg>; pub trait StorageTaskFactory { - fn new() -> StorageTask; + fn new() -> Self; } impl StorageTaskFactory for StorageTask { /// Create a StorageTask fn new() -> StorageTask { let (chan, port) = channel(); - spawn_named("StorageManager", proc() { + spawn_named("StorageManager".to_owned(), move || { StorageManager::new(port).start(); }); chan @@ -55,7 +56,7 @@ impl StorageTaskFactory for StorageTask { struct StorageManager { port: Receiver<StorageTaskMsg>, - data: HashMap<String, TreeMap<DOMString, DOMString>>, + data: HashMap<String, BTreeMap<DOMString, DOMString>>, } impl StorageManager { @@ -70,7 +71,7 @@ impl StorageManager { impl StorageManager { fn start(&mut self) { loop { - match self.port.recv() { + match self.port.recv().unwrap() { StorageTaskMsg::Length(sender, url) => { self.length(sender, url) } @@ -111,7 +112,7 @@ impl StorageManager { fn set_item(&mut self, sender: Sender<bool>, url: Url, name: DOMString, value: DOMString) { let origin = self.get_origin_as_string(url); if !self.data.contains_key(&origin) { - self.data.insert(origin.clone(), TreeMap::new()); + self.data.insert(origin.clone(), BTreeMap::new()); } let updated = self.data.get_mut(&origin).map(|entry| { diff --git a/components/plugins/jstraceable.rs b/components/plugins/jstraceable.rs index fb06b6a649a..47f2c99d274 100644 --- a/components/plugins/jstraceable.rs +++ b/components/plugins/jstraceable.rs @@ -15,7 +15,7 @@ use syntax::parse::token::InternedString; pub fn expand_dom_struct(_: &mut ExtCtxt, _: Span, _: &MetaItem, item: P<Item>) -> P<Item> { let mut item2 = (*item).clone(); { - let add_attr = |s| { + let mut add_attr = |&mut :s| { item2.attrs.push(attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_word_item(InternedString::new(s)))); }; add_attr("must_root"); @@ -34,7 +34,7 @@ pub fn expand_dom_struct(_: &mut ExtCtxt, _: Span, _: &MetaItem, item: P<Item>) /// Provides the hook to expand `#[jstraceable]` into an implementation of `JSTraceable` /// /// The expansion basically calls `trace()` on all of the fields of the struct/enum, erroring if they do not implement the method. -pub fn expand_jstraceable(cx: &mut ExtCtxt, span: Span, mitem: &MetaItem, item: &Item, push: |P<Item>|) { +pub fn expand_jstraceable(cx: &mut ExtCtxt, span: Span, mitem: &MetaItem, item: &Item, mut push: Box<FnMut(P<Item>)>) { let trait_def = TraitDef { span: span, attributes: Vec::new(), @@ -51,13 +51,11 @@ pub fn expand_jstraceable(cx: &mut ExtCtxt, span: Span, mitem: &MetaItem, item: attributes: vec!(attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_name_value_item_str(InternedString::new("inline"), InternedString::new("always")))), - combine_substructure: combine_substructure(|a, b, c| { - jstraceable_substructure(a, b, c) - }) + combine_substructure: combine_substructure(box jstraceable_substructure) } ) }; - trait_def.expand(cx, mitem, item, push) + trait_def.expand(cx, mitem, item, |:a| push(a)) } // Mostly copied from syntax::ext::deriving::hash @@ -68,7 +66,7 @@ fn jstraceable_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substru _ => cx.span_bug(trait_span, "incorrect number of arguments in `jstraceable`") }; let trace_ident = substr.method_ident; - let call_trace = |span, thing_expr| { + let call_trace = |&:span, thing_expr| { let expr = cx.expr_method_call(span, thing_expr, trace_ident, vec!(state_expr.clone())); cx.stmt_expr(expr) }; diff --git a/components/plugins/lib.rs b/components/plugins/lib.rs index f6494eadfd3..6190114ac39 100644 --- a/components/plugins/lib.rs +++ b/components/plugins/lib.rs @@ -12,15 +12,18 @@ //! - `#[dom_struct]` : Implies `#[privatize]`,`#[jstraceable]`, and `#[must_root]`. //! Use this for structs that correspond to a DOM type -#![feature(macro_rules, plugin_registrar, quote, phase)] +#![feature(plugin_registrar, quote, plugin, box_syntax)] #![deny(unused_imports)] #![deny(unused_variables)] #![allow(missing_copy_implementations)] +#![allow(unstable)] -#[phase(plugin,link)] +#[plugin] +#[macro_use] extern crate syntax; -#[phase(plugin, link)] +#[plugin] +#[macro_use] extern crate rustc; use rustc::lint::LintPassObject; @@ -50,23 +53,3 @@ pub fn plugin_registrar(reg: &mut Registry) { reg.register_lint_pass(box lints::str_to_string::StrToStringPass as LintPassObject); reg.register_lint_pass(box lints::ban::BanPass as LintPassObject); } - - -#[macro_export] -macro_rules! match_ignore_ascii_case { - ( $value: expr: $( $string: expr => $result: expr ),+ _ => $fallback: expr, ) => { - match_ignore_ascii_case! { $value: - $( $string => $result ),+ - _ => $fallback - } - }; - ( $value: expr: $( $string: expr => $result: expr ),+ _ => $fallback: expr ) => { - { - use std::ascii::AsciiExt; - match $value.as_slice() { - $( s if s.eq_ignore_ascii_case($string) => $result, )+ - _ => $fallback - } - } - }; -} diff --git a/components/plugins/lints/ban.rs b/components/plugins/lints/ban.rs index 78761c274f4..a4c3b7cea07 100644 --- a/components/plugins/lints/ban.rs +++ b/components/plugins/lints/ban.rs @@ -7,7 +7,7 @@ use rustc::lint::{Context, LintPass, LintArray}; use utils::match_ty_unwrap; declare_lint!(BANNED_TYPE, Deny, - "Ban various unsafe type combinations") + "Ban various unsafe type combinations"); /// Lint for banning various unsafe types /// diff --git a/components/plugins/lints/inheritance_integrity.rs b/components/plugins/lints/inheritance_integrity.rs index fa3f42770f0..d806b1cad1c 100644 --- a/components/plugins/lints/inheritance_integrity.rs +++ b/components/plugins/lints/inheritance_integrity.rs @@ -9,7 +9,7 @@ use rustc::middle::{ty, def}; use utils::match_lang_ty; declare_lint!(INHERITANCE_INTEGRITY, Deny, - "Ensures that struct fields are properly laid out for inheritance to work") + "Ensures that struct fields are properly laid out for inheritance to work"); /// Lint for ensuring proper layout of DOM structs /// diff --git a/components/plugins/lints/privatize.rs b/components/plugins/lints/privatize.rs index 379fa946b43..475338dee07 100644 --- a/components/plugins/lints/privatize.rs +++ b/components/plugins/lints/privatize.rs @@ -9,7 +9,7 @@ use rustc::lint::{Context, LintPass, LintArray}; use rustc::middle::ty; declare_lint!(PRIVATIZE, Deny, - "Allows to enforce private fields for struct definitions") + "Allows to enforce private fields for struct definitions"); /// Lint for keeping DOM fields private /// diff --git a/components/plugins/lints/str_to_string.rs b/components/plugins/lints/str_to_string.rs index d02e0d9bfde..d93268844e0 100644 --- a/components/plugins/lints/str_to_string.rs +++ b/components/plugins/lints/str_to_string.rs @@ -8,9 +8,9 @@ use rustc::middle::ty::expr_ty; use rustc::middle::ty; declare_lint!(STR_TO_STRING, Deny, - "Warn when a String could use into_string() instead of to_string()") + "Warn when a String could use to_owned() instead of to_string()"); -/// Prefer str.into_string() over str.to_string() +/// Prefer str.to_owned() over str.to_string() /// /// The latter creates a `Formatter` and is 5x slower than the former pub struct StrToStringPass; @@ -26,7 +26,7 @@ impl LintPass for StrToStringPass { if method.node.as_str() == "to_string" && is_str(cx, &*args[0]) => { cx.span_lint(STR_TO_STRING, expr.span, - "str.into_string() is more efficient than str.to_string(), please use it instead"); + "str.to_owned() is more efficient than str.to_string(), please use it instead"); }, _ => () } diff --git a/components/plugins/lints/transmute_type.rs b/components/plugins/lints/transmute_type.rs index 674f14c3c7d..6facd362108 100644 --- a/components/plugins/lints/transmute_type.rs +++ b/components/plugins/lints/transmute_type.rs @@ -9,7 +9,7 @@ use rustc::middle::ty::expr_ty; use rustc::util::ppaux::Repr; declare_lint!(TRANSMUTE_TYPE_LINT, Allow, - "Warn and report types being transmuted") + "Warn and report types being transmuted"); /// Lint for auditing transmutes /// diff --git a/components/plugins/lints/unrooted_must_root.rs b/components/plugins/lints/unrooted_must_root.rs index 636ff472fff..80b37a714ba 100644 --- a/components/plugins/lints/unrooted_must_root.rs +++ b/components/plugins/lints/unrooted_must_root.rs @@ -11,7 +11,7 @@ use rustc::util::ppaux::Repr; use utils::unsafe_context; declare_lint!(UNROOTED_MUST_ROOT, Deny, - "Warn and report usage of unrooted jsmanaged objects") + "Warn and report usage of unrooted jsmanaged objects"); /// Lint for ensuring safe usage of unrooted pointers /// @@ -84,7 +84,7 @@ impl LintPass for UnrootedPass { return; }, visit::FkItemFn(_, _, style, _) => match style { - ast::UnsafeFn => return, + ast::Unsafety::Unsafe => return, _ => () }, _ => () diff --git a/components/plugins/reflector.rs b/components/plugins/reflector.rs index 4b0681c4d39..43f2f625df4 100644 --- a/components/plugins/reflector.rs +++ b/components/plugins/reflector.rs @@ -10,7 +10,7 @@ use syntax::ast; use utils::match_ty_unwrap; -pub fn expand_reflector(cx: &mut ExtCtxt, span: Span, _: &MetaItem, item: &Item, push: |P<Item>|) { +pub fn expand_reflector(cx: &mut ExtCtxt, span: Span, _: &MetaItem, item: &Item, mut push: Box<FnMut(P<Item>) -> ()>) { if let ast::ItemStruct(ref def, _) = item.node { let struct_name = item.ident; // This path has to be hardcoded, unfortunately, since we can't resolve paths at expansion time diff --git a/components/plugins/utils.rs b/components/plugins/utils.rs index 6f7f00f9109..e9db633f2d4 100644 --- a/components/plugins/utils.rs +++ b/components/plugins/utils.rs @@ -70,7 +70,7 @@ pub fn unsafe_context(map: &ast_map::Map, id: ast::NodeId) -> bool { match *itm { ast::MethodImplItem(ref meth) => match meth.node { ast::MethDecl(_, _, _, _, style, _, _, _) => match style { - ast::UnsafeFn => true, + ast::Unsafety::Unsafe => true, _ => false, }, _ => false, @@ -81,7 +81,7 @@ pub fn unsafe_context(map: &ast_map::Map, id: ast::NodeId) -> bool { Some(ast_map::NodeItem(itm)) => { match itm.node { ast::ItemFn(_, style, _, _, _) => match style { - ast::UnsafeFn => true, + ast::Unsafety::Unsafe => true, _ => false, }, _ => false, diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index 2a211eb52d5..08c5cc732b8 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -55,9 +55,6 @@ branch = "servo" [dependencies.js] git = "https://github.com/servo/rust-mozjs" -[dependencies.url] -git = "https://github.com/servo/rust-url" - [dependencies.uuid] git = "https://github.com/rust-lang/uuid" @@ -67,8 +64,7 @@ git = "https://github.com/servo/string-cache" [dependencies.string_cache_macros] git = "https://github.com/servo/string-cache" -[dependencies.time] -git = "https://github.com/rust-lang/time" - [dependencies] encoding = "0.2" +url = "*" +time = "*"
\ No newline at end of file diff --git a/components/script/cors.rs b/components/script/cors.rs index e7fd20d866c..ebc2af7ec76 100644 --- a/components/script/cors.rs +++ b/components/script/cors.rs @@ -10,13 +10,13 @@ //! with CORSRequest being expanded into FetchRequest (etc) use std::ascii::AsciiExt; -use std::fmt::{mod, Show}; +use std::fmt::{self, Show}; use std::str::from_utf8; use time; use time::{now, Timespec}; use hyper::header::{Headers, Header, HeaderFormat, HeaderView}; -use hyper::header::common::util as header_util; +use hyper::header::shared::util as header_util; use hyper::client::Request; use hyper::mime::{Mime, TopLevel, SubLevel}; use hyper::header::common::{ContentType, Host}; @@ -25,7 +25,7 @@ use hyper::status::StatusClass::Success; use url::{SchemeData, Url}; -#[deriving(Clone)] +#[derive(Clone)] pub struct CORSRequest { pub origin: Url, pub destination: Url, @@ -40,7 +40,7 @@ pub struct CORSRequest { /// http://fetch.spec.whatwg.org/#concept-request-mode /// This only covers some of the request modes. The /// `same-origin` and `no CORS` modes are unnecessary for XHR. -#[deriving(PartialEq, Copy, Clone)] +#[derive(PartialEq, Copy, Clone)] pub enum RequestMode { CORS, // CORS ForcedPreflight // CORS-with-forced-preflight @@ -126,7 +126,7 @@ impl CORSRequest { // Step 5 - 7 let mut header_names = vec!(); for header in self.headers.iter() { - header_names.push(header.name().to_ascii_lower()); + header_names.push(header.name().to_ascii_lowercase()); } header_names.sort(); preflight.headers.set(AccessControlRequestHeaders(header_names)); @@ -240,12 +240,12 @@ impl CORSResponse { // CORS Cache stuff /// A CORS cache object. Anchor it somewhere to the user agent. -#[deriving(Clone)] +#[derive(Clone)] pub struct CORSCache(Vec<CORSCacheEntry>); /// Union type for CORS cache entries /// Each entry might pertain to a header or method -#[deriving(Clone)] +#[derive(Clone)] pub enum HeaderOrMethod { HeaderData(String), MethodData(Method) @@ -268,7 +268,7 @@ impl HeaderOrMethod { } // An entry in the CORS cache -#[deriving(Clone)] +#[derive(Clone)] pub struct CORSCacheEntry { pub origin: Url, pub url: Url, @@ -361,7 +361,7 @@ impl CORSCache { fn is_simple_header(h: &HeaderView) -> bool { //FIXME: use h.is::<HeaderType>() when AcceptLanguage and //ContentLanguage headers exist - match h.name().to_ascii_lower().as_slice() { + match h.name().to_ascii_lowercase().as_slice() { "accept" | "accept-language" | "content-language" => true, "content-type" => match h.value() { Some(&ContentType(Mime(TopLevel::Text, SubLevel::Plain, _))) | @@ -383,7 +383,7 @@ fn is_simple_method(m: &Method) -> bool { } //XXX(seanmonstar): worth uplifting to Hyper? -#[deriving(Clone)] +#[derive(Clone)] struct AccessControlRequestMethod(pub Method); impl Header for AccessControlRequestMethod { @@ -404,7 +404,7 @@ impl HeaderFormat for AccessControlRequestMethod { } } -#[deriving(Clone)] +#[derive(Clone)] struct AccessControlRequestHeaders(pub Vec<String>); impl Header for AccessControlRequestHeaders { @@ -425,7 +425,7 @@ impl HeaderFormat for AccessControlRequestHeaders { } } -#[deriving(Clone)] +#[derive(Clone)] struct AccessControlAllowMethods(pub Vec<Method>); impl Header for AccessControlAllowMethods { @@ -446,7 +446,7 @@ impl HeaderFormat for AccessControlAllowMethods { } } -#[deriving(Clone)] +#[derive(Clone)] struct AccessControlAllowHeaders(pub Vec<String>); impl Header for AccessControlAllowHeaders { @@ -467,7 +467,7 @@ impl HeaderFormat for AccessControlAllowHeaders { } } -#[deriving(Clone)] +#[derive(Clone)] enum AccessControlAllowOrigin { AllowStar, AllowOrigin(Url), @@ -482,7 +482,7 @@ impl Header for AccessControlAllowOrigin { fn parse_header(raw: &[Vec<u8>]) -> Option<AccessControlAllowOrigin> { if raw.len() == 1 { - from_utf8(raw[0].as_slice()).and_then(|s| { + from_utf8(raw[0].as_slice()).ok().and_then(|s| { if s == "*" { Some(AccessControlAllowOrigin::AllowStar) } else { @@ -504,7 +504,7 @@ impl HeaderFormat for AccessControlAllowOrigin { } } -#[deriving(Clone)] +#[derive(Clone)] struct AccessControlMaxAge(pub u32); impl Header for AccessControlMaxAge { diff --git a/components/script/devtools.rs b/components/script/devtools.rs index aedff559fe8..b4e0c4f3777 100644 --- a/components/script/devtools.rs +++ b/components/script/devtools.rs @@ -18,6 +18,8 @@ use dom::document::DocumentHelpers; use page::Page; use servo_msg::constellation_msg::PipelineId; use script_task::get_page; + +use std::sync::mpsc::Sender; use std::rc::Rc; diff --git a/components/script/dom/activation.rs b/components/script/dom/activation.rs index 6299abaa672..78e3d6cd4bb 100644 --- a/components/script/dom/activation.rs +++ b/components/script/dom/activation.rs @@ -11,6 +11,7 @@ use dom::eventtarget::{EventTarget, EventTargetHelpers}; use dom::mouseevent::MouseEvent; use dom::node::window_from_node; +use std::borrow::ToOwned; /// Trait for elements with defined activation behavior pub trait Activatable : Copy { @@ -44,7 +45,7 @@ pub trait Activatable : Copy { // https://html.spec.whatwg.org/multipage/webappapis.html#fire-a-synthetic-mouse-event let win = window_from_node(element.r()).root(); let target: JSRef<EventTarget> = EventTargetCast::from_ref(element.r()); - let mouse = MouseEvent::new(win.r(), "click".into_string(), + let mouse = MouseEvent::new(win.r(), "click".to_owned(), false, false, Some(win.r()), 1, 0, 0, 0, 0, ctrlKey, shiftKey, altKey, metaKey, 0, None).root(); diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs index 9a062679a4f..e8a66199db7 100644 --- a/components/script/dom/attr.rs +++ b/components/script/dom/attr.rs @@ -20,6 +20,7 @@ use servo_util::str::{DOMString, split_html_space_chars}; use string_cache::{Atom, Namespace}; +use std::borrow::ToOwned; use std::cell::Ref; use std::mem; @@ -28,7 +29,7 @@ pub enum AttrSettingType { ReplacedAttr, } -#[deriving(PartialEq, Clone)] +#[derive(PartialEq, Clone)] #[jstraceable] pub enum AttrValue { String(DOMString), @@ -57,7 +58,8 @@ impl AttrValue { } pub fn from_u32(string: DOMString, default: u32) -> AttrValue { - let result: u32 = from_str(string.as_slice()).unwrap_or(default); + // XXX Is parse() correct? + let result: u32 = string.parse().unwrap_or(default); AttrValue::UInt(string, result) } @@ -138,11 +140,11 @@ impl Attr { impl<'a> AttrMethods for JSRef<'a, Attr> { fn LocalName(self) -> DOMString { - self.local_name().as_slice().into_string() + self.local_name().as_slice().to_owned() } fn Value(self) -> DOMString { - self.value().as_slice().into_string() + self.value().as_slice().to_owned() } fn SetValue(self, value: DOMString) { @@ -175,14 +177,14 @@ impl<'a> AttrMethods for JSRef<'a, Attr> { } fn Name(self) -> DOMString { - self.name.as_slice().into_string() + self.name.as_slice().to_owned() } fn GetNamespaceURI(self) -> Option<DOMString> { let Namespace(ref atom) = self.namespace; match atom.as_slice() { "" => None, - url => Some(url.into_string()), + url => Some(url.to_owned()), } } @@ -237,7 +239,7 @@ impl<'a> AttrHelpers<'a> for JSRef<'a, Attr> { fn summarize(self) -> AttrInfo { let Namespace(ref ns) = self.namespace; AttrInfo { - namespace: ns.as_slice().into_string(), + namespace: ns.as_slice().to_owned(), name: self.Name(), value: self.Value(), } diff --git a/components/script/dom/bindings/callback.rs b/components/script/dom/bindings/callback.rs index 6b8fcc09e34..dd0bf8bf65c 100644 --- a/components/script/dom/bindings/callback.rs +++ b/components/script/dom/bindings/callback.rs @@ -2,8 +2,6 @@ * 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/. */ -#![deny(missing_docs)] - //! Base classes to work with IDL callbacks. use dom::bindings::global::global_object_for_js_object; @@ -14,10 +12,11 @@ use js::jsapi::{JS_GetProperty, JS_IsExceptionPending, JS_ReportPendingException use js::jsval::{JSVal, UndefinedValue}; use js::rust::with_compartment; +use std::ffi::CString; use std::ptr; /// The exception handling used for a call. -#[deriving(Copy, PartialEq)] +#[derive(Copy, PartialEq)] pub enum ExceptionHandling { /// Report any exception and don't throw it to the caller code. Report, @@ -26,7 +25,7 @@ pub enum ExceptionHandling { } /// A common base class for representing IDL callback function types. -#[deriving(Copy, Clone,PartialEq)] +#[derive(Copy, Clone,PartialEq)] #[jstraceable] pub struct CallbackFunction { object: CallbackObject @@ -44,7 +43,7 @@ impl CallbackFunction { } /// A common base class for representing IDL callback interface types. -#[deriving(Copy, Clone,PartialEq)] +#[derive(Copy, Clone,PartialEq)] #[jstraceable] pub struct CallbackInterface { object: CallbackObject @@ -52,8 +51,8 @@ pub struct CallbackInterface { /// A common base class for representing IDL callback function and /// callback interface types. -#[allow(raw_pointer_deriving)] -#[deriving(Copy, Clone,PartialEq)] +#[allow(raw_pointer_derive)] +#[derive(Copy, Clone,PartialEq)] #[jstraceable] struct CallbackObject { /// The underlying `JSObject`. @@ -99,7 +98,7 @@ impl CallbackInterface { pub fn GetCallableProperty(&self, cx: *mut JSContext, name: &str) -> Result<JSVal, ()> { let mut callable = UndefinedValue(); unsafe { - let name = name.to_c_str(); + let name = CString::from_slice(name.as_bytes()); if JS_GetProperty(cx, self.callback(), name.as_ptr(), &mut callable) == 0 { return Err(()); } diff --git a/components/script/dom/bindings/cell.rs b/components/script/dom/bindings/cell.rs index 9df1e448cc6..e064bf25bea 100644 --- a/components/script/dom/bindings/cell.rs +++ b/components/script/dom/bindings/cell.rs @@ -2,8 +2,6 @@ * 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/. */ -#![deny(missing_docs)] - //! A shareable mutable container for the DOM. use dom::bindings::trace::JSTraceable; diff --git a/components/script/dom/bindings/codegen/Bindings.conf b/components/script/dom/bindings/codegen/Bindings.conf index 48b6067d00c..439ddfbd59e 100644 --- a/components/script/dom/bindings/codegen/Bindings.conf +++ b/components/script/dom/bindings/codegen/Bindings.conf @@ -15,7 +15,7 @@ DOMInterfaces = { 'Window': { - 'outerObjectHook': 'Some(bindings::utils::outerize_global)', + 'outerObjectHook': 'Some(bindings::utils::outerize_global as extern fn(*mut JSContext, JSHandleObject) -> *mut JSObject)', }, #FIXME(jdm): This should be 'register': False, but then we don't generate enum types diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 3d28cf2bdc9..47dd912d700 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -674,12 +674,12 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, default = "None" else: assert defaultValue.type.tag() == IDLType.Tags.domstring - value = "str::from_utf8(&data).unwrap().into_string()" + value = "str::from_utf8(&data).unwrap().to_owned()" if type.nullable(): value = "Some(%s)" % value default = ( - "const data: [u8, ..%s] = [ %s ];\n" + "const data: [u8; %s] = [ %s ];\n" "%s" % (len(defaultValue.value) + 1, ", ".join(["'" + char + "' as u8" for char in defaultValue.value] + ["0"]), @@ -1189,14 +1189,16 @@ class MethodDefiner(PropertyDefiner): def specData(m): if m.get("methodInfo", True): jitinfo = ("&%s_methodinfo" % m["name"]) - accessor = "genericMethod" + accessor = "genericMethod as NonNullJSNative" else: jitinfo = "0 as *const JSJitInfo" accessor = m.get("nativeName", m["name"]) + if accessor[0:3] != 'JS_': + accessor = "%s as NonNullJSNative" % accessor return (m["name"], accessor, jitinfo, m["length"], m["flags"]) def stringDecl(m): - return "const %s_name: [u8, ..%i] = %s;\n" % (m["name"], len(m["name"]) + 1, + return "const %s_name: [u8; %i] = %s;\n" % (m["name"], len(m["name"]) + 1, str_to_const_array(m["name"])) decls = ''.join([stringDecl(m) for m in array]) @@ -1236,7 +1238,7 @@ class AttrDefiner(PropertyDefiner): accessor = "genericGetter" jitinfo = "&%s_getterinfo" % attr.identifier.name - return ("JSPropertyOpWrapper {op: Some(%(native)s), info: %(info)s as *const JSJitInfo}" + return ("JSPropertyOpWrapper {op: Some(%(native)s as NonNullJSNative), info: %(info)s as *const JSJitInfo}" % {"info" : jitinfo, "native" : accessor}) @@ -1254,7 +1256,7 @@ class AttrDefiner(PropertyDefiner): accessor = "genericSetter" jitinfo = "&%s_setterinfo" % attr.identifier.name - return ("JSStrictPropertyOpWrapper {op: Some(%(native)s), info: %(info)s as *const JSJitInfo}" + return ("JSStrictPropertyOpWrapper {op: Some(%(native)s as NonNullJSNative), info: %(info)s as *const JSJitInfo}" % {"info" : jitinfo, "native" : accessor}) @@ -1264,7 +1266,7 @@ class AttrDefiner(PropertyDefiner): def stringDecl(attr): name = attr.identifier.name - return "const %s_name: [u8, ..%i] = %s;\n" % (name, len(name) + 1, + return "const %s_name: [u8; %i] = %s;\n" % (name, len(name) + 1, str_to_const_array(name)) decls = ''.join([stringDecl(m) for m in array]) @@ -1434,7 +1436,7 @@ class CGDOMJSClass(CGThing): self.descriptor = descriptor def define(self): - traceHook = "Some(%s)" % TRACE_HOOK_NAME + traceHook = 'Some(%s as unsafe extern "C" fn(*mut JSTracer, *mut JSObject))' % TRACE_HOOK_NAME if self.descriptor.isGlobal(): flags = "JSCLASS_IS_GLOBAL | JSCLASS_DOM_GLOBAL" slots = "JSCLASS_GLOBAL_SLOT_COUNT + 1" @@ -1442,7 +1444,7 @@ class CGDOMJSClass(CGThing): flags = "0" slots = "1" return """\ -const Class_name: [u8, ..%i] = %s; +const Class_name: [u8; %i] = %s; static Class: DOMJSClass = DOMJSClass { base: js::Class { name: &Class_name as *const u8 as *const libc::c_char, @@ -1454,7 +1456,7 @@ static Class: DOMJSClass = DOMJSClass { enumerate: Some(JS_EnumerateStub), resolve: Some(JS_ResolveStub), convert: Some(JS_ConvertStub), - finalize: Some(%s), + finalize: Some(%s as unsafe extern "C" fn(*mut JSFreeOp, *mut JSObject)), checkAccess: None, call: None, hasInstance: None, @@ -1526,7 +1528,7 @@ class CGPrototypeJSClass(CGThing): def define(self): return """\ -const PrototypeClassName__: [u8, ..%s] = %s; +const PrototypeClassName__: [u8; %s] = %s; static PrototypeClass: JSClass = JSClass { name: &PrototypeClassName__ as *const u8 as *const libc::c_char, flags: (1 & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT as uint, //JSCLASS_HAS_RESERVED_SLOTS(1) @@ -1543,7 +1545,7 @@ static PrototypeClass: JSClass = JSClass { hasInstance: None, construct: None, trace: None, - reserved: [0 as *mut libc::c_void, ..40] + reserved: [0 as *mut libc::c_void; 40] }; """ % (len(self.descriptor.interface.identifier.name + "Prototype") + 1, str_to_const_array(self.descriptor.interface.identifier.name + "Prototype")) @@ -1992,7 +1994,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod): constructHook = "ThrowingConstructor" constructArgs = 0 - constructor = 'Some((%s, "%s", %d))' % ( + constructor = 'Some((%s as NonNullJSNative, "%s", %d))' % ( constructHook, self.descriptor.interface.identifier.name, constructArgs) else: @@ -2096,16 +2098,16 @@ class CGDefineProxyHandler(CGAbstractMethod): body = """\ let traps = ProxyTraps { - getPropertyDescriptor: Some(getPropertyDescriptor), - getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor), - defineProperty: Some(%s), - getOwnPropertyNames: Some(getOwnPropertyNames_), - delete_: Some(%s), - enumerate: Some(enumerate_), + getPropertyDescriptor: Some(getPropertyDescriptor as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, bool, *mut JSPropertyDescriptor) -> bool), + getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, bool, *mut JSPropertyDescriptor) -> bool), + defineProperty: Some(%s as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, *mut JSPropertyDescriptor) -> bool), + getOwnPropertyNames: Some(getOwnPropertyNames_ as unsafe extern "C" fn(*mut JSContext, *mut JSObject, *mut AutoIdVector) -> bool), + delete_: Some(%s as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, *mut bool) -> bool), + enumerate: Some(enumerate_ as unsafe extern "C" fn(*mut JSContext, *mut JSObject, *mut AutoIdVector) -> bool), has: None, - hasOwn: Some(hasOwn), - get: Some(get), + hasOwn: Some(hasOwn as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, *mut bool) -> bool), + get: Some(get as unsafe extern "C" fn(*mut JSContext, *mut JSObject, *mut JSObject, jsid, *mut JSVal) -> bool), set: None, keys: None, iterate: None, @@ -2116,15 +2118,15 @@ let traps = ProxyTraps { hasInstance: None, typeOf: None, objectClassIs: None, - obj_toString: Some(obj_toString), + obj_toString: Some(obj_toString as unsafe extern "C" fn(*mut JSContext, *mut JSObject) -> *mut js::jsapi::JSString), fun_toString: None, //regexp_toShared: ptr::null(), defaultValue: None, iteratorNext: None, - finalize: Some(%s), + finalize: Some(%s as unsafe extern "C" fn(*mut JSFreeOp, *mut JSObject)), getElementIfPresent: None, getPrototypeOf: None, - trace: Some(%s) + trace: Some(%s as unsafe extern "C" fn(*mut JSTracer, *mut JSObject)) }; CreateProxyHandler(&traps, &Class as *const _ as *const _)\ @@ -2763,7 +2765,7 @@ class CGEnum(CGThing): decl = """\ #[repr(uint)] -#[deriving(PartialEq, Copy)] +#[derive(PartialEq, Copy)] #[jstraceable] pub enum %s { %s @@ -4256,7 +4258,7 @@ class CGNonNamespacedEnum(CGThing): # Build the enum body. enumstr = comment + 'pub enum %s {\n%s\n}\n' % (enumName, ',\n'.join(entries)) if deriving: - enumstr = ('#[deriving(%s)]\n' % deriving) + enumstr + enumstr = ('#[derive(%s)]\n' % deriving) + enumstr curr = CGGeneric(enumstr) # Add some whitespace padding. @@ -4458,7 +4460,7 @@ class CGRegisterProxyHandlers(CGThing): descriptors = config.getDescriptors(proxy=True) length = len(descriptors) self.root = CGList([ - CGGeneric("pub static mut proxy_handlers: [*const libc::c_void, ..%d] = [0 as *const libc::c_void, ..%d];" % (length, length)), + CGGeneric("pub static mut proxy_handlers: [*const libc::c_void; %d] = [0 as *const libc::c_void; %d];" % (length, length)), CGRegisterProxyHandlersMethod(descriptors), ], "\n") @@ -4530,11 +4532,12 @@ class CGBindingRoot(CGThing): 'js::jsapi::{JSPropertyOpWrapper, JSPropertySpec, JS_PropertyStub}', 'js::jsapi::{JSStrictPropertyOpWrapper, JSString, JSTracer, JS_ConvertStub}', 'js::jsapi::{JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub}', + 'js::jsapi::{JSMutableHandleValue, JSHandleId, JSType}', 'js::jsval::JSVal', 'js::jsval::{ObjectValue, ObjectOrNullValue, PrivateValue}', 'js::jsval::{NullValue, UndefinedValue}', 'js::glue::{CallJitMethodOp, CallJitPropertyOp, CreateProxyHandler}', - 'js::glue::{GetProxyPrivate, NewProxyObject, ProxyTraps}', + 'js::glue::{GetProxyPrivate, NewProxyObject, ProxyTraps, AutoIdVector}', 'js::glue::{RUST_FUNCTION_VALUE_TO_JITINFO}', 'js::glue::{RUST_JS_NumberValue, RUST_JSID_IS_STRING}', 'js::rust::with_compartment', @@ -4559,6 +4562,7 @@ class CGBindingRoot(CGThing): 'dom::bindings::utils::get_dictionary_property', 'dom::bindings::utils::{NativeProperties, NativePropertyHooks}', 'dom::bindings::utils::ConstantVal::{IntVal, UintVal}', + 'dom::bindings::utils::NonNullJSNative', 'dom::bindings::trace::JSTraceable', 'dom::bindings::callback::{CallbackContainer,CallbackInterface,CallbackFunction}', 'dom::bindings::callback::{CallSetup,ExceptionHandling}', @@ -4584,6 +4588,7 @@ class CGBindingRoot(CGThing): 'page::JSPageInfo', 'libc', 'servo_util::str::DOMString', + 'std::borrow::ToOwned', 'std::cmp', 'std::iter::repeat', 'std::mem', @@ -4695,7 +4700,7 @@ class CGCallback(CGClass): bases=[ClassBase(baseName)], constructors=self.getConstructors(), methods=realMethods+getters+setters, - decorators="#[deriving(PartialEq,Copy,Clone)]#[jstraceable]") + decorators="#[derive(PartialEq,Copy,Clone)]#[jstraceable]") def getConstructors(self): return [ClassConstructor( @@ -5224,11 +5229,11 @@ class GlobalGenRoots(): CGGeneric("use std::mem;\n\n")] for descriptor in descriptors: name = descriptor.name - protos = [CGGeneric('pub trait %s {}\n' % (name + 'Base'))] + protos = [CGGeneric('pub trait %s : Sized {}\n' % (name + 'Base'))] for proto in descriptor.prototypeChain: protos += [CGGeneric('impl %s for %s {}\n' % (proto + 'Base', descriptor.concreteType))] - derived = [CGGeneric('pub trait %s { fn %s(&self) -> bool; }\n' % + derived = [CGGeneric('pub trait %s : Sized { fn %s(&self) -> bool; }\n' % (name + 'Derived', 'is_' + name.lower()))] for protoName in descriptor.prototypeChain[1:-1]: protoDescriptor = config.getDescriptor(protoName) @@ -5236,7 +5241,8 @@ class GlobalGenRoots(): impl ${selfName} for ${baseName} { #[inline] fn ${fname}(&self) -> bool { - ${parentName}Cast::from_actual(self).${fname}() +let base: &${parentName} = ${parentName}Cast::from_actual(self); + base.${fname}() } }\ """).substitute({'fname': 'is_' + name.lower(), @@ -5247,7 +5253,7 @@ impl ${selfName} for ${baseName} { derived += [CGGeneric('\n')] cast = [CGGeneric(string.Template("""\ -pub trait ${castTraitName} { +pub trait ${castTraitName} : Sized { #[inline(always)] fn to_ref<'a, T: ${toBound}+Reflectable>(base: JSRef<'a, T>) -> Option<JSRef<'a, Self>> { match base.${checkFn}() { diff --git a/components/script/dom/bindings/conversions.rs b/components/script/dom/bindings/conversions.rs index 8e9e656b0c4..13efe243929 100644 --- a/components/script/dom/bindings/conversions.rs +++ b/components/script/dom/bindings/conversions.rs @@ -2,8 +2,6 @@ * 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/. */ -#![deny(missing_docs)] - //! Conversions of Rust values to and from `JSVal`. use dom::bindings::codegen::PrototypeList; @@ -28,6 +26,7 @@ use js::jsval::{UndefinedValue, NullValue, BooleanValue, Int32Value, UInt32Value use js::jsval::{StringValue, ObjectValue, ObjectOrNullValue}; use libc; +use std::borrow::ToOwned; use std::default; use std::slice; @@ -44,7 +43,7 @@ pub trait IDLInterface { } /// A trait to convert Rust types to `JSVal`s. -pub trait ToJSValConvertible for Sized? { +pub trait ToJSValConvertible { /// Convert `self` to a `JSVal`. JSAPI failure causes a task failure. fn to_jsval(&self, cx: *mut JSContext) -> JSVal; } @@ -252,7 +251,7 @@ impl ToJSValConvertible for DOMString { } /// Behavior for stringification of `JSVal`s. -#[deriving(PartialEq)] +#[derive(PartialEq)] pub enum StringificationBehavior { /// Convert `null` to the string `"null"`. Default, @@ -289,7 +288,7 @@ pub fn jsid_to_str(cx: *mut JSContext, id: jsid) -> DOMString { impl FromJSValConvertible<StringificationBehavior> for DOMString { fn from_jsval(cx: *mut JSContext, value: JSVal, nullBehavior: StringificationBehavior) -> Result<DOMString, ()> { if nullBehavior == StringificationBehavior::Empty && value.is_null() { - Ok("".into_string()) + Ok("".to_owned()) } else { let jsstr = unsafe { JS_ValueToString(cx, value) }; if jsstr.is_null() { @@ -497,6 +496,7 @@ impl<T: ToJSValConvertible> ToJSValConvertible for Option<T> { } } +#[old_impl_check] impl<X: default::Default, T: FromJSValConvertible<X>> FromJSValConvertible<()> for Option<T> { fn from_jsval(cx: *mut JSContext, value: JSVal, _: ()) -> Result<Option<T>, ()> { if value.is_null_or_undefined() { diff --git a/components/script/dom/bindings/error.rs b/components/script/dom/bindings/error.rs index 2d02dc08ee9..bed13bcc32d 100644 --- a/components/script/dom/bindings/error.rs +++ b/components/script/dom/bindings/error.rs @@ -4,8 +4,6 @@ //! Utilities to throw exceptions from Rust bindings. -#![deny(missing_docs)] - use dom::bindings::conversions::ToJSValConvertible; use dom::bindings::global::GlobalRef; use dom::domexception::DOMException; @@ -18,10 +16,11 @@ use js::glue::{ReportError}; use js::rust::with_compartment; use libc; +use std::ffi::CString; use std::ptr; /// DOM exceptions that can be thrown by a native DOM method. -#[deriving(Show, Clone)] +#[derive(Show, Clone)] pub enum Error { /// IndexSizeError IndexSize, @@ -95,14 +94,13 @@ pub fn report_pending_exception(cx: *mut JSContext, obj: *mut JSObject) { pub fn throw_not_in_union(cx: *mut JSContext, names: &'static str) -> JSBool { assert!(unsafe { JS_IsExceptionPending(cx) } == 0); let message = format!("argument could not be converted to any of: {}", names); - message.with_c_str(|string| { - unsafe { ReportError(cx, string) }; - }); + let string = CString::from_slice(message.as_bytes()); + unsafe { ReportError(cx, string.as_ptr()) }; return 0; } /// Format string used to throw `TypeError`s. -static ERROR_FORMAT_STRING_STRING: [libc::c_char, ..4] = [ +static ERROR_FORMAT_STRING_STRING: [libc::c_char; 4] = [ '{' as libc::c_char, '0' as libc::c_char, '}' as libc::c_char, @@ -110,7 +108,7 @@ static ERROR_FORMAT_STRING_STRING: [libc::c_char, ..4] = [ ]; /// Format string struct used to throw `TypeError`s. -static ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString { +static mut ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString { format: &ERROR_FORMAT_STRING_STRING as *const libc::c_char, argCount: 1, exnType: JSEXN_TYPEERR as i16, @@ -127,8 +125,12 @@ unsafe extern fn get_error_message(_user_ref: *mut libc::c_void, /// Throw a `TypeError` with the given message. pub fn throw_type_error(cx: *mut JSContext, error: &str) { - let error = error.to_c_str(); + let error = CString::from_slice(error.as_bytes()); unsafe { - JS_ReportErrorNumber(cx, Some(get_error_message), ptr::null_mut(), 0, error.as_ptr()); + JS_ReportErrorNumber(cx, + Some(get_error_message as + unsafe extern "C" fn(*mut libc::c_void, *const libc::c_char, + libc::c_uint) -> *const JSErrorFormatString), + ptr::null_mut(), 0, error.as_ptr()); } } diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs index 94a9fdf0cd4..b53ab37c880 100644 --- a/components/script/dom/bindings/global.rs +++ b/components/script/dom/bindings/global.rs @@ -7,8 +7,6 @@ //! This module contains smart pointers to global scopes, to simplify writing //! code that works in workers as well as window scopes. -#[deny(missing_docs)] - use dom::bindings::conversions::FromJSValConvertible; use dom::bindings::js::{JS, JSRef, Root}; use dom::bindings::utils::{Reflectable, Reflector}; @@ -28,7 +26,7 @@ use url::Url; use std::ptr; /// A freely-copyable reference to a rooted global object. -#[deriving(Copy)] +#[derive(Copy)] pub enum GlobalRef<'a> { /// A reference to a `Window` object. Window(JSRef<'a, window::Window>), diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs index ac8da0f8ba6..f4c76dd4b07 100644 --- a/components/script/dom/bindings/js.rs +++ b/components/script/dom/bindings/js.rs @@ -42,7 +42,6 @@ //! - `OptionalRootable` and `OptionalRootedRootable`: make rooting `Option` values easy via a `root` method //! - `ResultRootable`: make rooting successful `Result` values easy //! - `TemporaryPushable`: allows mutating vectors of `JS<T>` with new elements of `JSRef`/`Temporary` -//! - `OptionalSettable`: allows assigning `Option` values of `JSRef`/`Temporary` to fields of `Option<JS<T>>` //! - `RootedReference`: makes obtaining an `Option<JSRef<T>>` from an `Option<Root<T>>` easy use dom::bindings::trace::JSTraceable; @@ -56,8 +55,9 @@ use script_task::STACK_ROOTS; use servo_util::smallvec::{SmallVec, SmallVec16}; use std::cell::{Cell, UnsafeCell}; use std::default::Default; -use std::kinds::marker::ContravariantLifetime; +use std::marker::ContravariantLifetime; use std::mem; +use std::ops::Deref; /// A type that represents a JS-owned value that is rooted for the lifetime of this value. /// Importantly, it requires explicit rooting in order to interact with the inner value. @@ -113,6 +113,8 @@ impl<T: Reflectable> Temporary<T> { self.inner.clone() } + /// Returns `self` as a `Temporary` of another type. For use by + /// `InheritTypes` only. //XXXjdm It would be lovely if this could be private. pub unsafe fn transmute<To>(self) -> Temporary<To> { mem::transmute(self) @@ -173,8 +175,9 @@ impl<T: Reflectable> JS<T> { } } -impl<T: Assignable<U>, U: Reflectable> JS<U> { - pub fn from_rooted(root: T) -> JS<U> { +impl<U: Reflectable> JS<U> { + /// Create a `JS<T>` from any JS-managed pointer. + pub fn from_rooted<T: Assignable<U>>(root: T) -> JS<U> { unsafe { root.get_js() } @@ -191,6 +194,10 @@ impl<T: Reflectable> Reflectable for JS<T> { } } +/// A trait to be implemented for JS-managed types that can be stored in +/// mutable member fields. +/// +/// Do not implement this trait yourself. pub trait HeapGCValue: JSTraceable { } @@ -210,16 +217,20 @@ pub struct MutHeap<T: HeapGCValue+Copy> { } impl<T: HeapGCValue+Copy> MutHeap<T> { + /// Create a new `MutHeap`. pub fn new(initial: T) -> MutHeap<T> { MutHeap { val: Cell::new(initial), } } + /// Set this `MutHeap` to the given value, calling write barriers as + /// appropriate. pub fn set(&self, val: T) { self.val.set(val) } + /// Set the value in this `MutHeap`, calling read barriers as appropriate. pub fn get(&self) -> T { self.val.get() } @@ -234,8 +245,9 @@ pub struct MutNullableJS<T: Reflectable> { ptr: Cell<Option<JS<T>>> } -impl<T: Assignable<U>, U: Reflectable> MutNullableJS<U> { - pub fn new(initial: Option<T>) -> MutNullableJS<U> { +impl<U: Reflectable> MutNullableJS<U> { + /// Create a new `MutNullableJS` + pub fn new<T: Assignable<U>>(initial: Option<T>) -> MutNullableJS<U> { MutNullableJS { ptr: Cell::new(initial.map(|initial| { unsafe { initial.get_js() } @@ -280,7 +292,11 @@ impl<T: Reflectable> MutNullableJS<T> { self.ptr.get() } - pub fn or_init(&self, cb: || -> Temporary<T>) -> Temporary<T> { + /// Retrieve a copy of the current inner value. If it is `None`, it is + /// initialized with the result of `cb` first. + pub fn or_init<F>(&self, cb: F) -> Temporary<T> + where F: FnOnce() -> Temporary<T> + { match self.get() { Some(inner) => inner, None => { @@ -293,11 +309,11 @@ impl<T: Reflectable> MutNullableJS<T> { } impl<T: Reflectable> JS<T> { - /// Returns an unsafe pointer to the interior of this JS object without touching the borrow - /// flags. This is the only method that be safely accessed from layout. (The fact that this - /// is unsafe is what necessitates the layout wrappers.) - pub unsafe fn unsafe_get(&self) -> *mut T { - mem::transmute_copy(&self.ptr) + /// Returns an unsafe pointer to the interior of this object. This is the + /// only method that be safely accessed from layout. (The fact that this is + /// unsafe is what necessitates the layout wrappers.) + pub unsafe fn unsafe_get(&self) -> *const T { + self.ptr } /// Store an unrooted value in this field. This is safe under the assumption that JS<T> @@ -308,13 +324,15 @@ impl<T: Reflectable> JS<T> { } } -impl<From, To> JS<From> { +impl<From> JS<From> { + /// Return `self` as a `JS` of another type. //XXXjdm It would be lovely if this could be private. - pub unsafe fn transmute(self) -> JS<To> { + pub unsafe fn transmute<To>(self) -> JS<To> { mem::transmute(self) } - pub unsafe fn transmute_copy(&self) -> JS<To> { + /// Return `self` as a `JS` of another type. + pub unsafe fn transmute_copy<To>(&self) -> JS<To> { mem::transmute_copy(self) } } @@ -322,6 +340,8 @@ impl<From, To> JS<From> { /// Get an `Option<JSRef<T>>` out of an `Option<Root<T>>` pub trait RootedReference<T> { + /// Obtain a safe optional reference to the wrapped JS owned-value that + /// cannot outlive the lifetime of this root. fn r<'a>(&'a self) -> Option<JSRef<'a, T>>; } @@ -333,6 +353,8 @@ impl<T: Reflectable> RootedReference<T> for Option<Root<T>> { /// Get an `Option<Option<JSRef<T>>>` out of an `Option<Option<Root<T>>>` pub trait OptionalRootedReference<T> { + /// Obtain a safe optional optional reference to the wrapped JS owned-value + /// that cannot outlive the lifetime of this root. fn r<'a>(&'a self) -> Option<Option<JSRef<'a, T>>>; } @@ -346,6 +368,7 @@ impl<T: Reflectable> OptionalRootedReference<T> for Option<Option<Root<T>>> { /// which in general is an unsafe operation since they can outlive the rooted lifetime of the /// original value. pub trait Assignable<T> { + /// Extract an unrooted `JS<T>`. unsafe fn get_js(&self) -> JS<T>; } @@ -367,21 +390,10 @@ impl<T: Reflectable> Assignable<T> for Temporary<T> { } } -/// Assign an optional rootable value (either of `JS<T>` or `Temporary<T>`) to an optional -/// field of a DOM type (ie. `Option<JS<T>>`) -pub trait OptionalSettable<T> { - fn assign(&self, val: Option<T>); -} - -impl<T: Assignable<U>, U: Reflectable> OptionalSettable<T> for Cell<Option<JS<U>>> { - fn assign(&self, val: Option<T>) { - self.set(val.map(|val| unsafe { val.get_js() })); - } -} - /// Root a rootable `Option` type (used for `Option<Temporary<T>>`) pub trait OptionalRootable<T> { + /// Root the inner value, if it exists. fn root(self) -> Option<Root<T>>; } @@ -393,6 +405,7 @@ impl<T: Reflectable> OptionalRootable<T> for Option<Temporary<T>> { /// Return an unrooted type for storing in optional DOM fields pub trait OptionalUnrootable<T> { + /// Returns a `JS<T>` for the inner value, if it exists. fn unrooted(&self) -> Option<JS<T>>; } @@ -404,6 +417,7 @@ impl<'a, T: Reflectable> OptionalUnrootable<T> for Option<JSRef<'a, T>> { /// Root a rootable `Option` type (used for `Option<JS<T>>`) pub trait OptionalRootedRootable<T> { + /// Root the inner value, if it exists. fn root(&self) -> Option<Root<T>>; } @@ -415,6 +429,7 @@ impl<T: Reflectable> OptionalRootedRootable<T> for Option<JS<T>> { /// Root a rootable `Option<Option>` type (used for `Option<Option<JS<T>>>`) pub trait OptionalOptionalRootedRootable<T> { + /// Root the inner value, if it exists. fn root(&self) -> Option<Option<Root<T>>>; } @@ -427,6 +442,7 @@ impl<T: Reflectable> OptionalOptionalRootedRootable<T> for Option<Option<JS<T>>> /// Root a rootable `Result` type (any of `Temporary<T>` or `JS<T>`) pub trait ResultRootable<T,U> { + /// Root the inner value, if it exists. fn root(self) -> Result<Root<T>, U>; } @@ -446,7 +462,9 @@ impl<T: Reflectable, U> ResultRootable<T, U> for Result<JS<T>, U> { /// under the assumption that said lists are reachable via the GC graph, and therefore the /// new values are transitively rooted for the lifetime of their new owner. pub trait TemporaryPushable<T> { + /// Push a new value onto this container. fn push_unrooted(&mut self, val: &T); + /// Insert a new value into this container. fn insert_unrooted(&mut self, index: uint, val: &T); } @@ -465,6 +483,7 @@ pub struct RootCollection { roots: UnsafeCell<SmallVec16<*mut JSObject>>, } +/// A pointer to a RootCollection, for use in global variables. pub struct RootCollectionPtr(pub *const RootCollection); impl Copy for RootCollectionPtr {} @@ -482,7 +501,7 @@ impl RootCollection { unsafe { let roots = self.roots.get(); (*roots).push(untracked.js_ptr); - debug!(" rooting {}", untracked.js_ptr); + debug!(" rooting {:?}", untracked.js_ptr); } } @@ -490,7 +509,7 @@ impl RootCollection { fn unroot<'b, T: Reflectable>(&self, rooted: &Root<T>) { unsafe { let roots = self.roots.get(); - debug!("unrooting {} (expecting {}", + debug!("unrooting {:?} (expecting {:?}", (*roots).as_slice().last().unwrap(), rooted.js_ptr); assert!(*(*roots).as_slice().last().unwrap() == rooted.js_ptr); @@ -547,13 +566,15 @@ impl<T: Reflectable> Drop for Root<T> { } } -impl<'b, T: Reflectable> Deref<JSRef<'b, T>> for Root<T> { +impl<'b, T: Reflectable> Deref for Root<T> { + type Target = JSRef<'b, T>; fn deref<'c>(&'c self) -> &'c JSRef<'b, T> { &self.jsref } } -impl<'a, T: Reflectable> Deref<T> for JSRef<'a, T> { +impl<'a, T: Reflectable> Deref for JSRef<'a, T> { + type Target = T; fn deref<'b>(&'b self) -> &'b T { unsafe { &*self.ptr @@ -585,16 +606,19 @@ impl<'a, T> PartialEq for JSRef<'a, T> { } impl<'a,T> JSRef<'a,T> { + /// Return `self` as a `JSRef` of another type. //XXXjdm It would be lovely if this could be private. pub unsafe fn transmute<To>(self) -> JSRef<'a, To> { mem::transmute(self) } + /// Return `self` as a borrowed reference to a `JSRef` of another type. // FIXME(zwarich): It would be nice to get rid of this entirely. pub unsafe fn transmute_borrowed<'b, To>(&'b self) -> &'b JSRef<'a, To> { mem::transmute(self) } + /// Return an unrooted `JS<T>` for the inner pointer. pub fn unrooted(&self) -> JS<T> { JS { ptr: self.ptr @@ -603,6 +627,7 @@ impl<'a,T> JSRef<'a,T> { } impl<'a, T: Reflectable> JSRef<'a, T> { + /// Returns the inner pointer directly. pub fn extended_deref(self) -> &'a T { unsafe { &*self.ptr @@ -611,13 +636,14 @@ impl<'a, T: Reflectable> JSRef<'a, T> { } impl<'a, T: Reflectable> Reflectable for JSRef<'a, T> { - fn reflector<'a>(&'a self) -> &'a Reflector { - self.deref().reflector() + fn reflector<'b>(&'b self) -> &'b Reflector { + (**self).reflector() } } /// A trait for comparing smart pointers ignoring the lifetimes pub trait Comparable<T> { + /// Returns whether the other value points to the same object. fn equals(&self, other: T) -> bool; } diff --git a/components/script/dom/bindings/proxyhandler.rs b/components/script/dom/bindings/proxyhandler.rs index 20bf723513f..53e69c48e84 100644 --- a/components/script/dom/bindings/proxyhandler.rs +++ b/components/script/dom/bindings/proxyhandler.rs @@ -2,7 +2,9 @@ * 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/. */ -///! Utilities for the implementation of JSAPI proxy handlers. +//! Utilities for the implementation of JSAPI proxy handlers. + +#![deny(missing_docs)] use dom::bindings::conversions::is_dom_proxy; use dom::bindings::utils::delete_property_by_id; @@ -25,6 +27,10 @@ use std::ptr; static JSPROXYSLOT_EXPANDO: u32 = 0; +/// Invoke the [[GetOwnProperty]] trap (`getOwnPropertyDescriptor`) on `proxy`, +/// with argument `id` and return the result, if it is not `undefined`. +/// Otherwise, walk along the prototype chain to find a property with that +/// name. pub unsafe extern fn getPropertyDescriptor(cx: *mut JSContext, proxy: *mut JSObject, id: jsid, set: bool, desc: *mut JSPropertyDescriptor) @@ -47,6 +53,7 @@ pub unsafe extern fn getPropertyDescriptor(cx: *mut JSContext, proxy: *mut JSObj JS_GetPropertyDescriptorById(cx, proto, id, JSRESOLVE_QUALIFIED, desc) != 0 } +/// Defines an expando on the given `proxy`. pub unsafe extern fn defineProperty_(cx: *mut JSContext, proxy: *mut JSObject, id: jsid, desc: *mut JSPropertyDescriptor) -> bool { static JSMSG_GETTER_ONLY: libc::c_uint = 160; @@ -63,24 +70,23 @@ pub unsafe extern fn defineProperty_(cx: *mut JSContext, proxy: *mut JSObject, i } let expando = EnsureExpandoObject(cx, proxy); - if expando.is_null() { - return false; - } - return JS_DefinePropertyById(cx, expando, id, (*desc).value, (*desc).getter, (*desc).setter, (*desc).attrs) != 0; } +/// Deletes an expando off the given `proxy`. pub unsafe extern fn delete_(cx: *mut JSContext, proxy: *mut JSObject, id: jsid, bp: *mut bool) -> bool { - let expando = EnsureExpandoObject(cx, proxy); + let expando = GetExpandoObject(proxy); if expando.is_null() { - return false; + *bp = true; + return true; } return delete_property_by_id(cx, expando, id, &mut *bp); } +/// Returns the stringification of an object with class `name`. pub fn _obj_toString(cx: *mut JSContext, name: &str) -> *mut JSString { unsafe { let result = format!("[object {}]", name); @@ -94,6 +100,7 @@ pub fn _obj_toString(cx: *mut JSContext, name: &str) -> *mut JSString { } } +/// Get the expando object, or null if there is none. pub fn GetExpandoObject(obj: *mut JSObject) -> *mut JSObject { unsafe { assert!(is_dom_proxy(obj)); @@ -106,6 +113,8 @@ pub fn GetExpandoObject(obj: *mut JSObject) -> *mut JSObject { } } +/// Get the expando object, or create it if it doesn't exist yet. +/// Fails on JSAPI failure. pub fn EnsureExpandoObject(cx: *mut JSContext, obj: *mut JSObject) -> *mut JSObject { unsafe { assert!(is_dom_proxy(obj)); @@ -114,9 +123,7 @@ pub fn EnsureExpandoObject(cx: *mut JSContext, obj: *mut JSObject) -> *mut JSObj expando = JS_NewObjectWithGivenProto(cx, ptr::null_mut(), ptr::null_mut(), GetObjectParent(obj)); - if expando.is_null() { - return ptr::null_mut(); - } + assert!(!expando.is_null()); SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, ObjectValue(&*expando)); } @@ -124,6 +131,8 @@ pub fn EnsureExpandoObject(cx: *mut JSContext, obj: *mut JSObject) -> *mut JSObj } } +/// Set the property descriptor's object to `obj` and set it to enumerable, +/// and writable if `readonly` is true. pub fn FillPropertyDescriptor(desc: &mut JSPropertyDescriptor, obj: *mut JSObject, readonly: bool) { desc.obj = obj; desc.attrs = if readonly { JSPROP_READONLY } else { 0 } | JSPROP_ENUMERATE; @@ -132,12 +141,14 @@ pub fn FillPropertyDescriptor(desc: &mut JSPropertyDescriptor, obj: *mut JSObjec desc.shortid = 0; } +/// No-op required hook. pub unsafe extern fn getOwnPropertyNames_(_cx: *mut JSContext, _obj: *mut JSObject, _v: *mut AutoIdVector) -> bool { true } +/// No-op required hook. pub unsafe extern fn enumerate_(_cx: *mut JSContext, _obj: *mut JSObject, _v: *mut AutoIdVector) -> bool { true diff --git a/components/script/dom/bindings/refcounted.rs b/components/script/dom/bindings/refcounted.rs index adf7d71fde5..742f187e061 100644 --- a/components/script/dom/bindings/refcounted.rs +++ b/components/script/dom/bindings/refcounted.rs @@ -2,8 +2,6 @@ * 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/. */ -#![deny(missing_docs)] - //! A generic, safe mechnanism by which DOM objects can be pinned and transferred //! between tasks (or intra-task for asynchronous events). Akin to Gecko's //! nsMainThreadPtrHandle, this uses thread-safe reference counting and ensures @@ -32,12 +30,17 @@ use js::jsapi::{JS_AddObjectRoot, JS_RemoveObjectRoot, JSContext}; use libc; use std::cell::RefCell; -use std::collections::hash_map::{HashMap, Vacant, Occupied}; +use std::collections::hash_map::HashMap; +use std::collections::hash_map::Entry::{Vacant, Occupied}; use std::rc::Rc; use std::sync::{Arc, Mutex}; -thread_local!(pub static LIVE_REFERENCES: Rc<RefCell<Option<LiveDOMReferences>>> = Rc::new(RefCell::new(None))) +thread_local!(pub static LIVE_REFERENCES: Rc<RefCell<Option<LiveDOMReferences>>> = Rc::new(RefCell::new(None))); + +/// A pointer to a Rust DOM object that needs to be destroyed. +pub struct TrustedReference(*const libc::c_void); +unsafe impl Send for TrustedReference {} /// A safe wrapper around a raw pointer to a DOM object that can be /// shared among tasks for use in asynchronous operations. The underlying @@ -52,6 +55,8 @@ pub struct Trusted<T> { owner_thread: *const libc::c_void, } +unsafe impl<T: Reflectable> Send for Trusted<T> {} + impl<T: Reflectable> Trusted<T> { /// Create a new `Trusted<T>` instance from an existing DOM pointer. The DOM object will /// be prevented from being GCed for the duration of the resulting `Trusted<T>` object's @@ -88,7 +93,7 @@ impl<T: Reflectable> Trusted<T> { impl<T: Reflectable> Clone for Trusted<T> { fn clone(&self) -> Trusted<T> { { - let mut refcount = self.refcount.lock(); + let mut refcount = self.refcount.lock().unwrap(); *refcount += 1; } @@ -104,11 +109,12 @@ impl<T: Reflectable> Clone for Trusted<T> { #[unsafe_destructor] impl<T: Reflectable> Drop for Trusted<T> { fn drop(&mut self) { - let mut refcount = self.refcount.lock(); + let mut refcount = self.refcount.lock().unwrap(); assert!(*refcount > 0); *refcount -= 1; if *refcount == 0 { - self.script_chan.send(ScriptMsg::RefcountCleanup(self.ptr)); + self.script_chan.send( + ScriptMsg::RefcountCleanup(TrustedReference(self.ptr))); } } } @@ -135,7 +141,7 @@ impl LiveDOMReferences { match table.entry(ptr as *const libc::c_void) { Occupied(mut entry) => { let refcount = entry.get_mut(); - *refcount.lock() += 1; + *refcount.lock().unwrap() += 1; refcount.clone() } Vacant(entry) => { @@ -144,14 +150,15 @@ impl LiveDOMReferences { JS_AddObjectRoot(cx, rootable); } let refcount = Arc::new(Mutex::new(1)); - entry.set(refcount.clone()); + entry.insert(refcount.clone()); refcount } } } /// Unpin the given DOM object if its refcount is 0. - pub fn cleanup(cx: *mut JSContext, raw_reflectable: *const libc::c_void) { + pub fn cleanup(cx: *mut JSContext, raw_reflectable: TrustedReference) { + let TrustedReference(raw_reflectable) = raw_reflectable; LIVE_REFERENCES.with(|ref r| { let r = r.borrow(); let live_references = r.as_ref().unwrap(); @@ -159,7 +166,7 @@ impl LiveDOMReferences { let mut table = live_references.table.borrow_mut(); match table.entry(raw_reflectable) { Occupied(entry) => { - if *entry.get().lock() != 0 { + if *entry.get().lock().unwrap() != 0 { // there could have been a new reference taken since // this message was dispatched. return; @@ -168,7 +175,7 @@ impl LiveDOMReferences { unsafe { JS_RemoveObjectRoot(cx, (*reflectable).rootable()); } - let _ = entry.take(); + let _ = entry.remove(); } Vacant(_) => { // there could be a cleanup message dispatched, then a new diff --git a/components/script/dom/bindings/str.rs b/components/script/dom/bindings/str.rs index c252a8a3e21..f9ac9947af8 100644 --- a/components/script/dom/bindings/str.rs +++ b/components/script/dom/bindings/str.rs @@ -2,16 +2,15 @@ * 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/. */ -#![deny(missing_docs)] - //! The `ByteString` struct. -use std::hash::{Hash, sip}; +use std::borrow::ToOwned; +use std::hash::{Hash, SipHasher}; use std::str; use std::str::FromStr; /// Encapsulates the IDL `ByteString` type. -#[deriving(Clone,Eq,PartialEq)] +#[derive(Clone,Eq,PartialEq)] #[jstraceable] pub struct ByteString(Vec<u8>); @@ -25,7 +24,7 @@ impl ByteString { /// otherwise. pub fn as_str<'a>(&'a self) -> Option<&'a str> { let ByteString(ref vec) = *self; - str::from_utf8(vec.as_slice()) + str::from_utf8(vec.as_slice()).ok() } /// Returns the underlying vector as a slice. @@ -83,7 +82,7 @@ impl ByteString { /// [RFC 2616](http://tools.ietf.org/html/rfc2616#page-32). pub fn is_field_value(&self) -> bool { // Classifications of characters necessary for the [CRLF] (SP|HT) rule - #[deriving(PartialEq)] + #[derive(PartialEq)] enum PreviousCharacter { Other, CR, @@ -145,8 +144,8 @@ impl ByteString { } } -impl Hash for ByteString { - fn hash(&self, state: &mut sip::SipState) { +impl Hash<SipHasher> for ByteString { + fn hash(&self, state: &mut SipHasher) { let ByteString(ref vec) = *self; vec.hash(state); } @@ -154,6 +153,6 @@ impl Hash for ByteString { impl FromStr for ByteString { fn from_str(s: &str) -> Option<ByteString> { - Some(ByteString::new(s.into_string().into_bytes())) + Some(ByteString::new(s.to_owned().into_bytes())) } } diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index f426c6f4677..bdcdc140028 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -2,6 +2,9 @@ * 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/. */ +//! This module implements structured cloning, as defined by [HTML] +//! (https://html.spec.whatwg.org/multipage/#safe-passing-of-structured-data). + use dom::bindings::error::Fallible; use dom::bindings::error::Error::DataClone; use dom::bindings::global::GlobalRef; @@ -15,12 +18,14 @@ use js::jsval::{JSVal, UndefinedValue}; use libc::size_t; use std::ptr; +/// A buffer for a structured clone. pub struct StructuredCloneData { data: *mut u64, nbytes: size_t, } impl StructuredCloneData { + /// Writes a structured clone. Returns a `DataClone` error if that fails. pub fn write(cx: *mut JSContext, message: JSVal) -> Fallible<StructuredCloneData> { let mut data = ptr::null_mut(); @@ -39,6 +44,9 @@ impl StructuredCloneData { }) } + /// Reads a structured clone. + /// + /// Panics if `JS_ReadStructuredClone` fails. pub fn read(self, global: GlobalRef) -> JSVal { let mut message = UndefinedValue(); unsafe { @@ -50,3 +58,5 @@ impl StructuredCloneData { message } } + +unsafe impl Send for StructuredCloneData {} diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index ff730ea1e12..1d19d5d8c41 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -2,8 +2,6 @@ * 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/. */ -#![deny(missing_docs)] - //! Utilities for tracing JS-managed values. //! //! The lifetime of DOM objects is managed by the SpiderMonkey Garbage @@ -33,7 +31,6 @@ use dom::bindings::utils::{Reflectable, Reflector, WindowProxyHandler}; use dom::node::{Node, TrustedNodeAddress}; use script_task::ScriptChan; -use collections::hash::{Hash, Hasher}; use cssparser::RGBA; use geom::rect::Rect; use html5ever::tree_builder::QuirksMode; @@ -54,9 +51,12 @@ use servo_util::smallvec::{SmallVec1, SmallVec}; use servo_util::str::{LengthOrPercentageOrAuto}; use std::cell::{Cell, RefCell}; use std::collections::HashMap; -use std::comm::{Receiver, Sender}; +use std::collections::hash_state::HashState; +use std::ffi::CString; +use std::hash::{Hash, Hasher}; use std::io::timer::Timer; use std::rc::Rc; +use std::sync::mpsc::{Receiver, Sender}; use string_cache::{Atom, Namespace}; use style::PropertyDeclarationBlock; use url::Url; @@ -74,7 +74,7 @@ impl<T: Reflectable> JSTraceable for JS<T> { } } -no_jsmanaged_fields!(Reflector) +no_jsmanaged_fields!(Reflector); /// Trace a `JSVal`. pub fn trace_jsval(tracer: *mut JSTracer, description: &str, val: JSVal) { @@ -83,7 +83,7 @@ pub fn trace_jsval(tracer: *mut JSTracer, description: &str, val: JSVal) { } unsafe { - let name = description.to_c_str(); + let name = CString::from_slice(description.as_bytes()); (*tracer).debugPrinter = None; (*tracer).debugPrintIndex = -1; (*tracer).debugPrintArg = name.as_ptr() as *const libc::c_void; @@ -101,7 +101,7 @@ pub fn trace_reflector(tracer: *mut JSTracer, description: &str, reflector: &Ref /// Trace a `JSObject`. pub fn trace_object(tracer: *mut JSTracer, description: &str, obj: *mut JSObject) { unsafe { - let name = description.to_c_str(); + let name = CString::from_slice(description.as_bytes()); (*tracer).debugPrinter = None; (*tracer).debugPrintIndex = -1; (*tracer).debugPrintArg = name.as_ptr() as *const libc::c_void; @@ -175,14 +175,17 @@ impl<T: JSTraceable> JSTraceable for Option<T> { } } -impl<K,V,S,H> JSTraceable for HashMap<K, V, H> where K: Eq + Hash<S> + JSTraceable, - V: JSTraceable, - H: Hasher<S> { +impl<K,V,S> JSTraceable for HashMap<K, V, S> + where K: Hash<<S as HashState>::Hasher> + Eq + JSTraceable, + V: JSTraceable, + S: HashState, + <S as HashState>::Hasher: Hasher<Output=u64>, +{ #[inline] fn trace(&self, trc: *mut JSTracer) { - for e in self.iter() { - e.val0().trace(trc); - e.val1().trace(trc); + for (k, v) in self.iter() { + k.trace(trc); + v.trace(trc); } } } @@ -197,28 +200,28 @@ impl<A: JSTraceable, B: JSTraceable> JSTraceable for (A, B) { } -no_jsmanaged_fields!(bool, f32, f64, String, Url) -no_jsmanaged_fields!(uint, u8, u16, u32, u64) -no_jsmanaged_fields!(int, i8, i16, i32, i64) -no_jsmanaged_fields!(Sender<T>) -no_jsmanaged_fields!(Receiver<T>) -no_jsmanaged_fields!(Rect<T>) -no_jsmanaged_fields!(ImageCacheTask, ScriptControlChan) -no_jsmanaged_fields!(Atom, Namespace, Timer) -no_jsmanaged_fields!(Trusted<T>) -no_jsmanaged_fields!(PropertyDeclarationBlock) +no_jsmanaged_fields!(bool, f32, f64, String, Url); +no_jsmanaged_fields!(uint, u8, u16, u32, u64); +no_jsmanaged_fields!(int, i8, i16, i32, i64); +no_jsmanaged_fields!(Sender<T>); +no_jsmanaged_fields!(Receiver<T>); +no_jsmanaged_fields!(Rect<T>); +no_jsmanaged_fields!(ImageCacheTask, ScriptControlChan); +no_jsmanaged_fields!(Atom, Namespace, Timer); +no_jsmanaged_fields!(Trusted<T>); +no_jsmanaged_fields!(PropertyDeclarationBlock); // These three are interdependent, if you plan to put jsmanaged data // in one of these make sure it is propagated properly to containing structs -no_jsmanaged_fields!(SubpageId, WindowSizeData, PipelineId) -no_jsmanaged_fields!(QuirksMode) -no_jsmanaged_fields!(Cx) -no_jsmanaged_fields!(Headers, Method) -no_jsmanaged_fields!(ConstellationChan) -no_jsmanaged_fields!(LayoutChan) -no_jsmanaged_fields!(WindowProxyHandler) -no_jsmanaged_fields!(UntrustedNodeAddress) -no_jsmanaged_fields!(LengthOrPercentageOrAuto) -no_jsmanaged_fields!(RGBA) +no_jsmanaged_fields!(SubpageId, WindowSizeData, PipelineId); +no_jsmanaged_fields!(QuirksMode); +no_jsmanaged_fields!(Cx); +no_jsmanaged_fields!(Headers, Method); +no_jsmanaged_fields!(ConstellationChan); +no_jsmanaged_fields!(LayoutChan); +no_jsmanaged_fields!(WindowProxyHandler); +no_jsmanaged_fields!(UntrustedNodeAddress); +no_jsmanaged_fields!(LengthOrPercentageOrAuto); +no_jsmanaged_fields!(RGBA); impl JSTraceable for Box<ScriptChan+Send> { #[inline] diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs index 13d662ae5f7..2819018cf27 100644 --- a/components/script/dom/bindings/utils.rs +++ b/components/script/dom/bindings/utils.rs @@ -2,8 +2,6 @@ * 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/. */ -#![deny(missing_docs)] - //! Various utilities to glue JavaScript and the DOM implementation together. use dom::bindings::codegen::PrototypeList; @@ -18,6 +16,7 @@ use dom::window; use libc; use libc::c_uint; use std::cell::Cell; +use std::ffi::CString; use std::mem; use std::ptr; use js::glue::UnwrapObject; @@ -48,7 +47,7 @@ use js; /// Proxy handler for a WindowProxy. pub struct WindowProxyHandler(pub *const libc::c_void); -#[allow(raw_pointer_deriving)] +#[allow(raw_pointer_derive)] #[jstraceable] /// Static data associated with a global object. pub struct GlobalStaticData { @@ -84,7 +83,7 @@ pub const DOM_PROTOTYPE_SLOT: u32 = js::JSCLASS_GLOBAL_SLOT_COUNT; pub const JSCLASS_DOM_GLOBAL: u32 = js::JSCLASS_USERBIT1; /// Representation of an IDL constant value. -#[deriving(Clone)] +#[derive(Clone)] pub enum ConstantVal { /// `long` constant. IntVal(i32), @@ -99,7 +98,7 @@ pub enum ConstantVal { } /// Representation of an IDL constant. -#[deriving(Clone)] +#[derive(Clone)] pub struct ConstantSpec { /// name of the constant. pub name: &'static [u8], @@ -130,24 +129,26 @@ pub struct NativePropertyHooks { } /// The struct that holds inheritance information for DOM object reflectors. -#[deriving(Copy)] +#[derive(Copy)] pub struct DOMClass { /// A list of interfaces that this object implements, in order of decreasing /// derivedness. - pub interface_chain: [PrototypeList::ID, ..MAX_PROTO_CHAIN_LENGTH], + pub interface_chain: [PrototypeList::ID; MAX_PROTO_CHAIN_LENGTH], /// The NativePropertyHooks for the interface associated with this class. pub native_hooks: &'static NativePropertyHooks, } +unsafe impl Sync for DOMClass {} /// The JSClass used for DOM object reflectors. -#[deriving(Copy)] +#[derive(Copy)] pub struct DOMJSClass { /// The actual JSClass. pub base: js::Class, /// Associated data for DOM object reflectors. pub dom_class: DOMClass } +unsafe impl Sync for DOMJSClass {} /// Returns the ProtoOrIfaceArray for the given global object. /// Fails if `global` is not a DOM global object. @@ -172,6 +173,7 @@ pub struct NativeProperties { /// Static attributes for the interface. pub staticAttrs: Option<&'static [JSPropertySpec]>, } +unsafe impl Sync for NativeProperties {} /// A JSNative that cannot be null. pub type NonNullJSNative = @@ -196,7 +198,7 @@ pub fn CreateInterfaceObjects2(cx: *mut JSContext, global: *mut JSObject, receiv match constructor { Some((native, name, nargs)) => { - let s = name.to_c_str(); + let s = CString::from_slice(name.as_bytes()); CreateInterfaceObject(cx, global, receiver, native, nargs, proto, members, s.as_ptr()) @@ -322,7 +324,7 @@ pub unsafe extern fn ThrowingConstructor(cx: *mut JSContext, _argc: c_uint, _vp: /// Construct and cache the ProtoOrIfaceArray for the given global. /// Fails if the argument is not a DOM global. pub fn initialize_global(global: *mut JSObject) { - let protoArray = box () ([0 as *mut JSObject, ..PrototypeList::ID::Count as uint]); + let protoArray = box () ([0 as *mut JSObject; PrototypeList::ID::Count as uint]); unsafe { assert!(((*JS_GetClass(global)).flags & JSCLASS_DOM_GLOBAL) != 0); let box_ = squirrel_away_unique(protoArray); @@ -350,8 +352,8 @@ pub fn reflect_dom_object<T: Reflectable> /// A struct to store a reference to the reflector of a DOM object. // Allowing unused_attribute because the lint sometimes doesn't run in order -#[allow(raw_pointer_deriving, unrooted_must_root, unused_attributes)] -#[deriving(PartialEq)] +#[allow(raw_pointer_derive, unrooted_must_root, unused_attributes)] +#[derive(PartialEq)] #[must_root] #[servo_lang = "reflector"] // If you're renaming or moving this field, update the path in plugins::reflector as well @@ -495,7 +497,7 @@ pub fn IsPlatformObject(obj: *mut JSObject) -> bool { pub fn get_dictionary_property(cx: *mut JSContext, object: *mut JSObject, property: &str) -> Result<Option<JSVal>, ()> { - use std::c_str::CString; + use std::ffi::CString; fn has_property(cx: *mut JSContext, object: *mut JSObject, property: &CString, found: &mut JSBool) -> bool { unsafe { @@ -509,7 +511,7 @@ pub fn get_dictionary_property(cx: *mut JSContext, } } - let property = property.to_c_str(); + let property = CString::from_slice(property.as_bytes()); if object.is_null() { return Ok(None); } @@ -594,7 +596,7 @@ pub unsafe fn delete_property_by_id(cx: *mut JSContext, object: *mut JSObject, } /// Results of `xml_name_type`. -#[deriving(PartialEq)] +#[derive(PartialEq)] #[allow(missing_docs)] pub enum XMLName { QName, diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs index f4794d9f6fe..69d75231fe8 100644 --- a/components/script/dom/blob.rs +++ b/components/script/dom/blob.rs @@ -11,8 +11,11 @@ use dom::bindings::codegen::Bindings::BlobBinding; use dom::bindings::codegen::Bindings::BlobBinding::BlobMethods; use servo_util::str::DOMString; -use std::cmp::{min, max}; + use std::ascii::AsciiExt; +use std::borrow::ToOwned; +use std::cmp::{min, max}; +use std::num::ToPrimitive; #[jstraceable] pub enum BlobTypeId { @@ -43,7 +46,7 @@ impl Blob { reflector_: Reflector::new(), type_: type_, bytes: bytes, - typeString: typeString.into_string(), + typeString: typeString.to_owned(), global: GlobalField::from_rooted(&global) //isClosed_: false } @@ -68,7 +71,7 @@ impl Blob { } else { "" }; - let typeStrLower = typeString.as_slice().to_ascii_lower(); + let typeStrLower = typeString.as_slice().to_ascii_lowercase(); Ok(Blob::new(global, bytes, typeStrLower.as_slice())) } } @@ -109,12 +112,12 @@ impl<'a> BlobMethods for JSRef<'a, Blob> { } }; let relativeContentType = match contentType { - None => "".into_string(), + None => "".to_owned(), Some(str) => { if is_ascii_printable(&str) { - str.as_slice().to_ascii_lower().into_string() + str.as_slice().to_ascii_lowercase().to_owned() } else { - "".into_string() + "".to_owned() } } }; diff --git a/components/script/dom/browsercontext.rs b/components/script/dom/browsercontext.rs index 959c021b4bc..cbe3bcbe63d 100644 --- a/components/script/dom/browsercontext.rs +++ b/components/script/dom/browsercontext.rs @@ -26,7 +26,7 @@ use js::{JSRESOLVE_QUALIFIED, JSRESOLVE_ASSIGNING}; use std::ptr; -#[allow(raw_pointer_deriving)] +#[allow(raw_pointer_derive)] #[jstraceable] #[privatize] pub struct BrowserContext { @@ -194,17 +194,20 @@ unsafe extern fn set(cx: *mut JSContext, proxy: *mut JSObject, _receiver: *mut J } static PROXY_HANDLER: ProxyTraps = ProxyTraps { - getPropertyDescriptor: Some(getPropertyDescriptor), - getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor), - defineProperty: Some(defineProperty), + getPropertyDescriptor: Some(getPropertyDescriptor as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, bool, *mut JSPropertyDescriptor) -> bool), + getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor + as unsafe extern "C" fn(*mut JSContext, *mut JSObject, + jsid, bool, *mut JSPropertyDescriptor) + -> bool), + defineProperty: Some(defineProperty as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, *mut JSPropertyDescriptor) -> bool), getOwnPropertyNames: None, delete_: None, enumerate: None, has: None, - hasOwn: Some(hasOwn), - get: Some(get), - set: Some(set), + hasOwn: Some(hasOwn as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, *mut bool) -> bool), + get: Some(get as unsafe extern "C" fn(*mut JSContext, *mut JSObject, *mut JSObject, jsid, *mut JSVal) -> bool), + set: Some(set as unsafe extern "C" fn(*mut JSContext, *mut JSObject, *mut JSObject, jsid, bool, *mut JSVal) -> bool), keys: None, iterate: None, diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index 9ed36217fec..a1eb1af9997 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -16,6 +16,8 @@ use geom::size::Size2D; use canvas::canvas_paint_task::{CanvasMsg, CanvasPaintTask}; use canvas::canvas_paint_task::CanvasMsg::{ClearRect, Close, FillRect, Recreate, StrokeRect}; +use std::sync::mpsc::Sender; + #[dom_struct] pub struct CanvasRenderingContext2D { reflector_: Reflector, diff --git a/components/script/dom/characterdata.rs b/components/script/dom/characterdata.rs index 55e4ab5f551..bdc56530e7d 100644 --- a/components/script/dom/characterdata.rs +++ b/components/script/dom/characterdata.rs @@ -16,6 +16,7 @@ use dom::node::{Node, NodeHelpers, NodeTypeId}; use servo_util::str::DOMString; +use std::borrow::ToOwned; use std::cell::Ref; #[dom_struct] @@ -80,7 +81,7 @@ impl<'a> CharacterDataMethods for JSRef<'a, CharacterData> { } fn SubstringData(self, offset: u32, count: u32) -> Fallible<DOMString> { - Ok(self.data.borrow().as_slice().slice(offset as uint, count as uint).into_string()) + Ok(self.data.borrow().as_slice().slice(offset as uint, count as uint).to_owned()) } fn AppendData(self, arg: DOMString) -> ErrorResult { @@ -93,7 +94,7 @@ impl<'a> CharacterDataMethods for JSRef<'a, CharacterData> { } fn DeleteData(self, offset: u32, count: u32) -> ErrorResult { - self.ReplaceData(offset, count, "".into_string()) + self.ReplaceData(offset, count, "".to_owned()) } fn ReplaceData(self, offset: u32, count: u32, arg: DOMString) -> ErrorResult { @@ -106,7 +107,7 @@ impl<'a> CharacterDataMethods for JSRef<'a, CharacterData> { } else { count }; - let mut data = self.data.borrow().as_slice().slice(0, offset as uint).into_string(); + let mut data = self.data.borrow().as_slice().slice(0, offset as uint).to_owned(); data.push_str(arg.as_slice()); data.push_str(self.data.borrow().as_slice().slice((offset + count) as uint, length as uint)); *self.data.borrow_mut() = data; diff --git a/components/script/dom/create.rs b/components/script/dom/create.rs index 4f8d3b9f846..8bbbdc9c832 100644 --- a/components/script/dom/create.rs +++ b/components/script/dom/create.rs @@ -79,19 +79,25 @@ use servo_util::str::DOMString; use string_cache::QualName; +use std::borrow::ToOwned; + pub fn create_element(name: QualName, prefix: Option<DOMString>, document: JSRef<Document>, creator: ElementCreator) -> Temporary<Element> { if name.ns != ns!(HTML) { - return Element::new(name.local.as_slice().into_string(), name.ns, prefix, document); + return Element::new(name.local.as_slice().to_owned(), name.ns, prefix, document); } macro_rules! make( - ($ctor:ident $(, $arg:expr)*) => ({ - let obj = $ctor::new(name.local.as_slice().into_string(), prefix, document $(, $arg)*); + ($ctor:ident) => ({ + let obj = $ctor::new(name.local.as_slice().to_owned(), prefix, document); + ElementCast::from_temporary(obj) + }); + ($ctor:ident, $($arg:expr),+) => ({ + let obj = $ctor::new(name.local.as_slice().to_owned(), prefix, document, $($arg),+); ElementCast::from_temporary(obj) }) - ) + ); // This is a big match, and the IDs for inline-interned atoms are not very structured. // Perhaps we should build a perfect hash from those IDs instead. diff --git a/components/script/dom/cssstyledeclaration.rs b/components/script/dom/cssstyledeclaration.rs index b95df387901..81dd6aeeebe 100644 --- a/components/script/dom/cssstyledeclaration.rs +++ b/components/script/dom/cssstyledeclaration.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::{mod, CSSStyleDeclarationMethods}; +use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::{self, CSSStyleDeclarationMethods}; use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast}; use dom::bindings::error::Error; use dom::bindings::error::ErrorResult; @@ -21,6 +21,7 @@ use style::{is_supported_property, longhands_from_shorthand, parse_style_attribu use style::PropertyDeclaration; use std::ascii::AsciiExt; +use std::borrow::ToOwned; #[dom_struct] pub struct CSSStyleDeclaration { @@ -29,7 +30,7 @@ pub struct CSSStyleDeclaration { readonly: bool, } -#[deriving(PartialEq)] +#[derive(PartialEq)] pub enum CSSModificationAccess { ReadWrite, Readonly @@ -39,14 +40,14 @@ macro_rules! css_properties( ( $([$getter:ident, $setter:ident, $cssprop:expr]),* ) => ( $( fn $getter(self) -> DOMString { - self.GetPropertyValue($cssprop.into_string()) + self.GetPropertyValue($cssprop.to_owned()) } fn $setter(self, value: DOMString) { - self.SetPropertyValue($cssprop.into_string(), value).unwrap(); + self.SetPropertyValue($cssprop.to_owned(), value).unwrap(); } )* ); -) +); fn serialize_list(list: &Vec<PropertyDeclaration>) -> DOMString { let mut result = String::new(); @@ -115,21 +116,21 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { if index as uint > declarations.normal.len() { declarations.important .get(index as uint - declarations.normal.len()) - .map(|decl| format!("{} !important", decl)) + .map(|decl| format!("{:?} !important", decl)) } else { declarations.normal .get(index as uint) - .map(|decl| format!("{}", decl)) + .map(|decl| format!("{:?}", decl)) } }); - result.unwrap_or("".into_string()) + result.unwrap_or("".to_owned()) } // http://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue fn GetPropertyValue(self, property: DOMString) -> DOMString { // Step 1 - let property = Atom::from_slice(property.as_slice().to_ascii_lower().as_slice()); + let property = Atom::from_slice(property.as_slice().to_ascii_lowercase().as_slice()); // Step 2 let longhand_properties = longhands_from_shorthand(property.as_slice()); @@ -145,7 +146,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { // Step 2.2.2 & 2.2.3 match declaration { Some(declaration) => list.push(declaration), - None => return "".into_string(), + None => return "".to_owned(), } } @@ -157,14 +158,14 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { if let Some(ref declaration) = self.get_declaration(&property) { serialize_value(declaration) } else { - "".into_string() + "".to_owned() } } // http://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority fn GetPropertyPriority(self, property: DOMString) -> DOMString { // Step 1 - let property = Atom::from_slice(property.as_slice().to_ascii_lower().as_slice()); + let property = Atom::from_slice(property.as_slice().to_ascii_lowercase().as_slice()); // Step 2 let longhand_properties = longhands_from_shorthand(property.as_slice()); @@ -174,15 +175,15 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { .map(|longhand| self.GetPropertyPriority(longhand.clone())) .all(|priority| priority.as_slice() == "important") { - return "important".into_string(); + return "important".to_owned(); } // Step 3 } else if self.get_important_declaration(&property).is_some() { - return "important".into_string(); + return "important".to_owned(); } // Step 4 - "".into_string() + "".to_owned() } // http://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-setproperty @@ -194,7 +195,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { } // Step 2 - let property = property.as_slice().to_ascii_lower(); + let property = property.as_slice().to_ascii_lowercase(); // Step 3 if !is_supported_property(property.as_slice()) { @@ -207,7 +208,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { } // Step 5 - let priority = priority.as_slice().to_ascii_lower(); + let priority = priority.as_slice().to_ascii_lowercase(); if priority.as_slice() != "!important" && !priority.is_empty() { return Ok(()); } @@ -253,7 +254,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { } // Step 2 - let property = property.as_slice().to_ascii_lower(); + let property = property.as_slice().to_ascii_lowercase(); // Step 3 if !is_supported_property(property.as_slice()) { @@ -261,7 +262,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { } // Step 4 - let priority = priority.as_slice().to_ascii_lower(); + let priority = priority.as_slice().to_ascii_lowercase(); if priority.as_slice() != "important" && !priority.is_empty() { return Ok(()); } @@ -289,7 +290,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { // http://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-setpropertyvalue fn SetPropertyValue(self, property: DOMString, value: DOMString) -> ErrorResult { - self.SetProperty(property, value, "".into_string()) + self.SetProperty(property, value, "".to_owned()) } // http://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-removeproperty @@ -300,7 +301,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { } // Step 2 - let property = property.as_slice().to_ascii_lower(); + let property = property.as_slice().to_ascii_lowercase(); // Step 3 let value = self.GetPropertyValue(property.clone()); @@ -328,12 +329,12 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { // http://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-cssfloat fn CssFloat(self) -> DOMString { - self.GetPropertyValue("float".into_string()) + self.GetPropertyValue("float".to_owned()) } // http://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-cssfloat fn SetCssFloat(self, value: DOMString) -> ErrorResult { - self.SetPropertyValue("float".into_string(), value) + self.SetPropertyValue("float".to_owned(), value) } fn IndexedGetter(self, index: u32, found: &mut bool) -> DOMString { @@ -342,5 +343,5 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { rval } - css_properties_accessors!(css_properties) + css_properties_accessors!(css_properties); } diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs index 1403344dad2..22b7befd87c 100644 --- a/components/script/dom/dedicatedworkerglobalscope.rs +++ b/components/script/dom/dedicatedworkerglobalscope.rs @@ -32,12 +32,13 @@ use js::jsval::JSVal; use js::rust::Cx; use std::rc::Rc; +use std::sync::mpsc::{Sender, Receiver}; use url::Url; /// A ScriptChan that can be cloned freely and will silently send a TrustedWorkerAddress with /// every message. While this SendableWorkerScriptChan is alive, the associated Worker object /// will remain alive. -#[deriving(Clone)] +#[derive(Clone)] #[jstraceable] pub struct SendableWorkerScriptChan { sender: Sender<(TrustedWorkerAddress, ScriptMsg)>, @@ -133,7 +134,7 @@ impl DedicatedWorkerGlobalScope { parent_sender: Box<ScriptChan+Send>, own_sender: Sender<(TrustedWorkerAddress, ScriptMsg)>, receiver: Receiver<(TrustedWorkerAddress, ScriptMsg)>) { - spawn_named(format!("WebWorker for {}", worker_url.serialize()), proc() { + spawn_named(format!("WebWorker for {}", worker_url.serialize()), move || { task_state::initialize(SCRIPT | IN_WORKER); let roots = RootCollection::new(); @@ -165,7 +166,7 @@ impl DedicatedWorkerGlobalScope { } loop { - match global.r().receiver.recv_opt() { + match global.r().receiver.recv() { Ok((linked_worker, msg)) => { let _ar = AutoWorkerReset::new(global.r(), linked_worker); global.r().handle_event(msg); @@ -228,7 +229,7 @@ impl<'a> DedicatedWorkerGlobalScopeMethods for JSRef<'a, DedicatedWorkerGlobalSc Ok(()) } - event_handler!(message, GetOnmessage, SetOnmessage) + event_handler!(message, GetOnmessage, SetOnmessage); } impl DedicatedWorkerGlobalScopeDerived for EventTarget { diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 22334b3b2a1..d7e9ce0daa2 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -23,7 +23,7 @@ use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::error::Error::{NotSupported, InvalidCharacter}; use dom::bindings::error::Error::{HierarchyRequest, NamespaceError}; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{MutNullableJS, JS, JSRef, Temporary, OptionalSettable, TemporaryPushable}; +use dom::bindings::js::{MutNullableJS, JS, JSRef, Temporary, TemporaryPushable}; use dom::bindings::js::{OptionalRootable, RootedReference}; use dom::bindings::utils::reflect_dom_object; use dom::bindings::utils::xml_name_type; @@ -63,14 +63,15 @@ use layout_interface::{LayoutChan, Msg}; use string_cache::{Atom, QualName}; use url::Url; +use std::borrow::ToOwned; use std::collections::HashMap; -use std::collections::hash_map::{Vacant, Occupied}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::ascii::AsciiExt; use std::cell::{Cell, Ref}; use std::default::Default; use time; -#[deriving(PartialEq)] +#[derive(PartialEq)] #[jstraceable] pub enum IsHTMLDocument { HTMLDocument, @@ -283,7 +284,7 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { match idmap.entry(id) { Vacant(entry) => { - entry.set(vec!(element.unrooted())); + entry.insert(vec!(element.unrooted())); } Occupied(entry) => { let elements = entry.into_mut(); @@ -320,7 +321,7 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { /// https://html.spec.whatwg.org/multipage/#the-indicated-part-of-the-document fn find_fragment_node(self, fragid: DOMString) -> Option<Temporary<Element>> { self.GetElementById(fragid.clone()).or_else(|| { - let check_anchor = |&node: &JSRef<HTMLAnchorElement>| { + let check_anchor = |&:&node: &JSRef<HTMLAnchorElement>| { let elem: JSRef<Element> = ElementCast::from_ref(node); elem.get_attribute(ns!(""), &atom!("name")).root().map_or(false, |attr| { attr.r().value().as_slice() == fragid.as_slice() @@ -339,7 +340,7 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { self.ready_state.set(state); let window = self.window.root(); - let event = Event::new(GlobalRef::Window(window.r()), "readystatechange".into_string(), + let event = Event::new(GlobalRef::Window(window.r()), "readystatechange".to_owned(), EventBubbles::DoesNotBubble, EventCancelable::NotCancelable).root(); let target: JSRef<EventTarget> = EventTargetCast::from_ref(self); @@ -384,7 +385,7 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { } } -#[deriving(PartialEq)] +#[derive(PartialEq)] pub enum DocumentSource { FromParser, NotFromParser, @@ -425,9 +426,9 @@ impl Document { Some(string) => string.clone(), None => match is_html_document { // http://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument - IsHTMLDocument::HTMLDocument => "text/html".into_string(), + IsHTMLDocument::HTMLDocument => "text/html".to_owned(), // http://dom.spec.whatwg.org/#concept-document-content-type - IsHTMLDocument::NonHTMLDocument => "application/xml".into_string() + IsHTMLDocument::NonHTMLDocument => "application/xml".to_owned() } }, last_modified: DOMRefCell::new(None), @@ -435,7 +436,7 @@ impl Document { // http://dom.spec.whatwg.org/#concept-document-quirks quirks_mode: Cell::new(NoQuirks), // http://dom.spec.whatwg.org/#concept-document-encoding - encoding_name: DOMRefCell::new("UTF-8".into_string()), + encoding_name: DOMRefCell::new("UTF-8".to_owned()), is_html_document: is_html_document == IsHTMLDocument::HTMLDocument, images: Default::default(), embeds: Default::default(), @@ -474,12 +475,12 @@ impl Document { } trait PrivateDocumentHelpers { - fn createNodeList(self, callback: |node: JSRef<Node>| -> bool) -> Temporary<NodeList>; + fn createNodeList<F: Fn(JSRef<Node>) -> bool>(self, callback: F) -> Temporary<NodeList>; fn get_html_element(self) -> Option<Temporary<HTMLHtmlElement>>; } impl<'a> PrivateDocumentHelpers for JSRef<'a, Document> { - fn createNodeList(self, callback: |node: JSRef<Node>| -> bool) -> Temporary<NodeList> { + fn createNodeList<F: Fn(JSRef<Node>) -> bool>(self, callback: F) -> Temporary<NodeList> { let window = self.window.root(); let document_element = self.GetDocumentElement().root(); let nodes = match document_element { @@ -520,8 +521,8 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { // http://dom.spec.whatwg.org/#dom-document-compatmode fn CompatMode(self) -> DOMString { match self.quirks_mode.get() { - LimitedQuirks | NoQuirks => "CSS1Compat".into_string(), - Quirks => "BackCompat".into_string() + LimitedQuirks | NoQuirks => "CSS1Compat".to_owned(), + Quirks => "BackCompat".to_owned() } } @@ -590,7 +591,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { return Err(InvalidCharacter); } let local_name = if self.is_html_document { - local_name.as_slice().to_ascii_lower() + local_name.as_slice().to_ascii_lowercase() } else { local_name }; @@ -639,7 +640,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } let name = QualName::new(ns, Atom::from_slice(local_name_from_qname)); - Ok(Element::create(name, prefix_from_qname.map(|s| s.into_string()), self, + Ok(Element::create(name, prefix_from_qname.map(|s| s.to_owned()), self, ElementCreator::ScriptCreated)) } @@ -654,7 +655,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { let name = Atom::from_slice(local_name.as_slice()); // repetition used because string_cache::atom::Atom is non-copyable let l_name = Atom::from_slice(local_name.as_slice()); - let value = AttrValue::String("".into_string()); + let value = AttrValue::String("".to_owned()); Ok(Attr::new(window.r(), name, value, l_name, ns!(""), None, None)) } @@ -726,7 +727,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { fn CreateEvent(self, interface: DOMString) -> Fallible<Temporary<Event>> { let window = self.window.root(); - match interface.as_slice().to_ascii_lower().as_slice() { + match interface.as_slice().to_ascii_lowercase().as_slice() { "uievents" | "uievent" => Ok(EventCast::from_temporary( UIEvent::new_uninitialized(window.r()))), "mouseevents" | "mouseevent" => Ok(EventCast::from_temporary( @@ -770,7 +771,11 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { root.traverse_preorder() .find(|node| node.type_id() == NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTitleElement))) .map(|title_elem| { - for text in title_elem.children().filter_map::<JSRef<Text>>(TextCast::to_ref) { + let mut children = title_elem.children().filter_map(|n| { + let t: Option<JSRef<Text>> = TextCast::to_ref(n); + t + }); + for text in children { title.push_str(text.characterdata().data().as_slice()); } }); @@ -802,7 +807,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } }, None => { - let new_title = HTMLTitleElement::new("title".into_string(), None, self).root(); + let new_title = HTMLTitleElement::new("title".to_owned(), None, self).root(); let new_title: JSRef<Node> = NodeCast::from_ref(new_title.r()); if !title.is_empty() { @@ -999,7 +1004,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { Temporary::new(self.window) } - global_event_handlers!() - event_handler!(readystatechange, GetOnreadystatechange, SetOnreadystatechange) + global_event_handlers!(); + event_handler!(readystatechange, GetOnreadystatechange, SetOnreadystatechange); } diff --git a/components/script/dom/documenttype.rs b/components/script/dom/documenttype.rs index 2fe9e340987..fc9407c5dd0 100644 --- a/components/script/dom/documenttype.rs +++ b/components/script/dom/documenttype.rs @@ -11,6 +11,8 @@ use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::node::{Node, NodeHelpers, NodeTypeId}; use servo_util::str::DOMString; +use std::borrow::ToOwned; + /// The `DOCTYPE` tag. #[dom_struct] pub struct DocumentType { @@ -35,8 +37,8 @@ impl DocumentType { DocumentType { node: Node::new_inherited(NodeTypeId::DocumentType, document), name: name, - public_id: public_id.unwrap_or("".into_string()), - system_id: system_id.unwrap_or("".into_string()) + public_id: public_id.unwrap_or("".to_owned()), + system_id: system_id.unwrap_or("".to_owned()) } } #[allow(unrooted_must_root)] diff --git a/components/script/dom/domexception.rs b/components/script/dom/domexception.rs index 0af98e21e81..48f8e4b52f6 100644 --- a/components/script/dom/domexception.rs +++ b/components/script/dom/domexception.rs @@ -11,8 +11,10 @@ use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::utils::{Reflector, reflect_dom_object}; use servo_util::str::DOMString; +use std::borrow::ToOwned; + #[repr(uint)] -#[deriving(Copy, Show)] +#[derive(Copy, Show)] #[jstraceable] pub enum DOMErrorName { IndexSizeError = DOMExceptionConstants::INDEX_SIZE_ERR as uint, @@ -96,7 +98,7 @@ impl<'a> DOMExceptionMethods for JSRef<'a, DOMException> { // http://dom.spec.whatwg.org/#error-names-0 fn Name(self) -> DOMString { - self.code.to_string() + format!("{:?}", self.code) } // http://dom.spec.whatwg.org/#error-names-0 @@ -125,6 +127,6 @@ impl<'a> DOMExceptionMethods for JSRef<'a, DOMException> { DOMErrorName::EncodingError => "The encoding operation (either encoded or decoding) failed." }; - message.into_string() + message.to_owned() } } diff --git a/components/script/dom/domimplementation.rs b/components/script/dom/domimplementation.rs index e298d275f47..285b86967e8 100644 --- a/components/script/dom/domimplementation.rs +++ b/components/script/dom/domimplementation.rs @@ -25,6 +25,8 @@ use dom::node::Node; use dom::text::Text; use servo_util::str::DOMString; +use std::borrow::ToOwned; + #[dom_struct] pub struct DOMImplementation { reflector_: Reflector, @@ -123,18 +125,18 @@ impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> { { // Step 3. - let doc_type = DocumentType::new("html".into_string(), None, None, doc.r()).root(); + let doc_type = DocumentType::new("html".to_owned(), None, None, doc.r()).root(); assert!(doc_node.AppendChild(NodeCast::from_ref(doc_type.r())).is_ok()); } { // Step 4. - let doc_html: Root<Node> = NodeCast::from_temporary(HTMLHtmlElement::new("html".into_string(), None, doc.r())).root(); + let doc_html: Root<Node> = NodeCast::from_temporary(HTMLHtmlElement::new("html".to_owned(), None, doc.r())).root(); assert!(doc_node.AppendChild(doc_html.r()).is_ok()); { // Step 5. - let doc_head: Root<Node> = NodeCast::from_temporary(HTMLHeadElement::new("head".into_string(), None, doc.r())).root(); + let doc_head: Root<Node> = NodeCast::from_temporary(HTMLHeadElement::new("head".to_owned(), None, doc.r())).root(); assert!(doc_html.r().AppendChild(doc_head.r()).is_ok()); // Step 6. @@ -142,7 +144,7 @@ impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> { None => (), Some(title_str) => { // Step 6.1. - let doc_title: Root<Node> = NodeCast::from_temporary(HTMLTitleElement::new("title".into_string(), None, doc.r())).root(); + let doc_title: Root<Node> = NodeCast::from_temporary(HTMLTitleElement::new("title".to_owned(), None, doc.r())).root(); assert!(doc_head.r().AppendChild(doc_title.r()).is_ok()); // Step 6.2. @@ -153,7 +155,7 @@ impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> { } // Step 7. - let doc_body: Root<HTMLBodyElement> = HTMLBodyElement::new("body".into_string(), None, doc.r()).root(); + let doc_body: Root<HTMLBodyElement> = HTMLBodyElement::new("body".to_owned(), None, doc.r()).root(); assert!(doc_html.r().AppendChild(NodeCast::from_ref(doc_body.r())).is_ok()); } diff --git a/components/script/dom/domparser.rs b/components/script/dom/domparser.rs index 4b473ed8ced..a3a7db0b1ca 100644 --- a/components/script/dom/domparser.rs +++ b/components/script/dom/domparser.rs @@ -17,6 +17,8 @@ use dom::window::Window; use parse::html::{HTMLInput, parse_html}; use servo_util::str::DOMString; +use std::borrow::ToOwned; + #[dom_struct] pub struct DOMParser { reflector_: Reflector, @@ -49,7 +51,7 @@ impl<'a> DOMParserMethods for JSRef<'a, DOMParser> { -> Fallible<Temporary<Document>> { let window = self.window.root(); let url = window.r().get_url(); - let content_type = DOMParserBinding::SupportedTypeValues::strings[ty as uint].into_string(); + let content_type = DOMParserBinding::SupportedTypeValues::strings[ty as uint].to_owned(); match ty { Text_html => { let document = Document::new(window.r(), Some(url.clone()), diff --git a/components/script/dom/domtokenlist.rs b/components/script/dom/domtokenlist.rs index c681dc7d710..0ab2a40b81e 100644 --- a/components/script/dom/domtokenlist.rs +++ b/components/script/dom/domtokenlist.rs @@ -16,6 +16,8 @@ use dom::node::window_from_node; use servo_util::str::{DOMString, HTML_SPACE_CHARACTERS}; use string_cache::Atom; +use std::borrow::ToOwned; + #[dom_struct] pub struct DOMTokenList { reflector_: Reflector, @@ -42,7 +44,7 @@ impl DOMTokenList { trait PrivateDOMTokenListHelpers { fn attribute(self) -> Option<Temporary<Attr>>; - fn check_token_exceptions<'a>(self, token: &'a str) -> Fallible<Atom>; + fn check_token_exceptions(self, token: &str) -> Fallible<Atom>; } impl<'a> PrivateDOMTokenListHelpers for JSRef<'a, DOMTokenList> { @@ -51,7 +53,7 @@ impl<'a> PrivateDOMTokenListHelpers for JSRef<'a, DOMTokenList> { element.r().get_attribute(ns!(""), &self.local_name) } - fn check_token_exceptions<'a>(self, token: &'a str) -> Fallible<Atom> { + fn check_token_exceptions(self, token: &str) -> Fallible<Atom> { match token { "" => Err(Syntax), slice if slice.find(HTML_SPACE_CHARACTERS).is_some() => Err(InvalidCharacter), @@ -72,7 +74,7 @@ impl<'a> DOMTokenListMethods for JSRef<'a, DOMTokenList> { // http://dom.spec.whatwg.org/#dom-domtokenlist-item fn Item(self, index: u32) -> Option<DOMString> { self.attribute().root().and_then(|attr| attr.r().value().tokens().and_then(|tokens| { - tokens.get(index as uint).map(|token| token.as_slice().into_string()) + tokens.get(index as uint).map(|token| token.as_slice().to_owned()) })) } @@ -116,7 +118,7 @@ impl<'a> DOMTokenListMethods for JSRef<'a, DOMTokenList> { let mut atoms = element.r().get_tokenlist_attribute(&self.local_name); for token in tokens.iter() { let token = try!(self.check_token_exceptions(token.as_slice())); - atoms.iter().position(|atom| *atom == token).and_then(|index| { + atoms.iter().position(|atom| *atom == token).map(|index| { atoms.remove(index) }); } diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 0735e19299f..f0ab72b430a 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -50,8 +50,8 @@ use dom::node::{window_from_node}; use dom::nodelist::NodeList; use dom::virtualmethods::{VirtualMethods, vtable_for}; use devtools_traits::AttrInfo; -use style::{mod, StylesheetOrigin, SimpleColorAttribute, UnsignedIntegerAttribute}; -use style::{IntegerAttribute, LengthAttribute, ParserContext, matches}; +use style::{self, SimpleColorAttribute, UnsignedIntegerAttribute}; +use style::{IntegerAttribute, LengthAttribute, matches}; use servo_util::namespace; use servo_util::str::{DOMString, LengthOrPercentageOrAuto}; @@ -59,6 +59,7 @@ use html5ever::tree_builder::{NoQuirks, LimitedQuirks, Quirks}; use cssparser::RGBA; use std::ascii::AsciiExt; +use std::borrow::{IntoCow, ToOwned}; use std::cell::{Ref, RefMut}; use std::default::Default; use std::mem; @@ -88,14 +89,14 @@ impl ElementDerived for EventTarget { } } -#[deriving(Copy, PartialEq, Show)] +#[derive(Copy, PartialEq, Show)] #[jstraceable] pub enum ElementTypeId { HTMLElement(HTMLElementTypeId), Element, } -#[deriving(PartialEq)] +#[derive(PartialEq)] pub enum ElementCreator { ParserCreated, ScriptCreated, @@ -387,7 +388,7 @@ impl LayoutElementHelpers for JS<Element> { } } -#[deriving(PartialEq)] +#[derive(PartialEq)] pub enum StylePriority { Important, Normal, @@ -423,7 +424,7 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> { // https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name fn parsed_name(self, name: DOMString) -> DOMString { if self.html_element_in_html_document() { - name.as_slice().to_ascii_lower() + name.as_slice().to_ascii_lowercase() } else { name } @@ -504,7 +505,7 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> { fn update_inline_style(self, property_decl: style::PropertyDeclaration, style_priority: StylePriority) { let mut inline_declarations = self.style_attribute().borrow_mut(); - if let Some(ref mut declarations) = *inline_declarations.deref_mut() { + if let &mut Some(ref mut declarations) = &mut *inline_declarations { let existing_declarations = if style_priority == StylePriority::Important { declarations.important.make_unique() } else { @@ -568,9 +569,10 @@ pub trait AttributeHandlers { prefix: Option<DOMString>); fn set_attribute(self, name: &Atom, value: AttrValue); fn set_custom_attribute(self, name: DOMString, value: DOMString) -> ErrorResult; - fn do_set_attribute(self, local_name: Atom, value: AttrValue, - name: Atom, namespace: Namespace, - prefix: Option<DOMString>, cb: |JSRef<Attr>| -> bool); + fn do_set_attribute<F>(self, local_name: Atom, value: AttrValue, + name: Atom, namespace: Namespace, + prefix: Option<DOMString>, cb: F) + where F: Fn(JSRef<Attr>) -> bool; fn parse_attribute(self, namespace: &Namespace, local_name: &Atom, value: DOMString) -> AttrValue; @@ -632,7 +634,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { } fn set_attribute(self, name: &Atom, value: AttrValue) { - assert!(name.as_slice() == name.as_slice().to_ascii_lower().as_slice()); + assert!(name.as_slice() == name.as_slice().to_ascii_lowercase().as_slice()); assert!(!name.as_slice().contains(":")); self.do_set_attribute(name.clone(), value, name.clone(), @@ -656,9 +658,15 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { Ok(()) } - fn do_set_attribute(self, local_name: Atom, value: AttrValue, - name: Atom, namespace: Namespace, - prefix: Option<DOMString>, cb: |JSRef<Attr>| -> bool) { + fn do_set_attribute<F>(self, + local_name: Atom, + value: AttrValue, + name: Atom, + namespace: Namespace, + prefix: Option<DOMString>, + cb: F) + where F: Fn(JSRef<Attr>) -> bool + { let idx = self.attrs.borrow().iter() .map(|attr| attr.root()) .position(|attr| cb(attr.r())); @@ -723,7 +731,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { let owner_doc = node.owner_doc().root(); owner_doc.r().quirks_mode() }; - let is_equal = |lhs: &Atom, rhs: &Atom| match quirks_mode { + let is_equal = |&:lhs: &Atom, rhs: &Atom| match quirks_mode { NoQuirks | LimitedQuirks => lhs == rhs, Quirks => lhs.as_slice().eq_ignore_ascii_case(rhs.as_slice()) }; @@ -741,9 +749,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { } fn has_attribute(self, name: &Atom) -> bool { - assert!(name.as_slice().chars().all(|ch| { - !ch.is_ascii() || ch.to_ascii().to_lowercase() == ch.to_ascii() - })); + assert!(name.as_slice().bytes().all(|&:b| b.to_ascii_lowercase() == b)); self.attrs.borrow().iter().map(|attr| attr.root()).any(|attr| { *attr.r().local_name() == *name && *attr.r().namespace() == ns!("") }) @@ -759,9 +765,9 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { } fn get_url_attribute(self, name: &Atom) -> DOMString { - assert!(name.as_slice() == name.as_slice().to_ascii_lower().as_slice()); + assert!(name.as_slice() == name.as_slice().to_ascii_lowercase().as_slice()); if !self.has_attribute(name) { - return "".into_string(); + return "".to_owned(); } let url = self.get_string_attribute(name); let doc = document_from_node(self).root(); @@ -770,7 +776,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { // XXXManishearth this doesn't handle `javascript:` urls properly match UrlParser::new().base_url(base).parse(url.as_slice()) { Ok(parsed) => parsed.serialize(), - Err(_) => "".into_string() + Err(_) => "".to_owned() } } fn set_url_attribute(self, name: &Atom, value: DOMString) { @@ -780,11 +786,11 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { fn get_string_attribute(self, name: &Atom) -> DOMString { match self.get_attribute(ns!(""), name) { Some(x) => x.root().r().Value(), - None => "".into_string() + None => "".to_owned() } } fn set_string_attribute(self, name: &Atom, value: DOMString) { - assert!(name.as_slice() == name.as_slice().to_ascii_lower().as_slice()); + assert!(name.as_slice() == name.as_slice().to_ascii_lowercase().as_slice()); self.set_attribute(name, AttrValue::String(value)); } @@ -799,18 +805,18 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { } fn set_tokenlist_attribute(self, name: &Atom, value: DOMString) { - assert!(name.as_slice() == name.as_slice().to_ascii_lower().as_slice()); + assert!(name.as_slice() == name.as_slice().to_ascii_lowercase().as_slice()); self.set_attribute(name, AttrValue::from_serialized_tokenlist(value)); } fn set_atomic_tokenlist_attribute(self, name: &Atom, tokens: Vec<Atom>) { - assert!(name.as_slice() == name.as_slice().to_ascii_lower().as_slice()); + assert!(name.as_slice() == name.as_slice().to_ascii_lowercase().as_slice()); self.set_attribute(name, AttrValue::from_atomic_tokens(tokens)); } fn get_uint_attribute(self, name: &Atom) -> u32 { assert!(name.as_slice().chars().all(|ch| { - !ch.is_ascii() || ch.to_ascii().to_lowercase() == ch.to_ascii() + !ch.is_ascii() || ch.to_ascii_lowercase() == ch })); let attribute = self.get_attribute(ns!(""), name).root(); match attribute { @@ -825,7 +831,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { } } fn set_uint_attribute(self, name: &Atom, value: u32) { - assert!(name.as_slice() == name.as_slice().to_ascii_lower().as_slice()); + assert!(name.as_slice() == name.as_slice().to_ascii_lowercase().as_slice()); self.set_attribute(name, AttrValue::UInt(value.to_string(), value)); } } @@ -835,12 +841,12 @@ impl<'a> ElementMethods for JSRef<'a, Element> { fn GetNamespaceURI(self) -> Option<DOMString> { match self.namespace { ns!("") => None, - Namespace(ref ns) => Some(ns.as_slice().into_string()) + Namespace(ref ns) => Some(ns.as_slice().to_owned()) } } fn LocalName(self) -> DOMString { - self.local_name.as_slice().into_string() + self.local_name.as_slice().to_owned() } // http://dom.spec.whatwg.org/#dom-element-prefix @@ -859,9 +865,9 @@ impl<'a> ElementMethods for JSRef<'a, Element> { None => self.local_name.as_slice().into_cow() }; if self.html_element_in_html_document() { - qualified_name.as_slice().to_ascii_upper() + qualified_name.as_slice().to_ascii_uppercase() } else { - qualified_name.into_string() + qualified_name.into_owned() } } @@ -996,7 +1002,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> { // Step 9. let value = self.parse_attribute(&namespace, &local_name, value); self.do_set_attribute(local_name.clone(), value, name, - namespace.clone(), prefix.map(|s| s.into_string()), + namespace.clone(), prefix.map(|s| s.to_owned()), |attr| { *attr.local_name() == local_name && *attr.namespace() == namespace @@ -1111,10 +1117,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> { // http://dom.spec.whatwg.org/#dom-element-matches fn Matches(self, selectors: DOMString) -> Fallible<bool> { - let parser_context = ParserContext { - origin: StylesheetOrigin::Author, - }; - match style::parse_selector_list_from_str(&parser_context, selectors.as_slice()) { + match style::parse_author_origin_selector_list_from_str(selectors.as_slice()) { Err(()) => Err(Syntax), Ok(ref selectors) => { let root: JSRef<Node> = NodeCast::from_ref(self); @@ -1125,10 +1128,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> { // https://dom.spec.whatwg.org/#dom-element-closest fn Closest(self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>> { - let parser_context = ParserContext { - origin: StylesheetOrigin::Author, - }; - match style::parse_selector_list_from_str(&parser_context, selectors.as_slice()) { + match style::parse_author_origin_selector_list_from_str(selectors.as_slice()) { Err(()) => Err(Syntax), Ok(ref selectors) => { let root: JSRef<Node> = NodeCast::from_ref(self); @@ -1155,7 +1155,7 @@ pub fn get_attribute_parts<'a>(name: &'a str) -> (Option<&'a str>, &'a str) { } impl<'a> VirtualMethods for JSRef<'a, Element> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let node: &JSRef<Node> = NodeCast::from_borrowed_ref(self); Some(node as &VirtualMethods) } @@ -1379,13 +1379,15 @@ impl<'a> style::TElement<'a> for JSRef<'a, Element> { node.get_enabled_state() } fn get_checked_state(self) -> bool { - match HTMLInputElementCast::to_ref(self) { + let input_element: Option<JSRef<HTMLInputElement>> = HTMLInputElementCast::to_ref(self); + match input_element { Some(input) => input.Checked(), None => false, } } fn get_indeterminate_state(self) -> bool { - match HTMLInputElementCast::to_ref(self) { + let input_element: Option<JSRef<HTMLInputElement>> = HTMLInputElementCast::to_ref(self); + match input_element { Some(input) => input.get_indeterminate_state(), None => false, } @@ -1399,7 +1401,9 @@ impl<'a> style::TElement<'a> for JSRef<'a, Element> { has_class(self, name) } - fn each_class(self, callback: |&Atom|) { + fn each_class<F>(self, callback: F) + where F: Fn(&Atom) + { match self.get_attribute(ns!(""), &atom!("class")).root() { None => {} Some(ref attr) => { @@ -1415,7 +1419,8 @@ impl<'a> style::TElement<'a> for JSRef<'a, Element> { } } fn has_nonzero_border(self) -> bool { - match HTMLTableElementCast::to_ref(self) { + let table_element: Option<JSRef<HTMLTableElement>> = HTMLTableElementCast::to_ref(self); + match table_element { None => false, Some(this) => { match this.get_border() { @@ -1466,7 +1471,10 @@ impl<'a> ActivationElementHelpers<'a> for JSRef<'a, Element> { None => { let node: JSRef<Node> = NodeCast::from_ref(self); node.ancestors() - .filter_map(|node| ElementCast::to_ref(node)) + .filter_map(|node| { + let e: Option<JSRef<Element>> = ElementCast::to_ref(node); + e + }) .filter(|e| e.as_maybe_activatable().is_some()).next() .map(|r| Temporary::from_rooted(r)) } diff --git a/components/script/dom/errorevent.rs b/components/script/dom/errorevent.rs index 51a86165cbe..2ae0eec9a18 100644 --- a/components/script/dom/errorevent.rs +++ b/components/script/dom/errorevent.rs @@ -17,6 +17,7 @@ use dom::event::{Event, EventTypeId, EventBubbles, EventCancelable}; use servo_util::str::DOMString; use dom::bindings::cell::DOMRefCell; +use std::borrow::ToOwned; use std::cell::{Cell}; use js::jsval::{JSVal, NullValue}; @@ -40,8 +41,8 @@ impl ErrorEvent { fn new_inherited(type_id: EventTypeId) -> ErrorEvent { ErrorEvent { event: Event::new_inherited(type_id), - message: DOMRefCell::new("".into_string()), - filename: DOMRefCell::new("".into_string()), + message: DOMRefCell::new("".to_owned()), + filename: DOMRefCell::new("".to_owned()), lineno: Cell::new(0), colno: Cell::new(0), error: MutHeap::new(NullValue()) @@ -80,11 +81,11 @@ impl ErrorEvent { init: &ErrorEventBinding::ErrorEventInit) -> Fallible<Temporary<ErrorEvent>>{ let msg = match init.message.as_ref() { Some(message) => message.clone(), - None => "".into_string(), + None => "".to_owned(), }; let file_name = match init.filename.as_ref() { - None => "".into_string(), + None => "".to_owned(), Some(filename) => filename.clone(), }; diff --git a/components/script/dom/event.rs b/components/script/dom/event.rs index 0f084288c7b..e2fe8c25609 100644 --- a/components/script/dom/event.rs +++ b/components/script/dom/event.rs @@ -11,13 +11,15 @@ use dom::bindings::js::{MutNullableJS, JSRef, Temporary}; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::eventtarget::EventTarget; use servo_util::str::DOMString; + +use std::borrow::ToOwned; use std::cell::Cell; use std::default::Default; use time; #[jstraceable] -#[deriving(Copy)] +#[derive(Copy)] pub enum EventPhase { None = EventConstants::NONE as int, Capturing = EventConstants::CAPTURING_PHASE as int, @@ -25,7 +27,7 @@ pub enum EventPhase { Bubbling = EventConstants::BUBBLING_PHASE as int, } -#[deriving(PartialEq)] +#[derive(PartialEq)] #[jstraceable] pub enum EventTypeId { CustomEvent, @@ -38,13 +40,13 @@ pub enum EventTypeId { ErrorEvent } -#[deriving(PartialEq)] +#[derive(PartialEq)] pub enum EventBubbles { Bubbles, DoesNotBubble } -#[deriving(PartialEq)] +#[derive(PartialEq)] pub enum EventCancelable { Cancelable, NotCancelable @@ -77,7 +79,7 @@ impl Event { current_target: Default::default(), target: Default::default(), phase: Cell::new(EventPhase::None), - type_: DOMRefCell::new("".into_string()), + type_: DOMRefCell::new("".to_owned()), canceled: Cell::new(false), cancelable: Cell::new(false), bubbles: Cell::new(false), diff --git a/components/script/dom/eventtarget.rs b/components/script/dom/eventtarget.rs index 71203d386a2..6a08c4d1d60 100644 --- a/components/script/dom/eventtarget.rs +++ b/components/script/dom/eventtarget.rs @@ -21,21 +21,26 @@ use js::jsapi::{JS_CompileUCFunction, JS_GetFunctionObject, JS_CloneFunctionObje use js::jsapi::{JSContext, JSObject}; use servo_util::fnv::FnvHasher; use servo_util::str::DOMString; + use libc::{c_char, size_t}; -use std::collections::hash_map::{Occupied, Vacant}; +use std::borrow::ToOwned; +use std::collections::hash_map::Entry::{Occupied, Vacant}; +use std::collections::hash_state::DefaultState; +use std::default::Default; +use std::ffi::CString; use std::ptr; use url::Url; use std::collections::HashMap; -#[deriving(Copy, PartialEq)] +#[derive(Copy, PartialEq)] #[jstraceable] pub enum ListenerPhase { Capturing, Bubbling, } -#[deriving(Copy, PartialEq)] +#[derive(Copy, PartialEq)] #[jstraceable] pub enum EventTargetTypeId { Node(NodeTypeId), @@ -46,7 +51,7 @@ pub enum EventTargetTypeId { XMLHttpRequestEventTarget(XMLHttpRequestEventTargetTypeId) } -#[deriving(Copy, PartialEq)] +#[derive(Copy, PartialEq)] #[jstraceable] pub enum EventListenerType { Additive(EventListener), @@ -62,7 +67,7 @@ impl EventListenerType { } } -#[deriving(Copy, PartialEq)] +#[derive(Copy, PartialEq)] #[jstraceable] #[privatize] pub struct EventListenerEntry { @@ -74,7 +79,7 @@ pub struct EventListenerEntry { pub struct EventTarget { reflector_: Reflector, type_id: EventTargetTypeId, - handlers: DOMRefCell<HashMap<DOMString, Vec<EventListenerEntry>, FnvHasher>>, + handlers: DOMRefCell<HashMap<DOMString, Vec<EventListenerEntry>, DefaultState<FnvHasher>>>, } impl EventTarget { @@ -82,7 +87,7 @@ impl EventTarget { EventTarget { reflector_: Reflector::new(), type_id: type_id, - handlers: DOMRefCell::new(HashMap::with_hasher(FnvHasher)), + handlers: DOMRefCell::new(Default::default()), } } @@ -145,7 +150,7 @@ impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> { let mut handlers = self.handlers.borrow_mut(); let entries = match handlers.entry(ty) { Occupied(entry) => entry.into_mut(), - Vacant(entry) => entry.set(vec!()), + Vacant(entry) => entry.insert(vec!()), }; let idx = entries.iter().position(|&entry| { @@ -193,14 +198,14 @@ impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> { scope: *mut JSObject, ty: &str, source: DOMString) { - let url = url.serialize().to_c_str(); - let name = ty.to_c_str(); + let url = CString::from_slice(url.serialize().as_bytes()); + let name = CString::from_slice(ty.as_bytes()); let lineno = 0; //XXXjdm need to get a real number here let nargs = 1; //XXXjdm not true for onerror - static ARG_NAME: [c_char, ..6] = + const ARG_NAME: [c_char; 6] = ['e' as c_char, 'v' as c_char, 'e' as c_char, 'n' as c_char, 't' as c_char, 0]; - static ARG_NAMES: [*const c_char, ..1] = [&ARG_NAME as *const c_char]; + static mut ARG_NAMES: [*const c_char; 1] = [&ARG_NAME as *const c_char]; let source: Vec<u16> = source.as_slice().utf16_units().collect(); let handler = unsafe { @@ -208,7 +213,7 @@ impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> { ptr::null_mut(), name.as_ptr(), nargs, - &ARG_NAMES as *const *const i8 as *mut *const i8, + &ARG_NAMES as *const *const c_char as *mut *const c_char, source.as_ptr(), source.len() as size_t, url.as_ptr(), @@ -231,11 +236,11 @@ impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> { { let event_listener = listener.map(|listener| EventListener::new(listener.callback())); - self.set_inline_event_listener(ty.into_string(), event_listener); + self.set_inline_event_listener(ty.to_owned(), event_listener); } fn get_event_handler_common<T: CallbackContainer>(self, ty: &str) -> Option<T> { - let listener = self.get_inline_event_listener(ty.into_string()); + let listener = self.get_inline_event_listener(ty.to_owned()); listener.map(|listener| CallbackContainer::new(listener.parent.callback())) } @@ -254,7 +259,7 @@ impl<'a> EventTargetMethods for JSRef<'a, EventTarget> { let mut handlers = self.handlers.borrow_mut(); let entry = match handlers.entry(ty) { Occupied(entry) => entry.into_mut(), - Vacant(entry) => entry.set(vec!()), + Vacant(entry) => entry.insert(vec!()), }; let phase = if capture { ListenerPhase::Capturing } else { ListenerPhase::Bubbling }; @@ -303,7 +308,7 @@ impl<'a> EventTargetMethods for JSRef<'a, EventTarget> { } impl<'a> VirtualMethods for JSRef<'a, EventTarget> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { None } } diff --git a/components/script/dom/formdata.rs b/components/script/dom/formdata.rs index bcac91da97e..452832560f9 100644 --- a/components/script/dom/formdata.rs +++ b/components/script/dom/formdata.rs @@ -16,10 +16,12 @@ use dom::blob::Blob; use dom::file::File; use dom::htmlformelement::HTMLFormElement; use servo_util::str::DOMString; + +use std::borrow::ToOwned; use std::collections::HashMap; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; -#[deriving(Clone)] +#[derive(Clone)] #[jstraceable] #[must_root] pub enum FormDatum { @@ -63,7 +65,7 @@ impl<'a> FormDataMethods for JSRef<'a, FormData> { match data.entry(name) { Occupied(entry) => entry.into_mut().push(file), Vacant(entry) => { - entry.set(vec!(file)); + entry.insert(vec!(file)); } } } @@ -72,7 +74,7 @@ impl<'a> FormDataMethods for JSRef<'a, FormData> { let mut data = self.data.borrow_mut(); match data.entry(name) { Occupied(entry) => entry.into_mut().push(FormDatum::StringData(value)), - Vacant (entry) => { entry.set(vec!(FormDatum::StringData(value))); }, + Vacant (entry) => { entry.insert(vec!(FormDatum::StringData(value))); }, } } @@ -115,7 +117,7 @@ impl PrivateFormDataHelpers for FormData { fn get_file_from_blob(&self, value: JSRef<Blob>, filename: Option<DOMString>) -> Temporary<File> { let global = self.global.root(); let f: Option<JSRef<File>> = FileCast::to_ref(value); - let name = filename.unwrap_or(f.map(|inner| inner.name().clone()).unwrap_or("blob".into_string())); + let name = filename.unwrap_or(f.map(|inner| inner.name().clone()).unwrap_or("blob".to_owned())); File::new(global.r(), value, name) } } diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs index be0e3e82d6f..dd1f8376ec2 100644 --- a/components/script/dom/htmlanchorelement.rs +++ b/components/script/dom/htmlanchorelement.rs @@ -75,7 +75,7 @@ impl<'a> PrivateHTMLAnchorElementHelpers for JSRef<'a, HTMLAnchorElement> { } impl<'a> VirtualMethods for JSRef<'a, HTMLAnchorElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } diff --git a/components/script/dom/htmlareaelement.rs b/components/script/dom/htmlareaelement.rs index c5f0784067d..82e5ad86d15 100644 --- a/components/script/dom/htmlareaelement.rs +++ b/components/script/dom/htmlareaelement.rs @@ -51,7 +51,7 @@ impl HTMLAreaElement { } impl<'a> VirtualMethods for JSRef<'a, HTMLAreaElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } diff --git a/components/script/dom/htmlbodyelement.rs b/components/script/dom/htmlbodyelement.rs index 220578d0282..a6bd56bc85d 100644 --- a/components/script/dom/htmlbodyelement.rs +++ b/components/script/dom/htmlbodyelement.rs @@ -4,7 +4,7 @@ use dom::attr::{Attr, AttrHelpers}; use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; -use dom::bindings::codegen::Bindings::HTMLBodyElementBinding::{mod, HTMLBodyElementMethods}; +use dom::bindings::codegen::Bindings::HTMLBodyElementBinding::{self, HTMLBodyElementMethods}; use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::codegen::InheritTypes::EventTargetCast; use dom::bindings::codegen::InheritTypes::{HTMLBodyElementDerived, HTMLElementCast}; @@ -18,7 +18,9 @@ use dom::node::{Node, NodeTypeId, window_from_node}; use dom::virtualmethods::VirtualMethods; use cssparser::RGBA; -use servo_util::str::{mod, DOMString}; +use servo_util::str::{self, DOMString}; + +use std::borrow::ToOwned; use std::cell::Cell; #[dom_struct] @@ -76,7 +78,7 @@ impl HTMLBodyElementHelpers for HTMLBodyElement { } impl<'a> VirtualMethods for JSRef<'a, HTMLBodyElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let element: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(element as &VirtualMethods) } @@ -106,7 +108,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLBodyElement> { }; evtarget.set_event_handler_uncompiled(cx, url, reflector, name.slice_from(2), - attr.value().as_slice().into_string()); + attr.value().as_slice().to_owned()); } match attr.local_name() { diff --git a/components/script/dom/htmlbuttonelement.rs b/components/script/dom/htmlbuttonelement.rs index dfc0309cc19..bb91d93ca00 100644 --- a/components/script/dom/htmlbuttonelement.rs +++ b/components/script/dom/htmlbuttonelement.rs @@ -19,6 +19,7 @@ use dom::validitystate::ValidityState; use dom::virtualmethods::VirtualMethods; use std::ascii::OwnedAsciiExt; +use std::borrow::ToOwned; use servo_util::str::DOMString; use string_cache::Atom; @@ -54,28 +55,28 @@ impl<'a> HTMLButtonElementMethods for JSRef<'a, HTMLButtonElement> { } // http://www.whatwg.org/html/#dom-fe-disabled - make_bool_getter!(Disabled) + make_bool_getter!(Disabled); // http://www.whatwg.org/html/#dom-fe-disabled - make_bool_setter!(SetDisabled, "disabled") + make_bool_setter!(SetDisabled, "disabled"); // https://html.spec.whatwg.org/multipage/forms.html#dom-button-type fn Type(self) -> DOMString { let elem: JSRef<Element> = ElementCast::from_ref(self); - let ty = elem.get_string_attribute(&atom!("type")).into_ascii_lower(); + let ty = elem.get_string_attribute(&atom!("type")).into_ascii_lowercase(); // https://html.spec.whatwg.org/multipage/forms.html#attr-button-type match ty.as_slice() { "reset" | "button" | "menu" => ty, - _ => "submit".into_string() + _ => "submit".to_owned() } } // https://html.spec.whatwg.org/multipage/forms.html#dom-button-type - make_setter!(SetType, "type") + make_setter!(SetType, "type"); } impl<'a> VirtualMethods for JSRef<'a, HTMLButtonElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index 15f25a495a5..cad7c4c7a33 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -26,6 +26,7 @@ use geom::size::Size2D; use std::cell::Cell; use std::default::Default; +use std::sync::mpsc::Sender; const DEFAULT_WIDTH: u32 = 300; const DEFAULT_HEIGHT: u32 = 150; @@ -115,7 +116,7 @@ impl<'a> HTMLCanvasElementMethods for JSRef<'a, HTMLCanvasElement> { } impl<'a> VirtualMethods for JSRef<'a, HTMLCanvasElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let element: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(element as &VirtualMethods) } diff --git a/components/script/dom/htmlcollection.rs b/components/script/dom/htmlcollection.rs index 9cbff941c03..a1aa197046e 100644 --- a/components/script/dom/htmlcollection.rs +++ b/components/script/dom/htmlcollection.rs @@ -96,7 +96,7 @@ impl HTMLCollection { } let filter = TagNameFilter { tag: Atom::from_slice(tag.as_slice()), - ascii_lower_tag: Atom::from_slice(tag.as_slice().to_ascii_lower().as_slice()), + ascii_lower_tag: Atom::from_slice(tag.as_slice().to_ascii_lowercase().as_slice()), }; HTMLCollection::create(window, root, box filter) } @@ -165,12 +165,13 @@ impl HTMLCollection { } fn traverse<'a>(root: JSRef<'a, Node>) - -> FilterMap<'a, JSRef<'a, Node>, + -> FilterMap<JSRef<'a, Node>, JSRef<'a, Element>, - Skip<TreeIterator<'a>>> { + Skip<TreeIterator<'a>>, + fn(JSRef<Node>) -> Option<JSRef<Element>>> { root.traverse_preorder() .skip(1) - .filter_map(ElementCast::to_ref) + .filter_map(ElementCast::to_ref as fn(JSRef<Node>) -> Option<JSRef<Element>>) } } diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs index d60591bb390..337490dc987 100644 --- a/components/script/dom/htmlelement.rs +++ b/components/script/dom/htmlelement.rs @@ -21,6 +21,7 @@ use dom::document::Document; use dom::domstringmap::DOMStringMap; use dom::element::{Element, ElementTypeId, ActivationElementHelpers, AttributeHandlers}; use dom::eventtarget::{EventTarget, EventTargetHelpers, EventTargetTypeId}; +use dom::htmlinputelement::HTMLInputElement; use dom::htmlmediaelement::HTMLMediaElementTypeId; use dom::htmltablecellelement::HTMLTableCellElementTypeId; use dom::node::{Node, NodeTypeId, window_from_node}; @@ -30,6 +31,7 @@ use servo_util::str::DOMString; use string_cache::Atom; +use std::borrow::ToOwned; use std::default::Default; #[dom_struct] @@ -83,17 +85,17 @@ impl<'a> HTMLElementMethods for JSRef<'a, HTMLElement> { }) } - make_getter!(Title) - make_setter!(SetTitle, "title") + make_getter!(Title); + make_setter!(SetTitle, "title"); - make_getter!(Lang) - make_setter!(SetLang, "lang") + make_getter!(Lang); + make_setter!(SetLang, "lang"); // http://html.spec.whatwg.org/multipage/#dom-hidden - make_bool_getter!(Hidden) - make_bool_setter!(SetHidden, "hidden") + make_bool_getter!(Hidden); + make_bool_setter!(SetHidden, "hidden"); - global_event_handlers!(NoOnload) + global_event_handlers!(NoOnload); // https://html.spec.whatwg.org/multipage/dom.html#dom-dataset fn Dataset(self) -> Temporary<DOMStringMap> { @@ -122,7 +124,7 @@ impl<'a> HTMLElementMethods for JSRef<'a, HTMLElement> { // https://html.spec.whatwg.org/multipage/interaction.html#dom-click fn Click(self) { - let maybe_input = HTMLInputElementCast::to_ref(self); + let maybe_input: Option<JSRef<HTMLInputElement>> = HTMLInputElementCast::to_ref(self); match maybe_input { Some(i) if i.Disabled() => return, _ => () @@ -141,7 +143,7 @@ pub trait HTMLElementCustomAttributeHelpers { } fn to_snake_case(name: DOMString) -> DOMString { - let mut attr_name = "data-".into_string(); + let mut attr_name = "data-".to_owned(); for ch in name.as_slice().chars() { if ch.is_uppercase() { attr_name.push('\x2d'); @@ -168,7 +170,7 @@ impl<'a> HTMLElementCustomAttributeHelpers for JSRef<'a, HTMLElement> { let element: JSRef<Element> = ElementCast::from_ref(self); element.get_attribute(ns!(""), &Atom::from_slice(to_snake_case(name).as_slice())).map(|attr| { let attr = attr.root(); - attr.r().value().as_slice().into_string() + attr.r().value().as_slice().to_owned() }) } @@ -179,7 +181,7 @@ impl<'a> HTMLElementCustomAttributeHelpers for JSRef<'a, HTMLElement> { } impl<'a> VirtualMethods for JSRef<'a, HTMLElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let element: &JSRef<Element> = ElementCast::from_borrowed_ref(self); Some(element as &VirtualMethods) } @@ -199,12 +201,12 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLElement> { let evtarget: JSRef<EventTarget> = EventTargetCast::from_ref(*self); evtarget.set_event_handler_uncompiled(cx, url, reflector, name.slice_from(2), - attr.value().as_slice().into_string()); + attr.value().as_slice().to_owned()); } } } -#[deriving(Copy, PartialEq, Show)] +#[derive(Copy, PartialEq, Show)] #[jstraceable] pub enum HTMLElementTypeId { HTMLElement, diff --git a/components/script/dom/htmlfieldsetelement.rs b/components/script/dom/htmlfieldsetelement.rs index 6f0241ff8cd..7befe8426d0 100644 --- a/components/script/dom/htmlfieldsetelement.rs +++ b/components/script/dom/htmlfieldsetelement.rs @@ -71,14 +71,14 @@ impl<'a> HTMLFieldSetElementMethods for JSRef<'a, HTMLFieldSetElement> { } // http://www.whatwg.org/html/#dom-fieldset-disabled - make_bool_getter!(Disabled) + make_bool_getter!(Disabled); // http://www.whatwg.org/html/#dom-fieldset-disabled - make_bool_setter!(SetDisabled, "disabled") + make_bool_setter!(SetDisabled, "disabled"); } impl<'a> VirtualMethods for JSRef<'a, HTMLFieldSetElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index fc8f9879c7b..48edae7059f 100644 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -30,6 +30,7 @@ use url::UrlParser; use url::form_urlencoded::serialize; use string_cache::Atom; +use std::borrow::ToOwned; use std::cell::Cell; #[dom_struct] @@ -61,28 +62,28 @@ impl HTMLFormElement { impl<'a> HTMLFormElementMethods for JSRef<'a, HTMLFormElement> { // https://html.spec.whatwg.org/multipage/forms.html#dom-form-acceptcharset - make_getter!(AcceptCharset, "accept-charset") + make_getter!(AcceptCharset, "accept-charset"); // https://html.spec.whatwg.org/multipage/forms.html#dom-form-acceptcharset - make_setter!(SetAcceptCharset, "accept-charset") + make_setter!(SetAcceptCharset, "accept-charset"); // https://html.spec.whatwg.org/multipage/forms.html#dom-fs-action - make_url_or_base_getter!(Action) + make_url_or_base_getter!(Action); // https://html.spec.whatwg.org/multipage/forms.html#dom-fs-action - make_setter!(SetAction, "action") + make_setter!(SetAction, "action"); // https://html.spec.whatwg.org/multipage/forms.html#dom-form-autocomplete - make_enumerated_getter!(Autocomplete, "on", "off") + make_enumerated_getter!(Autocomplete, "on", ("off")); // https://html.spec.whatwg.org/multipage/forms.html#dom-form-autocomplete - make_setter!(SetAutocomplete, "autocomplete") + make_setter!(SetAutocomplete, "autocomplete"); // https://html.spec.whatwg.org/multipage/forms.html#dom-fs-enctype - make_enumerated_getter!(Enctype, "application/x-www-form-urlencoded", "text/plain" | "multipart/form-data") + make_enumerated_getter!(Enctype, "application/x-www-form-urlencoded", ("text/plain") | ("multipart/form-data")); // https://html.spec.whatwg.org/multipage/forms.html#dom-fs-enctype - make_setter!(SetEnctype, "enctype") + make_setter!(SetEnctype, "enctype"); // https://html.spec.whatwg.org/multipage/forms.html#dom-fs-encoding fn Encoding(self) -> DOMString { @@ -95,28 +96,28 @@ impl<'a> HTMLFormElementMethods for JSRef<'a, HTMLFormElement> { } // https://html.spec.whatwg.org/multipage/forms.html#dom-fs-method - make_enumerated_getter!(Method, "get", "post" | "dialog") + make_enumerated_getter!(Method, "get", ("post") | ("dialog")); // https://html.spec.whatwg.org/multipage/forms.html#dom-fs-method - make_setter!(SetMethod, "method") + make_setter!(SetMethod, "method"); // https://html.spec.whatwg.org/multipage/forms.html#dom-form-name - make_getter!(Name) + make_getter!(Name); // https://html.spec.whatwg.org/multipage/forms.html#dom-form-name - make_setter!(SetName, "name") + make_setter!(SetName, "name"); // https://html.spec.whatwg.org/multipage/forms.html#dom-fs-novalidate - make_bool_getter!(NoValidate) + make_bool_getter!(NoValidate); // https://html.spec.whatwg.org/multipage/forms.html#dom-fs-novalidate - make_bool_setter!(SetNoValidate, "novalidate") + make_bool_setter!(SetNoValidate, "novalidate"); // https://html.spec.whatwg.org/multipage/forms.html#dom-fs-target - make_getter!(Target) + make_getter!(Target); // https://html.spec.whatwg.org/multipage/forms.html#dom-fs-target - make_setter!(SetTarget, "target") + make_setter!(SetTarget, "target"); // https://html.spec.whatwg.org/multipage/forms.html#the-form-element:concept-form-submit fn Submit(self) { @@ -129,13 +130,13 @@ impl<'a> HTMLFormElementMethods for JSRef<'a, HTMLFormElement> { } } -#[deriving(Copy)] +#[derive(Copy)] pub enum SubmittedFrom { FromFormSubmitMethod, NotFromFormSubmitMethod } -#[deriving(Copy)] +#[derive(Copy)] pub enum ResetFrom { FromFormResetMethod, NotFromFormResetMethod @@ -159,7 +160,7 @@ impl<'a> HTMLFormElementHelpers for JSRef<'a, HTMLFormElement> { // TODO: Handle browsing contexts // TODO: Handle validation let event = Event::new(GlobalRef::Window(win.r()), - "submit".into_string(), + "submit".to_owned(), EventBubbles::Bubbles, EventCancelable::Cancelable).root(); event.r().set_trusted(true); @@ -187,7 +188,7 @@ impl<'a> HTMLFormElementHelpers for JSRef<'a, HTMLFormElement> { let parsed_data = match enctype { FormEncType::UrlEncoded => serialize(form_data.iter().map(|d| (d.name.as_slice(), d.value.as_slice()))), - _ => "".into_string() // TODO: Add serializers for the other encoding types + _ => "".to_owned() // TODO: Add serializers for the other encoding types }; let mut load_data = LoadData::new(action_components); @@ -214,7 +215,7 @@ impl<'a> HTMLFormElementHelpers for JSRef<'a, HTMLFormElement> { fn clean_crlf(s: &str) -> DOMString { // https://html.spec.whatwg.org/multipage/forms.html#constructing-the-form-data-set // Step 4 - let mut buf = "".into_string(); + let mut buf = "".to_owned(); let mut prev = ' '; for ch in s.chars() { match ch { @@ -284,7 +285,7 @@ impl<'a> HTMLFormElementHelpers for JSRef<'a, HTMLFormElement> { "image" => None, // Unimplemented "radio" | "checkbox" => { if value.is_empty() { - value = "on".into_string(); + value = "on".to_owned(); } Some(FormDatum { ty: ty, @@ -346,7 +347,7 @@ impl<'a> HTMLFormElementHelpers for JSRef<'a, HTMLFormElement> { let win = window_from_node(self).root(); let event = Event::new(GlobalRef::Window(win.r()), - "reset".into_string(), + "reset".to_owned(), EventBubbles::Bubbles, EventCancelable::Cancelable).root(); let target: JSRef<EventTarget> = EventTargetCast::from_ref(self); @@ -398,21 +399,21 @@ pub struct FormDatum { pub value: DOMString } -#[deriving(Copy)] +#[derive(Copy)] pub enum FormEncType { TextPlainEncoded, UrlEncoded, FormDataEncoded } -#[deriving(Copy)] +#[derive(Copy)] pub enum FormMethod { FormGet, FormPost, FormDialog } -#[deriving(Copy)] +#[derive(Copy)] pub enum FormSubmitter<'a> { FormElement(JSRef<'a, HTMLFormElement>), InputElement(JSRef<'a, HTMLInputElement>) @@ -481,7 +482,7 @@ impl<'a> FormSubmitter<'a> { } } -pub trait FormControl<'a> : Copy { +pub trait FormControl<'a> : Copy + Sized { // FIXME: This is wrong (https://github.com/servo/servo/issues/3553) // but we need html5ever to do it correctly fn form_owner(self) -> Option<Temporary<HTMLFormElement>> { @@ -506,16 +507,21 @@ pub trait FormControl<'a> : Copy { .map(Temporary::from_rooted) } - fn get_form_attribute(self, - attr: &Atom, - input: |Self| -> DOMString, - owner: |JSRef<HTMLFormElement>| -> DOMString) -> DOMString { + fn get_form_attribute<InputFn, OwnerFn>(self, + attr: &Atom, + input: InputFn, + owner: OwnerFn) + -> DOMString + where InputFn: Fn(Self) -> DOMString, + OwnerFn: Fn(JSRef<HTMLFormElement>) -> DOMString + { if self.to_element().has_attribute(attr) { input(self) } else { - self.form_owner().map_or("".into_string(), |t| owner(t.root().r())) + self.form_owner().map_or("".to_owned(), |t| owner(t.root().r())) } } + fn to_element(self) -> JSRef<'a, Element>; // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-mutable fn mutable(self) -> bool; diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 66d0f824fa2..78afe6e0b14 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -198,7 +198,7 @@ impl<'a> HTMLIFrameElementMethods for JSRef<'a, HTMLIFrameElement> { } impl<'a> VirtualMethods for JSRef<'a, HTMLIFrameElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } @@ -214,7 +214,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLIFrameElement> { let mut modes = SandboxAllowance::AllowNothing as u8; if let Some(ref tokens) = attr.value().tokens() { for token in tokens.iter() { - modes |= match token.as_slice().to_ascii_lower().as_slice() { + modes |= match token.as_slice().to_ascii_lowercase().as_slice() { "allow-same-origin" => SandboxAllowance::AllowSameOrigin, "allow-forms" => SandboxAllowance::AllowForms, "allow-pointer-lock" => SandboxAllowance::AllowPointerLock, diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 0fb926666fa..2be787eabef 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -24,6 +24,8 @@ use string_cache::Atom; use url::{Url, UrlParser}; +use std::borrow::ToOwned; + #[dom_struct] pub struct HTMLImageElement { htmlelement: HTMLElement, @@ -93,19 +95,19 @@ impl LayoutHTMLImageElementHelpers for JS<HTMLImageElement> { } impl<'a> HTMLImageElementMethods for JSRef<'a, HTMLImageElement> { - make_getter!(Alt) + make_getter!(Alt); - make_setter!(SetAlt, "alt") + make_setter!(SetAlt, "alt"); - make_url_getter!(Src) + make_url_getter!(Src); - make_setter!(SetSrc, "src") + make_setter!(SetSrc, "src"); - make_getter!(UseMap) + make_getter!(UseMap); - make_setter!(SetUseMap, "usemap") + make_setter!(SetUseMap, "usemap"); - make_bool_getter!(IsMap) + make_bool_getter!(IsMap); fn SetIsMap(self, is_map: bool) { let element: JSRef<Element> = ElementCast::from_ref(self); @@ -148,33 +150,33 @@ impl<'a> HTMLImageElementMethods for JSRef<'a, HTMLImageElement> { elem.set_uint_attribute(&atom!("height"), height) } - make_getter!(Name) + make_getter!(Name); - make_setter!(SetName, "name") + make_setter!(SetName, "name"); - make_getter!(Align) + make_getter!(Align); - make_setter!(SetAlign, "align") + make_setter!(SetAlign, "align"); - make_uint_getter!(Hspace) + make_uint_getter!(Hspace); - make_uint_setter!(SetHspace, "hspace") + make_uint_setter!(SetHspace, "hspace"); - make_uint_getter!(Vspace) + make_uint_getter!(Vspace); - make_uint_setter!(SetVspace, "vspace") + make_uint_setter!(SetVspace, "vspace"); - make_getter!(LongDesc) + make_getter!(LongDesc); - make_setter!(SetLongDesc, "longdesc") + make_setter!(SetLongDesc, "longdesc"); - make_getter!(Border) + make_getter!(Border); - make_setter!(SetBorder, "border") + make_setter!(SetBorder, "border"); } impl<'a> VirtualMethods for JSRef<'a, HTMLImageElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } @@ -189,7 +191,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLImageElement> { &atom!("src") => { let window = window_from_node(*self).root(); let url = window.r().get_url(); - self.update_image(Some((attr.value().as_slice().into_string(), &url))); + self.update_image(Some((attr.value().as_slice().to_owned(), &url))); }, _ => () } diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 22da5bb20d7..b8af0ea9d36 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -38,6 +38,7 @@ use servo_util::str::DOMString; use string_cache::Atom; use std::ascii::OwnedAsciiExt; +use std::borrow::ToOwned; use std::cell::Cell; use std::default::Default; @@ -45,7 +46,7 @@ const DEFAULT_SUBMIT_VALUE: &'static str = "Submit"; const DEFAULT_RESET_VALUE: &'static str = "Reset"; #[jstraceable] -#[deriving(PartialEq, Copy)] +#[derive(PartialEq, Copy)] #[allow(dead_code)] enum InputType { InputSubmit, @@ -116,7 +117,7 @@ impl HTMLInputElement { checked_changed: Cell::new(false), value_changed: Cell::new(false), size: Cell::new(DEFAULT_INPUT_SIZE), - textinput: DOMRefCell::new(TextInput::new(Single, "".into_string())), + textinput: DOMRefCell::new(TextInput::new(Single, "".to_owned())), activation_state: DOMRefCell::new(InputActivationState::new()) } } @@ -149,18 +150,18 @@ impl LayoutHTMLInputElementHelpers for JS<HTMLInputElement> { unsafe fn get_raw_attr_value(input: JS<HTMLInputElement>) -> Option<String> { let elem: JS<Element> = input.transmute_copy(); (*elem.unsafe_get()).get_attr_val_for_layout(&ns!(""), &atom!("value")) - .map(|s| s.into_string()) + .map(|s| s.to_owned()) } match (*self.unsafe_get()).input_type.get() { - InputType::InputCheckbox | InputType::InputRadio => "".into_string(), - InputType::InputFile | InputType::InputImage => "".into_string(), - InputType::InputButton => get_raw_attr_value(self).unwrap_or_else(|| "".into_string()), - InputType::InputSubmit => get_raw_attr_value(self).unwrap_or_else(|| DEFAULT_SUBMIT_VALUE.into_string()), - InputType::InputReset => get_raw_attr_value(self).unwrap_or_else(|| DEFAULT_RESET_VALUE.into_string()), + InputType::InputCheckbox | InputType::InputRadio => "".to_owned(), + InputType::InputFile | InputType::InputImage => "".to_owned(), + InputType::InputButton => get_raw_attr_value(self).unwrap_or_else(|| "".to_owned()), + InputType::InputSubmit => get_raw_attr_value(self).unwrap_or_else(|| DEFAULT_SUBMIT_VALUE.to_owned()), + InputType::InputReset => get_raw_attr_value(self).unwrap_or_else(|| DEFAULT_RESET_VALUE.to_owned()), InputType::InputPassword => { let raw = get_raw_textinput_value(self); - String::from_char(raw.char_len(), '●') + raw.chars().map(|_| '●').collect() } _ => get_raw_textinput_value(self), } @@ -191,16 +192,16 @@ impl RawLayoutHTMLInputElementHelpers for HTMLInputElement { impl<'a> HTMLInputElementMethods for JSRef<'a, HTMLInputElement> { // http://www.whatwg.org/html/#dom-fe-disabled - make_bool_getter!(Disabled) + make_bool_getter!(Disabled); // http://www.whatwg.org/html/#dom-fe-disabled - make_bool_setter!(SetDisabled, "disabled") + make_bool_setter!(SetDisabled, "disabled"); // https://html.spec.whatwg.org/multipage/forms.html#dom-input-defaultchecked - make_bool_getter!(DefaultChecked, "checked") + make_bool_getter!(DefaultChecked, "checked"); // https://html.spec.whatwg.org/multipage/forms.html#dom-input-defaultchecked - make_bool_setter!(SetDefaultChecked, "checked") + make_bool_setter!(SetDefaultChecked, "checked"); // https://html.spec.whatwg.org/multipage/forms.html#dom-input-checked fn Checked(self) -> bool { @@ -213,28 +214,28 @@ impl<'a> HTMLInputElementMethods for JSRef<'a, HTMLInputElement> { } // https://html.spec.whatwg.org/multipage/forms.html#dom-input-readonly - make_bool_getter!(ReadOnly) + make_bool_getter!(ReadOnly); // https://html.spec.whatwg.org/multipage/forms.html#dom-input-readonly - make_bool_setter!(SetReadOnly, "readonly") + make_bool_setter!(SetReadOnly, "readonly"); // https://html.spec.whatwg.org/multipage/forms.html#dom-input-size - make_uint_getter!(Size) + make_uint_getter!(Size); // https://html.spec.whatwg.org/multipage/forms.html#dom-input-size - make_uint_setter!(SetSize, "size") + make_uint_setter!(SetSize, "size"); // https://html.spec.whatwg.org/multipage/forms.html#dom-input-type - make_enumerated_getter!(Type, "text", "hidden" | "search" | "tel" | - "url" | "email" | "password" | - "datetime" | "date" | "month" | - "week" | "time" | "datetime-local" | - "number" | "range" | "color" | - "checkbox" | "radio" | "file" | - "submit" | "image" | "reset" | "button") + make_enumerated_getter!(Type, "text", ("hidden") | ("search") | ("tel") | + ("url") | ("email") | ("password") | + ("datetime") | ("date") | ("month") | + ("week") | ("time") | ("datetime-local") | + ("number") | ("range") | ("color") | + ("checkbox") | ("radio") | ("file") | + ("submit") | ("image") | ("reset") | ("button")); // https://html.spec.whatwg.org/multipage/forms.html#dom-input-type - make_setter!(SetType, "type") + make_setter!(SetType, "type"); // https://html.spec.whatwg.org/multipage/forms.html#dom-input-value fn Value(self) -> DOMString { @@ -249,40 +250,40 @@ impl<'a> HTMLInputElementMethods for JSRef<'a, HTMLInputElement> { } // https://html.spec.whatwg.org/multipage/forms.html#dom-input-defaultvalue - make_getter!(DefaultValue, "value") + make_getter!(DefaultValue, "value"); // https://html.spec.whatwg.org/multipage/forms.html#dom-input-defaultvalue - make_setter!(SetDefaultValue, "value") + make_setter!(SetDefaultValue, "value"); // https://html.spec.whatwg.org/multipage/forms.html#attr-fe-name - make_getter!(Name) + make_getter!(Name); // https://html.spec.whatwg.org/multipage/forms.html#attr-fe-name - make_setter!(SetName, "name") + make_setter!(SetName, "name"); // https://html.spec.whatwg.org/multipage/forms.html#dom-input-formaction - make_url_or_base_getter!(FormAction) + make_url_or_base_getter!(FormAction); // https://html.spec.whatwg.org/multipage/forms.html#dom-input-formaction - make_setter!(SetFormAction, "formaction") + make_setter!(SetFormAction, "formaction"); // https://html.spec.whatwg.org/multipage/forms.html#dom-input-formenctype - make_enumerated_getter!(FormEnctype, "application/x-www-form-urlencoded", "text/plain" | "multipart/form-data") + make_enumerated_getter!(FormEnctype, "application/x-www-form-urlencoded", ("text/plain") | ("multipart/form-data")); // https://html.spec.whatwg.org/multipage/forms.html#dom-input-formenctype - make_setter!(SetFormEnctype, "formenctype") + make_setter!(SetFormEnctype, "formenctype"); // https://html.spec.whatwg.org/multipage/forms.html#dom-input-formmethod - make_enumerated_getter!(FormMethod, "get", "post" | "dialog") + make_enumerated_getter!(FormMethod, "get", ("post") | ("dialog")); // https://html.spec.whatwg.org/multipage/forms.html#dom-input-formmethod - make_setter!(SetFormMethod, "formmethod") + make_setter!(SetFormMethod, "formmethod"); // https://html.spec.whatwg.org/multipage/forms.html#dom-input-formtarget - make_getter!(FormTarget) + make_getter!(FormTarget); // https://html.spec.whatwg.org/multipage/forms.html#dom-input-formtarget - make_setter!(SetFormTarget, "formtarget") + make_setter!(SetFormTarget, "formtarget"); // https://html.spec.whatwg.org/multipage/forms.html#dom-input-indeterminate fn Indeterminate(self) -> bool { @@ -311,17 +312,23 @@ fn broadcast_radio_checked(broadcaster: JSRef<HTMLInputElement>, group: Option<& let doc = document_from_node(broadcaster).root(); let doc_node: JSRef<Node> = NodeCast::from_ref(doc.r()); - // There is no DOM tree manipulation here, so this is safe - let mut iter = unsafe { - doc_node.query_selector_iter("input[type=radio]".into_string()).unwrap() + // This function is a workaround for lifetime constraint difficulties. + fn do_broadcast<'a>(doc_node: JSRef<'a, Node>, broadcaster: JSRef<'a, HTMLInputElement>, + owner: Option<JSRef<'a, HTMLFormElement>>, group: Option<&str>) { + // There is no DOM tree manipulation here, so this is safe + let mut iter = unsafe { + doc_node.query_selector_iter("input[type=radio]".to_owned()).unwrap() .filter_map(|t| HTMLInputElementCast::to_ref(t)) - .filter(|&r| in_same_group(r, owner.r(), group) && broadcaster != r) - }; - for r in iter { - if r.Checked() { - r.SetChecked(false); + .filter(|&r| in_same_group(r, owner, group) && broadcaster != r) + }; + for r in iter { + if r.Checked() { + r.SetChecked(false); + } } } + + do_broadcast(doc_node, broadcaster, owner.r(), group) } fn in_same_group<'a,'b>(other: JSRef<'a, HTMLInputElement>, @@ -388,7 +395,7 @@ impl<'a> HTMLInputElementHelpers for JSRef<'a, HTMLInputElement> { } impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } @@ -439,7 +446,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> { } &atom!("value") => { if !self.value_changed.get() { - self.textinput.borrow_mut().set_content(attr.value().as_slice().into_string()); + self.textinput.borrow_mut().set_content(attr.value().as_slice().to_owned()); self.force_relayout(); } } @@ -488,7 +495,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> { } &atom!("value") => { if !self.value_changed.get() { - self.textinput.borrow_mut().set_content("".into_string()); + self.textinput.borrow_mut().set_content("".to_owned()); self.force_relayout(); } } @@ -639,7 +646,7 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> { // Safe since we only manipulate the DOM tree after finding an element let checked_member = unsafe { - doc_node.query_selector_iter("input[type=radio]".into_string()).unwrap() + doc_node.query_selector_iter("input[type=radio]".to_owned()).unwrap() .filter_map(|t| HTMLInputElementCast::to_ref(t)) .filter(|&r| in_same_group(r, owner.r(), group.as_ref().map(|gr| gr.as_slice()))) @@ -739,7 +746,7 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> { if self.mutable() { let win = window_from_node(*self).root(); let event = Event::new(GlobalRef::Window(win.r()), - "input".into_string(), + "input".to_owned(), EventBubbles::Bubbles, EventCancelable::NotCancelable).root(); event.r().set_trusted(true); @@ -747,7 +754,7 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> { target.DispatchEvent(event.r()).ok(); let event = Event::new(GlobalRef::Window(win.r()), - "change".into_string(), + "change".to_owned(), EventBubbles::Bubbles, EventCancelable::NotCancelable).root(); event.r().set_trusted(true); @@ -765,16 +772,20 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> { let doc = document_from_node(*self).root(); let node: JSRef<Node> = NodeCast::from_ref(doc.r()); let owner = self.form_owner(); - if owner.is_none() || ElementCast::from_ref(*self).click_in_progress() { + let elem: JSRef<Element> = ElementCast::from_ref(*self); + if owner.is_none() || elem.click_in_progress() { return; } // This is safe because we are stopping after finding the first element // and only then performing actions which may modify the DOM tree unsafe { - node.query_selector_iter("input[type=submit]".into_string()).unwrap() - .filter_map(|t| HTMLInputElementCast::to_ref(t)) + node.query_selector_iter("input[type=submit]".to_owned()).unwrap() + .filter_map(|t| { + let h: Option<JSRef<HTMLInputElement>> = HTMLInputElementCast::to_ref(t); + h + }) .find(|r| r.form_owner() == owner) - .map(|s| s.synthetic_click_activation(ctrlKey, shiftKey, altKey, metaKey)); + .map(|&:s| s.synthetic_click_activation(ctrlKey, shiftKey, altKey, metaKey)); } } } diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index e4febefa004..3cf8601bd04 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -21,6 +21,7 @@ use layout_interface::{LayoutChan, Msg}; use servo_util::str::{DOMString, HTML_SPACE_CHARACTERS}; use std::ascii::AsciiExt; +use std::borrow::ToOwned; use std::default::Default; use url::UrlParser; use string_cache::Atom; @@ -54,7 +55,7 @@ impl HTMLLinkElement { fn get_attr(element: JSRef<Element>, name: &Atom) -> Option<String> { let elem = element.get_attribute(ns!(""), name).root(); - elem.map(|e| e.r().value().as_slice().into_string()) + elem.map(|e| e.r().value().as_slice().to_owned()) } fn is_stylesheet(value: &Option<String>) -> bool { @@ -68,7 +69,7 @@ fn is_stylesheet(value: &Option<String>) -> bool { } impl<'a> VirtualMethods for JSRef<'a, HTMLLinkElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } @@ -140,20 +141,20 @@ impl<'a> PrivateHTMLLinkElementHelpers for JSRef<'a, HTMLLinkElement> { } impl<'a> HTMLLinkElementMethods for JSRef<'a, HTMLLinkElement> { - make_url_getter!(Href) - make_setter!(SetHref, "href") + make_url_getter!(Href); + make_setter!(SetHref, "href"); - make_getter!(Rel) - make_setter!(SetRel, "rel") + make_getter!(Rel); + make_setter!(SetRel, "rel"); - make_getter!(Media) - make_setter!(SetMedia, "media") + make_getter!(Media); + make_setter!(SetMedia, "media"); - make_getter!(Hreflang) - make_setter!(SetHreflang, "hreflang") + make_getter!(Hreflang); + make_setter!(SetHreflang, "hreflang"); - make_getter!(Type) - make_setter!(SetType, "type") + make_getter!(Type); + make_setter!(SetType, "type"); fn RelList(self) -> Temporary<DOMTokenList> { self.rel_list.or_init(|| { diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index ea8dcfa4041..ef75b1f43ee 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -38,7 +38,7 @@ impl HTMLMediaElement { } } -#[deriving(Copy, PartialEq, Show)] +#[derive(Copy, PartialEq, Show)] #[jstraceable] pub enum HTMLMediaElementTypeId { HTMLAudioElement, diff --git a/components/script/dom/htmlobjectelement.rs b/components/script/dom/htmlobjectelement.rs index 43478c532d5..1d4160a8a38 100644 --- a/components/script/dom/htmlobjectelement.rs +++ b/components/script/dom/htmlobjectelement.rs @@ -89,14 +89,14 @@ impl<'a> HTMLObjectElementMethods for JSRef<'a, HTMLObjectElement> { } // https://html.spec.whatwg.org/multipage/embedded-content.html#dom-object-type - make_getter!(Type) + make_getter!(Type); // https://html.spec.whatwg.org/multipage/embedded-content.html#dom-object-type - make_setter!(SetType, "type") + make_setter!(SetType, "type"); } impl<'a> VirtualMethods for JSRef<'a, HTMLObjectElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } diff --git a/components/script/dom/htmloptgroupelement.rs b/components/script/dom/htmloptgroupelement.rs index 846a53bc41e..d9d0e0cd2c4 100644 --- a/components/script/dom/htmloptgroupelement.rs +++ b/components/script/dom/htmloptgroupelement.rs @@ -47,14 +47,14 @@ impl HTMLOptGroupElement { impl<'a> HTMLOptGroupElementMethods for JSRef<'a, HTMLOptGroupElement> { // http://www.whatwg.org/html#dom-optgroup-disabled - make_bool_getter!(Disabled) + make_bool_getter!(Disabled); // http://www.whatwg.org/html#dom-optgroup-disabled - make_bool_setter!(SetDisabled, "disabled") + make_bool_setter!(SetDisabled, "disabled"); } impl<'a> VirtualMethods for JSRef<'a, HTMLOptGroupElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } diff --git a/components/script/dom/htmloptionelement.rs b/components/script/dom/htmloptionelement.rs index bfe11883cfc..f80f3b63c49 100644 --- a/components/script/dom/htmloptionelement.rs +++ b/components/script/dom/htmloptionelement.rs @@ -69,7 +69,7 @@ fn collect_text(node: &JSRef<Node>, value: &mut DOMString) { impl<'a> HTMLOptionElementMethods for JSRef<'a, HTMLOptionElement> { // http://www.whatwg.org/html/#dom-option-disabled - make_bool_getter!(Disabled) + make_bool_getter!(Disabled); // http://www.whatwg.org/html/#dom-option-disabled fn SetDisabled(self, disabled: bool) { @@ -104,7 +104,7 @@ impl<'a> HTMLOptionElementMethods for JSRef<'a, HTMLOptionElement> { } // https://html.spec.whatwg.org/multipage/forms.html#attr-option-value - make_setter!(SetValue, "value") + make_setter!(SetValue, "value"); // https://html.spec.whatwg.org/multipage/forms.html#attr-option-label fn Label(self) -> DOMString { @@ -118,12 +118,12 @@ impl<'a> HTMLOptionElementMethods for JSRef<'a, HTMLOptionElement> { } // https://html.spec.whatwg.org/multipage/forms.html#attr-option-label - make_setter!(SetLabel, "label") + make_setter!(SetLabel, "label"); } impl<'a> VirtualMethods for JSRef<'a, HTMLOptionElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index c2af3ae9f6a..f9f52d3f7c9 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -31,6 +31,7 @@ use encoding::all::UTF_8; use encoding::types::{Encoding, DecoderTrap}; use servo_net::resource_task::load_whole_resource; use servo_util::str::{DOMString, HTML_SPACE_CHARACTERS, StaticStringVec}; +use std::borrow::ToOwned; use std::cell::Cell; use string_cache::Atom; use url::UrlParser; @@ -239,7 +240,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { let window = window_from_node(self).root(); let window = window.r(); let event = Event::new(GlobalRef::Window(window), - "load".into_string(), + "load".to_owned(), EventBubbles::DoesNotBubble, EventCancelable::NotCancelable).root(); event.r().set_trusted(true); @@ -257,7 +258,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { }, Some(ref s) => { debug!("script type={}", *s); - SCRIPT_JS_MIMES.contains(&s.to_ascii_lower().as_slice().trim_chars(HTML_SPACE_CHARACTERS)) + SCRIPT_JS_MIMES.contains(&s.to_ascii_lowercase().as_slice().trim_matches(HTML_SPACE_CHARACTERS)) }, None => { debug!("no script type"); @@ -270,7 +271,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { }, Some(ref s) => { debug!("script language={}", *s); - SCRIPT_JS_MIMES.contains(&format!("text/{}", s).to_ascii_lower().as_slice()) + SCRIPT_JS_MIMES.contains(&format!("text/{}", s).to_ascii_lowercase().as_slice()) }, None => { debug!("no script type or language, inferring js"); @@ -287,7 +288,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { } impl<'a> VirtualMethods for JSRef<'a, HTMLScriptElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } @@ -341,9 +342,9 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLScriptElement> { } impl<'a> HTMLScriptElementMethods for JSRef<'a, HTMLScriptElement> { - make_url_getter!(Src) + make_url_getter!(Src); - make_setter!(SetSrc, "src") + make_setter!(SetSrc, "src"); // http://www.whatwg.org/html/#dom-script-text fn Text(self) -> DOMString { diff --git a/components/script/dom/htmlselectelement.rs b/components/script/dom/htmlselectelement.rs index dcef30bf1ac..4f82d2e91f8 100644 --- a/components/script/dom/htmlselectelement.rs +++ b/components/script/dom/htmlselectelement.rs @@ -23,6 +23,8 @@ use dom::virtualmethods::VirtualMethods; use servo_util::str::DOMString; use string_cache::Atom; +use std::borrow::ToOwned; + #[dom_struct] pub struct HTMLSelectElement { htmlelement: HTMLElement @@ -59,24 +61,24 @@ impl<'a> HTMLSelectElementMethods for JSRef<'a, HTMLSelectElement> { } // http://www.whatwg.org/html/#dom-fe-disabled - make_bool_getter!(Disabled) + make_bool_getter!(Disabled); // http://www.whatwg.org/html/#dom-fe-disabled - make_bool_setter!(SetDisabled, "disabled") + make_bool_setter!(SetDisabled, "disabled"); // https://html.spec.whatwg.org/multipage/forms.html#dom-select-type fn Type(self) -> DOMString { let elem: JSRef<Element> = ElementCast::from_ref(self); if elem.has_attribute(&atom!("multiple")) { - "select-multiple".into_string() + "select-multiple".to_owned() } else { - "select-one".into_string() + "select-one".to_owned() } } } impl<'a> VirtualMethods for JSRef<'a, HTMLSelectElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } diff --git a/components/script/dom/htmlserializer.rs b/components/script/dom/htmlserializer.rs index b4c3662fd30..a0ab5b82d03 100644 --- a/components/script/dom/htmlserializer.rs +++ b/components/script/dom/htmlserializer.rs @@ -15,6 +15,8 @@ use dom::node::{Node, NodeHelpers, NodeTypeId, NodeIterator}; use dom::processinginstruction::ProcessingInstruction; use dom::text::Text; +use std::borrow::ToOwned; + #[allow(unrooted_must_root)] pub fn serialize(iterator: &mut NodeIterator) -> String { let mut html = String::new(); @@ -126,7 +128,7 @@ fn serialize_elem(elem: JSRef<Element>, open_elements: &mut Vec<String>, html: & } if !(elem.is_void()) { - open_elements.push(elem.local_name().as_slice().into_string()); + open_elements.push(elem.local_name().as_slice().to_owned()); } } diff --git a/components/script/dom/htmlstyleelement.rs b/components/script/dom/htmlstyleelement.rs index 99899388964..8471280be07 100644 --- a/components/script/dom/htmlstyleelement.rs +++ b/components/script/dom/htmlstyleelement.rs @@ -63,7 +63,7 @@ impl<'a> StyleElementHelpers for JSRef<'a, HTMLStyleElement> { } impl<'a> VirtualMethods for JSRef<'a, HTMLStyleElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } diff --git a/components/script/dom/htmltablecellelement.rs b/components/script/dom/htmltablecellelement.rs index 24450399f77..d19a342b5ae 100644 --- a/components/script/dom/htmltablecellelement.rs +++ b/components/script/dom/htmltablecellelement.rs @@ -13,10 +13,10 @@ use dom::node::NodeTypeId; use dom::virtualmethods::VirtualMethods; use cssparser::RGBA; -use servo_util::str::{mod, DOMString, LengthOrPercentageOrAuto}; +use servo_util::str::{self, DOMString, LengthOrPercentageOrAuto}; use std::cell::Cell; -#[deriving(Copy, PartialEq, Show)] +#[derive(Copy, PartialEq, Show)] #[jstraceable] pub enum HTMLTableCellElementTypeId { HTMLTableDataCellElement, @@ -81,7 +81,7 @@ impl HTMLTableCellElementHelpers for HTMLTableCellElement { } impl<'a> VirtualMethods for JSRef<'a, HTMLTableCellElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } diff --git a/components/script/dom/htmltableelement.rs b/components/script/dom/htmltableelement.rs index e5494e71afa..f78ece6de15 100644 --- a/components/script/dom/htmltableelement.rs +++ b/components/script/dom/htmltableelement.rs @@ -18,7 +18,7 @@ use dom::node::{Node, NodeHelpers, NodeTypeId}; use dom::virtualmethods::VirtualMethods; use cssparser::RGBA; -use servo_util::str::{mod, DOMString, LengthOrPercentageOrAuto}; +use servo_util::str::{self, DOMString, LengthOrPercentageOrAuto}; use std::cell::Cell; #[dom_struct] @@ -62,7 +62,10 @@ impl<'a> HTMLTableElementMethods for JSRef<'a, HTMLTableElement> { fn GetCaption(self) -> Option<Temporary<HTMLTableCaptionElement>> { let node: JSRef<Node> = NodeCast::from_ref(self); node.children() - .filter_map::<JSRef<HTMLTableCaptionElement>>(HTMLTableCaptionElementCast::to_ref) + .filter_map(|n| { + let t: Option<JSRef<HTMLTableCaptionElement>> = HTMLTableCaptionElementCast::to_ref(n); + t + }) .next() .map(Temporary::from_rooted) } @@ -109,7 +112,7 @@ impl HTMLTableElementHelpers for HTMLTableElement { } impl<'a> VirtualMethods for JSRef<'a, HTMLTableElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } diff --git a/components/script/dom/htmltablerowelement.rs b/components/script/dom/htmltablerowelement.rs index a24fb8f3317..ffda70c187e 100644 --- a/components/script/dom/htmltablerowelement.rs +++ b/components/script/dom/htmltablerowelement.rs @@ -14,7 +14,7 @@ use dom::node::{Node, NodeTypeId}; use dom::virtualmethods::VirtualMethods; use cssparser::RGBA; -use servo_util::str::{mod, DOMString}; +use servo_util::str::{self, DOMString}; use std::cell::Cell; #[dom_struct] @@ -62,7 +62,7 @@ impl HTMLTableRowElementHelpers for HTMLTableRowElement { } impl<'a> VirtualMethods for JSRef<'a, HTMLTableRowElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } diff --git a/components/script/dom/htmltablesectionelement.rs b/components/script/dom/htmltablesectionelement.rs index a061ae97222..c3fcf254db3 100644 --- a/components/script/dom/htmltablesectionelement.rs +++ b/components/script/dom/htmltablesectionelement.rs @@ -14,7 +14,7 @@ use dom::node::{Node, NodeTypeId}; use dom::virtualmethods::VirtualMethods; use cssparser::RGBA; -use servo_util::str::{mod, DOMString}; +use servo_util::str::{self, DOMString}; use std::cell::Cell; #[dom_struct] @@ -60,7 +60,7 @@ impl HTMLTableSectionElementHelpers for HTMLTableSectionElement { } impl<'a> VirtualMethods for JSRef<'a, HTMLTableSectionElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index c5d3c1593c1..5582e6aa293 100644 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -29,6 +29,7 @@ use dom::virtualmethods::VirtualMethods; use servo_util::str::DOMString; use string_cache::Atom; +use std::borrow::ToOwned; use std::cell::Cell; #[dom_struct] @@ -83,7 +84,7 @@ impl HTMLTextAreaElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLTextAreaElement { HTMLTextAreaElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLTextAreaElement, localName, prefix, document), - textinput: DOMRefCell::new(TextInput::new(Lines::Multiple, "".into_string())), + textinput: DOMRefCell::new(TextInput::new(Lines::Multiple, "".to_owned())), cols: Cell::new(DEFAULT_COLS), rows: Cell::new(DEFAULT_ROWS), value_changed: Cell::new(false), @@ -102,56 +103,56 @@ impl<'a> HTMLTextAreaElementMethods for JSRef<'a, HTMLTextAreaElement> { // constraints // https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-cols - make_uint_getter!(Cols) + make_uint_getter!(Cols); // https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-cols - make_uint_setter!(SetCols, "cols") + make_uint_setter!(SetCols, "cols"); // http://www.whatwg.org/html/#dom-fe-disabled - make_bool_getter!(Disabled) + make_bool_getter!(Disabled); // http://www.whatwg.org/html/#dom-fe-disabled - make_bool_setter!(SetDisabled, "disabled") + make_bool_setter!(SetDisabled, "disabled"); // https://html.spec.whatwg.org/multipage/forms.html#attr-fe-name - make_getter!(Name) + make_getter!(Name); // https://html.spec.whatwg.org/multipage/forms.html#attr-fe-name - make_setter!(SetName, "name") + make_setter!(SetName, "name"); // https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-placeholder - make_getter!(Placeholder) + make_getter!(Placeholder); // https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-placeholder - make_setter!(SetPlaceholder, "placeholder") + make_setter!(SetPlaceholder, "placeholder"); // https://html.spec.whatwg.org/multipage/forms.html#attr-textarea-readonly - make_bool_getter!(ReadOnly) + make_bool_getter!(ReadOnly); // https://html.spec.whatwg.org/multipage/forms.html#attr-textarea-readonly - make_bool_setter!(SetReadOnly, "readonly") + make_bool_setter!(SetReadOnly, "readonly"); // https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-required - make_bool_getter!(Required) + make_bool_getter!(Required); // https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-required - make_bool_setter!(SetRequired, "required") + make_bool_setter!(SetRequired, "required"); // https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-rows - make_uint_getter!(Rows) + make_uint_getter!(Rows); // https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-rows - make_uint_setter!(SetRows, "rows") + make_uint_setter!(SetRows, "rows"); // https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-wrap - make_getter!(Wrap) + make_getter!(Wrap); // https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-wrap - make_setter!(SetWrap, "wrap") + make_setter!(SetWrap, "wrap"); // https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-type fn Type(self) -> DOMString { - "textarea".into_string() + "textarea".to_owned() } // https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-defaultvalue @@ -199,7 +200,7 @@ impl<'a> PrivateHTMLTextAreaElementHelpers for JSRef<'a, HTMLTextAreaElement> { } impl<'a> VirtualMethods for JSRef<'a, HTMLTextAreaElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } diff --git a/components/script/dom/htmltitleelement.rs b/components/script/dom/htmltitleelement.rs index efe9de12f16..2d3f9ef71aa 100644 --- a/components/script/dom/htmltitleelement.rs +++ b/components/script/dom/htmltitleelement.rs @@ -65,7 +65,7 @@ impl<'a> HTMLTitleElementMethods for JSRef<'a, HTMLTitleElement> { } impl<'a> VirtualMethods for JSRef<'a, HTMLTitleElement> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } diff --git a/components/script/dom/keyboardevent.rs b/components/script/dom/keyboardevent.rs index e28f1c90c6c..518543c27ed 100644 --- a/components/script/dom/keyboardevent.rs +++ b/components/script/dom/keyboardevent.rs @@ -15,6 +15,8 @@ use dom::uievent::UIEvent; use dom::window::Window; use servo_msg::constellation_msg; use servo_util::str::DOMString; + +use std::borrow::ToOwned; use std::cell::{RefCell, Cell}; #[jstraceable] @@ -44,8 +46,8 @@ impl KeyboardEvent { fn new_inherited() -> KeyboardEvent { KeyboardEvent { uievent: UIEvent::new_inherited(EventTypeId::KeyboardEvent), - key: RefCell::new("".into_string()), - code: RefCell::new("".into_string()), + key: RefCell::new("".to_owned()), + code: RefCell::new("".to_owned()), location: Cell::new(0), ctrl: Cell::new(false), alt: Cell::new(false), @@ -83,7 +85,7 @@ impl KeyboardEvent { key_code: u32) -> Temporary<KeyboardEvent> { let ev = KeyboardEvent::new_uninitialized(window).root(); ev.r().InitKeyboardEvent(type_, canBubble, cancelable, view, key, location, - "".into_string(), repeat, "".into_string()); + "".to_owned(), repeat, "".to_owned()); *ev.r().code.borrow_mut() = code; ev.r().ctrl.set(ctrlKey); ev.r().alt.set(altKey); @@ -348,7 +350,7 @@ fn code_value(key: constellation_msg::Key) -> &'static str { constellation_msg::Key::GraveAccent | constellation_msg::Key::World1 | - constellation_msg::Key::World2 => panic!("unknown char code for {}", key), + constellation_msg::Key::World2 => panic!("unknown char code for {:?}", key), constellation_msg::Key::Escape => "Escape", constellation_msg::Key::Enter => "Enter", diff --git a/components/script/dom/macros.rs b/components/script/dom/macros.rs index e67f04b30ba..30759c3bed0 100644 --- a/components/script/dom/macros.rs +++ b/components/script/dom/macros.rs @@ -11,13 +11,13 @@ macro_rules! make_getter( #[allow(unused_imports)] use std::ascii::AsciiExt; let element: JSRef<Element> = ElementCast::from_ref(self); - element.get_string_attribute(&Atom::from_slice($htmlname.to_ascii_lower().as_slice())) + element.get_string_attribute(&Atom::from_slice($htmlname.to_ascii_lowercase().as_slice())) } ); ($attr:ident) => { - make_getter!($attr, stringify!($attr).to_ascii_lower().as_slice()) + make_getter!($attr, stringify!($attr).to_ascii_lowercase().as_slice()); } -) +); #[macro_export] macro_rules! make_bool_getter( @@ -33,9 +33,9 @@ macro_rules! make_bool_getter( } ); ($attr:ident) => { - make_bool_getter!($attr, stringify!($attr).to_ascii_lower().as_slice()) + make_bool_getter!($attr, stringify!($attr).to_ascii_lowercase().as_slice()); } -) +); #[macro_export] macro_rules! make_uint_getter( @@ -51,9 +51,9 @@ macro_rules! make_uint_getter( } ); ($attr:ident) => { - make_uint_getter!($attr, stringify!($attr).to_ascii_lower().as_slice()) + make_uint_getter!($attr, stringify!($attr).to_ascii_lowercase().as_slice()); } -) +); #[macro_export] macro_rules! make_url_getter( @@ -70,9 +70,9 @@ macro_rules! make_url_getter( ); ($attr:ident) => { // FIXME(pcwalton): Do this at compile time, not runtime. - make_url_getter!($attr, stringify!($attr).to_ascii_lower().as_slice()) + make_url_getter!($attr, stringify!($attr).to_ascii_lowercase().as_slice()); } -) +); #[macro_export] macro_rules! make_url_or_base_getter( @@ -94,32 +94,33 @@ macro_rules! make_url_or_base_getter( } ); ($attr:ident) => { - make_url_or_base_getter!($attr, stringify!($attr).to_ascii_lower().as_slice()) + make_url_or_base_getter!($attr, stringify!($attr).to_ascii_lowercase().as_slice()); } -) +); #[macro_export] macro_rules! make_enumerated_getter( - ( $attr:ident, $htmlname:expr, $default:expr, $($choices: pat)|+) => ( + ( $attr:ident, $htmlname:expr, $default:expr, $(($choices: pat))|+) => ( fn $attr(self) -> DOMString { use dom::element::{Element, AttributeHandlers}; use dom::bindings::codegen::InheritTypes::ElementCast; #[allow(unused_imports)] use std::ascii::AsciiExt; + use std::borrow::ToOwned; let element: JSRef<Element> = ElementCast::from_ref(self); let val = element.get_string_attribute(&Atom::from_slice($htmlname)) - .into_ascii_lower(); + .into_ascii_lowercase(); // https://html.spec.whatwg.org/multipage/forms.html#attr-fs-method match val.as_slice() { $($choices)|+ => val, - _ => $default.into_string() + _ => $default.to_owned() } } ); - ($attr:ident, $default:expr, $($choices: pat)|+) => { - make_enumerated_getter!($attr, stringify!($attr).to_ascii_lower().as_slice(), $default, $($choices)|+) + ($attr:ident, $default:expr, $(($choices: pat))|+) => { + make_enumerated_getter!($attr, stringify!($attr).to_ascii_lowercase().as_slice(), $default, $(($choices))|+); } -) +); // concat_idents! doesn't work for function name positions, so // we have to specify both the content name and the HTML name here @@ -134,7 +135,7 @@ macro_rules! make_setter( element.set_string_attribute(&Atom::from_slice($htmlname), value) } ); -) +); #[macro_export] macro_rules! make_bool_setter( @@ -147,7 +148,7 @@ macro_rules! make_bool_setter( element.set_bool_attribute(&Atom::from_slice($htmlname), value) } ); -) +); #[macro_export] macro_rules! make_uint_setter( @@ -160,7 +161,7 @@ macro_rules! make_uint_setter( element.set_uint_attribute(&Atom::from_slice($htmlname), value) } ); -) +); /// For use on non-jsmanaged types /// Use #[jstraceable] on JS managed types @@ -183,7 +184,7 @@ macro_rules! no_jsmanaged_fields( } } ); -) +); /// These are used to generate a event handler which has no special case. macro_rules! define_event_handler( @@ -198,32 +199,32 @@ macro_rules! define_event_handler( eventtarget.set_event_handler_common(stringify!($event_type), listener) } ) -) +); macro_rules! event_handler( ($event_type: ident, $getter: ident, $setter: ident) => ( - define_event_handler!(EventHandlerNonNull, $event_type, $getter, $setter) + define_event_handler!(EventHandlerNonNull, $event_type, $getter, $setter); ) -) +); macro_rules! error_event_handler( ($event_type: ident, $getter: ident, $setter: ident) => ( - define_event_handler!(OnErrorEventHandlerNonNull, $event_type, $getter, $setter) + define_event_handler!(OnErrorEventHandlerNonNull, $event_type, $getter, $setter); ) -) +); // https://html.spec.whatwg.org/multipage/webappapis.html#globaleventhandlers // see webidls/EventHandler.webidl // As more methods get added, just update them here. macro_rules! global_event_handlers( () => ( - event_handler!(load, GetOnload, SetOnload) - global_event_handlers!(NoOnload) + event_handler!(load, GetOnload, SetOnload); + global_event_handlers!(NoOnload); ); (NoOnload) => ( - event_handler!(click, GetOnclick, SetOnclick) - event_handler!(input, GetOninput, SetOninput) - event_handler!(change, GetOnchange, SetOnchange) + event_handler!(click, GetOnclick, SetOnclick); + event_handler!(input, GetOninput, SetOninput); + event_handler!(change, GetOnchange, SetOnchange); ) -) +); diff --git a/components/script/dom/messageevent.rs b/components/script/dom/messageevent.rs index 976c7520378..7cae6302073 100644 --- a/components/script/dom/messageevent.rs +++ b/components/script/dom/messageevent.rs @@ -18,6 +18,8 @@ use servo_util::str::DOMString; use js::jsapi::JSContext; use js::jsval::{JSVal, UndefinedValue}; +use std::borrow::ToOwned; + #[dom_struct] pub struct MessageEvent { event: Event, @@ -44,7 +46,7 @@ impl MessageEvent { } pub fn new_uninitialized(global: GlobalRef) -> Temporary<MessageEvent> { - MessageEvent::new_initialized(global, UndefinedValue(), "".into_string(), "".into_string()) + MessageEvent::new_initialized(global, UndefinedValue(), "".to_owned(), "".to_owned()) } pub fn new_initialized(global: GlobalRef, data: JSVal, origin: DOMString, lastEventId: DOMString) -> Temporary<MessageEvent> { @@ -78,8 +80,8 @@ impl MessageEvent { scope: GlobalRef, message: JSVal) { let messageevent = MessageEvent::new( - scope, "message".into_string(), false, false, message, - "".into_string(), "".into_string()).root(); + scope, "message".to_owned(), false, false, message, + "".to_owned(), "".to_owned()).root(); let event: JSRef<Event> = EventCast::from_ref(messageevent.r()); target.dispatch_event(event); } diff --git a/components/script/dom/mouseevent.rs b/components/script/dom/mouseevent.rs index 76c785ee4eb..11a45bbc208 100644 --- a/components/script/dom/mouseevent.rs +++ b/components/script/dom/mouseevent.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods; use dom::bindings::codegen::InheritTypes::{EventCast, UIEventCast, MouseEventDerived}; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{MutNullableJS, JSRef, RootedReference, Temporary, OptionalSettable}; +use dom::bindings::js::{MutNullableJS, JSRef, RootedReference, Temporary}; use dom::bindings::utils::reflect_dom_object; use dom::event::{Event, EventTypeId}; use dom::eventtarget::EventTarget; diff --git a/components/script/dom/navigatorinfo.rs b/components/script/dom/navigatorinfo.rs index 0dff42d88ea..b8fabd01acf 100644 --- a/components/script/dom/navigatorinfo.rs +++ b/components/script/dom/navigatorinfo.rs @@ -5,8 +5,10 @@ use servo_util::str::DOMString; use servo_util::opts; +use std::borrow::ToOwned; + pub fn Product() -> DOMString { - "Gecko".into_string() + "Gecko".to_owned() } pub fn TaintEnabled() -> bool { @@ -14,20 +16,20 @@ pub fn TaintEnabled() -> bool { } pub fn AppName() -> DOMString { - "Netscape".into_string() // Like Gecko/Webkit + "Netscape".to_owned() // Like Gecko/Webkit } pub fn AppCodeName() -> DOMString { - "Mozilla".into_string() + "Mozilla".to_owned() } pub fn Platform() -> DOMString { - "".into_string() + "".to_owned() } pub fn UserAgent() -> DOMString { match opts::get().user_agent { Some(ref user_agent) => user_agent.clone(), - None => "".into_string(), + None => "".to_owned(), } } diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index fb336efd85b..b780a3923e2 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -24,7 +24,7 @@ use dom::bindings::error::Fallible; use dom::bindings::error::Error::{NotFound, HierarchyRequest, Syntax}; use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, JSRef, RootedReference, Temporary, Root}; -use dom::bindings::js::{OptionalSettable, TemporaryPushable, OptionalRootedRootable}; +use dom::bindings::js::{TemporaryPushable, OptionalRootedRootable}; use dom::bindings::js::{ResultRootable, OptionalRootable, MutNullableJS}; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::{Reflectable, reflect_dom_object}; @@ -48,17 +48,19 @@ use devtools_traits::NodeInfo; use script_traits::UntrustedNodeAddress; use servo_util::geometry::Au; use servo_util::str::{DOMString, null_str_as_empty}; -use style::{matches, StylesheetOrigin, ParserContext, SelectorList}; +use style::{matches, SelectorList}; use js::jsapi::{JSContext, JSObject, JSTracer, JSRuntime}; use js::jsfriendapi; +use core::nonzero::NonZero; use libc; use libc::{uintptr_t, c_void}; +use std::borrow::ToOwned; use std::cell::{Cell, RefCell, Ref, RefMut}; use std::default::Default; use std::iter::{FilterMap, Peekable}; use std::mem; -use style::{mod, ComputedValues}; +use style::{self, ComputedValues}; use std::sync::Arc; use uuid; use string_cache::QualName; @@ -121,7 +123,6 @@ impl NodeDerived for EventTarget { bitflags! { #[doc = "Flags for node items."] #[jstraceable] - #[deriving(Copy)] flags NodeFlags: u16 { #[doc = "Specifies whether this node is in a document."] const IS_IN_DOC = 0x01, @@ -182,7 +183,7 @@ impl Drop for Node { /// suppress observers flag /// http://dom.spec.whatwg.org/#concept-node-insert /// http://dom.spec.whatwg.org/#concept-node-remove -#[deriving(Copy)] +#[derive(Copy)] enum SuppressObserver { Suppressed, Unsuppressed @@ -198,14 +199,14 @@ pub struct SharedLayoutData { pub struct LayoutData { chan: Option<LayoutChan>, _shared_data: SharedLayoutData, - _data: *const (), + _data: NonZero<*const ()>, } pub struct LayoutDataRef { pub data_cell: RefCell<Option<LayoutData>>, } -no_jsmanaged_fields!(LayoutDataRef) +no_jsmanaged_fields!(LayoutDataRef); impl LayoutDataRef { pub fn new() -> LayoutDataRef { @@ -224,8 +225,8 @@ impl LayoutDataRef { pub fn take_chan(&self) -> Option<LayoutChan> { let mut layout_data = self.data_cell.borrow_mut(); match &mut *layout_data { - &None => None, - &Some(ref mut layout_data) => Some(layout_data.chan.take().unwrap()), + &mut None => None, + &mut Some(ref mut layout_data) => Some(layout_data.chan.take().unwrap()), } } @@ -254,8 +255,10 @@ impl LayoutDataRef { } } +unsafe impl Send for LayoutDataRef {} + /// The different types of nodes. -#[deriving(Copy, PartialEq, Show)] +#[derive(Copy, PartialEq, Show)] #[jstraceable] pub enum NodeTypeId { DocumentType, @@ -386,7 +389,9 @@ impl<'a> QuerySelectorIterator<'a> { } } -impl<'a> Iterator<JSRef<'a, Node>> for QuerySelectorIterator<'a> { +impl<'a> Iterator for QuerySelectorIterator<'a> { + type Item = JSRef<'a, Node>; + fn next(&mut self) -> Option<JSRef<'a, Node>> { let selectors = &self.selectors; // TODO(cgaebel): Is it worth it to build a bloom filter here @@ -500,7 +505,7 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> { } s.push_str(self.debug_str().as_slice()); - debug!("{}", s); + debug!("{:?}", s); // FIXME: this should have a pure version? for kid in self.children() { @@ -510,11 +515,11 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> { /// Returns a string that describes this node. fn debug_str(self) -> String { - format!("{}", self.type_id) + format!("{:?}", self.type_id) } fn is_in_doc(self) -> bool { - self.deref().flags.get().contains(IS_IN_DOC) + self.flags.get().contains(IS_IN_DOC) } /// Returns the type ID of this node. Fails if this node is borrowed mutably. @@ -727,7 +732,7 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> { } fn to_trusted_node_address(self) -> TrustedNodeAddress { - TrustedNodeAddress(self.deref() as *const Node as *const libc::c_void) + TrustedNodeAddress(&*self as *const Node as *const libc::c_void) } fn get_bounding_content_box(self) -> Rect<Au> { @@ -741,10 +746,7 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> { // http://dom.spec.whatwg.org/#dom-parentnode-queryselector fn query_selector(self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>> { // Step 1. - let parser_context = ParserContext { - origin: StylesheetOrigin::Author, - }; - match style::parse_selector_list_from_str(&parser_context, selectors.as_slice()) { + match style::parse_author_origin_selector_list_from_str(selectors.as_slice()) { // Step 2. Err(()) => return Err(Syntax), // Step 3. @@ -766,10 +768,7 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> { // Step 1. let nodes; let root = self.ancestors().last().unwrap_or(self.clone()); - let parser_context = ParserContext { - origin: StylesheetOrigin::Author, - }; - match style::parse_selector_list_from_str(&parser_context, selectors.as_slice()) { + match style::parse_author_origin_selector_list_from_str(selectors.as_slice()) { // Step 2. Err(()) => return Err(Syntax), // Step 3. @@ -830,8 +829,12 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> { } fn child_elements(self) -> ChildElementIterator<'a> { + fn cast(n: JSRef<Node>) -> Option<JSRef<Element>> { + ElementCast::to_ref(n) + } + self.children() - .filter_map::<JSRef<Element>>(ElementCast::to_ref) + .filter_map(cast as fn(JSRef<Node>) -> Option<JSRef<Element>>) .peekable() } @@ -854,21 +857,24 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> { NodeInfo { uniqueId: self.unique_id.borrow().clone(), - baseURI: self.GetBaseURI().unwrap_or("".into_string()), - parent: self.GetParentNode().root().map(|node| node.r().get_unique_id()).unwrap_or("".into_string()), + baseURI: self.GetBaseURI().unwrap_or("".to_owned()), + parent: self.GetParentNode().root().map(|node| node.r().get_unique_id()).unwrap_or("".to_owned()), nodeType: self.NodeType() as uint, - namespaceURI: "".into_string(), //FIXME + namespaceURI: "".to_owned(), //FIXME nodeName: self.NodeName(), numChildren: self.ChildNodes().root().r().Length() as uint, //FIXME doctype nodes only - name: "".into_string(), - publicId: "".into_string(), - systemId: "".into_string(), - - attrs: match ElementCast::to_ref(self) { - Some(element) => element.summarize(), - None => vec!(), + name: "".to_owned(), + publicId: "".to_owned(), + systemId: "".to_owned(), + + attrs: { + let e: Option<JSRef<Element>> = ElementCast::to_ref(self); + match e { + Some(element) => element.summarize(), + None => vec!(), + } }, isDocumentElement: @@ -878,7 +884,7 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> { .map(|elem| NodeCast::from_ref(elem.root().r()) == self) .unwrap_or(false), - shortValue: self.GetNodeValue().unwrap_or("".into_string()), //FIXME: truncate + shortValue: self.GetNodeValue().unwrap_or("".to_owned()), //FIXME: truncate incompleteValue: false, //FIXME: reflect truncation } } @@ -891,7 +897,7 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> { pub fn from_untrusted_node_address(runtime: *mut JSRuntime, candidate: UntrustedNodeAddress) -> Temporary<Node> { unsafe { - let candidate: uintptr_t = mem::transmute(candidate); + let candidate: uintptr_t = mem::transmute(candidate.0); let object: *mut JSObject = jsfriendapi::bindgen::JS_GetAddressableObject(runtime, candidate); if object.is_null() { @@ -1012,19 +1018,21 @@ impl RawLayoutNodeHelpers for Node { pub type ChildElementIterator<'a> = Peekable<JSRef<'a, Element>, - FilterMap<'a, - JSRef<'a, Node>, + FilterMap<JSRef<'a, Node>, JSRef<'a, Element>, - NodeChildrenIterator<'a>>>; + NodeChildrenIterator<'a>, + fn(JSRef<Node>) -> Option<JSRef<Element>>>>; pub struct NodeChildrenIterator<'a> { current: Option<JSRef<'a, Node>>, } -impl<'a> Iterator<JSRef<'a, Node>> for NodeChildrenIterator<'a> { +impl<'a> Iterator for NodeChildrenIterator<'a> { + type Item = JSRef<'a, Node>; + fn next(&mut self) -> Option<JSRef<'a, Node>> { let node = self.current; - self.current = node.and_then(|node| node.next_sibling().map(|node| *node.root().deref())); + self.current = node.and_then(|node| node.next_sibling().map(|node| *node.root())); node } } @@ -1033,7 +1041,9 @@ pub struct ReverseChildrenIterator { current: Option<Root<Node>>, } -impl Iterator<Temporary<Node>> for ReverseChildrenIterator { +impl Iterator for ReverseChildrenIterator { + type Item = Temporary<Node>; + fn next(&mut self) -> Option<Temporary<Node>> { let node = self.current.r().map(Temporary::from_rooted); self.current = self.current.take().and_then(|node| node.r().prev_sibling()).root(); @@ -1045,10 +1055,12 @@ pub struct AncestorIterator<'a> { current: Option<JSRef<'a, Node>>, } -impl<'a> Iterator<JSRef<'a, Node>> for AncestorIterator<'a> { +impl<'a> Iterator for AncestorIterator<'a> { + type Item = JSRef<'a, Node>; + fn next(&mut self) -> Option<JSRef<'a, Node>> { let node = self.current; - self.current = node.and_then(|node| node.parent_node().map(|node| *node.root().deref())); + self.current = node.and_then(|node| node.parent_node().map(|node| *node.root())); node } } @@ -1068,7 +1080,9 @@ impl<'a> TreeIterator<'a> { } } -impl<'a> Iterator<JSRef<'a, Node>> for TreeIterator<'a> { +impl<'a> Iterator for TreeIterator<'a> { + type Item = JSRef<'a, Node>; + fn next(&mut self) -> Option<JSRef<'a, Node>> { let ret = self.stack.pop(); ret.map(|node| { @@ -1101,7 +1115,7 @@ impl NodeIterator { } fn next_child<'b>(&self, node: JSRef<'b, Node>) -> Option<JSRef<'b, Node>> { - let skip = |element: JSRef<Element>| { + let skip = |&:element: JSRef<Element>| { !self.include_descendants_of_void && element.is_void() }; @@ -1112,7 +1126,9 @@ impl NodeIterator { } } -impl<'a> Iterator<JSRef<'a, Node>> for NodeIterator { +impl<'a> Iterator for NodeIterator { + type Item = JSRef<'a, Node>; + fn next(&mut self) -> Option<JSRef<'a, Node>> { self.current_node = match self.current_node.as_ref().map(|node| node.root()) { None => { @@ -1160,7 +1176,7 @@ impl<'a> Iterator<JSRef<'a, Node>> for NodeIterator { } /// Specifies whether children must be recursively cloned or not. -#[deriving(Copy, PartialEq)] +#[derive(Copy, PartialEq)] pub enum CloneChildrenFlag { CloneChildren, DoNotCloneChildren @@ -1567,7 +1583,7 @@ impl Node { local: element.local_name().clone() }; let element = Element::create(name, - element.prefix().as_ref().map(|p| p.as_slice().into_string()), + element.prefix().as_ref().map(|p| p.as_slice().to_owned()), document.r(), ElementCreator::ScriptCreated); NodeCast::from_temporary(element) }, @@ -1640,13 +1656,13 @@ impl Node { None => {} Some(chan) => { let LayoutChan(chan) = chan; - chan.send(Msg::ReapLayoutData(layout_data)) + chan.send(Msg::ReapLayoutData(layout_data)).unwrap() }, } } } - pub fn collect_text_contents<'a, T: Iterator<JSRef<'a, Node>>>(mut iterator: T) -> String { + pub fn collect_text_contents<'a, T: Iterator<Item=JSRef<'a, Node>>>(mut iterator: T) -> String { let mut content = String::new(); for node in iterator { let text: Option<JSRef<Text>> = TextCast::to_ref(node); @@ -1680,19 +1696,19 @@ impl<'a> NodeMethods for JSRef<'a, Node> { let elem: JSRef<Element> = ElementCast::to_ref(self).unwrap(); elem.TagName() } - NodeTypeId::Text => "#text".into_string(), + NodeTypeId::Text => "#text".to_owned(), NodeTypeId::ProcessingInstruction => { let processing_instruction: JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(self).unwrap(); processing_instruction.Target() } - NodeTypeId::Comment => "#comment".into_string(), + NodeTypeId::Comment => "#comment".to_owned(), NodeTypeId::DocumentType => { let doctype: JSRef<DocumentType> = DocumentTypeCast::to_ref(self).unwrap(); doctype.name().clone() }, - NodeTypeId::DocumentFragment => "#document-fragment".into_string(), - NodeTypeId::Document => "#document".into_string() + NodeTypeId::DocumentFragment => "#document-fragment".to_owned(), + NodeTypeId::Document => "#document".to_owned() } } @@ -1994,7 +2010,8 @@ impl<'a> NodeMethods for JSRef<'a, Node> { fn Normalize(self) { let mut prev_text = None; for child in self.children() { - match TextCast::to_ref(child) { + let t: Option<JSRef<Text>> = TextCast::to_ref(child); + match t { Some(text) => { let characterdata: JSRef<CharacterData> = CharacterDataCast::from_ref(text); if characterdata.Length() == 0 { @@ -2189,10 +2206,12 @@ impl<'a> NodeMethods for JSRef<'a, Node> { /// The address of a node known to be valid. These are sent from script to layout, /// and are also used in the HTML parser interface. -#[allow(raw_pointer_deriving)] -#[deriving(Clone, PartialEq, Eq, Copy)] +#[allow(raw_pointer_derive)] +#[derive(Clone, PartialEq, Eq, Copy)] pub struct TrustedNodeAddress(pub *const c_void); +unsafe impl Send for TrustedNodeAddress {} + pub fn document_from_node<T: NodeBase+Reflectable>(derived: JSRef<T>) -> Temporary<Document> { let node: JSRef<Node> = NodeCast::from_ref(derived); node.owner_doc() @@ -2204,7 +2223,7 @@ pub fn window_from_node<T: NodeBase+Reflectable>(derived: JSRef<T>) -> Temporary } impl<'a> VirtualMethods for JSRef<'a, Node> { - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { let eventtarget: &JSRef<EventTarget> = EventTargetCast::from_borrowed_ref(self); Some(eventtarget as &VirtualMethods) } @@ -2285,7 +2304,9 @@ impl<'a> style::TNode<'a, JSRef<'a, Element>> for JSRef<'a, Node> { ElementCast::to_ref(self).unwrap() } - fn match_attr(self, attr: &style::AttrSelector, test: |&str| -> bool) -> bool { + fn match_attr<F>(self, attr: &style::AttrSelector, test: F) -> bool + where F: Fn(&str) -> bool + { let name = { if self.is_html_element_in_html_document() { &attr.lower_name @@ -2372,7 +2393,7 @@ impl<'a> DisabledStateHelpers for JSRef<'a, Node> { } /// A summary of the changes that happened to a node. -#[deriving(Copy, Clone, PartialEq)] +#[derive(Copy, Clone, PartialEq)] pub enum NodeDamage { /// The node's `style` attribute changed. NodeStyleDamaged, diff --git a/components/script/dom/storage.rs b/components/script/dom/storage.rs index cbbabb912a7..01fce8d2d82 100644 --- a/components/script/dom/storage.rs +++ b/components/script/dom/storage.rs @@ -11,7 +11,7 @@ use dom::bindings::error::Fallible; use servo_util::str::DOMString; use servo_net::storage_task::StorageTask; use servo_net::storage_task::StorageTaskMsg; -use std::comm::channel; +use std::sync::mpsc::channel; use url::Url; #[dom_struct] @@ -55,21 +55,21 @@ impl<'a> StorageMethods for JSRef<'a, Storage> { let (sender, receiver) = channel(); self.get_storage_task().send(StorageTaskMsg::Length(sender, self.get_url())); - receiver.recv() + receiver.recv().unwrap() } fn Key(self, index: u32) -> Option<DOMString> { let (sender, receiver) = channel(); self.get_storage_task().send(StorageTaskMsg::Key(sender, self.get_url(), index)); - receiver.recv() + receiver.recv().unwrap() } fn GetItem(self, name: DOMString) -> Option<DOMString> { let (sender, receiver) = channel(); self.get_storage_task().send(StorageTaskMsg::GetItem(sender, self.get_url(), name)); - receiver.recv() + receiver.recv().unwrap() } fn NamedGetter(self, name: DOMString, found: &mut bool) -> Option<DOMString> { @@ -82,7 +82,7 @@ impl<'a> StorageMethods for JSRef<'a, Storage> { let (sender, receiver) = channel(); self.get_storage_task().send(StorageTaskMsg::SetItem(sender, self.get_url(), name, value)); - if receiver.recv() { + if receiver.recv().unwrap() { //TODO send notification } } @@ -99,7 +99,7 @@ impl<'a> StorageMethods for JSRef<'a, Storage> { let (sender, receiver) = channel(); self.get_storage_task().send(StorageTaskMsg::RemoveItem(sender, self.get_url(), name)); - if receiver.recv() { + if receiver.recv().unwrap() { //TODO send notification } } @@ -112,7 +112,7 @@ impl<'a> StorageMethods for JSRef<'a, Storage> { let (sender, receiver) = channel(); self.get_storage_task().send(StorageTaskMsg::Clear(sender, self.get_url())); - if receiver.recv() { + if receiver.recv().unwrap() { //TODO send notification } } diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs index fc222a4f604..2d0b58ec923 100644 --- a/components/script/dom/testbinding.rs +++ b/components/script/dom/testbinding.rs @@ -22,6 +22,8 @@ use servo_util::str::DOMString; use js::jsapi::{JSContext, JSObject}; use js::jsval::{JSVal, NullValue}; +use std::borrow::ToOwned; + #[dom_struct] pub struct TestBinding { reflector: Reflector, @@ -51,7 +53,7 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn SetFloatAttribute(self, _: f32) {} fn DoubleAttribute(self) -> f64 { 0. } fn SetDoubleAttribute(self, _: f64) {} - fn StringAttribute(self) -> DOMString { "".into_string() } + fn StringAttribute(self) -> DOMString { "".to_owned() } fn SetStringAttribute(self, _: DOMString) {} fn ByteStringAttribute(self) -> ByteString { ByteString::new(vec!()) } fn SetByteStringAttribute(self, _: ByteString) {} @@ -64,7 +66,7 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn SetInterfaceAttribute(self, _: JSRef<Blob>) {} fn UnionAttribute(self) -> HTMLElementOrLong { eLong(0) } fn SetUnionAttribute(self, _: HTMLElementOrLong) {} - fn Union2Attribute(self) -> EventOrString { eString("".into_string()) } + fn Union2Attribute(self) -> EventOrString { eString("".to_owned()) } fn SetUnion2Attribute(self, _: EventOrString) {} fn ArrayAttribute(self, _: *mut JSContext) -> *mut JSObject { NullValue().to_object_or_null() } fn AnyAttribute(self, _: *mut JSContext) -> JSVal { NullValue() } @@ -94,7 +96,7 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn SetDoubleAttributeNullable(self, _: Option<f64>) {} fn GetByteStringAttributeNullable(self) -> Option<ByteString> { Some(ByteString::new(vec!())) } fn SetByteStringAttributeNullable(self, _: Option<ByteString>) {} - fn GetStringAttributeNullable(self) -> Option<DOMString> { Some("".into_string()) } + fn GetStringAttributeNullable(self) -> Option<DOMString> { Some("".to_owned()) } fn SetStringAttributeNullable(self, _: Option<DOMString>) {} fn GetEnumAttributeNullable(self) -> Option<TestEnum> { Some(_empty) } fn GetInterfaceAttributeNullable(self) -> Option<Temporary<Blob>> { @@ -104,7 +106,7 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn SetInterfaceAttributeNullable(self, _: Option<JSRef<Blob>>) {} fn GetUnionAttributeNullable(self) -> Option<HTMLElementOrLong> { Some(eLong(0)) } fn SetUnionAttributeNullable(self, _: Option<HTMLElementOrLong>) {} - fn GetUnion2AttributeNullable(self) -> Option<EventOrString> { Some(eString("".into_string())) } + fn GetUnion2AttributeNullable(self) -> Option<EventOrString> { Some(eString("".to_owned())) } fn SetUnion2AttributeNullable(self, _: Option<EventOrString>) {} fn ReceiveVoid(self) -> () {} fn ReceiveBoolean(self) -> bool { false } @@ -118,7 +120,7 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn ReceiveUnsignedLongLong(self) -> u64 { 0 } fn ReceiveFloat(self) -> f32 { 0. } fn ReceiveDouble(self) -> f64 { 0. } - fn ReceiveString(self) -> DOMString { "".into_string() } + fn ReceiveString(self) -> DOMString { "".to_owned() } fn ReceiveByteString(self) -> ByteString { ByteString::new(vec!()) } fn ReceiveEnum(self) -> TestEnum { _empty } fn ReceiveInterface(self) -> Temporary<Blob> { @@ -127,7 +129,7 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { } fn ReceiveAny(self, _: *mut JSContext) -> JSVal { NullValue() } fn ReceiveUnion(self) -> HTMLElementOrLong { eLong(0) } - fn ReceiveUnion2(self) -> EventOrString { eString("".into_string()) } + fn ReceiveUnion2(self) -> EventOrString { eString("".to_owned()) } fn ReceiveNullableBoolean(self) -> Option<bool> { Some(false) } fn ReceiveNullableByte(self) -> Option<i8> { Some(0) } @@ -140,7 +142,7 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn ReceiveNullableUnsignedLongLong(self) -> Option<u64> { Some(0) } fn ReceiveNullableFloat(self) -> Option<f32> { Some(0.) } fn ReceiveNullableDouble(self) -> Option<f64> { Some(0.) } - fn ReceiveNullableString(self) -> Option<DOMString> { Some("".into_string()) } + fn ReceiveNullableString(self) -> Option<DOMString> { Some("".to_owned()) } fn ReceiveNullableByteString(self) -> Option<ByteString> { Some(ByteString::new(vec!())) } fn ReceiveNullableEnum(self) -> Option<TestEnum> { Some(_empty) } fn ReceiveNullableInterface(self) -> Option<Temporary<Blob>> { @@ -148,7 +150,7 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { Some(Blob::new(global.r(), None, "")) } fn ReceiveNullableUnion(self) -> Option<HTMLElementOrLong> { Some(eLong(0)) } - fn ReceiveNullableUnion2(self) -> Option<EventOrString> { Some(eString("".into_string())) } + fn ReceiveNullableUnion2(self) -> Option<EventOrString> { Some(eString("".to_owned())) } fn PassBoolean(self, _: bool) {} fn PassByte(self, _: i8) {} diff --git a/components/script/dom/treewalker.rs b/components/script/dom/treewalker.rs index b578823acd6..d7dab56949d 100644 --- a/components/script/dom/treewalker.rs +++ b/components/script/dom/treewalker.rs @@ -119,30 +119,37 @@ impl<'a> TreeWalkerMethods for JSRef<'a, TreeWalker> { } } -type NodeAdvancer<'a> = |node: JSRef<'a, Node>|: 'a -> Option<Temporary<Node>>; - -trait PrivateTreeWalkerHelpers<'a> { - fn traverse_children(self, - next_child: NodeAdvancer<'a>, - next_sibling: NodeAdvancer<'a>) - -> Fallible<Option<Temporary<Node>>>; - fn traverse_siblings(self, - next_child: NodeAdvancer<'a>, - next_sibling: NodeAdvancer<'a>) - -> Fallible<Option<Temporary<Node>>>; - fn is_root_node(self, node: JSRef<'a, Node>) -> bool; - fn is_current_node(self, node: JSRef<'a, Node>) -> bool; - fn first_following_node_not_following_root(self, node: JSRef<'a, Node>) +type NodeAdvancer<'a> = Fn(JSRef<'a, Node>) -> Option<Temporary<Node>> + 'a; + +trait PrivateTreeWalkerHelpers { + fn traverse_children<F, G>(self, + next_child: F, + next_sibling: G) + -> Fallible<Option<Temporary<Node>>> + where F: Fn(JSRef<Node>) -> Option<Temporary<Node>>, + G: Fn(JSRef<Node>) -> Option<Temporary<Node>>; + fn traverse_siblings<F, G>(self, + next_child: F, + next_sibling: G) + -> Fallible<Option<Temporary<Node>>> + where F: Fn(JSRef<Node>) -> Option<Temporary<Node>>, + G: Fn(JSRef<Node>) -> Option<Temporary<Node>>; + fn is_root_node(self, node: JSRef<Node>) -> bool; + fn is_current_node(self, node: JSRef<Node>) -> bool; + fn first_following_node_not_following_root(self, node: JSRef<Node>) -> Option<Temporary<Node>>; - fn accept_node(self, node: JSRef<'a, Node>) -> Fallible<u16>; + fn accept_node(self, node: JSRef<Node>) -> Fallible<u16>; } -impl<'a> PrivateTreeWalkerHelpers<'a> for JSRef<'a, TreeWalker> { +impl<'a> PrivateTreeWalkerHelpers for JSRef<'a, TreeWalker> { // http://dom.spec.whatwg.org/#concept-traverse-children - fn traverse_children(self, - next_child: NodeAdvancer<'a>, - next_sibling: NodeAdvancer<'a>) - -> Fallible<Option<Temporary<Node>>> { + fn traverse_children<F, G>(self, + next_child: F, + next_sibling: G) + -> Fallible<Option<Temporary<Node>>> + where F: Fn(JSRef<Node>) -> Option<Temporary<Node>>, + G: Fn(JSRef<Node>) -> Option<Temporary<Node>> + { // "To **traverse children** of type *type*, run these steps:" // "1. Let node be the value of the currentNode attribute." // "2. Set node to node's first child if type is first, and node's last child if type is last." @@ -218,10 +225,13 @@ impl<'a> PrivateTreeWalkerHelpers<'a> for JSRef<'a, TreeWalker> { } // http://dom.spec.whatwg.org/#concept-traverse-siblings - fn traverse_siblings(self, - next_child: NodeAdvancer<'a>, - next_sibling: NodeAdvancer<'a>) - -> Fallible<Option<Temporary<Node>>> { + fn traverse_siblings<F, G>(self, + next_child: F, + next_sibling: G) + -> Fallible<Option<Temporary<Node>>> + where F: Fn(JSRef<Node>) -> Option<Temporary<Node>>, + G: Fn(JSRef<Node>) -> Option<Temporary<Node>> + { // "To **traverse siblings** of type *type* run these steps:" // "1. Let node be the value of the currentNode attribute." let mut node = self.current_node.get().root().clone(); @@ -282,7 +292,7 @@ impl<'a> PrivateTreeWalkerHelpers<'a> for JSRef<'a, TreeWalker> { } // http://dom.spec.whatwg.org/#concept-tree-following - fn first_following_node_not_following_root(self, node: JSRef<'a, Node>) + fn first_following_node_not_following_root(self, node: JSRef<Node>) -> Option<Temporary<Node>> { // "An object A is following an object B if A and B are in the same tree // and A comes after B in tree order." @@ -309,7 +319,7 @@ impl<'a> PrivateTreeWalkerHelpers<'a> for JSRef<'a, TreeWalker> { } // http://dom.spec.whatwg.org/#concept-node-filter - fn accept_node(self, node: JSRef<'a, Node>) -> Fallible<u16> { + fn accept_node(self, node: JSRef<Node>) -> Fallible<u16> { // "To filter node run these steps:" // "1. Let n be node's nodeType attribute value minus 1." let n: uint = node.NodeType() as uint - 1; @@ -329,11 +339,11 @@ impl<'a> PrivateTreeWalkerHelpers<'a> for JSRef<'a, TreeWalker> { } } - fn is_root_node(self, node: JSRef<'a, Node>) -> bool { + fn is_root_node(self, node: JSRef<Node>) -> bool { JS::from_rooted(node) == self.root_node } - fn is_current_node(self, node: JSRef<'a, Node>) -> bool { + fn is_current_node(self, node: JSRef<Node>) -> bool { JS::from_rooted(node) == self.current_node.get() } } @@ -526,7 +536,9 @@ impl<'a> TreeWalkerHelpers<'a> for JSRef<'a, TreeWalker> { } } -impl<'a> Iterator<JSRef<'a, Node>> for JSRef<'a, TreeWalker> { +impl<'a> Iterator for JSRef<'a, TreeWalker> { + type Item = JSRef<'a, Node>; + fn next(&mut self) -> Option<JSRef<'a, Node>> { match self.next_node() { Ok(node) => node.map(|n| n.root().clone()), diff --git a/components/script/dom/uievent.rs b/components/script/dom/uievent.rs index dc6dbb8c756..33c539dd150 100644 --- a/components/script/dom/uievent.rs +++ b/components/script/dom/uievent.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods; use dom::bindings::codegen::InheritTypes::{EventCast, UIEventDerived}; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{MutNullableJS, JSRef, RootedReference, Temporary, OptionalSettable}; +use dom::bindings::js::{MutNullableJS, JSRef, RootedReference, Temporary}; use dom::bindings::utils::reflect_dom_object; use dom::event::{Event, EventTypeId}; diff --git a/components/script/dom/urlhelper.rs b/components/script/dom/urlhelper.rs index 8f3a005127d..290fede857c 100644 --- a/components/script/dom/urlhelper.rs +++ b/components/script/dom/urlhelper.rs @@ -5,6 +5,8 @@ use servo_util::str::DOMString; use url::Url; +use std::borrow::ToOwned; + pub struct UrlHelper; impl UrlHelper { @@ -14,16 +16,16 @@ impl UrlHelper { pub fn Search(url: &Url) -> DOMString { match url.query { - None => "".into_string(), - Some(ref query) if query.as_slice() == "" => "".into_string(), + None => "".to_owned(), + Some(ref query) if query.as_slice() == "" => "".to_owned(), Some(ref query) => format!("?{}", query) } } pub fn Hash(url: &Url) -> DOMString { match url.fragment { - None => "".into_string(), - Some(ref hash) if hash.as_slice() == "" => "".into_string(), + None => "".to_owned(), + Some(ref hash) if hash.as_slice() == "" => "".to_owned(), Some(ref hash) => format!("#{}", hash) } } diff --git a/components/script/dom/urlsearchparams.rs b/components/script/dom/urlsearchparams.rs index 035e558d878..b8ab6c9329c 100644 --- a/components/script/dom/urlsearchparams.rs +++ b/components/script/dom/urlsearchparams.rs @@ -18,7 +18,7 @@ use encoding::all::UTF_8; use encoding::types::{EncodingRef, EncoderTrap}; use std::collections::HashMap; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::fmt::radix; use std::ascii::OwnedAsciiExt; @@ -67,7 +67,7 @@ impl<'a> URLSearchParamsMethods for JSRef<'a, URLSearchParams> { match data.entry(name) { Occupied(entry) => entry.into_mut().push(value), Vacant(entry) => { - entry.set(vec!(value)); + entry.insert(vec!(value)); } } @@ -117,7 +117,7 @@ impl URLSearchParamsHelpers for URLSearchParams { a => { // http://url.spec.whatwg.org/#percent-encode let mut encoded = vec!(0x25); // % - let s = format!("{}", radix(a, 16)).into_ascii_upper(); + let s = format!("{}", radix(a, 16)).into_ascii_uppercase(); let bytes = s.as_bytes(); encoded.push_all(bytes); encoded diff --git a/components/script/dom/virtualmethods.rs b/components/script/dom/virtualmethods.rs index adbeb15c2ba..1bd86677bd6 100644 --- a/components/script/dom/virtualmethods.rs +++ b/components/script/dom/virtualmethods.rs @@ -66,7 +66,7 @@ use string_cache::Atom; pub trait VirtualMethods { /// Returns self as the superclass of the implementation for this trait, /// if any. - fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods>; + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods>; /// Called when changing or adding attributes, after the attribute's value /// has been updated. diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 91402fe6c1f..fe7ea336122 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -47,6 +47,7 @@ use libc; use serialize::base64::{FromBase64, ToBase64, STANDARD}; use std::cell::{Ref, RefMut}; use std::default::Default; +use std::ffi::CString; use std::rc::Rc; use time; @@ -283,9 +284,9 @@ impl<'a> WindowMethods for JSRef<'a, Window> { }) } - global_event_handlers!() - event_handler!(unload, GetOnunload, SetOnunload) - error_event_handler!(error, GetOnerror, SetOnerror) + global_event_handlers!(); + event_handler!(unload, GetOnunload, SetOnunload); + error_event_handler!(error, GetOnerror, SetOnerror); fn Screen(self) -> Temporary<Screen> { self.screen.or_init(|| Screen::new(self)) @@ -336,7 +337,7 @@ impl<'a, T: Reflectable> ScriptHelpers for JSRef<'a, T> { let global = global_object_for_js_object(this).root().r().reflector().get_jsobject(); let code: Vec<u16> = code.as_slice().utf16_units().collect(); let mut rval = UndefinedValue(); - let filename = filename.to_c_str(); + let filename = CString::from_slice(filename.as_bytes()); with_compartment(cx, global, || { unsafe { diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs index 8fa36436c19..df793ede178 100644 --- a/components/script/dom/worker.rs +++ b/components/script/dom/worker.rs @@ -26,6 +26,7 @@ use js::jsval::JSVal; use url::UrlParser; use std::cell::Cell; +use std::sync::mpsc::{channel, Sender}; pub type TrustedWorkerAddress = Trusted<Worker>; @@ -97,7 +98,7 @@ impl<'a> WorkerMethods for JSRef<'a, Worker> { Ok(()) } - event_handler!(message, GetOnmessage, SetOnmessage) + event_handler!(message, GetOnmessage, SetOnmessage); } pub struct WorkerMessageHandler { diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index da3b50b1f32..e78a4a71ed0 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -30,7 +30,7 @@ use std::default::Default; use std::rc::Rc; use url::{Url, UrlParser}; -#[deriving(Copy, PartialEq)] +#[derive(Copy, PartialEq)] #[jstraceable] pub enum WorkerGlobalScopeTypeId { DedicatedGlobalScope, diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index a5d5c767a72..62a42ec3cf6 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -34,8 +34,9 @@ use encoding::types::{DecoderTrap, Encoding, EncodingRef, EncoderTrap}; use hyper::header::Headers; use hyper::header::common::{Accept, ContentLength, ContentType}; +use hyper::header::quality_item::QualityItem; use hyper::http::RawStatus; -use hyper::mime::{mod, Mime}; +use hyper::mime::{self, Mime}; use hyper::method::Method; use js::jsapi::{JS_ParseJSON, JSContext}; @@ -50,8 +51,9 @@ use servo_util::str::DOMString; use servo_util::task::spawn_named; use std::ascii::AsciiExt; +use std::borrow::ToOwned; use std::cell::Cell; -use std::comm::{Sender, Receiver, channel}; +use std::sync::mpsc::{Sender, Receiver, channel}; use std::default::Default; use std::io::Timer; use std::str::FromStr; @@ -63,7 +65,7 @@ use dom::bindings::codegen::UnionTypes::StringOrURLSearchParams; use dom::bindings::codegen::UnionTypes::StringOrURLSearchParams::{eString, eURLSearchParams}; pub type SendParam = StringOrURLSearchParams; -#[deriving(PartialEq, Copy)] +#[derive(PartialEq, Copy)] #[jstraceable] enum XMLHttpRequestState { Unsent = 0, @@ -91,11 +93,11 @@ impl Runnable for XHRProgressHandler { } } -#[deriving(PartialEq, Clone, Copy)] +#[derive(PartialEq, Clone, Copy)] #[jstraceable] pub struct GenerationId(uint); -#[deriving(Clone)] +#[derive(Clone)] pub enum XHRProgress { /// Notify that headers have been received HeadersReceived(GenerationId, Option<Headers>, Option<RawStatus>), @@ -168,7 +170,7 @@ impl XMLHttpRequest { timeout: Cell::new(0u32), with_credentials: Cell::new(false), upload: JS::from_rooted(XMLHttpRequestUpload::new(global)), - response_url: "".into_string(), + response_url: "".to_owned(), status: Cell::new(0), status_text: DOMRefCell::new(ByteString::new(vec!())), response: DOMRefCell::new(ByteString::new(vec!())), @@ -229,7 +231,7 @@ impl XMLHttpRequest { notify_partial_progress(fetch_type, XHRProgress::Errored(gen_id, $err)); return Err($err) }); - ) + ); macro_rules! terminate( ($reason:expr) => ( @@ -242,7 +244,7 @@ impl XMLHttpRequest { } } ); - ) + ); match cors_request { @@ -256,13 +258,14 @@ impl XMLHttpRequest { let req2 = req.clone(); // TODO: this exists only to make preflight check non-blocking // perhaps should be handled by the resource_loader? - spawn_named("XHR:Cors", proc() { + spawn_named("XHR:Cors".to_owned(), move || { let response = req2.http_fetch(); chan.send(response); }); select! ( response = cors_port.recv() => { + let response = response.unwrap(); if response.network_error { notify_error_and_return!(Network); } else { @@ -272,8 +275,8 @@ impl XMLHttpRequest { }); } }, - reason = terminate_receiver.recv() => terminate!(reason) - ) + reason = terminate_receiver.recv() => terminate!(reason.unwrap()) + ); } _ => {} } @@ -285,6 +288,7 @@ impl XMLHttpRequest { let progress_port; select! ( response = start_port.recv() => { + let response = response.unwrap(); match cors_request { Ok(Some(ref req)) => { match response.metadata.headers { @@ -301,8 +305,8 @@ impl XMLHttpRequest { progress_port = response.progress_port; }, - reason = terminate_receiver.recv() => terminate!(reason) - ) + reason = terminate_receiver.recv() => terminate!(reason.unwrap()) + ); let mut buf = vec!(); loop { @@ -318,7 +322,7 @@ impl XMLHttpRequest { }; select! ( - progress = progress_port.recv() => match progress { + progress = progress_port.recv() => match progress.unwrap() { Payload(data) => { buf.push_all(data.as_slice()); notify_partial_progress(fetch_type, @@ -332,14 +336,14 @@ impl XMLHttpRequest { notify_error_and_return!(Network); } }, - reason = terminate_receiver.recv() => terminate!(reason) - ) + reason = terminate_receiver.recv() => terminate!(reason.unwrap()) + ); } } } impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> { - event_handler!(readystatechange, GetOnreadystatechange, SetOnreadystatechange) + event_handler!(readystatechange, GetOnreadystatechange, SetOnreadystatechange); fn ReadyState(self) -> u16 { self.ready_state.get() as u16 @@ -353,12 +357,12 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> { // without changing capitalization, this will actually sidestep rust-http's type system // since methods like "patch" or "PaTcH" will be considered extension methods // despite the there being a rust-http method variant for them - let upper = s.to_ascii_upper(); + let upper = s.to_ascii_uppercase(); match upper.as_slice() { "DELETE" | "GET" | "HEAD" | "OPTIONS" | "POST" | "PUT" | "CONNECT" | "TRACE" | - "TRACK" => from_str(upper.as_slice()), - _ => from_str(s) + "TRACK" => upper.parse(), + _ => s.parse() } }); // Step 2 @@ -437,24 +441,24 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> { None => return Err(Syntax) }; - debug!("SetRequestHeader: name={}, value={}", name.as_str(), value.as_str()); + debug!("SetRequestHeader: name={:?}, value={:?}", name.as_str(), value.as_str()); let mut headers = self.request_headers.borrow_mut(); // Steps 6,7 match headers.get_raw(name_str) { Some(raw) => { - debug!("SetRequestHeader: old value = {}", raw[0]); + debug!("SetRequestHeader: old value = {:?}", raw[0]); let mut buf = raw[0].clone(); buf.push_all(b", "); buf.push_all(value.as_slice()); - debug!("SetRequestHeader: new value = {}", buf); + debug!("SetRequestHeader: new value = {:?}", buf); value = ByteString::new(buf); }, None => {} } - headers.set_raw(name_str.into_string(), vec![value.as_slice().to_vec()]); + headers.set_raw(name_str.to_owned(), vec![value.as_slice().to_vec()]); Ok(()) } fn Timeout(self) -> u32 { @@ -525,12 +529,12 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> { // If one of the event handlers below aborts the fetch by calling // abort or open we will need the current generation id to detect it. let gen_id = self.generation_id.get(); - self.dispatch_response_progress_event("loadstart".into_string()); + self.dispatch_response_progress_event("loadstart".to_owned()); if self.generation_id.get() != gen_id { return Ok(()); } if !self.upload_complete.get() { - self.dispatch_upload_progress_event("loadstart".into_string(), Some(0)); + self.dispatch_upload_progress_event("loadstart".to_owned(), Some(0)); if self.generation_id.get() != gen_id { return Ok(()); } @@ -562,18 +566,19 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> { let n = "content-type"; match data { Some(eString(_)) => - request_headers.set_raw(n.into_string(), vec![join_raw("text/plain", params)]), + request_headers.set_raw(n.to_owned(), vec![join_raw("text/plain", params)]), Some(eURLSearchParams(_)) => request_headers.set_raw( - n.into_string(), vec![join_raw("application/x-www-form-urlencoded", params)]), + n.to_owned(), vec![join_raw("application/x-www-form-urlencoded", params)]), None => () } } if !request_headers.has::<Accept>() { + let mime = Mime(mime::TopLevel::Star, mime::SubLevel::Star, vec![]); request_headers.set( - Accept(vec![Mime(mime::TopLevel::Star, mime::SubLevel::Star, vec![])])); + Accept(vec![QualityItem::new(mime, 1.0)])); } } // drops the borrow_mut @@ -602,14 +607,14 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> { buf.push_str(format!("{}", p).as_slice()); }); referer_url.serialize_path().map(|ref h| buf.push_str(h.as_slice())); - self.request_headers.borrow_mut().set_raw("Referer".into_string(), vec![buf.into_bytes()]); + self.request_headers.borrow_mut().set_raw("Referer".to_owned(), vec![buf.into_bytes()]); }, - Ok(Some(ref req)) => self.insert_trusted_header("origin".into_string(), + Ok(Some(ref req)) => self.insert_trusted_header("origin".to_owned(), format!("{}", req.origin)), _ => {} } - debug!("request_headers = {}", *self.request_headers.borrow()); + debug!("request_headers = {:?}", *self.request_headers.borrow()); let gen_id = self.generation_id.get(); if self.sync.get() { @@ -623,7 +628,7 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> { // inflight events queued up in the script task's port. let addr = Trusted::new(self.global.root().r().get_cx(), self, script_chan.clone()); - spawn_named("XHRTask", proc() { + spawn_named("XHRTask".to_owned(), move || { let _ = XMLHttpRequest::fetch(&mut SyncOrAsync::Async(addr, script_chan), resource_task, load_data, @@ -705,7 +710,7 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> { }, _ if self.ready_state.get() != XMLHttpRequestState::XHRDone => NullValue(), Json => { - let decoded = UTF_8.decode(self.response.borrow().as_slice(), DecoderTrap::Replace).unwrap().into_string(); + let decoded = UTF_8.decode(self.response.borrow().as_slice(), DecoderTrap::Replace).unwrap().to_owned(); let decoded: Vec<u16> = decoded.as_slice().utf16_units().collect(); let mut vp = UndefinedValue(); unsafe { @@ -727,7 +732,7 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> { _empty | Text => { match self.ready_state.get() { XMLHttpRequestState::Loading | XMLHttpRequestState::XHRDone => Ok(self.text_response()), - _ => Ok("".into_string()) + _ => Ok("".to_owned()) } }, _ => Err(InvalidState) @@ -766,11 +771,11 @@ trait PrivateXMLHttpRequestHelpers { impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> { fn change_ready_state(self, rs: XMLHttpRequestState) { - assert!(self.ready_state.get() != rs) + assert!(self.ready_state.get() != rs); self.ready_state.set(rs); let global = self.global.root(); let event = Event::new(global.r(), - "readystatechange".into_string(), + "readystatechange".to_owned(), EventBubbles::DoesNotBubble, EventCancelable::Cancelable).root(); let target: JSRef<EventTarget> = EventTargetCast::from_ref(self); @@ -788,7 +793,7 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> { return } ); - ) + ); // Ignore message if it belongs to a terminated fetch return_if_fetch_was_terminated!(); @@ -804,11 +809,11 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> { self.upload_complete.set(true); // Substeps 2-4 if !self.sync.get() { - self.dispatch_upload_progress_event("progress".into_string(), None); + self.dispatch_upload_progress_event("progress".to_owned(), None); return_if_fetch_was_terminated!(); - self.dispatch_upload_progress_event("load".into_string(), None); + self.dispatch_upload_progress_event("load".to_owned(), None); return_if_fetch_was_terminated!(); - self.dispatch_upload_progress_event("loadend".into_string(), None); + self.dispatch_upload_progress_event("loadend".to_owned(), None); return_if_fetch_was_terminated!(); } // Part of step 13, send() (processing response) @@ -836,7 +841,7 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> { self.change_ready_state(XMLHttpRequestState::Loading); return_if_fetch_was_terminated!(); } - self.dispatch_response_progress_event("progress".into_string()); + self.dispatch_response_progress_event("progress".to_owned()); } }, XHRProgress::Done(_) => { @@ -852,11 +857,11 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> { self.change_ready_state(XMLHttpRequestState::XHRDone); return_if_fetch_was_terminated!(); // Subsubsteps 10-12 - self.dispatch_response_progress_event("progress".into_string()); + self.dispatch_response_progress_event("progress".to_owned()); return_if_fetch_was_terminated!(); - self.dispatch_response_progress_event("load".into_string()); + self.dispatch_response_progress_event("load".to_owned()); return_if_fetch_was_terminated!(); - self.dispatch_response_progress_event("loadend".into_string()); + self.dispatch_response_progress_event("loadend".to_owned()); }, XHRProgress::Errored(_, e) => { self.send_flag.set(false); @@ -873,18 +878,18 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> { let upload_complete: &Cell<bool> = &self.upload_complete; if !upload_complete.get() { upload_complete.set(true); - self.dispatch_upload_progress_event("progress".into_string(), None); + self.dispatch_upload_progress_event("progress".to_owned(), None); return_if_fetch_was_terminated!(); - self.dispatch_upload_progress_event(errormsg.into_string(), None); + self.dispatch_upload_progress_event(errormsg.to_owned(), None); return_if_fetch_was_terminated!(); - self.dispatch_upload_progress_event("loadend".into_string(), None); + self.dispatch_upload_progress_event("loadend".to_owned(), None); return_if_fetch_was_terminated!(); } - self.dispatch_response_progress_event("progress".into_string()); + self.dispatch_response_progress_event("progress".to_owned()); return_if_fetch_was_terminated!(); - self.dispatch_response_progress_event(errormsg.into_string()); + self.dispatch_response_progress_event(errormsg.to_owned()); return_if_fetch_was_terminated!(); - self.dispatch_response_progress_event("loadend".into_string()); + self.dispatch_response_progress_event("loadend".to_owned()); } } } @@ -892,7 +897,7 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> { fn terminate_ongoing_fetch(self) { let GenerationId(prev_id) = self.generation_id.get(); self.generation_id.set(GenerationId(prev_id + 1)); - self.terminate_sender.borrow().as_ref().map(|s| s.send_opt(TerminateReason::AbortedOrReopened)); + self.terminate_sender.borrow().as_ref().map(|s| s.send(TerminateReason::AbortedOrReopened)); } fn insert_trusted_header(self, name: String, value: String) { @@ -935,10 +940,10 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> { let oneshot = self.timer.borrow_mut() .oneshot(Duration::milliseconds(timeout as i64)); let terminate_sender = (*self.terminate_sender.borrow()).clone(); - spawn_named("XHR:Timer", proc () { - match oneshot.recv_opt() { + spawn_named("XHR:Timer".to_owned(), move || { + match oneshot.recv() { Ok(_) => { - terminate_sender.map(|s| s.send_opt(TerminateReason::TimedOut)); + terminate_sender.map(|s| s.send(TerminateReason::TimedOut)); }, Err(_) => { // This occurs if xhr.timeout (the sender) goes out of scope (i.e, xhr went out of scope) @@ -970,7 +975,7 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> { // According to Simon, decode() should never return an error, so unwrap()ing // the result should be fine. XXXManishearth have a closer look at this later - encoding.decode(self.response.borrow().as_slice(), DecoderTrap::Replace).unwrap().into_string() + encoding.decode(self.response.borrow().as_slice(), DecoderTrap::Replace).unwrap().to_owned() } fn filter_response_headers(self) -> Headers { // http://fetch.spec.whatwg.org/#concept-response-header-list @@ -979,7 +984,7 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> { use hyper::header::common::SetCookie; // a dummy header so we can use headers.remove::<SetCookie2>() - #[deriving(Clone)] + #[derive(Clone)] struct SetCookie2; impl Header for SetCookie2 { fn header_name(_: Option<SetCookie2>) -> &'static str { diff --git a/components/script/dom/xmlhttprequesteventtarget.rs b/components/script/dom/xmlhttprequesteventtarget.rs index f596fe8419b..e27496ec2d9 100644 --- a/components/script/dom/xmlhttprequesteventtarget.rs +++ b/components/script/dom/xmlhttprequesteventtarget.rs @@ -9,7 +9,7 @@ use dom::bindings::codegen::InheritTypes::XMLHttpRequestEventTargetDerived; use dom::bindings::js::JSRef; use dom::eventtarget::{EventTarget, EventTargetHelpers, EventTargetTypeId}; -#[deriving(Copy, PartialEq)] +#[derive(Copy, PartialEq)] #[jstraceable] pub enum XMLHttpRequestEventTargetTypeId { XMLHttpRequest, @@ -44,11 +44,11 @@ impl XMLHttpRequestEventTargetDerived for EventTarget { } impl<'a> XMLHttpRequestEventTargetMethods for JSRef<'a, XMLHttpRequestEventTarget> { - event_handler!(loadstart,GetOnloadstart, SetOnloadstart) - event_handler!(progress, GetOnprogress, SetOnprogress) - event_handler!(abort, GetOnabort, SetOnabort) - event_handler!(error, GetOnerror, SetOnerror) - event_handler!(load, GetOnload, SetOnload) - event_handler!(timeout, GetOntimeout, SetOntimeout) - event_handler!(loadend, GetOnloadend, SetOnloadend) + event_handler!(loadstart,GetOnloadstart, SetOnloadstart); + event_handler!(progress, GetOnprogress, SetOnprogress); + event_handler!(abort, GetOnabort, SetOnabort); + event_handler!(error, GetOnerror, SetOnerror); + event_handler!(load, GetOnload, SetOnload); + event_handler!(timeout, GetOntimeout, SetOntimeout); + event_handler!(loadend, GetOnloadend, SetOnloadend); } diff --git a/components/script/layout_interface.rs b/components/script/layout_interface.rs index 2856930b073..80181c09cda 100644 --- a/components/script/layout_interface.rs +++ b/components/script/layout_interface.rs @@ -13,8 +13,8 @@ use geom::rect::Rect; use script_traits::{ScriptControlChan, OpaqueScriptLayoutChannel, UntrustedNodeAddress}; use servo_msg::constellation_msg::{PipelineExitType, WindowSizeData}; use servo_util::geometry::Au; -use std::any::{Any, AnyRefExt}; -use std::comm::{channel, Receiver, Sender}; +use std::any::Any; +use std::sync::mpsc::{channel, Receiver, Sender}; use std::boxed::BoxAny; use style::Stylesheet; use url::Url; @@ -77,7 +77,7 @@ pub struct HitTestResponse(pub UntrustedNodeAddress); pub struct MouseOverResponse(pub Vec<UntrustedNodeAddress>); /// Why we're doing reflow. -#[deriving(PartialEq, Show)] +#[derive(PartialEq, Show)] pub enum ReflowGoal { /// We're reflowing in order to send a display list to the screen. ForDisplay, @@ -117,7 +117,7 @@ pub struct Reflow { } /// Encapsulates a channel to the layout task. -#[deriving(Clone)] +#[derive(Clone)] pub struct LayoutChan(pub Sender<Msg>); impl LayoutChan { diff --git a/components/script/lib.rs b/components/script/lib.rs index a3c528df29c..aab99ec9106 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -2,19 +2,22 @@ * 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/. */ -#![feature(default_type_params, globs, macro_rules, phase, unsafe_destructor)] +#![feature(unsafe_destructor, plugin, box_syntax, int_uint)] +#![feature(old_impl_check)] #![deny(unsafe_blocks)] #![deny(unused_imports)] #![deny(unused_variables)] #![allow(non_snake_case)] #![allow(missing_copy_implementations)] +#![allow(unstable)] #![doc="The script crate contains all matters DOM."] -#[phase(plugin, link)] +#[macro_use] extern crate log; +extern crate core; extern crate devtools_traits; extern crate cssparser; extern crate collections; @@ -26,22 +29,21 @@ extern crate js; extern crate libc; extern crate msg; extern crate net; -extern crate rustrt; extern crate serialize; extern crate time; extern crate canvas; extern crate script_traits; -#[phase(plugin)] +#[no_link] #[plugin] #[macro_use] extern crate "plugins" as servo_plugins; extern crate "net" as servo_net; extern crate "util" as servo_util; -#[phase(plugin, link)] +#[macro_use] extern crate style; extern crate "msg" as servo_msg; extern crate url; extern crate uuid; extern crate string_cache; -#[phase(plugin)] +#[no_link] #[macro_use] #[plugin] extern crate string_cache_macros; pub mod cors; @@ -54,6 +56,7 @@ pub mod dom { /// The code to expose the DOM to JavaScript through IDL bindings. #[allow(unsafe_blocks)] + #[deny(missing_docs)] pub mod bindings { pub mod cell; pub mod global; @@ -69,6 +72,7 @@ pub mod dom { pub mod trace; /// Generated JS-Rust bindings. + #[allow(missing_docs)] pub mod codegen { #[allow(unrooted_must_root)] pub mod Bindings; diff --git a/components/script/page.rs b/components/script/page.rs index 979f49f6681..b051e1df891 100644 --- a/components/script/page.rs +++ b/components/script/page.rs @@ -31,7 +31,8 @@ use servo_util::geometry; use servo_util::str::DOMString; use servo_util::smallvec::SmallVec; use std::cell::{Cell, Ref, RefMut}; -use std::comm::{channel, Receiver, Empty, Disconnected}; +use std::sync::mpsc::{channel, Receiver}; +use std::sync::mpsc::TryRecvError::{Empty, Disconnected}; use std::mem::replace; use std::num::Float; use std::rc::Rc; @@ -139,7 +140,7 @@ impl Page { let (rpc_send, rpc_recv) = channel(); let LayoutChan(ref lchan) = layout_chan; lchan.send(Msg::GetRPC(rpc_send)); - rpc_recv.recv() + rpc_recv.recv().unwrap() }; Page { id: id, @@ -196,7 +197,7 @@ impl Page { .position(|page_tree| page_tree.id == id) }; match remove_idx { - Some(idx) => Some(self.children.borrow_mut().remove(idx).unwrap()), + Some(idx) => Some(self.children.borrow_mut().remove(idx)), None => { self.children .borrow_mut() @@ -251,7 +252,9 @@ impl Page { } } -impl Iterator<Rc<Page>> for PageIterator { +impl Iterator for PageIterator { + type Item = Rc<Page>; + fn next(&mut self) -> Option<Rc<Page>> { match self.stack.pop() { Some(next) => { @@ -298,7 +301,7 @@ impl Page { } pub fn get_url(&self) -> Url { - self.url().as_ref().unwrap().ref0().clone() + self.url().as_ref().unwrap().0.clone() } // FIXME(cgaebel): join_layout is racey. What if the compositor triggers a @@ -353,7 +356,7 @@ impl Page { Some(root) => root, }; - debug!("script: performing reflow for goal {}", goal); + debug!("script: performing reflow for goal {:?}", goal); let root: JSRef<Node> = NodeCast::from_ref(root.r()); if !root.get_has_dirty_descendants() { @@ -361,7 +364,7 @@ impl Page { return } - debug!("script: performing reflow for goal {}", goal); + debug!("script: performing reflow for goal {:?}", goal); // Layout will let us know when it's done. let (join_chan, join_port) = channel(); diff --git a/components/script/parse/html.rs b/components/script/parse/html.rs index 156994e5ea1..99bb8edf60f 100644 --- a/components/script/parse/html.rs +++ b/components/script/parse/html.rs @@ -27,7 +27,7 @@ use servo_net::resource_task::{ProgressMsg, LoadResponse}; use servo_util::task_state; use servo_util::task_state::IN_HTML_PARSER; use std::ascii::AsciiExt; -use std::str::CowString; +use std::string::CowString; use url::Url; use html5ever::Attribute; use html5ever::tree_builder::{TreeSink, QuirksMode, NodeOrText, AppendNode, AppendText}; diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 46488446b9d..e41d069094a 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -18,7 +18,7 @@ use dom::bindings::conversions::StringificationBehavior; use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable}; use dom::bindings::js::{RootCollection, RootCollectionPtr}; -use dom::bindings::refcounted::{LiveDOMReferences, Trusted}; +use dom::bindings::refcounted::{LiveDOMReferences, Trusted, TrustedReference}; use dom::bindings::structuredclone::StructuredCloneData; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::{wrap_for_same_compartment, pre_wrap}; @@ -30,7 +30,7 @@ use dom::eventtarget::{EventTarget, EventTargetHelpers}; use dom::htmlelement::HTMLElementTypeId; use dom::keyboardevent::KeyboardEvent; use dom::mouseevent::MouseEvent; -use dom::node::{mod, Node, NodeHelpers, NodeDamage, NodeTypeId}; +use dom::node::{self, Node, NodeHelpers, NodeDamage, NodeTypeId}; use dom::window::{Window, WindowHelpers, ScriptHelpers}; use parse::html::{HTMLInput, parse_html}; use layout_interface::{ScriptLayoutChan, LayoutChan, ReflowGoal, ReflowQueryType}; @@ -68,9 +68,9 @@ use servo_util::task_state; use geom::point::Point2D; use hyper::header::{Header, HeaderFormat}; -use hyper::header::common::util as header_util; +use hyper::header::shared::util as header_util; use js::jsapi::{JS_SetWrapObjectCallbacks, JS_SetGCZeal, JS_DEFAULT_ZEAL_FREQ, JS_GC}; -use js::jsapi::{JSContext, JSRuntime}; +use js::jsapi::{JSContext, JSRuntime, JSObject}; use js::jsapi::{JS_SetGCParameter, JSGC_MAX_BYTES}; use js::jsapi::{JS_SetGCCallback, JSGCStatus, JSGC_BEGIN, JSGC_END}; use js::rust::{Cx, RtUtils}; @@ -78,18 +78,20 @@ use js; use url::Url; use libc; -use std::any::{Any, AnyRefExt}; +use std::any::Any; +use std::borrow::ToOwned; use std::cell::Cell; -use std::comm::{channel, Sender, Receiver, Select}; -use std::fmt::{mod, Show}; +use std::fmt::{self, Show}; use std::mem::replace; +use std::num::ToPrimitive; use std::rc::Rc; +use std::sync::mpsc::{channel, Sender, Receiver, Select}; use std::u32; use time::{Tm, strptime}; -thread_local!(pub static STACK_ROOTS: Cell<Option<RootCollectionPtr>> = Cell::new(None)) +thread_local!(pub static STACK_ROOTS: Cell<Option<RootCollectionPtr>> = Cell::new(None)); -#[deriving(Copy)] +#[derive(Copy)] pub enum TimerSource { FromWindow(PipelineId), FromWorker @@ -124,7 +126,7 @@ pub enum ScriptMsg { /// Generic message that encapsulates event handling. RunnableMsg(Box<Runnable+Send>), /// A DOM object's last pinned reference was removed (dispatched to all tasks). - RefcountCleanup(*const libc::c_void), + RefcountCleanup(TrustedReference), } /// A cloneable interface for communicating with an event loop. @@ -147,7 +149,7 @@ impl ScriptChan for NonWorkerScriptChan { fn clone(&self) -> Box<ScriptChan+Send> { let NonWorkerScriptChan(ref chan) = *self; - box NonWorkerScriptChan(chan.clone()) + box NonWorkerScriptChan((*chan).clone()) } } @@ -302,7 +304,7 @@ impl ScriptTaskFactory for ScriptTask { let ConstellationChan(const_chan) = constellation_chan.clone(); let (script_chan, script_port) = channel(); let layout_chan = LayoutChan(layout_chan.sender()); - spawn_named_with_send_on_failure("ScriptTask", task_state::SCRIPT, proc() { + spawn_named_with_send_on_failure("ScriptTask", task_state::SCRIPT, move || { let script_task = ScriptTask::new(id, box compositor as Box<ScriptListener>, layout_chan, @@ -350,6 +352,12 @@ impl ScriptTask { window_size: WindowSizeData) -> ScriptTask { let (js_runtime, js_context) = ScriptTask::new_rt_and_cx(); + let wrap_for_same_compartment = wrap_for_same_compartment as + unsafe extern "C" fn(*mut JSContext, *mut JSObject) -> *mut JSObject; + let pre_wrap = pre_wrap as + unsafe extern fn(*mut JSContext, *mut JSObject, *mut JSObject, + libc::c_uint) -> *mut JSObject; + unsafe { // JS_SetWrapObjectCallbacks clobbers the existing wrap callback, // and JSCompartment::wrap crashes if that happens. The only way @@ -425,7 +433,8 @@ impl ScriptTask { // Needed for debug assertions about whether GC is running. if !cfg!(ndebug) { unsafe { - JS_SetGCCallback(js_runtime.ptr, Some(debug_gc_callback)); + JS_SetGCCallback(js_runtime.ptr, + Some(debug_gc_callback as unsafe extern "C" fn(*mut JSRuntime, JSGCStatus))); } } @@ -497,11 +506,11 @@ impl ScriptTask { } let ret = sel.wait(); if ret == port1.id() { - MixedMessage::FromScript(self.port.recv()) + MixedMessage::FromScript(self.port.recv().unwrap()) } else if ret == port2.id() { - MixedMessage::FromConstellation(self.control_port.recv()) + MixedMessage::FromConstellation(self.control_port.recv().unwrap()) } else if ret == port3.id() { - MixedMessage::FromDevtools(self.devtools_port.recv()) + MixedMessage::FromDevtools(self.devtools_port.recv().unwrap()) } else { panic!("unexpected select result") } @@ -666,7 +675,7 @@ impl ScriptTask { /// Handles a notification that reflow completed. fn handle_reflow_complete_msg(&self, pipeline_id: PipelineId, reflow_id: uint) { - debug!("Script: Reflow {} complete for {}", reflow_id, pipeline_id); + debug!("Script: Reflow {:?} complete for {:?}", reflow_id, pipeline_id); let page = self.page.borrow_mut(); let page = page.find(pipeline_id).expect( "ScriptTask: received a load message for a layout channel that is not associated \ @@ -694,8 +703,8 @@ impl ScriptTask { with a page in the page tree. This is a bug."); page.window_size.set(new_size); match &mut *page.mut_url() { - &Some((_, ref mut needs_reflow)) => *needs_reflow = true, - &None => (), + &mut Some((_, ref mut needs_reflow)) => *needs_reflow = true, + &mut None => (), } } @@ -724,7 +733,7 @@ impl ScriptTask { // If root is being exited, shut down all pages let page = self.page.borrow_mut(); if page.id == id { - debug!("shutting down layout for root page {}", id); + debug!("shutting down layout for root page {:?}", id); *self.js_context.borrow_mut() = None; shut_down_layout(&*page, (*self.js_runtime).ptr, exit_type); return true @@ -748,7 +757,7 @@ impl ScriptTask { /// objects, parses HTML and CSS, and kicks off initial layout. fn load(&self, pipeline_id: PipelineId, load_data: LoadData) { let url = load_data.url.clone(); - debug!("ScriptTask: loading {} on page {}", url, pipeline_id); + debug!("ScriptTask: loading {:?} on page {:?}", url, pipeline_id); let page = self.page.borrow_mut(); let page = page.find(pipeline_id).expect("ScriptTask: received a load @@ -764,7 +773,7 @@ impl ScriptTask { // Pull out the `needs_reflow` flag explicitly because `reflow` can ask for the page's // URL, and we can't be holding a borrow on that URL (#4402). let needed_reflow = match &mut *page.mut_url() { - &Some((_, ref mut needs_reflow)) => replace(needs_reflow, false), + &mut Some((_, ref mut needs_reflow)) => replace(needs_reflow, false), _ => panic!("can't reload a page with no URL!") }; if needed_reflow { @@ -823,7 +832,7 @@ impl ScriptTask { consumer: input_chan, })); - let load_response = input_port.recv(); + let load_response = input_port.recv().unwrap(); load_response.metadata.headers.as_ref().map(|headers| { headers.get().map(|&LastModified(ref tm)| { @@ -846,7 +855,7 @@ impl ScriptTask { let jsval = window.r().evaluate_js_on_global_with_result(evalstr); let strval = FromJSValConvertible::from_jsval(self.get_cx(), jsval, StringificationBehavior::Empty); - (HTMLInput::InputString(strval.unwrap_or("".into_string())), doc_url) + (HTMLInput::InputString(strval.unwrap_or("".to_owned())), doc_url) }; parse_html(document.r(), parser_input, &final_url); @@ -855,7 +864,7 @@ impl ScriptTask { self.compositor.borrow_mut().set_ready_state(pipeline_id, PerformingLayout); // Kick off the initial reflow of the page. - debug!("kicking off initial reflow of {}", final_url); + debug!("kicking off initial reflow of {:?}", final_url); document.r().content_changed(NodeCast::from_ref(document.r()), NodeDamage::OtherNodeDamage); window.r().flush_layout(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery); @@ -1002,13 +1011,13 @@ impl ScriptTask { let ev_type = match state { KeyState::Pressed | KeyState::Repeated => "keydown", KeyState::Released => "keyup", - }.into_string(); + }.to_owned(); let props = KeyboardEvent::key_properties(key, modifiers); let keyevent = KeyboardEvent::new(window.r(), ev_type, true, true, Some(window.r()), 0, - props.key.into_string(), props.code.into_string(), + props.key.to_owned(), props.code.to_owned(), props.location, is_repeating, is_composing, ctrl, alt, shift, meta, None, props.key_code).root(); @@ -1019,15 +1028,14 @@ impl ScriptTask { // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#keys-cancelable-keys if state != KeyState::Released && props.is_printable() && !prevented { // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#keypress-event-order - let event = KeyboardEvent::new(window.r(), "keypress".into_string(), + let event = KeyboardEvent::new(window.r(), "keypress".to_owned(), true, true, Some(window.r()), - 0, props.key.into_string(), props.code.into_string(), + 0, props.key.to_owned(), props.code.to_owned(), props.location, is_repeating, is_composing, ctrl, alt, shift, meta, props.char_code, 0).root(); - let _ = target.DispatchEvent(EventCast::from_ref(event.r())); - let ev = EventCast::from_ref(event.r()); + let _ = target.DispatchEvent(ev); prevented = ev.DefaultPrevented(); // TODO: if keypress event is canceled, prevent firing input events } @@ -1105,7 +1113,7 @@ impl ScriptTask { // http://dev.w3.org/csswg/cssom-view/#resizing-viewports // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#event-type-resize let uievent = UIEvent::new(window.r(), - "resize".into_string(), false, + "resize".to_owned(), false, false, Some(window.r()), 0i32).root(); let event: JSRef<Event> = EventCast::from_ref(uievent.r()); @@ -1127,25 +1135,26 @@ impl ScriptTask { } fn handle_click_event(&self, pipeline_id: PipelineId, _button: uint, point: Point2D<f32>) { - debug!("ClickEvent: clicked at {}", point); + debug!("ClickEvent: clicked at {:?}", point); let page = get_page(&*self.page.borrow(), pipeline_id); match page.hit_test(&point) { Some(node_address) => { - debug!("node address is {}", node_address); + debug!("node address is {:?}", node_address.0); let temp_node = node::from_untrusted_node_address( self.js_runtime.ptr, node_address).root(); - let maybe_node = match ElementCast::to_ref(temp_node.r()) { + let maybe_elem: Option<JSRef<Element>> = ElementCast::to_ref(temp_node.r()); + let maybe_node = match maybe_elem { Some(element) => Some(element), None => temp_node.r().ancestors().filter_map(ElementCast::to_ref).next(), }; match maybe_node { Some(el) => { - let node = NodeCast::from_ref(el); - debug!("clicked on {}", node.debug_str()); + let node: JSRef<Node> = NodeCast::from_ref(el); + debug!("clicked on {:?}", node.debug_str()); // Prevent click event if form control element is disabled. if node.click_event_filter_by_disabled_state() { return; } match *page.frame() { @@ -1156,7 +1165,7 @@ impl ScriptTask { let event = Event::new(GlobalRef::Window(window.r()), - "click".into_string(), + "click".to_owned(), EventBubbles::Bubbles, EventCancelable::Cancelable).root(); // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#trusted-events @@ -1208,7 +1217,7 @@ impl ScriptTask { let y = point.y.to_i32().unwrap_or(0); let mouse_event = MouseEvent::new(window.r(), - "mousemove".into_string(), + "mousemove".to_owned(), true, true, Some(window.r()), @@ -1308,7 +1317,7 @@ pub fn get_page(page: &Rc<Page>, pipeline_id: PipelineId) -> Rc<Page> { } //FIXME(seanmonstar): uplift to Hyper -#[deriving(Clone)] +#[derive(Clone)] struct LastModified(pub Tm); impl Header for LastModified { @@ -1360,7 +1369,7 @@ impl DocumentProgressHandler { fn dispatch_dom_content_loaded(&self) { let document = self.addr.to_temporary().root(); let window = document.r().window().root(); - let event = Event::new(GlobalRef::Window(window.r()), "DOMContentLoaded".into_string(), + let event = Event::new(GlobalRef::Window(window.r()), "DOMContentLoaded".to_owned(), EventBubbles::DoesNotBubble, EventCancelable::NotCancelable).root(); let doctarget: JSRef<EventTarget> = EventTargetCast::from_ref(document.r()); @@ -1375,7 +1384,7 @@ impl DocumentProgressHandler { fn dispatch_load(&self) { let document = self.addr.to_temporary().root(); let window = document.r().window().root(); - let event = Event::new(GlobalRef::Window(window.r()), "load".into_string(), + let event = Event::new(GlobalRef::Window(window.r()), "load".to_owned(), EventBubbles::DoesNotBubble, EventCancelable::NotCancelable).root(); let wintarget: JSRef<EventTarget> = EventTargetCast::from_ref(window.r()); diff --git a/components/script/tests.rs b/components/script/tests.rs index 28710e23647..6b60f0ee534 100644 --- a/components/script/tests.rs +++ b/components/script/tests.rs @@ -35,14 +35,14 @@ macro_rules! sizeof_checker ( stringify!($t), old, new) } }); -) +); // Update the sizes here -sizeof_checker!(size_event_target, EventTarget, 48) -sizeof_checker!(size_node, Node, 288) -sizeof_checker!(size_element, Element, 432) -sizeof_checker!(size_htmlelement, HTMLElement, 464) -sizeof_checker!(size_div, HTMLDivElement, 464) -sizeof_checker!(size_span, HTMLSpanElement, 464) -sizeof_checker!(size_text, Text, 320) -sizeof_checker!(size_characterdata, CharacterData, 320) +sizeof_checker!(size_event_target, EventTarget, 48); +sizeof_checker!(size_node, Node, 288); +sizeof_checker!(size_element, Element, 432); +sizeof_checker!(size_htmlelement, HTMLElement, 464); +sizeof_checker!(size_div, HTMLDivElement, 464); +sizeof_checker!(size_span, HTMLSpanElement, 464); +sizeof_checker!(size_text, Text, 320); +sizeof_checker!(size_characterdata, CharacterData, 320); diff --git a/components/script/textinput.rs b/components/script/textinput.rs index 15dc23d677b..fa9ad4eacff 100644 --- a/components/script/textinput.rs +++ b/components/script/textinput.rs @@ -9,18 +9,19 @@ use dom::bindings::js::JSRef; use dom::keyboardevent::KeyboardEvent; use servo_util::str::DOMString; +use std::borrow::ToOwned; use std::cmp::{min, max}; use std::default::Default; use std::num::SignedInt; -#[deriving(Copy, PartialEq)] +#[derive(Copy, PartialEq)] enum Selection { Selected, NotSelected } #[jstraceable] -#[deriving(Copy)] +#[derive(Copy)] struct TextPoint { /// 0-based line number line: uint, @@ -58,14 +59,14 @@ impl Default for TextPoint { } /// Control whether this control should allow multiple lines. -#[deriving(PartialEq)] +#[derive(PartialEq)] pub enum Lines { Single, Multiple, } /// The direction in which to delete a character. -#[deriving(PartialEq)] +#[derive(PartialEq)] enum DeleteDir { Forward, Backward @@ -106,7 +107,7 @@ impl TextInput { -1 }, Selection::Selected); } - self.replace_selection("".into_string()); + self.replace_selection("".to_owned()); } /// Insert a character at the current editing point @@ -134,22 +135,22 @@ impl TextInput { let new_lines = { let prefix = self.lines[begin.line].slice_chars(0, begin.index); - let suffix = self.lines[end.line].slice_chars(end.index, self.lines[end.line].char_len()); + let suffix = self.lines[end.line].slice_chars(end.index, self.lines[end.line].chars().count()); let lines_prefix = self.lines.slice(0, begin.line); let lines_suffix = self.lines.slice(end.line + 1, self.lines.len()); let mut insert_lines = if self.multiline { - insert.as_slice().split('\n').map(|s| s.into_string()).collect() + insert.as_slice().split('\n').map(|s| s.to_owned()).collect() } else { vec!(insert) }; - let mut new_line = prefix.into_string(); + let mut new_line = prefix.to_owned(); new_line.push_str(insert_lines[0].as_slice()); insert_lines[0] = new_line; let last_insert_lines_index = insert_lines.len() - 1; - self.edit_point.index = insert_lines[last_insert_lines_index].char_len(); + self.edit_point.index = insert_lines[last_insert_lines_index].chars().count(); self.edit_point.line = begin.line + last_insert_lines_index; insert_lines[last_insert_lines_index].push_str(suffix); @@ -166,7 +167,7 @@ impl TextInput { /// Return the length of the current line under the editing point. fn current_line_length(&self) -> uint { - self.lines[self.edit_point.line].char_len() + self.lines[self.edit_point.line].chars().count() } /// Adjust the editing point position by a given of lines. The resulting column is @@ -259,7 +260,7 @@ impl TextInput { }); let last_line = self.lines.len() - 1; self.edit_point.line = last_line; - self.edit_point.index = self.lines[last_line].char_len(); + self.edit_point.index = self.lines[last_line].chars().count(); } /// Remove the current selection. @@ -338,7 +339,7 @@ impl TextInput { /// Get the current contents of the text input. Multiple lines are joined by \n. pub fn get_content(&self) -> DOMString { - let mut content = "".into_string(); + let mut content = "".to_owned(); for (i, line) in self.lines.iter().enumerate() { content.push_str(line.as_slice()); if i < self.lines.len() - 1 { @@ -352,7 +353,7 @@ impl TextInput { /// any \n encountered will be stripped and force a new logical line. pub fn set_content(&mut self, content: DOMString) { self.lines = if self.multiline { - content.as_slice().split('\n').map(|s| s.into_string()).collect() + content.as_slice().split('\n').map(|s| s.to_owned()).collect() } else { vec!(content) }; @@ -363,7 +364,7 @@ impl TextInput { #[test] fn test_textinput_delete_char() { - let mut textinput = TextInput::new(Lines::Single, "abcdefg".into_string()); + let mut textinput = TextInput::new(Lines::Single, "abcdefg".to_owned()); textinput.adjust_horizontal(2, Selection::NotSelected); textinput.delete_char(DeleteDir::Backward); assert_eq!(textinput.get_content().as_slice(), "acdefg"); @@ -378,7 +379,7 @@ fn test_textinput_delete_char() { #[test] fn test_textinput_insert_char() { - let mut textinput = TextInput::new(Lines::Single, "abcdefg".into_string()); + let mut textinput = TextInput::new(Lines::Single, "abcdefg".to_owned()); textinput.adjust_horizontal(2, Selection::NotSelected); textinput.insert_char('a'); assert_eq!(textinput.get_content().as_slice(), "abacdefg"); @@ -390,7 +391,7 @@ fn test_textinput_insert_char() { #[test] fn test_textinput_get_sorted_selection() { - let mut textinput = TextInput::new(Lines::Single, "abcdefg".into_string()); + let mut textinput = TextInput::new(Lines::Single, "abcdefg".to_owned()); textinput.adjust_horizontal(2, Selection::NotSelected); textinput.adjust_horizontal(2, Selection::Selected); let (begin, end) = textinput.get_sorted_selection(); @@ -407,17 +408,17 @@ fn test_textinput_get_sorted_selection() { #[test] fn test_textinput_replace_selection() { - let mut textinput = TextInput::new(Lines::Single, "abcdefg".into_string()); + let mut textinput = TextInput::new(Lines::Single, "abcdefg".to_owned()); textinput.adjust_horizontal(2, Selection::NotSelected); textinput.adjust_horizontal(2, Selection::Selected); - textinput.replace_selection("xyz".into_string()); + textinput.replace_selection("xyz".to_owned()); assert_eq!(textinput.get_content().as_slice(), "abxyzefg"); } #[test] fn test_textinput_current_line_length() { - let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".into_string()); + let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".to_owned()); assert_eq!(textinput.current_line_length(), 3); textinput.adjust_vertical(1, Selection::NotSelected); @@ -429,7 +430,7 @@ fn test_textinput_current_line_length() { #[test] fn test_textinput_adjust_vertical() { - let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".into_string()); + let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".to_owned()); textinput.adjust_horizontal(3, Selection::NotSelected); textinput.adjust_vertical(1, Selection::NotSelected); assert_eq!(textinput.edit_point.line, 1); @@ -446,7 +447,7 @@ fn test_textinput_adjust_vertical() { #[test] fn test_textinput_adjust_horizontal() { - let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".into_string()); + let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".to_owned()); textinput.adjust_horizontal(4, Selection::NotSelected); assert_eq!(textinput.edit_point.line, 1); assert_eq!(textinput.edit_point.index, 0); @@ -466,12 +467,12 @@ fn test_textinput_adjust_horizontal() { #[test] fn test_textinput_handle_return() { - let mut single_line_textinput = TextInput::new(Lines::Single, "abcdef".into_string()); + let mut single_line_textinput = TextInput::new(Lines::Single, "abcdef".to_owned()); single_line_textinput.adjust_horizontal(3, Selection::NotSelected); single_line_textinput.handle_return(); assert_eq!(single_line_textinput.get_content().as_slice(), "abcdef"); - let mut multi_line_textinput = TextInput::new(Lines::Multiple, "abcdef".into_string()); + let mut multi_line_textinput = TextInput::new(Lines::Multiple, "abcdef".to_owned()); multi_line_textinput.adjust_horizontal(3, Selection::NotSelected); multi_line_textinput.handle_return(); assert_eq!(multi_line_textinput.get_content().as_slice(), "abc\ndef"); @@ -479,7 +480,7 @@ fn test_textinput_handle_return() { #[test] fn test_textinput_select_all() { - let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".into_string()); + let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".to_owned()); assert_eq!(textinput.edit_point.line, 0); assert_eq!(textinput.edit_point.index, 0); @@ -490,19 +491,19 @@ fn test_textinput_select_all() { #[test] fn test_textinput_get_content() { - let single_line_textinput = TextInput::new(Lines::Single, "abcdefg".into_string()); + let single_line_textinput = TextInput::new(Lines::Single, "abcdefg".to_owned()); assert_eq!(single_line_textinput.get_content().as_slice(), "abcdefg"); - let multi_line_textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".into_string()); + let multi_line_textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".to_owned()); assert_eq!(multi_line_textinput.get_content().as_slice(), "abc\nde\nf"); } #[test] fn test_textinput_set_content() { - let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".into_string()); + let mut textinput = TextInput::new(Lines::Multiple, "abc\nde\nf".to_owned()); assert_eq!(textinput.get_content().as_slice(), "abc\nde\nf"); - textinput.set_content("abc\nf".into_string()); + textinput.set_content("abc\nf".to_owned()); assert_eq!(textinput.get_content().as_slice(), "abc\nf"); assert_eq!(textinput.edit_point.line, 0); @@ -510,7 +511,7 @@ fn test_textinput_set_content() { textinput.adjust_horizontal(3, Selection::Selected); assert_eq!(textinput.edit_point.line, 0); assert_eq!(textinput.edit_point.index, 3); - textinput.set_content("de".into_string()); + textinput.set_content("de".to_owned()); assert_eq!(textinput.get_content().as_slice(), "de"); assert_eq!(textinput.edit_point.line, 0); assert_eq!(textinput.edit_point.index, 2); diff --git a/components/script/timers.rs b/components/script/timers.rs index 9c6ec47ffef..bfcd76b95a4 100644 --- a/components/script/timers.rs +++ b/components/script/timers.rs @@ -17,18 +17,19 @@ use servo_util::str::DOMString; use js::jsval::JSVal; +use std::borrow::ToOwned; use std::cell::Cell; use std::cmp; use std::collections::HashMap; -use std::comm::{channel, Sender}; -use std::comm::Select; -use std::hash::{Hash, sip}; +use std::sync::mpsc::{channel, Sender}; +use std::sync::mpsc::Select; +use std::hash::{Hash, Hasher, Writer}; use std::io::timer::Timer; use std::time::duration::Duration; -#[deriving(PartialEq, Eq)] +#[derive(PartialEq, Eq)] #[jstraceable] -#[deriving(Copy)] +#[derive(Copy)] pub struct TimerId(i32); #[jstraceable] @@ -40,14 +41,14 @@ struct TimerHandle { } #[jstraceable] -#[deriving(Clone)] +#[derive(Clone)] pub enum TimerCallback { StringTimerCallback(DOMString), FunctionTimerCallback(Function) } -impl Hash for TimerId { - fn hash(&self, state: &mut sip::SipState) { +impl<H: Writer + Hasher> Hash<H> for TimerId { + fn hash(&self, state: &mut H) { let TimerId(id) = *self; id.hash(state); } @@ -55,7 +56,7 @@ impl Hash for TimerId { impl TimerHandle { fn cancel(&mut self) { - self.cancel_chan.as_ref().map(|chan| chan.send_opt(()).ok()); + self.cancel_chan.as_ref().map(|chan| chan.send(()).ok()); } } @@ -78,7 +79,7 @@ impl Drop for TimerManager { // Enum allowing more descriptive values for the is_interval field #[jstraceable] -#[deriving(PartialEq, Copy, Clone)] +#[derive(PartialEq, Copy, Clone)] pub enum IsInterval { Interval, NonInterval, @@ -90,7 +91,7 @@ pub enum IsInterval { // TODO: Handle rooting during fire_timer when movable GC is turned on #[jstraceable] #[privatize] -#[deriving(Clone)] +#[derive(Clone)] struct TimerData { is_interval: IsInterval, callback: TimerCallback, @@ -127,8 +128,8 @@ impl TimerManager { TimerSource::FromWorker if is_interval == IsInterval::Interval => "Worker:SetInterval", TimerSource::FromWindow(_) => "Window:SetTimeout", TimerSource::FromWorker => "Worker:SetTimeout", - }; - spawn_named(spawn_name, proc() { + }.to_owned(); + spawn_named(spawn_name, move || { let mut tm = tm; let duration = Duration::milliseconds(timeout as i64); let timeout_port = if is_interval == IsInterval::Interval { diff --git a/components/script_traits/Cargo.toml b/components/script_traits/Cargo.toml index b5ca1ca0389..d0075c2d08d 100644 --- a/components/script_traits/Cargo.toml +++ b/components/script_traits/Cargo.toml @@ -22,5 +22,5 @@ path = "../devtools_traits" [dependencies.geom] git = "https://github.com/servo/rust-geom" -[dependencies.url] -git = "https://github.com/servo/rust-url" +[dependencies] +url = "*"
\ No newline at end of file diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index 010ffe5b296..0b6bb4a3b36 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -2,6 +2,8 @@ * 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/. */ +#![feature(int_uint)] + #![deny(unused_imports)] #![deny(unused_variables)] #![allow(missing_copy_implementations)] @@ -31,15 +33,17 @@ use servo_net::resource_task::ResourceTask; use servo_net::storage_task::StorageTask; use servo_util::smallvec::SmallVec1; use std::any::Any; +use std::sync::mpsc::{Sender, Receiver}; use geom::point::Point2D; use geom::rect::Rect; -use serialize::{Encodable, Encoder}; - /// The address of a node. Layout sends these back. They must be validated via /// `from_untrusted_node_address` before they can be used, because we do not trust layout. -pub type UntrustedNodeAddress = *const c_void; +#[allow(raw_pointer_derive)] +#[derive(Copy, Clone)] +pub struct UntrustedNodeAddress(pub *const c_void); +unsafe impl Send for UntrustedNodeAddress {} pub struct NewLayoutInfo { pub old_pipeline_id: PipelineId, @@ -70,6 +74,9 @@ pub enum ConstellationControlMsg { GetTitle(PipelineId), } +unsafe impl Send for ConstellationControlMsg { +} + /// Events from the compositor that the script task needs to know about pub enum CompositorEvent { ResizeEvent(WindowSizeData), @@ -86,15 +93,9 @@ pub enum CompositorEvent { pub struct OpaqueScriptLayoutChannel(pub (Box<Any+Send>, Box<Any+Send>)); /// Encapsulates external communication with the script task. -#[deriving(Clone)] +#[derive(Clone)] pub struct ScriptControlChan(pub Sender<ConstellationControlMsg>); -impl<S: Encoder<E>, E> Encodable<S, E> for ScriptControlChan { - fn encode(&self, _s: &mut S) -> Result<(), E> { - Ok(()) - } -} - pub trait ScriptTaskFactory { fn create<C>(_phantom: Option<&mut Self>, id: PipelineId, diff --git a/components/servo/.cargo/config b/components/servo/.cargo/config index 102a11443bb..6c935952e2c 100644 --- a/components/servo/.cargo/config +++ b/components/servo/.cargo/config @@ -1,10 +1,4 @@ -# FIXME: Remove this next rustup. This is a temporary -# hack to allow android cross compilation to work. When -# this is removed, the support/time submodule can also -# be removed! -paths = [ - "../../support/time" -] +paths = ["../../support/android-rs-glue"] [target.arm-linux-androideabi] linker = "../../support/android-rs-glue/apk-builder/target/apk-builder" diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 8d302666dd8..bfa744ca8bf 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -2,23 +2,33 @@ name = "servo" version = "0.0.1" dependencies = [ + "android_glue 0.0.1", "compositing 0.0.1", + "devtools 0.0.1", "gfx 0.0.1", "glfw_app 0.0.1", "glutin_app 0.0.1", "layout 0.0.1", "msg 0.0.1", "net 0.0.1", + "png 0.1.0 (git+https://github.com/servo/rust-png)", "script 0.0.1", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "android_glue" version = "0.0.1" -source = "git+https://github.com/servo/android-rs-glue?ref=servo#122bc28545b5e59a923c466a484c403fa691bd55" +dependencies = [ + "compile_msg 0.1.1 (git+https://github.com/huonw/compile_msg)", +] + +[[package]] +name = "android_glue" +version = "0.0.1" +source = "git+https://github.com/tomaka/android-rs-glue#8fc770e4c1412293e459bc12ca4fcf57780e2186" dependencies = [ "compile_msg 0.1.1 (git+https://github.com/huonw/compile_msg)", ] @@ -26,7 +36,7 @@ dependencies = [ [[package]] name = "azure" version = "0.1.0" -source = "git+https://github.com/servo/rust-azure#d0acabef6221e5fd6840254dc23f91c66b874629" +source = "git+https://github.com/servo/rust-azure#72deb42903b12dc6f1924fa1757cd79d37b35429" dependencies = [ "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)", @@ -34,7 +44,7 @@ dependencies = [ "egl 0.1.0 (git+https://github.com/servo/rust-egl)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", - "skia-sys 0.0.20130412 (git+https://github.com/servo/skia?ref=upstream-2014-06-16)", + "skia-sys 0.0.20130412 (git+https://github.com/servo/skia?branch=upstream-2014-06-16)", "xlib 0.1.0 (git+https://github.com/servo/rust-xlib)", ] @@ -58,7 +68,7 @@ dependencies = [ [[package]] name = "cocoa" version = "0.1.1" -source = "git+https://github.com/servo/rust-cocoa#bf53a53ce306279fc1cae0d56fdd5e7216696420" +source = "git+https://github.com/servo/rust-cocoa#84a405ba9ff2a79d507dc6ee1ea3cf9bf48706d1" [[package]] name = "compile_msg" @@ -83,25 +93,26 @@ dependencies = [ "net 0.0.1", "png 0.1.0 (git+https://github.com/servo/rust-png)", "script_traits 0.0.1", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "cookie" -version = "0.1.0" -source = "git+https://github.com/alexcrichton/cookie-rs#8d1b4bb8d5ed06e58c162eb235a4ccd210b68108" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "openssl 0.2.4 (git+https://github.com/sfackler/rust-openssl)", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "openssl 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "core_foundation" version = "0.1.0" -source = "git+https://github.com/servo/rust-core-foundation#81db9ab15f67e16d7a3e9705a06cad65192014fd" +source = "git+https://github.com/servo/rust-core-foundation#ce3d852765827b64a0d5fb2aadd77da39665b0b0" [[package]] name = "core_graphics" @@ -114,7 +125,7 @@ dependencies = [ [[package]] name = "core_text" version = "0.1.0" -source = "git+https://github.com/servo/rust-core-text#cb369a26a0eb4e83c2128ceb3c685a191113417a" +source = "git+https://github.com/servo/rust-core-text#b5cb33905350e99b2a19f5a22f7b1efea7ad48c2" dependencies = [ "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)", @@ -122,11 +133,12 @@ dependencies = [ [[package]] name = "cssparser" -version = "0.1.1" -source = "git+https://github.com/servo/rust-cssparser#110bf3052d016bf6eda0689fb21cf971e2c23dc8" +version = "0.2.0" +source = "git+https://github.com/servo/rust-cssparser#2a8c9f2c5f568495bae16f44b799be39b8efad39" dependencies = [ - "encoding 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "text_writer 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "text_writer 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -148,63 +160,63 @@ dependencies = [ [[package]] name = "egl" version = "0.1.0" -source = "git+https://github.com/servo/rust-egl#88f2a13812ddbce2bf2317221663a61c31b3e220" +source = "git+https://github.com/servo/rust-egl#cd74c82a8537090edb6c16478e2261db2a8c0b4f" [[package]] name = "encoding" -version = "0.2.6" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "encoding-index-japanese 1.0.20140915 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding-index-korean 1.0.20140915 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding-index-simpchinese 1.0.20140915 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding-index-singlebyte 1.0.20140915 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding-index-tradchinese 1.0.20140915 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding-index-japanese 1.20141219.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding-index-korean 1.20141219.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding-index-simpchinese 1.20141219.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding-index-singlebyte 1.20141219.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding-index-tradchinese 1.20141219.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "encoding-index-japanese" -version = "1.0.20140915" +version = "1.20141219.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "encoding_index_tests 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_index_tests 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "encoding-index-korean" -version = "1.0.20140915" +version = "1.20141219.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "encoding_index_tests 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_index_tests 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "encoding-index-simpchinese" -version = "1.0.20140915" +version = "1.20141219.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "encoding_index_tests 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_index_tests 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "encoding-index-singlebyte" -version = "1.0.20140915" +version = "1.20141219.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "encoding_index_tests 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_index_tests 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "encoding-index-tradchinese" -version = "1.0.20140915" +version = "1.20141219.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "encoding_index_tests 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_index_tests 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "encoding_index_tests" -version = "0.1.0" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -232,7 +244,7 @@ dependencies = [ [[package]] name = "freetype" version = "0.1.0" -source = "git+https://github.com/servo/rust-freetype#e55b06110fb2d74a2db68ead740db7e98fb98060" +source = "git+https://github.com/servo/rust-freetype#ec0231343a3ad360d86846c12895a0a0cbb19f79" [[package]] name = "freetype-sys" @@ -241,18 +253,18 @@ source = "git+https://github.com/servo/libfreetype2#f5c49c0da1d5bc6b206c41763440 [[package]] name = "gcc" -version = "0.1.1" -source = "git+https://github.com/alexcrichton/gcc-rs#dfe97a119af4b2db53178eb8c3ca6be6589a152b" +version = "0.1.4" +source = "git+https://github.com/alexcrichton/gcc-rs#f5c52d956e0742a66e40c8301e634e136c3ae287" [[package]] name = "gcc" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "geom" version = "0.1.0" -source = "git+https://github.com/servo/rust-geom#05f2d5494355adc78ad7d17286912f0d128f503b" +source = "git+https://github.com/servo/rust-geom#a4a4a03aa024412bf3f4e093c0198b433c6ad63f" [[package]] name = "gfx" @@ -274,47 +286,66 @@ dependencies = [ "script_traits 0.0.1", "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)", "style 0.0.1", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "gl_common" -version = "0.0.1" -source = "git+https://github.com/bjz/gl-rs.git#b5e3f4f76c31bc1b459d5e4c10d879ffa4f67c6e" +version = "0.0.3" +source = "git+https://github.com/bjz/gl-rs.git#230e6c9ed611cddfcb6682dee9686471d54863d0" + +[[package]] +name = "gl_common" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "gl_generator" -version = "0.0.1" -source = "git+https://github.com/bjz/gl-rs.git#b5e3f4f76c31bc1b459d5e4c10d879ffa4f67c6e" +version = "0.0.12" +source = "git+https://github.com/bjz/gl-rs.git#230e6c9ed611cddfcb6682dee9686471d54863d0" +dependencies = [ + "gl_common 0.0.3 (git+https://github.com/bjz/gl-rs.git)", + "khronos_api 0.0.5 (git+https://github.com/bjz/gl-rs.git)", + "log 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "xml-rs 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "gl_generator" +version = "0.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gl_common 0.0.1 (git+https://github.com/bjz/gl-rs.git)", - "khronos_api 0.0.2 (git+https://github.com/bjz/gl-rs.git)", - "xml-rs 0.1.3 (git+https://github.com/netvl/xml-rs)", + "gl_common 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "khronos_api 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "xml-rs 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "gleam" version = "0.0.1" -source = "git+https://github.com/servo/gleam#c54eb9ad6d4b62b7effbe9c79a1b3720845b45b4" +source = "git+https://github.com/servo/gleam#375779e0e8e1eaa8ff1a732c81fa91808a7f6c63" dependencies = [ - "gl_generator 0.0.1 (git+https://github.com/bjz/gl-rs.git)", + "gl_common 0.0.3 (git+https://github.com/bjz/gl-rs.git)", + "gl_generator 0.0.12 (git+https://github.com/bjz/gl-rs.git)", ] [[package]] name = "glfw" version = "0.0.1" -source = "git+https://github.com/servo/glfw-rs?ref=servo#b186cb444e349a36b992445dc5cb2c99d38f2a42" +source = "git+https://github.com/servo/glfw-rs?branch=servo#907db700166b48e71d7d59b1eb9964b874c7ca42" dependencies = [ - "glfw-sys 3.0.4 (git+https://github.com/servo/glfw?ref=cargo-3.0.4)", - "semver 0.1.4 (git+https://github.com/rust-lang/semver)", + "glfw-sys 3.0.4 (git+https://github.com/servo/glfw?branch=cargo-3.0.4)", + "log 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "glfw-sys" version = "3.0.4" -source = "git+https://github.com/servo/glfw?ref=cargo-3.0.4#765dace7e4125b87c764f5ac0e7a80eae5c550b2" +source = "git+https://github.com/servo/glfw?branch=cargo-3.0.4#765dace7e4125b87c764f5ac0e7a80eae5c550b2" [[package]] name = "glfw_app" @@ -324,24 +355,26 @@ dependencies = [ "compositing 0.0.1", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gleam 0.0.1 (git+https://github.com/servo/gleam)", - "glfw 0.0.1 (git+https://github.com/servo/glfw-rs?ref=servo)", + "glfw 0.0.1 (git+https://github.com/servo/glfw-rs?branch=servo)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "msg 0.0.1", - "time 0.1.0 (git+https://github.com/rust-lang/time)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "glutin" -version = "0.0.2" -source = "git+https://github.com/servo/glutin?ref=servo#db27370a1cbafcbfcaeee52a44076a61b3e0573c" +version = "0.0.4-pre" +source = "git+https://github.com/tomaka/glutin#1d6b863cd454839b8e3cf1e296cbf8f31fb70029" dependencies = [ - "android_glue 0.0.1 (git+https://github.com/servo/android-rs-glue?ref=servo)", + "android_glue 0.0.1 (git+https://github.com/tomaka/android-rs-glue)", "cocoa 0.1.1 (git+https://github.com/servo/rust-cocoa)", + "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)", - "gl_common 0.0.1 (git+https://github.com/bjz/gl-rs.git)", - "gl_generator 0.0.1 (git+https://github.com/bjz/gl-rs.git)", - "winapi 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "gl_common 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "gl_generator 0.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "khronos_api 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -350,21 +383,23 @@ version = "0.0.1" dependencies = [ "cgl 0.0.1 (git+https://github.com/servo/rust-cgl)", "compositing 0.0.1", + "egl 0.1.0 (git+https://github.com/servo/rust-egl)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gleam 0.0.1 (git+https://github.com/servo/gleam)", - "glutin 0.0.2 (git+https://github.com/servo/glutin?ref=servo)", + "glutin 0.0.4-pre (git+https://github.com/tomaka/glutin)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "msg 0.0.1", - "time 0.1.0 (git+https://github.com/rust-lang/time)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "glx" version = "0.0.1" -source = "git+https://github.com/servo/rust-glx#7126ffa09fcfcc9f85f1406f3b5db729f5fdb7c3" +source = "git+https://github.com/servo/rust-glx#f056a8998987f6f081f9ad7fa396beb1b2988c02" dependencies = [ - "gl_generator 0.0.1 (git+https://github.com/bjz/gl-rs.git)", + "gl_common 0.0.3 (git+https://github.com/bjz/gl-rs.git)", + "gl_generator 0.0.12 (git+https://github.com/bjz/gl-rs.git)", ] [[package]] @@ -375,33 +410,36 @@ source = "git+https://github.com/servo/rust-harfbuzz#59b5b18087418404d661784934c [[package]] name = "html5ever" version = "0.0.0" -source = "git+https://github.com/servo/html5ever#0abe5e30cc03f9e73bfd4fdc018192d149c21fb3" +source = "git+https://github.com/servo/html5ever#d35dfaaf0d85007057a299afc370d07e92538944" dependencies = [ "html5ever_macros 0.0.0 (git+https://github.com/servo/html5ever)", - "phf 0.0.1 (git+https://github.com/sfackler/rust-phf)", - "phf_mac 0.0.1 (git+https://github.com/sfackler/rust-phf)", + "phf 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_mac 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", - "time 0.1.0 (git+https://github.com/rust-lang/time)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "html5ever_macros" version = "0.0.0" -source = "git+https://github.com/servo/html5ever#0abe5e30cc03f9e73bfd4fdc018192d149c21fb3" +source = "git+https://github.com/servo/html5ever#d35dfaaf0d85007057a299afc370d07e92538944" [[package]] name = "hyper" -version = "0.0.1" -source = "git+https://github.com/servo/hyper?ref=servo#43becc919c24939b8b84fe541b0e0898a4827836" +version = "0.1.0" +source = "git+https://github.com/servo/hyper?branch=servo#248a6f29086baa841eb30c88540dca3196accae4" dependencies = [ - "cookie 0.1.0 (git+https://github.com/alexcrichton/cookie-rs)", - "mime 0.0.1 (git+https://github.com/hyperium/mime.rs)", - "mucell 0.1.2 (git+https://github.com/chris-morgan/mucell)", - "openssl 0.2.4 (git+https://github.com/sfackler/rust-openssl)", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "unsafe-any 0.1.1 (git+https://github.com/reem/rust-unsafe-any)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "cookie 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mucell 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unsafe-any 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -418,20 +456,25 @@ dependencies = [ [[package]] name = "js" version = "0.1.0" -source = "git+https://github.com/servo/rust-mozjs#5a69e377d6ab7ea8601f711443994f1c8172c7a8" +source = "git+https://github.com/servo/rust-mozjs#6cabb12f858f27d23fc3d2d9f0c334b80eb56573" dependencies = [ "mozjs-sys 0.0.0 (git+https://github.com/servo/mozjs)", ] [[package]] name = "khronos_api" -version = "0.0.2" -source = "git+https://github.com/bjz/gl-rs.git#b5e3f4f76c31bc1b459d5e4c10d879ffa4f67c6e" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "khronos_api" +version = "0.0.5" +source = "git+https://github.com/bjz/gl-rs.git#230e6c9ed611cddfcb6682dee9686471d54863d0" [[package]] name = "layers" version = "0.1.0" -source = "git+https://github.com/servo/rust-layers#f20270839f8658a2b19eae6fade9325efe5f4578" +source = "git+https://github.com/servo/rust-layers#8dece8325eda4a74816832580e62ebd3afc99dfb" dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", "cgl 0.0.1 (git+https://github.com/servo/rust-cgl)", @@ -448,8 +491,9 @@ dependencies = [ name = "layout" version = "0.0.1" dependencies = [ - "cssparser 0.1.1 (git+https://github.com/servo/rust-cssparser)", - "encoding 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "canvas 0.0.1", + "cssparser 0.2.0 (git+https://github.com/servo/rust-cssparser)", + "encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gfx 0.0.1", "layout_traits 0.0.1", @@ -460,7 +504,7 @@ dependencies = [ "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", "style 0.0.1", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -477,8 +521,8 @@ dependencies = [ [[package]] name = "lazy_static" -version = "0.1.0" -source = "git+https://github.com/Kimundi/lazy-static.rs#76f06e4fa7bc8c92f11d1def19bd4ddfd8017cd8" +version = "0.1.6" +source = "git+https://github.com/Kimundi/lazy-static.rs#31a7aa0176ecd70b4aab274a40d1e2cd78c1fbf8" [[package]] name = "libressl-pnacl-sys" @@ -489,14 +533,30 @@ dependencies = [ ] [[package]] +name = "log" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "regex 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "matches" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "mime" -version = "0.0.1" -source = "git+https://github.com/hyperium/mime.rs#7898f1c29c7f5d35d0c3c7aed37ebcfc95a40873" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "mozjs-sys" version = "0.0.0" -source = "git+https://github.com/servo/mozjs#0335cc57346147851589dea04e85971f064081fd" +source = "git+https://github.com/servo/mozjs#58ee8869c7e589244ab2eb3a3ad15e2b64498428" [[package]] name = "msg" @@ -505,44 +565,44 @@ dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", - "hyper 0.0.1 (git+https://github.com/servo/hyper?ref=servo)", + "hyper 0.1.0 (git+https://github.com/servo/hyper?branch=servo)", "io_surface 0.1.0 (git+https://github.com/servo/rust-io-surface)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "style 0.0.1", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "mucell" -version = "0.1.2" -source = "git+https://github.com/chris-morgan/mucell#d198c6605b3e688719db168db0939051c803b1ea" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "net" version = "0.0.1" dependencies = [ "geom 0.1.0 (git+https://github.com/servo/rust-geom)", - "hyper 0.0.1 (git+https://github.com/servo/hyper?ref=servo)", + "hyper 0.1.0 (git+https://github.com/servo/hyper?branch=servo)", "png 0.1.0 (git+https://github.com/servo/rust-png)", "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "openssl" -version = "0.2.4" -source = "git+https://github.com/sfackler/rust-openssl#f299e336d06a85438c3ee90aa06235510f3f5dbe" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "openssl-sys 0.2.4 (git+https://github.com/sfackler/rust-openssl)", + "openssl-sys 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl-sys" -version = "0.2.4" -source = "git+https://github.com/sfackler/rust-openssl#f299e336d06a85438c3ee90aa06235510f3f5dbe" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libressl-pnacl-sys 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -550,22 +610,26 @@ dependencies = [ [[package]] name = "phf" -version = "0.0.1" -source = "git+https://github.com/sfackler/rust-phf#6a7cc6eb9ec08b103b6b62fa39bdb3229f3cdbe4" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "xxhash 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_shared 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "phf_mac" -version = "0.0.1" -source = "git+https://github.com/sfackler/rust-phf#6a7cc6eb9ec08b103b6b62fa39bdb3229f3cdbe4" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "time 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "xxhash 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_shared 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] +name = "phf_shared" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "pkg-config" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -582,29 +646,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "png" version = "0.1.0" -source = "git+https://github.com/servo/rust-png#cc1976df347bb21ac78c5b37e651b85878855991" +source = "git+https://github.com/servo/rust-png#2804379427ced963466d19132b816bb06a8a4006" dependencies = [ - "gcc 0.1.1 (git+https://github.com/alexcrichton/gcc-rs)", + "gcc 0.1.4 (git+https://github.com/alexcrichton/gcc-rs)", "png-sys 1.6.16 (git+https://github.com/servo/rust-png)", ] [[package]] name = "png-sys" version = "1.6.16" -source = "git+https://github.com/servo/rust-png#cc1976df347bb21ac78c5b37e651b85878855991" +source = "git+https://github.com/servo/rust-png#2804379427ced963466d19132b816bb06a8a4006" + +[[package]] +name = "regex" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc-serialize" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "script" version = "0.0.1" dependencies = [ "canvas 0.0.1", - "cssparser 0.1.1 (git+https://github.com/servo/rust-cssparser)", + "cssparser 0.2.0 (git+https://github.com/servo/rust-cssparser)", "devtools_traits 0.0.1", - "encoding 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gfx 0.0.1", "html5ever 0.0.0 (git+https://github.com/servo/html5ever)", - "hyper 0.0.1 (git+https://github.com/servo/hyper?ref=servo)", + "hyper 0.1.0 (git+https://github.com/servo/hyper?branch=servo)", "js 0.1.0 (git+https://github.com/servo/rust-mozjs)", "msg 0.0.1", "net 0.0.1", @@ -613,10 +687,10 @@ dependencies = [ "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", "style 0.0.1", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", - "uuid 0.1.1 (git+https://github.com/rust-lang/uuid)", + "uuid 0.1.7 (git+https://github.com/rust-lang/uuid)", ] [[package]] @@ -627,19 +701,19 @@ dependencies = [ "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "msg 0.0.1", "net 0.0.1", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "semver" -version = "0.1.4" -source = "git+https://github.com/rust-lang/semver#58dc6b1999d345ca925a2f12a6a84676e823e179" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "skia-sys" version = "0.0.20130412" -source = "git+https://github.com/servo/skia?ref=upstream-2014-06-16#35649d0cddfd89c0bfee0ff558da7291e26d30c3" +source = "git+https://github.com/servo/skia?branch=upstream-2014-06-16#aeb720b947ec463f780a0d00ab8485f902a83986" dependencies = [ "expat-sys 2.1.0 (git+https://github.com/servo/libexpat)", "freetype-sys 2.4.11 (git+https://github.com/servo/libfreetype2)", @@ -648,41 +722,42 @@ dependencies = [ [[package]] name = "stb_image" version = "0.1.0" -source = "git+https://github.com/servo/rust-stb-image#97d7e440e80e41a304647363c322eab68e3700aa" +source = "git+https://github.com/servo/rust-stb-image#2ba03a447b9ef101c25e07bb7f8876416e5fcd71" [[package]] name = "string_cache" version = "0.0.0" -source = "git+https://github.com/servo/string-cache#661c537b85f19ac81dfcd84e28557d480b6b7a9f" +source = "git+https://github.com/servo/string-cache#43a1e5d0d0f2a45e2b96160c8fbe6e1d9602cfa9" dependencies = [ - "lazy_static 0.1.0 (git+https://github.com/Kimundi/lazy-static.rs)", - "phf 0.0.1 (git+https://github.com/sfackler/rust-phf)", - "phf_mac 0.0.1 (git+https://github.com/sfackler/rust-phf)", + "lazy_static 0.1.6 (git+https://github.com/Kimundi/lazy-static.rs)", + "phf 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_mac 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", - "xxhash 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "xxhash 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "string_cache_macros" version = "0.0.0" -source = "git+https://github.com/servo/string-cache#661c537b85f19ac81dfcd84e28557d480b6b7a9f" +source = "git+https://github.com/servo/string-cache#43a1e5d0d0f2a45e2b96160c8fbe6e1d9602cfa9" dependencies = [ - "lazy_static 0.1.0 (git+https://github.com/Kimundi/lazy-static.rs)", + "lazy_static 0.1.6 (git+https://github.com/Kimundi/lazy-static.rs)", ] [[package]] name = "style" version = "0.0.1" dependencies = [ - "cssparser 0.1.1 (git+https://github.com/servo/rust-cssparser)", - "encoding 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.2.0 (git+https://github.com/servo/rust-cssparser)", + "encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", - "lazy_static 0.1.0 (git+https://github.com/Kimundi/lazy-static.rs)", + "lazy_static 0.1.6 (git+https://github.com/Kimundi/lazy-static.rs)", + "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", - "text_writer 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "text_writer 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -692,73 +767,77 @@ version = "0.0.1" [[package]] name = "text_writer" -version = "0.1.4" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "time" -version = "0.1.0" -source = "git+https://github.com/rust-lang/time#afab521f3b91658a3ba2d3e877b7e01699733bef" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.1.1 (git+https://github.com/alexcrichton/gcc-rs)", + "gcc 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "time" -version = "0.1.3" +name = "unicase" +version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "gcc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "unsafe-any" -version = "0.1.1" -source = "git+https://github.com/reem/rust-unsafe-any#eb3fe87bea85f375b8fcefa0cdecfd131fae9624" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "url" -version = "0.2.4" -source = "git+https://github.com/servo/rust-url#79f8034a8e1815ffa1f49204572ddbf6eb747c75" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "util" version = "0.0.1" dependencies = [ - "cssparser 0.1.1 (git+https://github.com/servo/rust-cssparser)", + "cssparser 0.2.0 (git+https://github.com/servo/rust-cssparser)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "plugins 0.0.1", "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", "task_info 0.0.1", - "text_writer 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "text_writer 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "uuid" -version = "0.1.1" -source = "git+https://github.com/rust-lang/uuid#fc793c974a25c126c5cf5daa3b18973512a7a6a0" +version = "0.1.7" +source = "git+https://github.com/rust-lang/uuid#3ea51ffa0682c820e8c8b505de078e3bc93e2cb3" +dependencies = [ + "rustc-serialize 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "winapi" -version = "0.0.2" +version = "0.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "xlib" version = "0.1.0" -source = "git+https://github.com/servo/rust-xlib#58ec3847b592aeabdcfeb6a2d02033d3a2c7f427" +source = "git+https://github.com/servo/rust-xlib#138b0e281b9fd64f7d2e17080fa9a2d4a8554313" [[package]] name = "xml-rs" -version = "0.1.3" -source = "git+https://github.com/netvl/xml-rs#1a812d3ba720afd768bd75d29a5b5f10ddcdfbeb" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "xxhash" -version = "0.0.3" +version = "0.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/components/servo/Cargo.toml b/components/servo/Cargo.toml index f42178bb90f..a99ada57b67 100644 --- a/components/servo/Cargo.toml +++ b/components/servo/Cargo.toml @@ -21,14 +21,19 @@ name = "reftest" path = "../../tests/reftest.rs" harness = false +[dependencies.png] +git = "https://github.com/servo/rust-png" + [[test]] name = "contenttest" path = "../../tests/contenttest.rs" harness = false [features] -default = ["glutin_app"] +default = ["glutin_app", "window"] glfw = ["glfw_app"] +window = ["glutin_app/window"] +headless = ["glutin_app/headless"] [dependencies.compositing] path = "../compositing" @@ -51,6 +56,9 @@ path = "../layout" [dependencies.gfx] path = "../gfx" +[dependencies.devtools] +path = "../devtools" + [dependencies.glfw_app] path = "../../ports/glfw" optional = true @@ -59,8 +67,10 @@ optional = true path = "../../ports/glutin" optional = true -[dependencies.url] -git = "https://github.com/servo/rust-url" +[dependencies.android_glue] +path = "../../support/android-rs-glue/glue" +optional = true -[dependencies.time] -git = "https://github.com/rust-lang/time" +[dependencies] +url = "*" +time = "*" diff --git a/components/servo/lib.rs b/components/servo/lib.rs index c64e7a10fc5..3cc121da0ff 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -2,26 +2,25 @@ * 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/. */ -#![feature(globs, macro_rules, phase, thread_local)] +#![feature(thread_local)] #![deny(unused_imports)] #![deny(unused_variables)] #![allow(missing_copy_implementations)] -#[phase(plugin, link)] +#[macro_use] extern crate log; extern crate compositing; extern crate devtools; extern crate "net" as servo_net; extern crate "msg" as servo_msg; -#[phase(plugin, link)] +#[macro_use] extern crate "util" as servo_util; extern crate script; extern crate layout; extern crate gfx; extern crate libc; -extern crate rustrt; extern crate url; use compositing::CompositorEventListener; @@ -41,7 +40,7 @@ use servo_net::image_cache_task::ImageCacheTask; #[cfg(not(test))] use servo_net::resource_task::new_resource_task; #[cfg(not(test))] -use servo_net::storage_task::StorageTaskFactory; +use servo_net::storage_task::{StorageTaskFactory, StorageTask}; #[cfg(not(test))] use gfx::font_cache_task::FontCacheTask; #[cfg(not(test))] @@ -58,7 +57,9 @@ use std::os; #[cfg(not(test))] use std::rc::Rc; #[cfg(not(test))] -use std::task::TaskBuilder; +use std::sync::mpsc::channel; +#[cfg(not(test))] +use std::thread::Builder; pub struct Browser<Window> { compositor: Box<CompositorEventListener + 'static>, @@ -86,8 +87,8 @@ impl<Window> Browser<Window> where Window: WindowMethods + 'static { let (result_chan, result_port) = channel(); let compositor_proxy_for_constellation = compositor_proxy.clone_compositor_proxy(); - TaskBuilder::new() - .spawn(proc() { + Builder::new() + .spawn(move || { let opts = &opts_clone; // Create a Servo instance. let resource_task = new_resource_task(opts.user_agent.clone()); @@ -100,7 +101,7 @@ impl<Window> Browser<Window> where Window: WindowMethods + 'static { ImageCacheTask::new(resource_task.clone(), shared_task_pool) }; let font_cache_task = FontCacheTask::new(resource_task.clone()); - let storage_task = StorageTaskFactory::new(); + let storage_task: StorageTask = StorageTaskFactory::new(); let constellation_chan = Constellation::<layout::layout_task::LayoutTask, script::script_task::ScriptTask>::start( compositor_proxy_for_constellation, @@ -129,7 +130,7 @@ impl<Window> Browser<Window> where Window: WindowMethods + 'static { result_chan.send(constellation_chan); }); - let constellation_chan = result_port.recv(); + let constellation_chan = result_port.recv().unwrap(); debug!("preparing to enter main loop"); let compositor = CompositorTask::create(window, diff --git a/components/servo/main.rs b/components/servo/main.rs index 81723d64b04..98463ee91a6 100644 --- a/components/servo/main.rs +++ b/components/servo/main.rs @@ -2,8 +2,6 @@ * 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/. */ -#![feature(phase)] - #![deny(unused_imports)] #![deny(unused_variables)] @@ -23,7 +21,7 @@ extern crate "glfw_app" as app; extern crate compositing; #[cfg(target_os="android")] -#[phase(plugin, link)] +#[macro_use] extern crate android_glue; #[cfg(target_os="android")] @@ -32,15 +30,14 @@ use libc::c_int; #[cfg(not(test))] use servo_util::opts; -// FIXME: Find replacement for this post-runtime removal -//#[cfg(not(test))] -//use servo_util::rtinstrument; - #[cfg(not(test))] use servo::Browser; #[cfg(not(test))] use compositing::windowing::WindowEvent; +#[cfg(target_os="android")] +use std::borrow::ToOwned; + #[cfg(not(any(test,target_os="android")))] use std::os; @@ -50,13 +47,13 @@ struct BrowserWrapper { } #[cfg(target_os="android")] -android_start!(main) +android_start!(main); #[cfg(target_os="android")] fn get_args() -> Vec<String> { vec![ - "servo".into_string(), - "http://en.wikipedia.org/wiki/Rust".into_string() + "servo".to_owned(), + "http://en.wikipedia.org/wiki/Rust".to_owned() ] } @@ -66,29 +63,36 @@ fn get_args() -> Vec<String> { } #[cfg(target_os="android")] +struct FilePtr(*mut libc::types::common::c95::FILE); + +#[cfg(target_os="android")] +unsafe impl Send for FilePtr {} + +#[cfg(target_os="android")] fn redirect_output(file_no: c_int) { use libc::funcs::posix88::unistd::{pipe, dup2}; use libc::funcs::posix88::stdio::fdopen; - use libc::c_char; use libc::funcs::c95::stdio::fgets; + use servo_util::task::spawn_named; use std::mem; - use std::c_str::CString; + use std::ffi::CString; + use std::str::from_utf8; unsafe { - let mut pipes: [c_int, ..2] = [ 0, 0 ]; + let mut pipes: [c_int; 2] = [ 0, 0 ]; pipe(pipes.as_mut_ptr()); dup2(pipes[1], file_no); - let input_file = "r".with_c_str(|mode| { - fdopen(pipes[0], mode) - }); - spawn(proc() { + let mode = CString::from_slice("r".as_bytes()); + let input_file = FilePtr(fdopen(pipes[0], mode.as_ptr())); + spawn_named("android-logger".to_owned(), move || { loop { - let mut read_buffer: [c_char, ..1024] = mem::zeroed(); - fgets(read_buffer.as_mut_ptr(), read_buffer.len() as i32, input_file); - let cs = CString::new(read_buffer.as_ptr(), false); - match cs.as_str() { - Some(s) => android_glue::write_log(s), - None => {}, + let mut read_buffer: [u8; 1024] = mem::zeroed(); + let FilePtr(input_file) = input_file; + fgets(read_buffer.as_mut_ptr() as *mut i8, read_buffer.len() as i32, input_file); + let cs = CString::from_slice(&read_buffer); + match from_utf8(cs.as_bytes()) { + Ok(s) => android_glue::write_log(s), + _ => {} } } }); @@ -158,8 +162,6 @@ fn main() { browser } = browser; browser.shutdown(); - - //rtinstrument::teardown(); } } diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml index ec0a3fcc2bb..f5c8bae0939 100644 --- a/components/style/Cargo.toml +++ b/components/style/Cargo.toml @@ -18,9 +18,6 @@ path = "../util" [dependencies.geom] git = "https://github.com/servo/rust-geom" -[dependencies.url] -git = "https://github.com/servo/rust-url" - [dependencies.cssparser] git = "https://github.com/servo/rust-cssparser" @@ -36,3 +33,5 @@ git = "https://github.com/servo/string-cache" [dependencies] text_writer = "0.1.1" encoding = "0.2" +matches = "0.1" +url = "*"
\ No newline at end of file diff --git a/components/style/errors.rs b/components/style/errors.rs deleted file mode 100644 index 1f238aeca4e..00000000000 --- a/components/style/errors.rs +++ /dev/null @@ -1,32 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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 cssparser::ast::{SyntaxError, SourceLocation}; - - -pub struct ErrorLoggerIterator<I>(pub I); - -impl<T, I: Iterator<Result<T, SyntaxError>>> Iterator<T> for ErrorLoggerIterator<I> { - fn next(&mut self) -> Option<T> { - let ErrorLoggerIterator(ref mut this) = *self; - loop { - match this.next() { - Some(Ok(v)) => return Some(v), - Some(Err(error)) => log_css_error(error.location, - format!("{}", error.reason).as_slice()), - None => return None, - } - } - } -} - - -/// Defaults to a no-op. -/// Set a `RUST_LOG=style::errors` environment variable -/// to log CSS parse errors to stderr. -pub fn log_css_error(location: SourceLocation, message: &str) { - // TODO eventually this will got into a "web console" or something. - info!("{}:{} {}", location.line, location.column, message) -} diff --git a/components/style/font_face.rs b/components/style/font_face.rs index 2e06f514510..d4d18f7960b 100644 --- a/components/style/font_face.rs +++ b/components/style/font_face.rs @@ -2,26 +2,25 @@ * 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 cssparser::ast::*; -use cssparser::ast::ComponentValue::*; -use cssparser::parse_declaration_list; -use errors::{ErrorLoggerIterator, log_css_error}; +use cssparser::{Token, Parser, DeclarationListParser, AtRuleParser, DeclarationParser}; use std::ascii::AsciiExt; -use parsing_utils::{BufferedIter, ParserIter, parse_slice_comma_separated}; -use properties::longhands::font_family::parse_one_family; -use properties::computed_values::font_family::FontFamily::FamilyName; use stylesheets::CSSRule; +use properties::longhands::font_family::parse_one_family; +use properties::computed_values::font_family::FontFamily; use media_queries::Device; use url::{Url, UrlParser}; +use parser::ParserContext; -pub fn iter_font_face_rules_inner(rules: &[CSSRule], device: &Device, - callback: |family: &str, source: &Source|) { +pub fn iter_font_face_rules_inner<F>(rules: &[CSSRule], device: &Device, + callback: &F) where F: Fn(&str, &Source) { for rule in rules.iter() { match *rule { - CSSRule::Style(_) => {}, + CSSRule::Style(..) | + CSSRule::Charset(..) | + CSSRule::Namespace(..) => {}, CSSRule::Media(ref rule) => if rule.media_queries.evaluate(device) { - iter_font_face_rules_inner(rule.rules.as_slice(), device, |f, s| callback(f, s)) + iter_font_face_rules_inner(rule.rules.as_slice(), device, callback) }, CSSRule::FontFace(ref rule) => { for source in rule.sources.iter() { @@ -32,102 +31,94 @@ pub fn iter_font_face_rules_inner(rules: &[CSSRule], device: &Device, } } -#[deriving(Clone)] +#[derive(Clone, Show, PartialEq, Eq)] pub enum Source { Url(UrlSource), Local(String), } -#[deriving(Clone)] +#[derive(Clone, Show, PartialEq, Eq)] pub struct UrlSource { pub url: Url, pub format_hints: Vec<String>, } +#[derive(Show, PartialEq, Eq)] pub struct FontFaceRule { pub family: String, pub sources: Vec<Source>, } -pub fn parse_font_face_rule(rule: AtRule, parent_rules: &mut Vec<CSSRule>, base_url: &Url) { - if rule.prelude.as_slice().skip_whitespace().next().is_some() { - log_css_error(rule.location, "@font-face prelude contains unexpected characters"); - return; - } - let block = match rule.block { - Some(block) => block, - None => { - log_css_error(rule.location, "Invalid @font-face rule"); - return - } +pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser) + -> Result<FontFaceRule, ()> { + let parser = FontFaceRuleParser { + context: context, + family: None, + src: None, }; + match DeclarationListParser::new(input, parser).run() { + FontFaceRuleParser { family: Some(family), src: Some(src), .. } => { + Ok(FontFaceRule { + family: family, + sources: src, + }) + } + _ => Err(()) + } +} - let mut maybe_family = None; - let mut maybe_sources = None; - - for item in ErrorLoggerIterator(parse_declaration_list(block.into_iter())) { - match item { - DeclarationListItem::AtRule(rule) => log_css_error( - rule.location, format!("Unsupported at-rule in declaration list: @{}", rule.name).as_slice()), - DeclarationListItem::Declaration(Declaration{ location, name, value, important }) => { - if important { - log_css_error(location, "!important is not allowed on @font-face descriptors"); - continue - } - let name_lower = name.as_slice().to_ascii_lower(); - match name_lower.as_slice() { - "font-family" => { - let iter = &mut BufferedIter::new(value.as_slice().skip_whitespace()); - match parse_one_family(iter) { - Ok(FamilyName(name)) => { - maybe_family = Some(name); - }, - // This also includes generic family names: - _ => log_css_error(location, "Invalid font-family in @font-face"), - } - }, - "src" => { - match parse_slice_comma_separated( - value.as_slice(), |iter| parse_one_src(iter, base_url)) { - Ok(sources) => maybe_sources = Some(sources), - Err(()) => log_css_error(location, "Invalid src in @font-face"), - }; - }, - _ => { - log_css_error(location, format!("Unsupported declaration {}", name).as_slice()); - } - } + +struct FontFaceRuleParser<'a, 'b: 'a> { + context: &'a ParserContext<'b>, + family: Option<String>, + src: Option<Vec<Source>>, +} + + +/// Default methods reject all at rules. +impl<'a, 'b> AtRuleParser<(), ()> for FontFaceRuleParser<'a, 'b> {} + + +impl<'a, 'b> DeclarationParser<()> for FontFaceRuleParser<'a, 'b> { + fn parse_value(&mut self, name: &str, input: &mut Parser) -> Result<(), ()> { + match_ignore_ascii_case! { name, + "font-family" => { + self.family = Some(try!(parse_one_non_generic_family_name(input))); + Ok(()) + }, + "src" => { + self.src = Some(try!(input.parse_comma_separated(|input| { + parse_one_src(self.context, input) + }))); + Ok(()) } + _ => Err(()) } } +} - match (maybe_family, maybe_sources) { - (Some(family), Some(sources)) => parent_rules.push(CSSRule::FontFace(FontFaceRule { - family: family, - sources: sources, - })), - (None, _) => log_css_error(rule.location, "@font-face without a font-family descriptor"), - _ => log_css_error(rule.location, "@font-face without an src descriptor"), +fn parse_one_non_generic_family_name(input: &mut Parser) -> Result<String, ()> { + match parse_one_family(input) { + Ok(FontFamily::FamilyName(name)) => Ok(name), + _ => Err(()) } } -fn parse_one_src(iter: ParserIter, base_url: &Url) -> Result<Source, ()> { - let url = match iter.next() { +fn parse_one_src(context: &ParserContext, input: &mut Parser) -> Result<Source, ()> { + let url = match input.next() { // Parsing url() - Some(&URL(ref url)) => { - UrlParser::new().base_url(base_url).parse(url.as_slice()).unwrap_or_else( + Ok(Token::Url(url)) => { + UrlParser::new().base_url(context.base_url).parse(url.as_slice()).unwrap_or_else( |_error| Url::parse("about:invalid").unwrap()) }, - // Parsing local() with early return() - Some(&Function(ref name, ref arguments)) => { - if name.as_slice().eq_ignore_ascii_case("local") { - let iter = &mut BufferedIter::new(arguments.as_slice().skip_whitespace()); - match parse_one_family(iter) { - Ok(FamilyName(name)) => return Ok(Source::Local(name)), - _ => return Err(()) - } + // Parsing local() with early return + Ok(Token::Function(name)) => { + if name.eq_ignore_ascii_case("local") { + return Ok(Source::Local(try!(input.parse_nested_block(|input| { + parse_one_non_generic_family_name(input) + })))) } return Err(()) }, @@ -135,18 +126,14 @@ fn parse_one_src(iter: ParserIter, base_url: &Url) -> Result<Source, ()> { }; // Parsing optional format() - let format_hints = match iter.next() { - Some(&Function(ref name, ref arguments)) => { - if !name.as_slice().eq_ignore_ascii_case("format") { - return Err(()) - } - try!(parse_slice_comma_separated(arguments.as_slice(), parse_one_format)) - } - Some(component_value) => { - iter.push_back(component_value); - vec![] - } - None => vec![], + let format_hints = if input.try(|input| input.expect_function_matching("format")).is_ok() { + try!(input.parse_nested_block(|input| { + input.parse_comma_separated(|input| { + Ok((try!(input.expect_string())).into_owned()) + }) + })) + } else { + vec![] }; Ok(Source::Url(UrlSource { @@ -154,17 +141,3 @@ fn parse_one_src(iter: ParserIter, base_url: &Url) -> Result<Source, ()> { format_hints: format_hints, })) } - - -fn parse_one_format(iter: ParserIter) -> Result<String, ()> { - match iter.next() { - Some(&QuotedString(ref value)) => { - if iter.next().is_none() { - Ok(value.clone()) - } else { - Err(()) - } - } - _ => Err(()) - } -} diff --git a/components/style/legacy.rs b/components/style/legacy.rs index 19381ebf2e7..95a0f7b6db6 100644 --- a/components/style/legacy.rs +++ b/components/style/legacy.rs @@ -6,10 +6,10 @@ //! `<input size>`, and so forth. use node::{TElement, TElementAttributes, TNode}; -use properties::common_types::specified::CSSColor; +use values::specified::CSSColor; +use values::{CSSFloat, specified}; use properties::DeclaredValue::SpecifiedValue; -use properties::PropertyDeclaration::*; -use properties::{CSSFloat, specified}; +use properties::PropertyDeclaration; use selector_matching::{DeclarationBlock, Stylist}; use cssparser::Color; @@ -18,14 +18,14 @@ use servo_util::smallvec::VecLike; use servo_util::str::LengthOrPercentageOrAuto; /// Legacy presentational attributes that take a length as defined in HTML5 § 2.4.4.4. -#[deriving(Copy, PartialEq, Eq)] +#[derive(Copy, PartialEq, Eq)] pub enum LengthAttribute { /// `<td width>` Width, } /// Legacy presentational attributes that take an integer as defined in HTML5 § 2.4.4.2. -#[deriving(Copy, PartialEq, Eq)] +#[derive(Copy, PartialEq, Eq)] pub enum IntegerAttribute { /// `<input size>` Size, @@ -34,7 +34,7 @@ pub enum IntegerAttribute { } /// Legacy presentational attributes that take a nonnegative integer as defined in HTML5 § 2.4.4.2. -#[deriving(Copy, PartialEq, Eq)] +#[derive(Copy, PartialEq, Eq)] pub enum UnsignedIntegerAttribute { /// `<td border>` Border, @@ -43,7 +43,7 @@ pub enum UnsignedIntegerAttribute { } /// Legacy presentational attributes that take a simple color as defined in HTML5 § 2.4.6. -#[deriving(Copy, PartialEq, Eq)] +#[derive(Copy, PartialEq, Eq)] pub enum SimpleColorAttribute { /// `<body bgcolor>` BgColor, @@ -110,13 +110,13 @@ impl PresentationalHintSynthesis for Stylist { LengthOrPercentageOrAuto::Percentage(percentage) => { let width_value = specified::LengthOrPercentageOrAuto::Percentage(percentage); matching_rules_list.vec_push(DeclarationBlock::from_declaration( - WidthDeclaration(SpecifiedValue(width_value)))); + PropertyDeclaration::Width(SpecifiedValue(width_value)))); *shareable = false } LengthOrPercentageOrAuto::Length(length) => { let width_value = specified::LengthOrPercentageOrAuto::Length(specified::Length::Au(length)); matching_rules_list.vec_push(DeclarationBlock::from_declaration( - WidthDeclaration(SpecifiedValue(width_value)))); + PropertyDeclaration::Width(SpecifiedValue(width_value)))); *shareable = false } } @@ -160,8 +160,8 @@ impl PresentationalHintSynthesis for Stylist { _ => specified::Length::Au(Au::from_px(value as int)), }; matching_rules_list.vec_push(DeclarationBlock::from_declaration( - WidthDeclaration(SpecifiedValue(specified::LengthOrPercentageOrAuto::Length( - value))))); + PropertyDeclaration::Width(SpecifiedValue( + specified::LengthOrPercentageOrAuto::Length(value))))); *shareable = false } Some(_) | None => {} @@ -177,8 +177,8 @@ impl PresentationalHintSynthesis for Stylist { // https://html.spec.whatwg.org/multipage/rendering.html#textarea-effective-width let value = specified::Length::ServoCharacterWidth(value); matching_rules_list.vec_push(DeclarationBlock::from_declaration( - WidthDeclaration(SpecifiedValue(specified::LengthOrPercentageOrAuto::Length( - value))))); + PropertyDeclaration::Width(SpecifiedValue( + specified::LengthOrPercentageOrAuto::Length(value))))); *shareable = false } Some(_) | None => {} @@ -190,8 +190,8 @@ impl PresentationalHintSynthesis for Stylist { // https://html.spec.whatwg.org/multipage/rendering.html#textarea-effective-height let value = specified::Length::Em(value as CSSFloat); matching_rules_list.vec_push(DeclarationBlock::from_declaration( - HeightDeclaration(SpecifiedValue(specified::LengthOrPercentageOrAuto::Length( - value))))); + PropertyDeclaration::Height(SpecifiedValue( + specified::LengthOrPercentageOrAuto::Length(value))))); *shareable = false } Some(_) | None => {} @@ -216,7 +216,8 @@ impl PresentationalHintSynthesis for Stylist { None => {} Some(color) => { matching_rules_list.vec_push(DeclarationBlock::from_declaration( - BackgroundColorDeclaration(SpecifiedValue(CSSColor { parsed: Color::RGBA(color), authored: None })))); + PropertyDeclaration::BackgroundColor(SpecifiedValue( + CSSColor { parsed: Color::RGBA(color), authored: None })))); *shareable = false } } @@ -236,13 +237,13 @@ impl PresentationalHintSynthesis for Stylist { Some(length) => { let width_value = specified::Length::Au(Au::from_px(length as int)); matching_rules_list.vec_push(DeclarationBlock::from_declaration( - BorderTopWidthDeclaration(SpecifiedValue(width_value)))); + PropertyDeclaration::BorderTopWidth(SpecifiedValue(width_value)))); matching_rules_list.vec_push(DeclarationBlock::from_declaration( - BorderLeftWidthDeclaration(SpecifiedValue(width_value)))); + PropertyDeclaration::BorderLeftWidth(SpecifiedValue(width_value)))); matching_rules_list.vec_push(DeclarationBlock::from_declaration( - BorderBottomWidthDeclaration(SpecifiedValue(width_value)))); + PropertyDeclaration::BorderBottomWidth(SpecifiedValue(width_value)))); matching_rules_list.vec_push(DeclarationBlock::from_declaration( - BorderRightWidthDeclaration(SpecifiedValue(width_value)))); + PropertyDeclaration::BorderRightWidth(SpecifiedValue(width_value)))); *shareable = false } } diff --git a/components/style/lib.rs b/components/style/lib.rs index 0c9e0c4c3ed..7a0ffa365d1 100644 --- a/components/style/lib.rs +++ b/components/style/lib.rs @@ -2,15 +2,17 @@ * 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/. */ -#![feature(globs, macro_rules)] +#![feature(plugin)] +#![feature(int_uint)] +#![feature(box_syntax)] #![deny(unused_imports)] #![deny(unused_variables)] #![allow(missing_copy_implementations)] +#![allow(unstable)] -#![feature(phase)] -#[phase(plugin, link)] extern crate log; -#[phase(plugin)] extern crate string_cache_macros; +#[macro_use] extern crate log; +#[no_link] #[macro_use] #[plugin] extern crate string_cache_macros; extern crate collections; extern crate geom; @@ -18,55 +20,56 @@ extern crate serialize; extern crate text_writer; extern crate url; +#[macro_use] extern crate cssparser; -extern crate encoding; -extern crate string_cache; -#[phase(plugin)] -extern crate string_cache_macros; +#[macro_use] +extern crate matches; -#[phase(plugin)] -extern crate plugins; +extern crate encoding; +extern crate string_cache; -#[phase(plugin)] +#[macro_use] extern crate lazy_static; extern crate "util" as servo_util; -// Public API pub use media_queries::{Device, MediaType}; pub use stylesheets::{Stylesheet, iter_font_face_rules}; -pub use selector_matching::{Stylist, StylesheetOrigin}; +pub use selector_matching::{Stylist}; pub use selector_matching::{DeclarationBlock, CommonStyleAffectingAttributes}; pub use selector_matching::{CommonStyleAffectingAttributeInfo, CommonStyleAffectingAttributeMode}; pub use selector_matching::{matches, matches_simple_selector, common_style_affecting_attributes}; pub use selector_matching::{rare_style_affecting_attributes}; pub use selector_matching::{RECOMMENDED_SELECTOR_BLOOM_FILTER_SIZE, SELECTOR_WHITESPACE}; -pub use properties::{cascade, cascade_anonymous, computed, longhands_from_shorthand}; +pub use properties::{cascade, cascade_anonymous, longhands_from_shorthand}; pub use properties::{is_supported_property, make_inline}; -pub use properties::{PropertyDeclaration, ComputedValues, computed_values, style_structs}; +pub use properties::{PropertyDeclaration}; +pub use properties::{computed_values, ComputedValues, style_structs}; pub use properties::{PropertyDeclarationBlock, parse_style_attribute}; // Style attributes -pub use properties::{CSSFloat, DeclaredValue, PropertyDeclarationParseResult}; -pub use properties::{Angle, AngleOrCorner}; -pub use properties::{HorizontalDirection, VerticalDirection}; +pub use properties::{DeclaredValue, PropertyDeclarationParseResult}; +pub use values::CSSFloat; +pub use values::specified::{Angle, AngleOrCorner, HorizontalDirection, VerticalDirection}; +pub use values::computed; pub use node::{TElement, TElementAttributes, TNode}; -pub use selectors::{PseudoElement, ParserContext, SelectorList}; +pub use selectors::{PseudoElement, SelectorList}; pub use selectors::{AttrSelector, NamespaceConstraint}; -pub use selectors::{SimpleSelector, parse_selector_list_from_str}; +pub use selectors::{SimpleSelector, parse_author_origin_selector_list_from_str}; pub use cssparser::{Color, RGBA}; pub use legacy::{IntegerAttribute, LengthAttribute}; pub use legacy::{SimpleColorAttribute, UnsignedIntegerAttribute}; pub use font_face::Source; +pub use stylesheets::Origin as StylesheetOrigin; -mod stylesheets; -mod errors; -mod selectors; -mod selector_matching; -mod properties; -mod namespaces; -mod node; -mod media_queries; -mod parsing_utils; -mod font_face; -mod legacy; +pub mod stylesheets; +pub mod parser; +pub mod selectors; +pub mod selector_matching; +#[macro_use] pub mod values; +pub mod properties; +pub mod namespaces; +pub mod node; +pub mod media_queries; +pub mod font_face; +pub mod legacy; diff --git a/components/style/media_queries.rs b/components/style/media_queries.rs index cf9facf8dcf..324ac1a8ee0 100644 --- a/components/style/media_queries.rs +++ b/components/style/media_queries.rs @@ -3,31 +3,20 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use std::ascii::AsciiExt; -use cssparser::parse_rule_list; -use cssparser::ast::*; -use cssparser::ast::ComponentValue::*; +use cssparser::{Token, Parser, Delimiter}; -use errors::{ErrorLoggerIterator, log_css_error}; use geom::size::TypedSize2D; -use selectors::ParserContext; -use stylesheets::{CSSRule, parse_style_rule, parse_nested_at_rule}; -use namespaces::NamespaceMap; -use parsing_utils::{BufferedIter, ParserIter}; -use properties::common_types::*; use properties::longhands; -use servo_util::geometry::ViewportPx; -use url::Url; +use servo_util::geometry::{Au, ViewportPx}; +use values::{computed, specified}; -pub struct MediaRule { - pub media_queries: MediaQueryList, - pub rules: Vec<CSSRule>, -} +#[derive(Show, PartialEq)] pub struct MediaQueryList { media_queries: Vec<MediaQuery> } -#[deriving(PartialEq, Eq, Copy)] +#[derive(PartialEq, Eq, Copy, Show)] pub enum Range<T> { Min(T), Max(T), @@ -44,17 +33,18 @@ impl<T: Ord> Range<T> { } } -#[deriving(PartialEq, Eq, Copy)] +#[derive(PartialEq, Eq, Copy, Show)] pub enum Expression { Width(Range<Au>), } -#[deriving(PartialEq, Eq, Copy)] +#[derive(PartialEq, Eq, Copy, Show)] pub enum Qualifier { Only, Not, } +#[derive(Show, PartialEq)] pub struct MediaQuery { qualifier: Option<Qualifier>, media_type: MediaQueryType, @@ -72,19 +62,21 @@ impl MediaQuery { } } -#[deriving(PartialEq, Eq, Copy)] +#[derive(PartialEq, Eq, Copy, Show)] pub enum MediaQueryType { All, // Always true MediaType(MediaType), } -#[deriving(PartialEq, Eq, Copy)] +#[derive(PartialEq, Eq, Copy, Show)] pub enum MediaType { Screen, Print, Unknown, } +#[allow(missing_copy_implementations)] +#[derive(Show)] pub struct Device { pub media_type: MediaType, pub viewport_size: TypedSize2D<ViewportPx, f32>, @@ -99,42 +91,9 @@ impl Device { } } -pub fn parse_media_rule(context: &ParserContext, - rule: AtRule, - parent_rules: &mut Vec<CSSRule>, - namespaces: &NamespaceMap, - base_url: &Url) { - let media_queries = parse_media_query_list(rule.prelude.as_slice()); - let block = match rule.block { - Some(block) => block, - None => { - log_css_error(rule.location, "Invalid @media rule"); - return - } - }; - let mut rules = vec!(); - for rule in ErrorLoggerIterator(parse_rule_list(block.into_iter())) { - match rule { - Rule::QualifiedRule(rule) => { - parse_style_rule(context, rule, &mut rules, namespaces, base_url) - } - Rule::AtRule(rule) => parse_nested_at_rule( - context, - rule.name.as_slice().to_ascii_lower().as_slice(), - rule, - &mut rules, - namespaces, - base_url), - } - } - parent_rules.push(CSSRule::Media(MediaRule { - media_queries: media_queries, - rules: rules, - })) -} -fn parse_value_as_length(value: &ComponentValue) -> Result<Au, ()> { - let length = try!(specified::Length::parse_non_negative(value)); +fn parse_non_negative_length(input: &mut Parser) -> Result<Au, ()> { + let length = try!(specified::Length::parse_non_negative(input)); // http://dev.w3.org/csswg/mediaqueries3/ - Section 6 // em units are relative to the initial font-size. @@ -142,154 +101,87 @@ fn parse_value_as_length(value: &ComponentValue) -> Result<Au, ()> { Ok(computed::compute_Au_with_font_size(length, initial_font_size, initial_font_size)) } -fn parse_media_query_expression(iter: ParserIter) -> Result<Expression, ()> { - // Expect a parenthesis block with the condition - match iter.next() { - Some(&ParenthesisBlock(ref block)) => { - let iter = &mut BufferedIter::new(block.as_slice().skip_whitespace()); - - // Parse the variable (e.g. min-width) - let variable = match iter.next() { - Some(&Ident(ref value)) => value, - _ => return Err(()) - }; - - // Ensure a colon follows - match iter.next() { - Some(&Colon) => {}, - _ => return Err(()) - } - - // Retrieve the value - let value = try!(iter.next_as_result()); - // TODO: Handle other media query types - let expression = match variable.as_slice().to_ascii_lower().as_slice() { +impl Expression { + fn parse(input: &mut Parser) -> Result<Expression, ()> { + try!(input.expect_parenthesis_block()); + input.parse_nested_block(|input| { + let name = try!(input.expect_ident()); + try!(input.expect_colon()); + // TODO: Handle other media features + match_ignore_ascii_case! { name, "min-width" => { - let au = try!(parse_value_as_length(value)); - Expression::Width(Range::Min(au)) - } + Ok(Expression::Width(Range::Min(try!(parse_non_negative_length(input))))) + }, "max-width" => { - let au = try!(parse_value_as_length(value)); - Expression::Width(Range::Max(au)) + Ok(Expression::Width(Range::Max(try!(parse_non_negative_length(input))))) } - _ => return Err(()) - }; - - if iter.is_eof() { - Ok(expression) - } else { - Err(()) + _ => Err(()) } - } - _ => Err(()) + }) } } -fn parse_media_query(iter: ParserIter) -> Result<MediaQuery, ()> { - let mut expressions = vec!(); - - // Check for optional 'only' or 'not' - let qualifier = match iter.next() { - Some(&Ident(ref value)) if value.as_slice().to_ascii_lower().as_slice() == "only" => Some(Qualifier::Only), - Some(&Ident(ref value)) if value.as_slice().to_ascii_lower().as_slice() == "not" => Some(Qualifier::Not), - Some(component_value) => { - iter.push_back(component_value); +impl MediaQuery { + fn parse(input: &mut Parser) -> Result<MediaQuery, ()> { + let mut expressions = vec![]; + + let qualifier = if input.try(|input| input.expect_ident_matching("only")).is_ok() { + Some(Qualifier::Only) + } else if input.try(|input| input.expect_ident_matching("not")).is_ok() { + Some(Qualifier::Not) + } else { None - } - None => return Err(()), // Empty queries are invalid - }; + }; - // Check for media type - let media_type = match iter.next() { - Some(&Ident(ref value)) => { - match value.as_slice().to_ascii_lower().as_slice() { + let media_type; + if let Ok(ident) = input.try(|input| input.expect_ident()) { + media_type = match_ignore_ascii_case! { ident, "screen" => MediaQueryType::MediaType(MediaType::Screen), "print" => MediaQueryType::MediaType(MediaType::Print), - "all" => MediaQueryType::All, - _ => MediaQueryType::MediaType(MediaType::Unknown), // Unknown media types never match + "all" => MediaQueryType::All + _ => MediaQueryType::MediaType(MediaType::Unknown) } - } - Some(component_value) => { + } else { // Media type is only optional if qualifier is not specified. if qualifier.is_some() { - return Err(()); + return Err(()) } - iter.push_back(component_value); - - // If no qualifier and media type present, an expression should exist here - let expression = try!(parse_media_query_expression(iter)); - expressions.push(expression); - - MediaQueryType::All + media_type = MediaQueryType::All; + // Without a media type, require at least one expression + expressions.push(try!(Expression::parse(input))); } - None => return Err(()), - }; - // Parse any subsequent expressions - loop { - // Each expression should begin with and - match iter.next() { - Some(&Ident(ref value)) => { - match value.as_slice().to_ascii_lower().as_slice() { - "and" => { - let expression = try!(parse_media_query_expression(iter)); - expressions.push(expression); - } - _ => return Err(()), - } - } - Some(component_value) => { - iter.push_back(component_value); - break; + // Parse any subsequent expressions + loop { + if input.try(|input| input.expect_ident_matching("and")).is_err() { + return Ok(MediaQuery::new(qualifier, media_type, expressions)) } - None => break, + expressions.push(try!(Expression::parse(input))) } } - - Ok(MediaQuery::new(qualifier, media_type, expressions)) } -pub fn parse_media_query_list(input: &[ComponentValue]) -> MediaQueryList { - let iter = &mut BufferedIter::new(input.skip_whitespace()); - let mut media_queries = vec!(); - - if iter.is_eof() { - media_queries.push(MediaQuery::new(None, MediaQueryType::All, vec!())); +pub fn parse_media_query_list(input: &mut Parser) -> MediaQueryList { + let queries = if input.is_exhausted() { + vec![MediaQuery::new(None, MediaQueryType::All, vec!())] } else { + let mut media_queries = vec![]; loop { - // Attempt to parse a media query. - let media_query_result = parse_media_query(iter); - - // Skip until next query or end - let mut trailing_tokens = false; - let mut more_queries = false; - loop { - match iter.next() { - Some(&Comma) => { - more_queries = true; - break; - } - Some(_) => trailing_tokens = true, - None => break, - } - } - - // Add the media query if it was valid and no trailing tokens were found. - // Otherwise, create a 'not all' media query, that will never match. - let media_query = match (media_query_result, trailing_tokens) { - (Ok(media_query), false) => media_query, - _ => MediaQuery::new(Some(Qualifier::Not), MediaQueryType::All, vec!()), - }; - media_queries.push(media_query); - - if !more_queries { - break; + media_queries.push( + input.parse_until_before(Delimiter::Comma, MediaQuery::parse) + .unwrap_or(MediaQuery::new(Some(Qualifier::Not), + MediaQueryType::All, + vec!()))); + match input.next() { + Ok(Token::Comma) => continue, + Ok(_) => unreachable!(), + Err(()) => break, } } - } - - MediaQueryList { media_queries: media_queries } + media_queries + }; + MediaQueryList { media_queries: queries } } impl MediaQueryList { @@ -323,16 +215,16 @@ impl MediaQueryList { #[cfg(test)] mod tests { use geom::size::TypedSize2D; - use properties::common_types::*; + use servo_util::geometry::Au; use stylesheets::{iter_stylesheet_media_rules, iter_stylesheet_style_rules, Stylesheet}; - use selector_matching::StylesheetOrigin; + use stylesheets::Origin; use super::*; use url::Url; + use std::borrow::ToOwned; - fn test_media_rule(css: &str, callback: |&MediaQueryList, &str|) { + fn test_media_rule<F>(css: &str, callback: F) where F: Fn(&MediaQueryList, &str) { let url = Url::parse("http://localhost").unwrap(); - let stylesheet = Stylesheet::from_str(css, url, - StylesheetOrigin::Author); + let stylesheet = Stylesheet::from_str(css, url, Origin::Author); let mut rule_count: int = 0; iter_stylesheet_media_rules(&stylesheet, |rule| { rule_count += 1; @@ -343,155 +235,155 @@ mod tests { fn media_query_test(device: &Device, css: &str, expected_rule_count: int) { let url = Url::parse("http://localhost").unwrap(); - let ss = Stylesheet::from_str(css, url, StylesheetOrigin::Author); + let ss = Stylesheet::from_str(css, url, Origin::Author); let mut rule_count: int = 0; iter_stylesheet_style_rules(&ss, device, |_| rule_count += 1); - assert!(rule_count == expected_rule_count, css.into_string()); + assert!(rule_count == expected_rule_count, css.to_owned()); } #[test] fn test_mq_empty() { test_media_rule("@media { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == None, css.into_string()); - assert!(q.media_type == MediaQueryType::All, css.into_string()); - assert!(q.expressions.len() == 0, css.into_string()); + assert!(q.qualifier == None, css.to_owned()); + assert!(q.media_type == MediaQueryType::All, css.to_owned()); + assert!(q.expressions.len() == 0, css.to_owned()); }); } #[test] fn test_mq_screen() { test_media_rule("@media screen { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == None, css.into_string()); - assert!(q.media_type == MediaQueryType::MediaType(MediaType::Screen), css.into_string()); - assert!(q.expressions.len() == 0, css.into_string()); + assert!(q.qualifier == None, css.to_owned()); + assert!(q.media_type == MediaQueryType::MediaType(MediaType::Screen), css.to_owned()); + assert!(q.expressions.len() == 0, css.to_owned()); }); test_media_rule("@media only screen { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == Some(Qualifier::Only), css.into_string()); - assert!(q.media_type == MediaQueryType::MediaType(MediaType::Screen), css.into_string()); - assert!(q.expressions.len() == 0, css.into_string()); + assert!(q.qualifier == Some(Qualifier::Only), css.to_owned()); + assert!(q.media_type == MediaQueryType::MediaType(MediaType::Screen), css.to_owned()); + assert!(q.expressions.len() == 0, css.to_owned()); }); test_media_rule("@media not screen { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == Some(Qualifier::Not), css.into_string()); - assert!(q.media_type == MediaQueryType::MediaType(MediaType::Screen), css.into_string()); - assert!(q.expressions.len() == 0, css.into_string()); + assert!(q.qualifier == Some(Qualifier::Not), css.to_owned()); + assert!(q.media_type == MediaQueryType::MediaType(MediaType::Screen), css.to_owned()); + assert!(q.expressions.len() == 0, css.to_owned()); }); } #[test] fn test_mq_print() { test_media_rule("@media print { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == None, css.into_string()); - assert!(q.media_type == MediaQueryType::MediaType(MediaType::Print), css.into_string()); - assert!(q.expressions.len() == 0, css.into_string()); + assert!(q.qualifier == None, css.to_owned()); + assert!(q.media_type == MediaQueryType::MediaType(MediaType::Print), css.to_owned()); + assert!(q.expressions.len() == 0, css.to_owned()); }); test_media_rule("@media only print { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == Some(Qualifier::Only), css.into_string()); - assert!(q.media_type == MediaQueryType::MediaType(MediaType::Print), css.into_string()); - assert!(q.expressions.len() == 0, css.into_string()); + assert!(q.qualifier == Some(Qualifier::Only), css.to_owned()); + assert!(q.media_type == MediaQueryType::MediaType(MediaType::Print), css.to_owned()); + assert!(q.expressions.len() == 0, css.to_owned()); }); test_media_rule("@media not print { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == Some(Qualifier::Not), css.into_string()); - assert!(q.media_type == MediaQueryType::MediaType(MediaType::Print), css.into_string()); - assert!(q.expressions.len() == 0, css.into_string()); + assert!(q.qualifier == Some(Qualifier::Not), css.to_owned()); + assert!(q.media_type == MediaQueryType::MediaType(MediaType::Print), css.to_owned()); + assert!(q.expressions.len() == 0, css.to_owned()); }); } #[test] fn test_mq_unknown() { test_media_rule("@media fridge { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == None, css.into_string()); - assert!(q.media_type == MediaQueryType::MediaType(MediaType::Unknown), css.into_string()); - assert!(q.expressions.len() == 0, css.into_string()); + assert!(q.qualifier == None, css.to_owned()); + assert!(q.media_type == MediaQueryType::MediaType(MediaType::Unknown), css.to_owned()); + assert!(q.expressions.len() == 0, css.to_owned()); }); test_media_rule("@media only glass { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == Some(Qualifier::Only), css.into_string()); - assert!(q.media_type == MediaQueryType::MediaType(MediaType::Unknown), css.into_string()); - assert!(q.expressions.len() == 0, css.into_string()); + assert!(q.qualifier == Some(Qualifier::Only), css.to_owned()); + assert!(q.media_type == MediaQueryType::MediaType(MediaType::Unknown), css.to_owned()); + assert!(q.expressions.len() == 0, css.to_owned()); }); test_media_rule("@media not wood { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == Some(Qualifier::Not), css.into_string()); - assert!(q.media_type == MediaQueryType::MediaType(MediaType::Unknown), css.into_string()); - assert!(q.expressions.len() == 0, css.into_string()); + assert!(q.qualifier == Some(Qualifier::Not), css.to_owned()); + assert!(q.media_type == MediaQueryType::MediaType(MediaType::Unknown), css.to_owned()); + assert!(q.expressions.len() == 0, css.to_owned()); }); } #[test] fn test_mq_all() { test_media_rule("@media all { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == None, css.into_string()); - assert!(q.media_type == MediaQueryType::All, css.into_string()); - assert!(q.expressions.len() == 0, css.into_string()); + assert!(q.qualifier == None, css.to_owned()); + assert!(q.media_type == MediaQueryType::All, css.to_owned()); + assert!(q.expressions.len() == 0, css.to_owned()); }); test_media_rule("@media only all { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == Some(Qualifier::Only), css.into_string()); - assert!(q.media_type == MediaQueryType::All, css.into_string()); - assert!(q.expressions.len() == 0, css.into_string()); + assert!(q.qualifier == Some(Qualifier::Only), css.to_owned()); + assert!(q.media_type == MediaQueryType::All, css.to_owned()); + assert!(q.expressions.len() == 0, css.to_owned()); }); test_media_rule("@media not all { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == Some(Qualifier::Not), css.into_string()); - assert!(q.media_type == MediaQueryType::All, css.into_string()); - assert!(q.expressions.len() == 0, css.into_string()); + assert!(q.qualifier == Some(Qualifier::Not), css.to_owned()); + assert!(q.media_type == MediaQueryType::All, css.to_owned()); + assert!(q.expressions.len() == 0, css.to_owned()); }); } #[test] fn test_mq_or() { test_media_rule("@media screen, print { }", |list, css| { - assert!(list.media_queries.len() == 2, css.into_string()); + assert!(list.media_queries.len() == 2, css.to_owned()); let q0 = &list.media_queries[0]; - assert!(q0.qualifier == None, css.into_string()); - assert!(q0.media_type == MediaQueryType::MediaType(MediaType::Screen), css.into_string()); - assert!(q0.expressions.len() == 0, css.into_string()); + assert!(q0.qualifier == None, css.to_owned()); + assert!(q0.media_type == MediaQueryType::MediaType(MediaType::Screen), css.to_owned()); + assert!(q0.expressions.len() == 0, css.to_owned()); let q1 = &list.media_queries[1]; - assert!(q1.qualifier == None, css.into_string()); - assert!(q1.media_type == MediaQueryType::MediaType(MediaType::Print), css.into_string()); - assert!(q1.expressions.len() == 0, css.into_string()); + assert!(q1.qualifier == None, css.to_owned()); + assert!(q1.media_type == MediaQueryType::MediaType(MediaType::Print), css.to_owned()); + assert!(q1.expressions.len() == 0, css.to_owned()); }); } #[test] fn test_mq_default_expressions() { test_media_rule("@media (min-width: 100px) { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == None, css.into_string()); - assert!(q.media_type == MediaQueryType::All, css.into_string()); - assert!(q.expressions.len() == 1, css.into_string()); + assert!(q.qualifier == None, css.to_owned()); + assert!(q.media_type == MediaQueryType::All, css.to_owned()); + assert!(q.expressions.len() == 1, css.to_owned()); match q.expressions[0] { Expression::Width(Range::Min(w)) => assert!(w == Au::from_px(100)), _ => panic!("wrong expression type"), @@ -499,11 +391,11 @@ mod tests { }); test_media_rule("@media (max-width: 43px) { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == None, css.into_string()); - assert!(q.media_type == MediaQueryType::All, css.into_string()); - assert!(q.expressions.len() == 1, css.into_string()); + assert!(q.qualifier == None, css.to_owned()); + assert!(q.media_type == MediaQueryType::All, css.to_owned()); + assert!(q.expressions.len() == 1, css.to_owned()); match q.expressions[0] { Expression::Width(Range::Max(w)) => assert!(w == Au::from_px(43)), _ => panic!("wrong expression type"), @@ -514,11 +406,11 @@ mod tests { #[test] fn test_mq_expressions() { test_media_rule("@media screen and (min-width: 100px) { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == None, css.into_string()); - assert!(q.media_type == MediaQueryType::MediaType(MediaType::Screen), css.into_string()); - assert!(q.expressions.len() == 1, css.into_string()); + assert!(q.qualifier == None, css.to_owned()); + assert!(q.media_type == MediaQueryType::MediaType(MediaType::Screen), css.to_owned()); + assert!(q.expressions.len() == 1, css.to_owned()); match q.expressions[0] { Expression::Width(Range::Min(w)) => assert!(w == Au::from_px(100)), _ => panic!("wrong expression type"), @@ -526,11 +418,11 @@ mod tests { }); test_media_rule("@media print and (max-width: 43px) { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == None, css.into_string()); - assert!(q.media_type == MediaQueryType::MediaType(MediaType::Print), css.into_string()); - assert!(q.expressions.len() == 1, css.into_string()); + assert!(q.qualifier == None, css.to_owned()); + assert!(q.media_type == MediaQueryType::MediaType(MediaType::Print), css.to_owned()); + assert!(q.expressions.len() == 1, css.to_owned()); match q.expressions[0] { Expression::Width(Range::Max(w)) => assert!(w == Au::from_px(43)), _ => panic!("wrong expression type"), @@ -538,11 +430,11 @@ mod tests { }); test_media_rule("@media fridge and (max-width: 52px) { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == None, css.into_string()); - assert!(q.media_type == MediaQueryType::MediaType(MediaType::Unknown), css.into_string()); - assert!(q.expressions.len() == 1, css.into_string()); + assert!(q.qualifier == None, css.to_owned()); + assert!(q.media_type == MediaQueryType::MediaType(MediaType::Unknown), css.to_owned()); + assert!(q.expressions.len() == 1, css.to_owned()); match q.expressions[0] { Expression::Width(Range::Max(w)) => assert!(w == Au::from_px(52)), _ => panic!("wrong expression type"), @@ -553,11 +445,11 @@ mod tests { #[test] fn test_mq_multiple_expressions() { test_media_rule("@media (min-width: 100px) and (max-width: 200px) { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == None, css.into_string()); - assert!(q.media_type == MediaQueryType::All, css.into_string()); - assert!(q.expressions.len() == 2, css.into_string()); + assert!(q.qualifier == None, css.to_owned()); + assert!(q.media_type == MediaQueryType::All, css.to_owned()); + assert!(q.expressions.len() == 2, css.to_owned()); match q.expressions[0] { Expression::Width(Range::Min(w)) => assert!(w == Au::from_px(100)), _ => panic!("wrong expression type"), @@ -569,11 +461,11 @@ mod tests { }); test_media_rule("@media not screen and (min-width: 100px) and (max-width: 200px) { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == Some(Qualifier::Not), css.into_string()); - assert!(q.media_type == MediaQueryType::MediaType(MediaType::Screen), css.into_string()); - assert!(q.expressions.len() == 2, css.into_string()); + assert!(q.qualifier == Some(Qualifier::Not), css.to_owned()); + assert!(q.media_type == MediaQueryType::MediaType(MediaType::Screen), css.to_owned()); + assert!(q.expressions.len() == 2, css.to_owned()); match q.expressions[0] { Expression::Width(Range::Min(w)) => assert!(w == Au::from_px(100)), _ => panic!("wrong expression type"), @@ -588,75 +480,79 @@ mod tests { #[test] fn test_mq_malformed_expressions() { test_media_rule("@media (min-width: 100blah) and (max-width: 200px) { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == Some(Qualifier::Not), css.into_string()); - assert!(q.media_type == MediaQueryType::All, css.into_string()); - assert!(q.expressions.len() == 0, css.into_string()); + assert!(q.qualifier == Some(Qualifier::Not), css.to_owned()); + assert!(q.media_type == MediaQueryType::All, css.to_owned()); + assert!(q.expressions.len() == 0, css.to_owned()); }); test_media_rule("@media screen and (height: 200px) { }", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == Some(Qualifier::Not), css.into_string()); - assert!(q.media_type == MediaQueryType::All, css.into_string()); - assert!(q.expressions.len() == 0, css.into_string()); + assert!(q.qualifier == Some(Qualifier::Not), css.to_owned()); + assert!(q.media_type == MediaQueryType::All, css.to_owned()); + assert!(q.expressions.len() == 0, css.to_owned()); }); test_media_rule("@media (min-width: 30em foo bar) {}", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == Some(Qualifier::Not), css.into_string()); - assert!(q.media_type == MediaQueryType::All, css.into_string()); - assert!(q.expressions.len() == 0, css.into_string()); + assert!(q.qualifier == Some(Qualifier::Not), css.to_owned()); + assert!(q.media_type == MediaQueryType::All, css.to_owned()); + assert!(q.expressions.len() == 0, css.to_owned()); }); test_media_rule("@media not {}", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == Some(Qualifier::Not), css.into_string()); - assert!(q.media_type == MediaQueryType::All, css.into_string()); - assert!(q.expressions.len() == 0, css.into_string()); + assert!(q.qualifier == Some(Qualifier::Not), css.to_owned()); + assert!(q.media_type == MediaQueryType::All, css.to_owned()); + assert!(q.expressions.len() == 0, css.to_owned()); }); test_media_rule("@media not (min-width: 300px) {}", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == Some(Qualifier::Not), css.into_string()); - assert!(q.media_type == MediaQueryType::All, css.into_string()); - assert!(q.expressions.len() == 0, css.into_string()); + assert!(q.qualifier == Some(Qualifier::Not), css.to_owned()); + assert!(q.media_type == MediaQueryType::All, css.to_owned()); + assert!(q.expressions.len() == 0, css.to_owned()); }); test_media_rule("@media , {}", |list, css| { - assert!(list.media_queries.len() == 1, css.into_string()); + assert!(list.media_queries.len() == 2, css.to_owned()); let q = &list.media_queries[0]; - assert!(q.qualifier == Some(Qualifier::Not), css.into_string()); - assert!(q.media_type == MediaQueryType::All, css.into_string()); - assert!(q.expressions.len() == 0, css.into_string()); + assert!(q.qualifier == Some(Qualifier::Not), css.to_owned()); + assert!(q.media_type == MediaQueryType::All, css.to_owned()); + assert!(q.expressions.len() == 0, css.to_owned()); + let q = &list.media_queries[1]; + assert!(q.qualifier == Some(Qualifier::Not), css.to_owned()); + assert!(q.media_type == MediaQueryType::All, css.to_owned()); + assert!(q.expressions.len() == 0, css.to_owned()); }); test_media_rule("@media screen 4px, print {}", |list, css| { - assert!(list.media_queries.len() == 2, css.into_string()); + assert!(list.media_queries.len() == 2, css.to_owned()); let q0 = &list.media_queries[0]; - assert!(q0.qualifier == Some(Qualifier::Not), css.into_string()); - assert!(q0.media_type == MediaQueryType::All, css.into_string()); - assert!(q0.expressions.len() == 0, css.into_string()); + assert!(q0.qualifier == Some(Qualifier::Not), css.to_owned()); + assert!(q0.media_type == MediaQueryType::All, css.to_owned()); + assert!(q0.expressions.len() == 0, css.to_owned()); let q1 = &list.media_queries[1]; - assert!(q1.qualifier == None, css.into_string()); - assert!(q1.media_type == MediaQueryType::MediaType(MediaType::Print), css.into_string()); - assert!(q1.expressions.len() == 0, css.into_string()); + assert!(q1.qualifier == None, css.to_owned()); + assert!(q1.media_type == MediaQueryType::MediaType(MediaType::Print), css.to_owned()); + assert!(q1.expressions.len() == 0, css.to_owned()); }); test_media_rule("@media screen, {}", |list, css| { - assert!(list.media_queries.len() == 2, css.into_string()); + assert!(list.media_queries.len() == 2, css.to_owned()); let q0 = &list.media_queries[0]; - assert!(q0.qualifier == None, css.into_string()); - assert!(q0.media_type == MediaQueryType::MediaType(MediaType::Screen), css.into_string()); - assert!(q0.expressions.len() == 0, css.into_string()); + assert!(q0.qualifier == None, css.to_owned()); + assert!(q0.media_type == MediaQueryType::MediaType(MediaType::Screen), css.to_owned()); + assert!(q0.expressions.len() == 0, css.to_owned()); let q1 = &list.media_queries[1]; - assert!(q1.qualifier == Some(Qualifier::Not), css.into_string()); - assert!(q1.media_type == MediaQueryType::All, css.into_string()); - assert!(q1.expressions.len() == 0, css.into_string()); + assert!(q1.qualifier == Some(Qualifier::Not), css.to_owned()); + assert!(q1.media_type == MediaQueryType::All, css.to_owned()); + assert!(q1.expressions.len() == 0, css.to_owned()); }); } diff --git a/components/style/namespaces.rs b/components/style/namespaces.rs index b1e1df89cd7..53b6467db9c 100644 --- a/components/style/namespaces.rs +++ b/components/style/namespaces.rs @@ -2,13 +2,13 @@ * 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 cssparser::ast::*; -use cssparser::ast::ComponentValue::*; +use cssparser::Parser; use std::collections::HashMap; -use servo_util::namespace; -use errors::log_css_error; -use string_cache::Namespace; +use string_cache::{Atom, Namespace}; +use parser::ParserContext; + +#[derive(Clone)] pub struct NamespaceMap { pub default: Option<Namespace>, pub prefix_map: HashMap<String, Namespace>, @@ -22,45 +22,28 @@ impl NamespaceMap { } -pub fn parse_namespace_rule(rule: AtRule, namespaces: &mut NamespaceMap) { - let location = rule.location; - macro_rules! syntax_error( - () => {{ - log_css_error(location, "Invalid @namespace rule"); - return - }}; - ); - if rule.block.is_some() { syntax_error!() } - let mut prefix: Option<String> = None; - let mut ns: Option<Namespace> = None; - let mut iter = rule.prelude.move_skip_whitespace(); - for component_value in iter { - match component_value { - Ident(value) => { - if prefix.is_some() { syntax_error!() } - prefix = Some(value); - }, - URL(value) | QuotedString(value) => { - if ns.is_some() { syntax_error!() } - ns = Some(namespace::from_domstring(Some(value))); - break - }, - _ => syntax_error!(), +pub fn parse_namespace_rule(context: &mut ParserContext, input: &mut Parser) + -> Result<(Option<String>, Namespace), ()> { + let prefix = input.try(|input| input.expect_ident()).ok().map(|p| p.into_owned()); + let url = try!(input.expect_url_or_string()); + try!(input.expect_exhausted()); + + let namespace = Namespace(Atom::from_slice(url.as_slice())); + let is_duplicate = match prefix { + Some(ref prefix) => { + context.namespaces.prefix_map.insert(prefix.clone(), namespace.clone()).is_some() } - } - if iter.next().is_some() { syntax_error!() } - match (prefix, ns) { - (Some(prefix), Some(ns)) => { - if namespaces.prefix_map.insert(prefix, ns).is_some() { - log_css_error(location, "Duplicate @namespace rule"); + None => { + let has_default = context.namespaces.default.is_some(); + if !has_default { + context.namespaces.default = Some(namespace.clone()); } - }, - (None, Some(ns)) => { - if namespaces.default.is_some() { - log_css_error(location, "Duplicate @namespace rule"); - } - namespaces.default = Some(ns); - }, - _ => syntax_error!() + has_default + } + }; + if is_duplicate { + Err(()) // "Duplicate @namespace rule" + } else { + Ok((prefix, namespace)) } } diff --git a/components/style/node.rs b/components/style/node.rs index 48afb072c43..8bf26b932b3 100644 --- a/components/style/node.rs +++ b/components/style/node.rs @@ -20,7 +20,7 @@ pub trait TNode<'a, E: TElement<'a>> : Clone + Copy { fn is_document(self) -> bool; fn is_element(self) -> bool; fn as_element(self) -> E; - fn match_attr(self, attr: &AttrSelector, test: |&str| -> bool) -> bool; + fn match_attr<F>(self, attr: &AttrSelector, test: F) -> bool where F: Fn(&str) -> bool; fn is_html_element_in_html_document(self) -> bool; fn has_changed(self) -> bool; @@ -55,7 +55,7 @@ pub trait TElement<'a> : Copy { // really messy, since there is a `JSRef` and a `RefCell` involved. Maybe // in the future when we have associated types and/or a more convenient // JS GC story... --pcwalton - fn each_class(self, callback: |&Atom|); + fn each_class<F>(self, callback: F) where F: FnMut(&Atom); } pub trait TElementAttributes : Copy { diff --git a/components/style/parser.rs b/components/style/parser.rs new file mode 100644 index 00000000000..6619ffd06dd --- /dev/null +++ b/components/style/parser.rs @@ -0,0 +1,42 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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 cssparser::{Parser, SourcePosition}; +use url::{Url, UrlParser}; +use log; + +use stylesheets::Origin; +use namespaces::NamespaceMap; + + +pub struct ParserContext<'a> { + pub stylesheet_origin: Origin, + pub base_url: &'a Url, + pub namespaces: NamespaceMap, +} + + +impl<'a> ParserContext<'a> { + pub fn in_user_agent_stylesheet(&self) -> bool { + self.stylesheet_origin == Origin::UserAgent + } + + pub fn parse_url(&self, input: &str) -> Url { + UrlParser::new().base_url(self.base_url).parse(input) + .unwrap_or_else(|_| Url::parse("about:invalid").unwrap()) + } +} + + +/// Defaults to a no-op. +/// Set a `RUST_LOG=style::errors` environment variable +/// to log CSS parse errors to stderr. +pub fn log_css_error(input: &mut Parser, position: SourcePosition, message: &str) { + if log_enabled!(log::INFO) { + let location = input.source_location(position); + // TODO eventually this will got into a "web console" or something. + info!("{}:{} {}", location.line, location.column, message) + } +} diff --git a/components/style/parsing_utils.rs b/components/style/parsing_utils.rs deleted file mode 100644 index 97ebb3cad4d..00000000000 --- a/components/style/parsing_utils.rs +++ /dev/null @@ -1,101 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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 std::ascii::AsciiExt; -use cssparser::ast::{SkipWhitespaceIterable, SkipWhitespaceIterator}; -use cssparser::ast::ComponentValue::{mod, Ident, Comma}; - - -pub fn one_component_value<'a>(input: &'a [ComponentValue]) -> Result<&'a ComponentValue, ()> { - let mut iter = input.skip_whitespace(); - match iter.next() { - Some(value) => if iter.next().is_none() { Ok(value) } else { Err(()) }, - None => Err(()) - } -} - - -pub fn get_ident_lower(component_value: &ComponentValue) -> Result<String, ()> { - match component_value { - &Ident(ref value) => Ok(value.as_slice().to_ascii_lower()), - _ => Err(()), - } -} - - -pub struct BufferedIter<E, I> { - iter: I, - buffer: Option<E>, -} - -impl<E, I: Iterator<E>> BufferedIter<E, I> { - pub fn new(iter: I) -> BufferedIter<E, I> { - BufferedIter { - iter: iter, - buffer: None, - } - } - - #[inline] - pub fn push_back(&mut self, value: E) { - assert!(self.buffer.is_none()); - self.buffer = Some(value); - } - - #[inline] - pub fn is_eof(&mut self) -> bool { - match self.next() { - Some(value) => { - self.push_back(value); - false - } - None => true - } - } - - #[inline] - pub fn next_as_result(&mut self) -> Result<E, ()> { - match self.next() { - Some(value) => Ok(value), - None => Err(()), - } - } -} - -impl<E, I: Iterator<E>> Iterator<E> for BufferedIter<E, I> { - #[inline] - fn next(&mut self) -> Option<E> { - if self.buffer.is_some() { - self.buffer.take() - } - else { - self.iter.next() - } - } -} - -pub type ParserIter<'a, 'b> = &'a mut BufferedIter<&'b ComponentValue, SkipWhitespaceIterator<'b>>; - - -#[inline] -pub fn parse_slice_comma_separated<T>(input: &[ComponentValue], - parse_one: |ParserIter| -> Result<T, ()>) - -> Result<Vec<T>, ()> { - parse_comma_separated(&mut BufferedIter::new(input.skip_whitespace()), parse_one) -} - -#[inline] -pub fn parse_comma_separated<T>(iter: ParserIter, - parse_one: |ParserIter| -> Result<T, ()>) - -> Result<Vec<T>, ()> { - let mut values = vec![try!(parse_one(iter))]; - loop { - match iter.next() { - Some(&Comma) => values.push(try!(parse_one(iter))), - Some(_) => return Err(()), - None => return Ok(values), - } - } -} diff --git a/components/style/properties/mod.rs.mako b/components/style/properties/mod.rs.mako index 5f800fd07e3..c4833972501 100644 --- a/components/style/properties/mod.rs.mako +++ b/components/style/properties/mod.rs.mako @@ -4,29 +4,27 @@ // This file is a Mako template: http://www.makotemplates.org/ -pub use std::ascii::AsciiExt; +use std::ascii::AsciiExt; +use std::borrow::ToOwned; use std::fmt; use std::fmt::Show; use std::sync::Arc; use servo_util::logical_geometry::{WritingMode, LogicalMargin}; -pub use url::Url; - -pub use cssparser::*; -pub use cssparser::ast::*; -pub use cssparser::ast::ComponentValue::*; -pub use geom::SideOffsets2D; -pub use self::common_types::specified::{Angle, AngleOrCorner}; -pub use self::common_types::specified::{HorizontalDirection, VerticalDirection}; - -use errors::{ErrorLoggerIterator, log_css_error}; -pub use parsing_utils::*; -pub use self::common_types::*; +use servo_util::geometry::Au; +use url::Url; +use cssparser::{Parser, Color, RGBA, AtRuleParser, DeclarationParser, + DeclarationListParser, parse_important}; +use geom::SideOffsets2D; + +use values::specified::BorderStyle; +use values::computed; use selector_matching::DeclarationBlock; +use parser::ParserContext; +use namespaces::NamespaceMap; +use stylesheets::Origin; - -pub use self::property_bit_field::PropertyBitField; -pub mod common_types; +use self::property_bit_field::PropertyBitField; <%! @@ -95,14 +93,13 @@ def switch_to_style_struct(name): %> pub mod longhands { - pub use super::*; - pub use std; + use values::computed; pub fn computed_as_specified<T>(value: T, _context: &computed::Context) -> T { value } - <%def name="raw_longhand(name, no_super=False, derived_from=None, experimental=False)"> + <%def name="raw_longhand(name, derived_from=None, experimental=False)"> <% if derived_from is not None: derived_from = derived_from.split() @@ -117,51 +114,44 @@ pub mod longhands { DERIVED_LONGHANDS.setdefault(name, []).append(property) %> pub mod ${property.ident} { - % if not no_super: - use super::*; + % if derived_from is None: + use cssparser::Parser; + use parser::ParserContext; + use properties::{CSSWideKeyword, DeclaredValue}; % endif - pub use self::computed_value::*; + #[allow(unused_imports)] + use values::{computed, specified}; ${caller.body()} % if derived_from is None: - pub fn parse_declared(input: &[ComponentValue], base_url: &Url) + pub fn parse_declared(context: &ParserContext, input: &mut Parser) -> Result<DeclaredValue<SpecifiedValue>, ()> { - match CSSWideKeyword::parse(input) { + match input.try(CSSWideKeyword::parse) { Ok(CSSWideKeyword::InheritKeyword) => Ok(DeclaredValue::Inherit), Ok(CSSWideKeyword::InitialKeyword) => Ok(DeclaredValue::Initial), Ok(CSSWideKeyword::UnsetKeyword) => Ok(DeclaredValue::${ "Inherit" if THIS_STYLE_STRUCT.inherited else "Initial"}), - Err(()) => parse_specified(input, base_url), + Err(()) => parse_specified(context, input), } } % endif } </%def> - <%def name="longhand(name, no_super=False, derived_from=None, experimental=False)"> + <%def name="longhand(name, derived_from=None, experimental=False)"> <%self:raw_longhand name="${name}" derived_from="${derived_from}" - experimental="${experimental}" no_super="${no_super}"> + experimental="${experimental}"> ${caller.body()} % if derived_from is None: - pub fn parse_specified(_input: &[ComponentValue], _base_url: &Url) + pub fn parse_specified(context: &ParserContext, input: &mut Parser) -> Result<DeclaredValue<SpecifiedValue>, ()> { - parse(_input, _base_url).map(super::DeclaredValue::SpecifiedValue) + parse(context, input).map(DeclaredValue::SpecifiedValue) } % endif </%self:raw_longhand> </%def> - <%def name="single_component_value(name, derived_from=None, experimental=False)"> - <%self:longhand name="${name}" derived_from="${derived_from}" - experimental="${experimental}"> - ${caller.body()} - pub fn parse(input: &[ComponentValue], base_url: &Url) -> Result<SpecifiedValue, ()> { - one_component_value(input).and_then(|c| from_component_value(c, base_url)) - } - </%self:longhand> - </%def> - <%def name="single_keyword_computed(name, values, experimental=False)"> - <%self:single_component_value name="${name}" experimental="${experimental}"> + <%self:longhand name="${name}" experimental="${experimental}"> pub use self::computed_value::T as SpecifiedValue; ${caller.body()} pub mod computed_value { @@ -172,13 +162,13 @@ pub mod longhands { } } #[inline] pub fn get_initial_value() -> computed_value::T { - T::${to_rust_ident(values.split()[0])} + computed_value::T::${to_rust_ident(values.split()[0])} } - pub fn from_component_value(v: &ComponentValue, _base_url: &Url) - -> Result<SpecifiedValue, ()> { - computed_value::T::parse(v) + pub fn parse(_context: &ParserContext, input: &mut Parser) + -> Result<SpecifiedValue, ()> { + computed_value::T::parse(input) } - </%self:single_component_value> + </%self:longhand> </%def> <%def name="single_keyword(name, values, experimental=False)"> @@ -191,18 +181,20 @@ pub mod longhands { </%def> <%def name="predefined_type(name, type, initial_value, parse_method='parse')"> - <%self:single_component_value name="${name}"> - pub use super::super::common_types::computed::compute_${type} as to_computed_value; + <%self:longhand name="${name}"> + #[allow(unused_imports)] + use servo_util::geometry::Au; + pub use values::computed::compute_${type} as to_computed_value; pub type SpecifiedValue = specified::${type}; pub mod computed_value { - pub type T = super::super::computed::${type}; + pub use values::computed::${type} as T; } #[inline] pub fn get_initial_value() -> computed_value::T { ${initial_value} } - #[inline] pub fn from_component_value(v: &ComponentValue, _base_url: &Url) - -> Result<SpecifiedValue, ()> { - specified::${type}::${parse_method}(v) + #[inline] pub fn parse(_context: &ParserContext, input: &mut Parser) + -> Result<SpecifiedValue, ()> { + specified::${type}::${parse_method}(input) } - </%self:single_component_value> + </%self:longhand> </%def> @@ -226,48 +218,29 @@ pub mod longhands { ${new_style_struct("Border", is_inherited=False)} % for side in ["top", "right", "bottom", "left"]: - ${predefined_type("border-%s-color" % side, "CSSColor", "super::super::computed::CSSColor::CurrentColor")} + ${predefined_type("border-%s-color" % side, "CSSColor", "::cssparser::Color::CurrentColor")} % endfor - ${single_keyword("border-top-style", values="none solid double dotted dashed hidden groove ridge inset outset")} - - % for side in ["right", "bottom", "left"]: - <%self:longhand name="border-${side}-style"> - pub use super::border_top_style::{get_initial_value, parse, to_computed_value}; - pub type SpecifiedValue = super::border_top_style::SpecifiedValue; - pub mod computed_value { - pub type T = super::super::border_top_style::computed_value::T; - } - </%self:longhand> + % for side in ["top", "right", "bottom", "left"]: + ${predefined_type("border-%s-style" % side, "BorderStyle", "computed::BorderStyle::none")} % endfor - pub fn parse_border_width(component_value: &ComponentValue, _base_url: &Url) - -> Result<specified::Length, ()> { - match component_value { - &Ident(ref value) => { - match value.as_slice().to_ascii_lower().as_slice() { - "thin" => Ok(specified::Length::from_px(1.)), - "medium" => Ok(specified::Length::from_px(3.)), - "thick" => Ok(specified::Length::from_px(5.)), - _ => Err(()) - } - }, - _ => specified::Length::parse_non_negative(component_value) - } - } % for side in ["top", "right", "bottom", "left"]: <%self:longhand name="border-${side}-width"> + use servo_util::geometry::Au; + #[inline] + pub fn parse(_context: &ParserContext, input: &mut Parser) + -> Result<SpecifiedValue, ()> { + specified::parse_border_width(input) + } pub type SpecifiedValue = specified::Length; pub mod computed_value { - use super::super::Au; + use servo_util::geometry::Au; pub type T = Au; } #[inline] pub fn get_initial_value() -> computed_value::T { Au::from_px(3) // medium } - pub fn parse(input: &[ComponentValue], base_url: &Url) -> Result<SpecifiedValue, ()> { - one_component_value(input).and_then(|c| parse_border_width(c, base_url)) - } #[inline] pub fn to_computed_value(value: SpecifiedValue, context: &computed::Context) -> computed_value::T { @@ -280,106 +253,39 @@ pub mod longhands { </%self:longhand> % endfor - <%self:longhand name="border-top-left-radius"> - #[deriving(Clone, Show, PartialEq, Copy)] - pub struct SpecifiedValue { - pub radius: specified::LengthOrPercentage, - } - - pub mod computed_value { - use super::super::computed; - - #[deriving(Clone, PartialEq, Copy, Show)] - pub struct T { - pub radius: computed::LengthOrPercentage, - } - } - - #[inline] - pub fn get_initial_value() -> computed_value::T { - computed_value::T { - radius: computed::LengthOrPercentage::Length(Au(0)), - } - } - #[inline] - pub fn to_computed_value(value: SpecifiedValue, context: &computed::Context) - -> computed_value::T { - computed_value::T { - radius: computed::compute_LengthOrPercentage(value.radius, context), - } - } - - pub fn parse(input: &[ComponentValue], _: &Url) -> Result<SpecifiedValue,()> { - let mut iter = input.skip_whitespace(); - - let radius = match iter.next() { - None => return Err(()), - Some(cv) => cv, - }; - - let radius = try!(specified::LengthOrPercentage::parse(radius)); - - if iter.next().is_some() { return Err(()); } - - Ok(SpecifiedValue { - radius: radius, - }) - } - </%self:longhand> - - % for corner in ["top-right", "bottom-right", "bottom-left"]: - <%self:longhand name="border-${corner}-radius"> - pub type SpecifiedValue = super::border_top_left_radius::SpecifiedValue; - - pub mod computed_value { - pub type T = super::super::border_top_left_radius::computed_value::T; - } - - #[inline] - pub fn get_initial_value() -> computed_value::T { - super::border_top_left_radius::get_initial_value() - } - #[inline] - pub fn to_computed_value(value: SpecifiedValue, context: &computed::Context) - -> computed_value::T { - super::border_top_left_radius::to_computed_value(value, context) - } - - pub fn parse(input: &[ComponentValue], u: &Url) -> Result<SpecifiedValue,()> { - super::border_top_left_radius::parse(input, u) - } - </%self:longhand> + // FIXME(#4126): when gfx supports painting it, make this Size2D<LengthOrPercentage> + % for corner in ["top-left", "top-right", "bottom-right", "bottom-left"]: + ${predefined_type("border-" + corner + "-radius", "LengthOrPercentage", + "computed::LengthOrPercentage::Length(Au(0))", + "parse_non_negative")} % endfor ${new_style_struct("Outline", is_inherited=False)} // TODO(pcwalton): `invert` - ${predefined_type("outline-color", "CSSColor", "super::super::computed::CSSColor::CurrentColor")} + ${predefined_type("outline-color", "CSSColor", "::cssparser::Color::CurrentColor")} - <%self:single_component_value name="outline-style"> - pub use super::border_top_style::{get_initial_value, to_computed_value}; - pub type SpecifiedValue = super::border_top_style::SpecifiedValue; + <%self:longhand name="outline-style"> + pub use values::specified::BorderStyle as SpecifiedValue; + pub use super::computed_as_specified as to_computed_value; + pub fn get_initial_value() -> SpecifiedValue { SpecifiedValue::none } pub mod computed_value { - pub type T = super::super::border_top_style::computed_value::T; + pub use values::specified::BorderStyle as T; } - pub fn from_component_value(value: &ComponentValue, base_url: &Url) - -> Result<SpecifiedValue,()> { - match value { - &Ident(ref ident) if ident.eq_ignore_ascii_case("hidden") => { - // `hidden` is not a valid value. - Err(()) - } - _ => super::border_top_style::from_component_value(value, base_url) + pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { + match SpecifiedValue::parse(input) { + Ok(SpecifiedValue::hidden) => Err(()), + result => result } } - </%self:single_component_value> + </%self:longhand> <%self:longhand name="outline-width"> pub use super::border_top_width::{get_initial_value, parse}; - pub use computed::compute_Au as to_computed_value; + pub use values::computed::compute_Au as to_computed_value; pub type SpecifiedValue = super::border_top_width::SpecifiedValue; pub mod computed_value { - pub type T = super::super::border_top_width::computed_value::T; + pub use servo_util::geometry::Au as T; } </%self:longhand> @@ -406,6 +312,7 @@ pub mod longhands { #[inline] pub fn to_computed_value(value: SpecifiedValue, context: &computed::Context) -> computed_value::T { + use self::computed_value::T; // if context.is_root_element && value == list_item { // return block // } @@ -430,32 +337,31 @@ pub mod longhands { ${single_keyword("float", "none left right")} ${single_keyword("clear", "none left right both")} - <%self:longhand name="-servo-display-for-hypothetical-box" derived_from="display" no_super="True"> + <%self:longhand name="-servo-display-for-hypothetical-box" derived_from="display"> pub use super::computed_as_specified as to_computed_value; pub use super::display::{SpecifiedValue, get_initial_value}; pub use super::display::{parse}; - use super::computed; - use super::display; pub mod computed_value { pub type T = super::SpecifiedValue; } #[inline] - pub fn derive_from_display(_: display::computed_value::T, context: &computed::Context) + pub fn derive_from_display(_: super::display::computed_value::T, + context: &computed::Context) -> computed_value::T { context.display } </%self:longhand> - <%self:single_component_value name="z-index"> + <%self:longhand name="z-index"> pub use super::computed_as_specified as to_computed_value; pub type SpecifiedValue = computed_value::T; pub mod computed_value { use std::fmt; - #[deriving(PartialEq, Clone, Eq, Copy)] + #[derive(PartialEq, Clone, Eq, Copy)] pub enum T { Auto, Number(i32), @@ -480,19 +386,16 @@ pub mod longhands { } #[inline] pub fn get_initial_value() -> computed_value::T { - T::Auto - } - fn from_component_value(input: &ComponentValue, _: &Url) -> Result<SpecifiedValue,()> { - match *input { - Ident(ref keyword) if keyword.as_slice().eq_ignore_ascii_case("auto") => Ok(T::Auto), - Number(NumericValue { - int_value: Some(value), - .. - }) => Ok(T::Number(value as i32)), - _ => Err(()) + computed_value::T::Auto + } + fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { + if input.try(|input| input.expect_ident_matching("auto")).is_ok() { + Ok(computed_value::T::Auto) + } else { + Ok(computed_value::T::Number(try!(input.expect_integer()) as i32)) } } - </%self:single_component_value> + </%self:longhand> ${new_style_struct("InheritedBox", is_inherited=True)} @@ -505,29 +408,29 @@ pub mod longhands { ${predefined_type("width", "LengthOrPercentageOrAuto", "computed::LengthOrPercentageOrAuto::Auto", "parse_non_negative")} - <%self:single_component_value name="height"> + <%self:longhand name="height"> pub type SpecifiedValue = specified::LengthOrPercentageOrAuto; pub mod computed_value { - pub type T = super::super::computed::LengthOrPercentageOrAuto; + pub use values::computed::LengthOrPercentageOrAuto as T; } #[inline] pub fn get_initial_value() -> computed_value::T { computed::LengthOrPercentageOrAuto::Auto } #[inline] - pub fn from_component_value(v: &ComponentValue, _base_url: &Url) - -> Result<SpecifiedValue, ()> { - specified::LengthOrPercentageOrAuto::parse_non_negative(v) + pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { + specified::LengthOrPercentageOrAuto::parse_non_negative(input) } pub fn to_computed_value(value: SpecifiedValue, context: &computed::Context) -> computed_value::T { match (value, context.inherited_height) { - (specified::LengthOrPercentageOrAuto::Percentage(_), computed::LengthOrPercentageOrAuto::Auto) + (specified::LengthOrPercentageOrAuto::Percentage(_), + computed::LengthOrPercentageOrAuto::Auto) if !context.is_root_element && !context.positioned => { computed::LengthOrPercentageOrAuto::Auto }, _ => computed::compute_LengthOrPercentageOrAuto(value, context) } } - </%self:single_component_value> + </%self:longhand> ${predefined_type("min-width", "LengthOrPercentage", "computed::LengthOrPercentage::Length(Au(0))", @@ -545,9 +448,10 @@ pub mod longhands { ${switch_to_style_struct("InheritedBox")} - <%self:single_component_value name="line-height"> + <%self:longhand name="line-height"> use std::fmt; - #[deriving(Clone, PartialEq, Copy)] + use values::CSSFloat; + #[derive(Clone, PartialEq, Copy)] pub enum SpecifiedValue { Normal, Length(specified::Length), @@ -558,32 +462,38 @@ pub mod longhands { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &SpecifiedValue::Normal => write!(f, "normal"), - &SpecifiedValue::Length(length) => write!(f, "{}", length), + &SpecifiedValue::Length(length) => write!(f, "{:?}", length), &SpecifiedValue::Number(number) => write!(f, "{}", number), &SpecifiedValue::Percentage(number) => write!(f, "{}%", number * 100.), } } } /// normal | <number> | <length> | <percentage> - pub fn from_component_value(input: &ComponentValue, _base_url: &Url) - -> Result<SpecifiedValue, ()> { - match input { - &Number(ref value) if value.value >= 0. => - Ok(SpecifiedValue::Number(value.value)), - &Percentage(ref value) if value.value >= 0. => - Ok(SpecifiedValue::Percentage(value.value / 100.)), - &Dimension(ref value, ref unit) if value.value >= 0. => + pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { + use std::ascii::AsciiExt; + use cssparser::Token; + match try!(input.next()) { + Token::Number(ref value) if value.value >= 0. => { + Ok(SpecifiedValue::Number(value.value)) + } + Token::Percentage(ref value) if value.unit_value >= 0. => { + Ok(SpecifiedValue::Percentage(value.unit_value)) + } + Token::Dimension(ref value, ref unit) if value.value >= 0. => { specified::Length::parse_dimension(value.value, unit.as_slice()) - .map(SpecifiedValue::Length), - &Ident(ref value) if value.as_slice().eq_ignore_ascii_case("normal") => - Ok(SpecifiedValue::Normal), + .map(SpecifiedValue::Length) + } + Token::Ident(ref value) if value.as_slice().eq_ignore_ascii_case("normal") => { + Ok(SpecifiedValue::Normal) + } _ => Err(()), } } pub mod computed_value { - use super::super::{Au, CSSFloat}; + use values::CSSFloat; + use servo_util::geometry::Au; use std::fmt; - #[deriving(PartialEq, Copy, Clone)] + #[derive(PartialEq, Copy, Clone)] pub enum T { Normal, Length(Au), @@ -593,34 +503,39 @@ pub mod longhands { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &T::Normal => write!(f, "normal"), - &T::Length(length) => write!(f, "{}%", length), + &T::Length(length) => write!(f, "{:?}%", length), &T::Number(number) => write!(f, "{}", number), } } } } #[inline] - pub fn get_initial_value() -> computed_value::T { T::Normal } + pub fn get_initial_value() -> computed_value::T { computed_value::T::Normal } #[inline] pub fn to_computed_value(value: SpecifiedValue, context: &computed::Context) -> computed_value::T { match value { - SpecifiedValue::Normal => T::Normal, - SpecifiedValue::Length(value) => T::Length(computed::compute_Au(value, context)), - SpecifiedValue::Number(value) => T::Number(value), - SpecifiedValue::Percentage(value) => T::Length(computed::compute_Au(specified::Length::Em(value), context)), + SpecifiedValue::Normal => computed_value::T::Normal, + SpecifiedValue::Length(value) => { + computed_value::T::Length(computed::compute_Au(value, context)) + } + SpecifiedValue::Number(value) => computed_value::T::Number(value), + SpecifiedValue::Percentage(value) => { + computed_value::T::Length(computed::compute_Au( + specified::Length::Em(value), context)) + } } } - </%self:single_component_value> + </%self:longhand> ${switch_to_style_struct("Box")} - <%self:single_component_value name="vertical-align"> + <%self:longhand name="vertical-align"> use std::fmt; <% vertical_align_keywords = ( "baseline sub super top text-top middle bottom text-bottom".split()) %> #[allow(non_camel_case_types)] - #[deriving(Clone, PartialEq, Copy)] + #[derive(Clone, PartialEq, Copy)] pub enum SpecifiedValue { % for keyword in vertical_align_keywords: ${to_rust_ident(keyword)}, @@ -633,32 +548,35 @@ pub mod longhands { % for keyword in vertical_align_keywords: &SpecifiedValue::${to_rust_ident(keyword)} => write!(f, "${keyword}"), % endfor - &SpecifiedValue::LengthOrPercentage(lop) => write!(f, "{}", lop), + &SpecifiedValue::LengthOrPercentage(lop) => write!(f, "{:?}", lop), } } } /// baseline | sub | super | top | text-top | middle | bottom | text-bottom /// | <percentage> | <length> - pub fn from_component_value(input: &ComponentValue, _base_url: &Url) - -> Result<SpecifiedValue, ()> { - match input { - &Ident(ref value) => { - match value.as_slice().to_ascii_lower().as_slice() { - % for keyword in vertical_align_keywords: + pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { + input.try(specified::LengthOrPercentage::parse_non_negative) + .map(SpecifiedValue::LengthOrPercentage) + .or_else(|()| { + match_ignore_ascii_case! { try!(input.expect_ident()), + % for keyword in vertical_align_keywords[:-1]: "${keyword}" => Ok(SpecifiedValue::${to_rust_ident(keyword)}), - % endfor - _ => Err(()), - } - }, - _ => specified::LengthOrPercentage::parse_non_negative(input) - .map(SpecifiedValue::LengthOrPercentage) - } + % endfor + + // Hack to work around quirks of macro_rules parsing in match_ignore_ascii_case! + % for keyword in vertical_align_keywords[-1:]: + "${keyword}" => Ok(SpecifiedValue::${to_rust_ident(keyword)}) + % endfor + _ => Err(()) + } + }) } pub mod computed_value { - use super::super::{Au, CSSFloat}; + use values::CSSFloat; + use servo_util::geometry::Au; use std::fmt; #[allow(non_camel_case_types)] - #[deriving(PartialEq, Copy, Clone)] + #[derive(PartialEq, Copy, Clone)] pub enum T { % for keyword in vertical_align_keywords: ${to_rust_ident(keyword)}, @@ -672,29 +590,36 @@ pub mod longhands { % for keyword in vertical_align_keywords: &T::${to_rust_ident(keyword)} => write!(f, "${keyword}"), % endfor - &T::Length(length) => write!(f, "{}", length), + &T::Length(length) => write!(f, "{:?}", length), &T::Percentage(number) => write!(f, "{}%", number), } } } } #[inline] - pub fn get_initial_value() -> computed_value::T { T::baseline } + pub fn get_initial_value() -> computed_value::T { computed_value::T::baseline } #[inline] pub fn to_computed_value(value: SpecifiedValue, context: &computed::Context) -> computed_value::T { match value { % for keyword in vertical_align_keywords: - SpecifiedValue::${to_rust_ident(keyword)} => computed_value::T::${to_rust_ident(keyword)}, + SpecifiedValue::${to_rust_ident(keyword)} => { + computed_value::T::${to_rust_ident(keyword)} + } % endfor - SpecifiedValue::LengthOrPercentage(value) - => match computed::compute_LengthOrPercentage(value, context) { - computed::LengthOrPercentage::Length(value) => T::Length(value), - computed::LengthOrPercentage::Percentage(value) => T::Percentage(value) + SpecifiedValue::LengthOrPercentage(value) => { + match computed::compute_LengthOrPercentage(value, context) { + computed::LengthOrPercentage::Length(value) => { + computed_value::T::Length(value) + } + computed::LengthOrPercentage::Percentage(value) => { + computed_value::T::Percentage(value) + } + } } } } - </%self:single_component_value> + </%self:longhand> // CSS 2.1, Section 11 - Visual effects @@ -712,9 +637,12 @@ pub mod longhands { <%self:longhand name="content"> pub use super::computed_as_specified as to_computed_value; + pub use self::computed_value::T as SpecifiedValue; + pub use self::computed_value::ContentItem; + use cssparser::Token; pub mod computed_value { - use std::fmt; - #[deriving(PartialEq, Eq, Clone)] + use std::fmt; + #[derive(PartialEq, Eq, Clone)] pub enum ContentItem { StringContent(String), } @@ -726,7 +654,7 @@ pub mod longhands { } } #[allow(non_camel_case_types)] - #[deriving(PartialEq, Eq, Clone)] + #[derive(PartialEq, Eq, Clone)] pub enum T { normal, none, @@ -739,7 +667,7 @@ pub mod longhands { &T::none => write!(f, "none"), &T::Content(ref content) => { for c in content.iter() { - let _ = write!(f, "{}", c); + let _ = write!(f, "{:?}", c); } Ok(()) } @@ -747,31 +675,31 @@ pub mod longhands { } } } - pub type SpecifiedValue = computed_value::T; - #[inline] pub fn get_initial_value() -> computed_value::T { T::normal } + #[inline] + pub fn get_initial_value() -> computed_value::T { + computed_value::T::normal + } // normal | none | [ <string> ]+ // TODO: <uri>, <counter>, attr(<identifier>), open-quote, close-quote, no-open-quote, no-close-quote - pub fn parse(input: &[ComponentValue], _base_url: &Url) -> Result<SpecifiedValue, ()> { - match one_component_value(input) { - Ok(&Ident(ref keyword)) => { - match keyword.as_slice().to_ascii_lower().as_slice() { - "normal" => return Ok(T::normal), - "none" => return Ok(T::none), - _ => () + pub fn parse(_context: &ParserContext, input: &mut Parser) + -> Result<SpecifiedValue, ()> { + if input.try(|input| input.expect_ident_matching("normal")).is_ok() { + return Ok(SpecifiedValue::normal) + } + if input.try(|input| input.expect_ident_matching("none")).is_ok() { + return Ok(SpecifiedValue::none) + } + let mut content = vec![]; + loop { + match input.next() { + Ok(Token::QuotedString(value)) => { + content.push(ContentItem::StringContent(value.into_owned())) } - }, - _ => () - } - let mut content = vec!(); - for component_value in input.skip_whitespace() { - match component_value { - &QuotedString(ref value) - => content.push(ContentItem::StringContent(value.clone())), - _ => return Err(()) // invalid/unsupported value + Ok(_) => return Err(()), + Err(()) => return Ok(SpecifiedValue::Content(content)) } } - Ok(T::Content(content)) } </%self:longhand> @@ -790,26 +718,26 @@ pub mod longhands { ${single_keyword("list-style-type", "disc none circle square disclosure-open disclosure-closed")} - <%self:single_component_value name="list-style-image"> + <%self:longhand name="list-style-image"> + use url::Url; pub use super::computed_as_specified as to_computed_value; pub type SpecifiedValue = Option<Url>; pub mod computed_value { use url::Url; pub type T = Option<Url>; } - pub fn from_component_value(input: &ComponentValue, base_url: &Url) - -> Result<SpecifiedValue,()> { - match *input { - URL(ref url) => Ok(Some(super::parse_url(url.as_slice(), base_url))), - Ident(ref value) if value.as_slice().eq_ignore_ascii_case("none") => Ok(None), - _ => Err(()), + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { + if input.try(|input| input.expect_ident_matching("none")).is_ok() { + Ok(None) + } else { + Ok(Some(context.parse_url(try!(input.expect_url()).as_slice()))) } } #[inline] pub fn get_initial_value() -> computed_value::T { None } - </%self:single_component_value> + </%self:longhand> // CSS 2.1, Section 13 - Paged media @@ -817,34 +745,24 @@ pub mod longhands { ${new_style_struct("Background", is_inherited=False)} ${predefined_type("background-color", "CSSColor", - "Color::RGBA(RGBA { red: 0., green: 0., blue: 0., alpha: 0. }) /* transparent */")} + "::cssparser::Color::RGBA(::cssparser::RGBA { red: 0., green: 0., blue: 0., alpha: 0. }) /* transparent */")} - <%self:single_component_value name="background-image"> - use super::common_types::specified as common_specified; - use super::super::common_types::specified::CSSImage as CSSImage; + <%self:longhand name="background-image"> + use values::specified::{CSSImage, Image}; pub mod computed_value { - use super::super::super::common_types::computed; + use values::computed; pub type T = Option<computed::Image>; } - pub type SpecifiedValue = common_specified::CSSImage; + pub type SpecifiedValue = CSSImage; #[inline] pub fn get_initial_value() -> computed_value::T { None } - pub fn from_component_value(component_value: &ComponentValue, base_url: &Url) - -> Result<SpecifiedValue, ()> { - match component_value { - &Ident(ref value) - if value.as_slice().eq_ignore_ascii_case("none") => { - Ok(CSSImage(None)) - } - _ => { - match common_specified::Image::from_component_value(component_value, - base_url) { - Err(err) => Err(err), - Ok(result) => Ok(CSSImage(Some(result))), - } - } + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { + if input.try(|input| input.expect_ident_matching("none")).is_ok() { + Ok(CSSImage(None)) + } else { + Ok(CSSImage(Some(try!(Image::parse(context, input))))) } } pub fn to_computed_value(value: SpecifiedValue, context: &computed::Context) @@ -854,41 +772,41 @@ pub mod longhands { CSSImage(Some(image)) => Some(image.to_computed_value(context)), } } - </%self:single_component_value> + </%self:longhand> <%self:longhand name="background-position"> use std::fmt; pub mod computed_value { - use super::super::super::common_types::computed::LengthOrPercentage; + use values::computed::LengthOrPercentage; use std::fmt; - #[deriving(PartialEq, Copy, Clone)] + #[derive(PartialEq, Copy, Clone)] pub struct T { pub horizontal: LengthOrPercentage, pub vertical: LengthOrPercentage, } impl fmt::Show for T { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} {}", self.horizontal, self.vertical) + write!(f, "{:?} {:?}", self.horizontal, self.vertical) } } } - #[deriving(Clone, PartialEq, Copy)] + #[derive(Clone, PartialEq, Copy)] pub struct SpecifiedValue { pub horizontal: specified::LengthOrPercentage, pub vertical: specified::LengthOrPercentage, } impl fmt::Show for SpecifiedValue { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} {}", self.horizontal, self.vertical) + write!(f, "{:?} {:?}", self.horizontal, self.vertical) } } impl SpecifiedValue { fn new(first: specified::PositionComponent, second: specified::PositionComponent) - -> Result<SpecifiedValue,()> { + -> Result<SpecifiedValue, ()> { let (horiz, vert) = match (category(first), category(second)) { // Don't allow two vertical keywords or two horizontal keywords. (PositionCategory::HorizontalKeyword, PositionCategory::HorizontalKeyword) | @@ -949,36 +867,13 @@ pub mod longhands { } } - pub fn parse_one(first: &ComponentValue) -> Result<SpecifiedValue, ()> { - let first = try!(specified::PositionComponent::parse(first)); - // If only one value is provided, use `center` for the second. - SpecifiedValue::new(first, specified::PositionComponent::Center) - } - - pub fn parse_two(first: &ComponentValue, second: &ComponentValue) - -> Result<SpecifiedValue, ()> { - let first = try!(specified::PositionComponent::parse(first)); - let second = try!(specified::PositionComponent::parse(second)); + pub fn parse(_context: &ParserContext, input: &mut Parser) + -> Result<SpecifiedValue, ()> { + let first = try!(specified::PositionComponent::parse(input)); + let second = input.try(specified::PositionComponent::parse) + .unwrap_or(specified::PositionComponent::Center); SpecifiedValue::new(first, second) } - - pub fn parse(input: &[ComponentValue], _: &Url) -> Result<SpecifiedValue, ()> { - let mut input_iter = input.skip_whitespace(); - let first = input_iter.next(); - let second = input_iter.next(); - if input_iter.next().is_some() { - return Err(()) - } - match (first, second) { - (Some(first), Some(second)) => { - parse_two(first, second) - } - (Some(first), None) => { - parse_one(first) - } - _ => Err(()) - } - } </%self:longhand> ${single_keyword("background-repeat", "repeat repeat-x repeat-y no-repeat")} @@ -988,7 +883,8 @@ pub mod longhands { ${new_style_struct("Color", is_inherited=True)} <%self:raw_longhand name="color"> - use super::super::common_types::specified::{CSSColor, CSSRGBA}; + use cssparser::{Color, RGBA}; + use values::specified::{CSSColor, CSSRGBA}; #[inline] pub fn to_computed_value(value: SpecifiedValue, _context: &computed::Context) -> computed_value::T { @@ -1003,19 +899,17 @@ pub mod longhands { #[inline] pub fn get_initial_value() -> computed_value::T { RGBA { red: 0., green: 0., blue: 0., alpha: 1. } /* black */ } - pub fn parse_specified(input: &[ComponentValue], _base_url: &Url) + pub fn parse_specified(_context: &ParserContext, input: &mut Parser) -> Result<DeclaredValue<SpecifiedValue>, ()> { - match one_component_value(input).and_then(CSSColor::parse) { - Ok(CSSColor { parsed: Color::RGBA(rgba), authored }) => { - let rgba = CSSRGBA { - parsed: rgba, - authored: authored, - }; - Ok(DeclaredValue::SpecifiedValue(rgba)) - } - Ok(CSSColor { parsed: Color::CurrentColor, .. }) => Ok(DeclaredValue::Inherit), - Err(()) => Err(()), - } + let value = try!(CSSColor::parse(input)); + let rgba = match value.parsed { + Color::RGBA(rgba) => rgba, + Color::CurrentColor => return Ok(DeclaredValue::Inherit) + }; + Ok(DeclaredValue::SpecifiedValue(CSSRGBA { + parsed: rgba, + authored: value.authored, + })) } </%self:raw_longhand> @@ -1025,9 +919,11 @@ pub mod longhands { <%self:longhand name="font-family"> pub use super::computed_as_specified as to_computed_value; + use std::borrow::ToOwned; + use self::computed_value::FontFamily; pub mod computed_value { use std::fmt; - #[deriving(PartialEq, Eq, Clone)] + #[derive(PartialEq, Eq, Clone)] pub enum FontFamily { FamilyName(String), // Generic @@ -1065,46 +961,33 @@ pub mod longhands { #[inline] pub fn get_initial_value() -> computed_value::T { - vec![FontFamily::FamilyName("serif".into_string())] - } - /// <familiy-name># - /// <familiy-name> = <string> | [ <ident>+ ] - /// TODO: <generic-familiy> - pub fn parse(input: &[ComponentValue], _base_url: &Url) -> Result<SpecifiedValue, ()> { - parse_slice_comma_separated(input, parse_one_family) - } - pub fn parse_one_family<'a>(iter: ParserIter) -> Result<FontFamily, ()> { - // TODO: avoid copying strings? - let mut idents = match iter.next() { - Some(&QuotedString(ref value)) => return Ok(FontFamily::FamilyName(value.clone())), - Some(&Ident(ref value)) => { -// match value.as_slice().to_ascii_lower().as_slice() { -// "serif" => return Ok(Serif), -// "sans-serif" => return Ok(SansSerif), -// "cursive" => return Ok(Cursive), -// "fantasy" => return Ok(Fantasy), -// "monospace" => return Ok(Monospace), -// _ => { - vec![value.as_slice()] -// } -// } - } - _ => return Err(()) - }; - loop { - match iter.next() { - Some(&Ident(ref value)) => { - idents.push(value.as_slice()); - iter.next(); - } - Some(component_value) => { - iter.push_back(component_value); - break - } - None => break, - } + vec![FontFamily::FamilyName("serif".to_owned())] + } + /// <family-name># + /// <family-name> = <string> | [ <ident>+ ] + /// TODO: <generic-family> + pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { + input.parse_comma_separated(parse_one_family) + } + pub fn parse_one_family(input: &mut Parser) -> Result<FontFamily, ()> { + if let Ok(value) = input.try(|input| input.expect_string()) { + return Ok(FontFamily::FamilyName(value.into_owned())) + } + let first_ident = try!(input.expect_ident()); +// match_ignore_ascii_case! { first_ident, +// "serif" => return Ok(Serif), +// "sans-serif" => return Ok(SansSerif), +// "cursive" => return Ok(Cursive), +// "fantasy" => return Ok(Fantasy), +// "monospace" => return Ok(Monospace) +// _ => {} +// } + let mut value = first_ident.into_owned(); + while let Ok(ident) = input.try(|input| input.expect_ident()) { + value.push_str(" "); + value.push_str(ident.as_slice()); } - Ok(FontFamily::FamilyName(idents.connect(" "))) + Ok(FontFamily::FamilyName(value)) } </%self:longhand> @@ -1112,14 +995,14 @@ pub mod longhands { ${single_keyword("font-style", "normal italic oblique")} ${single_keyword("font-variant", "normal small-caps")} - <%self:single_component_value name="font-weight"> + <%self:longhand name="font-weight"> use std::fmt; - #[deriving(Clone, PartialEq, Eq, Copy)] + #[derive(Clone, PartialEq, Eq, Copy)] pub enum SpecifiedValue { Bolder, Lighter, % for weight in range(100, 901, 100): - SpecifiedWeight${weight}, + Weight${weight}, % endfor } impl fmt::Show for SpecifiedValue { @@ -1128,42 +1011,39 @@ pub mod longhands { &SpecifiedValue::Bolder => write!(f, "bolder"), &SpecifiedValue::Lighter => write!(f, "lighter"), % for weight in range(100, 901, 100): - &SpecifiedValue::SpecifiedWeight${weight} => write!(f, "{}", ${weight}i), + &SpecifiedValue::Weight${weight} => write!(f, "{}", ${weight}i), % endfor } } } /// normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 - pub fn from_component_value(input: &ComponentValue, _base_url: &Url) - -> Result<SpecifiedValue, ()> { - match input { - &Ident(ref value) => { - match value.as_slice().to_ascii_lower().as_slice() { - "bold" => Ok(SpecifiedValue::SpecifiedWeight700), - "normal" => Ok(SpecifiedValue::SpecifiedWeight400), - "bolder" => Ok(SpecifiedValue::Bolder), - "lighter" => Ok(SpecifiedValue::Lighter), - _ => Err(()), - } - }, - &Number(ref value) => match value.int_value { - Some(100) => Ok(SpecifiedValue::SpecifiedWeight100), - Some(200) => Ok(SpecifiedValue::SpecifiedWeight200), - Some(300) => Ok(SpecifiedValue::SpecifiedWeight300), - Some(400) => Ok(SpecifiedValue::SpecifiedWeight400), - Some(500) => Ok(SpecifiedValue::SpecifiedWeight500), - Some(600) => Ok(SpecifiedValue::SpecifiedWeight600), - Some(700) => Ok(SpecifiedValue::SpecifiedWeight700), - Some(800) => Ok(SpecifiedValue::SpecifiedWeight800), - Some(900) => Ok(SpecifiedValue::SpecifiedWeight900), - _ => Err(()), - }, - _ => Err(()) - } + pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { + input.try(|input| { + match_ignore_ascii_case! { try!(input.expect_ident()), + "bold" => Ok(SpecifiedValue::Weight700), + "normal" => Ok(SpecifiedValue::Weight400), + "bolder" => Ok(SpecifiedValue::Bolder), + "lighter" => Ok(SpecifiedValue::Lighter) + _ => Err(()) + } + }).or_else(|()| { + match try!(input.expect_integer()) { + 100 => Ok(SpecifiedValue::Weight100), + 200 => Ok(SpecifiedValue::Weight200), + 300 => Ok(SpecifiedValue::Weight300), + 400 => Ok(SpecifiedValue::Weight400), + 500 => Ok(SpecifiedValue::Weight500), + 600 => Ok(SpecifiedValue::Weight600), + 700 => Ok(SpecifiedValue::Weight700), + 800 => Ok(SpecifiedValue::Weight800), + 900 => Ok(SpecifiedValue::Weight900), + _ => Err(()) + } + }) } pub mod computed_value { use std::fmt; - #[deriving(PartialEq, Eq, Copy, Clone)] + #[derive(PartialEq, Eq, Copy, Clone)] pub enum T { % for weight in range(100, 901, 100): Weight${weight}, @@ -1197,7 +1077,7 @@ pub mod longhands { -> computed_value::T { match value { % for weight in range(100, 901, 100): - SpecifiedValue::SpecifiedWeight${weight} => computed_value::T::Weight${weight}, + SpecifiedValue::Weight${weight} => computed_value::T::Weight${weight}, % endfor SpecifiedValue::Bolder => match context.inherited_font_weight { computed_value::T::Weight100 => computed_value::T::Weight400, @@ -1223,12 +1103,13 @@ pub mod longhands { }, } } - </%self:single_component_value> + </%self:longhand> - <%self:single_component_value name="font-size"> + <%self:longhand name="font-size"> + use servo_util::geometry::Au; pub type SpecifiedValue = specified::Length; // Percentages are the same as em. pub mod computed_value { - use super::super::Au; + use servo_util::geometry::Au; pub type T = Au; } const MEDIUM_PX: int = 16; @@ -1242,30 +1123,31 @@ pub mod longhands { return context.font_size } /// <length> | <percentage> | <absolute-size> | <relative-size> - pub fn from_component_value(input: &ComponentValue, _base_url: &Url) - -> Result<SpecifiedValue, ()> { - match specified::LengthOrPercentage::parse_non_negative(input) { - Ok(specified::LengthOrPercentage::Length(value)) => return Ok(value), - Ok(specified::LengthOrPercentage::Percentage(value)) => return Ok(specified::Length::Em(value)), - Err(()) => (), - } - match try!(get_ident_lower(input)).as_slice() { - "xx-small" => Ok(specified::Length::Au(Au::from_px(MEDIUM_PX) * 3 / 5)), - "x-small" => Ok(specified::Length::Au(Au::from_px(MEDIUM_PX) * 3 / 4)), - "small" => Ok(specified::Length::Au(Au::from_px(MEDIUM_PX) * 8 / 9)), - "medium" => Ok(specified::Length::Au(Au::from_px(MEDIUM_PX))), - "large" => Ok(specified::Length::Au(Au::from_px(MEDIUM_PX) * 6 / 5)), - "x-large" => Ok(specified::Length::Au(Au::from_px(MEDIUM_PX) * 3 / 2)), - "xx-large" => Ok(specified::Length::Au(Au::from_px(MEDIUM_PX) * 2)), - - // https://github.com/servo/servo/issues/3423#issuecomment-56321664 - "smaller" => Ok(specified::Length::Em(0.85)), - "larger" => Ok(specified::Length::Em(1.2)), + pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { + input.try(specified::LengthOrPercentage::parse_non_negative) + .map(|value| match value { + specified::LengthOrPercentage::Length(value) => value, + specified::LengthOrPercentage::Percentage(value) => specified::Length::Em(value) + }) + .or_else(|()| { + match_ignore_ascii_case! { try!(input.expect_ident()), + "xx-small" => Ok(specified::Length::Au(Au::from_px(MEDIUM_PX) * 3 / 5)), + "x-small" => Ok(specified::Length::Au(Au::from_px(MEDIUM_PX) * 3 / 4)), + "small" => Ok(specified::Length::Au(Au::from_px(MEDIUM_PX) * 8 / 9)), + "medium" => Ok(specified::Length::Au(Au::from_px(MEDIUM_PX))), + "large" => Ok(specified::Length::Au(Au::from_px(MEDIUM_PX) * 6 / 5)), + "x-large" => Ok(specified::Length::Au(Au::from_px(MEDIUM_PX) * 3 / 2)), + "xx-large" => Ok(specified::Length::Au(Au::from_px(MEDIUM_PX) * 2)), + + // https://github.com/servo/servo/issues/3423#issuecomment-56321664 + "smaller" => Ok(specified::Length::Em(0.85)), + "larger" => Ok(specified::Length::Em(1.2)) - _ => return Err(()) - } + _ => Err(()) + } + }) } - </%self:single_component_value> + </%self:longhand> // CSS 2.1, Section 16 - Text @@ -1274,10 +1156,10 @@ pub mod longhands { // TODO: initial value should be 'start' (CSS Text Level 3, direction-dependent.) ${single_keyword("text-align", "left right center justify")} - <%self:single_component_value name="letter-spacing"> + <%self:longhand name="letter-spacing"> pub type SpecifiedValue = Option<specified::Length>; pub mod computed_value { - use super::super::Au; + use servo_util::geometry::Au; pub type T = Option<Au>; } #[inline] @@ -1289,18 +1171,19 @@ pub mod longhands { -> computed_value::T { value.map(|length| computed::compute_Au(length, context)) } - pub fn from_component_value(input: &ComponentValue, _: &Url) -> Result<SpecifiedValue,()> { - match input { - &Ident(ref value) if value.eq_ignore_ascii_case("normal") => Ok(None), - _ => specified::Length::parse_non_negative(input).map(|length| Some(length)), + pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { + if input.try(|input| input.expect_ident_matching("normal")).is_ok() { + Ok(None) + } else { + specified::Length::parse_non_negative(input).map(Some) } } - </%self:single_component_value> + </%self:longhand> - <%self:single_component_value name="word-spacing"> + <%self:longhand name="word-spacing"> pub type SpecifiedValue = Option<specified::Length>; pub mod computed_value { - use super::super::Au; + use servo_util::geometry::Au; pub type T = Option<Au>; } #[inline] @@ -1312,13 +1195,14 @@ pub mod longhands { -> computed_value::T { value.map(|length| computed::compute_Au(length, context)) } - pub fn from_component_value(input: &ComponentValue, _: &Url) -> Result<SpecifiedValue,()> { - match input { - &Ident(ref value) if value.eq_ignore_ascii_case("normal") => Ok(None), - _ => specified::Length::parse_non_negative(input).map(|length| Some(length)), + pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { + if input.try(|input| input.expect_ident_matching("normal")).is_ok() { + Ok(None) + } else { + specified::Length::parse_non_negative(input).map(Some) } } - </%self:single_component_value> + </%self:longhand> ${predefined_type("text-indent", "LengthOrPercentage", "computed::LengthOrPercentage::Length(Au(0))")} @@ -1334,7 +1218,7 @@ pub mod longhands { <%self:longhand name="text-decoration"> pub use super::computed_as_specified as to_computed_value; use std::fmt; - #[deriving(PartialEq, Eq, Copy, Clone)] + #[derive(PartialEq, Eq, Copy, Clone)] pub struct SpecifiedValue { pub underline: bool, pub overline: bool, @@ -1368,37 +1252,34 @@ pub mod longhands { pub mod computed_value { pub type T = super::SpecifiedValue; #[allow(non_upper_case_globals)] - pub const none: T = super::SpecifiedValue { underline: false, overline: false, line_through: false }; + pub const none: T = super::SpecifiedValue { + underline: false, overline: false, line_through: false + }; } #[inline] pub fn get_initial_value() -> computed_value::T { - none + computed_value::none } /// none | [ underline || overline || line-through || blink ] - pub fn parse(input: &[ComponentValue], _base_url: &Url) -> Result<SpecifiedValue, ()> { + pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { let mut result = SpecifiedValue { underline: false, overline: false, line_through: false, }; - match one_component_value(input) { - Ok(&Ident(ref value)) - if value.as_slice().eq_ignore_ascii_case("none") => return Ok(result), - _ => {} + if input.try(|input| input.expect_ident_matching("none")).is_ok() { + return Ok(result) } let mut blink = false; let mut empty = true; - for component_value in input.skip_whitespace() { - match get_ident_lower(component_value) { - Err(()) => return Err(()), - Ok(keyword) => match keyword.as_slice() { - "underline" => if result.underline { return Err(()) } - else { empty = false; result.underline = true }, - "overline" => if result.overline { return Err(()) } - else { empty = false; result.overline = true }, - "line-through" => if result.line_through { return Err(()) } - else { empty = false; result.line_through = true }, - "blink" => if blink { return Err(()) } - else { empty = false; blink = true }, - _ => return Err(()), - } + loop { + match_ignore_ascii_case! { try!(input.expect_ident()), + "underline" => if result.underline { return Err(()) } + else { empty = false; result.underline = true }, + "overline" => if result.overline { return Err(()) } + else { empty = false; result.overline = true }, + "line-through" => if result.line_through { return Err(()) } + else { empty = false; result.line_through = true }, + "blink" => if blink { return Err(()) } + else { empty = false; blink = true } + _ => break } } if !empty { Ok(result) } else { Err(()) } @@ -1409,9 +1290,10 @@ pub mod longhands { <%self:longhand name="-servo-text-decorations-in-effect" derived_from="display text-decoration"> + use cssparser::RGBA; pub use super::computed_as_specified as to_computed_value; - #[deriving(Clone, PartialEq, Copy)] + #[derive(Clone, PartialEq, Copy)] pub struct SpecifiedValue { pub underline: Option<RGBA>, pub overline: Option<RGBA>, @@ -1443,7 +1325,9 @@ pub mod longhands { // Start with no declarations if this is a block; otherwise, start with the // declarations in effect and add in the text decorations that this inline specifies. let mut result = match context.display { - display::computed_value::T::inline => context.inherited_text_decorations_in_effect, + super::display::computed_value::T::inline => { + context.inherited_text_decorations_in_effect + } _ => { SpecifiedValue { underline: None, @@ -1467,14 +1351,15 @@ pub mod longhands { } #[inline] - pub fn derive_from_text_decoration(_: text_decoration::computed_value::T, + pub fn derive_from_text_decoration(_: super::text_decoration::computed_value::T, context: &computed::Context) -> computed_value::T { derive(context) } #[inline] - pub fn derive_from_display(_: display::computed_value::T, context: &computed::Context) + pub fn derive_from_display(_: super::display::computed_value::T, + context: &computed::Context) -> computed_value::T { derive(context) } @@ -1519,38 +1404,34 @@ pub mod longhands { ${new_style_struct("Pointing", is_inherited=True)} - <%self:single_component_value name="cursor"> + <%self:longhand name="cursor"> use servo_util::cursor as util_cursor; pub use super::computed_as_specified as to_computed_value; + pub use self::computed_value::T as SpecifiedValue; pub mod computed_value { use servo_util::cursor::Cursor; - #[deriving(Clone, PartialEq, Eq, Copy, Show)] + #[derive(Clone, PartialEq, Eq, Copy, Show)] pub enum T { AutoCursor, SpecifiedCursor(Cursor), } } - pub type SpecifiedValue = computed_value::T; #[inline] pub fn get_initial_value() -> computed_value::T { computed_value::T::AutoCursor } - pub fn from_component_value(value: &ComponentValue, _: &Url) - -> Result<SpecifiedValue,()> { - match value { - &Ident(ref ident) => { - if ident.eq_ignore_ascii_case("auto") { - Ok(T::AutoCursor) - } else { - util_cursor::Cursor::from_css_keyword(ident.as_slice()) - .map(T::SpecifiedCursor) - } - } - _ => Err(()) + pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { + use std::ascii::AsciiExt; + let ident = try!(input.expect_ident()); + if ident.eq_ignore_ascii_case("auto") { + Ok(SpecifiedValue::AutoCursor) + } else { + util_cursor::Cursor::from_css_keyword(ident.as_slice()) + .map(SpecifiedValue::SpecifiedCursor) } } - </%self:single_component_value> + </%self:longhand> // NB: `pointer-events: auto` (and use of `pointer-events` in anything that isn't SVG, in fact) // is nonstandard, slated for CSS4-UI. @@ -1560,10 +1441,11 @@ pub mod longhands { // Box-shadow, etc. ${new_style_struct("Effects", is_inherited=False)} - <%self:single_component_value name="opacity"> + <%self:longhand name="opacity"> + use values::CSSFloat; pub type SpecifiedValue = CSSFloat; pub mod computed_value { - use super::super::CSSFloat; + use values::CSSFloat; pub type T = CSSFloat; } #[inline] @@ -1581,13 +1463,10 @@ pub mod longhands { value } } - fn from_component_value(input: &ComponentValue, _: &Url) -> Result<SpecifiedValue,()> { - match *input { - Number(ref value) => Ok(value.value), - _ => Err(()) - } + fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { + input.expect_number() } - </%self:single_component_value> + </%self:longhand> <%self:longhand name="box-shadow"> use cssparser; @@ -1595,7 +1474,7 @@ pub mod longhands { pub type SpecifiedValue = Vec<SpecifiedBoxShadow>; - #[deriving(Clone, PartialEq)] + #[derive(Clone, PartialEq)] pub struct SpecifiedBoxShadow { pub offset_x: specified::Length, pub offset_y: specified::Length, @@ -1610,23 +1489,23 @@ pub mod longhands { if self.inset { let _ = write!(f, "inset "); } - let _ = write!(f, "{} {} {} {}", self.offset_x, self.offset_y, + let _ = write!(f, "{:?} {:?} {:?} {:?}", self.offset_x, self.offset_y, self.blur_radius, self.spread_radius); if let Some(ref color) = self.color { - let _ = write!(f, "{}", color); + let _ = write!(f, "{:?}", color); } Ok(()) } } pub mod computed_value { - use super::super::Au; - use super::super::super::computed; + use servo_util::geometry::Au; + use values::computed; use std::fmt; pub type T = Vec<BoxShadow>; - #[deriving(Clone, PartialEq, Copy)] + #[derive(Clone, PartialEq, Copy)] pub struct BoxShadow { pub offset_x: Au, pub offset_y: Au, @@ -1641,7 +1520,7 @@ pub mod longhands { if self.inset { let _ = write!(f, "inset "); } - let _ = write!(f, "{} {} {} {} {}", self.offset_x, self.offset_y, + let _ = write!(f, "{:?} {:?} {:?} {:?} {:?}", self.offset_x, self.offset_y, self.blur_radius, self.spread_radius, self.color); Ok(()) } @@ -1653,14 +1532,12 @@ pub mod longhands { Vec::new() } - pub fn parse(input: &[ComponentValue], _: &Url) -> Result<SpecifiedValue,()> { - match one_component_value(input) { - Ok(&Ident(ref value)) if value.as_slice().eq_ignore_ascii_case("none") => { - return Ok(Vec::new()) - } - _ => {} + pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { + if input.try(|input| input.expect_ident_matching("none")).is_ok() { + Ok(Vec::new()) + } else { + input.parse_comma_separated(parse_one_box_shadow) } - parse_slice_comma_separated(input, parse_one_box_shadow) } pub fn to_computed_value(value: SpecifiedValue, context: &computed::Context) @@ -1682,69 +1559,49 @@ pub mod longhands { } } - pub fn parse_one_box_shadow(iter: ParserIter) -> Result<SpecifiedBoxShadow,()> { - let mut lengths = [specified::Length::Au(Au(0)), ..4]; + pub fn parse_one_box_shadow(input: &mut Parser) -> Result<SpecifiedBoxShadow, ()> { + use servo_util::geometry::Au; + let mut lengths = [specified::Length::Au(Au(0)); 4]; let mut lengths_parsed = false; let mut color = None; let mut inset = false; loop { - match iter.next() { - Some(&Ident(ref value)) if value.eq_ignore_ascii_case("inset") && !inset => { + if !inset { + if input.try(|input| input.expect_ident_matching("inset")).is_ok() { inset = true; continue } - Some(value) => { - // Try to parse a length. - match specified::Length::parse(value) { - Ok(the_length) if !lengths_parsed => { - lengths[0] = the_length; - let mut length_parsed_count = 1; - while length_parsed_count < 4 { - match iter.next() { - Some(value) => { - match specified::Length::parse(value) { - Ok(the_length) => { - lengths[length_parsed_count] = the_length; - } - Err(_) => { - iter.push_back(value); - break - } - } - } - None => break, - } - length_parsed_count += 1; - } - - // The first two lengths must be specified. - if length_parsed_count < 2 { - return Err(()) - } - - lengths_parsed = true; - continue + } + if !lengths_parsed { + if let Ok(value) = input.try(specified::Length::parse) { + lengths[0] = value; + let mut length_parsed_count = 1; + while length_parsed_count < 4 { + if let Ok(value) = input.try(specified::Length::parse) { + lengths[length_parsed_count] = value + } else { + break } - Ok(_) => return Err(()), - Err(()) => {} + length_parsed_count += 1; } - // Try to parse a color. - match specified::CSSColor::parse(value) { - Ok(ref the_color) if color.is_none() => { - color = Some(the_color.clone()); - continue - } - Ok(_) => return Err(()), - Err(()) => {} + // The first two lengths must be specified. + if length_parsed_count < 2 { + return Err(()) } - iter.push_back(value); - break + lengths_parsed = true; + continue } - None => break, } + if color.is_none() { + if let Ok(value) = input.try(specified::CSSColor::parse) { + color = Some(value); + continue + } + } + break } // Lengths must be specified. @@ -1763,13 +1620,13 @@ pub mod longhands { } </%self:longhand> - <%self:single_component_value name="clip"> + <%self:longhand name="clip"> // NB: `top` and `left` are 0 if `auto` per CSS 2.1 11.1.2. pub mod computed_value { - use super::super::Au; + use servo_util::geometry::Au; - #[deriving(Clone, PartialEq, Eq, Copy, Show)] + #[derive(Clone, PartialEq, Eq, Copy, Show)] pub struct ClipRect { pub top: Au, pub right: Option<Au>, @@ -1780,7 +1637,7 @@ pub mod longhands { pub type T = Option<ClipRect>; } - #[deriving(Clone, Show, PartialEq, Copy)] + #[derive(Clone, Show, PartialEq, Copy)] pub struct SpecifiedClipRect { pub top: specified::Length, pub right: Option<specified::Length>, @@ -1805,48 +1662,51 @@ pub mod longhands { }) } - pub fn from_component_value(input: &ComponentValue, _: &Url) -> Result<SpecifiedValue,()> { - match *input { - Function(ref name, ref args) if name.as_slice().eq_ignore_ascii_case("rect") => { - let sides = try!(parse_slice_comma_separated(args.as_slice(), |parser| { - match parser.next() { - Some(&Ident(ref ident)) if ident.eq_ignore_ascii_case("auto") => { - Ok(None) - } - Some(arg) => { - match specified::Length::parse(arg) { - Err(_) => { - parser.push_back(arg); - Err(()) - } - Ok(value) => Ok(Some(value)), - } - } - None => Err(()), - } - })); - if sides.len() != 4 { - return Err(()) + pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { + use std::ascii::AsciiExt; + use servo_util::geometry::Au; + use values::specified::Length; + + if input.try(|input| input.expect_ident_matching("auto")).is_ok() { + return Ok(None) + } + if !try!(input.expect_function()).eq_ignore_ascii_case("rect") { + return Err(()) + } + let sides = try!(input.parse_nested_block(|input| { + input.parse_comma_separated(|input| { + if input.try(|input| input.expect_ident_matching("auto")).is_ok() { + Ok(None) + } else { + Length::parse(input).map(Some) } - Ok(Some(SpecifiedClipRect { - top: sides[0].unwrap_or(specified::Length::Au(Au(0))), - right: sides[1], - bottom: sides[2], - left: sides[3].unwrap_or(specified::Length::Au(Au(0))), - })) - } - Ident(ref ident) if ident.as_slice().eq_ignore_ascii_case("auto") => Ok(None), - _ => Err(()) + }) + })); + if sides.len() == 4 { + Ok(Some(SpecifiedClipRect { + top: sides[0].unwrap_or(Length::Au(Au(0))), + right: sides[1], + bottom: sides[2], + left: sides[3].unwrap_or(Length::Au(Au(0))), + })) + } else { + Err(()) } } - </%self:single_component_value> + </%self:longhand> <%self:longhand name="filter"> + use values::specified::Angle; + pub use super::computed_as_specified as to_computed_value; + pub use self::computed_value::T as SpecifiedValue; + pub use self::computed_value::Filter; + pub mod computed_value { - use super::super::{Angle, CSSFloat}; + use values::specified::Angle; + use values::CSSFloat; // TODO(pcwalton): `blur`, `drop-shadow` - #[deriving(Clone, PartialEq, Show)] + #[derive(Clone, PartialEq, Show)] pub enum Filter { Brightness(CSSFloat), Contrast(CSSFloat), @@ -1858,7 +1718,7 @@ pub mod longhands { Sepia(CSSFloat), } - #[deriving(Clone, PartialEq, Show)] + #[derive(Clone, PartialEq, Show)] pub struct T { pub filters: Vec<Filter>, } @@ -1898,86 +1758,39 @@ pub mod longhands { } } - // TODO(pcwalton): `blur`, `drop-shadow` - #[deriving(Clone, Show)] - pub enum SpecifiedFilter { - Brightness(CSSFloat), - Contrast(CSSFloat), - Grayscale(CSSFloat), - HueRotate(Angle), - Invert(CSSFloat), - Opacity(CSSFloat), - Saturate(CSSFloat), - Sepia(CSSFloat), - } - - pub type SpecifiedValue = Vec<SpecifiedFilter>; - #[inline] pub fn get_initial_value() -> computed_value::T { computed_value::T::new(Vec::new()) } - pub fn to_computed_value(value: SpecifiedValue, _: &computed::Context) - -> computed_value::T { - computed_value::T::new(value.into_iter().map(|filter| { - match filter { - SpecifiedFilter::Brightness(amount) => { - computed_value::Filter::Brightness(amount) - } - SpecifiedFilter::Contrast(amount) => computed_value::Filter::Contrast(amount), - SpecifiedFilter::Grayscale(amount) => { - computed_value::Filter::Grayscale(amount) - } - SpecifiedFilter::HueRotate(angle) => computed_value::Filter::HueRotate(angle), - SpecifiedFilter::Invert(amount) => computed_value::Filter::Invert(amount), - SpecifiedFilter::Opacity(amount) => computed_value::Filter::Opacity(amount), - SpecifiedFilter::Saturate(amount) => computed_value::Filter::Saturate(amount), - SpecifiedFilter::Sepia(amount) => computed_value::Filter::Sepia(amount), - } - }).collect()) - } - - pub fn parse(input: &[ComponentValue], _: &Url) -> Result<SpecifiedValue,()> { + pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { let mut filters = Vec::new(); - for filter in input.skip_whitespace() { - let name; - let args; - match *filter { - Function(ref function_name, ref function_args) => { - name = function_name; - args = function_args; - } - _ => return Err(()), - } - - if name.eq_ignore_ascii_case("brightness") && args.len() == 1 { - filters.push(SpecifiedFilter::Brightness(try!(parse_percentage(&args[0])))); - } else if name.eq_ignore_ascii_case("contrast") && args.len() == 1 { - filters.push(SpecifiedFilter::Contrast(try!(parse_percentage(&args[0])))); - } else if name.eq_ignore_ascii_case("grayscale") && args.len() == 1 { - filters.push(SpecifiedFilter::Grayscale(try!(parse_percentage(&args[0])))); - } else if name.eq_ignore_ascii_case("hue-rotate") && args.len() == 1 { - filters.push(SpecifiedFilter::HueRotate(try!(Angle::parse(&args[0])))); - } else if name.eq_ignore_ascii_case("invert") && args.len() == 1 { - filters.push(SpecifiedFilter::Invert(try!(parse_percentage(&args[0])))); - } else if name.eq_ignore_ascii_case("opacity") && args.len() == 1 { - filters.push(SpecifiedFilter::Opacity(try!(parse_percentage(&args[0])))); - } else if name.eq_ignore_ascii_case("saturate") && args.len() == 1 { - filters.push(SpecifiedFilter::Saturate(try!(parse_percentage(&args[0])))); - } else if name.eq_ignore_ascii_case("sepia") && args.len() == 1 { - filters.push(SpecifiedFilter::Sepia(try!(parse_percentage(&args[0])))); + loop { + if let Ok(function_name) = input.try(|input| input.expect_function()) { + filters.push(try!(input.parse_nested_block(|input| { + match_ignore_ascii_case! { function_name, + "brightness" => parse_factor(input).map(Filter::Brightness), + "contrast" => parse_factor(input).map(Filter::Contrast), + "grayscale" => parse_factor(input).map(Filter::Grayscale), + "hue-rotate" => Angle::parse(input).map(Filter::HueRotate), + "invert" => parse_factor(input).map(Filter::Invert), + "opacity" => parse_factor(input).map(Filter::Opacity), + "saturate" => parse_factor(input).map(Filter::Saturate), + "sepia" => parse_factor(input).map(Filter::Sepia) + _ => Err(()) + } + }))); } else { - return Err(()) + return Ok(SpecifiedValue::new(filters)) } } - Ok(filters) } - fn parse_percentage(input: &ComponentValue) -> Result<CSSFloat,()> { - match *input { - Number(ref value) => Ok(value.value), - Percentage(ref value) => Ok(value.value / 100.0), + fn parse_factor(input: &mut Parser) -> Result<::values::CSSFloat, ()> { + use cssparser::Token; + match input.next() { + Ok(Token::Number(value)) => Ok(value.value), + Ok(Token::Percentage(value)) => Ok(value.unit_value), _ => Err(()) } } @@ -1989,8 +1802,9 @@ pub mod longhands { pub mod shorthands { - pub use super::*; - pub use super::longhands::*; + use cssparser::Parser; + use parser::ParserContext; + use values::specified; <%def name="shorthand(name, sub_properties)"> <% @@ -1998,13 +1812,18 @@ pub mod shorthands { SHORTHANDS.append(shorthand) %> pub mod ${shorthand.ident} { - use super::*; + use cssparser::Parser; + use parser::ParserContext; + use properties::longhands; + + #[allow(missing_copy_implementations)] pub struct Longhands { % for sub_property in shorthand.sub_properties: - pub ${sub_property.ident}: Option<${sub_property.ident}::SpecifiedValue>, + pub ${sub_property.ident}: + Option<longhands::${sub_property.ident}::SpecifiedValue>, % endfor } - pub fn parse(input: &[ComponentValue], base_url: &Url) -> Result<Longhands, ()> { + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> { ${caller.body()} } } @@ -2014,187 +1833,161 @@ pub mod shorthands { <%self:shorthand name="${name}" sub_properties="${ ' '.join(sub_property_pattern % side for side in ['top', 'right', 'bottom', 'left'])}"> - let mut iter = input.skip_whitespace().map(|c| ${parser_function}(c, base_url).ok()); + use values::specified; + let _unused = context; // zero or more than four values is invalid. // one value sets them all // two values set (top, bottom) and (left, right) // three values set top, (left, right) and bottom // four values set them in order - let top = iter.next().unwrap_or(None); - let right = iter.next().unwrap_or(top.clone()); - let bottom = iter.next().unwrap_or(top.clone()); - let left = iter.next().unwrap_or(right.clone()); - if top.is_some() && right.is_some() && bottom.is_some() && left.is_some() - && iter.next().is_none() { - Ok(Longhands { - % for side in ["top", "right", "bottom", "left"]: - ${to_rust_ident(sub_property_pattern % side)}: ${side}, - % endfor - }) - } else { - Err(()) - } - </%self:shorthand> - </%def> - - // TODO: other background-* properties - <%self:shorthand name="background" - sub_properties="background-color background-position background-repeat background-attachment background-image"> - use std::mem; - - let (mut color, mut image, mut position, mut repeat, mut attachment) = - (None, None, None, None, None); - let mut unused_component_value = None; - let mut any = false; - - for component_value in input.skip_whitespace() { - // Try `background-position` first because it might not use the value. - if position.is_none() { - match mem::replace(&mut unused_component_value, None) { - Some(saved_component_value) => { - // First try parsing a pair of values, then a single value. - match background_position::parse_two(saved_component_value, - component_value) { - Ok(v) => { - position = Some(v); - any = true; - continue - }, - Err(()) => { - match background_position::parse_one(saved_component_value) { - Ok(v) => { - position = Some(v); - any = true; - // We haven't used the current `component_value`; - // keep attempting to parse it below. - }, - // If we get here, parsing failed. - Err(()) => return Err(()) - } - } + let top = try!(${parser_function}(input)); + let right; + let bottom; + let left; + match input.try(${parser_function}) { + Err(()) => { + right = top.clone(); + bottom = top.clone(); + left = top.clone(); + } + Ok(value) => { + right = value; + match input.try(${parser_function}) { + Err(()) => { + bottom = top.clone(); + left = right.clone(); + } + Ok(value) => { + bottom = value; + match input.try(${parser_function}) { + Err(()) => { + left = right.clone(); + } + Ok(value) => { + left = value; } } - None => () // Wait until we have a pair of potential values. - } - } - if color.is_none() { - match background_color::from_component_value(component_value, base_url) { - Ok(v) => { - color = Some(v); - any = true; - continue - }, - Err(()) => () } } - if image.is_none() { - match background_image::from_component_value(component_value, base_url) { - Ok(v) => { - image = Some(v); - any = true; - continue - }, - Err(()) => (), - } - } + } + } + Ok(Longhands { + % for side in ["top", "right", "bottom", "left"]: + ${to_rust_ident(sub_property_pattern % side)}: Some(${side}), + % endfor + }) + </%self:shorthand> + </%def> - if repeat.is_none() { - match background_repeat::from_component_value(component_value, base_url) { - Ok(v) => { - repeat = Some(v); - any = true; - continue - }, - Err(()) => () - } - } + // TODO: other background-* properties + <%self:shorthand name="background" + sub_properties="background-color background-position background-repeat background-attachment background-image"> + use properties::longhands::{background_color, background_position, background_repeat, + background_attachment, background_image}; - if attachment.is_none() { - match background_attachment::from_component_value(component_value, - base_url) { - Ok(v) => { - attachment = Some(v); - any = true; - continue - }, - Err(()) => () - } - } + let mut color = None; + let mut image = None; + let mut position = None; + let mut repeat = None; + let mut attachment = None; + let mut any = false; - // Save the component value. It may the first of a background-position pair. - unused_component_value = Some(component_value); + loop { + if position.is_none() { + if let Ok(value) = input.try(|input| background_position::parse(context, input)) { + position = Some(value); + any = true; + continue } - - if position.is_none() { - // Check for a lone trailing background-position value. - match mem::replace(&mut unused_component_value, None) { - Some(saved_component_value) => { - match background_position::parse_one(saved_component_value) { - Ok(v) => { - position = Some(v); - any = true; - }, - Err(()) => return Err(()) - } - } - None => () - } + } + if color.is_none() { + if let Ok(value) = input.try(|input| background_color::parse(context, input)) { + color = Some(value); + any = true; + continue } - - if any && unused_component_value.is_none() { - Ok(Longhands { - background_color: color, - background_image: image, - background_position: position, - background_repeat: repeat, - background_attachment: attachment, - }) - } else { - Err(()) + } + if image.is_none() { + if let Ok(value) = input.try(|input| background_image::parse(context, input)) { + image = Some(value); + any = true; + continue + } + } + if repeat.is_none() { + if let Ok(value) = input.try(|input| background_repeat::parse(context, input)) { + repeat = Some(value); + any = true; + continue } + } + if attachment.is_none() { + if let Ok(value) = input.try(|input| background_attachment::parse(context, input)) { + attachment = Some(value); + any = true; + continue + } + } + break + } + + if any { + Ok(Longhands { + background_color: color, + background_image: image, + background_position: position, + background_repeat: repeat, + background_attachment: attachment, + }) + } else { + Err(()) + } </%self:shorthand> - ${four_sides_shorthand("margin", "margin-%s", "margin_top::from_component_value")} - ${four_sides_shorthand("padding", "padding-%s", "padding_top::from_component_value")} + ${four_sides_shorthand("margin", "margin-%s", "specified::LengthOrPercentageOrAuto::parse")} + ${four_sides_shorthand("padding", "padding-%s", "specified::LengthOrPercentage::parse")} - pub fn parse_color(value: &ComponentValue, _base_url: &Url) -> Result<specified::CSSColor, ()> { - specified::CSSColor::parse(value) - } - ${four_sides_shorthand("border-color", "border-%s-color", "parse_color")} + ${four_sides_shorthand("border-color", "border-%s-color", "specified::CSSColor::parse")} ${four_sides_shorthand("border-style", "border-%s-style", - "border_top_style::from_component_value")} - ${four_sides_shorthand("border-width", "border-%s-width", "parse_border_width")} + "specified::BorderStyle::parse")} + ${four_sides_shorthand("border-width", "border-%s-width", + "specified::parse_border_width")} - pub fn parse_border(input: &[ComponentValue], base_url: &Url) + pub fn parse_border(context: &ParserContext, input: &mut Parser) -> Result<(Option<specified::CSSColor>, - Option<border_top_style::SpecifiedValue>, + Option<specified::BorderStyle>, Option<specified::Length>), ()> { + use values::specified; + let _unused = context; let mut color = None; let mut style = None; let mut width = None; let mut any = false; - for component_value in input.skip_whitespace() { + loop { if color.is_none() { - match specified::CSSColor::parse(component_value) { - Ok(c) => { color = Some(c); any = true; continue }, - Err(()) => () + if let Ok(value) = input.try(specified::CSSColor::parse) { + color = Some(value); + any = true; + continue } } if style.is_none() { - match border_top_style::from_component_value(component_value, base_url) { - Ok(s) => { style = Some(s); any = true; continue }, - Err(()) => () + if let Ok(value) = input.try(specified::BorderStyle::parse) { + style = Some(value); + any = true; + continue } } if width.is_none() { - match parse_border_width(component_value, base_url) { - Ok(w) => { width = Some(w); any = true; continue }, - Err(()) => () + if let Ok(value) = input.try(specified::parse_border_width) { + width = Some(value); + any = true; + continue } } - return Err(()) + break } if any { Ok((color, style, width)) } else { Err(()) } } @@ -2205,12 +1998,11 @@ pub mod shorthands { 'border-%s-%s' % (side, prop) for prop in ['color', 'style', 'width'] )}"> - parse_border(input, base_url).map(|(color, style, width)| { - Longhands { - % for prop in ["color", "style", "width"]: - ${"border_%s_%s: %s," % (side, prop, prop)} - % endfor - } + let (color, style, width) = try!(super::parse_border(context, input)); + Ok(Longhands { + % for prop in ["color", "style", "width"]: + ${"border_%s_%s: %s," % (side, prop, prop)} + % endfor }) </%self:shorthand> % endfor @@ -2220,14 +2012,13 @@ pub mod shorthands { for side in ['top', 'right', 'bottom', 'left'] for prop in ['color', 'style', 'width'] )}"> - parse_border(input, base_url).map(|(color, style, width)| { - Longhands { - % for side in ["top", "right", "bottom", "left"]: - % for prop in ["color", "style", "width"]: - ${"border_%s_%s: %s.clone()," % (side, prop, prop)} - % endfor + let (color, style, width) = try!(super::parse_border(context, input)); + Ok(Longhands { + % for side in ["top", "right", "bottom", "left"]: + % for prop in ["color", "style", "width"]: + ${"border_%s_%s: %s.clone()," % (side, prop, prop)} % endfor - } + % endfor }) </%self:shorthand> @@ -2235,27 +2026,21 @@ pub mod shorthands { 'border-%s-radius' % (corner) for corner in ['top-left', 'top-right', 'bottom-right', 'bottom-left'] )}"> - - use std::iter::Peekable; - - let _ignored = base_url; - - fn parse_one_set_of_border_radii<'a,I>(mut input: Peekable< &'a ComponentValue,I >) - -> Result<[specified::LengthOrPercentage, ..4],()> - where I: Iterator< &'a ComponentValue > { - let (mut count, mut values) = (0u, [specified::LengthOrPercentage::Length(specified::Length::Au(Au(0))), ..4]); + use servo_util::geometry::Au; + use values::specified::{Length, LengthOrPercentage}; + let _ignored = context; + + fn parse_one_set_of_border_radii(mut input: &mut Parser) + -> Result<[LengthOrPercentage; 4], ()> { + let mut count = 0; + let mut values = [LengthOrPercentage::Length(Length::Au(Au(0))); 4]; while count < 4 { - let token = match input.peek() { - None => break, - Some(token) => *token, - }; - let value = match specified::LengthOrPercentage::parse(token) { - Err(_) => break, - Ok(value) => value, - }; - drop(input.next()); - values[count] = value; - count += 1 + if let Ok(value) = input.try(LengthOrPercentage::parse) { + values[count] = value; + count += 1; + } else { + break + } } match count { @@ -2267,60 +2052,48 @@ pub mod shorthands { } } - let input = input.skip_whitespace().peekable(); let radii = try!(parse_one_set_of_border_radii(input)); // TODO(pcwalton): Elliptical borders. Ok(Longhands { - border_top_left_radius: Some(border_top_left_radius::SpecifiedValue { - radius: radii[0], - }), - border_top_right_radius: Some(border_top_left_radius::SpecifiedValue { - radius: radii[1], - }), - border_bottom_right_radius: Some(border_top_left_radius::SpecifiedValue { - radius: radii[2], - }), - border_bottom_left_radius: Some(border_top_left_radius::SpecifiedValue { - radius: radii[3], - }), + border_top_left_radius: Some(radii[0]), + border_top_right_radius: Some(radii[1]), + border_bottom_right_radius: Some(radii[2]), + border_bottom_left_radius: Some(radii[3]), }) </%self:shorthand> <%self:shorthand name="outline" sub_properties="outline-color outline-style outline-width"> - let (mut color, mut style, mut width, mut any) = (None, None, None, false); - for component_value in input.skip_whitespace() { + use values::specified; + + let _unused = context; + let mut color = None; + let mut style = None; + let mut width = None; + let mut any = false; + loop { if color.is_none() { - match specified::CSSColor::parse(component_value) { - Ok(c) => { - color = Some(c); - any = true; - continue - } - Err(()) => {} + if let Ok(value) = input.try(specified::CSSColor::parse) { + color = Some(value); + any = true; + continue } } if style.is_none() { - match border_top_style::from_component_value(component_value, base_url) { - Ok(s) => { - style = Some(s); - any = true; - continue - } - Err(()) => {} + if let Ok(value) = input.try(specified::BorderStyle::parse) { + style = Some(value); + any = true; + continue } } if width.is_none() { - match parse_border_width(component_value, base_url) { - Ok(w) => { - width = Some(w); - any = true; - continue - } - Err(()) => {} + if let Ok(value) = input.try(specified::parse_border_width) { + width = Some(value); + any = true; + continue } } - return Err(()) + break } if any { Ok(Longhands { @@ -2335,71 +2108,55 @@ pub mod shorthands { <%self:shorthand name="font" sub_properties="font-style font-variant font-weight font-size line-height font-family"> - let mut iter = input.skip_whitespace(); - let mut nb_normals = 0u; + use properties::longhands::{font_style, font_variant, font_weight, font_size, + line_height, font_family}; + let mut nb_normals = 0; let mut style = None; let mut variant = None; let mut weight = None; - let mut size = None; - let mut line_height = None; - for component_value in iter { + let size; + loop { // Special-case 'normal' because it is valid in each of // font-style, font-weight and font-variant. // Leaves the values to None, 'normal' is the initial value for each of them. - match get_ident_lower(component_value) { - Ok(ref ident) if ident.as_slice().eq_ignore_ascii_case("normal") => { - nb_normals += 1; - continue; - } - _ => {} + if input.try(|input| input.expect_ident_matching("normal")).is_ok() { + nb_normals += 1; + continue; } if style.is_none() { - match font_style::from_component_value(component_value, base_url) { - Ok(s) => { style = Some(s); continue }, - Err(()) => () + if let Ok(value) = input.try(|input| font_style::parse(context, input)) { + style = Some(value); + continue } } if weight.is_none() { - match font_weight::from_component_value(component_value, base_url) { - Ok(w) => { weight = Some(w); continue }, - Err(()) => () + if let Ok(value) = input.try(|input| font_weight::parse(context, input)) { + weight = Some(value); + continue } } if variant.is_none() { - match font_variant::from_component_value(component_value, base_url) { - Ok(v) => { variant = Some(v); continue }, - Err(()) => () + if let Ok(value) = input.try(|input| font_variant::parse(context, input)) { + variant = Some(value); + continue } } - match font_size::from_component_value(component_value, base_url) { - Ok(s) => { size = Some(s); break }, - Err(()) => return Err(()) - } + size = Some(try!(font_size::parse(context, input))); + break } #[inline] - fn count<T>(opt: &Option<T>) -> uint { - match opt { - &Some(_) => 1, - &None => 0, - } + fn count<T>(opt: &Option<T>) -> u8 { + if opt.is_some() { 1 } else { 0 } } if size.is_none() || (count(&style) + count(&weight) + count(&variant) + nb_normals) > 3 { return Err(()) } - let mut copied_iter = iter.clone(); - match copied_iter.next() { - Some(&Delim('/')) => { - iter = copied_iter; - line_height = match iter.next() { - Some(v) => line_height::from_component_value(v, base_url).ok(), - _ => return Err(()), - }; - if line_height.is_none() { return Err(()) } - } - _ => () - } - let family = try!(parse_comma_separated( - &mut BufferedIter::new(iter), font_family::parse_one_family)); + let line_height = if input.try(|input| input.expect_delim('/')).is_ok() { + Some(try!(line_height::parse(context, input))) + } else { + None + }; + let family = try!(input.parse_comma_separated(font_family::parse_one_family)); Ok(Longhands { font_style: style, font_variant: variant, @@ -2413,64 +2170,54 @@ pub mod shorthands { // Per CSS-TEXT 6.2, "for legacy reasons, UAs must treat `word-wrap` as an alternate name for // the `overflow-wrap` property, as if it were a shorthand of `overflow-wrap`." <%self:shorthand name="word-wrap" sub_properties="overflow-wrap"> - overflow_wrap::parse(input, base_url).map(|specified_value| { - Longhands { - overflow_wrap: Some(specified_value), - } + use properties::longhands::overflow_wrap; + Ok(Longhands { + overflow_wrap: Some(try!(overflow_wrap::parse(context, input))), }) </%self:shorthand> <%self:shorthand name="list-style" sub_properties="list-style-image list-style-position list-style-type"> + use properties::longhands::{list_style_image, list_style_position, list_style_type}; + // `none` is ambiguous until we've finished parsing the shorthands, so we count the number // of times we see it. let mut nones = 0u8; let (mut image, mut position, mut list_style_type, mut any) = (None, None, None, false); - for component_value in input.skip_whitespace() { - match component_value { - &Ident(ref value) if value.eq_ignore_ascii_case("none") => { - nones = nones + 1; - if nones > 2 { - return Err(()) - } - any = true; - continue + loop { + if input.try(|input| input.expect_ident_matching("none")).is_ok() { + nones = nones + 1; + if nones > 2 { + return Err(()) } - _ => {} + any = true; + continue } if list_style_type.is_none() { - match list_style_type::from_component_value(component_value, base_url) { - Ok(v) => { - list_style_type = Some(v); - any = true; - continue - }, - Err(()) => () + if let Ok(value) = input.try(|input| list_style_type::parse(context, input)) { + list_style_type = Some(value); + any = true; + continue } } if image.is_none() { - match list_style_image::from_component_value(component_value, base_url) { - Ok(v) => { - image = Some(v); - any = true; - continue - }, - Err(()) => (), + if let Ok(value) = input.try(|input| list_style_image::parse(context, input)) { + image = Some(value); + any = true; + continue } } if position.is_none() { - match list_style_position::from_component_value(component_value, base_url) { - Ok(v) => { - position = Some(v); - any = true; - continue - }, - Err(()) => () + if let Ok(value) = input.try(|input| list_style_position::parse(context, input)) { + position = Some(value); + any = true; + continue } } + break } // If there are two `none`s, then we can't have a type or image; if there is one `none`, @@ -2481,14 +2228,14 @@ pub mod shorthands { Ok(Longhands { list_style_position: position, list_style_image: Some(None), - list_style_type: Some(list_style_type::T::none), + list_style_type: Some(list_style_type::SpecifiedValue::none), }) } (true, 1, None, Some(image)) => { Ok(Longhands { list_style_position: position, list_style_image: Some(image), - list_style_type: Some(list_style_type::T::none), + list_style_type: Some(list_style_type::SpecifiedValue::none), }) } (true, 1, Some(list_style_type), None) => { @@ -2502,7 +2249,7 @@ pub mod shorthands { Ok(Longhands { list_style_position: position, list_style_image: Some(None), - list_style_type: Some(list_style_type::T::none), + list_style_type: Some(list_style_type::SpecifiedValue::none), }) } (true, 0, list_style_type, image) => { @@ -2525,7 +2272,7 @@ mod property_bit_field { use std::mem; pub struct PropertyBitField { - storage: [uint, ..(${len(LONGHANDS)} - 1 + uint::BITS) / uint::BITS] + storage: [uint; (${len(LONGHANDS)} - 1 + uint::BITS) / uint::BITS] } impl PropertyBitField { @@ -2562,6 +2309,7 @@ mod property_bit_field { /// Declarations are stored in reverse order. /// Overridden declarations are skipped. +#[derive(Show, PartialEq)] pub struct PropertyDeclarationBlock { pub important: Arc<Vec<PropertyDeclaration>>, pub normal: Arc<Vec<PropertyDeclaration>>, @@ -2569,49 +2317,89 @@ pub struct PropertyDeclarationBlock { pub fn parse_style_attribute(input: &str, base_url: &Url) -> PropertyDeclarationBlock { - parse_property_declaration_list(tokenize(input), base_url) + let context = ParserContext { + stylesheet_origin: Origin::Author, + base_url: base_url, + namespaces: NamespaceMap::new(), + }; + parse_property_declaration_list(&context, &mut Parser::new(input)) } -pub fn parse_property_declaration_list<I: Iterator<Node>>(input: I, base_url: &Url) -> PropertyDeclarationBlock { - let mut important_declarations = vec!(); - let mut normal_declarations = vec!(); - let mut important_seen = PropertyBitField::new(); - let mut normal_seen = PropertyBitField::new(); - let items: Vec<DeclarationListItem> = - ErrorLoggerIterator(parse_declaration_list(input)).collect(); - for item in items.into_iter().rev() { - match item { - DeclarationListItem::AtRule(rule) => log_css_error( - rule.location, format!("Unsupported at-rule in declaration list: @{}", rule.name).as_slice()), - DeclarationListItem::Declaration(Declaration{ location: l, name: n, value: v, important: i}) => { - // TODO: only keep the last valid declaration for a given name. - let (list, seen) = if i { - (&mut important_declarations, &mut important_seen) - } else { - (&mut normal_declarations, &mut normal_seen) - }; - match PropertyDeclaration::parse(n.as_slice(), v.as_slice(), list, base_url, seen) { - PropertyDeclarationParseResult::UnknownProperty => log_css_error(l, format!( - "Unsupported property: {}:{}", n, v.to_css_string()).as_slice()), - PropertyDeclarationParseResult::ExperimentalProperty => log_css_error(l, format!( - "Experimental property, use `servo --enable_experimental` \ - or `servo -e` to enable: {}:{}", - n, v.to_css_string()).as_slice()), - PropertyDeclarationParseResult::InvalidValue => log_css_error(l, format!( - "Invalid value: {}:{}", n, v.to_css_string()).as_slice()), - PropertyDeclarationParseResult::ValidOrIgnoredDeclaration => (), - } +struct PropertyDeclarationParser<'a, 'b: 'a> { + context: &'a ParserContext<'b>, + important_declarations: Vec<PropertyDeclaration>, + normal_declarations: Vec<PropertyDeclaration>, +} + + +/// Default methods reject all at rules. +impl<'a, 'b> AtRuleParser<(), ()> for PropertyDeclarationParser<'a, 'b> {} + + +impl<'a, 'b> DeclarationParser<()> for PropertyDeclarationParser<'a, 'b> { + fn parse_value(&mut self, name: &str, input: &mut Parser) -> Result<(), ()> { + let mut results = vec![]; + let important = try!(input.parse_entirely(|input| { + match PropertyDeclaration::parse(name, self.context, input, &mut results) { + PropertyDeclarationParseResult::ValidOrIgnoredDeclaration => {} + _ => return Err(()) } + Ok(input.try(parse_important).is_ok()) + })); + if important { + self.important_declarations.push_all(results.as_slice()); + } else { + self.normal_declarations.push_all(results.as_slice()); } + Ok(()) } +} + + +pub fn parse_property_declaration_list(context: &ParserContext, input: &mut Parser) + -> PropertyDeclarationBlock { + let parser = PropertyDeclarationParser { + context: context, + important_declarations: vec![], + normal_declarations: vec![], + }; + let parser = DeclarationListParser::new(input, parser).run(); PropertyDeclarationBlock { - important: Arc::new(important_declarations), - normal: Arc::new(normal_declarations), + important: Arc::new(deduplicate_property_declarations(parser.important_declarations)), + normal: Arc::new(deduplicate_property_declarations(parser.normal_declarations)), + } +} + + +/// Only keep the last declaration for any given property. +/// The input is in source order, output in reverse source order. +fn deduplicate_property_declarations(declarations: Vec<PropertyDeclaration>) + -> Vec<PropertyDeclaration> { + let mut deduplicated = vec![]; + let mut seen = PropertyBitField::new(); + for declaration in declarations.into_iter().rev() { + match declaration { + % for property in LONGHANDS: + PropertyDeclaration::${property.camel_case}(..) => { + % if property.derived_from is None: + if seen.get_${property.ident}() { + continue + } + seen.set_${property.ident}() + % else: + unreachable!(); + % endif + }, + % endfor + } + deduplicated.push(declaration) } + deduplicated } +#[derive(Copy, PartialEq, Eq, Show)] pub enum CSSWideKeyword { InitialKeyword, InheritKeyword, @@ -2619,20 +2407,18 @@ pub enum CSSWideKeyword { } impl CSSWideKeyword { - pub fn parse(input: &[ComponentValue]) -> Result<CSSWideKeyword, ()> { - one_component_value(input).and_then(get_ident_lower).and_then(|keyword| { - match keyword.as_slice() { - "initial" => Ok(CSSWideKeyword::InitialKeyword), - "inherit" => Ok(CSSWideKeyword::InheritKeyword), - "unset" => Ok(CSSWideKeyword::UnsetKeyword), - _ => Err(()) - } - }) + pub fn parse(input: &mut Parser) -> Result<CSSWideKeyword, ()> { + match_ignore_ascii_case! { try!(input.expect_ident()), + "initial" => Ok(CSSWideKeyword::InitialKeyword), + "inherit" => Ok(CSSWideKeyword::InheritKeyword), + "unset" => Ok(CSSWideKeyword::UnsetKeyword) + _ => Err(()) + } } } -#[deriving(Clone, PartialEq, Eq, Copy)] +#[derive(Clone, PartialEq, Eq, Copy, Show)] pub enum DeclaredValue<T> { SpecifiedValue(T), Initial, @@ -2645,22 +2431,22 @@ pub enum DeclaredValue<T> { impl<T: Show> DeclaredValue<T> { pub fn specified_value(&self) -> Option<String> { match self { - &DeclaredValue::SpecifiedValue(ref inner) => Some(format!("{}", inner)), + &DeclaredValue::SpecifiedValue(ref inner) => Some(format!("{:?}", inner)), &DeclaredValue::Initial => None, - &DeclaredValue::Inherit => Some("inherit".into_string()), + &DeclaredValue::Inherit => Some("inherit".to_owned()), } } } -#[deriving(Clone)] +#[derive(Clone, PartialEq)] pub enum PropertyDeclaration { % for property in LONGHANDS: - ${property.camel_case}Declaration(DeclaredValue<longhands::${property.ident}::SpecifiedValue>), + ${property.camel_case}(DeclaredValue<longhands::${property.ident}::SpecifiedValue>), % endfor } -#[deriving(Eq, PartialEq, Copy)] +#[derive(Eq, PartialEq, Copy)] pub enum PropertyDeclarationParseResult { UnknownProperty, ExperimentalProperty, @@ -2669,14 +2455,14 @@ pub enum PropertyDeclarationParseResult { } impl PropertyDeclaration { - pub fn name(&self) -> String { + pub fn name(&self) -> &'static str { match self { % for property in LONGHANDS: % if property.derived_from is None: - &PropertyDeclaration::${property.camel_case}Declaration(..) => "${property.name}".into_string(), + &PropertyDeclaration::${property.camel_case}(..) => "${property.name}", % endif % endfor - _ => "".into_string(), + _ => "", } } @@ -2684,32 +2470,30 @@ impl PropertyDeclaration { match self { % for property in LONGHANDS: % if property.derived_from is None: - &PropertyDeclaration::${property.camel_case}Declaration(ref value) => + &PropertyDeclaration::${property.camel_case}(ref value) => value.specified_value() - .unwrap_or_else(|| format!("{}", longhands::${property.ident}::get_initial_value())), + .unwrap_or_else(|| format!("{:?}", longhands::${property.ident}::get_initial_value())), % endif % endfor - decl => panic!("unsupported property declaration: {}", decl.name()), + decl => panic!("unsupported property declaration: {:?}", decl.name()), } } pub fn matches(&self, name: &str) -> bool { - let name_lower = name.as_slice().to_ascii_lower(); + let name_lower = name.as_slice().to_ascii_lowercase(); match (self, name_lower.as_slice()) { % for property in LONGHANDS: % if property.derived_from is None: - (&PropertyDeclaration::${property.camel_case}Declaration(..), "${property.name}") => true, + (&PropertyDeclaration::${property.camel_case}(..), "${property.name}") => true, % endif % endfor _ => false, } } - pub fn parse(name: &str, value: &[ComponentValue], - result_list: &mut Vec<PropertyDeclaration>, - base_url: &Url, - seen: &mut PropertyBitField) -> PropertyDeclarationParseResult { - match name.to_ascii_lower().as_slice() { + pub fn parse(name: &str, context: &ParserContext, input: &mut Parser, + result_list: &mut Vec<PropertyDeclaration>) -> PropertyDeclarationParseResult { + match_ignore_ascii_case! { name, % for property in LONGHANDS: % if property.derived_from is None: "${property.name}" => { @@ -2718,13 +2502,9 @@ impl PropertyDeclaration { return PropertyDeclarationParseResult::ExperimentalProperty } % endif - if seen.get_${property.ident}() { - return PropertyDeclarationParseResult::ValidOrIgnoredDeclaration - } - match longhands::${property.ident}::parse_declared(value, base_url) { + match longhands::${property.ident}::parse_declared(context, input) { Ok(value) => { - seen.set_${property.ident}(); - result_list.push(PropertyDeclaration::${property.camel_case}Declaration(value)); + result_list.push(PropertyDeclaration::${property.camel_case}(value)); PropertyDeclarationParseResult::ValidOrIgnoredDeclaration }, Err(()) => PropertyDeclarationParseResult::InvalidValue, @@ -2736,56 +2516,40 @@ impl PropertyDeclaration { % endfor % for shorthand in SHORTHANDS: "${shorthand.name}" => { - if ${" && ".join("seen.get_%s()" % sub_property.ident - for sub_property in shorthand.sub_properties)} { - return PropertyDeclarationParseResult::ValidOrIgnoredDeclaration - } - match CSSWideKeyword::parse(value) { + match input.try(CSSWideKeyword::parse) { Ok(CSSWideKeyword::InheritKeyword) => { % for sub_property in shorthand.sub_properties: - if !seen.get_${sub_property.ident}() { - seen.set_${sub_property.ident}(); - result_list.push( - PropertyDeclaration::${sub_property.camel_case}Declaration( - DeclaredValue::Inherit)); - } + result_list.push( + PropertyDeclaration::${sub_property.camel_case}( + DeclaredValue::Inherit)); % endfor PropertyDeclarationParseResult::ValidOrIgnoredDeclaration }, Ok(CSSWideKeyword::InitialKeyword) => { % for sub_property in shorthand.sub_properties: - if !seen.get_${sub_property.ident}() { - seen.set_${sub_property.ident}(); - result_list.push( - PropertyDeclaration::${sub_property.camel_case}Declaration( - DeclaredValue::Initial)); - } + result_list.push( + PropertyDeclaration::${sub_property.camel_case}( + DeclaredValue::Initial)); % endfor PropertyDeclarationParseResult::ValidOrIgnoredDeclaration }, Ok(CSSWideKeyword::UnsetKeyword) => { % for sub_property in shorthand.sub_properties: - if !seen.get_${sub_property.ident}() { - seen.set_${sub_property.ident}(); - result_list.push(PropertyDeclaration::${sub_property.camel_case}Declaration( - DeclaredValue::${"Inherit" if sub_property.style_struct.inherited else "Initial"} - )); - } + result_list.push(PropertyDeclaration::${sub_property.camel_case}( + DeclaredValue::${"Inherit" if sub_property.style_struct.inherited else "Initial"} + )); % endfor PropertyDeclarationParseResult::ValidOrIgnoredDeclaration }, - Err(()) => match shorthands::${shorthand.ident}::parse(value, base_url) { + Err(()) => match shorthands::${shorthand.ident}::parse(context, input) { Ok(result) => { % for sub_property in shorthand.sub_properties: - if !seen.get_${sub_property.ident}() { - seen.set_${sub_property.ident}(); - result_list.push(PropertyDeclaration::${sub_property.camel_case}Declaration( - match result.${sub_property.ident} { - Some(value) => DeclaredValue::SpecifiedValue(value), - None => DeclaredValue::Initial, - } - )); - } + result_list.push(PropertyDeclaration::${sub_property.camel_case}( + match result.${sub_property.ident} { + Some(value) => DeclaredValue::SpecifiedValue(value), + None => DeclaredValue::Initial, + } + )); % endfor PropertyDeclarationParseResult::ValidOrIgnoredDeclaration }, @@ -2794,7 +2558,11 @@ impl PropertyDeclaration { } }, % endfor - _ => PropertyDeclarationParseResult::UnknownProperty, + + // Hack to work around quirks of macro_rules parsing in match_ignore_ascii_case! + "_nonexistent" => PropertyDeclarationParseResult::UnknownProperty + + _ => PropertyDeclarationParseResult::UnknownProperty } } } @@ -2811,7 +2579,7 @@ pub mod style_structs { % for style_struct in STYLE_STRUCTS: #[allow(missing_copy_implementations)] - #[deriving(PartialEq, Clone)] + #[derive(PartialEq, Clone)] pub struct ${style_struct.name} { % for longhand in style_struct.longhands: pub ${longhand.ident}: longhands::${longhand.ident}::computed_value::T, @@ -2820,7 +2588,7 @@ pub mod style_structs { % endfor } -#[deriving(Clone)] +#[derive(Clone)] pub struct ComputedValues { % for style_struct in STYLE_STRUCTS: ${style_struct.ident}: Arc<style_structs::${style_struct.name}>, @@ -2838,7 +2606,7 @@ impl ComputedValues { /// Usage example: /// let top_color = style.resolve_color(style.Border.border_top_color); #[inline] - pub fn resolve_color(&self, color: computed::CSSColor) -> RGBA { + pub fn resolve_color(&self, color: Color) -> RGBA { match color { Color::RGBA(rgba) => rgba, Color::CurrentColor => self.get_color().color, @@ -3024,7 +2792,7 @@ fn cascade_with_cached_declarations(applicable_declarations: &[DeclarationBlock] % for style_struct in STYLE_STRUCTS: % for property in style_struct.longhands: % if property.derived_from is None: - PropertyDeclaration::${property.camel_case}Declaration(ref ${'_' if not style_struct.inherited else ''}declared_value) => { + PropertyDeclaration::${property.camel_case}(ref ${'_' if not style_struct.inherited else ''}declared_value) => { % if style_struct.inherited: if seen.get_${property.ident}() { continue @@ -3070,7 +2838,7 @@ fn cascade_with_cached_declarations(applicable_declarations: &[DeclarationBlock] % endif } % else: - PropertyDeclaration::${property.camel_case}Declaration(_) => { + PropertyDeclaration::${property.camel_case}(_) => { // Do not allow stylesheets to set derived properties. } % endif @@ -3150,7 +2918,7 @@ pub fn cascade(applicable_declarations: &[DeclarationBlock], DeclaredValue::Inherit => inherited_style.$style_struct_getter().$property.clone(), } }; - ) + ); // Initialize `context` // Declarations blocks are already stored in increasing precedence order. @@ -3158,7 +2926,7 @@ pub fn cascade(applicable_declarations: &[DeclarationBlock], // Declarations are stored in reverse source order, we want them in forward order here. for declaration in sub_list.declarations.iter().rev() { match *declaration { - PropertyDeclaration::FontSizeDeclaration(ref value) => { + PropertyDeclaration::FontSize(ref value) => { context.font_size = match *value { DeclaredValue::SpecifiedValue(specified_value) => computed::compute_Au_with_font_size( specified_value, context.inherited_font_size, context.root_font_size), @@ -3166,35 +2934,35 @@ pub fn cascade(applicable_declarations: &[DeclarationBlock], DeclaredValue::Inherit => context.inherited_font_size, } } - PropertyDeclaration::ColorDeclaration(ref value) => { + PropertyDeclaration::Color(ref value) => { context.color = match *value { DeclaredValue::SpecifiedValue(ref specified_value) => specified_value.parsed, DeclaredValue::Initial => longhands::color::get_initial_value(), DeclaredValue::Inherit => inherited_style.get_color().color.clone(), }; } - PropertyDeclaration::DisplayDeclaration(ref value) => { + PropertyDeclaration::Display(ref value) => { context.display = get_specified!(get_box, display, value); } - PropertyDeclaration::PositionDeclaration(ref value) => { + PropertyDeclaration::Position(ref value) => { context.positioned = match get_specified!(get_box, position, value) { - longhands::position::T::absolute | longhands::position::T::fixed => true, + longhands::position::SpecifiedValue::absolute | + longhands::position::SpecifiedValue::fixed => true, _ => false, } } - PropertyDeclaration::FloatDeclaration(ref value) => { + PropertyDeclaration::Float(ref value) => { context.floated = get_specified!(get_box, float, value) - != longhands::float::T::none; + != longhands::float::SpecifiedValue::none; } - PropertyDeclaration::TextDecorationDeclaration(ref value) => { + PropertyDeclaration::TextDecoration(ref value) => { context.text_decoration = get_specified!(get_text, text_decoration, value); } % for side in ["top", "right", "bottom", "left"]: - PropertyDeclaration::Border${side.capitalize()}StyleDeclaration(ref value) => { + PropertyDeclaration::Border${side.capitalize()}Style(ref value) => { context.border_${side}_present = match get_specified!(get_border, border_${side}_style, value) { - longhands::border_top_style::T::none | - longhands::border_top_style::T::hidden => false, + BorderStyle::none | BorderStyle::hidden => false, _ => true, }; } @@ -3236,7 +3004,7 @@ pub fn cascade(applicable_declarations: &[DeclarationBlock], % for style_struct in STYLE_STRUCTS: % for property in style_struct.longhands: % if property.derived_from is None: - PropertyDeclaration::${property.camel_case}Declaration(ref declared_value) => { + PropertyDeclaration::${property.camel_case}(ref declared_value) => { if seen.get_${property.ident}() { continue } @@ -3276,7 +3044,7 @@ pub fn cascade(applicable_declarations: &[DeclarationBlock], % endif } % else: - PropertyDeclaration::${property.camel_case}Declaration(_) => { + PropertyDeclaration::${property.camel_case}(_) => { // Do not allow stylesheets to set derived properties. } % endif @@ -3368,9 +3136,9 @@ pub fn is_supported_property(property: &str) -> bool { } #[macro_export] -macro_rules! css_properties_accessors( - ($macro: ident) => ( - $macro!( +macro_rules! css_properties_accessors { + ($macro_name: ident) => { + $macro_name! { % for property in SHORTHANDS + LONGHANDS: ## Servo internal CSS properties are not accessible. ## FIXME: Add BinaryName WebIDL annotation (#4435). @@ -3382,16 +3150,16 @@ macro_rules! css_properties_accessors( % endif % endif % endfor - ) - ) -) + } + } +} pub fn longhands_from_shorthand(shorthand: &str) -> Option<Vec<String>> { match shorthand { % for property in SHORTHANDS: "${property.name}" => Some(vec!( % for sub in property.sub_properties: - "${sub.name}".into_string(), + "${sub.name}".to_owned(), % endfor )), % endfor @@ -3408,7 +3176,7 @@ pub mod computed_values { pub use super::longhands::border_top_style::computed_value as border_style; pub use cssparser::RGBA; - pub use super::common_types::computed::{ + pub use values::computed::{ LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; diff --git a/components/style/selector_matching.rs b/components/style/selector_matching.rs index 0870d99711a..1f5688ee140 100644 --- a/components/style/selector_matching.rs +++ b/components/style/selector_matching.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use std::ascii::AsciiExt; +use std::cmp::Ordering; use std::collections::HashMap; use std::hash::Hash; use std::sync::Arc; @@ -22,14 +23,8 @@ use properties::{PropertyDeclaration, PropertyDeclarationBlock}; use selectors::{CaseSensitivity, Combinator, CompoundSelector, LocalName}; use selectors::{PseudoElement, SelectorList, SimpleSelector}; use selectors::{get_selector_list_selectors}; -use stylesheets::{Stylesheet, iter_stylesheet_media_rules, iter_stylesheet_style_rules}; +use stylesheets::{Stylesheet, iter_stylesheet_media_rules, iter_stylesheet_style_rules, Origin}; -#[deriving(Clone, PartialEq, Eq, Copy)] -pub enum StylesheetOrigin { - UserAgent, - Author, - User, -} /// The definition of whitespace per CSS Selectors Level 3 § 4. pub static SELECTOR_WHITESPACE: &'static [char] = &[' ', '\t', '\n', '\r', '\x0C']; @@ -189,14 +184,14 @@ impl SelectorMap { match SelectorMap::get_id_name(&rule) { Some(id_name) => { - self.id_hash.find_push(id_name, rule); + find_push(&mut self.id_hash, id_name, rule); return; } None => {} } match SelectorMap::get_class_name(&rule) { Some(class_name) => { - self.class_hash.find_push(class_name, rule); + find_push(&mut self.class_hash, class_name, rule); return; } None => {} @@ -204,8 +199,8 @@ impl SelectorMap { match SelectorMap::get_local_name(&rule) { Some(LocalName { name, lower_name }) => { - self.local_name_hash.find_push(name, rule.clone()); - self.lower_local_name_hash.find_push(lower_name, rule); + find_push(&mut self.local_name_hash, name, rule.clone()); + find_push(&mut self.lower_local_name_hash, lower_name, rule); return; } None => {} @@ -300,10 +295,10 @@ impl Stylist { for &filename in ["user-agent.css", "servo.css", "presentational-hints.css"].iter() { let ua_stylesheet = Stylesheet::from_bytes( read_resource_file(&[filename]).unwrap().as_slice(), - Url::parse(format!("chrome:///{}", filename).as_slice()).unwrap(), + Url::parse(format!("chrome:///{:?}", filename).as_slice()).unwrap(), None, None, - StylesheetOrigin::UserAgent); + Origin::UserAgent); stylist.add_stylesheet(ua_stylesheet); } stylist @@ -318,17 +313,17 @@ impl Stylist { for stylesheet in self.stylesheets.iter() { let (mut element_map, mut before_map, mut after_map) = match stylesheet.origin { - StylesheetOrigin::UserAgent => ( + Origin::UserAgent => ( &mut self.element_map.user_agent, &mut self.before_map.user_agent, &mut self.after_map.user_agent, ), - StylesheetOrigin::Author => ( + Origin::Author => ( &mut self.element_map.author, &mut self.before_map.author, &mut self.after_map.author, ), - StylesheetOrigin::User => ( + Origin::User => ( &mut self.element_map.user, &mut self.before_map.user, &mut self.after_map.user, @@ -395,7 +390,7 @@ impl Stylist { Url::parse("chrome:///quirks-mode.css").unwrap(), None, None, - StylesheetOrigin::UserAgent)) + Origin::UserAgent)) } pub fn add_stylesheet(&mut self, stylesheet: Stylesheet) { @@ -518,7 +513,7 @@ impl PerPseudoElementSelectorMap { } } -#[deriving(Clone)] +#[derive(Clone)] struct Rule { // This is an Arc because Rule will essentially be cloned for every node // that it matches. Selector contains an owned vector (through @@ -529,7 +524,7 @@ struct Rule { /// A property declaration together with its precedence among rules of equal specificity so that /// we can sort them. -#[deriving(Clone)] +#[derive(Clone, Show)] pub struct DeclarationBlock { pub declarations: Arc<Vec<PropertyDeclaration>>, source_order: uint, @@ -624,7 +619,7 @@ fn matches_compound_selector<'a,E,N>(selector: &CompoundSelector, /// However since the selector "c1" raises /// NotMatchedAndRestartFromClosestDescendant. So the selector /// "b1 + c1 > b2 ~ " doesn't match and restart matching from "d1". -#[deriving(PartialEq, Eq, Copy)] +#[derive(PartialEq, Eq, Copy)] enum SelectorMatchingResult { Matched, NotMatchedAndRestartFromClosestLaterSibling, @@ -764,7 +759,6 @@ fn matches_compound_selector_internal<'a,E,N>(selector: &CompoundSelector, } bitflags! { - #[deriving(Copy)] flags CommonStyleAffectingAttributes: u8 { const HIDDEN_ATTRIBUTE = 0x01, const NO_WRAP_ATTRIBUTE = 0x02, @@ -779,7 +773,7 @@ pub struct CommonStyleAffectingAttributeInfo { pub mode: CommonStyleAffectingAttributeMode, } -#[deriving(Copy)] +#[derive(Copy)] pub enum CommonStyleAffectingAttributeMode { IsPresent(CommonStyleAffectingAttributes), IsEqual(&'static str, CommonStyleAffectingAttributes), @@ -787,7 +781,7 @@ pub enum CommonStyleAffectingAttributeMode { // NB: This must match the order in `layout::css::matching::CommonStyleAffectingAttributes`. #[inline] -pub fn common_style_affecting_attributes() -> [CommonStyleAffectingAttributeInfo, ..5] { +pub fn common_style_affecting_attributes() -> [CommonStyleAffectingAttributeInfo; 5] { [ CommonStyleAffectingAttributeInfo { atom: atom!("hidden"), @@ -815,7 +809,7 @@ pub fn common_style_affecting_attributes() -> [CommonStyleAffectingAttributeInfo /// Attributes that, if present, disable style sharing. All legacy HTML attributes must be in /// either this list or `common_style_affecting_attributes`. See the comment in /// `synthesize_presentational_hints_for_legacy_attributes`. -pub fn rare_style_affecting_attributes() -> [Atom, ..3] { +pub fn rare_style_affecting_attributes() -> [Atom; 3] { [ atom!("bgcolor"), atom!("border"), atom!("colspan") ] } @@ -1147,45 +1141,42 @@ fn matches_last_child<'a,E,N>(element: &N) -> bool where E: TElement<'a>, N: TNo } } - -trait FindPush<K, V> { - fn find_push(&mut self, key: K, value: V); -} - -impl<K: Eq + Hash, V> FindPush<K, V> for HashMap<K, Vec<V>> { - fn find_push(&mut self, key: K, value: V) { - match self.get_mut(&key) { - Some(vec) => { - vec.push(value); - return - } - None => {} +fn find_push(map: &mut HashMap<Atom, Vec<Rule>>, key: Atom, value: Rule) { + match map.get_mut(&key) { + Some(vec) => { + vec.push(value); + return } - self.insert(key, vec![value]); + None => {} } + map.insert(key, vec![value]); } #[cfg(test)] mod tests { + use std::cmp::Ordering; use std::sync::Arc; use super::{DeclarationBlock, Rule, SelectorMap}; use selectors::LocalName; use string_cache::Atom; + use cssparser::Parser; + use parser::ParserContext; + use url::Url; /// Helper method to get some Rules from selector strings. /// Each sublist of the result contains the Rules for one StyleRule. fn get_mock_rules(css_selectors: &[&str]) -> Vec<Vec<Rule>> { use namespaces::NamespaceMap; - use selectors::{ParserContext, parse_selector_list}; - use selector_matching::StylesheetOrigin; - use cssparser::tokenize; + use selectors::parse_selector_list; + use stylesheets::Origin; - let namespaces = NamespaceMap::new(); css_selectors.iter().enumerate().map(|(i, selectors)| { let context = ParserContext { - origin: StylesheetOrigin::Author, + stylesheet_origin: Origin::Author, + namespaces: NamespaceMap::new(), + base_url: &Url::parse("about:blank").unwrap(), }; - parse_selector_list(&context, tokenize(*selectors).map(|(c, _)| c), &namespaces) + parse_selector_list(&context, &mut Parser::new(*selectors)) .unwrap().into_iter().map(|s| { Rule { selector: s.compound_selectors.clone(), @@ -1204,7 +1195,7 @@ mod tests { let rules_list = get_mock_rules(&["a.intro", "img.sidebar"]); let a = &rules_list[0][0].declarations; let b = &rules_list[1][0].declarations; - assert!((a.specificity, a.source_order).cmp(&(b.specificity, b.source_order)) == Less, + assert!((a.specificity, a.source_order).cmp(&(b.specificity, b.source_order)) == Ordering::Less, "The rule that comes later should win."); } @@ -1225,7 +1216,7 @@ mod tests { #[test] fn test_get_local_name(){ let rules_list = get_mock_rules(&["img.foo", "#top", "IMG", "ImG"]); - let check = |i, names: Option<(&str, &str)>| { + let check = |&:i: uint, names: Option<(&str, &str)>| { assert!(SelectorMap::get_local_name(&rules_list[i][0]) == names.map(|(name, lower_name)| LocalName { name: Atom::from_slice(name), diff --git a/components/style/selectors.rs b/components/style/selectors.rs index 92570409552..a4c4b0bea53 100644 --- a/components/style/selectors.rs +++ b/components/style/selectors.rs @@ -2,49 +2,42 @@ * 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 std::{cmp, iter}; +use std::cmp; use std::ascii::{AsciiExt, OwnedAsciiExt}; use std::sync::Arc; +use std::string::CowString; -use cssparser::ast::*; -use cssparser::ast::ComponentValue::*; -use cssparser::{tokenize, parse_nth}; - -use selector_matching::StylesheetOrigin; +use cssparser::{Token, Parser, parse_nth}; use string_cache::{Atom, Namespace}; +use url::Url; +use parser::ParserContext; use namespaces::NamespaceMap; +use stylesheets::Origin; -/// Ambient data used by the parser. -#[deriving(Copy)] -pub struct ParserContext { - /// The origin of this stylesheet. - pub origin: StylesheetOrigin, -} -#[deriving(PartialEq, Clone)] +#[derive(PartialEq, Clone, Show)] pub struct Selector { pub compound_selectors: Arc<CompoundSelector>, pub pseudo_element: Option<PseudoElement>, pub specificity: u32, } -#[deriving(Eq, PartialEq, Clone, Hash, Copy)] +#[derive(Eq, PartialEq, Clone, Hash, Copy, Show)] pub enum PseudoElement { Before, After, -// FirstLine, -// FirstLetter, + // ... } -#[deriving(PartialEq, Clone)] +#[derive(PartialEq, Clone, Show)] pub struct CompoundSelector { pub simple_selectors: Vec<SimpleSelector>, pub next: Option<(Box<CompoundSelector>, Combinator)>, // c.next is left of c } -#[deriving(PartialEq, Clone, Copy)] +#[derive(PartialEq, Clone, Copy, Show)] pub enum Combinator { Child, // > Descendant, // space @@ -52,7 +45,7 @@ pub enum Combinator { LaterSibling, // ~ } -#[deriving(Eq, PartialEq, Clone, Hash)] +#[derive(Eq, PartialEq, Clone, Hash, Show)] pub enum SimpleSelector { ID(Atom), Class(Atom), @@ -79,9 +72,7 @@ pub enum SimpleSelector { Checked, Indeterminate, FirstChild, LastChild, OnlyChild, -// Empty, Root, -// Lang(String), NthChild(i32, i32), NthLastChild(i32, i32), NthOfType(i32, i32), @@ -94,27 +85,27 @@ pub enum SimpleSelector { } -#[deriving(Eq, PartialEq, Clone, Hash, Copy)] +#[derive(Eq, PartialEq, Clone, Hash, Copy, Show)] pub enum CaseSensitivity { CaseSensitive, // Selectors spec says language-defined, but HTML says sensitive. CaseInsensitive, } -#[deriving(Eq, PartialEq, Clone, Hash)] +#[derive(Eq, PartialEq, Clone, Hash, Show)] pub struct LocalName { pub name: Atom, pub lower_name: Atom, } -#[deriving(Eq, PartialEq, Clone, Hash)] +#[derive(Eq, PartialEq, Clone, Hash, Show)] pub struct AttrSelector { pub name: Atom, pub lower_name: Atom, pub namespace: NamespaceConstraint, } -#[deriving(Eq, PartialEq, Clone, Hash)] +#[derive(Eq, PartialEq, Clone, Hash, Show)] pub enum NamespaceConstraint { Any, Specific(Namespace), @@ -132,9 +123,6 @@ pub fn get_selector_list_selectors<'a>(selector_list: &'a SelectorList) -> &'a [ } -type Iter<I> = iter::Peekable<ComponentValue, I>; - - fn compute_specificity(mut selector: &CompoundSelector, pseudo_element: &Option<PseudoElement>) -> u32 { struct Specificity { @@ -183,7 +171,6 @@ fn compute_specificity(mut selector: &CompoundSelector, &SimpleSelector::OnlyChild | &SimpleSelector::Root | &SimpleSelector::Checked | &SimpleSelector::Indeterminate | -// &SimpleSelector::Empty | &SimpleSelector::Lang(*) | &SimpleSelector::NthChild(..) | &SimpleSelector::NthLastChild(..) | &SimpleSelector::NthOfType(..) | @@ -207,14 +194,87 @@ fn compute_specificity(mut selector: &CompoundSelector, +pub fn parse_author_origin_selector_list_from_str(input: &str) + -> Result<SelectorList,()> { + let context = ParserContext { + stylesheet_origin: Origin::Author, + namespaces: NamespaceMap::new(), + base_url: &Url::parse("about:blank").unwrap(), + }; + parse_selector_list(&context, &mut Parser::new(input)) + .map(|s| SelectorList { selectors: s }) +} + +/// Parse a comma-separated list of Selectors. +/// aka Selector Group in http://www.w3.org/TR/css3-selectors/#grouping +/// +/// Return the Selectors or None if there is an invalid selector. +pub fn parse_selector_list(context: &ParserContext, input: &mut Parser) + -> Result<Vec<Selector>,()> { + input.parse_comma_separated(|input| parse_selector(context, input)) +} + + +/// Build up a Selector. +/// selector : simple_selector_sequence [ combinator simple_selector_sequence ]* ; +/// +/// `Err` means invalid selector. +fn parse_selector(context: &ParserContext, input: &mut Parser) -> Result<Selector,()> { + let (first, mut pseudo_element) = try!(parse_simple_selectors(context, input)); + let mut compound = CompoundSelector{ simple_selectors: first, next: None }; + + 'outer_loop: while pseudo_element.is_none() { + let combinator; + let mut any_whitespace = false; + loop { + let position = input.position(); + match input.next_including_whitespace() { + Err(()) => break 'outer_loop, + Ok(Token::WhiteSpace(_)) => any_whitespace = true, + Ok(Token::Delim('>')) => { + combinator = Combinator::Child; + break + } + Ok(Token::Delim('+')) => { + combinator = Combinator::NextSibling; + break + } + Ok(Token::Delim('~')) => { + combinator = Combinator::LaterSibling; + break + } + Ok(_) => { + input.reset(position); + if any_whitespace { + combinator = Combinator::Descendant; + break + } else { + break 'outer_loop + } + } + } + } + let (simple_selectors, pseudo) = try!(parse_simple_selectors(context, input)); + compound = CompoundSelector { + simple_selectors: simple_selectors, + next: Some((box compound, combinator)) + }; + pseudo_element = pseudo; + } + Ok(Selector { + specificity: compute_specificity(&compound, &pseudo_element), + compound_selectors: Arc::new(compound), + pseudo_element: pseudo_element, + }) +} + + /// * `Err(())`: Invalid selector, abort -/// * `Ok(None)`: Not a type selector, could be something else. `iter` was not consumed. +/// * `Ok(None)`: Not a type selector, could be something else. `input` was not consumed. /// * `Ok(Some(vec))`: Length 0 (`*|*`), 1 (`*|E` or `ns|*`) or 2 (`|E` or `ns|E`) -fn parse_type_selector<I: Iterator<ComponentValue>>( - iter: &mut Iter<I>, namespaces: &NamespaceMap) +fn parse_type_selector(context: &ParserContext, input: &mut Parser) -> Result<Option<Vec<SimpleSelector>>, ()> { - skip_whitespace(iter); - match try!(parse_qualified_name(iter, /* in_attr_selector = */ false, namespaces)) { + match try!(parse_qualified_name(context, input, /* in_attr_selector = */ false)) { None => Ok(None), Some((namespace, local_name)) => { let mut simple_selectors = vec!(); @@ -228,7 +288,7 @@ fn parse_type_selector<I: Iterator<ComponentValue>>( Some(name) => { simple_selectors.push(SimpleSelector::LocalName(LocalName { name: Atom::from_slice(name.as_slice()), - lower_name: Atom::from_slice(name.into_ascii_lower().as_slice()) + lower_name: Atom::from_slice(name.into_owned().into_ascii_lowercase().as_slice()) })) } None => (), @@ -239,6 +299,7 @@ fn parse_type_selector<I: Iterator<ComponentValue>>( } +#[derive(Show)] enum SimpleSelectorParseResult { SimpleSelector(SimpleSelector), PseudoElement(PseudoElement), @@ -246,219 +307,145 @@ enum SimpleSelectorParseResult { /// * `Err(())`: Invalid selector, abort -/// * `Ok(None)`: Not a simple selector, could be something else. `iter` was not consumed. +/// * `Ok(None)`: Not a simple selector, could be something else. `input` was not consumed. /// * `Ok(Some((namespace, local_name)))`: `None` for the local name means a `*` universal selector -fn parse_qualified_name<I: Iterator<ComponentValue>>( - iter: &mut Iter<I>, in_attr_selector: bool, namespaces: &NamespaceMap) - -> Result<Option<(NamespaceConstraint, Option<String>)>, ()> { - let default_namespace = |local_name| { - let namespace = match namespaces.default { +fn parse_qualified_name<'i, 't> + (context: &ParserContext, input: &mut Parser<'i, 't>, + in_attr_selector: bool) + -> Result<Option<(NamespaceConstraint, Option<CowString<'i>>)>, ()> { + let default_namespace = |:local_name| { + let namespace = match context.namespaces.default { Some(ref ns) => NamespaceConstraint::Specific(ns.clone()), None => NamespaceConstraint::Any, }; Ok(Some((namespace, local_name))) }; - let explicit_namespace = |iter: &mut Iter<I>, namespace| { - assert!(iter.next() == Some(Delim('|')), - "Implementation error, this should not happen."); - match iter.peek() { - Some(&Delim('*')) if !in_attr_selector => { - iter.next(); + let explicit_namespace = |&: input: &mut Parser<'i, 't>, namespace| { + match input.next_including_whitespace() { + Ok(Token::Delim('*')) if !in_attr_selector => { Ok(Some((namespace, None))) }, - Some(&Ident(_)) => { - let local_name = get_next_ident(iter); + Ok(Token::Ident(local_name)) => { Ok(Some((namespace, Some(local_name)))) }, _ => Err(()), } }; - match iter.peek() { - Some(&Ident(_)) => { - let value = get_next_ident(iter); - match iter.peek() { - Some(&Delim('|')) => { - let namespace = match namespaces.prefix_map.get(&value) { - None => return Err(()), // Undeclared namespace prefix - Some(ref ns) => (*ns).clone(), - }; - explicit_namespace(iter, NamespaceConstraint::Specific(namespace)) + let position = input.position(); + match input.next_including_whitespace() { + Ok(Token::Ident(value)) => { + let position = input.position(); + match input.next_including_whitespace() { + Ok(Token::Delim('|')) => { + let result = context.namespaces.prefix_map.get(value.as_slice()); + let namespace = try!(result.ok_or(())); + explicit_namespace(input, NamespaceConstraint::Specific(namespace.clone())) }, - _ if in_attr_selector => Ok(Some( - (NamespaceConstraint::Specific(ns!("")), Some(value)))), - _ => default_namespace(Some(value)), + _ => { + input.reset(position); + if in_attr_selector { + Ok(Some((NamespaceConstraint::Specific(ns!("")), Some(value)))) + } else { + default_namespace(Some(value)) + } + } } }, - Some(&Delim('*')) => { - iter.next(); // Consume '*' - match iter.peek() { - Some(&Delim('|')) => explicit_namespace(iter, NamespaceConstraint::Any), + Ok(Token::Delim('*')) => { + let position = input.position(); + match input.next_including_whitespace() { + Ok(Token::Delim('|')) => explicit_namespace(input, NamespaceConstraint::Any), _ => { - if !in_attr_selector { default_namespace(None) } - else { Err(()) } + input.reset(position); + if in_attr_selector { + Err(()) + } else { + default_namespace(None) + } }, } }, - Some(&Delim('|')) => explicit_namespace(iter, NamespaceConstraint::Specific(ns!(""))), - _ => Ok(None), + Ok(Token::Delim('|')) => explicit_namespace(input, NamespaceConstraint::Specific(ns!(""))), + _ => { + input.reset(position); + Ok(None) + } } } -fn parse_attribute_selector(content: Vec<ComponentValue>, namespaces: &NamespaceMap) +fn parse_attribute_selector(context: &ParserContext, input: &mut Parser) -> Result<SimpleSelector, ()> { - let iter = &mut content.into_iter().peekable(); - let attr = match try!(parse_qualified_name(iter, /* in_attr_selector = */ true, namespaces)) { + let attr = match try!(parse_qualified_name(context, input, /* in_attr_selector = */ true)) { None => return Err(()), - Some((_, None)) => panic!("Implementation error, this should not happen."), + Some((_, None)) => unreachable!(), Some((namespace, Some(local_name))) => AttrSelector { namespace: namespace, - lower_name: Atom::from_slice(local_name.as_slice().to_ascii_lower().as_slice()), + lower_name: Atom::from_slice(local_name.as_slice().to_ascii_lowercase().as_slice()), name: Atom::from_slice(local_name.as_slice()), }, }; - skip_whitespace(iter); + + fn parse_value(input: &mut Parser) -> Result<String, ()> { + Ok((try!(input.expect_ident_or_string())).into_owned()) + } // TODO: deal with empty value or value containing whitespace (see spec) - let result = match iter.next() { + match input.next() { // [foo] - None => SimpleSelector::AttrExists(attr), + Err(()) => Ok(SimpleSelector::AttrExists(attr)), // [foo=bar] - Some(Delim('=')) => - SimpleSelector::AttrEqual(attr, try!(parse_attribute_value(iter)), - try!(parse_attribute_flags(iter))), - + Ok(Token::Delim('=')) => { + Ok(SimpleSelector::AttrEqual(attr, try!(parse_value(input)), + try!(parse_attribute_flags(input)))) + } // [foo~=bar] - Some(IncludeMatch) => - SimpleSelector::AttrIncludes(attr, try!(parse_attribute_value(iter))), - + Ok(Token::IncludeMatch) => { + Ok(SimpleSelector::AttrIncludes(attr, try!(parse_value(input)))) + } // [foo|=bar] - Some(DashMatch) => { - let value = try!(parse_attribute_value(iter)); - let dashing_value = format!("{}-", value); - SimpleSelector::AttrDashMatch(attr, value, dashing_value) - }, - + Ok(Token::DashMatch) => { + let value = try!(parse_value(input)); + let dashing_value = format!("{:?}-", value); + Ok(SimpleSelector::AttrDashMatch(attr, value, dashing_value)) + } // [foo^=bar] - Some(PrefixMatch) => - SimpleSelector::AttrPrefixMatch(attr, try!(parse_attribute_value(iter))), - + Ok(Token::PrefixMatch) => { + Ok(SimpleSelector::AttrPrefixMatch(attr, try!(parse_value(input)))) + } // [foo*=bar] - Some(SubstringMatch) => - SimpleSelector::AttrSubstringMatch(attr, try!(parse_attribute_value(iter))), - + Ok(Token::SubstringMatch) => { + Ok(SimpleSelector::AttrSubstringMatch(attr, try!(parse_value(input)))) + } // [foo$=bar] - Some(SuffixMatch) => - SimpleSelector::AttrSuffixMatch(attr, try!(parse_attribute_value(iter))), - - _ => return Err(()) - }; - skip_whitespace(iter); - if iter.next().is_none() { Ok(result) } else { Err(()) } -} - - -fn parse_attribute_value<I: Iterator<ComponentValue>>(iter: &mut Iter<I>) -> Result<String, ()> { - skip_whitespace(iter); - match iter.next() { - Some(Ident(value)) | Some(QuotedString(value)) => Ok(value), - _ => Err(()) - } -} - - -fn parse_attribute_flags<I: Iterator<ComponentValue>>(iter: &mut Iter<I>) - -> Result<CaseSensitivity, ()> { - skip_whitespace(iter); - match iter.next() { - None => Ok(CaseSensitivity::CaseSensitive), - Some(Ident(ref value)) if value.as_slice().eq_ignore_ascii_case("i") - => Ok(CaseSensitivity::CaseInsensitive), + Ok(Token::SuffixMatch) => { + Ok(SimpleSelector::AttrSuffixMatch(attr, try!(parse_value(input)))) + } _ => Err(()) } } -pub fn parse_selector_list_from_str(context: &ParserContext, input: &str) - -> Result<SelectorList,()> { - let namespaces = NamespaceMap::new(); - let iter = tokenize(input).map(|(token, _)| token); - parse_selector_list(context, iter, &namespaces).map(|s| SelectorList { selectors: s }) -} -/// Parse a comma-separated list of Selectors. -/// aka Selector Group in http://www.w3.org/TR/css3-selectors/#grouping -/// -/// Return the Selectors or None if there is an invalid selector. -pub fn parse_selector_list<I>(context: &ParserContext, iter: I, namespaces: &NamespaceMap) - -> Result<Vec<Selector>,()> - where I: Iterator<ComponentValue> { - let iter = &mut iter.peekable(); - let mut results = vec![try!(parse_selector(context, iter, namespaces))]; - - loop { - skip_whitespace(iter); - match iter.peek() { - None => break, // EOF - Some(&Comma) => { - iter.next(); - } - _ => return Err(()), +fn parse_attribute_flags(input: &mut Parser) -> Result<CaseSensitivity, ()> { + match input.next() { + Err(()) => Ok(CaseSensitivity::CaseSensitive), + Ok(Token::Ident(ref value)) if value.eq_ignore_ascii_case("i") => { + Ok(CaseSensitivity::CaseInsensitive) } - results.push(try!(parse_selector(context, iter, namespaces))); + _ => Err(()) } - Ok(results) } -/// Build up a Selector. -/// selector : simple_selector_sequence [ combinator simple_selector_sequence ]* ; -/// -/// `Err` means invalid selector. -fn parse_selector<I>(context: &ParserContext, iter: &mut Iter<I>, namespaces: &NamespaceMap) - -> Result<Selector,()> - where I: Iterator<ComponentValue> { - let (first, mut pseudo_element) = try!(parse_simple_selectors(context, iter, namespaces)); - let mut compound = CompoundSelector{ simple_selectors: first, next: None }; - while pseudo_element.is_none() { - let any_whitespace = skip_whitespace(iter); - let combinator = match iter.peek() { - None => break, // EOF - Some(&Comma) => break, - Some(&Delim('>')) => { iter.next(); Combinator::Child }, - Some(&Delim('+')) => { iter.next(); Combinator::NextSibling }, - Some(&Delim('~')) => { iter.next(); Combinator::LaterSibling }, - Some(_) => { - if any_whitespace { Combinator::Descendant } - else { return Err(()) } - } - }; - let (simple_selectors, pseudo) = try!(parse_simple_selectors(context, iter, namespaces)); - compound = CompoundSelector { - simple_selectors: simple_selectors, - next: Some((box compound, combinator)) - }; - pseudo_element = pseudo; - } - Ok(Selector { - specificity: compute_specificity(&compound, &pseudo_element), - compound_selectors: Arc::new(compound), - pseudo_element: pseudo_element, - }) -} /// Level 3: Parse **one** simple_selector -fn parse_negation(context: &ParserContext, - arguments: Vec<ComponentValue>, - namespaces: &NamespaceMap) - -> Result<SimpleSelector,()> { - let iter = &mut arguments.into_iter().peekable(); - match try!(parse_type_selector(iter, namespaces)) { +fn parse_negation(context: &ParserContext, input: &mut Parser) -> Result<SimpleSelector,()> { + match try!(parse_type_selector(context, input)) { Some(type_selector) => Ok(SimpleSelector::Negation(type_selector)), None => { match try!(parse_one_simple_selector(context, - iter, - namespaces, + input, /* inside_negation = */ true)) { Some(SimpleSelectorParseResult::SimpleSelector(simple_selector)) => { Ok(SimpleSelector::Negation(vec![simple_selector])) @@ -474,13 +461,18 @@ fn parse_negation(context: &ParserContext, /// | [ HASH | class | attrib | pseudo | negation ]+ /// /// `Err(())` means invalid selector -fn parse_simple_selectors<I>(context: &ParserContext, - iter: &mut Iter<I>, - namespaces: &NamespaceMap) - -> Result<(Vec<SimpleSelector>, Option<PseudoElement>),()> - where I: Iterator<ComponentValue> { +fn parse_simple_selectors(context: &ParserContext, input: &mut Parser) + -> Result<(Vec<SimpleSelector>, Option<PseudoElement>),()> { + // Consume any leading whitespace. + loop { + let position = input.position(); + if !matches!(input.next_including_whitespace(), Ok(Token::WhiteSpace(_))) { + input.reset(position); + break + } + } let mut empty = true; - let mut simple_selectors = match try!(parse_type_selector(iter, namespaces)) { + let mut simple_selectors = match try!(parse_type_selector(context, input)) { None => vec![], Some(s) => { empty = false; s } }; @@ -488,12 +480,18 @@ fn parse_simple_selectors<I>(context: &ParserContext, let mut pseudo_element = None; loop { match try!(parse_one_simple_selector(context, - iter, - namespaces, + input, /* inside_negation = */ false)) { None => break, - Some(SimpleSelectorParseResult::SimpleSelector(s)) => { simple_selectors.push(s); empty = false }, - Some(SimpleSelectorParseResult::PseudoElement(p)) => { pseudo_element = Some(p); empty = false; break }, + Some(SimpleSelectorParseResult::SimpleSelector(s)) => { + simple_selectors.push(s); + empty = false + } + Some(SimpleSelectorParseResult::PseudoElement(p)) => { + pseudo_element = Some(p); + empty = false; + break + } } } if empty { @@ -505,100 +503,111 @@ fn parse_simple_selectors<I>(context: &ParserContext, } fn parse_functional_pseudo_class(context: &ParserContext, - name: String, - arguments: Vec<ComponentValue>, - namespaces: &NamespaceMap, + input: &mut Parser, + name: &str, inside_negation: bool) -> Result<SimpleSelector,()> { - match name.as_slice().to_ascii_lower().as_slice() { -// "lang" => parse_lang(arguments), - "nth-child" => parse_nth(arguments.as_slice()).map(|(a, b)| SimpleSelector::NthChild(a, b)), - "nth-last-child" => parse_nth(arguments.as_slice()).map(|(a, b)| SimpleSelector::NthLastChild(a, b)), - "nth-of-type" => parse_nth(arguments.as_slice()).map(|(a, b)| SimpleSelector::NthOfType(a, b)), - "nth-last-of-type" => parse_nth(arguments.as_slice()).map(|(a, b)| SimpleSelector::NthLastOfType(a, b)), + match_ignore_ascii_case! { name, + "nth-child" => parse_nth_pseudo_class(input, SimpleSelector::NthChild), + "nth-of-type" => parse_nth_pseudo_class(input, SimpleSelector::NthOfType), + "nth-last-child" => parse_nth_pseudo_class(input, SimpleSelector::NthLastChild), + "nth-last-of-type" => parse_nth_pseudo_class(input, SimpleSelector::NthLastOfType), "not" => { if inside_negation { Err(()) } else { - parse_negation(context, arguments, namespaces) + parse_negation(context, input) } } _ => Err(()) } } + +fn parse_nth_pseudo_class<F>(input: &mut Parser, selector: F) -> Result<SimpleSelector, ()> +where F: FnOnce(i32, i32) -> SimpleSelector { + let (a, b) = try!(parse_nth(input)); + Ok(selector(a, b)) +} + + /// Parse a simple selector other than a type selector. /// /// * `Err(())`: Invalid selector, abort -/// * `Ok(None)`: Not a simple selector, could be something else. `iter` was not consumed. +/// * `Ok(None)`: Not a simple selector, could be something else. `input` was not consumed. /// * `Ok(Some(_))`: Parsed a simple selector or pseudo-element -fn parse_one_simple_selector<I>(context: &ParserContext, - iter: &mut Iter<I>, - namespaces: &NamespaceMap, - inside_negation: bool) - -> Result<Option<SimpleSelectorParseResult>,()> - where I: Iterator<ComponentValue> { - match iter.peek() { - Some(&IDHash(_)) => match iter.next() { - Some(IDHash(id)) => Ok(Some(SimpleSelectorParseResult::SimpleSelector( - SimpleSelector::ID(Atom::from_slice(id.as_slice()))))), - _ => panic!("Implementation error, this should not happen."), - }, - Some(&Delim('.')) => { - iter.next(); - match iter.next() { - Some(Ident(class)) => Ok(Some(SimpleSelectorParseResult::SimpleSelector( - SimpleSelector::Class(Atom::from_slice(class.as_slice()))))), +fn parse_one_simple_selector(context: &ParserContext, + input: &mut Parser, + inside_negation: bool) + -> Result<Option<SimpleSelectorParseResult>,()> { + let start_position = input.position(); + match input.next_including_whitespace() { + Ok(Token::IDHash(id)) => { + let id = SimpleSelector::ID(Atom::from_slice(id.as_slice())); + Ok(Some(SimpleSelectorParseResult::SimpleSelector(id))) + } + Ok(Token::Delim('.')) => { + match input.next_including_whitespace() { + Ok(Token::Ident(class)) => { + let class = SimpleSelector::Class(Atom::from_slice(class.as_slice())); + Ok(Some(SimpleSelectorParseResult::SimpleSelector(class))) + } _ => Err(()), } } - Some(&SquareBracketBlock(_)) => match iter.next() { - Some(SquareBracketBlock(content)) - => Ok(Some(SimpleSelectorParseResult::SimpleSelector(try!(parse_attribute_selector(content, namespaces))))), - _ => panic!("Implementation error, this should not happen."), - }, - Some(&Colon) => { - iter.next(); - match iter.next() { - Some(Ident(name)) => match parse_simple_pseudo_class(context, name.as_slice()) { - Err(()) => { - match name.as_slice().to_ascii_lower().as_slice() { - // Supported CSS 2.1 pseudo-elements only. - // ** Do not add to this list! ** - "before" => Ok(Some(SimpleSelectorParseResult::PseudoElement(PseudoElement::Before))), - "after" => Ok(Some(SimpleSelectorParseResult::PseudoElement(PseudoElement::After))), -// "first-line" => SimpleSelectorParseResult::PseudoElement(FirstLine), -// "first-letter" => SimpleSelectorParseResult::PseudoElement(FirstLetter), - _ => Err(()) - } - }, - Ok(result) => Ok(Some(SimpleSelectorParseResult::SimpleSelector(result))), - }, - Some(Function(name, arguments)) - => { - Ok(Some(SimpleSelectorParseResult::SimpleSelector(try!(parse_functional_pseudo_class( - context, - name, - arguments, - namespaces, - inside_negation))))) + Ok(Token::SquareBracketBlock) => { + let attr = try!(input.parse_nested_block(|input| { + parse_attribute_selector(context, input) + })); + Ok(Some(SimpleSelectorParseResult::SimpleSelector(attr))) + } + Ok(Token::Colon) => { + match input.next_including_whitespace() { + Ok(Token::Ident(name)) => { + match parse_simple_pseudo_class(context, name.as_slice()) { + Err(()) => { + let pseudo_element = match_ignore_ascii_case! { name, + // Supported CSS 2.1 pseudo-elements only. + // ** Do not add to this list! ** + "before" => PseudoElement::Before, + "after" => PseudoElement::After, + "first-line" => return Err(()), + "first-letter" => return Err(()) + _ => return Err(()) + }; + Ok(Some(SimpleSelectorParseResult::PseudoElement(pseudo_element))) + }, + Ok(result) => Ok(Some(SimpleSelectorParseResult::SimpleSelector(result))), + } + } + Ok(Token::Function(name)) => { + let name = name.as_slice(); + let pseudo = try!(input.parse_nested_block(|input| { + parse_functional_pseudo_class(context, input, name, inside_negation) + })); + Ok(Some(SimpleSelectorParseResult::SimpleSelector(pseudo))) } - Some(Colon) => { - match iter.next() { - Some(Ident(name)) - => Ok(Some(SimpleSelectorParseResult::PseudoElement(try!(parse_pseudo_element(name))))), - _ => Err(()), + Ok(Token::Colon) => { + match input.next() { + Ok(Token::Ident(name)) => { + let pseudo = try!(parse_pseudo_element(name.as_slice())); + Ok(Some(SimpleSelectorParseResult::PseudoElement(pseudo))) + } + _ => Err(()) } } - _ => Err(()), + _ => Err(()) } } - _ => Ok(None), + _ => { + input.reset(start_position); + Ok(None) + } } } fn parse_simple_pseudo_class(context: &ParserContext, name: &str) -> Result<SimpleSelector,()> { - match name.to_ascii_lower().as_slice() { + match_ignore_ascii_case! { name, "any-link" => Ok(SimpleSelector::AnyLink), "link" => Ok(SimpleSelector::Link), "visited" => Ok(SimpleSelector::Visited), @@ -614,76 +623,48 @@ fn parse_simple_pseudo_class(context: &ParserContext, name: &str) -> Result<Simp "first-of-type" => Ok(SimpleSelector::FirstOfType), "last-of-type" => Ok(SimpleSelector::LastOfType), "only-of-type" => Ok(SimpleSelector::OnlyOfType), - "-servo-nonzero-border" if context.origin == StylesheetOrigin::UserAgent => Ok(SimpleSelector::ServoNonzeroBorder), -// "empty" => Ok(Empty), + "-servo-nonzero-border" => { + if context.in_user_agent_stylesheet() { + Ok(SimpleSelector::ServoNonzeroBorder) + } else { + Err(()) + } + } _ => Err(()) } } -fn parse_pseudo_element(name: String) -> Result<PseudoElement, ()> { - match name.as_slice().to_ascii_lower().as_slice() { - // All supported pseudo-elements +fn parse_pseudo_element(name: &str) -> Result<PseudoElement, ()> { + match_ignore_ascii_case! { name, "before" => Ok(PseudoElement::Before), - "after" => Ok(PseudoElement::After), -// "first-line" => Some(FirstLine), -// "first-letter" => Some(FirstLetter), + "after" => Ok(PseudoElement::After) _ => Err(()) } } -//fn parse_lang(arguments: vec!(ComponentValue)) -> Result<SimpleSelector, ()> { -// let mut iter = arguments.move_skip_whitespace(); -// match iter.next() { -// Some(Ident(value)) => { -// if "" == value || iter.next().is_some() { None } -// else { Ok(Lang(value)) } -// }, -// _ => Err(()), -// } -//} - - - -/// Assuming the next token is an ident, consume it and return its value -#[inline] -fn get_next_ident<I: Iterator<ComponentValue>>(iter: &mut Iter<I>) -> String { - match iter.next() { - Some(Ident(value)) => value, - _ => panic!("Implementation error, this should not happen."), - } -} - - -#[inline] -fn skip_whitespace<I: Iterator<ComponentValue>>(iter: &mut Iter<I>) -> bool { - let mut any_whitespace = false; - loop { - if iter.peek() != Some(&WhiteSpace) { return any_whitespace } - any_whitespace = true; - iter.next(); - } -} - - #[cfg(test)] mod tests { use std::sync::Arc; - use cssparser; + use cssparser::Parser; use namespaces::NamespaceMap; - use selector_matching::StylesheetOrigin; + use stylesheets::Origin; use string_cache::Atom; + use parser::ParserContext; + use url::Url; use super::*; fn parse(input: &str) -> Result<Vec<Selector>, ()> { - parse_ns(input, &NamespaceMap::new()) + parse_ns(input, NamespaceMap::new()) } - fn parse_ns(input: &str, namespaces: &NamespaceMap) -> Result<Vec<Selector>, ()> { + fn parse_ns(input: &str, namespaces: NamespaceMap) -> Result<Vec<Selector>, ()> { let context = ParserContext { - origin: StylesheetOrigin::Author, + stylesheet_origin: Origin::Author, + namespaces: namespaces, + base_url: &Url::parse("about:blank").unwrap(), }; - parse_selector_list(&context, cssparser::tokenize(input).map(|(v, _)| v), namespaces) + parse_selector_list(&context, &mut Parser::new(input)) } fn specificity(a: u32, b: u32, c: u32) -> u32 { @@ -692,8 +673,8 @@ mod tests { #[test] fn test_parsing() { - assert!(parse("") == Err(())) - assert!(parse("EeÉ") == Ok(vec!(Selector { + assert_eq!(parse(""), Err(())) ; + assert_eq!(parse("EeÉ"), Ok(vec!(Selector { compound_selectors: Arc::new(CompoundSelector { simple_selectors: vec!(SimpleSelector::LocalName(LocalName { name: Atom::from_slice("EeÉ"), @@ -702,24 +683,24 @@ mod tests { }), pseudo_element: None, specificity: specificity(0, 0, 1), - }))) - assert!(parse(".foo") == Ok(vec!(Selector { + }))); + assert_eq!(parse(".foo"), Ok(vec!(Selector { compound_selectors: Arc::new(CompoundSelector { simple_selectors: vec!(SimpleSelector::Class(Atom::from_slice("foo"))), next: None, }), pseudo_element: None, specificity: specificity(0, 1, 0), - }))) - assert!(parse("#bar") == Ok(vec!(Selector { + }))); + assert_eq!(parse("#bar"), Ok(vec!(Selector { compound_selectors: Arc::new(CompoundSelector { simple_selectors: vec!(SimpleSelector::ID(Atom::from_slice("bar"))), next: None, }), pseudo_element: None, specificity: specificity(1, 0, 0), - }))) - assert!(parse("e.foo#bar") == Ok(vec!(Selector { + }))); + assert_eq!(parse("e.foo#bar"), Ok(vec!(Selector { compound_selectors: Arc::new(CompoundSelector { simple_selectors: vec!(SimpleSelector::LocalName(LocalName { name: Atom::from_slice("e"), @@ -730,8 +711,8 @@ mod tests { }), pseudo_element: None, specificity: specificity(1, 1, 1), - }))) - assert!(parse("e.foo #bar") == Ok(vec!(Selector { + }))); + assert_eq!(parse("e.foo #bar"), Ok(vec!(Selector { compound_selectors: Arc::new(CompoundSelector { simple_selectors: vec!(SimpleSelector::ID(Atom::from_slice("bar"))), next: Some((box CompoundSelector { @@ -744,11 +725,11 @@ mod tests { }), pseudo_element: None, specificity: specificity(1, 1, 1), - }))) + }))); // Default namespace does not apply to attribute selectors // https://github.com/mozilla/servo/pull/1652 let mut namespaces = NamespaceMap::new(); - assert!(parse_ns("[Foo]", &namespaces) == Ok(vec!(Selector { + assert_eq!(parse_ns("[Foo]", namespaces.clone()), Ok(vec!(Selector { compound_selectors: Arc::new(CompoundSelector { simple_selectors: vec!(SimpleSelector::AttrExists(AttrSelector { name: Atom::from_slice("Foo"), @@ -759,11 +740,11 @@ mod tests { }), pseudo_element: None, specificity: specificity(0, 1, 0), - }))) + }))); // Default namespace does not apply to attribute selectors // https://github.com/mozilla/servo/pull/1652 namespaces.default = Some(ns!(MathML)); - assert!(parse_ns("[Foo]", &namespaces) == Ok(vec!(Selector { + assert_eq!(parse_ns("[Foo]", namespaces.clone()), Ok(vec!(Selector { compound_selectors: Arc::new(CompoundSelector { simple_selectors: vec!(SimpleSelector::AttrExists(AttrSelector { name: Atom::from_slice("Foo"), @@ -774,9 +755,9 @@ mod tests { }), pseudo_element: None, specificity: specificity(0, 1, 0), - }))) + }))); // Default namespace does apply to type selectors - assert!(parse_ns("e", &namespaces) == Ok(vec!(Selector { + assert_eq!(parse_ns("e", namespaces), Ok(vec!(Selector { compound_selectors: Arc::new(CompoundSelector { simple_selectors: vec!( SimpleSelector::Namespace(ns!(MathML)), @@ -788,17 +769,17 @@ mod tests { }), pseudo_element: None, specificity: specificity(0, 0, 1), - }))) + }))); // https://github.com/mozilla/servo/issues/1723 - assert!(parse("::before") == Ok(vec!(Selector { + assert_eq!(parse("::before"), Ok(vec!(Selector { compound_selectors: Arc::new(CompoundSelector { simple_selectors: vec!(), next: None, }), pseudo_element: Some(PseudoElement::Before), specificity: specificity(0, 0, 1), - }))) - assert!(parse("div :after") == Ok(vec!(Selector { + }))); + assert_eq!(parse("div :after"), Ok(vec!(Selector { compound_selectors: Arc::new(CompoundSelector { simple_selectors: vec!(), next: Some((box CompoundSelector { @@ -810,6 +791,21 @@ mod tests { }), pseudo_element: Some(PseudoElement::After), specificity: specificity(0, 0, 2), - }))) + }))); + assert_eq!(parse("#d1 > .ok"), Ok(vec![Selector { + compound_selectors: Arc::new(CompoundSelector { + simple_selectors: vec![ + SimpleSelector::Class(Atom::from_slice("ok")), + ], + next: Some((box CompoundSelector { + simple_selectors: vec![ + SimpleSelector::ID(Atom::from_slice("d1")), + ], + next: None, + }, Combinator::Child)), + }), + pseudo_element: None, + specificity: (1 << 20) + (1 << 10) + (0 << 0), + }])) } } diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs index 71eb15cc1e2..7d9aeaf0297 100644 --- a/components/style/stylesheets.rs +++ b/components/style/stylesheets.rs @@ -8,55 +8,75 @@ use url::Url; use encoding::EncodingRef; -use cssparser::{decode_stylesheet_bytes, tokenize, parse_stylesheet_rules, ToCss}; -use cssparser::ast::*; -use selectors::{mod, ParserContext}; -use properties; -use errors::{ErrorLoggerIterator, log_css_error}; +use cssparser::{Parser, decode_stylesheet_bytes, + QualifiedRuleParser, AtRuleParser, RuleListParser, AtRuleType}; +use string_cache::Namespace; +use selectors::{Selector, parse_selector_list}; +use parser::ParserContext; +use properties::{PropertyDeclarationBlock, parse_property_declaration_list}; use namespaces::{NamespaceMap, parse_namespace_rule}; -use media_queries::{mod, Device, MediaRule}; -use font_face::{FontFaceRule, Source, parse_font_face_rule, iter_font_face_rules_inner}; -use selector_matching::StylesheetOrigin; +use media_queries::{self, Device, MediaQueryList, parse_media_query_list}; +use font_face::{FontFaceRule, Source, parse_font_face_block, iter_font_face_rules_inner}; +#[derive(Clone, PartialEq, Eq, Copy, Show)] +pub enum Origin { + UserAgent, + Author, + User, +} + + +#[derive(Show, PartialEq)] pub struct Stylesheet { /// List of rules in the order they were found (important for /// cascading order) rules: Vec<CSSRule>, - pub origin: StylesheetOrigin, + pub origin: Origin, } +#[derive(Show, PartialEq)] pub enum CSSRule { + Charset(String), + Namespace(Option<String>, Namespace), Style(StyleRule), Media(MediaRule), FontFace(FontFaceRule), } +#[derive(Show, PartialEq)] +pub struct MediaRule { + pub media_queries: MediaQueryList, + pub rules: Vec<CSSRule>, +} + +#[derive(Show, PartialEq)] pub struct StyleRule { - pub selectors: Vec<selectors::Selector>, - pub declarations: properties::PropertyDeclarationBlock, + pub selectors: Vec<Selector>, + pub declarations: PropertyDeclarationBlock, } impl Stylesheet { - pub fn from_bytes_iter<I: Iterator<Vec<u8>>>( + pub fn from_bytes_iter<I: Iterator<Item=Vec<u8>>>( mut input: I, base_url: Url, protocol_encoding_label: Option<&str>, - environment_encoding: Option<EncodingRef>, origin: StylesheetOrigin) -> Stylesheet { + environment_encoding: Option<EncodingRef>, origin: Origin) -> Stylesheet { let mut bytes = vec!(); // TODO: incremental decoding and tokenization/parsing for chunk in input { bytes.push_all(chunk.as_slice()) } - Stylesheet::from_bytes(bytes.as_slice(), base_url, protocol_encoding_label, environment_encoding, origin) + Stylesheet::from_bytes(bytes.as_slice(), base_url, protocol_encoding_label, + environment_encoding, origin) } pub fn from_bytes(bytes: &[u8], base_url: Url, protocol_encoding_label: Option<&str>, environment_encoding: Option<EncodingRef>, - origin: StylesheetOrigin) + origin: Origin) -> Stylesheet { // TODO: bytes.as_slice could be bytes.container_as_bytes() let (string, _) = decode_stylesheet_bytes( @@ -64,152 +84,307 @@ impl Stylesheet { Stylesheet::from_str(string.as_slice(), base_url, origin) } - pub fn from_str(css: &str, base_url: Url, origin: StylesheetOrigin) -> Stylesheet { - static STATE_CHARSET: uint = 1; - static STATE_IMPORTS: uint = 2; - static STATE_NAMESPACES: uint = 3; - static STATE_BODY: uint = 4; - - let parser_context = ParserContext { - origin: origin, + pub fn from_str<'i>(css: &'i str, base_url: Url, origin: Origin) -> Stylesheet { + let mut context = ParserContext { + stylesheet_origin: origin, + base_url: &base_url, + namespaces: NamespaceMap::new() }; + let rule_parser = MainRuleParser { + context: &mut context, + state: State::Start, + }; + let rules = RuleListParser::new_for_stylesheet(&mut Parser::new(css), rule_parser) + .filter_map(|result| result.ok()) + .collect(); + Stylesheet { + origin: origin, + rules: rules, + } + } +} - let mut state: uint = STATE_CHARSET; - let mut rules = vec!(); - let mut namespaces = NamespaceMap::new(); +fn parse_nested_rules(context: &mut ParserContext, input: &mut Parser) -> Vec<CSSRule> { + let parser = MainRuleParser { + context: context, + state: State::Body, + }; + RuleListParser::new_for_nested_rule(input, parser) + .filter_map(|result| result.ok()) + .collect() +} - for rule in ErrorLoggerIterator(parse_stylesheet_rules(tokenize(css))) { - let next_state; // Unitialized to force each branch to set it. - match rule { - Rule::QualifiedRule(rule) => { - next_state = STATE_BODY; - parse_style_rule(&parser_context, rule, &mut rules, &namespaces, &base_url) - }, - Rule::AtRule(rule) => { - let lower_name = rule.name.as_slice().to_ascii_lower(); - match lower_name.as_slice() { - "charset" => { - if state > STATE_CHARSET { - log_css_error(rule.location, "@charset must be the first rule") - } - // Valid @charset rules are just ignored - next_state = STATE_IMPORTS; - }, - "import" => { - if state > STATE_IMPORTS { - next_state = state; - log_css_error(rule.location, - "@import must be before any rule but @charset") - } else { - next_state = STATE_IMPORTS; - // TODO: support @import - log_css_error(rule.location, "@import is not supported yet") - } - }, - "namespace" => { - if state > STATE_NAMESPACES { - next_state = state; - log_css_error( - rule.location, - "@namespace must be before any rule but @charset and @import" - ) - } else { - next_state = STATE_NAMESPACES; - parse_namespace_rule(rule, &mut namespaces) - } - }, - _ => { - next_state = STATE_BODY; - parse_nested_at_rule(&parser_context, - lower_name.as_slice(), - rule, - &mut rules, - &namespaces, - &base_url) - }, - } - }, + +struct MainRuleParser<'a, 'b: 'a> { + context: &'a mut ParserContext<'b>, + state: State, +} + + +#[derive(Eq, PartialEq, Ord, PartialOrd)] +enum State { + Start = 1, + Imports = 2, + Namespaces = 3, + Body = 4, +} + + +enum AtRulePrelude { + FontFace, + Media(MediaQueryList), +} + + +impl<'a, 'b> AtRuleParser<AtRulePrelude, CSSRule> for MainRuleParser<'a, 'b> { + fn parse_prelude(&mut self, name: &str, input: &mut Parser) + -> Result<AtRuleType<AtRulePrelude, CSSRule>, ()> { + match_ignore_ascii_case! { name, + "charset" => { + if self.state <= State::Start { + // Valid @charset rules are just ignored + self.state = State::Imports; + let charset = try!(input.expect_string()).into_owned(); + return Ok(AtRuleType::WithoutBlock(CSSRule::Charset(charset))) + } else { + return Err(()) // "@charset must be the first rule" + } + }, + "import" => { + if self.state <= State::Imports { + self.state = State::Imports; + // TODO: support @import + return Err(()) // "@import is not supported yet" + } else { + return Err(()) // "@import must be before any rule but @charset" + } + }, + "namespace" => { + if self.state <= State::Namespaces { + self.state = State::Namespaces; + let (prefix, namespace) = try!(parse_namespace_rule(self.context, input)); + return Ok(AtRuleType::WithoutBlock(CSSRule::Namespace(prefix, namespace))) + } else { + return Err(()) // "@namespace must be before any rule but @charset and @import" + } } - state = next_state; + _ => {} } - Stylesheet { - rules: rules, - origin: origin, + + self.state = State::Body; + + match_ignore_ascii_case! { name, + "media" => { + let media_queries = parse_media_query_list(input); + Ok(AtRuleType::WithBlock(AtRulePrelude::Media(media_queries))) + }, + "font-face" => { + Ok(AtRuleType::WithBlock(AtRulePrelude::FontFace)) + } + _ => Err(()) } } -} -// lower_name is passed explicitly to avoid computing it twice. -pub fn parse_nested_at_rule(context: &ParserContext, - lower_name: &str, - rule: AtRule, - parent_rules: &mut Vec<CSSRule>, - namespaces: &NamespaceMap, - base_url: &Url) { - match lower_name { - "media" => { - media_queries::parse_media_rule(context, rule, parent_rules, namespaces, base_url) + fn parse_block(&mut self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CSSRule, ()> { + match prelude { + AtRulePrelude::FontFace => { + parse_font_face_block(self.context, input).map(CSSRule::FontFace) + } + AtRulePrelude::Media(media_queries) => { + Ok(CSSRule::Media(MediaRule { + media_queries: media_queries, + rules: parse_nested_rules(self.context, input), + })) + } } - "font-face" => parse_font_face_rule(rule, parent_rules, base_url), - _ => log_css_error(rule.location, - format!("Unsupported at-rule: @{}", lower_name).as_slice()) } } -pub fn parse_style_rule(context: &ParserContext, - rule: QualifiedRule, - parent_rules: &mut Vec<CSSRule>, - namespaces: &NamespaceMap, - base_url: &Url) { - let QualifiedRule { - location, - prelude, - block - } = rule; - // FIXME: avoid doing this for valid selectors - let serialized = prelude.to_css_string(); - match selectors::parse_selector_list(context, prelude.into_iter(), namespaces) { - Ok(selectors) => parent_rules.push(CSSRule::Style(StyleRule{ - selectors: selectors, - declarations: properties::parse_property_declaration_list(block.into_iter(), base_url) - })), - Err(()) => log_css_error(location, format!( - "Invalid/unsupported selector: {}", serialized).as_slice()), + +impl<'a, 'b> QualifiedRuleParser<Vec<Selector>, CSSRule> for MainRuleParser<'a, 'b> { + fn parse_prelude(&mut self, input: &mut Parser) -> Result<Vec<Selector>, ()> { + self.state = State::Body; + parse_selector_list(self.context, input) + } + + fn parse_block(&mut self, prelude: Vec<Selector>, input: &mut Parser) -> Result<CSSRule, ()> { + Ok(CSSRule::Style(StyleRule { + selectors: prelude, + declarations: parse_property_declaration_list(self.context, input) + })) } } -pub fn iter_style_rules<'a>(rules: &[CSSRule], device: &media_queries::Device, - callback: |&StyleRule|) { + +pub fn iter_style_rules<'a, F>(rules: &[CSSRule], device: &media_queries::Device, + callback: &mut F) where F: FnMut(&StyleRule) { for rule in rules.iter() { match *rule { CSSRule::Style(ref rule) => callback(rule), CSSRule::Media(ref rule) => if rule.media_queries.evaluate(device) { - iter_style_rules(rule.rules.as_slice(), device, |s| callback(s)) + iter_style_rules(rule.rules.as_slice(), device, callback) }, - CSSRule::FontFace(_) => {}, + CSSRule::FontFace(..) | + CSSRule::Charset(..) | + CSSRule::Namespace(..) => {} } } } -pub fn iter_stylesheet_media_rules(stylesheet: &Stylesheet, callback: |&MediaRule|) { +pub fn iter_stylesheet_media_rules<F>(stylesheet: &Stylesheet, mut callback: F) where F: FnMut(&MediaRule) { for rule in stylesheet.rules.iter() { match *rule { CSSRule::Media(ref rule) => callback(rule), - _ => {} + CSSRule::Style(..) | + CSSRule::FontFace(..) | + CSSRule::Charset(..) | + CSSRule::Namespace(..) => {} } } } #[inline] -pub fn iter_stylesheet_style_rules(stylesheet: &Stylesheet, device: &media_queries::Device, - callback: |&StyleRule|) { - iter_style_rules(stylesheet.rules.as_slice(), device, callback) +pub fn iter_stylesheet_style_rules<F>(stylesheet: &Stylesheet, device: &media_queries::Device, + mut callback: F) where F: FnMut(&StyleRule) { + iter_style_rules(stylesheet.rules.as_slice(), device, &mut callback) } #[inline] -pub fn iter_font_face_rules(stylesheet: &Stylesheet, device: &Device, - callback: |family: &str, source: &Source|) { +pub fn iter_font_face_rules<F>(stylesheet: &Stylesheet, device: &Device, + callback: &F) where F: Fn(&str, &Source) { iter_font_face_rules_inner(stylesheet.rules.as_slice(), device, callback) } + + +#[test] +fn test_parse_stylesheet() { + use std::sync::Arc; + use cssparser; + use selectors::*; + use string_cache::Atom; + use properties::{PropertyDeclaration, DeclaredValue, longhands}; + use std::borrow::ToOwned; + + let css = r" + @namespace url(http://www.w3.org/1999/xhtml); + /* FIXME: only if scripting is enabled */ + input[type=hidden i] { display: none !important; } + html , body /**/ { display: block; } + #d1 > .ok { background: blue; } + "; + let url = Url::parse("about::test").unwrap(); + let stylesheet = Stylesheet::from_str(css, url, Origin::UserAgent); + assert_eq!(stylesheet, Stylesheet { + origin: Origin::UserAgent, + rules: vec![ + CSSRule::Namespace(None, ns!(HTML)), + CSSRule::Style(StyleRule { + selectors: vec![ + Selector { + compound_selectors: Arc::new(CompoundSelector { + simple_selectors: vec![ + SimpleSelector::Namespace(ns!(HTML)), + SimpleSelector::LocalName(LocalName { + name: atom!(input), + lower_name: atom!(input), + }), + SimpleSelector::AttrEqual(AttrSelector { + name: atom!(type), + lower_name: atom!(type), + namespace: NamespaceConstraint::Specific(ns!("")), + }, "hidden".to_owned(), CaseSensitivity::CaseInsensitive) + ], + next: None, + }), + pseudo_element: None, + specificity: (0 << 20) + (1 << 10) + (1 << 0), + }, + ], + declarations: PropertyDeclarationBlock { + normal: Arc::new(vec![]), + important: Arc::new(vec![ + PropertyDeclaration::Display(DeclaredValue::SpecifiedValue( + longhands::display::SpecifiedValue::none)), + ]), + }, + }), + CSSRule::Style(StyleRule { + selectors: vec![ + Selector { + compound_selectors: Arc::new(CompoundSelector { + simple_selectors: vec![ + SimpleSelector::Namespace(ns!(HTML)), + SimpleSelector::LocalName(LocalName { + name: atom!(html), + lower_name: atom!(html), + }), + ], + next: None, + }), + pseudo_element: None, + specificity: (0 << 20) + (0 << 10) + (1 << 0), + }, + Selector { + compound_selectors: Arc::new(CompoundSelector { + simple_selectors: vec![ + SimpleSelector::Namespace(ns!(HTML)), + SimpleSelector::LocalName(LocalName { + name: atom!(body), + lower_name: atom!(body), + }), + ], + next: None, + }), + pseudo_element: None, + specificity: (0 << 20) + (0 << 10) + (1 << 0), + }, + ], + declarations: PropertyDeclarationBlock { + normal: Arc::new(vec![ + PropertyDeclaration::Display(DeclaredValue::SpecifiedValue( + longhands::display::SpecifiedValue::block)), + ]), + important: Arc::new(vec![]), + }, + }), + CSSRule::Style(StyleRule { + selectors: vec![ + Selector { + compound_selectors: Arc::new(CompoundSelector { + simple_selectors: vec![ + SimpleSelector::Class(Atom::from_slice("ok")), + ], + next: Some((box CompoundSelector { + simple_selectors: vec![ + SimpleSelector::ID(Atom::from_slice("d1")), + ], + next: None, + }, Combinator::Child)), + }), + pseudo_element: None, + specificity: (1 << 20) + (1 << 10) + (0 << 0), + }, + ], + declarations: PropertyDeclarationBlock { + normal: Arc::new(vec![ + PropertyDeclaration::BackgroundImage(DeclaredValue::Initial), + PropertyDeclaration::BackgroundAttachment(DeclaredValue::Initial), + PropertyDeclaration::BackgroundRepeat(DeclaredValue::Initial), + PropertyDeclaration::BackgroundPosition(DeclaredValue::Initial), + PropertyDeclaration::BackgroundColor(DeclaredValue::SpecifiedValue( + longhands::background_color::SpecifiedValue { + authored: Some("blue".to_owned()), + parsed: cssparser::Color::RGBA(cssparser::RGBA { + red: 0., green: 0., blue: 1., alpha: 1. + }), + } + )), + ]), + important: Arc::new(vec![]), + }, + }), + ], + }); +} diff --git a/components/style/properties/common_types.rs b/components/style/values.rs index 1ca01d2d504..73a563aebbb 100644 --- a/components/style/properties/common_types.rs +++ b/components/style/values.rs @@ -3,33 +3,23 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #![allow(non_camel_case_types)] -#![macro_escape] - -use url::{Url, UrlParser}; - -pub use servo_util::geometry::Au; macro_rules! define_css_keyword_enum { ($name: ident: $( $css: expr => $variant: ident ),+,) => { - define_css_keyword_enum!($name: $( $css => $variant ),+) + define_css_keyword_enum!($name: $( $css => $variant ),+); }; ($name: ident: $( $css: expr => $variant: ident ),+) => { #[allow(non_camel_case_types)] - #[deriving(Clone, Eq, PartialEq, FromPrimitive, Copy)] + #[derive(Clone, Eq, PartialEq, FromPrimitive, Copy)] pub enum $name { $( $variant ),+ } impl $name { - pub fn parse(component_value: &::cssparser::ast::ComponentValue) -> Result<$name, ()> { - match component_value { - &::cssparser::ast::ComponentValue::Ident(ref value) => { - match_ignore_ascii_case! { value: - $( $css => Ok($name::$variant) ),+ - _ => Err(()) - } - } + pub fn parse(input: &mut ::cssparser::Parser) -> Result<$name, ()> { + match_ignore_ascii_case! { try!(input.expect_ident()), + $( $css => Ok($name::$variant) ),+ _ => Err(()) } } @@ -63,30 +53,29 @@ pub mod specified { use std::fmt; use std::fmt::{Formatter, Show}; use url::Url; - use cssparser::{mod, ToCss, CssStringWriter}; - use cssparser::ast::*; - use cssparser::ast::ComponentValue::*; - use text_writer::{mod, TextWriter}; - use parsing_utils::{mod, BufferedIter, ParserIter}; - use super::{Au, CSSFloat}; - - #[deriving(Clone, PartialEq)] + use cssparser::{self, Token, Parser, ToCss, CssStringWriter}; + use parser::ParserContext; + use text_writer::{self, TextWriter}; + use servo_util::geometry::Au; + use super::CSSFloat; + use super::computed; + + #[derive(Clone, PartialEq)] pub struct CSSColor { pub parsed: cssparser::Color, pub authored: Option<String>, } impl CSSColor { - pub fn parse(component_value: &ComponentValue) -> Result<CSSColor, ()> { - let parsed = cssparser::Color::parse(component_value); - parsed.map(|parsed| { - let authored = match component_value { - &Ident(ref s) => Some(s.clone()), - _ => None, - }; - CSSColor { - parsed: parsed, - authored: authored, - } + pub fn parse(input: &mut Parser) -> Result<CSSColor, ()> { + let start_position = input.position(); + let authored = match input.next() { + Ok(Token::Ident(s)) => Some(s.into_owned()), + _ => None, + }; + input.reset(start_position); + Ok(CSSColor { + parsed: try!(cssparser::Color::parse(input)), + authored: authored, }) } } @@ -104,7 +93,7 @@ pub mod specified { } } - #[deriving(Clone)] + #[derive(Clone, PartialEq)] pub struct CSSRGBA { pub parsed: cssparser::RGBA, pub authored: Option<String>, @@ -122,7 +111,7 @@ pub mod specified { } } - #[deriving(Clone, PartialEq)] + #[derive(Clone, PartialEq)] pub struct CSSImage(pub Option<Image>); impl fmt::Show for CSSImage { @@ -138,7 +127,7 @@ pub mod specified { } } - #[deriving(Clone, PartialEq, Copy)] + #[derive(Clone, PartialEq, Copy)] pub enum Length { Au(Au), // application units Em(CSSFloat), @@ -150,13 +139,6 @@ pub mod specified { /// This cannot be specified by the user directly and is only generated by /// `Stylist::synthesize_rules_for_legacy_attributes()`. ServoCharacterWidth(i32), - - // XXX uncomment when supported: -// Ch(CSSFloat), -// Vw(CSSFloat), -// Vh(CSSFloat), -// Vmin(CSSFloat), -// Vmax(CSSFloat), } impl fmt::Show for Length { @@ -184,23 +166,24 @@ pub mod specified { const AU_PER_PC: CSSFloat = AU_PER_PT * 12.; impl Length { #[inline] - fn parse_internal(input: &ComponentValue, negative_ok: bool) -> Result<Length, ()> { - match input { - &Dimension(ref value, ref unit) if negative_ok || value.value >= 0. - => Length::parse_dimension(value.value, unit.as_slice()), - &Number(ref value) if value.value == 0. => Ok(Length::Au(Au(0))), + fn parse_internal(input: &mut Parser, negative_ok: bool) -> Result<Length, ()> { + match try!(input.next()) { + Token::Dimension(ref value, ref unit) if negative_ok || value.value >= 0. => { + Length::parse_dimension(value.value, unit.as_slice()) + } + Token::Number(ref value) if value.value == 0. => Ok(Length::Au(Au(0))), _ => Err(()) } } #[allow(dead_code)] - pub fn parse(input: &ComponentValue) -> Result<Length, ()> { + pub fn parse(input: &mut Parser) -> Result<Length, ()> { Length::parse_internal(input, /* negative_ok = */ true) } - pub fn parse_non_negative(input: &ComponentValue) -> Result<Length, ()> { + pub fn parse_non_negative(input: &mut Parser) -> Result<Length, ()> { Length::parse_internal(input, /* negative_ok = */ false) } pub fn parse_dimension(value: CSSFloat, unit: &str) -> Result<Length, ()> { - match unit.to_ascii_lower().as_slice() { + match_ignore_ascii_case! { unit, "px" => Ok(Length::from_px(value)), "in" => Ok(Length::Au(Au((value * AU_PER_IN) as i32))), "cm" => Ok(Length::Au(Au((value * AU_PER_CM) as i32))), @@ -209,7 +192,7 @@ pub mod specified { "pc" => Ok(Length::Au(Au((value * AU_PER_PC) as i32))), "em" => Ok(Length::Em(value)), "ex" => Ok(Length::Ex(value)), - "rem" => Ok(Length::Rem(value)), + "rem" => Ok(Length::Rem(value)) _ => Err(()) } } @@ -219,7 +202,8 @@ pub mod specified { } } - #[deriving(Clone, PartialEq, Copy)] + + #[derive(Clone, PartialEq, Copy)] pub enum LengthOrPercentage { Length(Length), Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0] @@ -239,31 +223,34 @@ pub mod specified { } } impl LengthOrPercentage { - fn parse_internal(input: &ComponentValue, negative_ok: bool) - -> Result<LengthOrPercentage, ()> { - match input { - &Dimension(ref value, ref unit) if negative_ok || value.value >= 0. => + fn parse_internal(input: &mut Parser, negative_ok: bool) + -> Result<LengthOrPercentage, ()> { + match try!(input.next()) { + Token::Dimension(ref value, ref unit) if negative_ok || value.value >= 0. => { Length::parse_dimension(value.value, unit.as_slice()) - .map(LengthOrPercentage::Length), - &Percentage(ref value) if negative_ok || value.value >= 0. => - Ok(LengthOrPercentage::Percentage(value.value / 100.)), - &Number(ref value) if value.value == 0. => - Ok(LengthOrPercentage::Length(Length::Au(Au(0)))), + .map(LengthOrPercentage::Length) + } + Token::Percentage(ref value) if negative_ok || value.unit_value >= 0. => { + Ok(LengthOrPercentage::Percentage(value.unit_value)) + } + Token::Number(ref value) if value.value == 0. => { + Ok(LengthOrPercentage::Length(Length::Au(Au(0)))) + } _ => Err(()) } } #[allow(dead_code)] #[inline] - pub fn parse(input: &ComponentValue) -> Result<LengthOrPercentage, ()> { + pub fn parse(input: &mut Parser) -> Result<LengthOrPercentage, ()> { LengthOrPercentage::parse_internal(input, /* negative_ok = */ true) } #[inline] - pub fn parse_non_negative(input: &ComponentValue) -> Result<LengthOrPercentage, ()> { + pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrPercentage, ()> { LengthOrPercentage::parse_internal(input, /* negative_ok = */ false) } } - #[deriving(Clone, PartialEq, Copy)] + #[derive(Clone, PartialEq, Copy)] pub enum LengthOrPercentageOrAuto { Length(Length), Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0] @@ -285,31 +272,36 @@ pub mod specified { } } impl LengthOrPercentageOrAuto { - fn parse_internal(input: &ComponentValue, negative_ok: bool) + fn parse_internal(input: &mut Parser, negative_ok: bool) -> Result<LengthOrPercentageOrAuto, ()> { - match input { - &Dimension(ref value, ref unit) if negative_ok || value.value >= 0. => - Length::parse_dimension(value.value, unit.as_slice()).map(LengthOrPercentageOrAuto::Length), - &Percentage(ref value) if negative_ok || value.value >= 0. => - Ok(LengthOrPercentageOrAuto::Percentage(value.value / 100.)), - &Number(ref value) if value.value == 0. => - Ok(LengthOrPercentageOrAuto::Length(Length::Au(Au(0)))), - &Ident(ref value) if value.as_slice().eq_ignore_ascii_case("auto") => - Ok(LengthOrPercentageOrAuto::Auto), + match try!(input.next()) { + Token::Dimension(ref value, ref unit) if negative_ok || value.value >= 0. => { + Length::parse_dimension(value.value, unit.as_slice()) + .map(LengthOrPercentageOrAuto::Length) + } + Token::Percentage(ref value) if negative_ok || value.unit_value >= 0. => { + Ok(LengthOrPercentageOrAuto::Percentage(value.unit_value)) + } + Token::Number(ref value) if value.value == 0. => { + Ok(LengthOrPercentageOrAuto::Length(Length::Au(Au(0)))) + } + Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => { + Ok(LengthOrPercentageOrAuto::Auto) + } _ => Err(()) } } #[inline] - pub fn parse(input: &ComponentValue) -> Result<LengthOrPercentageOrAuto, ()> { + pub fn parse(input: &mut Parser) -> Result<LengthOrPercentageOrAuto, ()> { LengthOrPercentageOrAuto::parse_internal(input, /* negative_ok = */ true) } #[inline] - pub fn parse_non_negative(input: &ComponentValue) -> Result<LengthOrPercentageOrAuto, ()> { + pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrPercentageOrAuto, ()> { LengthOrPercentageOrAuto::parse_internal(input, /* negative_ok = */ false) } } - #[deriving(Clone, PartialEq, Copy)] + #[derive(Clone, PartialEq, Copy)] pub enum LengthOrPercentageOrNone { Length(Length), Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0] @@ -331,31 +323,38 @@ pub mod specified { } } impl LengthOrPercentageOrNone { - fn parse_internal(input: &ComponentValue, negative_ok: bool) + fn parse_internal(input: &mut Parser, negative_ok: bool) -> Result<LengthOrPercentageOrNone, ()> { - match input { - &Dimension(ref value, ref unit) if negative_ok || value.value >= 0. - => Length::parse_dimension(value.value, unit.as_slice()).map(LengthOrPercentageOrNone::Length), - &Percentage(ref value) if negative_ok || value.value >= 0. - => Ok(LengthOrPercentageOrNone::Percentage(value.value / 100.)), - &Number(ref value) if value.value == 0. => Ok(LengthOrPercentageOrNone::Length(Length::Au(Au(0)))), - &Ident(ref value) if value.as_slice().eq_ignore_ascii_case("none") => Ok(LengthOrPercentageOrNone::None), + match try!(input.next()) { + Token::Dimension(ref value, ref unit) if negative_ok || value.value >= 0. => { + Length::parse_dimension(value.value, unit.as_slice()) + .map(LengthOrPercentageOrNone::Length) + } + Token::Percentage(ref value) if negative_ok || value.unit_value >= 0. => { + Ok(LengthOrPercentageOrNone::Percentage(value.unit_value)) + } + Token::Number(ref value) if value.value == 0. => { + Ok(LengthOrPercentageOrNone::Length(Length::Au(Au(0)))) + } + Token::Ident(ref value) if value.eq_ignore_ascii_case("none") => { + Ok(LengthOrPercentageOrNone::None) + } _ => Err(()) } } #[allow(dead_code)] #[inline] - pub fn parse(input: &ComponentValue) -> Result<LengthOrPercentageOrNone, ()> { + pub fn parse(input: &mut Parser) -> Result<LengthOrPercentageOrNone, ()> { LengthOrPercentageOrNone::parse_internal(input, /* negative_ok = */ true) } #[inline] - pub fn parse_non_negative(input: &ComponentValue) -> Result<LengthOrPercentageOrNone, ()> { + pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrPercentageOrNone, ()> { LengthOrPercentageOrNone::parse_internal(input, /* negative_ok = */ false) } } // http://dev.w3.org/csswg/css2/colors.html#propdef-background-position - #[deriving(Clone, PartialEq, Copy)] + #[derive(Clone, PartialEq, Copy)] pub enum PositionComponent { Length(Length), Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0] @@ -366,19 +365,27 @@ pub mod specified { Bottom, } impl PositionComponent { - pub fn parse(input: &ComponentValue) -> Result<PositionComponent, ()> { - match input { - &Dimension(ref value, ref unit) => - Length::parse_dimension(value.value, unit.as_slice()).map(PositionComponent::Length), - &Percentage(ref value) => Ok(PositionComponent::Percentage(value.value / 100.)), - &Number(ref value) if value.value == 0. => Ok(PositionComponent::Length(Length::Au(Au(0)))), - &Ident(ref value) => { - if value.as_slice().eq_ignore_ascii_case("center") { Ok(PositionComponent::Center) } - else if value.as_slice().eq_ignore_ascii_case("left") { Ok(PositionComponent::Left) } - else if value.as_slice().eq_ignore_ascii_case("right") { Ok(PositionComponent::Right) } - else if value.as_slice().eq_ignore_ascii_case("top") { Ok(PositionComponent::Top) } - else if value.as_slice().eq_ignore_ascii_case("bottom") { Ok(PositionComponent::Bottom) } - else { Err(()) } + pub fn parse(input: &mut Parser) -> Result<PositionComponent, ()> { + match try!(input.next()) { + Token::Dimension(ref value, ref unit) => { + Length::parse_dimension(value.value, unit.as_slice()) + .map(PositionComponent::Length) + } + Token::Percentage(ref value) => { + Ok(PositionComponent::Percentage(value.unit_value)) + } + Token::Number(ref value) if value.value == 0. => { + Ok(PositionComponent::Length(Length::Au(Au(0)))) + } + Token::Ident(value) => { + match_ignore_ascii_case! { value, + "center" => Ok(PositionComponent::Center), + "left" => Ok(PositionComponent::Left), + "right" => Ok(PositionComponent::Right), + "top" => Ok(PositionComponent::Top), + "bottom" => Ok(PositionComponent::Bottom) + _ => Err(()) + } } _ => Err(()) } @@ -389,13 +396,15 @@ pub mod specified { PositionComponent::Length(x) => LengthOrPercentage::Length(x), PositionComponent::Percentage(x) => LengthOrPercentage::Percentage(x), PositionComponent::Center => LengthOrPercentage::Percentage(0.5), - PositionComponent::Left | PositionComponent::Top => LengthOrPercentage::Percentage(0.0), - PositionComponent::Right | PositionComponent::Bottom => LengthOrPercentage::Percentage(1.0), + PositionComponent::Left | + PositionComponent::Top => LengthOrPercentage::Percentage(0.0), + PositionComponent::Right | + PositionComponent::Bottom => LengthOrPercentage::Percentage(1.0), } } } - #[deriving(Clone, PartialEq, PartialOrd, Copy)] + #[derive(Clone, PartialEq, PartialOrd, Copy)] pub struct Angle(pub CSSFloat); impl fmt::Show for Angle { @@ -416,37 +425,31 @@ pub mod specified { } } - static DEG_TO_RAD: CSSFloat = PI / 180.0; - static GRAD_TO_RAD: CSSFloat = PI / 200.0; + const RAD_PER_DEG: CSSFloat = PI / 180.0; + const RAD_PER_GRAD: CSSFloat = PI / 200.0; + const RAD_PER_TURN: CSSFloat = PI * 2.0; impl Angle { /// Parses an angle according to CSS-VALUES § 6.1. - fn parse_dimension(value: CSSFloat, unit: &str) -> Result<Angle,()> { - if unit.eq_ignore_ascii_case("deg") { - Ok(Angle(value * DEG_TO_RAD)) - } else if unit.eq_ignore_ascii_case("grad") { - Ok(Angle(value * GRAD_TO_RAD)) - } else if unit.eq_ignore_ascii_case("rad") { - Ok(Angle(value)) - } else if unit.eq_ignore_ascii_case("turn") { - Ok(Angle(value * 2.0 * PI)) - } else { - Err(()) - } - } - /// Parses an angle from a token according to CSS-VALUES § 6.1. - pub fn parse(value: &ComponentValue) -> Result<Angle,()> { - match *value { - Dimension(ref value, ref unit) => { - Angle::parse_dimension(value.value, unit.as_slice()) + pub fn parse(input: &mut Parser) -> Result<Angle, ()> { + match try!(input.next()) { + Token::Dimension(value, unit) => { + match_ignore_ascii_case! { unit, + "deg" => Ok(Angle(value.value * RAD_PER_DEG)), + "grad" => Ok(Angle(value.value * RAD_PER_GRAD)), + "turn" => Ok(Angle(value.value * RAD_PER_TURN)), + "rad" => Ok(Angle(value.value)) + _ => Err(()) + } } + Token::Number(ref value) if value.value == 0. => Ok(Angle(0.)), _ => Err(()) } } } /// Specified values for an image according to CSS-IMAGES. - #[deriving(Clone, PartialEq)] + #[derive(Clone, PartialEq)] pub enum Image { Url(Url), LinearGradient(LinearGradient), @@ -471,40 +474,37 @@ pub mod specified { } impl Image { - pub fn from_component_value(component_value: &ComponentValue, base_url: &Url) - -> Result<Image,()> { - match component_value { - &URL(ref url) => { - let image_url = super::parse_url(url.as_slice(), base_url); - Ok(Image::Url(image_url)) - }, - &Function(ref name, ref args) => { - if name.as_slice().eq_ignore_ascii_case("linear-gradient") { - Ok(Image::LinearGradient(try!( - super::specified::LinearGradient::parse_function( - args.as_slice())))) - } else { - Err(()) + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<Image, ()> { + match try!(input.next()) { + Token::Url(url) => { + Ok(Image::Url(context.parse_url(url.as_slice()))) + } + Token::Function(name) => { + match_ignore_ascii_case! { name, + "linear-gradient" => { + Ok(Image::LinearGradient(try!( + input.parse_nested_block(LinearGradient::parse_function)))) + } + _ => Err(()) } } - _ => Err(()), + _ => Err(()) } } - pub fn to_computed_value(self, context: &super::computed::Context) - -> super::computed::Image { + pub fn to_computed_value(self, context: &computed::Context) -> computed::Image { match self { - Image::Url(url) => super::computed::Image::Url(url), + Image::Url(url) => computed::Image::Url(url), Image::LinearGradient(linear_gradient) => { - super::computed::Image::LinearGradient( - super::computed::LinearGradient::compute(linear_gradient, context)) + computed::Image::LinearGradient( + computed::LinearGradient::compute(linear_gradient, context)) } } } } /// Specified values for a CSS linear gradient. - #[deriving(Clone, PartialEq)] + #[derive(Clone, PartialEq)] pub struct LinearGradient { /// The angle or corner of the gradient. pub angle_or_corner: AngleOrCorner, @@ -531,7 +531,7 @@ pub mod specified { } /// Specified values for an angle or a corner in a linear gradient. - #[deriving(Clone, PartialEq, Copy)] + #[derive(Clone, PartialEq, Copy)] pub enum AngleOrCorner { Angle(Angle), Corner(HorizontalDirection, VerticalDirection), @@ -557,7 +557,7 @@ pub mod specified { } /// Specified values for one color stop in a linear gradient. - #[deriving(Clone, PartialEq)] + #[derive(Clone, PartialEq)] pub struct ColorStop { /// The color of this stop. pub color: CSSColor, @@ -582,157 +582,108 @@ pub mod specified { } } - define_css_keyword_enum!(HorizontalDirection: "left" => Left, "right" => Right) - define_css_keyword_enum!(VerticalDirection: "top" => Top, "bottom" => Bottom) - - fn parse_color_stop(source: ParserIter) -> Result<ColorStop,()> { - let color = match source.next() { - Some(color) => try!(CSSColor::parse(color)), - None => return Err(()), - }; - - let position = match source.next() { - None => None, - Some(value) => { - match *value { - Comma => { - source.push_back(value); - None - } - ref position => Some(try!(LengthOrPercentage::parse(position))), - } - } - }; + define_css_keyword_enum!(HorizontalDirection: "left" => Left, "right" => Right); + define_css_keyword_enum!(VerticalDirection: "top" => Top, "bottom" => Bottom); + fn parse_one_color_stop(input: &mut Parser) -> Result<ColorStop, ()> { Ok(ColorStop { - color: color, - position: position, + color: try!(CSSColor::parse(input)), + position: input.try(LengthOrPercentage::parse).ok(), }) } impl LinearGradient { /// Parses a linear gradient from the given arguments. - pub fn parse_function(args: &[ComponentValue]) -> Result<LinearGradient,()> { - let mut source = BufferedIter::new(args.skip_whitespace()); - - // Parse the angle. - let (angle_or_corner, need_to_parse_comma) = match source.next() { - None => return Err(()), - Some(token) => { - match *token { - Dimension(ref value, ref unit) => { - match Angle::parse_dimension(value.value, unit.as_slice()) { - Ok(angle) => { - (AngleOrCorner::Angle(angle), true) - } - Err(()) => { - source.push_back(token); - (AngleOrCorner::Angle(Angle(PI)), false) - } - } - } - Ident(ref ident) if ident.as_slice().eq_ignore_ascii_case("to") => { - let (mut horizontal, mut vertical) = (None, None); - loop { - match source.next() { - None => break, - Some(token) => { - match *token { - Ident(ref ident) => { - let ident = ident.as_slice(); - if ident.eq_ignore_ascii_case("top") && - vertical.is_none() { - vertical = Some(VerticalDirection::Top) - } else if ident.eq_ignore_ascii_case("bottom") && - vertical.is_none() { - vertical = Some(VerticalDirection::Bottom) - } else if ident.eq_ignore_ascii_case("left") && - horizontal.is_none() { - horizontal = Some(HorizontalDirection::Left) - } else if ident.eq_ignore_ascii_case("right") && - horizontal.is_none() { - horizontal = Some(HorizontalDirection::Right) - } else { - return Err(()) - } - } - Comma => { - source.push_back(token); - break - } - _ => return Err(()), - } - } - } - } - - (match (horizontal, vertical) { - (None, Some(VerticalDirection::Top)) => { - AngleOrCorner::Angle(Angle(0.0)) - }, - (Some(HorizontalDirection::Right), None) => { - AngleOrCorner::Angle(Angle(PI * 0.5)) - }, - (None, Some(VerticalDirection::Bottom)) => { - AngleOrCorner::Angle(Angle(PI)) - }, - (Some(HorizontalDirection::Left), None) => { - AngleOrCorner::Angle(Angle(PI * 1.5)) - }, - (Some(horizontal), Some(vertical)) => { - AngleOrCorner::Corner(horizontal, vertical) - } - (None, None) => return Err(()), - }, true) - } - _ => { - source.push_back(token); - (AngleOrCorner::Angle(Angle(PI)), false) - } - } - } - }; - - // Parse the color stops. - let stops = if need_to_parse_comma { - match source.next() { - Some(&Comma) => { - try!(parsing_utils::parse_comma_separated(&mut source, parse_color_stop)) + pub fn parse_function(input: &mut Parser) -> Result<LinearGradient, ()> { + let angle_or_corner = if input.try(|input| input.expect_ident_matching("to")).is_ok() { + let (horizontal, vertical) = + if let Ok(value) = input.try(HorizontalDirection::parse) { + (Some(value), input.try(VerticalDirection::parse).ok()) + } else { + let value = try!(VerticalDirection::parse(input)); + (input.try(HorizontalDirection::parse).ok(), Some(value)) + }; + try!(input.expect_comma()); + match (horizontal, vertical) { + (None, Some(VerticalDirection::Top)) => { + AngleOrCorner::Angle(Angle(0.0)) + }, + (Some(HorizontalDirection::Right), None) => { + AngleOrCorner::Angle(Angle(PI * 0.5)) + }, + (None, Some(VerticalDirection::Bottom)) => { + AngleOrCorner::Angle(Angle(PI)) + }, + (Some(HorizontalDirection::Left), None) => { + AngleOrCorner::Angle(Angle(PI * 1.5)) + }, + (Some(horizontal), Some(vertical)) => { + AngleOrCorner::Corner(horizontal, vertical) } - None => Vec::new(), - Some(_) => return Err(()), + (None, None) => unreachable!(), } + } else if let Ok(angle) = input.try(Angle::parse) { + try!(input.expect_comma()); + AngleOrCorner::Angle(angle) } else { - try!(parsing_utils::parse_comma_separated(&mut source, parse_color_stop)) + AngleOrCorner::Angle(Angle(PI)) }; - + // Parse the color stops. + let stops = try!(input.parse_comma_separated(parse_one_color_stop)); if stops.len() < 2 { return Err(()) } - Ok(LinearGradient { angle_or_corner: angle_or_corner, stops: stops, }) } } + + + pub fn parse_border_width(input: &mut Parser) -> Result<Length, ()> { + input.try(Length::parse_non_negative).or_else(|()| { + match_ignore_ascii_case! { try!(input.expect_ident()), + "thin" => Ok(Length::from_px(1.)), + "medium" => Ok(Length::from_px(3.)), + "thick" => Ok(Length::from_px(5.)) + _ => Err(()) + } + }) + } + + define_css_keyword_enum! { BorderStyle: + "none" => none, + "solid" => solid, + "double" => double, + "dotted" => dotted, + "dashed" => dashed, + "hidden" => hidden, + "groove" => groove, + "ridge" => ridge, + "inset" => inset, + "outset" => outset, + } } + pub mod computed { - pub use super::specified::{Angle, AngleOrCorner, HorizontalDirection}; - pub use super::specified::{VerticalDirection}; + pub use super::specified::BorderStyle; + use super::specified::{AngleOrCorner}; + use super::{specified, CSSFloat}; pub use cssparser::Color as CSSColor; - use super::*; - use super::super::longhands; + use properties::longhands; use std::fmt; use url::Url; + use servo_util::geometry::Au; #[allow(missing_copy_implementations)] // It’s kinda big pub struct Context { pub inherited_font_weight: longhands::font_weight::computed_value::T, pub inherited_font_size: longhands::font_size::computed_value::T, - pub inherited_text_decorations_in_effect: longhands::_servo_text_decorations_in_effect::T, - pub inherited_height: longhands::height::T, + pub inherited_text_decorations_in_effect: + longhands::_servo_text_decorations_in_effect::computed_value::T, + pub inherited_height: longhands::height::computed_value::T, pub color: longhands::color::computed_value::T, pub text_decoration: longhands::text_decoration::computed_value::T, pub font_size: longhands::font_size::computed_value::T, @@ -750,12 +701,18 @@ pub mod computed { #[allow(non_snake_case)] #[inline] - pub fn compute_CSSColor(value: specified::CSSColor, _context: &computed::Context) -> CSSColor { + pub fn compute_CSSColor(value: specified::CSSColor, _context: &Context) -> CSSColor { value.parsed } #[allow(non_snake_case)] #[inline] + pub fn compute_BorderStyle(value: BorderStyle, _context: &Context) -> BorderStyle { + value + } + + #[allow(non_snake_case)] + #[inline] pub fn compute_Au(value: specified::Length, context: &Context) -> Au { compute_Au_with_font_size(value, context.font_size, context.root_font_size) } @@ -784,7 +741,7 @@ pub mod computed { } } - #[deriving(PartialEq, Clone, Copy)] + #[derive(PartialEq, Clone, Copy)] pub enum LengthOrPercentage { Length(Au), Percentage(CSSFloat), @@ -792,7 +749,7 @@ pub mod computed { impl fmt::Show for LengthOrPercentage { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &LengthOrPercentage::Length(length) => write!(f, "{}", length), + &LengthOrPercentage::Length(length) => write!(f, "{:?}", length), &LengthOrPercentage::Percentage(percentage) => write!(f, "{}%", percentage * 100.), } } @@ -809,7 +766,7 @@ pub mod computed { } } - #[deriving(PartialEq, Clone, Copy)] + #[derive(PartialEq, Clone, Copy)] pub enum LengthOrPercentageOrAuto { Length(Au), Percentage(CSSFloat), @@ -818,7 +775,7 @@ pub mod computed { impl fmt::Show for LengthOrPercentageOrAuto { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &LengthOrPercentageOrAuto::Length(length) => write!(f, "{}", length), + &LengthOrPercentageOrAuto::Length(length) => write!(f, "{:?}", length), &LengthOrPercentageOrAuto::Percentage(percentage) => write!(f, "{}%", percentage * 100.), &LengthOrPercentageOrAuto::Auto => write!(f, "auto"), } @@ -837,7 +794,7 @@ pub mod computed { } } - #[deriving(PartialEq, Clone, Copy)] + #[derive(PartialEq, Clone, Copy)] pub enum LengthOrPercentageOrNone { Length(Au), Percentage(CSSFloat), @@ -846,7 +803,7 @@ pub mod computed { impl fmt::Show for LengthOrPercentageOrNone { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &LengthOrPercentageOrNone::Length(length) => write!(f, "{}", length), + &LengthOrPercentageOrNone::Length(length) => write!(f, "{:?}", length), &LengthOrPercentageOrNone::Percentage(percentage) => write!(f, "{}%", percentage * 100.), &LengthOrPercentageOrNone::None => write!(f, "none"), } @@ -866,7 +823,7 @@ pub mod computed { } /// Computed values for an image according to CSS-IMAGES. - #[deriving(Clone, PartialEq)] + #[derive(Clone, PartialEq)] pub enum Image { Url(Url), LinearGradient(LinearGradient), @@ -876,13 +833,13 @@ pub mod computed { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &Image::Url(ref url) => write!(f, "url(\"{}\")", url), - &Image::LinearGradient(ref grad) => write!(f, "linear-gradient({})", grad), + &Image::LinearGradient(ref grad) => write!(f, "linear-gradient({:?})", grad), } } } /// Computed values for a CSS linear gradient. - #[deriving(Clone, PartialEq)] + #[derive(Clone, PartialEq)] pub struct LinearGradient { /// The angle or corner of the gradient. pub angle_or_corner: AngleOrCorner, @@ -893,16 +850,16 @@ pub mod computed { impl fmt::Show for LinearGradient { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let _ = write!(f, "{}", self.angle_or_corner); + let _ = write!(f, "{:?}", self.angle_or_corner); for stop in self.stops.iter() { - let _ = write!(f, ", {}", stop); + let _ = write!(f, ", {:?}", stop); } Ok(()) } } /// Computed values for one color stop in a linear gradient. - #[deriving(Clone, PartialEq, Copy)] + #[derive(Clone, PartialEq, Copy)] pub struct ColorStop { /// The color of this stop. pub color: CSSColor, @@ -914,9 +871,9 @@ pub mod computed { impl fmt::Show for ColorStop { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let _ = write!(f, "{}", self.color); + let _ = write!(f, "{:?}", self.color); self.position.map(|pos| { - let _ = write!(f, " {}", pos); + let _ = write!(f, " {:?}", pos); }); Ok(()) } @@ -951,8 +908,3 @@ pub mod computed { pub type Length = Au; } - -pub fn parse_url(input: &str, base_url: &Url) -> Url { - UrlParser::new().base_url(base_url).parse(input) - .unwrap_or_else(|_| Url::parse("about:invalid").unwrap()) -} diff --git a/components/util/Cargo.toml b/components/util/Cargo.toml index c418d0b2880..d9209c74e4f 100644 --- a/components/util/Cargo.toml +++ b/components/util/Cargo.toml @@ -36,11 +36,7 @@ git = "https://github.com/servo/string-cache" [dependencies.string_cache_macros] git = "https://github.com/servo/string-cache" -[dependencies.url] -git = "https://github.com/servo/rust-url" - -[dependencies.time] -git = "https://github.com/rust-lang/time" - [dependencies] text_writer = "0.1.1" +url = "*" +time = "*"
\ No newline at end of file diff --git a/components/util/bloom.rs b/components/util/bloom.rs index 2bed80e9e13..6fd5d17e775 100644 --- a/components/util/bloom.rs +++ b/components/util/bloom.rs @@ -58,7 +58,7 @@ const KEY_SHIFT: uint = 16; /// positive rate for N == 100 and to quite bad false positive /// rates for larger N. pub struct BloomFilter { - counters: [u8, ..ARRAY_SIZE], + counters: [u8; ARRAY_SIZE], } impl Clone for BloomFilter { @@ -75,7 +75,7 @@ impl BloomFilter { #[inline] pub fn new() -> BloomFilter { BloomFilter { - counters: [0, ..ARRAY_SIZE], + counters: [0; ARRAY_SIZE], } } @@ -101,7 +101,7 @@ impl BloomFilter { #[inline] pub fn clear(&mut self) { - self.counters = [0, ..ARRAY_SIZE] + self.counters = [0; ARRAY_SIZE] } #[inline] @@ -231,7 +231,7 @@ fn create_and_insert_some_stuff() { let false_positives = range(1001u, 2000).filter(|i| bf.might_contain(i)).count(); - assert!(false_positives < 10) // 1%. + assert!(false_positives < 10); // 1%. for i in range(0u, 100) { bf.remove(&i); @@ -256,7 +256,7 @@ fn create_and_insert_some_stuff() { mod bench { extern crate test; - use std::hash::hash; + use std::hash::{hash, SipHasher}; use std::iter; use super::BloomFilter; @@ -331,7 +331,7 @@ mod bench { fn hash_a_uint(b: &mut test::Bencher) { let mut i = 0u; b.iter(|| { - test::black_box(hash(&i)); + test::black_box(hash::<uint, SipHasher>(&i)); i += 1; }) } diff --git a/components/util/cache.rs b/components/util/cache.rs index 35390d309bf..99e086cdbfe 100644 --- a/components/util/cache.rs +++ b/components/util/cache.rs @@ -2,69 +2,59 @@ * 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/. */ +#![old_impl_check] + use std::collections::HashMap; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; +use std::collections::hash_state::DefaultState; use rand::Rng; -use std::hash::{Hash, sip}; +use std::hash::{Hash, SipHasher}; use std::iter::repeat; -use std::rand::task_rng; -use std::slice::Items; +use std::rand; +use std::slice::Iter; #[cfg(test)] use std::cell::Cell; -pub trait Cache<K: PartialEq, V: Clone> { - fn insert(&mut self, key: K, value: V); - fn find(&mut self, key: &K) -> Option<V>; - fn find_or_create(&mut self, key: &K, blk: |&K| -> V) -> V; - fn evict_all(&mut self); -} - pub struct HashCache<K, V> { - entries: HashMap<K, V>, + entries: HashMap<K, V, DefaultState<SipHasher>>, } -impl<K: Clone + PartialEq + Eq + Hash, V: Clone> HashCache<K,V> { - pub fn new() -> HashCache<K, V> { +impl<K, V> HashCache<K,V> + where K: Clone + PartialEq + Eq + Hash<SipHasher>, + V: Clone, +{ + pub fn new() -> HashCache<K,V> { HashCache { - entries: HashMap::new(), + entries: HashMap::with_hash_state(DefaultState), } } -} -impl<K: Clone + PartialEq + Eq + Hash, V: Clone> Cache<K,V> for HashCache<K,V> { - fn insert(&mut self, key: K, value: V) { + pub fn insert(&mut self, key: K, value: V) { self.entries.insert(key, value); } - fn find(&mut self, key: &K) -> Option<V> { + pub fn find(&self, key: &K) -> Option<V> { match self.entries.get(key) { Some(v) => Some(v.clone()), - None => None, + None => None, } } - fn find_or_create(&mut self, key: &K, blk: |&K| -> V) -> V { + pub fn find_or_create<F>(&mut self, key: &K, blk: F) -> V where F: Fn(&K) -> V { match self.entries.entry(key.clone()) { Occupied(occupied) => { (*occupied.get()).clone() } Vacant(vacant) => { - (*vacant.set(blk(key))).clone() + (*vacant.insert(blk(key))).clone() } } } - fn evict_all(&mut self) { + pub fn evict_all(&mut self) { self.entries.clear(); } - -} - -impl<K,V> HashCache<K,V> where K: Clone + PartialEq + Eq + Hash, V: Clone { - pub fn find_equiv<'a,Sized? Q>(&'a self, key: &Q) -> Option<&'a V> where Q: Hash + Equiv<K> { - self.entries.find_equiv(key) - } } #[test] @@ -98,32 +88,30 @@ impl<K: Clone + PartialEq, V: Clone> LRUCache<K,V> { let last_index = self.entries.len() - 1; if pos != last_index { let entry = self.entries.remove(pos); - self.entries.push(entry.unwrap()); + self.entries.push(entry); } - self.entries[last_index].ref1().clone() + self.entries[last_index].1.clone() } - pub fn iter<'a>(&'a self) -> Items<'a,(K,V)> { + pub fn iter<'a>(&'a self) -> Iter<'a,(K,V)> { self.entries.iter() } -} -impl<K: Clone + PartialEq, V: Clone> Cache<K,V> for LRUCache<K,V> { - fn insert(&mut self, key: K, val: V) { + pub fn insert(&mut self, key: K, val: V) { if self.entries.len() == self.cache_size { self.entries.remove(0); } self.entries.push((key, val)); } - fn find(&mut self, key: &K) -> Option<V> { - match self.entries.iter().position(|&(ref k, _)| *k == *key) { + pub fn find(&mut self, key: &K) -> Option<V> { + match self.entries.iter().position(|&(ref k, _)| key == k) { Some(pos) => Some(self.touch(pos)), None => None, } } - fn find_or_create(&mut self, key: &K, blk: |&K| -> V) -> V { + pub fn find_or_create<F>(&mut self, key: &K, blk: F) -> V where F: Fn(&K) -> V { match self.entries.iter().position(|&(ref k, _)| *k == *key) { Some(pos) => self.touch(pos), None => { @@ -134,7 +122,7 @@ impl<K: Clone + PartialEq, V: Clone> Cache<K,V> for LRUCache<K,V> { } } - fn evict_all(&mut self) { + pub fn evict_all(&mut self) { self.entries.clear(); } } @@ -145,9 +133,9 @@ pub struct SimpleHashCache<K,V> { k1: u64, } -impl<K:Clone+PartialEq+Hash,V:Clone> SimpleHashCache<K,V> { +impl<K:Clone+Eq+Hash<SipHasher>,V:Clone> SimpleHashCache<K,V> { pub fn new(cache_size: uint) -> SimpleHashCache<K,V> { - let mut r = task_rng(); + let mut r = rand::thread_rng(); SimpleHashCache { entries: repeat(None).take(cache_size).collect(), k0: r.gen(), @@ -161,35 +149,26 @@ impl<K:Clone+PartialEq+Hash,V:Clone> SimpleHashCache<K,V> { } #[inline] - fn bucket_for_key<Q:Hash>(&self, key: &Q) -> uint { - self.to_bucket(sip::hash_with_keys(self.k0, self.k1, key) as uint) + fn bucket_for_key<Q:Hash<SipHasher>>(&self, key: &Q) -> uint { + let mut hasher = SipHasher::new_with_keys(self.k0, self.k1); + key.hash(&mut hasher); + self.to_bucket(hasher.result() as uint) } - #[inline] - pub fn find_equiv<'a,Q:Hash+Equiv<K>>(&'a self, key: &Q) -> Option<&'a V> { - let bucket_index = self.bucket_for_key(key); - match self.entries[bucket_index] { - Some((ref existing_key, ref value)) if key.equiv(existing_key) => Some(value), - _ => None, - } - } -} - -impl<K:Clone+PartialEq+Hash,V:Clone> Cache<K,V> for SimpleHashCache<K,V> { - fn insert(&mut self, key: K, value: V) { + pub fn insert(&mut self, key: K, value: V) { let bucket_index = self.bucket_for_key(&key); self.entries[bucket_index] = Some((key, value)); } - fn find(&mut self, key: &K) -> Option<V> { + pub fn find<Q>(&self, key: &Q) -> Option<V> where Q: PartialEq<K> + Hash<SipHasher> + Eq { let bucket_index = self.bucket_for_key(key); match self.entries[bucket_index] { - Some((ref existing_key, ref value)) if existing_key == key => Some((*value).clone()), + Some((ref existing_key, ref value)) if key == existing_key => Some((*value).clone()), _ => None, } } - fn find_or_create(&mut self, key: &K, blk: |&K| -> V) -> V { + pub fn find_or_create<F>(&mut self, key: &K, blk: F) -> V where F: Fn(&K) -> V { match self.find(key) { Some(value) => return value, None => {} @@ -199,7 +178,7 @@ impl<K:Clone+PartialEq+Hash,V:Clone> Cache<K,V> for SimpleHashCache<K,V> { value } - fn evict_all(&mut self) { + pub fn evict_all(&mut self) { for slot in self.entries.iter_mut() { *slot = None } diff --git a/components/util/cursor.rs b/components/util/cursor.rs index 23ca2c0af4a..ff203f1a0e7 100644 --- a/components/util/cursor.rs +++ b/components/util/cursor.rs @@ -8,10 +8,9 @@ use cssparser::ToCss; use std::ascii::AsciiExt; use text_writer::TextWriter; - macro_rules! define_cursor { ($( $css: expr => $variant: ident = $value: expr, )+) => { - #[deriving(Clone, Copy, PartialEq, Eq, FromPrimitive, Show)] + #[derive(Clone, Copy, PartialEq, Eq, FromPrimitive, Show)] #[repr(u8)] pub enum Cursor { $( $variant = $value ),+ @@ -19,7 +18,7 @@ macro_rules! define_cursor { impl Cursor { pub fn from_css_keyword(keyword: &str) -> Result<Cursor, ()> { - match_ignore_ascii_case! { keyword: + match_ignore_ascii_case! { keyword, $( concat!($css) => Ok(Cursor::$variant) ),+ _ => Err(()) } diff --git a/components/util/deque/mod.rs b/components/util/deque/mod.rs index b98c872cf0f..505b09ab021 100644 --- a/components/util/deque/mod.rs +++ b/components/util/deque/mod.rs @@ -54,12 +54,13 @@ pub use self::Stolen::{Empty, Abort, Data}; use alloc::arc::Arc; use alloc::heap::{allocate, deallocate}; -use std::kinds::marker; +use std::marker; use std::mem::{forget, min_align_of, size_of, transmute}; use std::ptr; use std::sync::Mutex; -use std::sync::atomic::{AtomicInt, AtomicPtr, SeqCst}; +use std::sync::atomic::{AtomicInt, AtomicPtr}; +use std::sync::atomic::Ordering::SeqCst; // Once the queue is less than 1/K full, then it will be downsized. Note that // the deque requires that this number be less than 2. @@ -97,7 +98,7 @@ pub struct Stealer<T> { } /// When stealing some data, this is an enumeration of the possible outcomes. -#[deriving(PartialEq, Show)] +#[derive(PartialEq, Show)] pub enum Stolen<T> { /// The deque was empty at the time of stealing Empty, @@ -141,6 +142,8 @@ struct Buffer<T> { log_size: uint, } +unsafe impl<T: 'static> Send for Buffer<T> { } + impl<T: Send> BufferPool<T> { /// Allocates a new buffer pool which in turn can be used to allocate new /// deques. @@ -159,16 +162,16 @@ impl<T: Send> BufferPool<T> { fn alloc(&mut self, bits: uint) -> Box<Buffer<T>> { unsafe { - let mut pool = self.pool.lock(); + let mut pool = self.pool.lock().unwrap(); match pool.iter().position(|x| x.size() >= (1 << bits)) { - Some(i) => pool.remove(i).unwrap(), + Some(i) => pool.remove(i), None => box Buffer::new(bits) } } } fn free(&self, buf: Box<Buffer<T>>) { - let mut pool = self.pool.lock(); + let mut pool = self.pool.lock().unwrap(); match pool.iter().position(|v| v.size() > buf.size()) { Some(i) => pool.insert(i, buf), None => pool.push(buf), @@ -403,256 +406,3 @@ impl<T: Send> Drop for Buffer<T> { unsafe { deallocate(self.storage as *mut u8, size, min_align_of::<T>()) } } } - -#[cfg(test)] -mod tests { - use super::{Data, BufferPool, Abort, Empty, Worker, Stealer}; - - use std::mem; - use rustrt::thread::Thread; - use std::rand; - use std::rand::Rng; - use std::sync::atomic::{AtomicBool, INIT_ATOMIC_BOOL, SeqCst, - AtomicUint, INIT_ATOMIC_UINT}; - use std::vec; - - #[test] - fn smoke() { - let pool = BufferPool::new(); - let (w, s) = pool.deque(); - assert_eq!(w.pop(), None); - assert_eq!(s.steal(), Empty); - w.push(1i); - assert_eq!(w.pop(), Some(1)); - w.push(1); - assert_eq!(s.steal(), Data(1)); - w.push(1); - assert_eq!(s.clone().steal(), Data(1)); - } - - #[test] - fn stealpush() { - static AMT: int = 100000; - let pool = BufferPool::<int>::new(); - let (w, s) = pool.deque(); - let t = Thread::start(proc() { - let mut left = AMT; - while left > 0 { - match s.steal() { - Data(i) => { - assert_eq!(i, 1); - left -= 1; - } - Abort | Empty => {} - } - } - }); - - for _ in range(0, AMT) { - w.push(1); - } - - t.join(); - } - - #[test] - fn stealpush_large() { - static AMT: int = 100000; - let pool = BufferPool::<(int, int)>::new(); - let (w, s) = pool.deque(); - let t = Thread::start(proc() { - let mut left = AMT; - while left > 0 { - match s.steal() { - Data((1, 10)) => { left -= 1; } - Data(..) => panic!(), - Abort | Empty => {} - } - } - }); - - for _ in range(0, AMT) { - w.push((1, 10)); - } - - t.join(); - } - - fn stampede(w: Worker<Box<int>>, s: Stealer<Box<int>>, - nthreads: int, amt: uint) { - for _ in range(0, amt) { - w.push(box 20); - } - let mut remaining = AtomicUint::new(amt); - let unsafe_remaining: *mut AtomicUint = &mut remaining; - - let threads = range(0, nthreads).map(|_| { - let s = s.clone(); - Thread::start(proc() { - unsafe { - while (*unsafe_remaining).load(SeqCst) > 0 { - match s.steal() { - Data(box 20) => { - (*unsafe_remaining).fetch_sub(1, SeqCst); - } - Data(..) => panic!(), - Abort | Empty => {} - } - } - } - }) - }).collect::<Vec<Thread<()>>>(); - - while remaining.load(SeqCst) > 0 { - match w.pop() { - Some(box 20) => { remaining.fetch_sub(1, SeqCst); } - Some(..) => panic!(), - None => {} - } - } - - for thread in threads.into_iter() { - thread.join(); - } - } - - #[test] - fn run_stampede() { - let pool = BufferPool::<Box<int>>::new(); - let (w, s) = pool.deque(); - stampede(w, s, 8, 10000); - } - - #[test] - fn many_stampede() { - static AMT: uint = 4; - let pool = BufferPool::<Box<int>>::new(); - let threads = range(0, AMT).map(|_| { - let (w, s) = pool.deque(); - Thread::start(proc() { - stampede(w, s, 4, 10000); - }) - }).collect::<Vec<Thread<()>>>(); - - for thread in threads.into_iter() { - thread.join(); - } - } - - #[test] - fn stress() { - static AMT: int = 100000; - static NTHREADS: int = 8; - static DONE: AtomicBool = INIT_ATOMIC_BOOL; - static HITS: AtomicUint = INIT_ATOMIC_UINT; - let pool = BufferPool::<int>::new(); - let (w, s) = pool.deque(); - - let threads = range(0, NTHREADS).map(|_| { - let s = s.clone(); - Thread::start(proc() { - loop { - match s.steal() { - Data(2) => { HITS.fetch_add(1, SeqCst); } - Data(..) => panic!(), - _ if DONE.load(SeqCst) => break, - _ => {} - } - } - }) - }).collect::<Vec<Thread<()>>>(); - - let mut rng = rand::task_rng(); - let mut expected = 0; - while expected < AMT { - if rng.gen_range(0i, 3) == 2 { - match w.pop() { - None => {} - Some(2) => { HITS.fetch_add(1, SeqCst); }, - Some(_) => panic!(), - } - } else { - expected += 1; - w.push(2); - } - } - - while HITS.load(SeqCst) < AMT as uint { - match w.pop() { - None => {} - Some(2) => { HITS.fetch_add(1, SeqCst); }, - Some(_) => panic!(), - } - } - DONE.store(true, SeqCst); - - for thread in threads.into_iter() { - thread.join(); - } - - assert_eq!(HITS.load(SeqCst), expected as uint); - } - - #[test] - #[cfg_attr(windows, ignore)] // apparently windows scheduling is weird? - fn no_starvation() { - static AMT: int = 10000; - static NTHREADS: int = 4; - static DONE: AtomicBool = INIT_ATOMIC_BOOL; - let pool = BufferPool::<(int, uint)>::new(); - let (w, s) = pool.deque(); - - let (threads, hits) = vec::unzip(range(0, NTHREADS).map(|_| { - let s = s.clone(); - let unique_box = box AtomicUint::new(0); - let thread_box = unsafe { - *mem::transmute::<&Box<AtomicUint>, - *const *mut AtomicUint>(&unique_box) - }; - (Thread::start(proc() { - unsafe { - loop { - match s.steal() { - Data((1, 2)) => { - (*thread_box).fetch_add(1, SeqCst); - } - Data(..) => panic!(), - _ if DONE.load(SeqCst) => break, - _ => {} - } - } - } - }), unique_box) - })); - - let mut rng = rand::task_rng(); - let mut myhit = false; - 'outer: loop { - for _ in range(0, rng.gen_range(0, AMT)) { - if !myhit && rng.gen_range(0i, 3) == 2 { - match w.pop() { - None => {} - Some((1, 2)) => myhit = true, - Some(_) => panic!(), - } - } else { - w.push((1, 2)); - } - } - - for slot in hits.iter() { - let amt = slot.load(SeqCst); - if amt == 0 { continue 'outer; } - } - if myhit { - break - } - } - - DONE.store(true, SeqCst); - - for thread in threads.into_iter() { - thread.join(); - } - } -} diff --git a/components/util/fnv.rs b/components/util/fnv.rs index 13c8e1c28ad..61b4cd73d48 100644 --- a/components/util/fnv.rs +++ b/components/util/fnv.rs @@ -4,7 +4,8 @@ //! This file stolen wholesale from rustc/src/librustc/util/nodemap.rs -pub use std::hash::{Hash, Hasher, Writer}; +use std::default::Default; +use std::hash::{Hasher, Writer}; /// A speedy hash algorithm for node ids and def ids. The hashmap in /// libcollections by default uses SipHash which isn't quite as speedy as we @@ -13,33 +14,26 @@ pub use std::hash::{Hash, Hasher, Writer}; /// /// This uses FNV hashing, as described here: /// http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function -#[deriving(Clone)] -pub struct FnvHasher; +#[allow(missing_copy_implementations)] +pub struct FnvHasher(u64); -pub struct FnvState(u64); +impl Default for FnvHasher { + fn default() -> FnvHasher { FnvHasher(0xcbf29ce484222325) } +} -impl Hasher<FnvState> for FnvHasher { - fn hash<Sized? T: Hash<FnvState>>(&self, t: &T) -> u64 { - let mut state = FnvState(0xcbf29ce484222325); - t.hash(&mut state); - let FnvState(ret) = state; - return ret; - } +impl Hasher for FnvHasher { + type Output = u64; + fn reset(&mut self) { *self = Default::default(); } + fn finish(&self) -> u64 { self.0 } } -impl Writer for FnvState { +impl Writer for FnvHasher { fn write(&mut self, bytes: &[u8]) { - let FnvState(mut hash) = *self; + let FnvHasher(mut hash) = *self; for byte in bytes.iter() { hash = hash ^ (*byte as u64); hash = hash * 0x100000001b3; } - *self = FnvState(hash); + *self = FnvHasher(hash); } } - -#[inline(always)] -pub fn hash<T: Hash<FnvState>>(t: &T) -> u64 { - let s = FnvHasher; - s.hash(t) -} diff --git a/components/util/geometry.rs b/components/util/geometry.rs index 5c3ee808b43..a30849eaf5d 100644 --- a/components/util/geometry.rs +++ b/components/util/geometry.rs @@ -8,11 +8,13 @@ use geom::rect::Rect; use geom::size::Size2D; use geom::num::Zero; -use serialize::{Encodable, Encoder}; use std::default::Default; use std::i32; -use std::num::{Float, NumCast}; +use std::num::{Float, NumCast, ToPrimitive}; use std::fmt; +use std::ops::{Add, Sub, Neg, Mul, Div, Rem}; + +use rustc_serialize::{Encoder, Encodable}; // Units for use with geom::length and geom::scale_factor. @@ -29,7 +31,7 @@ use std::fmt; /// /// The ratio between ScreenPx and DevicePixel for a given display be found by calling /// `servo::windowing::WindowMethods::hidpi_factor`. -#[deriving(Show, Copy)] +#[derive(Show, Copy)] pub enum ScreenPx {} /// One CSS "px" in the coordinate system of the "initial viewport": @@ -41,7 +43,7 @@ pub enum ScreenPx {} /// /// At the default zoom level of 100%, one PagePx is equal to one ScreenPx. However, if the /// document is zoomed in or out then this scale may be larger or smaller. -#[deriving(Encodable, Show, Copy)] +#[derive(RustcEncodable, Show, Copy)] pub enum ViewportPx {} /// One CSS "px" in the root coordinate system for the content document. @@ -50,7 +52,7 @@ pub enum ViewportPx {} /// This is the mobile-style "pinch zoom" that enlarges content without reflowing it. When the /// viewport zoom is not equal to 1.0, then the layout viewport is no longer the same physical size /// as the viewable area. -#[deriving(Encodable, Show, Copy)] +#[derive(RustcEncodable, Show, Copy)] pub enum PagePx {} // In summary, the hierarchy of pixel units and the factors to convert from one to the next: @@ -65,7 +67,7 @@ pub enum PagePx {} // See https://bugzilla.mozilla.org/show_bug.cgi?id=177805 for more info. // // FIXME: Implement Au using Length and ScaleFactor instead of a custom type. -#[deriving(Clone, Copy, Hash, PartialEq, PartialOrd, Eq, Ord)] +#[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Eq, Ord)] pub struct Au(pub i32); impl Default for Au { @@ -112,8 +114,8 @@ pub static MAX_RECT: Rect<Au> = Rect { pub const MIN_AU: Au = Au(i32::MIN); pub const MAX_AU: Au = Au(i32::MAX); -impl<E, S: Encoder<E>> Encodable<S, E> for Au { - fn encode(&self, e: &mut S) -> Result<(), E> { +impl Encodable for Au { + fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> { e.emit_f64(to_frac_px(*self)) } } @@ -123,53 +125,65 @@ impl fmt::Show for Au { write!(f, "{}px", to_frac_px(*self)) }} -impl Add<Au,Au> for Au { +impl Add for Au { + type Output = Au; + #[inline] - fn add(&self, other: &Au) -> Au { - let Au(s) = *self; - let Au(o) = *other; + fn add(self, other: Au) -> Au { + let Au(s) = self; + let Au(o) = other; Au(s + o) } } -impl Sub<Au,Au> for Au { +impl Sub for Au { + type Output = Au; + #[inline] - fn sub(&self, other: &Au) -> Au { - let Au(s) = *self; - let Au(o) = *other; + fn sub(self, other: Au) -> Au { + let Au(s) = self; + let Au(o) = other; Au(s - o) } } -impl Mul<i32, Au> for Au { +impl Mul<i32> for Au { + type Output = Au; + #[inline] - fn mul(&self, other: &i32) -> Au { - let Au(s) = *self; - Au(s * *other) + fn mul(self, other: i32) -> Au { + let Au(s) = self; + Au(s * other) } } -impl Div<i32, Au> for Au { +impl Div<i32> for Au { + type Output = Au; + #[inline] - fn div(&self, other: &i32) -> Au { - let Au(s) = *self; - Au(s / *other) + fn div(self, other: i32) -> Au { + let Au(s) = self; + Au(s / other) } } -impl Rem<i32, Au> for Au { +impl Rem<i32> for Au { + type Output = Au; + #[inline] - fn rem(&self, other: &i32) -> Au { - let Au(s) = *self; - Au(s % *other) + fn rem(self, other: i32) -> Au { + let Au(s) = self; + Au(s % other) } } -impl Neg<Au> for Au { +impl Neg for Au { + type Output = Au; + #[inline] - fn neg(&self) -> Au { - let Au(s) = *self; + fn neg(self) -> Au { + let Au(s) = self; Au(-s) } } @@ -323,7 +337,7 @@ pub fn to_pt(au: Au) -> f64 { /// Returns true if the rect contains the given point. Points on the top or left sides of the rect /// are considered inside the rectangle, while points on the right or bottom sides of the rect are /// not considered inside the rectangle. -pub fn rect_contains_point<T:PartialOrd + Add<T,T>>(rect: Rect<T>, point: Point2D<T>) -> bool { +pub fn rect_contains_point<T:PartialOrd + Add<T, Output=T>>(rect: Rect<T>, point: Point2D<T>) -> bool { point.x >= rect.origin.x && point.x < rect.origin.x + rect.size.width && point.y >= rect.origin.y && point.y < rect.origin.y + rect.size.height } diff --git a/components/util/lib.rs b/components/util/lib.rs index d69bc982e17..bceab7a3014 100644 --- a/components/util/lib.rs +++ b/components/util/lib.rs @@ -2,15 +2,18 @@ * 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/. */ -#![feature(default_type_params,macro_rules,unsafe_destructor)] +#![feature(unsafe_destructor)] +#![feature(plugin)] +#![feature(int_uint)] +#![feature(old_impl_check)] +#![feature(box_syntax)] #![deny(unused_imports)] #![deny(unused_variables)] #![allow(missing_copy_implementations)] +#![allow(unstable)] -#![feature(phase)] -#[phase(plugin, link)] -extern crate log; +#[macro_use] extern crate log; extern crate alloc; extern crate collections; @@ -19,9 +22,9 @@ extern crate geom; extern crate getopts; extern crate layers; extern crate libc; +#[no_link] #[macro_use] extern crate cssparser; extern crate rand; -extern crate rustrt; -extern crate serialize; +extern crate "serialize" as rustc_serialize; #[cfg(target_os="macos")] extern crate task_info; extern crate "time" as std_time; @@ -30,9 +33,9 @@ extern crate string_cache; extern crate unicode; extern crate url; -#[phase(plugin)] extern crate plugins; -#[phase(plugin)] extern crate string_cache_macros; -#[phase(plugin)] extern crate lazy_static; +#[no_link] #[macro_use] #[plugin] +extern crate string_cache_macros; +extern crate lazy_static; use std::sync::Arc; @@ -51,8 +54,6 @@ pub mod opts; pub mod persistent_list; pub mod range; pub mod resource_files; -// FIXME: Find replacement for this post-runtime removal -// pub mod rtinstrument; pub mod smallvec; pub mod sort; pub mod str; @@ -71,7 +72,7 @@ pub fn breakpoint() { // Workaround for lack of `ptr_eq` on Arcs... #[inline] pub fn arc_ptr_eq<T: 'static + Send + Sync>(a: &Arc<T>, b: &Arc<T>) -> bool { - let a: &T = a.deref(); - let b: &T = b.deref(); + let a: &T = &**a; + let b: &T = &**b; (a as *const T) == (b as *const T) } diff --git a/components/util/logical_geometry.rs b/components/util/logical_geometry.rs index eebd0735b81..a76bd1ca21e 100644 --- a/components/util/logical_geometry.rs +++ b/components/util/logical_geometry.rs @@ -8,16 +8,17 @@ use geom::{Size2D, Point2D, SideOffsets2D, Rect}; use geom::num::Zero; use std::cmp::{min, max}; use std::fmt::{Show, Formatter, Error}; +use std::ops::{Add, Sub}; bitflags!( - #[deriving(Encodable, Copy)] + #[derive(RustcEncodable)] flags WritingMode: u8 { const FLAG_RTL = 1 << 0, const FLAG_VERTICAL = 1 << 1, const FLAG_VERTICAL_LR = 1 << 2, const FLAG_SIDEWAYS_LEFT = 1 << 3 } -) +); impl WritingMode { #[inline] @@ -79,11 +80,11 @@ impl Show for WritingMode { /// (in addition to taking it as a parameter to methods) and check it. /// In non-debug builds, make this storage zero-size and the checks no-ops. #[cfg(ndebug)] -#[deriving(Encodable, PartialEq, Eq, Clone, Copy)] +#[derive(RustcEncodable, PartialEq, Eq, Clone, Copy)] struct DebugWritingMode; #[cfg(not(ndebug))] -#[deriving(Encodable, PartialEq, Eq, Clone, Copy)] +#[derive(RustcEncodable, PartialEq, Eq, Clone, Copy)] struct DebugWritingMode { mode: WritingMode } @@ -134,7 +135,7 @@ impl Show for DebugWritingMode { /// A 2D size in flow-relative dimensions -#[deriving(Encodable, PartialEq, Eq, Clone, Copy)] +#[derive(RustcEncodable, PartialEq, Eq, Clone, Copy)] pub struct LogicalSize<T> { pub inline: T, // inline-size, a.k.a. logical width, a.k.a. measure pub block: T, // block-size, a.k.a. logical height, a.k.a. extent @@ -143,7 +144,7 @@ pub struct LogicalSize<T> { impl<T: Show> Show for LogicalSize<T> { fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> { - write!(formatter, "LogicalSize({}, i{}×b{})", + write!(formatter, "LogicalSize({:?}, i{:?}×b{:?})", self.debug_writing_mode, self.inline, self.block) } } @@ -240,9 +241,11 @@ impl<T: Copy> LogicalSize<T> { } } -impl<T: Add<T, T>> Add<LogicalSize<T>, LogicalSize<T>> for LogicalSize<T> { +impl<T: Add<T, Output=T>> Add for LogicalSize<T> { + type Output = LogicalSize<T>; + #[inline] - fn add(&self, other: &LogicalSize<T>) -> LogicalSize<T> { + fn add(self, other: LogicalSize<T>) -> LogicalSize<T> { self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalSize { debug_writing_mode: self.debug_writing_mode, @@ -252,9 +255,11 @@ impl<T: Add<T, T>> Add<LogicalSize<T>, LogicalSize<T>> for LogicalSize<T> { } } -impl<T: Sub<T, T>> Sub<LogicalSize<T>, LogicalSize<T>> for LogicalSize<T> { +impl<T: Sub<T, Output=T>> Sub for LogicalSize<T> { + type Output = LogicalSize<T>; + #[inline] - fn sub(&self, other: &LogicalSize<T>) -> LogicalSize<T> { + fn sub(self, other: LogicalSize<T>) -> LogicalSize<T> { self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalSize { debug_writing_mode: self.debug_writing_mode, @@ -266,7 +271,7 @@ impl<T: Sub<T, T>> Sub<LogicalSize<T>, LogicalSize<T>> for LogicalSize<T> { /// A 2D point in flow-relative dimensions -#[deriving(PartialEq, Encodable, Eq, Clone, Copy)] +#[derive(PartialEq, RustcEncodable, Eq, Clone, Copy)] pub struct LogicalPoint<T> { pub i: T, /// inline-axis coordinate pub b: T, /// block-axis coordinate @@ -275,7 +280,7 @@ pub struct LogicalPoint<T> { impl<T: Show> Show for LogicalPoint<T> { fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> { - write!(formatter, "LogicalPoint({} (i{}, b{}))", + write!(formatter, "LogicalPoint({:?} (i{:?}, b{:?}))", self.debug_writing_mode, self.i, self.b) } } @@ -303,7 +308,7 @@ impl<T: Copy> LogicalPoint<T> { } } -impl<T: Copy + Sub<T, T>> LogicalPoint<T> { +impl<T: Copy + Sub<T, Output=T>> LogicalPoint<T> { #[inline] pub fn from_physical(mode: WritingMode, point: Point2D<T>, container_size: Size2D<T>) -> LogicalPoint<T> { @@ -391,7 +396,7 @@ impl<T: Copy + Sub<T, T>> LogicalPoint<T> { } } -impl<T: Add<T,T>> LogicalPoint<T> { +impl<T: Copy + Add<T, Output=T>> LogicalPoint<T> { /// This doesn’t really makes sense, /// but happens when dealing with multiple origins. #[inline] @@ -405,9 +410,11 @@ impl<T: Add<T,T>> LogicalPoint<T> { } } -impl<T: Add<T,T>> Add<LogicalSize<T>, LogicalPoint<T>> for LogicalPoint<T> { +impl<T: Copy + Add<T,Output=T>> Add<LogicalSize<T>> for LogicalPoint<T> { + type Output = LogicalPoint<T>; + #[inline] - fn add(&self, other: &LogicalSize<T>) -> LogicalPoint<T> { + fn add(self, other: LogicalSize<T>) -> LogicalPoint<T> { self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalPoint { debug_writing_mode: self.debug_writing_mode, @@ -417,9 +424,11 @@ impl<T: Add<T,T>> Add<LogicalSize<T>, LogicalPoint<T>> for LogicalPoint<T> { } } -impl<T: Sub<T,T>> Sub<LogicalSize<T>, LogicalPoint<T>> for LogicalPoint<T> { +impl<T: Copy + Sub<T,Output=T>> Sub<LogicalSize<T>> for LogicalPoint<T> { + type Output = LogicalPoint<T>; + #[inline] - fn sub(&self, other: &LogicalSize<T>) -> LogicalPoint<T> { + fn sub(self, other: LogicalSize<T>) -> LogicalPoint<T> { self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalPoint { debug_writing_mode: self.debug_writing_mode, @@ -434,7 +443,7 @@ impl<T: Sub<T,T>> Sub<LogicalSize<T>, LogicalPoint<T>> for LogicalPoint<T> { /// Represents the four sides of the margins, borders, or padding of a CSS box, /// or a combination of those. /// A positive "margin" can be added to a rectangle to obtain a bigger rectangle. -#[deriving(Encodable, PartialEq, Eq, Clone, Copy)] +#[derive(RustcEncodable, PartialEq, Eq, Clone, Copy)] pub struct LogicalMargin<T> { pub block_start: T, pub inline_end: T, @@ -446,7 +455,7 @@ pub struct LogicalMargin<T> { impl<T: Show> Show for LogicalMargin<T> { fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> { write!(formatter, - "LogicalMargin({}, inline: {}..{} block: {}..{})", + "LogicalMargin({:?}, inline: {:?}..{:?} block: {:?}..{:?})", self.debug_writing_mode, self.inline_start, self.inline_end, @@ -656,7 +665,7 @@ impl<T: PartialEq + Zero> LogicalMargin<T> { } } -impl<T: Add<T, T>> LogicalMargin<T> { +impl<T: Copy + Add<T, Output=T>> LogicalMargin<T> { #[inline] pub fn inline_start_end(&self) -> T { self.inline_start + self.inline_end @@ -688,9 +697,11 @@ impl<T: Add<T, T>> LogicalMargin<T> { } } -impl<T: Add<T, T>> Add<LogicalMargin<T>, LogicalMargin<T>> for LogicalMargin<T> { +impl<T: Add<T, Output=T>> Add for LogicalMargin<T> { + type Output = LogicalMargin<T>; + #[inline] - fn add(&self, other: &LogicalMargin<T>) -> LogicalMargin<T> { + fn add(self, other: LogicalMargin<T>) -> LogicalMargin<T> { self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalMargin { debug_writing_mode: self.debug_writing_mode, @@ -702,9 +713,11 @@ impl<T: Add<T, T>> Add<LogicalMargin<T>, LogicalMargin<T>> for LogicalMargin<T> } } -impl<T: Sub<T, T>> Sub<LogicalMargin<T>, LogicalMargin<T>> for LogicalMargin<T> { +impl<T: Sub<T, Output=T>> Sub for LogicalMargin<T> { + type Output = LogicalMargin<T>; + #[inline] - fn sub(&self, other: &LogicalMargin<T>) -> LogicalMargin<T> { + fn sub(self, other: LogicalMargin<T>) -> LogicalMargin<T> { self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalMargin { debug_writing_mode: self.debug_writing_mode, @@ -718,7 +731,7 @@ impl<T: Sub<T, T>> Sub<LogicalMargin<T>, LogicalMargin<T>> for LogicalMargin<T> /// A rectangle in flow-relative dimensions -#[deriving(Encodable, PartialEq, Eq, Clone, Copy)] +#[derive(RustcEncodable, PartialEq, Eq, Clone, Copy)] pub struct LogicalRect<T> { pub start: LogicalPoint<T>, pub size: LogicalSize<T>, @@ -728,7 +741,7 @@ pub struct LogicalRect<T> { impl<T: Show> Show for LogicalRect<T> { fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> { write!(formatter, - "LogicalRect({}, i{}×b{}, @ (i{},b{}))", + "LogicalRect({:?}, i{:?}×b{:?}, @ (i{:?},b{:?}))", self.debug_writing_mode, self.size.inline, self.size.block, @@ -772,7 +785,7 @@ impl<T: Copy> LogicalRect<T> { } } -impl<T: Copy + Add<T, T> + Sub<T, T>> LogicalRect<T> { +impl<T: Copy + Add<T, Output=T> + Sub<T, Output=T>> LogicalRect<T> { #[inline] pub fn from_physical(mode: WritingMode, rect: Rect<T>, container_size: Size2D<T>) -> LogicalRect<T> { @@ -881,7 +894,7 @@ impl<T: Copy + Add<T, T> + Sub<T, T>> LogicalRect<T> { } } -impl<T: Copy + Ord + Add<T, T> + Sub<T, T>> LogicalRect<T> { +impl<T: Copy + Ord + Add<T, Output=T> + Sub<T, Output=T>> LogicalRect<T> { #[inline] pub fn union(&self, other: &LogicalRect<T>) -> LogicalRect<T> { self.debug_writing_mode.check_debug(other.debug_writing_mode); @@ -904,9 +917,11 @@ impl<T: Copy + Ord + Add<T, T> + Sub<T, T>> LogicalRect<T> { } } -impl<T: Add<T, T> + Sub<T, T>> Add<LogicalMargin<T>, LogicalRect<T>> for LogicalRect<T> { +impl<T: Copy + Add<T, Output=T> + Sub<T, Output=T>> Add<LogicalMargin<T>> for LogicalRect<T> { + type Output = LogicalRect<T>; + #[inline] - fn add(&self, other: &LogicalMargin<T>) -> LogicalRect<T> { + fn add(self, other: LogicalMargin<T>) -> LogicalRect<T> { self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalRect { start: LogicalPoint { @@ -927,9 +942,11 @@ impl<T: Add<T, T> + Sub<T, T>> Add<LogicalMargin<T>, LogicalRect<T>> for Logical } -impl<T: Add<T, T> + Sub<T, T>> Sub<LogicalMargin<T>, LogicalRect<T>> for LogicalRect<T> { +impl<T: Copy + Add<T, Output=T> + Sub<T, Output=T>> Sub<LogicalMargin<T>> for LogicalRect<T> { + type Output = LogicalRect<T>; + #[inline] - fn sub(&self, other: &LogicalMargin<T>) -> LogicalRect<T> { + fn sub(self, other: LogicalMargin<T>) -> LogicalRect<T> { self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalRect { start: LogicalPoint { @@ -950,7 +967,7 @@ impl<T: Add<T, T> + Sub<T, T>> Sub<LogicalMargin<T>, LogicalRect<T>> for Logical } #[cfg(test)] -fn modes() -> [WritingMode, ..10] { +fn modes() -> [WritingMode; 10] { [ WritingMode::empty(), FLAG_VERTICAL, diff --git a/components/util/memory.rs b/components/util/memory.rs index 0c1d1dac3b1..5e3033e2aa5 100644 --- a/components/util/memory.rs +++ b/components/util/memory.rs @@ -5,13 +5,17 @@ //! Memory profiling functions. use libc::{c_char,c_int,c_void,size_t}; +use std::borrow::ToOwned; +use std::ffi::CString; use std::io::timer::sleep; #[cfg(target_os="linux")] use std::io::File; +use std::mem; use std::mem::size_of; #[cfg(target_os="linux")] use std::os::page_size; use std::ptr::null_mut; +use std::sync::mpsc::{Sender, channel, Receiver}; use std::time::duration::Duration; use task::spawn_named; #[cfg(target_os="macos")] @@ -44,16 +48,16 @@ impl MemoryProfiler { Some(period) => { let period = Duration::milliseconds((period * 1000f64) as i64); let chan = chan.clone(); - spawn_named("Memory profiler timer", proc() { + spawn_named("Memory profiler timer".to_owned(), move || { loop { sleep(period); - if chan.send_opt(MemoryProfilerMsg::Print).is_err() { + if chan.send(MemoryProfilerMsg::Print).is_err() { break; } } }); // Spawn the memory profiler. - spawn_named("Memory profiler", proc() { + spawn_named("Memory profiler".to_owned(), move || { let memory_profiler = MemoryProfiler::new(port); memory_profiler.start(); }); @@ -61,9 +65,9 @@ impl MemoryProfiler { None => { // No-op to handle messages when the memory profiler is // inactive. - spawn_named("Memory profiler", proc() { + spawn_named("Memory profiler".to_owned(), move || { loop { - match port.recv_opt() { + match port.recv() { Err(_) | Ok(MemoryProfilerMsg::Exit) => break, _ => {} } @@ -83,7 +87,7 @@ impl MemoryProfiler { pub fn start(&self) { loop { - match self.port.recv_opt() { + match self.port.recv() { Ok(msg) => { if !self.handle_msg(msg) { break @@ -150,12 +154,13 @@ extern { fn get_jemalloc_stat(name: &'static str) -> Option<u64> { let mut old: size_t = 0; - let c_name = name.to_c_str(); + let c_name = CString::from_slice(name.as_bytes()); let oldp = &mut old as *mut _ as *mut c_void; let mut oldlen = size_of::<size_t>() as size_t; let rv: c_int; unsafe { - rv = je_mallctl(c_name.into_inner(), oldp, &mut oldlen, null_mut(), 0); + rv = je_mallctl(c_name.as_ptr(), oldp, &mut oldlen, null_mut(), 0); + mem::forget(c_name); // XXX correct? } if rv == 0 { Some(old as u64) } else { None } } @@ -163,7 +168,7 @@ fn get_jemalloc_stat(name: &'static str) -> Option<u64> { // Like std::macros::try!, but for Option<>. macro_rules! option_try( ($e:expr) => (match $e { Some(e) => e, None => return None }) -) +); #[cfg(target_os="linux")] fn get_proc_self_statm_field(field: uint) -> Option<u64> { @@ -171,7 +176,7 @@ fn get_proc_self_statm_field(field: uint) -> Option<u64> { match f.read_to_string() { Ok(contents) => { let s = option_try!(contents.as_slice().words().nth(field)); - let npages: u64 = option_try!(from_str(s)); + let npages: u64 = option_try!(s.parse()); Some(npages * (page_size() as u64)) } Err(_) => None diff --git a/components/util/opts.rs b/components/util/opts.rs index 8ee877bd9fd..ae19723b975 100644 --- a/components/util/opts.rs +++ b/components/util/opts.rs @@ -19,14 +19,8 @@ use std::os; use std::ptr; use std::rt; -#[deriving(Clone, Copy)] -pub enum RenderApi { - OpenGL, - Mesa, -} - /// Global flags for Servo, currently set on the command line. -#[deriving(Clone)] +#[derive(Clone)] pub struct Opts { /// The initial URLs to load. pub urls: Vec<String>, @@ -112,8 +106,6 @@ pub struct Opts { /// Whether to show an error when display list geometry escapes flow overflow regions. pub validate_display_list_geometry: bool, - pub render_api: RenderApi, - /// A specific path to find required resources (such as user-agent.css). pub resources_path: Option<String>, } @@ -182,7 +174,6 @@ pub fn default_opts() -> Opts { dump_flow_tree: false, validate_display_list_geometry: false, profile_tasks: false, - render_api: RenderApi::OpenGL, resources_path: None, } } @@ -250,31 +241,31 @@ pub fn from_cmdline_args(args: &[String]) -> bool { }; let tile_size: uint = match opt_match.opt_str("s") { - Some(tile_size_str) => from_str(tile_size_str.as_slice()).unwrap(), + Some(tile_size_str) => tile_size_str.parse().unwrap(), None => 512, }; let device_pixels_per_px = opt_match.opt_str("device-pixel-ratio").map(|dppx_str| - ScaleFactor(from_str(dppx_str.as_slice()).unwrap()) + ScaleFactor(dppx_str.parse().unwrap()) ); let mut n_paint_threads: uint = match opt_match.opt_str("t") { - Some(n_paint_threads_str) => from_str(n_paint_threads_str.as_slice()).unwrap(), + Some(n_paint_threads_str) => n_paint_threads_str.parse().unwrap(), None => 1, // FIXME: Number of cores. }; // If only the flag is present, default to a 5 second period for both profilers. let time_profiler_period = opt_match.opt_default("p", "5").map(|period| { - from_str(period.as_slice()).unwrap() + period.parse().unwrap() }); let memory_profiler_period = opt_match.opt_default("m", "5").map(|period| { - from_str(period.as_slice()).unwrap() + period.parse().unwrap() }); let gpu_painting = !FORCE_CPU_PAINTING && opt_match.opt_present("g"); let mut layout_threads: uint = match opt_match.opt_str("y") { - Some(layout_threads_str) => from_str(layout_threads_str.as_slice()).unwrap(), + Some(layout_threads_str) => layout_threads_str.parse().unwrap(), None => cmp::max(rt::default_sched_threads() * 3 / 4, 1), }; @@ -289,12 +280,12 @@ pub fn from_cmdline_args(args: &[String]) -> bool { } let devtools_port = opt_match.opt_default("devtools", "6000").map(|port| { - from_str(port.as_slice()).unwrap() + port.parse().unwrap() }); let initial_window_size = match opt_match.opt_str("resolution") { Some(res_string) => { - let res: Vec<uint> = res_string.as_slice().split('x').map(|r| from_str(r).unwrap()).collect(); + let res: Vec<uint> = res_string.split('x').map(|r| r.parse().unwrap()).collect(); TypedSize2D(res[0], res[1]) } None => { @@ -302,15 +293,6 @@ pub fn from_cmdline_args(args: &[String]) -> bool { } }; - let render_api = match opt_match.opt_str("r").unwrap_or("gl".into_string()).as_slice() { - "mesa" => RenderApi::Mesa, - "gl" => RenderApi::OpenGL, - _ => { - args_fail("Unknown render api specified"); - return false; - } - }; - let opts = Opts { urls: urls, n_paint_threads: n_paint_threads, @@ -336,7 +318,6 @@ pub fn from_cmdline_args(args: &[String]) -> bool { enable_text_antialiasing: !debug_options.contains(&"disable-text-aa"), dump_flow_tree: debug_options.contains(&"dump-flow-tree"), validate_display_list_geometry: debug_options.contains(&"validate-display-list-geometry"), - render_api: render_api, resources_path: opt_match.opt_str("resources-path"), }; diff --git a/components/util/persistent_list.rs b/components/util/persistent_list.rs index 458c4c96a2a..f20edff3d38 100644 --- a/components/util/persistent_list.rs +++ b/components/util/persistent_list.rs @@ -74,7 +74,9 @@ pub struct PersistentListIterator<'a,T> where T: 'a + Send + Sync { entry: Option<&'a PersistentListEntry<T>>, } -impl<'a,T> Iterator<&'a T> for PersistentListIterator<'a,T> where T: Send + Sync { +impl<'a,T> Iterator for PersistentListIterator<'a,T> where T: Send + Sync { + type Item = &'a T; + #[inline] fn next(&mut self) -> Option<&'a T> { let entry = match self.entry { diff --git a/components/util/range.rs b/components/util/range.rs index ef6e7e0ff47..fbf14f38400 100644 --- a/components/util/range.rs +++ b/components/util/range.rs @@ -26,7 +26,7 @@ impl RangeIndex<int> for int { #[macro_export] macro_rules! int_range_index { ($(#[$attr:meta])* struct $Self:ident($T:ty)) => ( - #[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Show, Copy)] + #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Show, Copy)] $(#[$attr])* pub struct $Self(pub $T); @@ -74,40 +74,42 @@ macro_rules! int_range_index { } } - impl Add<$Self, $Self> for $Self { + impl Add<$Self> for $Self { + type Output = $Self; + #[inline] - fn add(&self, other: &$Self) -> $Self { + fn add(self, other: $Self) -> $Self { $Self(self.get() + other.get()) } } - impl Sub<$Self, $Self> for $Self { + impl Sub<$Self> for $Self { + type Output = $Self; + #[inline] - fn sub(&self, other: &$Self) -> $Self { + fn sub(self, other: $Self) -> $Self { $Self(self.get() - other.get()) } } - impl Mul<$Self, $Self> for $Self { + impl Mul<$Self> for $Self { + type Output = $Self; + #[inline] - fn mul(&self, other: &$Self) -> $Self { + fn mul(self, other: $Self) -> $Self { $Self(self.get() * other.get()) } } - impl Neg<$Self> for $Self { + impl Neg for $Self { + type Output = $Self; + #[inline] - fn neg(&self) -> $Self { + fn neg(self) -> $Self { $Self(-self.get()) } } - impl ::std::num::One for $Self { - fn one() -> $Self { - $Self(1) - } - } - impl ToPrimitive for $Self { fn to_i64(&self) -> Option<i64> { Some(self.get() as i64) @@ -124,66 +126,75 @@ macro_rules! int_range_index { } } - impl Div<$Self, $Self> for $Self { - fn div(&self, other: &$Self) -> $Self { + impl Div<$Self> for $Self { + type Output = $Self; + fn div(self, other: $Self) -> $Self { $Self(self.get() / other.get()) } } - impl Rem<$Self, $Self> for $Self { - fn rem(&self, other: &$Self) -> $Self { + impl Rem<$Self> for $Self { + type Output = $Self; + fn rem(self, other: $Self) -> $Self { $Self(self.get() % other.get()) } } - impl Not<$Self> for $Self { - fn not(&self) -> $Self { + impl Not for $Self { + type Output = $Self; + fn not(self) -> $Self { $Self(!self.get()) } } - impl BitAnd<$Self, $Self> for $Self { - fn bitand(&self, other: &$Self) -> $Self { + impl BitAnd<$Self> for $Self { + type Output = $Self; + fn bitand(self, other: $Self) -> $Self { $Self(self.get() & other.get()) } } - impl BitOr<$Self, $Self> for $Self { - fn bitor(&self, other: &$Self) -> $Self { + impl BitOr<$Self> for $Self { + type Output = $Self; + fn bitor(self, other: $Self) -> $Self { $Self(self.get() | other.get()) } } - impl BitXor<$Self, $Self> for $Self { - fn bitxor(&self, other: &$Self) -> $Self { + impl BitXor<$Self> for $Self { + type Output = $Self; + fn bitxor(self, other: $Self) -> $Self { $Self(self.get() ^ other.get()) } } - impl Shl<uint, $Self> for $Self { - fn shl(&self, n: &uint) -> $Self { - $Self(self.get() << *n) + impl Shl<uint> for $Self { + type Output = $Self; + fn shl(self, n: uint) -> $Self { + $Self(self.get() << n) } } - impl Shr<uint, $Self> for $Self { - fn shr(&self, n: &uint) -> $Self { - $Self(self.get() >> *n) + impl Shr<uint> for $Self { + type Output = $Self; + fn shr(self, n: uint) -> $Self { + $Self(self.get() >> n) } } ) } /// A range of indices -#[deriving(Clone, Encodable, Copy)] +#[derive(Clone, RustcEncodable, Copy)] pub struct Range<I> { begin: I, length: I, } +#[old_impl_check] impl<I: RangeIndex<T>, T> fmt::Show for Range<I> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "[{} .. {})", self.begin(), self.end()) + write!(f, "[{:?} .. {:?})", self.begin(), self.end()) } } @@ -196,7 +207,9 @@ pub fn each_index<T: Int, I: RangeIndex<T>>(start: I, stop: I) -> EachIndex<T, I EachIndex { it: iter::range(start.get(), stop.get()) } } -impl<T: Int, I: RangeIndex<T>> Iterator<I> for EachIndex<T, I> { +impl<T: Int, I: RangeIndex<T>> Iterator for EachIndex<T, I> { + type Item = I; + #[inline] fn next(&mut self) -> Option<I> { self.it.next().map(|i| RangeIndex::new(i)) @@ -208,6 +221,7 @@ impl<T: Int, I: RangeIndex<T>> Iterator<I> for EachIndex<T, I> { } } +#[old_impl_check] impl<I: RangeIndex<T>, T> Range<I> { /// Create a new range from beginning and length offsets. This could be /// denoted as `[begin, begin + length)`. @@ -345,6 +359,7 @@ impl<I: RangeIndex<T>, T> Range<I> { } /// Methods for `Range`s with indices based on integer values +#[old_impl_check] impl<T: Int, I: RangeIndex<T>> Range<I> { /// Returns an iterater that increments over `[begin, end)`. #[inline] @@ -363,8 +378,9 @@ impl<T: Int, I: RangeIndex<T>> Range<I> { && self.length() <= len }, None => { - debug!("Range<T>::is_valid_for_string: string length (len={}) is longer than the \ - max value for the range index (max={})", s_len, + debug!("Range<T>::is_valid_for_string: string length \ + (len={:?}) is longer than the max value for the range \ + index (max={:?})", s_len, { let max: T = Int::max_value(); let val: I = RangeIndex::new(max); diff --git a/components/util/rtinstrument.rs b/components/util/rtinstrument.rs deleted file mode 100644 index ea9a5ecef32..00000000000 --- a/components/util/rtinstrument.rs +++ /dev/null @@ -1,197 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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 opts; -use std::any::Any; -#[cfg(not(test))] -use std::io::File; -//use std::mem; -//use std::raw; -use std::rt::Runtime; -use std::rt::local::Local; -//use std::rt::rtio; -use std::rt::task::{Task, TaskOpts, BlockedTask}; -use std_time; -use std::sync::Mutex; -#[cfg(not(test))] -use serialize::json; - -#[deriving(Encodable)] -pub enum Event { - Spawn, - Schedule, - Unschedule, - Death, -} - -#[deriving(Encodable)] -pub struct Message { - timestamp: u64, - event: Event, -} - -#[deriving(Encodable)] -pub struct TaskStats { - pub name: String, - pub messages: Vec<Message>, - pub task_id: uint, -} - -struct InstrumentedRuntime { - inner: Option<Box<Runtime + Send>>, - messages: Vec<Message>, -} - -#[deriving(Encodable)] -pub struct GlobalState { - task_stats: Vec<TaskStats>, -} - -#[cfg(not(test))] -pub fn teardown() { - if opts::get().profile_tasks { - let state = GLOBAL_STATE.lock(); - let result = json::encode(&*state); - let path = Path::new("thread_trace.json"); - let mut file = File::create(&path).unwrap(); - file.write_str(result.as_slice()).unwrap(); - } -} - -impl GlobalState { - fn new() -> GlobalState { - GlobalState { - task_stats: vec!(), - } - } -} - -lazy_static! { - pub static ref GLOBAL_STATE: Mutex<GlobalState> = Mutex::new(GlobalState::new()); -} - -/// Instrument all code run inside the specific block, returning a vector of all -/// messages which occurred. -pub fn instrument(f: proc()) { - if opts::get().profile_tasks { - install(); - f(); - let rt = uninstall(); - let task_id = rt.task_id(); - let name = { - let task = Local::borrow(None::<Task>); - match task.name { - Some(ref name) => name.to_string(), - None => "unknown".into_string(), - } - }; - let stats = TaskStats { - name: name, - messages: rt.messages, - task_id: task_id, - }; - let mut state = GLOBAL_STATE.lock(); - state.task_stats.push(stats); - } else { - f(); - } -} - -/// Installs an instrumented runtime which will append to the given vector of -/// messages. -/// -/// The instrumented runtime is installed into the current task. -fn install() { - let mut task = Local::borrow(None::<Task>); - let rt = task.take_runtime(); - let mut new_rt = box InstrumentedRuntime { - inner: Some(rt), - messages: vec!(), - }; - new_rt.log(Event::Spawn); - task.put_runtime(new_rt); -} - -/// Uninstalls the runtime from the current task, returning the instrumented -/// runtime. -fn uninstall() -> InstrumentedRuntime { - let mut task = Local::borrow(None::<Task>); - let mut rt = task.maybe_take_runtime::<InstrumentedRuntime>().unwrap(); - rt.log(Event::Death); - task.put_runtime(rt.inner.take().unwrap()); - *rt -} - -impl InstrumentedRuntime { - /// Puts this runtime back into the local task - fn put(mut self: Box<InstrumentedRuntime>, event: Option<Event>) { - assert!(self.inner.is_none()); - - let mut task: Box<Task> = Local::take(); - let rt = task.take_runtime(); - self.inner = Some(rt); - match event { - Some(event) => self.log(event), - None => {} - } - task.put_runtime(self); - Local::put(task); - } - - /// Logs a message into this runtime - fn log(&mut self, event: Event) { - self.messages.push(Message { - timestamp: std_time::precise_time_ns(), - event: event, - }); - } - - fn task_id(&self) -> uint { self as *const _ as uint } -} - -impl Runtime for InstrumentedRuntime { - fn stack_guard(&self) -> Option<uint> { - self.inner.as_ref().unwrap().stack_guard() - } - - fn yield_now(mut self: Box<InstrumentedRuntime>, cur_task: Box<Task>) { - self.inner.take().unwrap().yield_now(cur_task); - self.put(None) - } - - fn maybe_yield(mut self: Box<InstrumentedRuntime>, cur_task: Box<Task>) { - self.inner.take().unwrap().maybe_yield(cur_task); - self.put(None) - } - - fn deschedule(mut self: Box<InstrumentedRuntime>, times: uint, cur_task: Box<Task>, - f: |BlockedTask| -> Result<(), BlockedTask>) { - self.log(Event::Unschedule); - self.inner.take().unwrap().deschedule(times, cur_task, f); - self.put(Some(Event::Schedule)); - } - - fn reawaken(mut self: Box<InstrumentedRuntime>, to_wake: Box<Task>) { - self.inner.take().unwrap().reawaken(to_wake); - self.put(None); - } - - fn spawn_sibling(mut self: Box<InstrumentedRuntime>, - cur_task: Box<Task>, - opts: TaskOpts, - f: proc():Send) { - // Be sure to install an instrumented runtime for the spawned sibling by - // specifying a new runtime. - self.inner.take().unwrap().spawn_sibling(cur_task, opts, proc() { - install(); - f(); - drop(uninstall()); - }); - self.put(None) - } - - fn stack_bounds(&self) -> (uint, uint) { self.inner.as_ref().unwrap().stack_bounds() } - fn can_block(&self) -> bool { self.inner.as_ref().unwrap().can_block() } - fn wrap(self: Box<InstrumentedRuntime>) -> Box<Any+'static> { self as Box<Any> } -} diff --git a/components/util/smallvec.rs b/components/util/smallvec.rs index e92d3d3eeba..efd1bfc7f35 100644 --- a/components/util/smallvec.rs +++ b/components/util/smallvec.rs @@ -9,7 +9,8 @@ use std::mem::zeroed as i; use std::cmp; use std::fmt; use std::intrinsics; -use std::kinds::marker::ContravariantLifetime; +use std::iter::FromIterator; +use std::marker::ContravariantLifetime; use std::mem; use std::ptr; use std::raw::Slice; @@ -249,7 +250,9 @@ pub struct SmallVecIterator<'a,T> { lifetime: ContravariantLifetime<'a> } -impl<'a,T> Iterator<&'a T> for SmallVecIterator<'a,T> { +impl<'a,T> Iterator for SmallVecIterator<'a,T> { + type Item = &'a T; + #[inline] fn next(&mut self) -> Option<&'a T> { unsafe { @@ -273,7 +276,9 @@ pub struct SmallVecMutIterator<'a,T> { lifetime: ContravariantLifetime<'a>, } -impl<'a,T> Iterator<&'a mut T> for SmallVecMutIterator<'a,T> { +impl<'a,T> Iterator for SmallVecMutIterator<'a,T> { + type Item = &'a mut T; + #[inline] fn next(&mut self) -> Option<&'a mut T> { unsafe { @@ -298,7 +303,9 @@ pub struct SmallVecMoveIterator<'a,T> { lifetime: ContravariantLifetime<'a>, } -impl<'a, T: 'a> Iterator<T> for SmallVecMoveIterator<'a,T> { +impl<'a, T: 'a> Iterator for SmallVecMoveIterator<'a,T> { + type Item = T; + #[inline] fn next(&mut self) -> Option<T> { unsafe { @@ -341,7 +348,7 @@ macro_rules! def_small_vector( len: uint, cap: uint, ptr: *const T, - data: [T, ..$size], + data: [T; $size], } impl<T> SmallVecPrivate<T> for $name<T> { @@ -403,7 +410,7 @@ macro_rules! def_small_vector( } impl<T> FromIterator<T> for $name<T> { - fn from_iter<I: Iterator<T>>(mut iter: I) -> $name<T> { + fn from_iter<I: Iterator<Item=T>>(mut iter: I) -> $name<T> { let mut v = $name::new(); let (lower_size_bound, _) = iter.size_hint(); @@ -421,7 +428,7 @@ macro_rules! def_small_vector( } impl<T> $name<T> { - pub fn extend<I: Iterator<T>>(&mut self, mut iter: I) { + pub fn extend<I: Iterator<Item=T>>(&mut self, mut iter: I) { let (lower_size_bound, _) = iter.size_hint(); let target_len = self.len() + lower_size_bound; @@ -438,7 +445,7 @@ macro_rules! def_small_vector( impl<T: fmt::Show> fmt::Show for $name<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.as_slice()) + write!(f, "{:?}", self.as_slice()) } } @@ -456,15 +463,15 @@ macro_rules! def_small_vector( } } ) -) +); -def_small_vector!(SmallVec1, 1) -def_small_vector!(SmallVec2, 2) -def_small_vector!(SmallVec4, 4) -def_small_vector!(SmallVec8, 8) -def_small_vector!(SmallVec16, 16) -def_small_vector!(SmallVec24, 24) -def_small_vector!(SmallVec32, 32) +def_small_vector!(SmallVec1, 1); +def_small_vector!(SmallVec2, 2); +def_small_vector!(SmallVec4, 4); +def_small_vector!(SmallVec8, 8); +def_small_vector!(SmallVec16, 16); +def_small_vector!(SmallVec24, 24); +def_small_vector!(SmallVec32, 32); macro_rules! def_small_vector_drop_impl( ($name:ident, $size:expr) => ( @@ -488,15 +495,15 @@ macro_rules! def_small_vector_drop_impl( } } ) -) +); -def_small_vector_drop_impl!(SmallVec1, 1) -def_small_vector_drop_impl!(SmallVec2, 2) -def_small_vector_drop_impl!(SmallVec4, 4) -def_small_vector_drop_impl!(SmallVec8, 8) -def_small_vector_drop_impl!(SmallVec16, 16) -def_small_vector_drop_impl!(SmallVec24, 24) -def_small_vector_drop_impl!(SmallVec32, 32) +def_small_vector_drop_impl!(SmallVec1, 1); +def_small_vector_drop_impl!(SmallVec2, 2); +def_small_vector_drop_impl!(SmallVec4, 4); +def_small_vector_drop_impl!(SmallVec8, 8); +def_small_vector_drop_impl!(SmallVec16, 16); +def_small_vector_drop_impl!(SmallVec24, 24); +def_small_vector_drop_impl!(SmallVec32, 32); macro_rules! def_small_vector_clone_impl( ($name:ident) => ( @@ -510,68 +517,69 @@ macro_rules! def_small_vector_clone_impl( } } ) -) +); -def_small_vector_clone_impl!(SmallVec1) -def_small_vector_clone_impl!(SmallVec2) -def_small_vector_clone_impl!(SmallVec4) -def_small_vector_clone_impl!(SmallVec8) -def_small_vector_clone_impl!(SmallVec16) -def_small_vector_clone_impl!(SmallVec24) -def_small_vector_clone_impl!(SmallVec32) +def_small_vector_clone_impl!(SmallVec1); +def_small_vector_clone_impl!(SmallVec2); +def_small_vector_clone_impl!(SmallVec4); +def_small_vector_clone_impl!(SmallVec8); +def_small_vector_clone_impl!(SmallVec16); +def_small_vector_clone_impl!(SmallVec24); +def_small_vector_clone_impl!(SmallVec32); #[cfg(test)] pub mod tests { use smallvec::{SmallVec, SmallVec2, SmallVec16}; + use std::borrow::ToOwned; // We heap allocate all these strings so that double frees will show up under valgrind. #[test] pub fn test_inline() { let mut v = SmallVec16::new(); - v.push("hello".into_string()); - v.push("there".into_string()); + v.push("hello".to_owned()); + v.push("there".to_owned()); assert_eq!(v.as_slice(), vec![ - "hello".into_string(), - "there".into_string(), + "hello".to_owned(), + "there".to_owned(), ].as_slice()); } #[test] pub fn test_spill() { let mut v = SmallVec2::new(); - v.push("hello".into_string()); - v.push("there".into_string()); - v.push("burma".into_string()); - v.push("shave".into_string()); + v.push("hello".to_owned()); + v.push("there".to_owned()); + v.push("burma".to_owned()); + v.push("shave".to_owned()); assert_eq!(v.as_slice(), vec![ - "hello".into_string(), - "there".into_string(), - "burma".into_string(), - "shave".into_string(), + "hello".to_owned(), + "there".to_owned(), + "burma".to_owned(), + "shave".to_owned(), ].as_slice()); } #[test] pub fn test_double_spill() { let mut v = SmallVec2::new(); - v.push("hello".into_string()); - v.push("there".into_string()); - v.push("burma".into_string()); - v.push("shave".into_string()); - v.push("hello".into_string()); - v.push("there".into_string()); - v.push("burma".into_string()); - v.push("shave".into_string()); + v.push("hello".to_owned()); + v.push("there".to_owned()); + v.push("burma".to_owned()); + v.push("shave".to_owned()); + v.push("hello".to_owned()); + v.push("there".to_owned()); + v.push("burma".to_owned()); + v.push("shave".to_owned()); assert_eq!(v.as_slice(), vec![ - "hello".into_string(), - "there".into_string(), - "burma".into_string(), - "shave".into_string(), - "hello".into_string(), - "there".into_string(), - "burma".into_string(), - "shave".into_string(), + "hello".to_owned(), + "there".to_owned(), + "burma".to_owned(), + "shave".to_owned(), + "hello".to_owned(), + "there".to_owned(), + "burma".to_owned(), + "shave".to_owned(), ].as_slice()); } } diff --git a/components/util/sort.rs b/components/util/sort.rs index 73a244f713f..ce7ab4d86c9 100644 --- a/components/util/sort.rs +++ b/components/util/sort.rs @@ -4,6 +4,8 @@ //! In-place sorting. +use std::cmp::Ordering; + fn quicksort_helper<T>(arr: &mut [T], left: int, right: int, compare: fn(&T, &T) -> Ordering) { if right <= left { return @@ -17,11 +19,11 @@ fn quicksort_helper<T>(arr: &mut [T], left: int, right: int, compare: fn(&T, &T) let v: *mut T = &mut arr[right as uint]; loop { i += 1; - while compare(&arr[i as uint], &*v) == Less { + while compare(&arr[i as uint], &*v) == Ordering::Less { i += 1 } j -= 1; - while compare(&*v, &arr[j as uint]) == Less { + while compare(&*v, &arr[j as uint]) == Ordering::Less { if j == left { break } @@ -31,11 +33,11 @@ fn quicksort_helper<T>(arr: &mut [T], left: int, right: int, compare: fn(&T, &T) break } arr.swap(i as uint, j as uint); - if compare(&arr[i as uint], &*v) == Equal { + if compare(&arr[i as uint], &*v) == Ordering::Equal { p += 1; arr.swap(p as uint, i as uint) } - if compare(&*v, &arr[j as uint]) == Equal { + if compare(&*v, &arr[j as uint]) == Ordering::Equal { q -= 1; arr.swap(j as uint, q as uint) } @@ -79,6 +81,7 @@ pub fn quicksort_by<T>(arr: &mut [T], compare: fn(&T, &T) -> Ordering) { #[cfg(test)] pub mod test { + use std::cmp::Ordering; use std::rand; use std::rand::Rng; @@ -86,7 +89,7 @@ pub mod test { #[test] pub fn random() { - let mut rng = rand::task_rng(); + let mut rng = rand::thread_rng(); for _ in range(0u32, 50000u32) { let len: uint = rng.gen(); let mut v: Vec<int> = rng.gen_iter::<int>().take((len % 32) + 1).collect(); diff --git a/components/util/str.rs b/components/util/str.rs index 4cf5a5cc3f4..e0642abdffe 100644 --- a/components/util/str.rs +++ b/components/util/str.rs @@ -4,23 +4,26 @@ use geometry::Au; -use cssparser::{mod, RGBA, Color}; +use cssparser::{self, RGBA, Color}; + +use libc::c_char; use std::ascii::AsciiExt; +use std::borrow::ToOwned; +use std::ffi::c_str_to_bytes; use std::iter::Filter; -use std::num::Int; -use std::str::{CharEq, CharSplits, FromStr}; -use unicode::char::UnicodeChar; +use std::num::{Int, ToPrimitive}; +use std::str::{from_utf8, CharEq, FromStr, Split}; pub type DOMString = String; pub type StaticCharVec = &'static [char]; pub type StaticStringVec = &'static [&'static str]; pub fn null_str_as_empty(s: &Option<DOMString>) -> DOMString { - // We don't use map_default because it would allocate "".into_string() even + // We don't use map_default because it would allocate "".to_owned() even // for Some. match *s { Some(ref s) => s.clone(), - None => "".into_string() + None => "".to_owned() } } @@ -64,15 +67,16 @@ pub static HTML_SPACE_CHARACTERS: StaticCharVec = &[ '\u{000d}', ]; -pub fn split_html_space_chars<'a>(s: &'a str) - -> Filter<'a, &'a str, CharSplits<'a, StaticCharVec>> { - s.split(HTML_SPACE_CHARACTERS).filter(|&split| !split.is_empty()) +pub fn split_html_space_chars<'a>(s: &'a str) -> + Filter<&'a str, Split<'a, StaticCharVec>, fn(&&str) -> bool> { + fn not_empty(&split: &&str) -> bool { !split.is_empty() } + s.split(HTML_SPACE_CHARACTERS).filter(not_empty as fn(&&str) -> bool) } /// Shared implementation to parse an integer according to /// <http://www.whatwg.org/html/#rules-for-parsing-integers> or /// <http://www.whatwg.org/html/#rules-for-parsing-non-negative-integers>. -fn do_parse_integer<T: Iterator<char>>(input: T) -> Option<i64> { +fn do_parse_integer<T: Iterator<Item=char>>(input: T) -> Option<i64> { fn is_ascii_digit(c: &char) -> bool { match *c { '0'...'9' => true, @@ -117,7 +121,7 @@ fn do_parse_integer<T: Iterator<char>>(input: T) -> Option<i64> { /// Parse an integer according to /// <http://www.whatwg.org/html/#rules-for-parsing-integers>. -pub fn parse_integer<T: Iterator<char>>(input: T) -> Option<i32> { +pub fn parse_integer<T: Iterator<Item=char>>(input: T) -> Option<i32> { do_parse_integer(input).and_then(|result| { result.to_i32() }) @@ -125,13 +129,13 @@ pub fn parse_integer<T: Iterator<char>>(input: T) -> Option<i32> { /// Parse an integer according to /// <http://www.whatwg.org/html/#rules-for-parsing-non-negative-integers>. -pub fn parse_unsigned_integer<T: Iterator<char>>(input: T) -> Option<u32> { +pub fn parse_unsigned_integer<T: Iterator<Item=char>>(input: T) -> Option<u32> { do_parse_integer(input).and_then(|result| { result.to_u32() }) } -#[deriving(Copy)] +#[derive(Copy)] pub enum LengthOrPercentageOrAuto { Auto, Percentage(f64), @@ -140,14 +144,14 @@ pub enum LengthOrPercentageOrAuto { /// Parses a length per HTML5 § 2.4.4.4. If unparseable, `Auto` is returned. pub fn parse_length(mut value: &str) -> LengthOrPercentageOrAuto { - value = value.trim_left_chars(Whitespace); + value = value.trim_left_matches(Whitespace); if value.len() == 0 { return LengthOrPercentageOrAuto::Auto } if value.starts_with("+") { value = value.slice_from(1) } - value = value.trim_left_chars('0'); + value = value.trim_left_matches('0'); if value.len() == 0 { return LengthOrPercentageOrAuto::Auto } @@ -196,7 +200,7 @@ pub fn parse_legacy_color(mut input: &str) -> Result<RGBA,()> { } // Step 3. - input = input.trim_left_chars(Whitespace).trim_right_chars(Whitespace); + input = input.trim_left_matches(Whitespace).trim_right_matches(Whitespace); // Step 4. if input.eq_ignore_ascii_case("transparent") { @@ -320,7 +324,7 @@ pub fn parse_legacy_color(mut input: &str) -> Result<RGBA,()> { } -#[deriving(Clone, Eq, PartialEq, Hash, Show)] +#[derive(Clone, Eq, PartialEq, Hash, Show)] pub struct LowercaseString { inner: String, } @@ -339,3 +343,9 @@ impl Str for LowercaseString { self.inner.as_slice() } } + +/// Creates a String from the given null-terminated buffer. +/// Panics if the buffer does not contain UTF-8. +pub unsafe fn c_str_to_string(s: *const c_char) -> String { + from_utf8(c_str_to_bytes(&s)).unwrap().to_owned() +} diff --git a/components/util/task.rs b/components/util/task.rs index 2d07be08da3..2045d0c3e83 100644 --- a/components/util/task.rs +++ b/components/util/task.rs @@ -2,44 +2,50 @@ * 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 std::task; -use std::comm::Sender; -use std::task::TaskBuilder; -// use rtinstrument; +use std::borrow::ToOwned; use task_state; +use std::thread; +use std::sync::mpsc::Sender; +use std::thread::Builder; -pub fn spawn_named<S: IntoCow<'static, String, str>>(name: S, f: proc():Send) { - let builder = task::TaskBuilder::new().named(name); - builder.spawn(proc() { - // rtinstrument::instrument(f); - f(); +pub fn spawn_named<F>(name: String, f: F) + where F: FnOnce() + Send +{ + let builder = thread::Builder::new().name(name); + builder.spawn(move || { + f() }); } /// Arrange to send a particular message to a channel if the task fails. -pub fn spawn_named_with_send_on_failure<T: Send>(name: &'static str, - state: task_state::TaskState, - f: proc(): Send, - msg: T, - dest: Sender<T>) { - let future_result = TaskBuilder::new().named(name).try_future(proc() { +pub fn spawn_named_with_send_on_failure<F, T>(name: &'static str, + state: task_state::TaskState, + f: F, + msg: T, + dest: Sender<T>) + where F: FnOnce() + Send, + T: Send +{ + let future_handle = thread::Builder::new().name(name.to_owned()).scoped(move || { task_state::initialize(state); - // FIXME: Find replacement for this post-runtime removal - // rtinstrument::instrument(f); - f(); + f() }); - let watched_name = name.into_string(); - let watcher_name = format!("{}Watcher", watched_name); - TaskBuilder::new().named(watcher_name).spawn(proc() { - //rtinstrument::instrument(proc() { - match future_result.into_inner() { - Ok(()) => (), - Err(..) => { - debug!("{} failed, notifying constellation", name); - dest.send(msg); - } + let watcher_name = format!("{}Watcher", name); + Builder::new().name(watcher_name).spawn(move || { + match future_handle.join() { + Ok(()) => (), + Err(..) => { + debug!("{} failed, notifying constellation", name); + dest.send(msg); } - //}); + } + }); +} + +#[test] +fn spawn_named_test() { + spawn_named("Test".to_owned(), move || { + debug!("I can run!"); }); } diff --git a/components/util/task_state.rs b/components/util/task_state.rs index 3915eeb3059..ef1dbb2ed3e 100644 --- a/components/util/task_state.rs +++ b/components/util/task_state.rs @@ -11,7 +11,7 @@ pub use self::imp::{initialize, get, enter, exit}; bitflags! { - #[deriving(Show, Copy)] + #[derive(Show)] flags TaskState: u32 { const SCRIPT = 0x01, const LAYOUT = 0x02, @@ -35,7 +35,7 @@ macro_rules! task_types ( ( $( $fun:ident = $flag:ident ; )* ) => ( #[cfg(not(ndebug))] static TYPES: &'static [TaskState] = &[ $( $flag ),* ]; -)) +)); task_types! { is_script = SCRIPT; @@ -48,12 +48,12 @@ mod imp { use super::{TaskState, TYPES}; use std::cell::RefCell; - thread_local!(static STATE: RefCell<Option<TaskState>> = RefCell::new(None)) + thread_local!(static STATE: RefCell<Option<TaskState>> = RefCell::new(None)); pub fn initialize(x: TaskState) { STATE.with(|ref k| { match *k.borrow() { - Some(s) => panic!("Task state already initialized as {}", s), + Some(s) => panic!("Task state already initialized as {:?}", s), None => () }; *k.borrow_mut() = Some(x); diff --git a/components/util/taskpool.rs b/components/util/taskpool.rs index 8521ef9dc93..7f2d36be936 100644 --- a/components/util/taskpool.rs +++ b/components/util/taskpool.rs @@ -17,9 +17,11 @@ use task::spawn_named; use std::sync::{Arc, Mutex}; +use std::sync::mpsc::{channel, Sender, Receiver}; +use std::thunk::Thunk; pub struct TaskPool { - tx: Sender<proc():Send>, + tx: Sender<Thunk<()>>, } impl TaskPool { @@ -33,23 +35,25 @@ impl TaskPool { let state = state.clone(); spawn_named( format!("TaskPoolWorker {}/{}", i+1, tasks), - proc() worker(&*state)); + move || worker(&*state)); } return TaskPool { tx: tx }; - fn worker(rx: &Mutex<Receiver<proc():Send>>) { + fn worker(rx: &Mutex<Receiver<Thunk<()>>>) { loop { - let job = rx.lock().recv_opt(); + let job = rx.lock().unwrap().recv(); match job { - Ok(job) => job(), + Ok(job) => job.invoke(()), Err(..) => break, } } } } - pub fn execute(&self, job: proc():Send) { - self.tx.send(job); + pub fn execute<F>(&self, job: F) + where F: FnOnce() + Send + { + self.tx.send(Thunk::new(job)); } } diff --git a/components/util/tid.rs b/components/util/tid.rs index 5cea4fe0d43..e52dbf7fd61 100644 --- a/components/util/tid.rs +++ b/components/util/tid.rs @@ -2,20 +2,20 @@ * 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 std::sync::atomic::{AtomicUint, INIT_ATOMIC_UINT, SeqCst}; +use std::sync::atomic::{AtomicUint, ATOMIC_UINT_INIT, Ordering}; use std::rc::Rc; use std::cell::RefCell; -static mut next_tid: AtomicUint = INIT_ATOMIC_UINT; +static mut next_tid: AtomicUint = ATOMIC_UINT_INIT; -thread_local!(static TASK_LOCAL_TID: Rc<RefCell<Option<uint>>> = Rc::new(RefCell::new(None))) +thread_local!(static TASK_LOCAL_TID: Rc<RefCell<Option<uint>>> = Rc::new(RefCell::new(None))); /// Every task gets one, that's unique. pub fn tid() -> uint { TASK_LOCAL_TID.with(|ref k| { let ret = match *k.borrow() { - None => unsafe { next_tid.fetch_add(1, SeqCst) }, + None => unsafe { next_tid.fetch_add(1, Ordering::SeqCst) }, Some(x) => x, }; diff --git a/components/util/time.rs b/components/util/time.rs index 96d037c520a..b5805dfa092 100644 --- a/components/util/time.rs +++ b/components/util/time.rs @@ -4,19 +4,21 @@ //! Timing functions. -use collections::TreeMap; -use std::comm::{Sender, channel, Receiver}; +use collections::BTreeMap; +use std::borrow::ToOwned; +use std::cmp::Ordering; use std::f64; use std::io::timer::sleep; use std::iter::AdditiveIterator; -use std::num::FloatMath; +use std::num::Float; +use std::sync::mpsc::{Sender, channel, Receiver}; use std::time::duration::Duration; use std_time::precise_time_ns; use task::{spawn_named}; use url::Url; // front-end representation of the profiler used to communicate with the profiler -#[deriving(Clone)] +#[derive(Clone)] pub struct TimeProfilerChan(pub Sender<TimeProfilerMsg>); impl TimeProfilerChan { @@ -26,7 +28,7 @@ impl TimeProfilerChan { } } -#[deriving(PartialEq, Clone, PartialOrd, Eq, Ord)] +#[derive(PartialEq, Clone, PartialOrd, Eq, Ord)] pub struct TimerMetadata { url: String, iframe: bool, @@ -58,7 +60,7 @@ impl Formatable for Option<TimerMetadata> { } } -#[deriving(Clone)] +#[derive(Clone)] pub enum TimeProfilerMsg { /// Normal message used for reporting time Time((TimeProfilerCategory, Option<TimerMetadata>), f64), @@ -69,7 +71,7 @@ pub enum TimeProfilerMsg { } #[repr(u32)] -#[deriving(PartialEq, Clone, PartialOrd, Eq, Ord)] +#[derive(PartialEq, Clone, PartialOrd, Eq, Ord)] pub enum TimeProfilerCategory { Compositing, LayoutPerform, @@ -128,7 +130,7 @@ impl Formatable for TimeProfilerCategory { } } -type TimeProfilerBuckets = TreeMap<(TimeProfilerCategory, Option<TimerMetadata>), Vec<f64>>; +type TimeProfilerBuckets = BTreeMap<(TimeProfilerCategory, Option<TimerMetadata>), Vec<f64>>; // back end of the profiler that handles data aggregation and performance metrics pub struct TimeProfiler { @@ -144,25 +146,25 @@ impl TimeProfiler { Some(period) => { let period = Duration::milliseconds((period * 1000f64) as i64); let chan = chan.clone(); - spawn_named("Time profiler timer", proc() { + spawn_named("Time profiler timer".to_owned(), move || { loop { sleep(period); - if chan.send_opt(TimeProfilerMsg::Print).is_err() { + if chan.send(TimeProfilerMsg::Print).is_err() { break; } } }); // Spawn the time profiler. - spawn_named("Time profiler", proc() { + spawn_named("Time profiler".to_owned(), move || { let mut profiler = TimeProfiler::new(port); profiler.start(); }); } None => { // No-op to handle messages when the time profiler is inactive. - spawn_named("Time profiler", proc() { + spawn_named("Time profiler".to_owned(), move || { loop { - match port.recv_opt() { + match port.recv() { Err(_) | Ok(TimeProfilerMsg::Exit) => break, _ => {} } @@ -177,14 +179,14 @@ impl TimeProfiler { pub fn new(port: Receiver<TimeProfilerMsg>) -> TimeProfiler { TimeProfiler { port: port, - buckets: TreeMap::new(), + buckets: BTreeMap::new(), last_msg: None, } } pub fn start(&mut self) { loop { - let msg = self.port.recv_opt(); + let msg = self.port.recv(); match msg { Ok(msg) => { if !self.handle_msg(msg) { @@ -227,9 +229,9 @@ impl TimeProfiler { for (&(ref category, ref meta), ref mut data) in self.buckets.iter_mut() { data.sort_by(|a, b| { if a < b { - Less + Ordering::Less } else { - Greater + Ordering::Greater } }); let data_len = data.len(); @@ -247,13 +249,13 @@ impl TimeProfiler { } } -#[deriving(Eq, PartialEq)] +#[derive(Eq, PartialEq)] pub enum TimerMetadataFrameType { RootWindow, IFrame, } -#[deriving(Eq, PartialEq)] +#[derive(Eq, PartialEq)] pub enum TimerMetadataReflowType { Incremental, FirstReflow, @@ -261,11 +263,13 @@ pub enum TimerMetadataReflowType { pub type ProfilerMetadata<'a> = Option<(&'a Url, TimerMetadataFrameType, TimerMetadataReflowType)>; -pub fn profile<T>(category: TimeProfilerCategory, - meta: ProfilerMetadata, - time_profiler_chan: TimeProfilerChan, - callback: || -> T) - -> T { +pub fn profile<T, F>(category: TimeProfilerCategory, + meta: ProfilerMetadata, + time_profiler_chan: TimeProfilerChan, + callback: F) + -> T + where F: FnOnce() -> T +{ let start_time = precise_time_ns(); let val = callback(); let end_time = precise_time_ns(); @@ -280,7 +284,9 @@ pub fn profile<T>(category: TimeProfilerCategory, return val; } -pub fn time<T>(msg: &str, callback: || -> T) -> T{ +pub fn time<T, F>(msg: &str, callback: F) -> T + where F: Fn() -> T +{ let start_time = precise_time_ns(); let val = callback(); let end_time = precise_time_ns(); diff --git a/components/util/vec.rs b/components/util/vec.rs index b9a67b6760b..a902a3133df 100644 --- a/components/util/vec.rs +++ b/components/util/vec.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use std::cmp::{PartialOrd, PartialEq}; +use std::cmp::{PartialOrd, PartialEq, Ordering}; #[cfg(test)] use std::fmt::Show; @@ -47,9 +47,9 @@ impl<'a, T> FullBinarySearchMethods<T> for &'a [T] { let midv = &self[mid]; match cmp.compare(key, midv) { - Greater => low = (mid as int) + 1, - Less => high = (mid as int) - 1, - Equal => return Some(mid), + Ordering::Greater => low = (mid as int) + 1, + Ordering::Less => high = (mid as int) - 1, + Ordering::Equal => return Some(mid), } } return None; @@ -78,7 +78,7 @@ fn test_miss_all_elems<T: PartialEq + PartialOrd + Eq + Ord + Show>(arr: &[T], m let mut i = 0; while i < misses.len() { let res = arr.binary_search_(&misses[i]); - debug!("{} == {} ?", misses[i], res); + debug!("{:?} == {:?} ?", misses[i], res); assert!(!test_match(&misses[i], arr.binary_search_(&misses[i]))); i += 1; } diff --git a/components/util/workqueue.rs b/components/util/workqueue.rs index 9fef7ac2a81..c83902526fd 100644 --- a/components/util/workqueue.rs +++ b/components/util/workqueue.rs @@ -14,7 +14,8 @@ use libc::funcs::posix88::unistd::usleep; use rand::{Rng, XorShiftRng}; use std::mem; use std::rand::weak_rng; -use std::sync::atomic::{AtomicUint, SeqCst}; +use std::sync::atomic::{AtomicUint, Ordering}; +use std::sync::mpsc::{channel, Sender, Receiver}; use deque::{Abort, BufferPool, Data, Empty, Stealer, Worker}; /// A unit of work. @@ -31,7 +32,7 @@ pub struct WorkUnit<QueueData, WorkData> { } /// Messages from the supervisor to the worker. -enum WorkerMsg<QueueData, WorkData> { +enum WorkerMsg<QueueData: 'static, WorkData: 'static> { /// Tells the worker to start work. Start(Worker<WorkUnit<QueueData, WorkData>>, *mut AtomicUint, *const QueueData), /// Tells the worker to stop. It can be restarted again with a `WorkerMsg::Start`. @@ -40,14 +41,18 @@ enum WorkerMsg<QueueData, WorkData> { Exit, } +unsafe impl<QueueData: 'static, WorkData: 'static> Send for WorkerMsg<QueueData, WorkData> {} + /// Messages to the supervisor. -enum SupervisorMsg<QueueData, WorkData> { +enum SupervisorMsg<QueueData: 'static, WorkData: 'static> { Finished, ReturnDeque(uint, Worker<WorkUnit<QueueData, WorkData>>), } +unsafe impl<QueueData: 'static, WorkData: 'static> Send for SupervisorMsg<QueueData, WorkData> {} + /// Information that the supervisor thread keeps about the worker threads. -struct WorkerInfo<QueueData, WorkData> { +struct WorkerInfo<QueueData: 'static, WorkData: 'static> { /// The communication channel to the workers. chan: Sender<WorkerMsg<QueueData, WorkData>>, /// The worker end of the deque, if we have it. @@ -57,7 +62,7 @@ struct WorkerInfo<QueueData, WorkData> { } /// Information specific to each worker thread that the thread keeps. -struct WorkerThread<QueueData, WorkData> { +struct WorkerThread<QueueData: 'static, WorkData: 'static> { /// The index of this worker. index: uint, /// The communication port from the supervisor. @@ -70,6 +75,8 @@ struct WorkerThread<QueueData, WorkData> { rng: XorShiftRng, } +unsafe impl<QueueData: 'static, WorkData: 'static> Send for WorkerThread<QueueData, WorkData> {} + static SPIN_COUNT: u32 = 128; static SPINS_UNTIL_BACKOFF: u32 = 100; static BACKOFF_INCREMENT_IN_US: u32 = 5; @@ -80,7 +87,7 @@ impl<QueueData: Send, WorkData: Send> WorkerThread<QueueData, WorkData> { fn start(&mut self) { loop { // Wait for a start message. - let (mut deque, ref_count, queue_data) = match self.port.recv() { + let (mut deque, ref_count, queue_data) = match self.port.recv().unwrap() { WorkerMsg::Start(deque, ref_count, queue_data) => (deque, ref_count, queue_data), WorkerMsg::Stop => panic!("unexpected stop message"), WorkerMsg::Exit => return, @@ -157,14 +164,14 @@ impl<QueueData: Send, WorkData: Send> WorkerThread<QueueData, WorkData> { // The work is done. Now decrement the count of outstanding work items. If this was // the last work unit in the queue, then send a message on the channel. unsafe { - if (*ref_count).fetch_sub(1, SeqCst) == 1 { - self.chan.send(SupervisorMsg::Finished) + if (*ref_count).fetch_sub(1, Ordering::SeqCst) == 1 { + self.chan.send(SupervisorMsg::Finished).unwrap() } } } // Give the deque back to the supervisor. - self.chan.send(SupervisorMsg::ReturnDeque(self.index, deque)) + self.chan.send(SupervisorMsg::ReturnDeque(self.index, deque)).unwrap() } } } @@ -181,7 +188,7 @@ impl<'a, QueueData: 'static, WorkData: Send> WorkerProxy<'a, QueueData, WorkData #[inline] pub fn push(&mut self, work_unit: WorkUnit<QueueData, WorkData>) { unsafe { - drop((*self.ref_count).fetch_add(1, SeqCst)); + drop((*self.ref_count).fetch_add(1, Ordering::SeqCst)); } self.worker.push(work_unit); } @@ -196,7 +203,7 @@ impl<'a, QueueData: 'static, WorkData: Send> WorkerProxy<'a, QueueData, WorkData } /// A work queue on which units of work can be submitted. -pub struct WorkQueue<QueueData, WorkData> { +pub struct WorkQueue<QueueData: 'static, WorkData: 'static> { /// Information about each of the workers. workers: Vec<WorkerInfo<QueueData, WorkData>>, /// A port on which deques can be received from the workers. @@ -250,7 +257,7 @@ impl<QueueData: Send, WorkData: Send> WorkQueue<QueueData, WorkData> { spawn_named( format!("{} worker {}/{}", task_name, i+1, thread_count), - proc() { + move || { task_state::initialize(state | task_state::IN_WORKER); let mut thread = thread; thread.start() @@ -283,7 +290,7 @@ impl<QueueData: Send, WorkData: Send> WorkQueue<QueueData, WorkData> { // Tell the workers to start. let mut work_count = AtomicUint::new(self.work_count); for worker in self.workers.iter_mut() { - worker.chan.send(WorkerMsg::Start(worker.deque.take().unwrap(), &mut work_count, &self.data)) + worker.chan.send(WorkerMsg::Start(worker.deque.take().unwrap(), &mut work_count, &self.data)).unwrap() } // Wait for the work to finish. @@ -292,12 +299,12 @@ impl<QueueData: Send, WorkData: Send> WorkQueue<QueueData, WorkData> { // Tell everyone to stop. for worker in self.workers.iter() { - worker.chan.send(WorkerMsg::Stop) + worker.chan.send(WorkerMsg::Stop).unwrap() } // Get our deques back. for _ in range(0, self.workers.len()) { - match self.port.recv() { + match self.port.recv().unwrap() { SupervisorMsg::ReturnDeque(index, deque) => self.workers[index].deque = Some(deque), SupervisorMsg::Finished => panic!("unexpected finished message!"), } @@ -306,7 +313,7 @@ impl<QueueData: Send, WorkData: Send> WorkQueue<QueueData, WorkData> { pub fn shutdown(&mut self) { for worker in self.workers.iter() { - worker.chan.send(WorkerMsg::Exit) + worker.chan.send(WorkerMsg::Exit).unwrap() } } } diff --git a/ports/cef/.cargo/config b/ports/cef/.cargo/config index 92ac197ce5d..8b137891791 100644 --- a/ports/cef/.cargo/config +++ b/ports/cef/.cargo/config @@ -1,7 +1 @@ -# FIXME: Remove this next rustup. This is a temporary -# hack to allow android cross compilation to work. When -# this is removed, the support/time submodule can also -# be removed! -paths = [ - "../../support/time" -] + diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index bbcb25348c0..8a28e365033 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -26,7 +26,7 @@ dependencies = [ [[package]] name = "android_glue" version = "0.0.1" -source = "git+https://github.com/servo/android-rs-glue?ref=servo#122bc28545b5e59a923c466a484c403fa691bd55" +source = "git+https://github.com/tomaka/android-rs-glue#7e930d2822adb791a515c24dfefe6ae37493f40f" dependencies = [ "compile_msg 0.1.3 (git+https://github.com/huonw/compile_msg)", ] @@ -34,7 +34,7 @@ dependencies = [ [[package]] name = "azure" version = "0.1.0" -source = "git+https://github.com/servo/rust-azure#d0acabef6221e5fd6840254dc23f91c66b874629" +source = "git+https://github.com/servo/rust-azure#72deb42903b12dc6f1924fa1757cd79d37b35429" dependencies = [ "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)", @@ -42,7 +42,7 @@ dependencies = [ "egl 0.1.0 (git+https://github.com/servo/rust-egl)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", - "skia-sys 0.0.20130412 (git+https://github.com/servo/skia?ref=upstream-2014-06-16)", + "skia-sys 0.0.20130412 (git+https://github.com/servo/skia?branch=upstream-2014-06-16)", "xlib 0.1.0 (git+https://github.com/servo/rust-xlib)", ] @@ -66,7 +66,7 @@ dependencies = [ [[package]] name = "cocoa" version = "0.1.1" -source = "git+https://github.com/servo/rust-cocoa#bf53a53ce306279fc1cae0d56fdd5e7216696420" +source = "git+https://github.com/servo/rust-cocoa#84a405ba9ff2a79d507dc6ee1ea3cf9bf48706d1" [[package]] name = "compile_msg" @@ -91,25 +91,26 @@ dependencies = [ "net 0.0.1", "png 0.1.0 (git+https://github.com/servo/rust-png)", "script_traits 0.0.1", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "cookie" -version = "0.1.0" -source = "git+https://github.com/alexcrichton/cookie-rs#8d1b4bb8d5ed06e58c162eb235a4ccd210b68108" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "openssl 0.2.4 (git+https://github.com/sfackler/rust-openssl)", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "openssl 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "core_foundation" version = "0.1.0" -source = "git+https://github.com/servo/rust-core-foundation#81db9ab15f67e16d7a3e9705a06cad65192014fd" +source = "git+https://github.com/servo/rust-core-foundation#ce3d852765827b64a0d5fb2aadd77da39665b0b0" [[package]] name = "core_graphics" @@ -122,7 +123,7 @@ dependencies = [ [[package]] name = "core_text" version = "0.1.0" -source = "git+https://github.com/servo/rust-core-text#cb369a26a0eb4e83c2128ceb3c685a191113417a" +source = "git+https://github.com/servo/rust-core-text#b5cb33905350e99b2a19f5a22f7b1efea7ad48c2" dependencies = [ "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)", @@ -130,11 +131,12 @@ dependencies = [ [[package]] name = "cssparser" -version = "0.1.1" -source = "git+https://github.com/servo/rust-cssparser#110bf3052d016bf6eda0689fb21cf971e2c23dc8" +version = "0.2.0" +source = "git+https://github.com/servo/rust-cssparser#2a8c9f2c5f568495bae16f44b799be39b8efad39" dependencies = [ - "encoding 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "text_writer 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "text_writer 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -156,63 +158,63 @@ dependencies = [ [[package]] name = "egl" version = "0.1.0" -source = "git+https://github.com/servo/rust-egl#88f2a13812ddbce2bf2317221663a61c31b3e220" +source = "git+https://github.com/servo/rust-egl#cd74c82a8537090edb6c16478e2261db2a8c0b4f" [[package]] name = "encoding" -version = "0.2.6" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "encoding-index-japanese 1.0.20140915 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding-index-korean 1.0.20140915 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding-index-simpchinese 1.0.20140915 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding-index-singlebyte 1.0.20140915 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding-index-tradchinese 1.0.20140915 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding-index-japanese 1.20141219.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding-index-korean 1.20141219.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding-index-simpchinese 1.20141219.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding-index-singlebyte 1.20141219.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding-index-tradchinese 1.20141219.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "encoding-index-japanese" -version = "1.0.20140915" +version = "1.20141219.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "encoding_index_tests 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_index_tests 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "encoding-index-korean" -version = "1.0.20140915" +version = "1.20141219.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "encoding_index_tests 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_index_tests 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "encoding-index-simpchinese" -version = "1.0.20140915" +version = "1.20141219.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "encoding_index_tests 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_index_tests 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "encoding-index-singlebyte" -version = "1.0.20140915" +version = "1.20141219.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "encoding_index_tests 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_index_tests 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "encoding-index-tradchinese" -version = "1.0.20140915" +version = "1.20141219.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "encoding_index_tests 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_index_tests 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "encoding_index_tests" -version = "0.1.0" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -240,7 +242,7 @@ dependencies = [ [[package]] name = "freetype" version = "0.1.0" -source = "git+https://github.com/servo/rust-freetype#e55b06110fb2d74a2db68ead740db7e98fb98060" +source = "git+https://github.com/servo/rust-freetype#ec0231343a3ad360d86846c12895a0a0cbb19f79" [[package]] name = "freetype-sys" @@ -249,18 +251,18 @@ source = "git+https://github.com/servo/libfreetype2#f5c49c0da1d5bc6b206c41763440 [[package]] name = "gcc" -version = "0.1.1" -source = "git+https://github.com/alexcrichton/gcc-rs#dfe97a119af4b2db53178eb8c3ca6be6589a152b" +version = "0.1.4" +source = "git+https://github.com/alexcrichton/gcc-rs#f5c52d956e0742a66e40c8301e634e136c3ae287" [[package]] name = "gcc" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "geom" version = "0.1.0" -source = "git+https://github.com/servo/rust-geom#05f2d5494355adc78ad7d17286912f0d128f503b" +source = "git+https://github.com/servo/rust-geom#a4a4a03aa024412bf3f4e093c0198b433c6ad63f" [[package]] name = "gfx" @@ -282,74 +284,65 @@ dependencies = [ "script_traits 0.0.1", "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)", "style 0.0.1", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "gl_common" -version = "0.0.1" -source = "git+https://github.com/bjz/gl-rs.git#b5e3f4f76c31bc1b459d5e4c10d879ffa4f67c6e" +version = "0.0.3" +source = "git+https://github.com/bjz/gl-rs.git#230e6c9ed611cddfcb6682dee9686471d54863d0" [[package]] -name = "gl_generator" -version = "0.0.1" -source = "git+https://github.com/bjz/gl-rs.git#b5e3f4f76c31bc1b459d5e4c10d879ffa4f67c6e" -dependencies = [ - "gl_common 0.0.1 (git+https://github.com/bjz/gl-rs.git)", - "khronos_api 0.0.2 (git+https://github.com/bjz/gl-rs.git)", - "xml-rs 0.1.3 (git+https://github.com/netvl/xml-rs)", -] +name = "gl_common" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "gleam" -version = "0.0.1" -source = "git+https://github.com/servo/gleam#c54eb9ad6d4b62b7effbe9c79a1b3720845b45b4" +name = "gl_generator" +version = "0.0.12" +source = "git+https://github.com/bjz/gl-rs.git#230e6c9ed611cddfcb6682dee9686471d54863d0" dependencies = [ - "gl_generator 0.0.1 (git+https://github.com/bjz/gl-rs.git)", + "gl_common 0.0.3 (git+https://github.com/bjz/gl-rs.git)", + "khronos_api 0.0.5 (git+https://github.com/bjz/gl-rs.git)", + "log 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "xml-rs 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "glfw" -version = "0.0.1" -source = "git+https://github.com/servo/glfw-rs?ref=servo#b186cb444e349a36b992445dc5cb2c99d38f2a42" +name = "gl_generator" +version = "0.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "glfw-sys 3.0.4 (git+https://github.com/servo/glfw?ref=cargo-3.0.4)", - "semver 0.1.4 (git+https://github.com/rust-lang/semver)", + "gl_common 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "khronos_api 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "xml-rs 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "glfw-sys" -version = "3.0.4" -source = "git+https://github.com/servo/glfw?ref=cargo-3.0.4#765dace7e4125b87c764f5ac0e7a80eae5c550b2" - -[[package]] -name = "glfw_app" +name = "gleam" version = "0.0.1" +source = "git+https://github.com/servo/gleam#375779e0e8e1eaa8ff1a732c81fa91808a7f6c63" dependencies = [ - "cgl 0.0.1 (git+https://github.com/servo/rust-cgl)", - "compositing 0.0.1", - "geom 0.1.0 (git+https://github.com/servo/rust-geom)", - "gleam 0.0.1 (git+https://github.com/servo/gleam)", - "glfw 0.0.1 (git+https://github.com/servo/glfw-rs?ref=servo)", - "layers 0.1.0 (git+https://github.com/servo/rust-layers)", - "msg 0.0.1", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "util 0.0.1", + "gl_common 0.0.3 (git+https://github.com/bjz/gl-rs.git)", + "gl_generator 0.0.12 (git+https://github.com/bjz/gl-rs.git)", ] [[package]] name = "glutin" -version = "0.0.2" -source = "git+https://github.com/servo/glutin?ref=servo#db27370a1cbafcbfcaeee52a44076a61b3e0573c" +version = "0.0.4-pre" +source = "git+https://github.com/tomaka/glutin#1d6b863cd454839b8e3cf1e296cbf8f31fb70029" dependencies = [ - "android_glue 0.0.1 (git+https://github.com/servo/android-rs-glue?ref=servo)", + "android_glue 0.0.1 (git+https://github.com/tomaka/android-rs-glue)", "cocoa 0.1.1 (git+https://github.com/servo/rust-cocoa)", + "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)", - "gl_common 0.0.1 (git+https://github.com/bjz/gl-rs.git)", - "gl_generator 0.0.1 (git+https://github.com/bjz/gl-rs.git)", - "winapi 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "gl_common 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "gl_generator 0.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "khronos_api 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -358,21 +351,23 @@ version = "0.0.1" dependencies = [ "cgl 0.0.1 (git+https://github.com/servo/rust-cgl)", "compositing 0.0.1", + "egl 0.1.0 (git+https://github.com/servo/rust-egl)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gleam 0.0.1 (git+https://github.com/servo/gleam)", - "glutin 0.0.2 (git+https://github.com/servo/glutin?ref=servo)", + "glutin 0.0.4-pre (git+https://github.com/tomaka/glutin)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "msg 0.0.1", - "time 0.1.0 (git+https://github.com/rust-lang/time)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "glx" version = "0.0.1" -source = "git+https://github.com/servo/rust-glx#7126ffa09fcfcc9f85f1406f3b5db729f5fdb7c3" +source = "git+https://github.com/servo/rust-glx#f056a8998987f6f081f9ad7fa396beb1b2988c02" dependencies = [ - "gl_generator 0.0.1 (git+https://github.com/bjz/gl-rs.git)", + "gl_common 0.0.3 (git+https://github.com/bjz/gl-rs.git)", + "gl_generator 0.0.12 (git+https://github.com/bjz/gl-rs.git)", ] [[package]] @@ -383,33 +378,36 @@ source = "git+https://github.com/servo/rust-harfbuzz#59b5b18087418404d661784934c [[package]] name = "html5ever" version = "0.0.0" -source = "git+https://github.com/servo/html5ever#0abe5e30cc03f9e73bfd4fdc018192d149c21fb3" +source = "git+https://github.com/servo/html5ever#d35dfaaf0d85007057a299afc370d07e92538944" dependencies = [ "html5ever_macros 0.0.0 (git+https://github.com/servo/html5ever)", - "phf 0.0.1 (git+https://github.com/sfackler/rust-phf)", - "phf_mac 0.0.1 (git+https://github.com/sfackler/rust-phf)", + "phf 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_mac 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", - "time 0.1.0 (git+https://github.com/rust-lang/time)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "html5ever_macros" version = "0.0.0" -source = "git+https://github.com/servo/html5ever#0abe5e30cc03f9e73bfd4fdc018192d149c21fb3" +source = "git+https://github.com/servo/html5ever#d35dfaaf0d85007057a299afc370d07e92538944" [[package]] name = "hyper" -version = "0.0.1" -source = "git+https://github.com/servo/hyper?ref=servo#43becc919c24939b8b84fe541b0e0898a4827836" +version = "0.1.0" +source = "git+https://github.com/servo/hyper?branch=servo#248a6f29086baa841eb30c88540dca3196accae4" dependencies = [ - "cookie 0.1.0 (git+https://github.com/alexcrichton/cookie-rs)", - "mime 0.0.1 (git+https://github.com/hyperium/mime.rs)", - "mucell 0.1.2 (git+https://github.com/chris-morgan/mucell)", - "openssl 0.2.4 (git+https://github.com/sfackler/rust-openssl)", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "unsafe-any 0.1.1 (git+https://github.com/reem/rust-unsafe-any)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "cookie 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mucell 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unsafe-any 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -426,20 +424,25 @@ dependencies = [ [[package]] name = "js" version = "0.1.0" -source = "git+https://github.com/servo/rust-mozjs#5a69e377d6ab7ea8601f711443994f1c8172c7a8" +source = "git+https://github.com/servo/rust-mozjs#6cabb12f858f27d23fc3d2d9f0c334b80eb56573" dependencies = [ "mozjs-sys 0.0.0 (git+https://github.com/servo/mozjs)", ] [[package]] name = "khronos_api" -version = "0.0.2" -source = "git+https://github.com/bjz/gl-rs.git#b5e3f4f76c31bc1b459d5e4c10d879ffa4f67c6e" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "khronos_api" +version = "0.0.5" +source = "git+https://github.com/bjz/gl-rs.git#230e6c9ed611cddfcb6682dee9686471d54863d0" [[package]] name = "layers" version = "0.1.0" -source = "git+https://github.com/servo/rust-layers#f20270839f8658a2b19eae6fade9325efe5f4578" +source = "git+https://github.com/servo/rust-layers#8dece8325eda4a74816832580e62ebd3afc99dfb" dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", "cgl 0.0.1 (git+https://github.com/servo/rust-cgl)", @@ -456,8 +459,9 @@ dependencies = [ name = "layout" version = "0.0.1" dependencies = [ - "cssparser 0.1.1 (git+https://github.com/servo/rust-cssparser)", - "encoding 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "canvas 0.0.1", + "cssparser 0.2.0 (git+https://github.com/servo/rust-cssparser)", + "encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gfx 0.0.1", "layout_traits 0.0.1", @@ -468,7 +472,7 @@ dependencies = [ "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", "style 0.0.1", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -485,8 +489,8 @@ dependencies = [ [[package]] name = "lazy_static" -version = "0.1.0" -source = "git+https://github.com/Kimundi/lazy-static.rs#76f06e4fa7bc8c92f11d1def19bd4ddfd8017cd8" +version = "0.1.6" +source = "git+https://github.com/Kimundi/lazy-static.rs#31a7aa0176ecd70b4aab274a40d1e2cd78c1fbf8" [[package]] name = "libressl-pnacl-sys" @@ -497,14 +501,30 @@ dependencies = [ ] [[package]] +name = "log" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "regex 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "matches" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "mime" -version = "0.0.1" -source = "git+https://github.com/hyperium/mime.rs#7898f1c29c7f5d35d0c3c7aed37ebcfc95a40873" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "mozjs-sys" version = "0.0.0" -source = "git+https://github.com/servo/mozjs#0335cc57346147851589dea04e85971f064081fd" +source = "git+https://github.com/servo/mozjs#58ee8869c7e589244ab2eb3a3ad15e2b64498428" [[package]] name = "msg" @@ -513,44 +533,44 @@ dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", - "hyper 0.0.1 (git+https://github.com/servo/hyper?ref=servo)", + "hyper 0.1.0 (git+https://github.com/servo/hyper?branch=servo)", "io_surface 0.1.0 (git+https://github.com/servo/rust-io-surface)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "style 0.0.1", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "mucell" -version = "0.1.2" -source = "git+https://github.com/chris-morgan/mucell#d198c6605b3e688719db168db0939051c803b1ea" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "net" version = "0.0.1" dependencies = [ "geom 0.1.0 (git+https://github.com/servo/rust-geom)", - "hyper 0.0.1 (git+https://github.com/servo/hyper?ref=servo)", + "hyper 0.1.0 (git+https://github.com/servo/hyper?branch=servo)", "png 0.1.0 (git+https://github.com/servo/rust-png)", "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "openssl" -version = "0.2.4" -source = "git+https://github.com/sfackler/rust-openssl#f299e336d06a85438c3ee90aa06235510f3f5dbe" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "openssl-sys 0.2.4 (git+https://github.com/sfackler/rust-openssl)", + "openssl-sys 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl-sys" -version = "0.2.4" -source = "git+https://github.com/sfackler/rust-openssl#f299e336d06a85438c3ee90aa06235510f3f5dbe" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libressl-pnacl-sys 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -558,22 +578,26 @@ dependencies = [ [[package]] name = "phf" -version = "0.0.1" -source = "git+https://github.com/sfackler/rust-phf#6a7cc6eb9ec08b103b6b62fa39bdb3229f3cdbe4" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "xxhash 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_shared 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "phf_mac" -version = "0.0.1" -source = "git+https://github.com/sfackler/rust-phf#6a7cc6eb9ec08b103b6b62fa39bdb3229f3cdbe4" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "time 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "xxhash 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_shared 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] +name = "phf_shared" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "pkg-config" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -590,29 +614,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "png" version = "0.1.0" -source = "git+https://github.com/servo/rust-png#cc1976df347bb21ac78c5b37e651b85878855991" +source = "git+https://github.com/servo/rust-png#2804379427ced963466d19132b816bb06a8a4006" dependencies = [ - "gcc 0.1.1 (git+https://github.com/alexcrichton/gcc-rs)", + "gcc 0.1.4 (git+https://github.com/alexcrichton/gcc-rs)", "png-sys 1.6.16 (git+https://github.com/servo/rust-png)", ] [[package]] name = "png-sys" version = "1.6.16" -source = "git+https://github.com/servo/rust-png#cc1976df347bb21ac78c5b37e651b85878855991" +source = "git+https://github.com/servo/rust-png#2804379427ced963466d19132b816bb06a8a4006" + +[[package]] +name = "regex" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc-serialize" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "script" version = "0.0.1" dependencies = [ "canvas 0.0.1", - "cssparser 0.1.1 (git+https://github.com/servo/rust-cssparser)", + "cssparser 0.2.0 (git+https://github.com/servo/rust-cssparser)", "devtools_traits 0.0.1", - "encoding 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gfx 0.0.1", "html5ever 0.0.0 (git+https://github.com/servo/html5ever)", - "hyper 0.0.1 (git+https://github.com/servo/hyper?ref=servo)", + "hyper 0.1.0 (git+https://github.com/servo/hyper?branch=servo)", "js 0.1.0 (git+https://github.com/servo/rust-mozjs)", "msg 0.0.1", "net 0.0.1", @@ -621,10 +655,10 @@ dependencies = [ "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", "style 0.0.1", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", - "uuid 0.1.1 (git+https://github.com/rust-lang/uuid)", + "uuid 0.1.7 (git+https://github.com/rust-lang/uuid)", ] [[package]] @@ -635,35 +669,32 @@ dependencies = [ "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "msg 0.0.1", "net 0.0.1", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] -name = "semver" -version = "0.1.4" -source = "git+https://github.com/rust-lang/semver#58dc6b1999d345ca925a2f12a6a84676e823e179" - -[[package]] name = "servo" version = "0.0.1" dependencies = [ "compositing 0.0.1", + "devtools 0.0.1", "gfx 0.0.1", - "glfw_app 0.0.1", + "glutin_app 0.0.1", "layout 0.0.1", "msg 0.0.1", "net 0.0.1", + "png 0.1.0 (git+https://github.com/servo/rust-png)", "script 0.0.1", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "skia-sys" version = "0.0.20130412" -source = "git+https://github.com/servo/skia?ref=upstream-2014-06-16#35649d0cddfd89c0bfee0ff558da7291e26d30c3" +source = "git+https://github.com/servo/skia?branch=upstream-2014-06-16#aeb720b947ec463f780a0d00ab8485f902a83986" dependencies = [ "expat-sys 2.1.0 (git+https://github.com/servo/libexpat)", "freetype-sys 2.4.11 (git+https://github.com/servo/libfreetype2)", @@ -672,41 +703,42 @@ dependencies = [ [[package]] name = "stb_image" version = "0.1.0" -source = "git+https://github.com/servo/rust-stb-image#97d7e440e80e41a304647363c322eab68e3700aa" +source = "git+https://github.com/servo/rust-stb-image#2ba03a447b9ef101c25e07bb7f8876416e5fcd71" [[package]] name = "string_cache" version = "0.0.0" -source = "git+https://github.com/servo/string-cache#661c537b85f19ac81dfcd84e28557d480b6b7a9f" +source = "git+https://github.com/servo/string-cache#43a1e5d0d0f2a45e2b96160c8fbe6e1d9602cfa9" dependencies = [ - "lazy_static 0.1.0 (git+https://github.com/Kimundi/lazy-static.rs)", - "phf 0.0.1 (git+https://github.com/sfackler/rust-phf)", - "phf_mac 0.0.1 (git+https://github.com/sfackler/rust-phf)", + "lazy_static 0.1.6 (git+https://github.com/Kimundi/lazy-static.rs)", + "phf 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_mac 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", - "xxhash 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "xxhash 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "string_cache_macros" version = "0.0.0" -source = "git+https://github.com/servo/string-cache#661c537b85f19ac81dfcd84e28557d480b6b7a9f" +source = "git+https://github.com/servo/string-cache#43a1e5d0d0f2a45e2b96160c8fbe6e1d9602cfa9" dependencies = [ - "lazy_static 0.1.0 (git+https://github.com/Kimundi/lazy-static.rs)", + "lazy_static 0.1.6 (git+https://github.com/Kimundi/lazy-static.rs)", ] [[package]] name = "style" version = "0.0.1" dependencies = [ - "cssparser 0.1.1 (git+https://github.com/servo/rust-cssparser)", - "encoding 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.2.0 (git+https://github.com/servo/rust-cssparser)", + "encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", - "lazy_static 0.1.0 (git+https://github.com/Kimundi/lazy-static.rs)", + "lazy_static 0.1.6 (git+https://github.com/Kimundi/lazy-static.rs)", + "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", - "text_writer 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "text_writer 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -716,73 +748,77 @@ version = "0.0.1" [[package]] name = "text_writer" -version = "0.1.4" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "time" -version = "0.1.0" -source = "git+https://github.com/rust-lang/time#afab521f3b91658a3ba2d3e877b7e01699733bef" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.1.1 (git+https://github.com/alexcrichton/gcc-rs)", + "gcc 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "time" -version = "0.1.3" +name = "unicase" +version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "gcc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "unsafe-any" -version = "0.1.1" -source = "git+https://github.com/reem/rust-unsafe-any#eb3fe87bea85f375b8fcefa0cdecfd131fae9624" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "url" -version = "0.2.4" -source = "git+https://github.com/servo/rust-url#79f8034a8e1815ffa1f49204572ddbf6eb747c75" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "util" version = "0.0.1" dependencies = [ - "cssparser 0.1.1 (git+https://github.com/servo/rust-cssparser)", + "cssparser 0.2.0 (git+https://github.com/servo/rust-cssparser)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "plugins 0.0.1", "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", "task_info 0.0.1", - "text_writer 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "text_writer 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "uuid" -version = "0.1.1" -source = "git+https://github.com/rust-lang/uuid#fc793c974a25c126c5cf5daa3b18973512a7a6a0" +version = "0.1.7" +source = "git+https://github.com/rust-lang/uuid#3ea51ffa0682c820e8c8b505de078e3bc93e2cb3" +dependencies = [ + "rustc-serialize 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "winapi" -version = "0.0.2" +version = "0.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "xlib" version = "0.1.0" -source = "git+https://github.com/servo/rust-xlib#58ec3847b592aeabdcfeb6a2d02033d3a2c7f427" +source = "git+https://github.com/servo/rust-xlib#138b0e281b9fd64f7d2e17080fa9a2d4a8554313" [[package]] name = "xml-rs" -version = "0.1.3" -source = "git+https://github.com/netvl/xml-rs#1a812d3ba720afd768bd75d29a5b5f10ddcdfbeb" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "xxhash" -version = "0.0.3" +version = "0.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/ports/cef/browser.rs b/ports/cef/browser.rs index 968d6a320db..a4d01a03828 100644 --- a/ports/cef/browser.rs +++ b/ports/cef/browser.rs @@ -16,11 +16,12 @@ use compositing::windowing::{WindowNavigateMsg, WindowEvent}; use glutin_app; use libc::c_int; use servo_util::opts; +use std::borrow::ToOwned; use std::cell::{Cell, RefCell}; -use std::sync::atomic::{AtomicInt, SeqCst}; +use std::sync::atomic::{AtomicInt, Ordering}; -thread_local!(pub static ID_COUNTER: AtomicInt = AtomicInt::new(0)) -thread_local!(pub static BROWSERS: RefCell<Vec<CefBrowser>> = RefCell::new(vec!())) +thread_local!(pub static ID_COUNTER: AtomicInt = AtomicInt::new(0)); +thread_local!(pub static BROWSERS: RefCell<Vec<CefBrowser>> = RefCell::new(vec!())); pub enum ServoBrowser { Invalid, @@ -56,22 +57,22 @@ impl ServoBrowser { cef_class_impl! { ServoCefBrowser : CefBrowser, cef_browser_t { - fn get_host(&this) -> *mut cef_browser_host_t { + fn get_host(&this,) -> *mut cef_browser_host_t {{ this.downcast().host.clone() - } + }} - fn go_back(&this) -> () { + fn go_back(&this,) -> () {{ this.send_window_event(WindowEvent::Navigation(WindowNavigateMsg::Back)); - } + }} - fn go_forward(&this) -> () { + fn go_forward(&this,) -> () {{ this.send_window_event(WindowEvent::Navigation(WindowNavigateMsg::Forward)); - } + }} // Returns the main (top-level) frame for the browser window. - fn get_main_frame(&this) -> *mut cef_frame_t { + fn get_main_frame(&this,) -> *mut cef_frame_t {{ this.downcast().frame.clone() - } + }} } } @@ -104,7 +105,7 @@ impl ServoCefBrowser { }; let id = ID_COUNTER.with(|counter| { - counter.fetch_add(1, SeqCst) + counter.fetch_add(1, Ordering::SeqCst) }); ServoCefBrowser { @@ -204,7 +205,7 @@ fn browser_host_create(window_info: &cef_window_info_t, callback_executed: bool) -> CefBrowser { let mut urls = Vec::new(); - urls.push("http://s27.postimg.org/vqbtrolyr/servo.jpg".into_string()); + urls.push("http://s27.postimg.org/vqbtrolyr/servo.jpg".to_owned()); let mut opts = opts::default_opts(); opts.urls = urls; let browser = ServoCefBrowser::new(window_info, client).as_cef_interface(); @@ -224,25 +225,25 @@ cef_static_method_impls! { _url: *const cef_string_t, _browser_settings: *const cef_browser_settings_t, _request_context: *mut cef_request_context_t) - -> c_int { + -> c_int {{ let client: CefClient = client; let _url: &[u16] = _url; let _browser_settings: &cef_browser_settings_t = _browser_settings; let _request_context: CefRequestContext = _request_context; browser_host_create(window_info, client, false); 1i32 - } + }} fn cef_browser_host_create_browser_sync(window_info: *const cef_window_info_t, client: *mut cef_client_t, _url: *const cef_string_t, _browser_settings: *const cef_browser_settings_t, _request_context: *mut cef_request_context_t) - -> *mut cef_browser_t { + -> *mut cef_browser_t {{ let client: CefClient = client; let _url: &[u16] = _url; let _browser_settings: &cef_browser_settings_t = _browser_settings; let _request_context: CefRequestContext = _request_context; browser_host_create(window_info, client, true) - } + }} } diff --git a/ports/cef/browser_host.rs b/ports/cef/browser_host.rs index 8ed741eb05f..ed8e8f66ede 100644 --- a/ports/cef/browser_host.rs +++ b/ports/cef/browser_host.rs @@ -22,32 +22,33 @@ pub struct ServoCefBrowserHost { pub client: CefClient, } -cef_class_impl! { +full_cef_class_impl! { ServoCefBrowserHost : CefBrowserHost, cef_browser_host_t { - fn get_client(&this) -> *mut cef_client_t { + fn get_client(&this,) -> *mut cef_client_t {{ this.downcast().client.clone() - } + }} - fn was_resized(&this) -> () { + fn was_resized(&this,) -> () {{ let mut rect = cef_rect_t::zero(); this.get_client() .get_render_handler() .get_backing_rect(this.downcast().browser.borrow().clone().unwrap(), &mut rect); - let size = TypedSize2D(rect.width as uint, rect.height as uint); + let size = TypedSize2D(rect.width as u32, rect.height as u32); this.downcast().send_window_event(WindowEvent::Resize(size)); - } + }} - fn close_browser(&this, _force: c_int) -> () { + fn close_browser(&this, _force: c_int [c_int],) -> () {{ browser::close(this.downcast().browser.borrow_mut().take().unwrap()); - } + }} - fn send_focus_event(&this, focus: c_int) -> () { + fn send_focus_event(&this, focus: c_int [c_int],) -> () {{ + let focus: c_int = focus; if focus != 0 { this.downcast().send_window_event(WindowEvent::Refresh); } - } + }} - fn send_key_event(&this, event: *const cef_key_event) -> () { + fn send_key_event(&this, event: *const cef_key_event [&cef_key_event],) -> () {{ // FIXME(pcwalton): So awful. But it's nearly midnight here and I have to get // Google working. let event: &cef_key_event = event; @@ -98,15 +99,17 @@ cef_class_impl! { }; let key_modifiers = KeyModifiers::empty(); // TODO(pcwalton) this.downcast().send_window_event(WindowEvent::KeyEvent(key, key_state, key_modifiers)) - } + }} fn send_mouse_click_event(&this, - event: *const cef_mouse_event, - mouse_button_type: cef_mouse_button_type_t, - mouse_up: c_int, - _click_count: c_int) - -> () { + event: *const cef_mouse_event [&cef_mouse_event], + mouse_button_type: cef_mouse_button_type_t [cef_mouse_button_type_t], + mouse_up: c_int [c_int], + _click_count: c_int [c_int],) + -> () {{ let event: &cef_mouse_event = event; + let mouse_button_type: cef_mouse_button_type_t = mouse_button_type; + let mouse_up: c_int = mouse_up; let button_type = mouse_button_type as uint; let point = TypedPoint2D((*event).x as f32, (*event).y as f32); if mouse_up != 0 { @@ -116,38 +119,42 @@ cef_class_impl! { this.downcast().send_window_event(WindowEvent::MouseWindowEventClass( MouseWindowEvent::MouseUp(button_type, point))) } - } + }} - fn send_mouse_move_event(&this, event: *const cef_mouse_event, _mouse_exited: c_int) - -> () { + fn send_mouse_move_event(&this, event: *const cef_mouse_event [&cef_mouse_event], + _mouse_exited: c_int [c_int],) + -> () {{ let event: &cef_mouse_event = event; let point = TypedPoint2D((*event).x as f32, (*event).y as f32); this.downcast().send_window_event(WindowEvent::MouseWindowMoveEventClass(point)) - } + }} fn send_mouse_wheel_event(&this, - event: *const cef_mouse_event, - delta_x: c_int, - delta_y: c_int) - -> () { + event: *const cef_mouse_event [&cef_mouse_event], + delta_x: c_int [c_int], + delta_y: c_int [c_int],) + -> () {{ let event: &cef_mouse_event = event; + let delta_x: c_int = delta_x; + let delta_y: c_int = delta_y; let delta = TypedPoint2D(delta_x as f32, delta_y as f32); let origin = TypedPoint2D((*event).x as i32, (*event).y as i32); this.downcast().send_window_event(WindowEvent::Scroll(delta, origin)) - } + }} - fn get_zoom_level(&this) -> c_double { + fn get_zoom_level(&this,) -> c_double {{ this.downcast().pinch_zoom_level() as c_double - } + }} - fn set_zoom_level(&this, new_zoom_level: c_double) -> () { + fn set_zoom_level(&this, new_zoom_level: c_double [c_double],) -> () {{ + let new_zoom_level: c_double = new_zoom_level; let old_zoom_level = this.get_zoom_level(); this.downcast().send_window_event(WindowEvent::PinchZoom((new_zoom_level / old_zoom_level) as f32)) - } + }} - fn initialize_compositing(&this) -> () { + fn initialize_compositing(&this,) -> () {{ this.downcast().send_window_event(WindowEvent::InitializeCompositing); - } + }} } } diff --git a/ports/cef/command_line.rs b/ports/cef/command_line.rs index 53655b28c79..393b3d62004 100644 --- a/ports/cef/command_line.rs +++ b/ports/cef/command_line.rs @@ -4,10 +4,11 @@ use interfaces::cef_command_line_t; -use libc::{calloc, c_int, size_t}; +use libc::{calloc, c_int, c_char, size_t}; +use std::ffi; use std::mem; -use std::string; -use std::c_vec::CVec; +use std::slice; +use std::str; use string as cef_string; use string::cef_string_utf16_set; use types::{cef_string_t, cef_string_userfree_t, cef_string_utf16_t}; @@ -33,12 +34,15 @@ pub fn command_line_init(argc: c_int, argv: *const *const u8) { unsafe { let mut a: Vec<String> = vec!(); for i in range(0u, argc as uint) { - a.push(string::raw::from_buf(*argv.offset(i as int) as *const u8)); + let offset = *argv.offset(i as int) as *const c_char; + let slice = ffi::c_str_to_bytes(&offset); + let s = str::from_utf8(slice).unwrap(); + a.push(String::from_str(s)); } let cl = command_line_new(); (*cl).argc = argc; (*cl).argv = a; - (*cl).cl.get_switch_value = Some(command_line_get_switch_value); + (*cl).cl.get_switch_value = Some(command_line_get_switch_value as extern "C" fn(*mut cef_command_line_t, *const cef_string_t) -> cef_string_userfree_t); GLOBAL_CMDLINE = Some(cl); } } @@ -53,20 +57,21 @@ pub extern "C" fn command_line_get_switch_value(cmd: *mut cef_command_line_t, na //but the default cef callback uses utf16, so I'm jumping on board the SS Copy let cl: *mut command_line_t = mem::transmute(cmd); let cs: *const cef_string_utf16_t = mem::transmute(name); - let opt = String::from_utf16(CVec::new((*cs).str, (*cs).length as uint).as_slice()).unwrap(); + let buf = (*cs).str as *const _; + let slice = slice::from_raw_buf(&buf, (*cs).length as usize); + let opt = String::from_utf16(slice).unwrap(); //debug!("opt: {}", opt); for s in (*cl).argv.iter() { - let o = s.as_slice().trim_left_chars('-'); + let o = s.as_slice().trim_left_matches('-'); //debug!("arg: {}", o); if o.as_slice().starts_with(opt.as_slice()) { let mut string = mem::uninitialized(); let arg = o.slice_from(opt.len() + 1).as_bytes(); - arg.with_c_str(|c_str| { - cef_string_utf16_set(mem::transmute(c_str), - arg.len() as size_t, - &mut string, - 1); - }); + let c_str = ffi::CString::from_slice(arg); + cef_string_utf16_set(c_str.as_bytes().as_ptr() as *const _, + arg.len() as size_t, + &mut string, + 1); return cef_string::string_to_userfree_string(string) } } @@ -78,7 +83,7 @@ pub extern "C" fn command_line_get_switch_value(cmd: *mut cef_command_line_t, na pub extern "C" fn cef_command_line_create() -> *mut cef_command_line_t { unsafe { let cl = command_line_new(); - (*cl).cl.get_switch_value = Some(command_line_get_switch_value); + (*cl).cl.get_switch_value = Some(command_line_get_switch_value as extern "C" fn(*mut cef_command_line_t, *const cef_string_t) -> cef_string_userfree_t); mem::transmute(cl) } } @@ -98,7 +103,7 @@ pub extern "C" fn cef_command_line_get_global() -> *mut cef_command_line_t { } cef_stub_static_method_impls! { - fn cef_command_line_create_command_line() -> *mut cef_command_line_t; - fn cef_command_line_get_global_command_line() -> *mut cef_command_line_t; + fn cef_command_line_create_command_line() -> *mut cef_command_line_t + fn cef_command_line_get_global_command_line() -> *mut cef_command_line_t } diff --git a/ports/cef/cookie.rs b/ports/cef/cookie.rs index c1290767430..34aae98b594 100644 --- a/ports/cef/cookie.rs +++ b/ports/cef/cookie.rs @@ -8,9 +8,9 @@ use types::cef_string_t; use libc::c_int; cef_stub_static_method_impls! { - fn cef_cookie_manager_get_global_manager() -> *mut cef_cookie_manager_t; + fn cef_cookie_manager_get_global_manager() -> *mut cef_cookie_manager_t fn cef_cookie_manager_create_manager(path: *const cef_string_t, persist_session_cookies: c_int) - -> *mut cef_cookie_manager_t; + -> *mut cef_cookie_manager_t } diff --git a/ports/cef/core.rs b/ports/cef/core.rs index 98e3fcfc168..fac8d8ac512 100644 --- a/ports/cef/core.rs +++ b/ports/cef/core.rs @@ -8,12 +8,10 @@ use types::{cef_main_args_t, cef_settings_t}; use geom::size::TypedSize2D; use libc::{c_char, c_int, c_void}; -use rustrt::local::Local; -use rustrt::task; use servo_util::opts; -use servo_util::opts::RenderApi; -use std::c_str::CString; -use std::rt; +use std::borrow::ToOwned; +use std::ffi; +use std::str; use browser; const MAX_RENDERING_THREADS: uint = 128; @@ -31,7 +29,7 @@ static CEF_API_HASH_PLATFORM: &'static [u8] = b"2bc564c3871965ef3a2531b528bda3e1 #[cfg(target_os="linux")] fn resources_path() -> Option<String> { - Some("../../servo/resources".into_string()) + Some("../../servo/resources".to_owned()) } #[cfg(not(target_os="linux"))] @@ -39,11 +37,6 @@ fn resources_path() -> Option<String> { None } -fn create_rust_task() { - let task = box task::Task::new(None, None); - Local::put(task); -} - #[no_mangle] pub extern "C" fn cef_initialize(args: *const cef_main_args_t, settings: *mut cef_settings_t, @@ -55,22 +48,19 @@ pub extern "C" fn cef_initialize(args: *const cef_main_args_t, } unsafe { - rt::init((*args).argc as int, (*args).argv); command_line_init((*args).argc, (*args).argv); if !application.is_null() { (*application).get_browser_process_handler.map(|cb| { let handler = cb(application); - if handler.is_not_null() { + if !handler.is_null() { (*handler).on_context_initialized.map(|hcb| hcb(handler)); } }); } } - create_rust_task(); - - let urls = vec![HOME_URL.into_string()]; + let urls = vec![HOME_URL.to_owned()]; opts::set_opts(opts::Opts { urls: urls, n_paint_threads: 1, @@ -104,7 +94,6 @@ pub extern "C" fn cef_initialize(args: *const cef_main_args_t, user_agent: None, dump_flow_tree: false, validate_display_list_geometry: false, - render_api: RenderApi::OpenGL, resources_path: resources_path(), }); @@ -157,7 +146,8 @@ pub extern "C" fn cef_log(_file: *const c_char, _severity: c_int, message: *const c_char) { unsafe { - println!("{}", CString::new(message, false)) + let slice = ffi::c_str_to_bytes(&message); + println!("{}", str::from_utf8(slice).unwrap()) } } diff --git a/ports/cef/drag_data.rs b/ports/cef/drag_data.rs index 4285f204b64..f7660a6b5ca 100644 --- a/ports/cef/drag_data.rs +++ b/ports/cef/drag_data.rs @@ -5,6 +5,6 @@ use interfaces::{cef_drag_data_t}; cef_stub_static_method_impls! { - fn cef_drag_data_create() -> *mut cef_drag_data_t; + fn cef_drag_data_create() -> *mut cef_drag_data_t } diff --git a/ports/cef/eutil.rs b/ports/cef/eutil.rs index 0821bb9d6c6..c46158430ec 100644 --- a/ports/cef/eutil.rs +++ b/ports/cef/eutil.rs @@ -19,11 +19,10 @@ pub trait Downcast<Class> { fn downcast(&self) -> &Class; } -pub fn slice_to_str(s: *const u8, l: uint, f: |&str| -> c_int) -> c_int { +pub fn slice_to_str<F>(s: *const u8, l: uint, f: F) -> c_int where F: FnOnce(&str) -> c_int { unsafe { - slice::raw::buf_as_slice(s, l, |result| { - str::from_utf8(result).map(|s| f(s)).unwrap_or(0) - }) + let s = slice::from_raw_buf(&s, l); + str::from_utf8(s).map(f).unwrap_or(0) } } @@ -34,8 +33,8 @@ pub unsafe fn create_cef_object<Base,Extra>(size: size_t) -> *mut Base { let object = libc::calloc(1, (mem::size_of::<Base>() + mem::size_of::<Extra>()) as u64) as *mut cef_base_t; (*object).size = size; - (*object).add_ref = Some(servo_add_ref); - (*object).release = Some(servo_release); + (*object).add_ref = Some(servo_add_ref as extern "C" fn(*mut cef_base_t) -> c_int); + (*object).release = Some(servo_release as extern "C" fn(*mut cef_base_t) -> c_int); *ref_count(object) = 1; object as *mut Base } diff --git a/ports/cef/frame.rs b/ports/cef/frame.rs index b551e53a8e4..26c287afb06 100644 --- a/ports/cef/frame.rs +++ b/ports/cef/frame.rs @@ -28,23 +28,24 @@ impl ServoCefFrame { } } -cef_class_impl! { +full_cef_class_impl! { ServoCefFrame : CefFrame, cef_frame_t { - fn load_url(&this, url: *const cef_string_t) -> () { + fn load_url(&this, url: *const cef_string_t [&[u16]],) -> () {{ let this = this.downcast(); - *this.url.borrow_mut() = String::from_utf16(url).unwrap(); - let event = WindowEvent::LoadUrl(String::from_utf16(url).unwrap()); + let url = String::from_utf16(url).unwrap(); + *this.url.borrow_mut() = url.clone(); + let event = WindowEvent::LoadUrl(url); this.browser.borrow_mut().as_mut().unwrap().send_window_event(event); - } - fn get_url(&this) -> cef_string_userfree_t { + }} + fn get_url(&this,) -> cef_string_userfree_t {{ let this = this.downcast(); (*this.url.borrow()).clone() - } - fn get_text(&this, visitor: *mut cef_string_visitor_t) -> () { + }} + fn get_text(&this, visitor: *mut cef_string_visitor_t [CefStringVisitor],) -> () {{ let this = this.downcast(); *this.title_visitor.borrow_mut() = Some(visitor); this.browser.borrow().as_ref().unwrap().get_title_for_main_frame(); - } + }} } } @@ -56,4 +57,4 @@ impl ServoCefFrameExtensions for CefFrame { fn set_browser(&self, browser: CefBrowser) { *self.downcast().browser.borrow_mut() = Some(browser) } -}
\ No newline at end of file +} diff --git a/ports/cef/lib.rs b/ports/cef/lib.rs index 669f8239686..73c0fa10e80 100644 --- a/ports/cef/lib.rs +++ b/ports/cef/lib.rs @@ -2,15 +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/. */ -#![feature(globs, macro_rules, phase, thread_local, link_args)] +#![feature(thread_local, link_args, plugin, box_syntax, int_uint)] -#![allow(experimental, non_camel_case_types)] +#![allow(experimental, non_camel_case_types, unstable)] #![deny(unused_imports, unused_variables, unused_mut)] -#![feature(phase)] -#[phase(plugin, link)] +#[macro_use] extern crate log; -#[phase(plugin)] +#[plugin] extern crate "plugins" as servo_plugins; extern crate servo; @@ -32,7 +31,6 @@ extern crate "util" as servo_util; extern crate style; extern crate stb_image; -extern crate rustrt; extern crate libc; extern crate "url" as std_url; diff --git a/ports/cef/macros.rs b/ports/cef/macros.rs index 1a96cef97b2..dd31afe6573 100644 --- a/ports/cef/macros.rs +++ b/ports/cef/macros.rs @@ -35,9 +35,29 @@ macro_rules! cef_class_impl( ($class_name:ident : $interface_name:ident, $c_interface_name:ident { $( - fn $method_name:ident ( & $method_this:ident - $( , $method_arg_name:ident : $method_arg_type:ty )* ) - -> $method_return_type:ty $method_body:block + fn $method_name:ident ( & $method_this:ident , + $( $method_arg_name:ident : $c_method_arg_type:ty ,)* ) + -> $method_return_type:ty {$method_body:block} + )* + }) => ( + full_cef_class_impl! { + $class_name : $interface_name, $c_interface_name { + $(fn $method_name(&$method_this, + $($method_arg_name : $c_method_arg_type [$c_method_arg_type],)*) + -> $method_return_type { + $method_body + })* + } + } + ) +); + +macro_rules! full_cef_class_impl( + ($class_name:ident : $interface_name:ident, $c_interface_name:ident { + $( + fn $method_name:ident ( & $method_this:ident , + $( $method_arg_name:ident : $c_method_arg_type:ty [$method_arg_type:ty] ,)* ) + -> $method_return_type:ty {$method_body:block} )* }) => ( impl $class_name { @@ -52,7 +72,7 @@ macro_rules! cef_class_impl( ::eutil::create_cef_object::<$c_interface_name,$class_name>(size)) }; unsafe { - $((*cef_object.c_object()).$method_name = Some($method_name);)* + $((*cef_object.c_object()).$method_name = Some($method_name as extern "C" fn(*mut $c_interface_name, $($c_method_arg_type,)*) -> $method_return_type);)* let extra_slot = ::std::mem::transmute::<&mut u8, &mut $class_name>(&mut (*cef_object.c_object()) @@ -65,13 +85,13 @@ macro_rules! cef_class_impl( $( extern "C" fn $method_name(raw_this: *mut $c_interface_name, - $($method_arg_name: $method_arg_type),*) + $($method_arg_name: $c_method_arg_type),*) -> $method_return_type { let $method_this = unsafe { $interface_name::from_c_object_addref(raw_this) }; $( - let $method_arg_name = unsafe { + let $method_arg_name: $method_arg_type = unsafe { ::wrappers::CefWrap::to_rust($method_arg_name) }; )* @@ -87,13 +107,13 @@ macro_rules! cef_class_impl( } } ) -) +); macro_rules! cef_static_method_impls( ( $( fn $method_name:ident ( $($method_arg_name:ident : $method_arg_type:ty ),* ) - -> $method_return_type:ty $method_body:block + -> $method_return_type:ty {$method_body:block} )* ) => ( $( @@ -109,13 +129,13 @@ macro_rules! cef_static_method_impls( } )* ) -) +); macro_rules! cef_stub_static_method_impls( ( $( fn $method_name:ident ( $($method_arg_name:ident : $method_arg_type:ty ),* ) - -> $method_return_type:ty ; + -> $method_return_type:ty )* ) => ( $( @@ -126,4 +146,4 @@ macro_rules! cef_stub_static_method_impls( } )* ) -) +); diff --git a/ports/cef/print_settings.rs b/ports/cef/print_settings.rs index 31c6d08347b..91310c47806 100644 --- a/ports/cef/print_settings.rs +++ b/ports/cef/print_settings.rs @@ -5,5 +5,5 @@ use interfaces::cef_print_settings_t; cef_stub_static_method_impls! { - fn cef_print_settings_create() -> *mut cef_print_settings_t; + fn cef_print_settings_create() -> *mut cef_print_settings_t } diff --git a/ports/cef/process_message.rs b/ports/cef/process_message.rs index c3f42fe63c0..ed3800d78a1 100644 --- a/ports/cef/process_message.rs +++ b/ports/cef/process_message.rs @@ -6,6 +6,6 @@ use interfaces::cef_process_message_t; use types::cef_string_t; cef_stub_static_method_impls! { - fn cef_process_message_create(name: *const cef_string_t) -> *mut cef_process_message_t; + fn cef_process_message_create(name: *const cef_string_t) -> *mut cef_process_message_t } diff --git a/ports/cef/request.rs b/ports/cef/request.rs index d25d0e98d56..531575e5ae5 100644 --- a/ports/cef/request.rs +++ b/ports/cef/request.rs @@ -5,8 +5,8 @@ use interfaces::{cef_post_data_element_t, cef_post_data_t, cef_request_t}; cef_stub_static_method_impls! { - fn cef_request_create() -> *mut cef_request_t; - fn cef_post_data_create() -> *mut cef_post_data_t; - fn cef_post_data_element_create() -> *mut cef_post_data_element_t; + fn cef_request_create() -> *mut cef_request_t + fn cef_post_data_create() -> *mut cef_post_data_t + fn cef_post_data_element_create() -> *mut cef_post_data_element_t } diff --git a/ports/cef/request_context.rs b/ports/cef/request_context.rs index 4c256e1d62a..d5b01f08b08 100644 --- a/ports/cef/request_context.rs +++ b/ports/cef/request_context.rs @@ -5,8 +5,8 @@ use interfaces::{cef_request_context_handler_t, cef_request_context_t}; cef_stub_static_method_impls! { - fn cef_request_context_get_global_context() -> *mut cef_request_context_t; + fn cef_request_context_get_global_context() -> *mut cef_request_context_t fn cef_request_context_create_context(_handler: *mut cef_request_context_handler_t) - -> *mut cef_request_context_t; + -> *mut cef_request_context_t } diff --git a/ports/cef/response.rs b/ports/cef/response.rs index c6ed25a81a3..5c66e0acaa4 100644 --- a/ports/cef/response.rs +++ b/ports/cef/response.rs @@ -5,6 +5,6 @@ use interfaces::cef_response_t; cef_stub_static_method_impls! { - fn cef_response_create() -> *mut cef_response_t; + fn cef_response_create() -> *mut cef_response_t } diff --git a/ports/cef/stream.rs b/ports/cef/stream.rs index 753fe228501..9ed02ee91db 100644 --- a/ports/cef/stream.rs +++ b/ports/cef/stream.rs @@ -10,14 +10,14 @@ use libc; cef_stub_static_method_impls! { fn cef_stream_reader_create_for_file(_file_name: *const cef_string_t) - -> *mut cef_stream_reader_t; + -> *mut cef_stream_reader_t fn cef_stream_reader_create_for_data(_data: *mut (), _size: libc::size_t) - -> *mut cef_stream_reader_t; + -> *mut cef_stream_reader_t fn cef_stream_reader_create_for_handler(_handler: *mut cef_read_handler_t) - -> *mut cef_stream_reader_t; + -> *mut cef_stream_reader_t fn cef_stream_writer_create_for_file(_file_name: *const cef_string_t) - -> *mut cef_stream_writer_t; + -> *mut cef_stream_writer_t fn cef_stream_writer_create_for_handler(_handler: *mut cef_write_handler_t) - -> *mut cef_stream_writer_t; + -> *mut cef_stream_writer_t } diff --git a/ports/cef/string.rs b/ports/cef/string.rs index d0a0e4ba4e3..8c59c60f4bf 100644 --- a/ports/cef/string.rs +++ b/ports/cef/string.rs @@ -7,6 +7,7 @@ use eutil::slice_to_str; use libc::{mod, size_t, c_int, c_ushort, c_void}; use libc::types::os::arch::c95::wchar_t; use std::char; +use std::cmp::Ordering; use std::mem; use std::ptr; use std::slice; @@ -92,7 +93,7 @@ pub extern "C" fn cef_string_utf8_set(src: *const u8, src_len: size_t, output: * ptr::copy_memory((*output).str, src, src_len as uint); (*output).length = src_len; - (*output).dtor = Some(string_utf8_dtor); + (*output).dtor = Some(string_utf8_dtor as extern "C" fn(*mut u8)); } } else { (*output).str = mem::transmute(src); @@ -106,15 +107,15 @@ pub extern "C" fn cef_string_utf8_set(src: *const u8, src_len: size_t, output: * #[no_mangle] pub extern "C" fn cef_string_utf8_cmp(a: *const cef_string_utf8_t, b: *const cef_string_utf8_t) -> c_int { unsafe { - slice::raw::buf_as_slice((*a).str as *const u8, (*a).length as uint, |astr:&[u8]| { - slice::raw::buf_as_slice((*b).str as *const u8, (*b).length as uint, |bstr:&[u8]| { - match astr.cmp(bstr) { - Less => -1, - Equal => 0, - Greater => 1 - } - }) - }) + let astr = (*a).str as *const u8; + let bstr = (*b).str as *const u8; + let astr = slice::from_raw_buf(&astr, (*a).length as uint); + let bstr = slice::from_raw_buf(&bstr, (*b).length as uint); + match astr.cmp(bstr) { + Ordering::Less => -1, + Ordering::Equal => 0, + Ordering::Greater => 1 + } } } @@ -130,15 +131,14 @@ pub extern "C" fn cef_string_utf8_to_utf16(src: *const u8, src_len: size_t, outp #[no_mangle] pub extern "C" fn cef_string_utf16_to_utf8(src: *const u16, src_len: size_t, output: *mut cef_string_utf8_t) -> c_int { unsafe { - slice::raw::buf_as_slice(src, src_len as uint, |ustr| { - match string::String::from_utf16(ustr) { - Some(str) => { - cef_string_utf8_set(str.as_bytes().as_ptr(), str.len() as size_t, output, 1); - 1 as c_int - }, - None => 0 as c_int - } - }) + let ustr = slice::from_raw_buf(&src, src_len as uint); + match string::String::from_utf16(ustr) { + Ok(str) => { + cef_string_utf8_set(str.as_bytes().as_ptr(), str.len() as size_t, output, 1); + 1 as c_int + }, + _ => 0 as c_int + } } } @@ -174,7 +174,7 @@ pub extern "C" fn cef_string_utf16_set(src: *const c_ushort, src_len: size_t, ou ptr::copy_memory((*output).str, src, src_len as uint); (*output).length = src_len; - (*output).dtor = Some(string_utf16_dtor); + (*output).dtor = Some(string_utf16_dtor as extern "C" fn(*mut c_ushort)); } } else { (*output).str = mem::transmute(src); @@ -188,15 +188,15 @@ pub extern "C" fn cef_string_utf16_set(src: *const c_ushort, src_len: size_t, ou #[no_mangle] pub extern "C" fn cef_string_utf16_cmp(a: *const cef_string_utf16_t, b: *const cef_string_utf16_t) -> c_int { unsafe { - slice::raw::buf_as_slice(mem::transmute((*a).str), (*a).length as uint, |astr:&[u16]| { - slice::raw::buf_as_slice(mem::transmute((*b).str), (*b).length as uint, |bstr:&[u16]| { - match astr.cmp(bstr) { - Less => -1, - Equal => 0, - Greater => 1 - } - }) - }) + let astr = (*a).str as *const _; + let bstr = (*b).str as *const _; + let astr: &[u16] = slice::from_raw_buf(&astr, (*a).length as uint); + let bstr: &[u16] = slice::from_raw_buf(&bstr, (*b).length as uint); + match astr.cmp(bstr) { + Ordering::Less => -1, + Ordering::Equal => 0, + Ordering::Greater => 1 + } } } @@ -232,7 +232,7 @@ pub extern "C" fn cef_string_wide_set(src: *const wchar_t, src_len: size_t, outp ptr::copy_memory((*output).str, src, src_len as uint); (*output).length = src_len; - (*output).dtor = Some(string_wide_dtor); + (*output).dtor = Some(string_wide_dtor as extern "C" fn(*mut wchar_t)); } } else { (*output).str = mem::transmute(src); @@ -246,15 +246,15 @@ pub extern "C" fn cef_string_wide_set(src: *const wchar_t, src_len: size_t, outp #[no_mangle] pub extern "C" fn cef_string_wide_cmp(a: *const cef_string_wide_t, b: *const cef_string_wide_t) -> c_int { unsafe { - slice::raw::buf_as_slice((*a).str as *const wchar_t, (*a).length as uint, |astr:&[wchar_t]| { - slice::raw::buf_as_slice((*b).str as *const wchar_t, (*b).length as uint, |bstr:&[wchar_t]| { - match astr.cmp(bstr) { - Less => -1, - Equal => 0, - Greater => 1 - } - }) - }) + let astr = (*a).str as *const wchar_t; + let bstr = (*b).str as *const wchar_t; + let astr = slice::from_raw_buf(&astr, (*a).length as uint); + let bstr = slice::from_raw_buf(&bstr, (*b).length as uint); + match astr.cmp(bstr) { + Ordering::Less => -1, + Ordering::Equal => 0, + Ordering::Greater => 1 + } } } @@ -275,10 +275,9 @@ pub extern "C" fn cef_string_wide_to_utf8(src: *const wchar_t, src_len: size_t, return cef_string_utf16_to_utf8(src as *const u16, src_len, output); } unsafe { - slice::raw::buf_as_slice(src, src_len as uint, |ustr| { - let conv = ustr.iter().map(|&c| char::from_u32(c as u32).unwrap_or('\u{FFFD}')).collect::<String>(); - cef_string_utf8_set(conv.as_bytes().as_ptr(), conv.len() as size_t, output, 1) - }) + let ustr = slice::from_raw_buf(&src, src_len as uint); + let conv = ustr.iter().map(|&c| char::from_u32(c as u32).unwrap_or('\u{FFFD}')).collect::<String>(); + cef_string_utf8_set(conv.as_bytes().as_ptr(), conv.len() as size_t, output, 1) } } @@ -293,10 +292,9 @@ pub extern "C" fn cef_string_ascii_to_utf16(src: *const u8, src_len: size_t, out #[no_mangle] pub extern "C" fn cef_string_ascii_to_wide(src: *const u8, src_len: size_t, output: *mut cef_string_wide_t) -> c_int { unsafe { - slice::raw::buf_as_slice(src, src_len as uint, |ustr| { - let conv = ustr.iter().map(|&c| c as u8).collect::<Vec<u8>>(); - cef_string_wide_set(conv.as_ptr() as *const wchar_t, conv.len() as size_t, output, 1) - }) + let ustr = slice::from_raw_buf(&src, src_len as uint); + let conv = ustr.iter().map(|&c| c as u8).collect::<Vec<u8>>(); + cef_string_wide_set(conv.as_ptr() as *const wchar_t, conv.len() as size_t, output, 1) } } diff --git a/ports/cef/string_map.rs b/ports/cef/string_map.rs index 8321244fdc6..048f11484f9 100644 --- a/ports/cef/string_map.rs +++ b/ports/cef/string_map.rs @@ -4,15 +4,15 @@ use eutil::slice_to_str; use libc::{c_int}; -use std::collections::TreeMap; +use std::collections::BTreeMap; use std::mem; use std::string::String; use string::{cef_string_userfree_utf16_alloc, cef_string_userfree_utf16_free}; use string::{cef_string_utf16_set}; use types::{cef_string_map_t, cef_string_t}; -fn string_map_to_treemap(sm: *mut cef_string_map_t) -> *mut TreeMap<String, *mut cef_string_t> { - sm as *mut TreeMap<String, *mut cef_string_t> +fn string_map_to_treemap(sm: *mut cef_string_map_t) -> *mut BTreeMap<String, *mut cef_string_t> { + sm as *mut BTreeMap<String, *mut cef_string_t> } //cef_string_map @@ -20,7 +20,7 @@ fn string_map_to_treemap(sm: *mut cef_string_map_t) -> *mut TreeMap<String, *mut #[no_mangle] pub extern "C" fn cef_string_map_alloc() -> *mut cef_string_map_t { unsafe { - let sm: Box<TreeMap<String, *mut cef_string_t>> = box TreeMap::new(); + let sm: Box<BTreeMap<String, *mut cef_string_t>> = box BTreeMap::new(); mem::transmute(sm) } } @@ -119,7 +119,7 @@ pub extern "C" fn cef_string_map_clear(sm: *mut cef_string_map_t) { pub extern "C" fn cef_string_map_free(sm: *mut cef_string_map_t) { unsafe { if sm.is_null() { return; } - let _v: Box<TreeMap<String, *mut cef_string_t>> = mem::transmute(sm); + let _v: Box<BTreeMap<String, *mut cef_string_t>> = mem::transmute(sm); cef_string_map_clear(sm); } } diff --git a/ports/cef/string_multimap.rs b/ports/cef/string_multimap.rs index 31974d5a95d..1872c36d541 100644 --- a/ports/cef/string_multimap.rs +++ b/ports/cef/string_multimap.rs @@ -4,7 +4,7 @@ use eutil::slice_to_str; use libc::{c_int}; -use std::collections::TreeMap; +use std::collections::BTreeMap; use std::iter::AdditiveIterator; use std::mem; use std::string::String; @@ -12,8 +12,8 @@ use string::{cef_string_userfree_utf16_alloc, cef_string_userfree_utf16_free}; use string::{cef_string_utf16_set}; use types::{cef_string_multimap_t,cef_string_t}; -fn string_multimap_to_treemap(smm: *mut cef_string_multimap_t) -> *mut TreeMap<String, Vec<*mut cef_string_t>> { - smm as *mut TreeMap<String, Vec<*mut cef_string_t>> +fn string_multimap_to_treemap(smm: *mut cef_string_multimap_t) -> *mut BTreeMap<String, Vec<*mut cef_string_t>> { + smm as *mut BTreeMap<String, Vec<*mut cef_string_t>> } //cef_string_multimap @@ -21,7 +21,7 @@ fn string_multimap_to_treemap(smm: *mut cef_string_multimap_t) -> *mut TreeMap<S #[no_mangle] pub extern "C" fn cef_string_multimap_alloc() -> *mut cef_string_multimap_t { unsafe { - let smm: Box<TreeMap<String, Vec<*mut cef_string_t>>> = box TreeMap::new(); + let smm: Box<BTreeMap<String, Vec<*mut cef_string_t>>> = box BTreeMap::new(); mem::transmute(smm) } } @@ -147,7 +147,7 @@ pub extern "C" fn cef_string_multimap_clear(smm: *mut cef_string_multimap_t) { pub extern "C" fn cef_string_multimap_free(smm: *mut cef_string_multimap_t) { unsafe { if smm.is_null() { return; } - let v: Box<TreeMap<String, Vec<*mut cef_string_t>>> = mem::transmute(smm); + let v: Box<BTreeMap<String, Vec<*mut cef_string_t>>> = mem::transmute(smm); cef_string_multimap_clear(smm); drop(v); } diff --git a/ports/cef/stubs.rs b/ports/cef/stubs.rs index 2264bc693c0..52519cfec45 100644 --- a/ports/cef/stubs.rs +++ b/ports/cef/stubs.rs @@ -16,38 +16,38 @@ macro_rules! stub( } } ) -) +); -stub!(cef_add_cross_origin_whitelist_entry) -stub!(cef_add_web_plugin_directory) -stub!(cef_add_web_plugin_path) -stub!(cef_begin_tracing) -stub!(cef_clear_cross_origin_whitelist) -stub!(cef_clear_scheme_handler_factories) -stub!(cef_create_url) -stub!(cef_end_tracing) -stub!(cef_force_web_plugin_shutdown) -stub!(cef_get_current_platform_thread_handle) -stub!(cef_get_current_platform_thread_id) -stub!(cef_get_extensions_for_mime_type) -stub!(cef_get_geolocation) -stub!(cef_get_mime_type) -stub!(cef_get_path) -stub!(cef_is_web_plugin_unstable) -stub!(cef_launch_process) -stub!(cef_now_from_system_trace_time) -stub!(cef_parse_url) -stub!(cef_post_delayed_task) -stub!(cef_post_task) -stub!(cef_refresh_web_plugins) -stub!(cef_register_extension) -stub!(cef_register_scheme_handler_factory) -stub!(cef_register_web_plugin_crash) -stub!(cef_remove_cross_origin_whitelist_entry) -stub!(cef_remove_web_plugin_path) -stub!(cef_set_osmodal_loop) -stub!(cef_string_utf16_to_wide) -stub!(cef_string_wide_to_utf16) -stub!(cef_unregister_internal_web_plugin) -stub!(cef_visit_web_plugin_info) +stub!(cef_add_cross_origin_whitelist_entry); +stub!(cef_add_web_plugin_directory); +stub!(cef_add_web_plugin_path); +stub!(cef_begin_tracing); +stub!(cef_clear_cross_origin_whitelist); +stub!(cef_clear_scheme_handler_factories); +stub!(cef_create_url); +stub!(cef_end_tracing); +stub!(cef_force_web_plugin_shutdown); +stub!(cef_get_current_platform_thread_handle); +stub!(cef_get_current_platform_thread_id); +stub!(cef_get_extensions_for_mime_type); +stub!(cef_get_geolocation); +stub!(cef_get_mime_type); +stub!(cef_get_path); +stub!(cef_is_web_plugin_unstable); +stub!(cef_launch_process); +stub!(cef_now_from_system_trace_time); +stub!(cef_parse_url); +stub!(cef_post_delayed_task); +stub!(cef_post_task); +stub!(cef_refresh_web_plugins); +stub!(cef_register_extension); +stub!(cef_register_scheme_handler_factory); +stub!(cef_register_web_plugin_crash); +stub!(cef_remove_cross_origin_whitelist_entry); +stub!(cef_remove_web_plugin_path); +stub!(cef_set_osmodal_loop); +stub!(cef_string_utf16_to_wide); +stub!(cef_string_wide_to_utf16); +stub!(cef_unregister_internal_web_plugin); +stub!(cef_visit_web_plugin_info); diff --git a/ports/cef/task.rs b/ports/cef/task.rs index b6a43ca7481..edf04243dd4 100644 --- a/ports/cef/task.rs +++ b/ports/cef/task.rs @@ -14,7 +14,7 @@ pub extern "C" fn cef_currently_on(_tid: cef_thread_id_t) -> c_int { } cef_stub_static_method_impls! { - fn cef_task_runner_get_for_current_thread() -> *mut cef_task_runner_t; - fn cef_task_runner_get_for_thread(thread_id: cef_thread_id_t) -> *mut cef_task_runner_t; + fn cef_task_runner_get_for_current_thread() -> *mut cef_task_runner_t + fn cef_task_runner_get_for_thread(thread_id: cef_thread_id_t) -> *mut cef_task_runner_t } diff --git a/ports/cef/v8.rs b/ports/cef/v8.rs index e8e5996a100..48b139ccda6 100644 --- a/ports/cef/v8.rs +++ b/ports/cef/v8.rs @@ -9,21 +9,21 @@ use types::{cef_string_t, cef_time_t}; use libc::{mod, c_double, c_int}; cef_stub_static_method_impls! { - fn cef_v8context_get_current_context() -> *mut cef_v8context_t; - fn cef_v8context_get_entered_context() -> *mut cef_v8context_t; - fn cef_v8context_in_context() -> libc::c_int; - fn cef_v8value_create_undefined() -> *mut cef_v8value_t; - fn cef_v8value_create_null() -> *mut cef_v8value_t; - fn cef_v8value_create_bool(_value: c_int) -> *mut cef_v8value_t; - fn cef_v8value_create_int(_value: i32) -> *mut cef_v8value_t; - fn cef_v8value_create_uint(_value: u32) -> *mut cef_v8value_t; - fn cef_v8value_create_double(_value: c_double) -> *mut cef_v8value_t; - fn cef_v8value_create_date(_date: *const cef_time_t) -> *mut cef_v8value_t; - fn cef_v8value_create_string(_value: *const cef_string_t) -> *mut cef_v8value_t; - fn cef_v8value_create_object(_accessor: *mut cef_v8accessor_t) -> *mut cef_v8value_t; - fn cef_v8value_create_array(_length: libc::c_int) -> *mut cef_v8value_t; + fn cef_v8context_get_current_context() -> *mut cef_v8context_t + fn cef_v8context_get_entered_context() -> *mut cef_v8context_t + fn cef_v8context_in_context() -> libc::c_int + fn cef_v8value_create_undefined() -> *mut cef_v8value_t + fn cef_v8value_create_null() -> *mut cef_v8value_t + fn cef_v8value_create_bool(_value: c_int) -> *mut cef_v8value_t + fn cef_v8value_create_int(_value: i32) -> *mut cef_v8value_t + fn cef_v8value_create_uint(_value: u32) -> *mut cef_v8value_t + fn cef_v8value_create_double(_value: c_double) -> *mut cef_v8value_t + fn cef_v8value_create_date(_date: *const cef_time_t) -> *mut cef_v8value_t + fn cef_v8value_create_string(_value: *const cef_string_t) -> *mut cef_v8value_t + fn cef_v8value_create_object(_accessor: *mut cef_v8accessor_t) -> *mut cef_v8value_t + fn cef_v8value_create_array(_length: libc::c_int) -> *mut cef_v8value_t fn cef_v8value_create_function(_name: *const cef_string_t, _handler: *mut cef_v8handler_t) - -> *mut cef_v8value_t; - fn cef_v8stack_trace_get_current(_frame_limit: libc::c_int) -> *mut cef_v8stack_trace_t; + -> *mut cef_v8value_t + fn cef_v8stack_trace_get_current(_frame_limit: libc::c_int) -> *mut cef_v8stack_trace_t } diff --git a/ports/cef/values.rs b/ports/cef/values.rs index 81a0e60a3d0..29ad0b6dfdc 100644 --- a/ports/cef/values.rs +++ b/ports/cef/values.rs @@ -7,8 +7,8 @@ use interfaces::{cef_binary_value_t, cef_dictionary_value_t, cef_list_value_t}; use libc; cef_stub_static_method_impls! { - fn cef_binary_value_create(_data: *const (), _size: libc::size_t) -> *mut cef_binary_value_t; - fn cef_dictionary_value_create() -> *mut cef_dictionary_value_t; - fn cef_list_value_create() -> *mut cef_list_value_t; + fn cef_binary_value_create(_data: *const (), _size: libc::size_t) -> *mut cef_binary_value_t + fn cef_dictionary_value_create() -> *mut cef_dictionary_value_t + fn cef_list_value_create() -> *mut cef_list_value_t } diff --git a/ports/cef/window.rs b/ports/cef/window.rs index 25901c95ebf..a4e4ebca08f 100644 --- a/ports/cef/window.rs +++ b/ports/cef/window.rs @@ -27,13 +27,15 @@ use servo_msg::constellation_msg::LoadData; use servo_util::cursor::Cursor; use servo_util::geometry::ScreenPx; use std::cell::RefCell; +use std::ffi::CString; use std::rc::Rc; +use std::sync::mpsc::{Sender, channel}; #[cfg(target_os="macos")] use std::ptr; /// The type of an off-screen window. -#[deriving(Clone)] +#[derive(Clone)] pub struct Window { cef_browser: RefCell<Option<CefBrowser>>, } @@ -48,7 +50,7 @@ fn load_gl() { gl::load_with(|s| { unsafe { - let c_str = s.to_c_str(); + let c_str = CString::from_slice(s.as_bytes()); dlsym(RTLD_DEFAULT, c_str.as_ptr()) as *const c_void } }); @@ -62,7 +64,7 @@ fn load_gl() { gl::load_with(|s| { unsafe { - let c_str = s.to_c_str(); + let c_str = CString::from_slice(s.as_bytes()); glXGetProcAddress(c_str.as_ptr()) as *const c_void } }); @@ -126,7 +128,7 @@ impl Window { } impl WindowMethods for Window { - fn framebuffer_size(&self) -> TypedSize2D<DevicePixel,uint> { + fn framebuffer_size(&self) -> TypedSize2D<DevicePixel,u32> { let browser = self.cef_browser.borrow(); match *browser { None => TypedSize2D(400, 300), @@ -136,7 +138,7 @@ impl WindowMethods for Window { .get_client() .get_render_handler() .get_backing_rect((*browser).clone(), &mut rect); - TypedSize2D(rect.width as uint, rect.height as uint) + TypedSize2D(rect.width as u32, rect.height as u32) } } } @@ -274,8 +276,8 @@ impl WindowMethods for Window { let frame = frame.downcast(); let mut title_visitor = frame.title_visitor.borrow_mut(); match &mut *title_visitor { - &None => {} - &Some(ref mut visitor) => { + &mut None => {} + &mut Some(ref mut visitor) => { match string { None => visitor.visit(&[]), Some(string) => { diff --git a/ports/cef/wrappers.rs b/ports/cef/wrappers.rs index 8c650dad1dd..caaacaba29a 100644 --- a/ports/cef/wrappers.rs +++ b/ports/cef/wrappers.rs @@ -51,7 +51,7 @@ macro_rules! cef_noop_wrapper( } } ) -) +); macro_rules! cef_pointer_wrapper( ($ty:ty) => ( @@ -71,10 +71,10 @@ macro_rules! cef_pointer_wrapper( mem::transmute::<*mut $ty,&'a mut $ty>(c_object) } } - cef_noop_wrapper!(*const $ty) - cef_noop_wrapper!(*mut $ty) + cef_noop_wrapper!(*const $ty); + cef_noop_wrapper!(*mut $ty); ) -) +); macro_rules! cef_unimplemented_wrapper( ($c_type:ty, $rust_type:ty) => ( @@ -87,95 +87,95 @@ macro_rules! cef_unimplemented_wrapper( } } ) -) +); -cef_pointer_wrapper!(()) -cef_pointer_wrapper!(*mut ()) -cef_pointer_wrapper!(*mut c_void) -cef_pointer_wrapper!(c_void) -cef_pointer_wrapper!(cef_base_t) -cef_pointer_wrapper!(cef_browser_settings_t) -cef_pointer_wrapper!(cef_cookie_t) -cef_pointer_wrapper!(cef_geoposition_t) -cef_pointer_wrapper!(cef_key_event) -cef_pointer_wrapper!(cef_mouse_event) -cef_pointer_wrapper!(cef_page_range_t) -cef_pointer_wrapper!(cef_point_t) -cef_pointer_wrapper!(cef_popup_features_t) -cef_pointer_wrapper!(cef_rect_t) -cef_pointer_wrapper!(cef_screen_info_t) -cef_pointer_wrapper!(cef_size_t) -cef_pointer_wrapper!(cef_time_t) -cef_pointer_wrapper!(cef_window_info_t) -cef_pointer_wrapper!(i32) -cef_pointer_wrapper!(i64) -cef_pointer_wrapper!(u32) -cef_pointer_wrapper!(u64) +cef_pointer_wrapper!(()); +cef_pointer_wrapper!(*mut ()); +cef_pointer_wrapper!(*mut c_void); +cef_pointer_wrapper!(c_void); +cef_pointer_wrapper!(cef_base_t); +cef_pointer_wrapper!(cef_browser_settings_t); +cef_pointer_wrapper!(cef_cookie_t); +cef_pointer_wrapper!(cef_geoposition_t); +cef_pointer_wrapper!(cef_key_event); +cef_pointer_wrapper!(cef_mouse_event); +cef_pointer_wrapper!(cef_page_range_t); +cef_pointer_wrapper!(cef_point_t); +cef_pointer_wrapper!(cef_popup_features_t); +cef_pointer_wrapper!(cef_rect_t); +cef_pointer_wrapper!(cef_screen_info_t); +cef_pointer_wrapper!(cef_size_t); +cef_pointer_wrapper!(cef_time_t); +cef_pointer_wrapper!(cef_window_info_t); +cef_pointer_wrapper!(i32); +cef_pointer_wrapper!(i64); +cef_pointer_wrapper!(u32); +cef_pointer_wrapper!(u64); -cef_noop_wrapper!(()) -cef_noop_wrapper!(*const cef_geolocation_handler_t) -cef_noop_wrapper!(*const cef_string_utf16) -cef_noop_wrapper!(*mut cef_context_menu_handler_t) -cef_noop_wrapper!(*mut cef_dialog_handler_t) -cef_noop_wrapper!(*mut cef_download_handler_t) -cef_noop_wrapper!(*mut cef_drag_data_t) -cef_noop_wrapper!(*mut cef_drag_handler_t) -cef_noop_wrapper!(*mut cef_event_handle_t) -cef_noop_wrapper!(*mut cef_focus_handler_t) -cef_noop_wrapper!(*mut cef_geolocation_handler_t) -cef_noop_wrapper!(*mut cef_jsdialog_handler_t) -cef_noop_wrapper!(*mut cef_keyboard_handler_t) -cef_noop_wrapper!(*mut cef_load_handler_t) -cef_noop_wrapper!(*mut cef_request_handler_t) -cef_noop_wrapper!(*mut cef_string_list_t) -cef_noop_wrapper!(*mut cef_string_utf16) -cef_noop_wrapper!(c_int) -cef_noop_wrapper!(cef_color_model_t) -cef_noop_wrapper!(cef_context_menu_edit_state_flags_t) -cef_noop_wrapper!(cef_context_menu_media_state_flags_t) -cef_noop_wrapper!(cef_context_menu_media_type_t) -cef_noop_wrapper!(cef_context_menu_type_flags_t) -cef_noop_wrapper!(cef_dom_document_type_t) -cef_noop_wrapper!(cef_dom_node_type_t) -cef_noop_wrapper!(cef_drag_operations_mask_t) -cef_noop_wrapper!(cef_duplex_mode_t) -cef_noop_wrapper!(cef_errorcode_t) -cef_noop_wrapper!(cef_event_flags_t) -cef_noop_wrapper!(cef_event_handle_t) -cef_noop_wrapper!(cef_file_dialog_mode_t) -cef_noop_wrapper!(cef_focus_source_t) -cef_noop_wrapper!(cef_jsdialog_handler_t) -cef_noop_wrapper!(cef_jsdialog_type_t) -cef_noop_wrapper!(cef_key_event) -cef_noop_wrapper!(cef_menu_item_type_t) -cef_noop_wrapper!(cef_mouse_button_type_t) -cef_noop_wrapper!(cef_navigation_type_t) -cef_noop_wrapper!(cef_paint_element_type_t) -cef_noop_wrapper!(cef_postdataelement_type_t) -cef_noop_wrapper!(cef_process_id_t) -cef_noop_wrapper!(cef_resource_type_t) -cef_noop_wrapper!(cef_termination_status_t) -cef_noop_wrapper!(cef_text_input_context_t) -cef_noop_wrapper!(cef_thread_id_t) -cef_noop_wrapper!(cef_time_t) -cef_noop_wrapper!(cef_transition_type_t) -cef_noop_wrapper!(cef_urlrequest_status_t) -cef_noop_wrapper!(cef_v8_accesscontrol_t) -cef_noop_wrapper!(cef_v8_propertyattribute_t) -cef_noop_wrapper!(cef_value_type_t) -cef_noop_wrapper!(cef_xml_encoding_type_t) -cef_noop_wrapper!(cef_xml_node_type_t) -cef_noop_wrapper!(f64) -cef_noop_wrapper!(i64) -cef_noop_wrapper!(u32) -cef_noop_wrapper!(u64) +cef_noop_wrapper!(()); +cef_noop_wrapper!(*const cef_geolocation_handler_t); +cef_noop_wrapper!(*const cef_string_utf16); +cef_noop_wrapper!(*mut cef_context_menu_handler_t); +cef_noop_wrapper!(*mut cef_dialog_handler_t); +cef_noop_wrapper!(*mut cef_download_handler_t); +cef_noop_wrapper!(*mut cef_drag_data_t); +cef_noop_wrapper!(*mut cef_drag_handler_t); +cef_noop_wrapper!(*mut cef_event_handle_t); +cef_noop_wrapper!(*mut cef_focus_handler_t); +cef_noop_wrapper!(*mut cef_geolocation_handler_t); +cef_noop_wrapper!(*mut cef_jsdialog_handler_t); +cef_noop_wrapper!(*mut cef_keyboard_handler_t); +cef_noop_wrapper!(*mut cef_load_handler_t); +cef_noop_wrapper!(*mut cef_request_handler_t); +cef_noop_wrapper!(*mut cef_string_list_t); +cef_noop_wrapper!(*mut cef_string_utf16); +cef_noop_wrapper!(c_int); +cef_noop_wrapper!(cef_color_model_t); +cef_noop_wrapper!(cef_context_menu_edit_state_flags_t); +cef_noop_wrapper!(cef_context_menu_media_state_flags_t); +cef_noop_wrapper!(cef_context_menu_media_type_t); +cef_noop_wrapper!(cef_context_menu_type_flags_t); +cef_noop_wrapper!(cef_dom_document_type_t); +cef_noop_wrapper!(cef_dom_node_type_t); +cef_noop_wrapper!(cef_drag_operations_mask_t); +cef_noop_wrapper!(cef_duplex_mode_t); +cef_noop_wrapper!(cef_errorcode_t); +cef_noop_wrapper!(cef_event_flags_t); +cef_noop_wrapper!(cef_event_handle_t); +cef_noop_wrapper!(cef_file_dialog_mode_t); +cef_noop_wrapper!(cef_focus_source_t); +cef_noop_wrapper!(cef_jsdialog_handler_t); +cef_noop_wrapper!(cef_jsdialog_type_t); +cef_noop_wrapper!(cef_key_event); +cef_noop_wrapper!(cef_menu_item_type_t); +cef_noop_wrapper!(cef_mouse_button_type_t); +cef_noop_wrapper!(cef_navigation_type_t); +cef_noop_wrapper!(cef_paint_element_type_t); +cef_noop_wrapper!(cef_postdataelement_type_t); +cef_noop_wrapper!(cef_process_id_t); +cef_noop_wrapper!(cef_resource_type_t); +cef_noop_wrapper!(cef_termination_status_t); +cef_noop_wrapper!(cef_text_input_context_t); +cef_noop_wrapper!(cef_thread_id_t); +cef_noop_wrapper!(cef_time_t); +cef_noop_wrapper!(cef_transition_type_t); +cef_noop_wrapper!(cef_urlrequest_status_t); +cef_noop_wrapper!(cef_v8_accesscontrol_t); +cef_noop_wrapper!(cef_v8_propertyattribute_t); +cef_noop_wrapper!(cef_value_type_t); +cef_noop_wrapper!(cef_xml_encoding_type_t); +cef_noop_wrapper!(cef_xml_node_type_t); +cef_noop_wrapper!(f64); +cef_noop_wrapper!(i64); +cef_noop_wrapper!(u32); +cef_noop_wrapper!(u64); -cef_unimplemented_wrapper!(*const *mut cef_v8value_t, *const CefV8Value) -cef_unimplemented_wrapper!(*mut *mut cef_post_data_element_t, *mut CefPostDataElement) -cef_unimplemented_wrapper!(cef_string_list_t, Vec<String>) -cef_unimplemented_wrapper!(cef_string_map_t, HashMap<String,String>) -cef_unimplemented_wrapper!(cef_string_multimap_t, HashMap<String,Vec<String>>) -cef_unimplemented_wrapper!(cef_string_t, String) +cef_unimplemented_wrapper!(*const *mut cef_v8value_t, *const CefV8Value); +cef_unimplemented_wrapper!(*mut *mut cef_post_data_element_t, *mut CefPostDataElement); +cef_unimplemented_wrapper!(cef_string_list_t, Vec<String>); +cef_unimplemented_wrapper!(cef_string_map_t, HashMap<String,String>); +cef_unimplemented_wrapper!(cef_string_multimap_t, HashMap<String,Vec<String>>); +cef_unimplemented_wrapper!(cef_string_t, String); impl<'a> CefWrap<*const cef_string_t> for &'a [u16] { fn to_c(buffer: &'a [u16]) -> *const cef_string_t { @@ -189,7 +189,7 @@ impl<'a> CefWrap<*const cef_string_t> for &'a [u16] { let boxed_string = box cef_string_utf16 { str: ptr, length: buffer.len() as u64, - dtor: Some(free_boxed_utf16_string), + dtor: Some(free_boxed_utf16_string as extern "C" fn(*mut c_ushort)), }; let result: *const cef_string_utf16 = &*boxed_string; mem::forget(boxed_string); @@ -255,7 +255,7 @@ impl<'a> CefWrap<cef_string_userfree_t> for String { *mut cef_string_utf16; ptr::write(&mut (*boxed_string).str, buffer); ptr::write(&mut (*boxed_string).length, utf16_chars.len() as u64); - ptr::write(&mut (*boxed_string).dtor, Some(free_utf16_buffer)); + ptr::write(&mut (*boxed_string).dtor, Some(free_utf16_buffer as extern "C" fn(*mut c_ushort))); mem::forget(utf16_chars); } boxed_string @@ -278,7 +278,7 @@ pub struct Utf16Encoder<I> { } impl<I> Utf16Encoder<I> { - pub fn new(chars: I) -> Utf16Encoder<I> where I: Iterator<char> { + pub fn new(chars: I) -> Utf16Encoder<I> where I: Iterator<Item=char> { Utf16Encoder { chars: chars, extra: 0, @@ -286,13 +286,14 @@ impl<I> Utf16Encoder<I> { } } -impl<I> Iterator<u16> for Utf16Encoder<I> where I: Iterator<char> { +impl<I> Iterator for Utf16Encoder<I> where I: Iterator<Item=char> { + type Item = u16; fn next(&mut self) -> Option<u16> { if self.extra != 0 { return Some(mem::replace(&mut self.extra, 0)) } - let mut buf = [0u16, ..2]; + let mut buf = [0u16; 2]; self.chars.next().map(|ch| { let n = ch.encode_utf16(buf.as_mut_slice()).unwrap_or(0); if n == 2 { @@ -305,10 +306,10 @@ impl<I> Iterator<u16> for Utf16Encoder<I> where I: Iterator<char> { impl<'a> CefWrap<cef_string_t> for &'a mut String { fn to_c(_: &'a mut String) -> cef_string_t { - panic!("unimplemented CEF type conversion: &'a mut String") + panic!("unimplemented CEF type conversion: &'a mut String"); } unsafe fn to_rust(_: cef_string_t) -> &'a mut String { - panic!("unimplemented CEF type conversion: cef_string_t") + panic!("unimplemented CEF type conversion: cef_string_t"); } } diff --git a/ports/cef/xml_reader.rs b/ports/cef/xml_reader.rs index e80698db8ef..2b758a96a08 100644 --- a/ports/cef/xml_reader.rs +++ b/ports/cef/xml_reader.rs @@ -9,6 +9,6 @@ cef_stub_static_method_impls! { fn cef_xml_reader_create(stream: *mut cef_stream_reader_t, encoding_type: cef_xml_encoding_type_t, uri: *const cef_string_t) - -> *mut cef_xml_reader_t; + -> *mut cef_xml_reader_t } diff --git a/ports/cef/zip_reader.rs b/ports/cef/zip_reader.rs index 2603f6b2383..0b8793122f5 100644 --- a/ports/cef/zip_reader.rs +++ b/ports/cef/zip_reader.rs @@ -5,6 +5,6 @@ use interfaces::{cef_stream_reader_t, cef_zip_reader_t}; cef_stub_static_method_impls! { - fn cef_zip_reader_create(stream: *mut cef_stream_reader_t) -> *mut cef_zip_reader_t; + fn cef_zip_reader_create(stream: *mut cef_stream_reader_t) -> *mut cef_zip_reader_t } diff --git a/ports/glfw/Cargo.toml b/ports/glfw/Cargo.toml index b77d2ca306a..a89db4276c4 100644 --- a/ports/glfw/Cargo.toml +++ b/ports/glfw/Cargo.toml @@ -32,5 +32,5 @@ git = "https://github.com/servo/rust-cgl" [dependencies.gleam] git = "https://github.com/servo/gleam" -[dependencies.time] -git = "https://github.com/rust-lang/time" +[dependencies] +time = "*"
\ No newline at end of file diff --git a/ports/glutin/Cargo.toml b/ports/glutin/Cargo.toml index 57d89f5949b..ccfdb761f76 100644 --- a/ports/glutin/Cargo.toml +++ b/ports/glutin/Cargo.toml @@ -7,6 +7,10 @@ authors = ["The Servo Project Developers"] name = "glutin_app" path = "lib.rs" +[features] +window = ["glutin/window"] +headless = ["glutin/headless"] + [dependencies.compositing] path = "../../components/compositing" @@ -23,9 +27,7 @@ path = "../../components/msg" path = "../../components/util" [dependencies.glutin] -git = "https://github.com/servo/glutin" -branch = "servo" -features = ["window", "headless"] +git = "https://github.com/tomaka/glutin" [dependencies.gleam] git = "https://github.com/servo/gleam" @@ -33,5 +35,8 @@ git = "https://github.com/servo/gleam" [dependencies.cgl] git = "https://github.com/servo/rust-cgl" -[dependencies.time] -git = "https://github.com/rust-lang/time" +[dependencies.egl] +git = "https://github.com/servo/rust-egl" + +[dependencies] +time = "*" diff --git a/ports/glutin/lib.rs b/ports/glutin/lib.rs index 1e1aca93602..d47a8fb22e5 100644 --- a/ports/glutin/lib.rs +++ b/ports/glutin/lib.rs @@ -4,7 +4,7 @@ //! A simple application that uses GLFW to open a window for Servo to display in. -#![feature(macro_rules)] +#![feature(box_syntax, int_uint)] #![deny(unused_imports, unused_variables)] #[cfg(target_os="macos")] @@ -40,5 +40,5 @@ pub fn create_window() -> Rc<Window> { let size = opts.initial_window_size.as_f32() * scale_factor; // Open a window. - Window::new(foreground, size.as_uint(), opts.render_api) + Window::new(foreground, size.as_uint().cast().unwrap()) } diff --git a/ports/glutin/window.rs b/ports/glutin/window.rs index 52d404f7e87..80261c3c33b 100644 --- a/ports/glutin/window.rs +++ b/ports/glutin/window.rs @@ -5,59 +5,49 @@ //! A windowing implementation using glutin. use compositing::compositor_task::{mod, CompositorProxy, CompositorReceiver}; -use compositing::windowing::WindowNavigateMsg; -use compositing::windowing::{MouseWindowEvent, WindowEvent, WindowMethods}; -use geom::point::{Point2D, TypedPoint2D}; +use compositing::windowing::{WindowEvent, WindowMethods}; use geom::scale_factor::ScaleFactor; use geom::size::TypedSize2D; +use gleam::gl; +use glutin; use layers::geometry::DevicePixel; use layers::platform::surface::NativeGraphicsMetadata; use msg::constellation_msg; -use msg::constellation_msg::{Key, KeyState, CONTROL, SHIFT, ALT}; +use msg::constellation_msg::Key; use msg::compositor_msg::{PaintState, ReadyState}; use msg::constellation_msg::LoadData; +use NestedEventLoopListener; +use std::rc::Rc; +use std::sync::mpsc::{channel, Sender}; +use util::cursor::Cursor; +use util::geometry::ScreenPx; + +#[cfg(feature = "window")] +use compositing::windowing::{MouseWindowEvent, WindowNavigateMsg}; +#[cfg(feature = "window")] +use geom::point::{Point2D, TypedPoint2D}; +#[cfg(feature = "window")] +use glutin::{ElementState, Event, MouseButton, VirtualKeyCode}; +#[cfg(feature = "window")] +use msg::constellation_msg::{KeyState, CONTROL, SHIFT, ALT}; +#[cfg(feature = "window")] use std::cell::{Cell, RefCell}; +#[cfg(feature = "window")] use std::num::Float; -use std::rc::Rc; +#[cfg(feature = "window")] use time::{mod, Timespec}; -use util::geometry::ScreenPx; +#[cfg(feature = "window")] use util::opts; -use util::opts::RenderApi; -use gleam::gl; -use glutin; -use glutin::{ElementState, Event, MouseButton, VirtualKeyCode}; -use NestedEventLoopListener; -use util::cursor::Cursor; -#[cfg(target_os="linux")] +#[cfg(all(feature = "headless", target_os="linux"))] use std::ptr; -struct HeadlessContext { - #[allow(dead_code)] - context: glutin::HeadlessContext, - size: TypedSize2D<DevicePixel, uint>, -} - -enum WindowHandle { - Windowed(glutin::Window), - Headless(HeadlessContext), -} - +#[cfg(feature = "window")] static mut g_nested_event_loop_listener: Option<*mut (NestedEventLoopListener + 'static)> = None; -fn nested_window_resize(width: uint, height: uint) { - unsafe { - match g_nested_event_loop_listener { - None => {} - Some(listener) => { - (*listener).handle_event_from_nested_event_loop(WindowEvent::Resize(TypedSize2D(width, height))); - } - } - } -} - -bitflags!( - #[deriving(Show, Copy)] +#[cfg(feature = "window")] +bitflags! { + #[derive(Show)] flags KeyModifiers: u8 { const LEFT_CONTROL = 1, const RIGHT_CONTROL = 2, @@ -66,17 +56,18 @@ bitflags!( const LEFT_ALT = 16, const RIGHT_ALT = 32, } -) +} /// The type of a window. +#[cfg(feature = "window")] pub struct Window { - glutin: WindowHandle, + window: glutin::Window, mouse_down_button: Cell<Option<glutin::MouseButton>>, - mouse_down_point: Cell<Point2D<int>>, + mouse_down_point: Cell<Point2D<i32>>, event_queue: RefCell<Vec<WindowEvent>>, - mouse_pos: Cell<Point2D<int>>, + mouse_pos: Cell<Point2D<i32>>, ready_state: Cell<ReadyState>, paint_state: Cell<PaintState>, key_modifiers: Cell<KeyModifiers>, @@ -84,67 +75,24 @@ pub struct Window { last_title_set_time: Cell<Timespec>, } -#[cfg(not(target_os="android"))] -fn load_gl_functions(glutin: &WindowHandle) { - match glutin { - &WindowHandle::Windowed(ref window) => gl::load_with(|s| window.get_proc_address(s)), - &WindowHandle::Headless(ref headless) => gl::load_with(|s| headless.context.get_proc_address(s)), - } -} - -#[cfg(target_os="android")] -fn load_gl_functions(_glutin: &WindowHandle) { -} - -#[cfg(not(target_os="android"))] -fn gl_version() -> (uint, uint) { - (3, 0) -} - -#[cfg(target_os="android")] -fn gl_version() -> (uint, uint) { - (2, 0) -} - +#[cfg(feature = "window")] impl Window { - /// Creates a new window. - pub fn new(is_foreground: bool, size: TypedSize2D<DevicePixel, uint>, render_api: RenderApi) - -> Rc<Window> { - - // Create the glutin window. - let window_size = size.to_untyped(); - - let glutin = match render_api { - RenderApi::OpenGL => { - let mut glutin_window = glutin::WindowBuilder::new() - .with_title("Servo [glutin]".to_string()) - .with_dimensions(window_size.width, window_size.height) - .with_gl_version(gl_version()) - .with_visibility(is_foreground) - .build() - .unwrap(); - unsafe { glutin_window.make_current() }; - - glutin_window.set_window_resize_callback(Some(nested_window_resize)); - WindowHandle::Windowed(glutin_window) - } - RenderApi::Mesa => { - let headless_builder = glutin::HeadlessRendererBuilder::new(window_size.width, - window_size.height); - let headless_context = headless_builder.build().unwrap(); - unsafe { headless_context.make_current() }; - - WindowHandle::Headless(HeadlessContext { - context: headless_context, - size: size, - }) - } - }; + pub fn new(is_foreground: bool, window_size: TypedSize2D<DevicePixel, u32>) -> Rc<Window> { + let mut glutin_window = glutin::WindowBuilder::new() + .with_title("Servo [glutin]".to_string()) + .with_dimensions(window_size.to_untyped().width, window_size.to_untyped().height) + .with_gl_version(Window::gl_version()) + .with_visibility(is_foreground) + .build() + .unwrap(); + unsafe { glutin_window.make_current() }; - load_gl_functions(&glutin); + glutin_window.set_window_resize_callback(Some(Window::nested_window_resize as fn(u32, u32))); + + Window::load_gl_functions(&glutin_window); let window = Window { - glutin: glutin, + window: glutin_window, event_queue: RefCell::new(vec!()), mouse_down_button: Cell::new(None), mouse_down_point: Cell::new(Point2D(0, 0)), @@ -164,303 +112,37 @@ impl Window { Rc::new(window) } -} - -impl WindowMethods for Window { - /// Returns the size of the window in hardware pixels. - fn framebuffer_size(&self) -> TypedSize2D<DevicePixel, uint> { - let (width, height) = match self.glutin { - WindowHandle::Windowed(ref window) => { - let scale_factor = window.hidpi_factor() as uint; - let (width, height) = window.get_inner_size().unwrap(); - Some((width * scale_factor, height * scale_factor)) - } - WindowHandle::Headless(ref context) => Some((context.size.to_untyped().width, - context.size.to_untyped().height)), - }.unwrap(); - TypedSize2D(width as uint, height as uint) - } - - /// Returns the size of the window in density-independent "px" units. - fn size(&self) -> TypedSize2D<ScreenPx, f32> { - // TODO: Handle hidpi - let (width, height) = match self.glutin { - WindowHandle::Windowed(ref window) => window.get_inner_size(), - WindowHandle::Headless(ref context) => Some((context.size.to_untyped().width, - context.size.to_untyped().height)), - }.unwrap(); - TypedSize2D(width as f32, height as f32) - } - - /// Presents the window to the screen (perhaps by page flipping). - fn present(&self) { - match self.glutin { - WindowHandle::Windowed(ref window) => window.swap_buffers(), - WindowHandle::Headless(_) => {}, - } - } - - fn create_compositor_channel(window: &Option<Rc<Window>>) - -> (Box<CompositorProxy+Send>, Box<CompositorReceiver>) { - let (sender, receiver) = channel(); - - let window_proxy = match window { - &Some(ref window) => { - match window.glutin { - WindowHandle::Windowed(ref window) => Some(window.create_window_proxy()), - WindowHandle::Headless(_) => None, - } - } - &None => None, - }; - - (box GlutinCompositorProxy { - sender: sender, - window_proxy: window_proxy, - } as Box<CompositorProxy+Send>, - box receiver as Box<CompositorReceiver>) - } - - /// Sets the ready state. - fn set_ready_state(&self, ready_state: ReadyState) { - self.ready_state.set(ready_state); - self.update_window_title() - } - - /// Sets the paint state. - fn set_paint_state(&self, paint_state: PaintState) { - self.paint_state.set(paint_state); - self.update_window_title() - } - - fn hidpi_factor(&self) -> ScaleFactor<ScreenPx, DevicePixel, f32> { - match self.glutin { - WindowHandle::Windowed(ref window) => ScaleFactor(window.hidpi_factor()), - WindowHandle::Headless(_) => ScaleFactor(1.0), - } - } - - fn set_page_title(&self, _: Option<String>) { - // TODO(gw) - } - - fn set_page_load_data(&self, _: LoadData) { - // TODO(gw) - } - - fn load_end(&self) { - // TODO(gw) - } - - fn set_cursor(&self, _: Cursor) { - // No-op. We could take over mouse handling ourselves and draw the cursor as an extra - // layer with our own custom bitmaps or something, but it doesn't seem worth the - // trouble. - } - fn prepare_for_composite(&self) -> bool { - true - } - - #[cfg(target_os="linux")] - fn native_metadata(&self) -> NativeGraphicsMetadata { - match self.glutin { - WindowHandle::Windowed(ref window) => { - NativeGraphicsMetadata { - display: unsafe { window.platform_display() } + fn nested_window_resize(width: u32, height: u32) { + unsafe { + match g_nested_event_loop_listener { + None => {} + Some(listener) => { + (*listener).handle_event_from_nested_event_loop(WindowEvent::Resize(TypedSize2D(width, height))); } } - WindowHandle::Headless(_) => { - NativeGraphicsMetadata { - display: ptr::null_mut() - } - }, } } - #[cfg(target_os="macos")] - fn native_metadata(&self) -> NativeGraphicsMetadata { - use cgl::{CGLGetCurrentContext, CGLGetPixelFormat}; - unsafe { - NativeGraphicsMetadata { - pixel_format: CGLGetPixelFormat(CGLGetCurrentContext()), - } - } + #[cfg(not(target_os="android"))] + fn gl_version() -> (u32, u32) { + (3, 0) } #[cfg(target_os="android")] - fn native_metadata(&self) -> NativeGraphicsMetadata { - use egl::egl::GetCurrentDisplay; - NativeGraphicsMetadata { - display: GetCurrentDisplay(), - } - } - - /// Helper function to handle keyboard events. - fn handle_key(&self, key: Key, mods: constellation_msg::KeyModifiers) { - match key { - Key::Equal if mods.contains(CONTROL) => { // Ctrl-+ - self.event_queue.borrow_mut().push(WindowEvent::Zoom(1.1)); - } - Key::Minus if mods.contains(CONTROL) => { // Ctrl-- - self.event_queue.borrow_mut().push(WindowEvent::Zoom(1.0/1.1)); - } - Key::Backspace if mods.contains(SHIFT) => { // Shift-Backspace - self.event_queue.borrow_mut().push(WindowEvent::Navigation(WindowNavigateMsg::Forward)); - } - Key::Backspace => { // Backspace - self.event_queue.borrow_mut().push(WindowEvent::Navigation(WindowNavigateMsg::Back)); - } - Key::PageDown => { - self.scroll_window(0.0, -self.framebuffer_size().as_f32().to_untyped().height); - } - Key::PageUp => { - self.scroll_window(0.0, self.framebuffer_size().as_f32().to_untyped().height); - } - _ => {} - } - } -} - -impl Window { - /// Helper function to set the window title in accordance with the ready state. - fn update_window_title(&self) { - match self.glutin { - WindowHandle::Windowed(ref window) => { - let now = time::get_time(); - if now.sec == self.last_title_set_time.get().sec { - return - } - self.last_title_set_time.set(now); - - match self.ready_state.get() { - ReadyState::Blank => { - window.set_title("blank - Servo [glutin]") - } - ReadyState::Loading => { - window.set_title("Loading - Servo [glutin]") - } - ReadyState::PerformingLayout => { - window.set_title("Performing Layout - Servo [glutin]") - } - ReadyState::FinishedLoading => { - match self.paint_state.get() { - PaintState::Painting => { - window.set_title("Rendering - Servo [glutin]") - } - PaintState::Idle => { - window.set_title("Servo [glutin]") - } - } - } - } - } - WindowHandle::Headless(_) => {}, - } + fn gl_version() -> (u32, u32) { + (2, 0) } -} -fn glutin_mods_to_script_mods(modifiers: KeyModifiers) -> constellation_msg::KeyModifiers { - let mut result = constellation_msg::KeyModifiers::from_bits(0).unwrap(); - if modifiers.intersects(LEFT_SHIFT | RIGHT_SHIFT) { - result.insert(SHIFT); - } - if modifiers.intersects(LEFT_CONTROL | RIGHT_CONTROL) { - result.insert(CONTROL); + #[cfg(not(target_os="android"))] + fn load_gl_functions(window: &glutin::Window) { + gl::load_with(|s| window.get_proc_address(s)); } - if modifiers.intersects(LEFT_ALT | RIGHT_ALT) { - result.insert(ALT); - } - result -} -fn glutin_key_to_script_key(key: glutin::VirtualKeyCode) -> Result<constellation_msg::Key, ()> { - // TODO(negge): add more key mappings - match key { - VirtualKeyCode::A => Ok(Key::A), - VirtualKeyCode::B => Ok(Key::B), - VirtualKeyCode::C => Ok(Key::C), - VirtualKeyCode::D => Ok(Key::D), - VirtualKeyCode::E => Ok(Key::E), - VirtualKeyCode::F => Ok(Key::F), - VirtualKeyCode::G => Ok(Key::G), - VirtualKeyCode::H => Ok(Key::H), - VirtualKeyCode::I => Ok(Key::I), - VirtualKeyCode::J => Ok(Key::J), - VirtualKeyCode::K => Ok(Key::K), - VirtualKeyCode::L => Ok(Key::L), - VirtualKeyCode::M => Ok(Key::M), - VirtualKeyCode::N => Ok(Key::N), - VirtualKeyCode::O => Ok(Key::O), - VirtualKeyCode::P => Ok(Key::P), - VirtualKeyCode::Q => Ok(Key::Q), - VirtualKeyCode::R => Ok(Key::R), - VirtualKeyCode::S => Ok(Key::S), - VirtualKeyCode::T => Ok(Key::T), - VirtualKeyCode::U => Ok(Key::U), - VirtualKeyCode::V => Ok(Key::V), - VirtualKeyCode::W => Ok(Key::W), - VirtualKeyCode::X => Ok(Key::X), - VirtualKeyCode::Y => Ok(Key::Y), - VirtualKeyCode::Z => Ok(Key::Z), - - VirtualKeyCode::Numpad0 => Ok(Key::Num0), - VirtualKeyCode::Numpad1 => Ok(Key::Num1), - VirtualKeyCode::Numpad2 => Ok(Key::Num2), - VirtualKeyCode::Numpad3 => Ok(Key::Num3), - VirtualKeyCode::Numpad4 => Ok(Key::Num4), - VirtualKeyCode::Numpad5 => Ok(Key::Num5), - VirtualKeyCode::Numpad6 => Ok(Key::Num6), - VirtualKeyCode::Numpad7 => Ok(Key::Num7), - VirtualKeyCode::Numpad8 => Ok(Key::Num8), - VirtualKeyCode::Numpad9 => Ok(Key::Num9), - - VirtualKeyCode::Key0 => Ok(Key::Kp0), - VirtualKeyCode::Key1 => Ok(Key::Kp1), - VirtualKeyCode::Key2 => Ok(Key::Kp2), - VirtualKeyCode::Key3 => Ok(Key::Kp3), - VirtualKeyCode::Key4 => Ok(Key::Kp4), - VirtualKeyCode::Key5 => Ok(Key::Kp5), - VirtualKeyCode::Key6 => Ok(Key::Kp6), - VirtualKeyCode::Key7 => Ok(Key::Kp7), - VirtualKeyCode::Key8 => Ok(Key::Kp8), - VirtualKeyCode::Key9 => Ok(Key::Kp9), - - VirtualKeyCode::Return => Ok(Key::Enter), - VirtualKeyCode::Space => Ok(Key::Space), - VirtualKeyCode::Escape => Ok(Key::Escape), - VirtualKeyCode::Equals => Ok(Key::Equal), - VirtualKeyCode::Minus => Ok(Key::Minus), - VirtualKeyCode::Back => Ok(Key::Backspace), - VirtualKeyCode::PageDown => Ok(Key::PageDown), - VirtualKeyCode::PageUp => Ok(Key::PageUp), - - VirtualKeyCode::Insert => Ok(Key::Insert), - VirtualKeyCode::Home => Ok(Key::Home), - VirtualKeyCode::Delete => Ok(Key::Delete), - VirtualKeyCode::End => Ok(Key::End), - - VirtualKeyCode::Left => Ok(Key::Left), - VirtualKeyCode::Up => Ok(Key::Up), - VirtualKeyCode::Right => Ok(Key::Right), - VirtualKeyCode::Down => Ok(Key::Down), - - VirtualKeyCode::Apostrophe => Ok(Key::Apostrophe), - VirtualKeyCode::Backslash => Ok(Key::Backslash), - VirtualKeyCode::Comma => Ok(Key::Comma), - VirtualKeyCode::Grave => Ok(Key::GraveAccent), - VirtualKeyCode::LBracket => Ok(Key::LeftBracket), - VirtualKeyCode::Period => Ok(Key::Period), - VirtualKeyCode::RBracket => Ok(Key::RightBracket), - VirtualKeyCode::Semicolon => Ok(Key::Semicolon), - VirtualKeyCode::Slash => Ok(Key::Slash), - VirtualKeyCode::Tab => Ok(Key::Tab), - - _ => Err(()), + #[cfg(target_os="android")] + fn load_gl_functions(_: &glutin::Window) { } -} -impl Window { fn handle_window_event(&self, event: glutin::Event) -> bool { match event { Event::KeyboardInput(element_state, _scan_code, virtual_key_code) => { @@ -476,10 +158,10 @@ impl Window { (_, VirtualKeyCode::RAlt) => self.toggle_modifier(RIGHT_ALT), (ElementState::Pressed, VirtualKeyCode::Escape) => return true, (ElementState::Pressed, key_code) => { - match glutin_key_to_script_key(key_code) { + match Window::glutin_key_to_script_key(key_code) { Ok(key) => { let state = KeyState::Pressed; - let modifiers = glutin_mods_to_script_mods(self.key_modifiers.get()); + let modifiers = Window::glutin_mods_to_script_mods(self.key_modifiers.get()); self.event_queue.borrow_mut().push(WindowEvent::KeyEvent(key, state, modifiers)); } _ => {} @@ -544,7 +226,7 @@ impl Window { } /// Helper function to handle a click - fn handle_mouse(&self, button: glutin::MouseButton, action: glutin::ElementState, x: int, y: int) { + fn handle_mouse(&self, button: glutin::MouseButton, action: glutin::ElementState, x: i32, y: i32) { // FIXME(tkuehn): max pixel dist should be based on pixel density let max_pixel_dist = 10f64; let event = match action { @@ -574,6 +256,81 @@ impl Window { self.event_queue.borrow_mut().push(WindowEvent::MouseWindowEventClass(event)); } + fn update_window_title(&self) { + let now = time::get_time(); + if now.sec == self.last_title_set_time.get().sec { + return + } + self.last_title_set_time.set(now); + + match self.ready_state.get() { + ReadyState::Blank => { + self.window.set_title("blank - Servo [glutin]") + } + ReadyState::Loading => { + self.window.set_title("Loading - Servo [glutin]") + } + ReadyState::PerformingLayout => { + self.window.set_title("Performing Layout - Servo [glutin]") + } + ReadyState::FinishedLoading => { + match self.paint_state.get() { + PaintState::Painting => { + self.window.set_title("Rendering - Servo [glutin]") + } + PaintState::Idle => { + self.window.set_title("Servo [glutin]") + } + } + } + } + } + + pub fn wait_events(&self) -> WindowEvent { + { + let mut event_queue = self.event_queue.borrow_mut(); + if !event_queue.is_empty() { + return event_queue.remove(0); + } + } + + let mut close_event = false; + + // When writing to a file then exiting, use event + // polling so that we don't block on a GUI event + // such as mouse click. + if opts::get().output_file.is_some() { + for event in self.window.poll_events() { + close_event = self.handle_window_event(event); + if close_event { + break; + } + } + } else { + // GWTODO: Something has changed in the wait_events + // behaviour in glutin. Switching to poll events + // for now, so that things display correctly, + // need to fix glutin / handle the changed behaviour. + for event in self.window.poll_events() { + close_event = self.handle_window_event(event); + if close_event { + break; + } + } + } + + if close_event || self.window.is_closed() { + WindowEvent::Quit + } else { + let mut event_queue = self.event_queue.borrow_mut(); + if event_queue.is_empty() { + WindowEvent::Idle + } else { + event_queue.remove(0) + } + } + } + pub unsafe fn set_nested_event_loop_listener( &self, listener: *mut (NestedEventLoopListener + 'static)) { @@ -584,48 +341,327 @@ impl Window { g_nested_event_loop_listener = None } - pub fn wait_events(&self) -> WindowEvent { - { - let mut event_queue = self.event_queue.borrow_mut(); - if !event_queue.is_empty() { - return event_queue.remove(0).unwrap(); + fn glutin_key_to_script_key(key: glutin::VirtualKeyCode) -> Result<constellation_msg::Key, ()> { + // TODO(negge): add more key mappings + match key { + VirtualKeyCode::A => Ok(Key::A), + VirtualKeyCode::B => Ok(Key::B), + VirtualKeyCode::C => Ok(Key::C), + VirtualKeyCode::D => Ok(Key::D), + VirtualKeyCode::E => Ok(Key::E), + VirtualKeyCode::F => Ok(Key::F), + VirtualKeyCode::G => Ok(Key::G), + VirtualKeyCode::H => Ok(Key::H), + VirtualKeyCode::I => Ok(Key::I), + VirtualKeyCode::J => Ok(Key::J), + VirtualKeyCode::K => Ok(Key::K), + VirtualKeyCode::L => Ok(Key::L), + VirtualKeyCode::M => Ok(Key::M), + VirtualKeyCode::N => Ok(Key::N), + VirtualKeyCode::O => Ok(Key::O), + VirtualKeyCode::P => Ok(Key::P), + VirtualKeyCode::Q => Ok(Key::Q), + VirtualKeyCode::R => Ok(Key::R), + VirtualKeyCode::S => Ok(Key::S), + VirtualKeyCode::T => Ok(Key::T), + VirtualKeyCode::U => Ok(Key::U), + VirtualKeyCode::V => Ok(Key::V), + VirtualKeyCode::W => Ok(Key::W), + VirtualKeyCode::X => Ok(Key::X), + VirtualKeyCode::Y => Ok(Key::Y), + VirtualKeyCode::Z => Ok(Key::Z), + + VirtualKeyCode::Numpad0 => Ok(Key::Num0), + VirtualKeyCode::Numpad1 => Ok(Key::Num1), + VirtualKeyCode::Numpad2 => Ok(Key::Num2), + VirtualKeyCode::Numpad3 => Ok(Key::Num3), + VirtualKeyCode::Numpad4 => Ok(Key::Num4), + VirtualKeyCode::Numpad5 => Ok(Key::Num5), + VirtualKeyCode::Numpad6 => Ok(Key::Num6), + VirtualKeyCode::Numpad7 => Ok(Key::Num7), + VirtualKeyCode::Numpad8 => Ok(Key::Num8), + VirtualKeyCode::Numpad9 => Ok(Key::Num9), + + VirtualKeyCode::Key0 => Ok(Key::Kp0), + VirtualKeyCode::Key1 => Ok(Key::Kp1), + VirtualKeyCode::Key2 => Ok(Key::Kp2), + VirtualKeyCode::Key3 => Ok(Key::Kp3), + VirtualKeyCode::Key4 => Ok(Key::Kp4), + VirtualKeyCode::Key5 => Ok(Key::Kp5), + VirtualKeyCode::Key6 => Ok(Key::Kp6), + VirtualKeyCode::Key7 => Ok(Key::Kp7), + VirtualKeyCode::Key8 => Ok(Key::Kp8), + VirtualKeyCode::Key9 => Ok(Key::Kp9), + + VirtualKeyCode::Return => Ok(Key::Enter), + VirtualKeyCode::Space => Ok(Key::Space), + VirtualKeyCode::Escape => Ok(Key::Escape), + VirtualKeyCode::Equals => Ok(Key::Equal), + VirtualKeyCode::Minus => Ok(Key::Minus), + VirtualKeyCode::Back => Ok(Key::Backspace), + VirtualKeyCode::PageDown => Ok(Key::PageDown), + VirtualKeyCode::PageUp => Ok(Key::PageUp), + + VirtualKeyCode::Insert => Ok(Key::Insert), + VirtualKeyCode::Home => Ok(Key::Home), + VirtualKeyCode::Delete => Ok(Key::Delete), + VirtualKeyCode::End => Ok(Key::End), + + VirtualKeyCode::Left => Ok(Key::Left), + VirtualKeyCode::Up => Ok(Key::Up), + VirtualKeyCode::Right => Ok(Key::Right), + VirtualKeyCode::Down => Ok(Key::Down), + + VirtualKeyCode::Apostrophe => Ok(Key::Apostrophe), + VirtualKeyCode::Backslash => Ok(Key::Backslash), + VirtualKeyCode::Comma => Ok(Key::Comma), + VirtualKeyCode::Grave => Ok(Key::GraveAccent), + VirtualKeyCode::LBracket => Ok(Key::LeftBracket), + VirtualKeyCode::Period => Ok(Key::Period), + VirtualKeyCode::RBracket => Ok(Key::RightBracket), + VirtualKeyCode::Semicolon => Ok(Key::Semicolon), + VirtualKeyCode::Slash => Ok(Key::Slash), + VirtualKeyCode::Tab => Ok(Key::Tab), + + _ => Err(()), + } + } + + fn glutin_mods_to_script_mods(modifiers: KeyModifiers) -> constellation_msg::KeyModifiers { + let mut result = constellation_msg::KeyModifiers::from_bits(0).unwrap(); + if modifiers.intersects(LEFT_SHIFT | RIGHT_SHIFT) { + result.insert(SHIFT); + } + if modifiers.intersects(LEFT_CONTROL | RIGHT_CONTROL) { + result.insert(CONTROL); + } + if modifiers.intersects(LEFT_ALT | RIGHT_ALT) { + result.insert(ALT); + } + result + } +} + +#[cfg(feature = "window")] +impl WindowMethods for Window { + fn framebuffer_size(&self) -> TypedSize2D<DevicePixel, u32> { + let scale_factor = self.window.hidpi_factor() as u32; + let (width, height) = self.window.get_inner_size().unwrap(); + TypedSize2D(width * scale_factor, height * scale_factor) + } + + fn size(&self) -> TypedSize2D<ScreenPx, f32> { + let (width, height) = self.window.get_inner_size().unwrap(); + TypedSize2D(width as f32, height as f32) + } + + fn present(&self) { + self.window.swap_buffers() + } + + fn create_compositor_channel(window: &Option<Rc<Window>>) + -> (Box<CompositorProxy+Send>, Box<CompositorReceiver>) { + let (sender, receiver) = channel(); + + let window_proxy = match window { + &Some(ref window) => Some(window.window.create_window_proxy()), + &None => None, + }; + + (box GlutinCompositorProxy { + sender: sender, + window_proxy: window_proxy, + } as Box<CompositorProxy+Send>, + box receiver as Box<CompositorReceiver>) + } + + /// Sets the ready state. + fn set_ready_state(&self, ready_state: ReadyState) { + self.ready_state.set(ready_state); + self.update_window_title() + } + + /// Sets the paint state. + fn set_paint_state(&self, paint_state: PaintState) { + self.paint_state.set(paint_state); + self.update_window_title() + } + + fn hidpi_factor(&self) -> ScaleFactor<ScreenPx, DevicePixel, f32> { + ScaleFactor(self.window.hidpi_factor()) + } + + fn set_page_title(&self, _: Option<String>) { + } + + fn set_page_load_data(&self, _: LoadData) { + } + + fn load_end(&self) { + } + + fn set_cursor(&self, _: Cursor) { + } + + fn prepare_for_composite(&self) -> bool { + true + } + + #[cfg(target_os="linux")] + fn native_metadata(&self) -> NativeGraphicsMetadata { + NativeGraphicsMetadata { + display: unsafe { self.window.platform_display() } + } + } + + #[cfg(target_os="macos")] + fn native_metadata(&self) -> NativeGraphicsMetadata { + use cgl::{CGLGetCurrentContext, CGLGetPixelFormat}; + unsafe { + NativeGraphicsMetadata { + pixel_format: CGLGetPixelFormat(CGLGetCurrentContext()), } } + } - match self.glutin { - WindowHandle::Windowed(ref window) => { - let mut close_event = false; - - // When writing to a file then exiting, use event - // polling so that we don't block on a GUI event - // such as mouse click. - if opts::get().output_file.is_some() { - for event in window.poll_events() { - close_event = self.handle_window_event(event); - if close_event { - break; - } - } - } else { - for event in window.wait_events() { - close_event = self.handle_window_event(event); - if close_event { - break; - } - } - } + #[cfg(target_os="android")] + fn native_metadata(&self) -> NativeGraphicsMetadata { + use egl::egl::GetCurrentDisplay; + NativeGraphicsMetadata { + display: GetCurrentDisplay(), + } + } - if close_event || window.is_closed() { - WindowEvent::Quit - } else { - self.event_queue.borrow_mut().remove(0).unwrap_or(WindowEvent::Idle) - } + /// Helper function to handle keyboard events. + fn handle_key(&self, key: Key, mods: constellation_msg::KeyModifiers) { + match key { + Key::Equal if mods.contains(CONTROL) => { // Ctrl-+ + self.event_queue.borrow_mut().push(WindowEvent::Zoom(1.1)); } - WindowHandle::Headless(_) => { - self.event_queue.borrow_mut().remove(0).unwrap_or(WindowEvent::Idle) + Key::Minus if mods.contains(CONTROL) => { // Ctrl-- + self.event_queue.borrow_mut().push(WindowEvent::Zoom(1.0/1.1)); + } + Key::Backspace if mods.contains(SHIFT) => { // Shift-Backspace + self.event_queue.borrow_mut().push(WindowEvent::Navigation(WindowNavigateMsg::Forward)); + } + Key::Backspace => { // Backspace + self.event_queue.borrow_mut().push(WindowEvent::Navigation(WindowNavigateMsg::Back)); } + Key::PageDown => { + self.scroll_window(0.0, -self.framebuffer_size().as_f32().to_untyped().height); + } + Key::PageUp => { + self.scroll_window(0.0, self.framebuffer_size().as_f32().to_untyped().height); + } + _ => {} + } + } +} + +/// The type of a window. +#[cfg(feature = "headless")] +pub struct Window { + #[allow(dead_code)] + context: glutin::HeadlessContext, + width: u32, + height: u32, +} + +#[cfg(feature = "headless")] +impl Window { + pub fn new(_is_foreground: bool, window_size: TypedSize2D<DevicePixel, u32>) -> Rc<Window> { + let window_size = window_size.to_untyped(); + let headless_builder = glutin::HeadlessRendererBuilder::new(window_size.width, + window_size.height); + let headless_context = headless_builder.build().unwrap(); + unsafe { headless_context.make_current() }; + + gl::load_with(|s| headless_context.get_proc_address(s)); + + let window = Window { + context: headless_context, + width: window_size.width, + height: window_size.height, + }; + + Rc::new(window) + } + + pub fn wait_events(&self) -> WindowEvent { + WindowEvent::Idle + } + + pub unsafe fn set_nested_event_loop_listener( + &self, + _listener: *mut (NestedEventLoopListener + 'static)) { + } + + pub unsafe fn remove_nested_event_loop_listener(&self) { + } +} + +#[cfg(feature = "headless")] +impl WindowMethods for Window { + fn framebuffer_size(&self) -> TypedSize2D<DevicePixel, u32> { + TypedSize2D(self.width, self.height) + } + + fn size(&self) -> TypedSize2D<ScreenPx, f32> { + TypedSize2D(self.width as f32, self.height as f32) + } + + fn present(&self) { + } + + fn create_compositor_channel(_: &Option<Rc<Window>>) + -> (Box<CompositorProxy+Send>, Box<CompositorReceiver>) { + let (sender, receiver) = channel(); + + (box GlutinCompositorProxy { + sender: sender, + window_proxy: None, + } as Box<CompositorProxy+Send>, + box receiver as Box<CompositorReceiver>) + } + + /// Sets the ready state. + fn set_ready_state(&self, _: ReadyState) { + } + + /// Sets the paint state. + fn set_paint_state(&self, _: PaintState) { + } + + fn hidpi_factor(&self) -> ScaleFactor<ScreenPx, DevicePixel, f32> { + ScaleFactor(1.0) + } + + fn set_page_title(&self, _: Option<String>) { + } + + fn set_page_load_data(&self, _: LoadData) { + } + + fn load_end(&self) { + } + + fn set_cursor(&self, _: Cursor) { + } + + fn prepare_for_composite(&self) -> bool { + true + } + + #[cfg(target_os="linux")] + fn native_metadata(&self) -> NativeGraphicsMetadata { + NativeGraphicsMetadata { + display: ptr::null_mut() } } + + /// Helper function to handle keyboard events. + fn handle_key(&self, _: Key, _: constellation_msg::KeyModifiers) { + } } struct GlutinCompositorProxy { @@ -633,6 +669,9 @@ struct GlutinCompositorProxy { window_proxy: Option<glutin::WindowProxy>, } +// TODO: Should this be implemented here or upstream in glutin::WindowProxy? +unsafe impl Send for GlutinCompositorProxy {} + impl CompositorProxy for GlutinCompositorProxy { fn send(&mut self, msg: compositor_task::Msg) { // Send a message and kick the OS event loop awake. diff --git a/ports/gonk/.cargo/config b/ports/gonk/.cargo/config index 8d63b74e1a9..e4951060177 100644 --- a/ports/gonk/.cargo/config +++ b/ports/gonk/.cargo/config @@ -1,11 +1,3 @@ -# FIXME: Remove this next rustup. This is a temporary -# hack to allow android cross compilation to work. When -# this is removed, the support/time submodule can also -# be removed! -paths = [ - "../../support/time" -] - [target.arm-linux-androideabi] ar = "arm-linux-androideabi-ar" linker = "arm-linux-androideabi-g++" diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock index 2afc1110cc0..12d56c86fea 100644 --- a/ports/gonk/Cargo.lock +++ b/ports/gonk/Cargo.lock @@ -15,7 +15,7 @@ dependencies = [ [[package]] name = "azure" version = "0.1.0" -source = "git+https://github.com/servo/rust-azure#d0acabef6221e5fd6840254dc23f91c66b874629" +source = "git+https://github.com/servo/rust-azure#72deb42903b12dc6f1924fa1757cd79d37b35429" dependencies = [ "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)", @@ -23,7 +23,7 @@ dependencies = [ "egl 0.1.0 (git+https://github.com/servo/rust-egl)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", - "skia-sys 0.0.20130412 (git+https://github.com/servo/skia?ref=upstream-2014-06-16)", + "skia-sys 0.0.20130412 (git+https://github.com/servo/skia?branch=upstream-2014-06-16)", "xlib 0.1.0 (git+https://github.com/servo/rust-xlib)", ] @@ -62,25 +62,26 @@ dependencies = [ "net 0.0.1", "png 0.1.0 (git+https://github.com/servo/rust-png)", "script_traits 0.0.1", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "cookie" -version = "0.1.0" -source = "git+https://github.com/alexcrichton/cookie-rs#8d1b4bb8d5ed06e58c162eb235a4ccd210b68108" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "openssl 0.2.4 (git+https://github.com/sfackler/rust-openssl)", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "openssl 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "core_foundation" version = "0.1.0" -source = "git+https://github.com/servo/rust-core-foundation#81db9ab15f67e16d7a3e9705a06cad65192014fd" +source = "git+https://github.com/servo/rust-core-foundation#ce3d852765827b64a0d5fb2aadd77da39665b0b0" [[package]] name = "core_graphics" @@ -93,7 +94,7 @@ dependencies = [ [[package]] name = "core_text" version = "0.1.0" -source = "git+https://github.com/servo/rust-core-text#cb369a26a0eb4e83c2128ceb3c685a191113417a" +source = "git+https://github.com/servo/rust-core-text#b5cb33905350e99b2a19f5a22f7b1efea7ad48c2" dependencies = [ "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)", "core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)", @@ -101,11 +102,12 @@ dependencies = [ [[package]] name = "cssparser" -version = "0.1.1" -source = "git+https://github.com/servo/rust-cssparser#110bf3052d016bf6eda0689fb21cf971e2c23dc8" +version = "0.2.0" +source = "git+https://github.com/servo/rust-cssparser#2a8c9f2c5f568495bae16f44b799be39b8efad39" dependencies = [ - "encoding 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "text_writer 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "text_writer 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -127,63 +129,63 @@ dependencies = [ [[package]] name = "egl" version = "0.1.0" -source = "git+https://github.com/servo/rust-egl#88f2a13812ddbce2bf2317221663a61c31b3e220" +source = "git+https://github.com/servo/rust-egl#cd74c82a8537090edb6c16478e2261db2a8c0b4f" [[package]] name = "encoding" -version = "0.2.6" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "encoding-index-japanese 1.0.20140915 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding-index-korean 1.0.20140915 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding-index-simpchinese 1.0.20140915 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding-index-singlebyte 1.0.20140915 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding-index-tradchinese 1.0.20140915 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding-index-japanese 1.20141219.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding-index-korean 1.20141219.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding-index-simpchinese 1.20141219.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding-index-singlebyte 1.20141219.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding-index-tradchinese 1.20141219.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "encoding-index-japanese" -version = "1.0.20140915" +version = "1.20141219.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "encoding_index_tests 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_index_tests 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "encoding-index-korean" -version = "1.0.20140915" +version = "1.20141219.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "encoding_index_tests 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_index_tests 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "encoding-index-simpchinese" -version = "1.0.20140915" +version = "1.20141219.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "encoding_index_tests 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_index_tests 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "encoding-index-singlebyte" -version = "1.0.20140915" +version = "1.20141219.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "encoding_index_tests 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_index_tests 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "encoding-index-tradchinese" -version = "1.0.20140915" +version = "1.20141219.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "encoding_index_tests 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_index_tests 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "encoding_index_tests" -version = "0.1.0" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -211,7 +213,7 @@ dependencies = [ [[package]] name = "freetype" version = "0.1.0" -source = "git+https://github.com/servo/rust-freetype#e55b06110fb2d74a2db68ead740db7e98fb98060" +source = "git+https://github.com/servo/rust-freetype#ec0231343a3ad360d86846c12895a0a0cbb19f79" [[package]] name = "freetype-sys" @@ -220,18 +222,18 @@ source = "git+https://github.com/servo/libfreetype2#f5c49c0da1d5bc6b206c41763440 [[package]] name = "gcc" -version = "0.1.1" -source = "git+https://github.com/alexcrichton/gcc-rs#dfe97a119af4b2db53178eb8c3ca6be6589a152b" +version = "0.1.4" +source = "git+https://github.com/alexcrichton/gcc-rs#f5c52d956e0742a66e40c8301e634e136c3ae287" [[package]] name = "gcc" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "geom" version = "0.1.0" -source = "git+https://github.com/servo/rust-geom#05f2d5494355adc78ad7d17286912f0d128f503b" +source = "git+https://github.com/servo/rust-geom#a4a4a03aa024412bf3f4e093c0198b433c6ad63f" [[package]] name = "gfx" @@ -253,40 +255,43 @@ dependencies = [ "script_traits 0.0.1", "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)", "style 0.0.1", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "gl_common" -version = "0.0.1" -source = "git+https://github.com/bjz/gl-rs.git#b5e3f4f76c31bc1b459d5e4c10d879ffa4f67c6e" +version = "0.0.3" +source = "git+https://github.com/bjz/gl-rs.git#230e6c9ed611cddfcb6682dee9686471d54863d0" [[package]] name = "gl_generator" -version = "0.0.1" -source = "git+https://github.com/bjz/gl-rs.git#b5e3f4f76c31bc1b459d5e4c10d879ffa4f67c6e" +version = "0.0.12" +source = "git+https://github.com/bjz/gl-rs.git#230e6c9ed611cddfcb6682dee9686471d54863d0" dependencies = [ - "gl_common 0.0.1 (git+https://github.com/bjz/gl-rs.git)", - "khronos_api 0.0.2 (git+https://github.com/bjz/gl-rs.git)", - "xml-rs 0.1.3 (git+https://github.com/netvl/xml-rs)", + "gl_common 0.0.3 (git+https://github.com/bjz/gl-rs.git)", + "khronos_api 0.0.5 (git+https://github.com/bjz/gl-rs.git)", + "log 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "xml-rs 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "gleam" version = "0.0.1" -source = "git+https://github.com/servo/gleam#c54eb9ad6d4b62b7effbe9c79a1b3720845b45b4" +source = "git+https://github.com/servo/gleam#375779e0e8e1eaa8ff1a732c81fa91808a7f6c63" dependencies = [ - "gl_generator 0.0.1 (git+https://github.com/bjz/gl-rs.git)", + "gl_common 0.0.3 (git+https://github.com/bjz/gl-rs.git)", + "gl_generator 0.0.12 (git+https://github.com/bjz/gl-rs.git)", ] [[package]] name = "glx" version = "0.0.1" -source = "git+https://github.com/servo/rust-glx#7126ffa09fcfcc9f85f1406f3b5db729f5fdb7c3" +source = "git+https://github.com/servo/rust-glx#f056a8998987f6f081f9ad7fa396beb1b2988c02" dependencies = [ - "gl_generator 0.0.1 (git+https://github.com/bjz/gl-rs.git)", + "gl_common 0.0.3 (git+https://github.com/bjz/gl-rs.git)", + "gl_generator 0.0.12 (git+https://github.com/bjz/gl-rs.git)", ] [[package]] @@ -297,33 +302,36 @@ source = "git+https://github.com/servo/rust-harfbuzz#59b5b18087418404d661784934c [[package]] name = "html5ever" version = "0.0.0" -source = "git+https://github.com/servo/html5ever#0abe5e30cc03f9e73bfd4fdc018192d149c21fb3" +source = "git+https://github.com/servo/html5ever#d35dfaaf0d85007057a299afc370d07e92538944" dependencies = [ "html5ever_macros 0.0.0 (git+https://github.com/servo/html5ever)", - "phf 0.0.1 (git+https://github.com/sfackler/rust-phf)", - "phf_mac 0.0.1 (git+https://github.com/sfackler/rust-phf)", + "phf 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_mac 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", - "time 0.1.0 (git+https://github.com/rust-lang/time)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "html5ever_macros" version = "0.0.0" -source = "git+https://github.com/servo/html5ever#0abe5e30cc03f9e73bfd4fdc018192d149c21fb3" +source = "git+https://github.com/servo/html5ever#d35dfaaf0d85007057a299afc370d07e92538944" [[package]] name = "hyper" -version = "0.0.1" -source = "git+https://github.com/servo/hyper?ref=servo#43becc919c24939b8b84fe541b0e0898a4827836" +version = "0.1.0" +source = "git+https://github.com/servo/hyper?branch=servo#248a6f29086baa841eb30c88540dca3196accae4" dependencies = [ - "cookie 0.1.0 (git+https://github.com/alexcrichton/cookie-rs)", - "mime 0.0.1 (git+https://github.com/hyperium/mime.rs)", - "mucell 0.1.2 (git+https://github.com/chris-morgan/mucell)", - "openssl 0.2.4 (git+https://github.com/sfackler/rust-openssl)", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "unsafe-any 0.1.1 (git+https://github.com/reem/rust-unsafe-any)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "cookie 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mucell 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unsafe-any 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -340,20 +348,20 @@ dependencies = [ [[package]] name = "js" version = "0.1.0" -source = "git+https://github.com/servo/rust-mozjs#5a69e377d6ab7ea8601f711443994f1c8172c7a8" +source = "git+https://github.com/servo/rust-mozjs#6cabb12f858f27d23fc3d2d9f0c334b80eb56573" dependencies = [ "mozjs-sys 0.0.0 (git+https://github.com/servo/mozjs)", ] [[package]] name = "khronos_api" -version = "0.0.2" -source = "git+https://github.com/bjz/gl-rs.git#b5e3f4f76c31bc1b459d5e4c10d879ffa4f67c6e" +version = "0.0.5" +source = "git+https://github.com/bjz/gl-rs.git#230e6c9ed611cddfcb6682dee9686471d54863d0" [[package]] name = "layers" version = "0.1.0" -source = "git+https://github.com/servo/rust-layers#f20270839f8658a2b19eae6fade9325efe5f4578" +source = "git+https://github.com/servo/rust-layers#8dece8325eda4a74816832580e62ebd3afc99dfb" dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", "cgl 0.0.1 (git+https://github.com/servo/rust-cgl)", @@ -370,8 +378,9 @@ dependencies = [ name = "layout" version = "0.0.1" dependencies = [ - "cssparser 0.1.1 (git+https://github.com/servo/rust-cssparser)", - "encoding 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "canvas 0.0.1", + "cssparser 0.2.0 (git+https://github.com/servo/rust-cssparser)", + "encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gfx 0.0.1", "layout_traits 0.0.1", @@ -382,7 +391,7 @@ dependencies = [ "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", "style 0.0.1", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -399,8 +408,8 @@ dependencies = [ [[package]] name = "lazy_static" -version = "0.1.0" -source = "git+https://github.com/Kimundi/lazy-static.rs#76f06e4fa7bc8c92f11d1def19bd4ddfd8017cd8" +version = "0.1.6" +source = "git+https://github.com/Kimundi/lazy-static.rs#31a7aa0176ecd70b4aab274a40d1e2cd78c1fbf8" [[package]] name = "libressl-pnacl-sys" @@ -411,14 +420,30 @@ dependencies = [ ] [[package]] +name = "log" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "regex 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "matches" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "mime" -version = "0.0.1" -source = "git+https://github.com/hyperium/mime.rs#7898f1c29c7f5d35d0c3c7aed37ebcfc95a40873" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "mozjs-sys" version = "0.0.0" -source = "git+https://github.com/servo/mozjs#0335cc57346147851589dea04e85971f064081fd" +source = "git+https://github.com/servo/mozjs#58ee8869c7e589244ab2eb3a3ad15e2b64498428" [[package]] name = "msg" @@ -427,44 +452,44 @@ dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", - "hyper 0.0.1 (git+https://github.com/servo/hyper?ref=servo)", + "hyper 0.1.0 (git+https://github.com/servo/hyper?branch=servo)", "io_surface 0.1.0 (git+https://github.com/servo/rust-io-surface)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "style 0.0.1", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "mucell" -version = "0.1.2" -source = "git+https://github.com/chris-morgan/mucell#d198c6605b3e688719db168db0939051c803b1ea" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "net" version = "0.0.1" dependencies = [ "geom 0.1.0 (git+https://github.com/servo/rust-geom)", - "hyper 0.0.1 (git+https://github.com/servo/hyper?ref=servo)", + "hyper 0.1.0 (git+https://github.com/servo/hyper?branch=servo)", "png 0.1.0 (git+https://github.com/servo/rust-png)", "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "openssl" -version = "0.2.4" -source = "git+https://github.com/sfackler/rust-openssl#f299e336d06a85438c3ee90aa06235510f3f5dbe" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "openssl-sys 0.2.4 (git+https://github.com/sfackler/rust-openssl)", + "openssl-sys 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl-sys" -version = "0.2.4" -source = "git+https://github.com/sfackler/rust-openssl#f299e336d06a85438c3ee90aa06235510f3f5dbe" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libressl-pnacl-sys 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -472,22 +497,26 @@ dependencies = [ [[package]] name = "phf" -version = "0.0.1" -source = "git+https://github.com/sfackler/rust-phf#6a7cc6eb9ec08b103b6b62fa39bdb3229f3cdbe4" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "xxhash 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_shared 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "phf_mac" -version = "0.0.1" -source = "git+https://github.com/sfackler/rust-phf#6a7cc6eb9ec08b103b6b62fa39bdb3229f3cdbe4" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "time 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "xxhash 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_shared 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] +name = "phf_shared" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "pkg-config" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -504,29 +533,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "png" version = "0.1.0" -source = "git+https://github.com/servo/rust-png#cc1976df347bb21ac78c5b37e651b85878855991" +source = "git+https://github.com/servo/rust-png#2804379427ced963466d19132b816bb06a8a4006" dependencies = [ - "gcc 0.1.1 (git+https://github.com/alexcrichton/gcc-rs)", + "gcc 0.1.4 (git+https://github.com/alexcrichton/gcc-rs)", "png-sys 1.6.16 (git+https://github.com/servo/rust-png)", ] [[package]] name = "png-sys" version = "1.6.16" -source = "git+https://github.com/servo/rust-png#cc1976df347bb21ac78c5b37e651b85878855991" +source = "git+https://github.com/servo/rust-png#2804379427ced963466d19132b816bb06a8a4006" + +[[package]] +name = "regex" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc-serialize" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "script" version = "0.0.1" dependencies = [ "canvas 0.0.1", - "cssparser 0.1.1 (git+https://github.com/servo/rust-cssparser)", + "cssparser 0.2.0 (git+https://github.com/servo/rust-cssparser)", "devtools_traits 0.0.1", - "encoding 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gfx 0.0.1", "html5ever 0.0.0 (git+https://github.com/servo/html5ever)", - "hyper 0.0.1 (git+https://github.com/servo/hyper?ref=servo)", + "hyper 0.1.0 (git+https://github.com/servo/hyper?branch=servo)", "js 0.1.0 (git+https://github.com/servo/rust-mozjs)", "msg 0.0.1", "net 0.0.1", @@ -535,10 +574,10 @@ dependencies = [ "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", "style 0.0.1", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", - "uuid 0.1.1 (git+https://github.com/rust-lang/uuid)", + "uuid 0.1.7 (git+https://github.com/rust-lang/uuid)", ] [[package]] @@ -549,7 +588,7 @@ dependencies = [ "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "msg 0.0.1", "net 0.0.1", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -558,20 +597,22 @@ name = "servo" version = "0.0.1" dependencies = [ "compositing 0.0.1", + "devtools 0.0.1", "gfx 0.0.1", "layout 0.0.1", "msg 0.0.1", "net 0.0.1", + "png 0.1.0 (git+https://github.com/servo/rust-png)", "script 0.0.1", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "skia-sys" version = "0.0.20130412" -source = "git+https://github.com/servo/skia?ref=upstream-2014-06-16#35649d0cddfd89c0bfee0ff558da7291e26d30c3" +source = "git+https://github.com/servo/skia?branch=upstream-2014-06-16#aeb720b947ec463f780a0d00ab8485f902a83986" dependencies = [ "expat-sys 2.1.0 (git+https://github.com/servo/libexpat)", "freetype-sys 2.4.11 (git+https://github.com/servo/libfreetype2)", @@ -580,41 +621,42 @@ dependencies = [ [[package]] name = "stb_image" version = "0.1.0" -source = "git+https://github.com/servo/rust-stb-image#97d7e440e80e41a304647363c322eab68e3700aa" +source = "git+https://github.com/servo/rust-stb-image#2ba03a447b9ef101c25e07bb7f8876416e5fcd71" [[package]] name = "string_cache" version = "0.0.0" -source = "git+https://github.com/servo/string-cache#661c537b85f19ac81dfcd84e28557d480b6b7a9f" +source = "git+https://github.com/servo/string-cache#43a1e5d0d0f2a45e2b96160c8fbe6e1d9602cfa9" dependencies = [ - "lazy_static 0.1.0 (git+https://github.com/Kimundi/lazy-static.rs)", - "phf 0.0.1 (git+https://github.com/sfackler/rust-phf)", - "phf_mac 0.0.1 (git+https://github.com/sfackler/rust-phf)", + "lazy_static 0.1.6 (git+https://github.com/Kimundi/lazy-static.rs)", + "phf 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_mac 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", - "xxhash 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "xxhash 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "string_cache_macros" version = "0.0.0" -source = "git+https://github.com/servo/string-cache#661c537b85f19ac81dfcd84e28557d480b6b7a9f" +source = "git+https://github.com/servo/string-cache#43a1e5d0d0f2a45e2b96160c8fbe6e1d9602cfa9" dependencies = [ - "lazy_static 0.1.0 (git+https://github.com/Kimundi/lazy-static.rs)", + "lazy_static 0.1.6 (git+https://github.com/Kimundi/lazy-static.rs)", ] [[package]] name = "style" version = "0.0.1" dependencies = [ - "cssparser 0.1.1 (git+https://github.com/servo/rust-cssparser)", - "encoding 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.2.0 (git+https://github.com/servo/rust-cssparser)", + "encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", - "lazy_static 0.1.0 (git+https://github.com/Kimundi/lazy-static.rs)", + "lazy_static 0.1.6 (git+https://github.com/Kimundi/lazy-static.rs)", + "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", - "text_writer 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "text_writer 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -624,68 +666,72 @@ version = "0.0.1" [[package]] name = "text_writer" -version = "0.1.4" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "time" -version = "0.1.0" -source = "git+https://github.com/rust-lang/time#afab521f3b91658a3ba2d3e877b7e01699733bef" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.1.1 (git+https://github.com/alexcrichton/gcc-rs)", + "gcc 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "time" -version = "0.1.3" +name = "unicase" +version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "gcc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "unsafe-any" -version = "0.1.1" -source = "git+https://github.com/reem/rust-unsafe-any#eb3fe87bea85f375b8fcefa0cdecfd131fae9624" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "url" -version = "0.2.4" -source = "git+https://github.com/servo/rust-url#79f8034a8e1815ffa1f49204572ddbf6eb747c75" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "util" version = "0.0.1" dependencies = [ - "cssparser 0.1.1 (git+https://github.com/servo/rust-cssparser)", + "cssparser 0.2.0 (git+https://github.com/servo/rust-cssparser)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "plugins 0.0.1", "string_cache 0.0.0 (git+https://github.com/servo/string-cache)", "string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)", "task_info 0.0.1", - "text_writer 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.0 (git+https://github.com/rust-lang/time)", - "url 0.2.4 (git+https://github.com/servo/rust-url)", + "text_writer 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "uuid" -version = "0.1.1" -source = "git+https://github.com/rust-lang/uuid#fc793c974a25c126c5cf5daa3b18973512a7a6a0" +version = "0.1.7" +source = "git+https://github.com/rust-lang/uuid#3ea51ffa0682c820e8c8b505de078e3bc93e2cb3" +dependencies = [ + "rustc-serialize 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "xlib" version = "0.1.0" -source = "git+https://github.com/servo/rust-xlib#58ec3847b592aeabdcfeb6a2d02033d3a2c7f427" +source = "git+https://github.com/servo/rust-xlib#138b0e281b9fd64f7d2e17080fa9a2d4a8554313" [[package]] name = "xml-rs" -version = "0.1.3" -source = "git+https://github.com/netvl/xml-rs#1a812d3ba720afd768bd75d29a5b5f10ddcdfbeb" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "xxhash" -version = "0.0.3" +version = "0.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/ports/gonk/src/lib.rs b/ports/gonk/src/lib.rs index 0a9da7e0394..de2f7db6098 100644 --- a/ports/gonk/src/lib.rs +++ b/ports/gonk/src/lib.rs @@ -2,19 +2,19 @@ * 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/. */ -#![feature(globs, macro_rules, phase, thread_local)] +#![feature(macro_rules, phase, thread_local)] #![deny(unused_imports)] #![deny(unused_variables)] -#[phase(plugin, link)] +#[macro_use] extern crate log; extern crate compositing; extern crate devtools; extern crate "net" as servo_net; extern crate "msg" as servo_msg; -#[phase(plugin, link)] +#[macro_use] extern crate "util" as servo_util; extern crate script; extern crate layout; diff --git a/ports/gonk/src/window.rs b/ports/gonk/src/window.rs index a7c55e45469..361c05c47ef 100644 --- a/ports/gonk/src/window.rs +++ b/ports/gonk/src/window.rs @@ -147,7 +147,7 @@ pub struct hwc_color { } #[repr(C)] -#[deriving(Copy)] +#[derive(Copy)] pub struct hwc_rect { left: c_int, top: c_int, diff --git a/python/servo/build_commands.py b/python/servo/build_commands.py index 78d9fb51318..9a5b6a609f1 100644 --- a/python/servo/build_commands.py +++ b/python/servo/build_commands.py @@ -1,5 +1,6 @@ from __future__ import print_function, unicode_literals +import os import os.path as path import subprocess from time import time @@ -12,6 +13,8 @@ from mach.decorators import ( from servo.command_base import CommandBase, cd +def is_headless_build(): + return int(os.getenv('SERVO_HEADLESS', 0)) == 1 @CommandProvider class MachCommands(CommandBase): @@ -69,6 +72,13 @@ class MachCommands(CommandBase): if debug_mozjs or self.config["build"]["debug-mozjs"]: features += ["script/debugmozjs"] + if is_headless_build(): + opts += ["--no-default-features"] + features += ["glutin_app", "headless"] + + if android: + features += ["android_glue"] + if features: opts += ["--features", "%s" % ' '.join(features)] @@ -132,11 +142,11 @@ class MachCommands(CommandBase): help='Number of jobs to run in parallel') def build_tests(self, jobs=None): self.ensure_bootstrapped() - opts = [] - if jobs is not None: - opts += ["-j", jobs] + args = ["cargo", "test", "--no-run"] + if is_headless_build(): + args += ["--no-default-features", "--features", "glutin_app headless"] return subprocess.call( - ["cargo", "test", "--no-run"], + args, env=self.build_env(), cwd=self.servo_crate()) @Command('clean', diff --git a/rust-snapshot-hash b/rust-snapshot-hash index 82317dbea35..e4cefd940fb 100644 --- a/rust-snapshot-hash +++ b/rust-snapshot-hash @@ -1 +1 @@ -2cfb5acb5a2751c759627377e602bac4f88f2d19/rust-0.13.0-dev +00b112c45a604fa6f4b59af2a40c9deeadfdb7c6/rustc-1.0.0-dev diff --git a/support/android-rs-glue b/support/android-rs-glue -Subproject 122bc28545b5e59a923c466a484c403fa691bd5 +Subproject 70c2242c45216a731d5ccd5d028ebbd206e2c9a diff --git a/support/rust-task_info/src/lib.rs b/support/rust-task_info/src/lib.rs index 57cba461435..4aea5cff193 100644 --- a/support/rust-task_info/src/lib.rs +++ b/support/rust-task_info/src/lib.rs @@ -10,8 +10,6 @@ #![crate_name = "task_info"] #![crate_type = "rlib"] -#![feature(globs)] - extern crate libc; #[cfg(target_os="macos")] diff --git a/tests/contenttest.rs b/tests/contenttest.rs index 3214b3d9025..66ad05f72bf 100644 --- a/tests/contenttest.rs +++ b/tests/contenttest.rs @@ -21,9 +21,10 @@ use std::{os, str}; use std::io::fs; use std::io::Reader; use std::io::process::{Command, Ignored, CreatePipe, InheritFd, ExitStatus}; +use std::thunk::Thunk; use regex::Regex; -#[deriving(Clone)] +#[derive(Clone)] struct Config { source_dir: String, filter: Option<Regex> @@ -51,7 +52,7 @@ fn parse_config(args: Vec<String>) -> Config { Config { source_dir: matches.opt_str("source-dir").unwrap(), - filter: matches.free.as_slice().head().map(|s| Regex::new(s.as_slice()).unwrap()) + filter: matches.free.as_slice().first().map(|&:s| Regex::new(s.as_slice()).unwrap()) } } @@ -91,7 +92,7 @@ fn make_test(file: String) -> TestDescAndFn { ignore: false, should_fail: ShouldFail::No, }, - testfn: DynTestFn(proc() { run_test(file) }) + testfn: DynTestFn(Thunk::new(move |:| { run_test(file) })) } } @@ -135,6 +136,6 @@ fn run_test(file: String) { let retval = prc.wait(); if retval != Ok(ExitStatus(0)) { - panic!("Servo exited with non-zero status {}", retval); + panic!("Servo exited with non-zero status {:?}", retval); } } diff --git a/tests/ref/basic.list b/tests/ref/basic.list index cfd3478a357..f4af79d356f 100644 --- a/tests/ref/basic.list +++ b/tests/ref/basic.list @@ -224,6 +224,7 @@ fragment=top != ../html/acid2.html acid2_ref.html != inset_blackborder.html blackborder_ref.html != outset_blackborder.html blackborder_ref.html == border_radius_clip_a.html border_radius_clip_ref.html +== border_radius_overlapping_a.html border_radius_overlapping_ref.html == stacking_context_overflow_a.html stacking_context_overflow_ref.html == stacking_context_overflow_relative_outline_a.html stacking_context_overflow_relative_outline_ref.html == word_break_a.html word_break_ref.html diff --git a/tests/ref/border_radius_overlapping_a.html b/tests/ref/border_radius_overlapping_a.html new file mode 100644 index 00000000000..58baa1720ca --- /dev/null +++ b/tests/ref/border_radius_overlapping_a.html @@ -0,0 +1,6 @@ +<!DOCTYPE html> +<html> + <body> + <div style='box-sizing:border-box; width:6em; height:2em; border-radius:.5em 2em .5em 2em; background-color:red;'></div> + </body> +</html> diff --git a/tests/ref/border_radius_overlapping_ref.html b/tests/ref/border_radius_overlapping_ref.html new file mode 100644 index 00000000000..287a3d52085 --- /dev/null +++ b/tests/ref/border_radius_overlapping_ref.html @@ -0,0 +1,6 @@ +<!DOCTYPE html> +<html> + <body> + <div style='box-sizing:border-box; width:6em; height:2em; border-radius:.4em 1.6em .4em 1.6em; background-color:red;'></div> + </body> +</html> diff --git a/tests/reftest.rs b/tests/reftest.rs index 6c483d6d02a..d1305687076 100644 --- a/tests/reftest.rs +++ b/tests/reftest.rs @@ -22,6 +22,7 @@ use std::io::process::ExitStatus; use std::io::fs::PathExtensions; use std::os; use std::path::Path; +use std::thunk::Thunk; use test::{AutoColor, DynTestName, DynTestFn, TestDesc, TestOpts, TestDescAndFn, ShouldFail}; use test::run_tests_console; use regex::Regex; @@ -29,7 +30,6 @@ use url::Url; bitflags!( - #[deriving(Copy)] flags RenderMode: u32 { const CPU_RENDERING = 0x00000001, const GPU_RENDERING = 0x00000010, @@ -37,7 +37,7 @@ bitflags!( const MACOS_TARGET = 0x00001000, const ANDROID_TARGET = 0x00010000 } -) +); fn main() { @@ -75,7 +75,7 @@ fn main() { let maybe_extension = file.extension_str(); match maybe_extension { Some(extension) => { - if extension.to_ascii_lower().as_slice() == "list" && file.is_file() { + if extension.to_ascii_lowercase().as_slice() == "list" && file.is_file() { let tests = parse_lists(&file, servo_args, render_mode, all_tests.len()); println!("\t{} [{} tests]", file.display(), tests.len()); all_tests.extend(tests.into_iter()); @@ -131,7 +131,7 @@ fn run(test_opts: TestOpts, all_tests: Vec<TestDescAndFn>, run_tests_console(&test_opts, all_tests) } -#[deriving(PartialEq)] +#[derive(PartialEq)] enum ReftestKind { Same, Different, @@ -140,7 +140,7 @@ enum ReftestKind { struct Reftest { name: String, kind: ReftestKind, - files: [Path, ..2], + files: [Path; 2], id: uint, servo_args: Vec<String>, render_mode: RenderMode, @@ -245,9 +245,9 @@ fn make_test(reftest: Reftest) -> TestDescAndFn { ignore: false, should_fail: ShouldFail::No, }, - testfn: DynTestFn(proc() { + testfn: DynTestFn(Thunk::new(move || { check_reftest(reftest); - }), + })), } } @@ -276,16 +276,14 @@ fn capture(reftest: &Reftest, side: uint) -> (u32, u32, Vec<u8>) { if reftest.experimental { command.arg("--experimental"); } - if cfg!(target_os = "linux") { - command.args(["-r", "mesa"].as_slice()); - } let retval = match command.status() { Ok(status) => status, Err(e) => panic!("failed to execute process: {}", e), }; assert_eq!(retval, ExitStatus(0)); - let image = png::load_png(&from_str::<Path>(png_filename.as_slice()).unwrap()).unwrap(); + let path = png_filename.parse::<Path>().unwrap(); + let image = png::load_png(&path).unwrap(); let rgba8_bytes = match image.pixels { png::PixelsByColorType::RGBA8(pixels) => pixels, _ => panic!(), @@ -322,7 +320,7 @@ fn check_reftest(reftest: Reftest) { if pixels.iter().any(|&a| a < 255) { let output_str = format!("/tmp/servo-reftest-{:06}-diff.png", reftest.id); - let output = from_str::<Path>(output_str.as_slice()).unwrap(); + let output = output_str.parse::<Path>().unwrap(); let mut img = png::Image { width: left_width, diff --git a/tests/wpt/metadata/XMLHttpRequest/send-accept.htm.ini b/tests/wpt/metadata/XMLHttpRequest/send-accept.htm.ini new file mode 100644 index 00000000000..c93664275f4 --- /dev/null +++ b/tests/wpt/metadata/XMLHttpRequest/send-accept.htm.ini @@ -0,0 +1,4 @@ +[send-accept.htm] + type: testharness + [XMLHttpRequest: send() - Accept] + expected: FAIL diff --git a/tests/wpt/metadata/html/dom/documents/resource-metadata-management/document-lastModified-01.html.ini b/tests/wpt/metadata/html/dom/documents/resource-metadata-management/document-lastModified-01.html.ini new file mode 100644 index 00000000000..45275168378 --- /dev/null +++ b/tests/wpt/metadata/html/dom/documents/resource-metadata-management/document-lastModified-01.html.ini @@ -0,0 +1,3 @@ +[document-lastModified-01.html] + type: testharness + disabled: https://github.com/servo/servo/issues/3228 |