From 85c88c707f5b00d215fab42e6da409615bbd6767 Mon Sep 17 00:00:00 2001 From: WriterOfAlicrow Date: Fri, 15 May 2015 22:44:10 -0400 Subject: [PATCH 01/38] Fix for Issue #6073 --- components/script/dom/htmlinputelement.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index e077cfac737..09c4667025f 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -413,6 +413,8 @@ impl<'a> HTMLInputElementHelpers for JSRef<'a, HTMLInputElement> { .as_ref() .map(|group| &**group)); } + + self.force_relayout(); //TODO: dispatch change event } From 11a4aac2a2f00718890aca500ee9abad4c8d740d Mon Sep 17 00:00:00 2001 From: WriterOfAlicrow Date: Fri, 15 May 2015 23:04:15 -0400 Subject: [PATCH 02/38] fixup! Fix for Issue #6073 --- components/script/dom/htmlinputelement.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 09c4667025f..eb784c91b6f 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -413,7 +413,7 @@ impl<'a> HTMLInputElementHelpers for JSRef<'a, HTMLInputElement> { .as_ref() .map(|group| &**group)); } - + self.force_relayout(); //TODO: dispatch change event } From 5ce23cd36cb20539ff2219f2213cacbb8b08ae09 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Mon, 18 May 2015 12:26:46 -0400 Subject: [PATCH 03/38] update glutin repo ref --- components/servo/Cargo.lock | 2 +- ports/cef/Cargo.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 3202bcf3859..fc3bf6baa8b 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -431,7 +431,7 @@ dependencies = [ [[package]] name = "glutin" version = "0.0.26" -source = "git+https://github.com/servo/glutin?branch=servo#b28f35aa5b06e7d34ada307a5a1b1e9b9de697a1" +source = "git+https://github.com/servo/glutin?branch=servo#33f26a11d73cb4a3969059c57471f9f7b151dc1d" dependencies = [ "android_glue 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "gdi32-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index ce8b96337e1..1630fcca163 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -433,7 +433,7 @@ dependencies = [ [[package]] name = "glutin" version = "0.0.26" -source = "git+https://github.com/servo/glutin?branch=servo#b28f35aa5b06e7d34ada307a5a1b1e9b9de697a1" +source = "git+https://github.com/servo/glutin?branch=servo#33f26a11d73cb4a3969059c57471f9f7b151dc1d" dependencies = [ "android_glue 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "gdi32-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", From 35a570ab66227fb640e64bd50373f1e1a9f51b22 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Tue, 19 May 2015 16:14:25 +1000 Subject: [PATCH 04/38] Fix several hangs / panics during pipeline cleanup of in progress loads. This fixes a hang found while testing the jQuery test suite. --- components/compositing/compositor_task.rs | 8 ++++++- components/gfx/paint_task.rs | 2 +- components/layout/layout_task.rs | 2 +- components/msg/constellation_msg.rs | 2 +- components/script/dom/window.rs | 11 +++++++++ components/script/script_task.rs | 29 +++++++++++++++++++---- components/util/task.rs | 2 +- 7 files changed, 46 insertions(+), 10 deletions(-) diff --git a/components/compositing/compositor_task.rs b/components/compositing/compositor_task.rs index 5a3c6bdd5fa..10a49fa3928 100644 --- a/components/compositing/compositor_task.rs +++ b/components/compositing/compositor_task.rs @@ -94,7 +94,13 @@ impl PaintListener for Box { fn get_graphics_metadata(&mut self) -> Option { let (chan, port) = channel(); self.send(Msg::GetGraphicsMetadata(chan)); - port.recv().unwrap() + // If the compositor is shutting down when a paint task + // is being created, the compositor won't respond to + // this message, resulting in an eventual panic. Instead, + // just return None in this case, since the paint task + // will exit shortly and never actually be requested + // to paint buffers by the compositor. + port.recv().unwrap_or(None) } fn assign_painted_buffers(&mut self, diff --git a/components/gfx/paint_task.rs b/components/gfx/paint_task.rs index 4b9f2c6f6d1..d0b8182730e 100644 --- a/components/gfx/paint_task.rs +++ b/components/gfx/paint_task.rs @@ -145,7 +145,7 @@ impl PaintTask where C: PaintListener + Send + 'static { time_profiler_chan: time::ProfilerChan, shutdown_chan: Sender<()>) { let ConstellationChan(c) = constellation_chan.clone(); - spawn_named_with_send_on_failure("PaintTask", task_state::PAINT, move || { + spawn_named_with_send_on_failure(format!("PaintTask {:?}", id), task_state::PAINT, move || { { // Ensures that the paint task and graphics context are destroyed before the // shutdown message. diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 9ac33d0d267..83538a3818c 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -207,7 +207,7 @@ impl LayoutTaskFactory for LayoutTask { memory_profiler_chan: mem::ProfilerChan, shutdown_chan: Sender<()>) { let ConstellationChan(con_chan) = constellation_chan.clone(); - spawn_named_with_send_on_failure("LayoutTask", task_state::LAYOUT, move || { + spawn_named_with_send_on_failure(format!("LayoutTask {:?}", id), task_state::LAYOUT, move || { { // Ensures layout task is destroyed before we send shutdown message let sender = chan.sender(); let layout = LayoutTask::new(id, diff --git a/components/msg/constellation_msg.rs b/components/msg/constellation_msg.rs index cba1b2c6d86..09bf676405b 100644 --- a/components/msg/constellation_msg.rs +++ b/components/msg/constellation_msg.rs @@ -366,7 +366,7 @@ pub struct SubpageId(pub u32); // The type of pipeline exit. During complete shutdowns, pipelines do not have to // release resources automatically released on process termination. -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub enum PipelineExitType { PipelineOnly, Complete, diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 2621a9498a3..f791464366d 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -584,6 +584,17 @@ impl<'a> WindowHelpers for JSRef<'a, Window> { let document = self.Document().root(); NodeCast::from_ref(document.r()).teardown(); + // The above code may not catch all DOM objects + // (e.g. DOM objects removed from the tree that haven't + // been collected yet). Forcing a GC here means that + // those DOM objects will be able to call dispose() + // to free their layout data before the layout task + // exits. Without this, those remaining objects try to + // send a message to free their layout data to the + // layout task when the script task is dropped, + // which causes a panic! + self.Gc(); + *self.js_runtime.borrow_mut() = None; *self.browser_context.borrow_mut() = None; } diff --git a/components/script/script_task.rs b/components/script/script_task.rs index b114819c613..e291d98e5ee 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -386,7 +386,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, move || { + spawn_named_with_send_on_failure(format!("ScriptTask {:?}", id), task_state::SCRIPT, move || { let script_task = ScriptTask::new(box compositor as Box, script_port, NonWorkerScriptChan(script_chan), @@ -1080,11 +1080,30 @@ impl ScriptTask { /// Handles a request to exit the script task and shut down layout. /// Returns true if the script task should shut down and false otherwise. fn handle_exit_pipeline_msg(&self, id: PipelineId, exit_type: PipelineExitType) -> bool { - if self.page.borrow().is_none() { - // The root page doesn't even exist yet, so it - // is safe to exit this script task. + // Check if the exit message is for an in progress load. + let idx = self.incomplete_loads.borrow().iter().position(|load| { + load.pipeline_id == id + }); + + if let Some(idx) = idx { // TODO(gw): This probably leaks resources! - return true; + let load = self.incomplete_loads.borrow_mut().remove(idx); + + // Tell the layout task to begin shutting down, and wait until it + // processed this message. + let (response_chan, response_port) = channel(); + let LayoutChan(chan) = load.layout_chan; + if chan.send(layout_interface::Msg::PrepareToExit(response_chan)).is_ok() { + debug!("shutting down layout for root page {:?}", id); + response_port.recv().unwrap(); + chan.send(layout_interface::Msg::ExitNow(exit_type)).ok(); + } + + let has_pending_loads = self.incomplete_loads.borrow().len() > 0; + let has_root_page = self.page.borrow().is_some(); + + // Exit if no pending loads and no root page + return !has_pending_loads && !has_root_page; } // If root is being exited, shut down all pages diff --git a/components/util/task.rs b/components/util/task.rs index de206526f44..d00f29c1c67 100644 --- a/components/util/task.rs +++ b/components/util/task.rs @@ -18,7 +18,7 @@ pub fn spawn_named(name: String, f: F) } /// Arrange to send a particular message to a channel if the task fails. -pub fn spawn_named_with_send_on_failure(name: &'static str, +pub fn spawn_named_with_send_on_failure(name: String, state: task_state::TaskState, f: F, msg: T, From 72f031e2a13c6d7238748a57d3e0f53c9dfd6ae8 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 18 May 2015 12:22:17 -0700 Subject: [PATCH 05/38] layout: Support inline incremental reflow, and stop reconstructing all flows when mousing over the document. This exposes more "jumpiness" on sites like Hacker News, but the bug that causes it was pre-existing. --- components/layout/construct.rs | 50 +++++++++++++++++++++-------- components/layout/css/node_style.rs | 40 ++++++++--------------- components/layout/incremental.rs | 1 - components/layout/layout_task.rs | 4 ++- components/layout/traversal.rs | 2 +- components/script/dom/node.rs | 4 +-- 6 files changed, 57 insertions(+), 44 deletions(-) diff --git a/components/layout/construct.rs b/components/layout/construct.rs index 95d07afec6f..ba9f077c785 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -1250,22 +1250,28 @@ impl<'a> FlowConstructor<'a> { return false } - match node.swap_out_construction_result() { - ConstructionResult::None => true, - ConstructionResult::Flow(mut flow, _) => { + let mut layout_data_ref = node.mutate_layout_data(); + let layout_data = layout_data_ref.as_mut().expect("no layout data"); + let style = (*node.get_style(&layout_data)).clone(); + let damage = layout_data.data.restyle_damage; + match node.get_construction_result(layout_data) { + &mut ConstructionResult::None => true, + &mut ConstructionResult::Flow(ref mut flow, _) => { // The node's flow is of the same type and has the same set of children and can // therefore be repaired by simply propagating damage and style to the flow. - flow::mut_base(&mut *flow).restyle_damage.insert(node.restyle_damage()); - flow.repair_style_and_bubble_inline_sizes(node.style()); + if !flow.is_block_flow() { + return false + } + flow::mut_base(&mut **flow).restyle_damage.insert(damage); + flow.repair_style_and_bubble_inline_sizes(&style); true } - ConstructionResult::ConstructionItem(ConstructionItem::InlineFragments( - mut inline_fragments_construction_result)) => { + &mut ConstructionResult::ConstructionItem(ConstructionItem::InlineFragments( + ref mut inline_fragments_construction_result)) => { if !inline_fragments_construction_result.splits.is_empty() { return false } - let damage = node.restyle_damage(); for fragment in inline_fragments_construction_result.fragments .fragments .iter_mut() { @@ -1274,17 +1280,34 @@ impl<'a> FlowConstructor<'a> { flow::mut_base(&mut *inline_block_fragment.flow_ref).restyle_damage .insert(damage); // FIXME(pcwalton): Fragment restyle damage too? - inline_block_fragment.flow_ref.repair_style_and_bubble_inline_sizes( - node.style()); + inline_block_fragment.flow_ref + .repair_style_and_bubble_inline_sizes(&style); + } + SpecificFragmentInfo::InlineAbsoluteHypothetical( + ref mut inline_absolute_hypothetical_fragment) => { + flow::mut_base(&mut *inline_absolute_hypothetical_fragment.flow_ref) + .restyle_damage.insert(damage); + // FIXME(pcwalton): Fragment restyle damage too? + inline_absolute_hypothetical_fragment + .flow_ref + .repair_style_and_bubble_inline_sizes(&style); + } + SpecificFragmentInfo::InlineAbsolute(ref mut inline_absolute_fragment) => { + flow::mut_base(&mut *inline_absolute_fragment.flow_ref).restyle_damage + .insert(damage); + // FIXME(pcwalton): Fragment restyle damage too? + inline_absolute_fragment.flow_ref + .repair_style_and_bubble_inline_sizes(&style); } _ => { - return false + fragment.repair_style(&style); + return true } } } true } - ConstructionResult::ConstructionItem(_) => { + &mut ConstructionResult::ConstructionItem(_) => { false } } @@ -1450,7 +1473,8 @@ trait NodeUtils { /// Returns true if this node doesn't render its kids and false otherwise. fn is_replaced_content(&self) -> bool; - fn get_construction_result<'a>(self, layout_data: &'a mut LayoutDataWrapper) -> &'a mut ConstructionResult; + fn get_construction_result<'a>(self, layout_data: &'a mut LayoutDataWrapper) + -> &'a mut ConstructionResult; /// Sets the construction result of a flow. fn set_flow_construction_result(self, result: ConstructionResult); diff --git a/components/layout/css/node_style.rs b/components/layout/css/node_style.rs index 5b33d8d4c2d..5f513a19399 100644 --- a/components/layout/css/node_style.rs +++ b/components/layout/css/node_style.rs @@ -4,6 +4,7 @@ //! Style retrieval from DOM elements. +use data::LayoutDataWrapper; use wrapper::{PseudoElementType, ThreadSafeLayoutNode}; use std::mem; @@ -12,6 +13,7 @@ use std::sync::Arc; /// Node mixin providing `style` method that returns a `NodeStyle` pub trait StyledNode { + fn get_style<'a>(&'a self, layout_data_ref: &'a LayoutDataWrapper) -> &'a Arc; /// Returns the style results for the given node. If CSS selector matching has not yet been /// performed, fails. fn style<'a>(&'a self) -> &'a Arc; @@ -22,37 +24,23 @@ pub trait StyledNode { } impl<'ln> StyledNode for ThreadSafeLayoutNode<'ln> { + #[inline] + fn get_style<'a>(&self, layout_data_ref: &'a LayoutDataWrapper) -> &'a Arc { + match self.get_pseudo_element_type() { + PseudoElementType::Before(_) => layout_data_ref.data.before_style.as_ref().unwrap(), + PseudoElementType::After(_) => layout_data_ref.data.after_style.as_ref().unwrap(), + PseudoElementType::Normal => layout_data_ref.shared_data.style.as_ref().unwrap(), + } + } + #[inline] #[allow(unsafe_code)] fn style<'a>(&'a self) -> &'a Arc { unsafe { let layout_data_ref = self.borrow_layout_data(); - match self.get_pseudo_element_type() { - PseudoElementType::Before(_) => { - mem::transmute(layout_data_ref.as_ref() - .unwrap() - .data - .before_style - .as_ref() - .unwrap()) - } - PseudoElementType::After(_) => { - mem::transmute(layout_data_ref.as_ref() - .unwrap() - .data - .after_style - .as_ref() - .unwrap()) - } - PseudoElementType::Normal => { - mem::transmute(layout_data_ref.as_ref() - .unwrap() - .shared_data - .style - .as_ref() - .unwrap()) - } - } + let layout_data = layout_data_ref.as_ref().expect("no layout data"); + mem::transmute::<&Arc, + &'a Arc>(self.get_style(&layout_data)) } } diff --git a/components/layout/incremental.rs b/components/layout/incremental.rs index f9fda729cfe..9a8cbd822f5 100644 --- a/components/layout/incremental.rs +++ b/components/layout/incremental.rs @@ -184,7 +184,6 @@ pub fn compute_damage(old: &Option>, new: &ComputedValues) - [ get_box.float, get_box.display, get_box.position ]); // FIXME: test somehow that we checked every CSS property - damage } diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 9ac33d0d267..7b30e10e727 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -887,7 +887,8 @@ impl LayoutTask { // let the constellation know about the viewport constraints let ConstellationChan(ref constellation_chan) = rw_data.constellation_chan; - constellation_chan.send(ConstellationMsg::ViewportConstrained(self.id, constraints)).unwrap(); + constellation_chan.send(ConstellationMsg::ViewportConstrained( + self.id, constraints)).unwrap(); } } @@ -1074,6 +1075,7 @@ impl LayoutTask { } fn reflow_all_nodes(flow: &mut Flow) { + debug!("reflowing all nodes!"); flow::mut_base(flow).restyle_damage.insert(REFLOW | REPAINT); for child in flow::child_iter(flow) { diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index b362ac6975f..39169787cad 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -170,7 +170,7 @@ impl<'a> PreorderDomTraversal for RecalcStyleForNode<'a> { &some_bf, &mut applicable_declarations, &mut shareable); - } else { + } else if node.has_changed() { ThreadSafeLayoutNode::new(&node).set_restyle_damage( incremental::rebuild_and_reflow()) } diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index f7401c99b11..789d2920832 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -629,7 +629,7 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { fn set_hover_state(self, state: bool) { self.set_flag(IN_HOVER_STATE, state); - self.dirty(NodeDamage::OtherNodeDamage); + self.dirty(NodeDamage::NodeStyleDamaged); } fn get_focus_state(self) -> bool { @@ -638,7 +638,7 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { fn set_focus_state(self, state: bool) { self.set_flag(IN_FOCUS_STATE, state); - self.dirty(NodeDamage::OtherNodeDamage); + self.dirty(NodeDamage::NodeStyleDamaged); } fn get_disabled_state(self) -> bool { From 52ff17527917d644849fd226b2050992933feab4 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Tue, 19 May 2015 11:42:43 -0700 Subject: [PATCH 06/38] Enable 'direction' without --experimental --- components/style/properties.mako.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/style/properties.mako.rs b/components/style/properties.mako.rs index 3edc0a312fa..7ddeb3795ff 100644 --- a/components/style/properties.mako.rs +++ b/components/style/properties.mako.rs @@ -424,7 +424,7 @@ pub mod longhands { ${new_style_struct("InheritedBox", is_inherited=True)} - ${single_keyword("direction", "ltr rtl", experimental=True)} + ${single_keyword("direction", "ltr rtl")} // CSS 2.1, Section 10 - Visual formatting model details From c2ed42d2bcdc0f0cd665908ff5270051fb9946e6 Mon Sep 17 00:00:00 2001 From: Michael Wu Date: Tue, 19 May 2015 13:56:19 -0400 Subject: [PATCH 07/38] Fix mutable transmutes --- components/layout/parallel.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/components/layout/parallel.rs b/components/layout/parallel.rs index 5d61e11a3d4..6ff9acc19d5 100644 --- a/components/layout/parallel.rs +++ b/components/layout/parallel.rs @@ -169,7 +169,7 @@ trait ParallelPostorderDomTraversal : PostorderDomTraversal { unsafe_node = layout_node_to_unsafe_layout_node(&parent); - let parent_layout_data: &mut LayoutDataWrapper = mem::transmute(parent_layout_data); + let parent_layout_data: &LayoutDataWrapper = mem::transmute(parent_layout_data); if parent_layout_data .data .parallel @@ -221,7 +221,7 @@ trait ParallelPostorderFlowTraversal : PostorderFlowTraversal { loop { unsafe { // Get a real flow. - let flow: &mut FlowRef = mem::transmute(&unsafe_flow); + let flow: &mut FlowRef = mem::transmute(&mut unsafe_flow); // Perform the appropriate traversal. if self.should_process(&mut **flow) { @@ -236,7 +236,7 @@ trait ParallelPostorderFlowTraversal : PostorderFlowTraversal { Ordering::Relaxed); // Possibly enqueue the parent. - let unsafe_parent = base.parallel.parent; + let mut unsafe_parent = base.parallel.parent; if unsafe_parent == null_unsafe_flow() { // We're done! break @@ -245,7 +245,7 @@ trait ParallelPostorderFlowTraversal : PostorderFlowTraversal { // No, we're not at the root yet. Then are we the last child // 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: &mut FlowRef = mem::transmute(&mut unsafe_parent); 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. @@ -269,14 +269,14 @@ trait ParallelPreorderFlowTraversal : PreorderFlowTraversal { #[inline(always)] fn run_parallel_helper(&self, - unsafe_flow: UnsafeFlow, + mut unsafe_flow: UnsafeFlow, proxy: &mut WorkerProxy, top_down_func: FlowTraversalFunction, bottom_up_func: FlowTraversalFunction) { let mut had_children = false; unsafe { // Get a real flow. - let flow: &mut FlowRef = mem::transmute(&unsafe_flow); + let flow: &mut FlowRef = mem::transmute(&mut unsafe_flow); if self.should_record_thread_ids() { flow::mut_base(&mut **flow).thread_id = proxy.worker_index(); From 7772984e0b5eb48a3e5ee63efa2050baf1a7fef7 Mon Sep 17 00:00:00 2001 From: Michael Wu Date: Tue, 19 May 2015 15:23:18 -0400 Subject: [PATCH 08/38] Fix borrow_unchecked in LayoutDataRef --- components/script/dom/node.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index f7401c99b11..033afb43a7f 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -245,7 +245,7 @@ impl LayoutDataRef { #[inline] #[allow(unsafe_code)] pub unsafe fn borrow_unchecked(&self) -> *const Option { - mem::transmute(&self.data_cell) + self.data_cell.as_unsafe_cell().get() as *const _ } /// Borrows the layout data immutably. This function is *not* thread-safe. From d5ca1a18dc110d2c6fbad69a517c5bca858c32be Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 8 May 2015 16:33:30 -0700 Subject: [PATCH 09/38] layout: Support percentage widths in inline-blocks. Improves Twitter. --- components/layout/block.rs | 6 +++--- components/layout/fragment.rs | 13 +++++++++++++ components/layout/inline.rs | 3 ++- tests/ref/basic.list | 1 + tests/ref/percentage_width_inline_block_a.html | 17 +++++++++++++++++ .../ref/percentage_width_inline_block_ref.html | 16 ++++++++++++++++ 6 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 tests/ref/percentage_width_inline_block_a.html create mode 100644 tests/ref/percentage_width_inline_block_ref.html diff --git a/components/layout/block.rs b/components/layout/block.rs index fa3a13c58e7..c77c9266345 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -2134,9 +2134,9 @@ pub trait ISizeAndMarginsComputer { } fn containing_block_inline_size(&self, - _: &mut BlockFlow, - parent_flow_inline_size: Au, - _: &LayoutContext) + _: &mut BlockFlow, + parent_flow_inline_size: Au, + _: &LayoutContext) -> Au { parent_flow_inline_size } diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index b5c96816933..c8d496c04bf 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -1897,6 +1897,19 @@ impl Fragment { } } + /// Determines the inline sizes of inline-block fragments. These cannot be fully computed until + /// inline size assignment has run for the child flow: thus it is computed "late", during + /// block size assignment. + pub fn update_late_computed_replaced_inline_size_if_necessary(&mut self) { + if let SpecificFragmentInfo::InlineBlock(ref mut inline_block_info) = self.specific { + let block_flow = inline_block_info.flow_ref.as_block(); + let margin = block_flow.fragment.style.logical_margin(); + self.border_box.size.inline = block_flow.fragment.border_box.size.inline + + MaybeAuto::from_style(margin.inline_start, Au(0)).specified_or_zero() + + MaybeAuto::from_style(margin.inline_end, Au(0)).specified_or_zero() + } + } + pub fn update_late_computed_inline_position_if_necessary(&mut self) { match self.specific { SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut info) => { diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 79d4db2fe5f..07a3068d65b 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -1283,10 +1283,11 @@ impl Flow for InlineFlow { // TODO(pcwalton): Cache the line scanner? debug!("assign_block_size_inline: floats in: {:?}", self.base.floats); - // Assign the block-size for the inline fragments. + // Assign the block-size and late-computed inline-sizes for the inline fragments. let containing_block_block_size = self.base.block_container_explicit_block_size.unwrap_or(Au(0)); for fragment in self.fragments.fragments.iter_mut() { + fragment.update_late_computed_replaced_inline_size_if_necessary(); fragment.assign_replaced_block_size_if_necessary( containing_block_block_size); } diff --git a/tests/ref/basic.list b/tests/ref/basic.list index 9a9e015e4fb..07182d40582 100644 --- a/tests/ref/basic.list +++ b/tests/ref/basic.list @@ -233,6 +233,7 @@ experimental != overconstrained_block.html overconstrained_block_ref.html == percent_height.html percent_height_ref.html == percentage_height_float_a.html percentage_height_float_ref.html == percentage_height_root.html percentage_height_root_ref.html +== percentage_width_inline_block_a.html percentage_width_inline_block_ref.html == png_rgba_colorspace_a.html png_rgba_colorspace_b.html == position_abs_cb_with_non_cb_kid_a.html position_abs_cb_with_non_cb_kid_b.html == position_abs_height_width_a.html position_abs_height_width_b.html diff --git a/tests/ref/percentage_width_inline_block_a.html b/tests/ref/percentage_width_inline_block_a.html new file mode 100644 index 00000000000..0e04a34c0b1 --- /dev/null +++ b/tests/ref/percentage_width_inline_block_a.html @@ -0,0 +1,17 @@ + + + + + + +Y
X
+ + + diff --git a/tests/ref/percentage_width_inline_block_ref.html b/tests/ref/percentage_width_inline_block_ref.html new file mode 100644 index 00000000000..375c7c8354f --- /dev/null +++ b/tests/ref/percentage_width_inline_block_ref.html @@ -0,0 +1,16 @@ + + + + + + +Y
X
+ + + From decfb0da6edec9857c304932f3c6fa5ca23b8f07 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Wed, 20 May 2015 07:10:55 +1000 Subject: [PATCH 10/38] Address review comments --- components/script/script_task.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/script/script_task.rs b/components/script/script_task.rs index e291d98e5ee..fcc0615213a 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -1086,7 +1086,6 @@ impl ScriptTask { }); if let Some(idx) = idx { - // TODO(gw): This probably leaks resources! let load = self.incomplete_loads.borrow_mut().remove(idx); // Tell the layout task to begin shutting down, and wait until it @@ -1094,7 +1093,7 @@ impl ScriptTask { let (response_chan, response_port) = channel(); let LayoutChan(chan) = load.layout_chan; if chan.send(layout_interface::Msg::PrepareToExit(response_chan)).is_ok() { - debug!("shutting down layout for root page {:?}", id); + debug!("shutting down layout for page {:?}", id); response_port.recv().unwrap(); chan.send(layout_interface::Msg::ExitNow(exit_type)).ok(); } From 23b18a841714a4dc8931fda0f73014699d2cbbbe Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Wed, 20 May 2015 07:55:22 +1000 Subject: [PATCH 11/38] Handle case where a page fetch completes after pipeline exits. --- components/script/script_task.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/components/script/script_task.rs b/components/script/script_task.rs index fcc0615213a..0a9d97b4540 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -1062,12 +1062,15 @@ impl ScriptTask { /// Kick off the document and frame tree creation process using the result. fn handle_page_fetch_complete(&self, id: PipelineId, subpage: Option, response: LoadResponse) { - // Any notification received should refer to an existing, in-progress load that is tracked. let idx = self.incomplete_loads.borrow().iter().position(|load| { load.pipeline_id == id && load.parent_info.map(|info| info.1) == subpage - }).unwrap(); - let load = self.incomplete_loads.borrow_mut().remove(idx); - self.load(response, load); + }); + // The matching in progress load structure may not exist if + // the pipeline exited before the page load completed. + if let Some(idx) = idx { + let load = self.incomplete_loads.borrow_mut().remove(idx); + self.load(response, load); + } } /// Handles a request for the window title. From 41c243e853a1a19bac512fd26b6c9bae3402c4df Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Wed, 20 May 2015 09:22:08 +1000 Subject: [PATCH 12/38] Add closed pipelines record as a debugging aid --- components/script/script_task.rs | 33 +++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 0a9d97b4540..014e32f2f97 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -317,6 +317,9 @@ pub struct ScriptTask { js_runtime: Rc, mouse_over_targets: DOMRefCell>>, + + /// List of pipelines that have been owned and closed by this script task. + closed_pipelines: RefCell>, } /// In the event of task failure, all data on the stack runs its destructor. However, there @@ -494,7 +497,8 @@ impl ScriptTask { devtools_marker_sender: RefCell::new(None), js_runtime: Rc::new(runtime), - mouse_over_targets: DOMRefCell::new(vec!()) + mouse_over_targets: DOMRefCell::new(vec!()), + closed_pipelines: RefCell::new(HashSet::new()), } } @@ -1027,11 +1031,15 @@ impl ScriptTask { fn handle_reflow_complete_msg(&self, pipeline_id: PipelineId, reflow_id: u32) { debug!("Script: Reflow {:?} complete for {:?}", reflow_id, pipeline_id); let page = self.root_page(); - let page = page.find(pipeline_id).expect( - "ScriptTask: received a load message for a layout channel that is not associated \ - with this script task. This is a bug."); - let window = page.window().root(); - window.r().handle_reflow_complete_msg(reflow_id); + match page.find(pipeline_id) { + Some(page) => { + let window = page.window().root(); + window.r().handle_reflow_complete_msg(reflow_id); + } + None => { + assert!(self.closed_pipelines.borrow().contains(&pipeline_id)); + } + } } /// Window was resized, but this script was not active, so don't reflow yet @@ -1067,9 +1075,14 @@ impl ScriptTask { }); // The matching in progress load structure may not exist if // the pipeline exited before the page load completed. - if let Some(idx) = idx { - let load = self.incomplete_loads.borrow_mut().remove(idx); - self.load(response, load); + match idx { + Some(idx) => { + let load = self.incomplete_loads.borrow_mut().remove(idx); + self.load(response, load); + } + None => { + assert!(self.closed_pipelines.borrow().contains(&id)); + } } } @@ -1083,6 +1096,8 @@ impl ScriptTask { /// Handles a request to exit the script task and shut down layout. /// Returns true if the script task should shut down and false otherwise. fn handle_exit_pipeline_msg(&self, id: PipelineId, exit_type: PipelineExitType) -> bool { + self.closed_pipelines.borrow_mut().insert(id); + // Check if the exit message is for an in progress load. let idx = self.incomplete_loads.borrow().iter().position(|load| { load.pipeline_id == id From 7d9eda916be7b9bd95a34e90c7aef17ce5cb0a17 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 8 May 2015 12:55:32 -0700 Subject: [PATCH 13/38] script: Implement the `color` attribute of the `` element. Improves Hacker News. --- components/script/dom/element.rs | 20 ++- components/script/dom/htmlfontelement.rs | 62 ++++++++- components/script/dom/virtualmethods.rs | 10 +- .../script/dom/webidls/HTMLFontElement.webidl | 2 +- tests/ref/basic.list | 1 + tests/ref/font_color_attribute_a.html | 9 ++ tests/ref/font_color_attribute_ref.html | 9 ++ .../wpt/metadata/html/dom/interfaces.html.ini | 6 - .../html/dom/reflection-obsolete.html.ini | 129 ------------------ 9 files changed, 105 insertions(+), 143 deletions(-) create mode 100644 tests/ref/font_color_attribute_a.html create mode 100644 tests/ref/font_color_attribute_ref.html diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index f0ff55e2e5b..e8ae592e63c 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -17,7 +17,8 @@ use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementM use dom::bindings::codegen::Bindings::NamedNodeMapBinding::NamedNodeMapMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::InheritTypes::{ElementCast, ElementDerived, EventTargetCast}; -use dom::bindings::codegen::InheritTypes::{HTMLBodyElementDerived, HTMLInputElementCast}; +use dom::bindings::codegen::InheritTypes::{HTMLBodyElementDerived, HTMLFontElementDerived}; +use dom::bindings::codegen::InheritTypes::{HTMLInputElementCast}; use dom::bindings::codegen::InheritTypes::{HTMLInputElementDerived, HTMLTableElementCast}; use dom::bindings::codegen::InheritTypes::{HTMLTableElementDerived, HTMLTableCellElementDerived}; use dom::bindings::codegen::InheritTypes::{HTMLTableRowElementDerived, HTMLTextAreaElementDerived}; @@ -45,6 +46,7 @@ use dom::htmlanchorelement::HTMLAnchorElement; use dom::htmlbodyelement::{HTMLBodyElement, HTMLBodyElementHelpers}; use dom::htmlcollection::HTMLCollection; use dom::htmlelement::HTMLElementTypeId; +use dom::htmlfontelement::{HTMLFontElement, HTMLFontElementHelpers}; use dom::htmlinputelement::{HTMLInputElement, RawLayoutHTMLInputElementHelpers, HTMLInputElementHelpers}; use dom::htmltableelement::{HTMLTableElement, HTMLTableElementHelpers}; use dom::htmltablecellelement::{HTMLTableCellElement, HTMLTableCellElementHelpers}; @@ -64,7 +66,7 @@ use style::properties::{PropertyDeclarationBlock, PropertyDeclaration, parse_sty use style::properties::DeclaredValue::SpecifiedValue; use style::properties::longhands::{self, border_spacing}; use style::values::CSSFloat; -use style::values::specified::{self, CSSColor}; +use style::values::specified::{self, CSSColor, CSSRGBA}; use util::geometry::Au; use util::namespace; use util::smallvec::VecLike; @@ -269,6 +271,20 @@ impl RawLayoutElementHelpers for Element { CSSColor { parsed: Color::RGBA(color), authored: None })))); } + let color = if self.is_htmlfontelement() { + let this: &HTMLFontElement = mem::transmute(self); + this.get_color() + } else { + None + }; + + if let Some(color) = color { + hints.push(from_declaration( + PropertyDeclaration::Color(SpecifiedValue(CSSRGBA { + parsed: color, + authored: None, + })))); + } let cellspacing = if self.is_htmltableelement() { let this: &HTMLTableElement = mem::transmute(self); diff --git a/components/script/dom/htmlfontelement.rs b/components/script/dom/htmlfontelement.rs index 2df515cbc83..d2faa87441c 100644 --- a/components/script/dom/htmlfontelement.rs +++ b/components/script/dom/htmlfontelement.rs @@ -2,19 +2,26 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use dom::attr::{Attr, AttrHelpers}; use dom::bindings::codegen::Bindings::HTMLFontElementBinding; -use dom::bindings::codegen::InheritTypes::HTMLFontElementDerived; +use dom::bindings::codegen::Bindings::HTMLFontElementBinding::HTMLFontElementMethods; +use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLFontElementDerived}; use dom::bindings::js::{JSRef, Temporary}; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; use dom::htmlelement::{HTMLElement, HTMLElementTypeId}; use dom::node::{Node, NodeTypeId}; -use util::str::DOMString; +use dom::virtualmethods::VirtualMethods; +use util::str::{self, DOMString}; + +use cssparser::RGBA; +use std::cell::Cell; #[dom_struct] pub struct HTMLFontElement { - htmlelement: HTMLElement + htmlelement: HTMLElement, + color: Cell>, } impl HTMLFontElementDerived for EventTarget { @@ -26,7 +33,8 @@ impl HTMLFontElementDerived for EventTarget { impl HTMLFontElement { fn new_inherited(localName: DOMString, prefix: Option, document: JSRef) -> HTMLFontElement { HTMLFontElement { - htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLFontElement, localName, prefix, document) + htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLFontElement, localName, prefix, document), + color: Cell::new(None), } } @@ -37,3 +45,49 @@ impl HTMLFontElement { } } +impl<'a> HTMLFontElementMethods for JSRef<'a, HTMLFontElement> { + make_getter!(Color, "color"); + make_setter!(SetColor, "color"); +} + +impl<'a> VirtualMethods for JSRef<'a,HTMLFontElement> { + fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { + let htmlelement: &JSRef = HTMLElementCast::from_borrowed_ref(self); + Some(htmlelement as &VirtualMethods) + } + + fn after_set_attr(&self, attr: JSRef) { + if let Some(ref s) = self.super_type() { + s.after_set_attr(attr); + } + + match attr.local_name() { + &atom!("color") => { + self.color.set(str::parse_legacy_color(&attr.value()).ok()) + } + _ => {} + } + } + + fn before_remove_attr(&self, attr: JSRef) { + if let Some(ref s) = self.super_type() { + s.before_remove_attr(attr); + } + + match attr.local_name() { + &atom!("color") => self.color.set(None), + _ => () + } + } +} + +pub trait HTMLFontElementHelpers { + fn get_color(&self) -> Option; +} + +impl HTMLFontElementHelpers for HTMLFontElement { + fn get_color(&self) -> Option { + self.color.get() + } +} + diff --git a/components/script/dom/virtualmethods.rs b/components/script/dom/virtualmethods.rs index 2147ee07c48..a83c801831d 100644 --- a/components/script/dom/virtualmethods.rs +++ b/components/script/dom/virtualmethods.rs @@ -12,6 +12,7 @@ use dom::bindings::codegen::InheritTypes::HTMLButtonElementCast; use dom::bindings::codegen::InheritTypes::HTMLCanvasElementCast; use dom::bindings::codegen::InheritTypes::HTMLElementCast; use dom::bindings::codegen::InheritTypes::HTMLFieldSetElementCast; +use dom::bindings::codegen::InheritTypes::HTMLFontElementCast; use dom::bindings::codegen::InheritTypes::HTMLFormElementCast; use dom::bindings::codegen::InheritTypes::HTMLHeadElementCast; use dom::bindings::codegen::InheritTypes::HTMLIFrameElementCast; @@ -42,6 +43,8 @@ use dom::htmlbuttonelement::HTMLButtonElement; use dom::htmlcanvaselement::HTMLCanvasElement; use dom::htmlelement::{HTMLElement, HTMLElementTypeId}; use dom::htmlfieldsetelement::HTMLFieldSetElement; +use dom::htmlfontelement::HTMLFontElement; +use dom::htmlformelement::HTMLFormElement; use dom::htmlheadelement::HTMLHeadElement; use dom::htmliframeelement::HTMLIFrameElement; use dom::htmlimageelement::HTMLImageElement; @@ -169,8 +172,13 @@ pub fn vtable_for<'a>(node: &'a JSRef<'a, Node>) -> &'a (VirtualMethods + 'a) { let element: &'a JSRef<'a, HTMLFieldSetElement> = HTMLFieldSetElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } + NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLFontElement)) => { + let element: &'a JSRef<'a, HTMLFontElement> = HTMLFontElementCast::to_borrowed_ref(node).unwrap(); + element as &'a (VirtualMethods + 'a) + } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLFormElement)) => { - HTMLFormElementCast::to_borrowed_ref(node).unwrap() as &'a (VirtualMethods + 'a) + let element: &'a JSRef<'a, HTMLFormElement> = HTMLFormElementCast::to_borrowed_ref(node).unwrap(); + element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLHeadElement)) => { let element: &'a JSRef<'a, HTMLHeadElement> = HTMLHeadElementCast::to_borrowed_ref(node).unwrap(); diff --git a/components/script/dom/webidls/HTMLFontElement.webidl b/components/script/dom/webidls/HTMLFontElement.webidl index 9a58672baf5..03b68498db7 100644 --- a/components/script/dom/webidls/HTMLFontElement.webidl +++ b/components/script/dom/webidls/HTMLFontElement.webidl @@ -5,7 +5,7 @@ // https://www.whatwg.org/html/#htmlfontelement interface HTMLFontElement : HTMLElement { - //[TreatNullAs=EmptyString] attribute DOMString color; + [TreatNullAs=EmptyString] attribute DOMString color; // attribute DOMString face; // attribute DOMString size; }; diff --git a/tests/ref/basic.list b/tests/ref/basic.list index 9a9e015e4fb..847fe5499f8 100644 --- a/tests/ref/basic.list +++ b/tests/ref/basic.list @@ -102,6 +102,7 @@ flaky_cpu == append_style_a.html append_style_b.html == floated_table_with_margin_a.html floated_table_with_margin_ref.html == focus_selector.html focus_selector_ref.html == font_advance.html font_advance_ref.html +== font_color_attribute_a.html font_color_attribute_ref.html == font_size.html font_size_ref.html == font_style.html font_style_ref.html == height_compute_reset.html height_compute.html diff --git a/tests/ref/font_color_attribute_a.html b/tests/ref/font_color_attribute_a.html new file mode 100644 index 00000000000..320f662ea15 --- /dev/null +++ b/tests/ref/font_color_attribute_a.html @@ -0,0 +1,9 @@ + + + + + +

Servo

+ + + diff --git a/tests/ref/font_color_attribute_ref.html b/tests/ref/font_color_attribute_ref.html new file mode 100644 index 00000000000..7fab0492782 --- /dev/null +++ b/tests/ref/font_color_attribute_ref.html @@ -0,0 +1,9 @@ + + + + + +

Servo

+ + + diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini index c0e0586d1b1..6dfe517ace6 100644 --- a/tests/wpt/metadata/html/dom/interfaces.html.ini +++ b/tests/wpt/metadata/html/dom/interfaces.html.ini @@ -9255,18 +9255,12 @@ [HTMLFontElement interface object length] expected: FAIL - [HTMLFontElement interface: attribute color] - expected: FAIL - [HTMLFontElement interface: attribute face] expected: FAIL [HTMLFontElement interface: attribute size] expected: FAIL - [HTMLFontElement interface: document.createElement("font") must inherit property "color" with the proper type (0)] - expected: FAIL - [HTMLFontElement interface: document.createElement("font") must inherit property "face" with the proper type (1)] expected: FAIL diff --git a/tests/wpt/metadata/html/dom/reflection-obsolete.html.ini b/tests/wpt/metadata/html/dom/reflection-obsolete.html.ini index 9cf4851242b..4b892b43332 100644 --- a/tests/wpt/metadata/html/dom/reflection-obsolete.html.ini +++ b/tests/wpt/metadata/html/dom/reflection-obsolete.html.ini @@ -8523,135 +8523,6 @@ [font.tabIndex: IDL set to -2147483648 followed by getAttribute()] expected: FAIL - [font.color: typeof IDL attribute] - expected: FAIL - - [font.color: IDL get with DOM attribute unset] - expected: FAIL - - [font.color: setAttribute() to "" followed by IDL get] - expected: FAIL - - [font.color: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by IDL get] - expected: FAIL - - [font.color: setAttribute() to undefined followed by IDL get] - expected: FAIL - - [font.color: setAttribute() to 7 followed by IDL get] - expected: FAIL - - [font.color: setAttribute() to 1.5 followed by IDL get] - expected: FAIL - - [font.color: setAttribute() to true followed by IDL get] - expected: FAIL - - [font.color: setAttribute() to false followed by IDL get] - expected: FAIL - - [font.color: setAttribute() to object "[object Object\]" followed by IDL get] - expected: FAIL - - [font.color: setAttribute() to NaN followed by IDL get] - expected: FAIL - - [font.color: setAttribute() to Infinity followed by IDL get] - expected: FAIL - - [font.color: setAttribute() to -Infinity followed by IDL get] - expected: FAIL - - [font.color: setAttribute() to "\\0" followed by IDL get] - expected: FAIL - - [font.color: setAttribute() to null followed by IDL get] - expected: FAIL - - [font.color: setAttribute() to object "test-toString" followed by IDL get] - expected: FAIL - - [font.color: setAttribute() to object "test-valueOf" followed by IDL get] - expected: FAIL - - [font.color: IDL set to "" followed by getAttribute()] - expected: FAIL - - [font.color: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by getAttribute()] - expected: FAIL - - [font.color: IDL set to undefined followed by getAttribute()] - expected: FAIL - - [font.color: IDL set to undefined followed by IDL get] - expected: FAIL - - [font.color: IDL set to 7 followed by getAttribute()] - expected: FAIL - - [font.color: IDL set to 7 followed by IDL get] - expected: FAIL - - [font.color: IDL set to 1.5 followed by getAttribute()] - expected: FAIL - - [font.color: IDL set to 1.5 followed by IDL get] - expected: FAIL - - [font.color: IDL set to true followed by getAttribute()] - expected: FAIL - - [font.color: IDL set to true followed by IDL get] - expected: FAIL - - [font.color: IDL set to false followed by getAttribute()] - expected: FAIL - - [font.color: IDL set to false followed by IDL get] - expected: FAIL - - [font.color: IDL set to object "[object Object\]" followed by getAttribute()] - expected: FAIL - - [font.color: IDL set to object "[object Object\]" followed by IDL get] - expected: FAIL - - [font.color: IDL set to NaN followed by getAttribute()] - expected: FAIL - - [font.color: IDL set to NaN followed by IDL get] - expected: FAIL - - [font.color: IDL set to Infinity followed by getAttribute()] - expected: FAIL - - [font.color: IDL set to Infinity followed by IDL get] - expected: FAIL - - [font.color: IDL set to -Infinity followed by getAttribute()] - expected: FAIL - - [font.color: IDL set to -Infinity followed by IDL get] - expected: FAIL - - [font.color: IDL set to "\\0" followed by getAttribute()] - expected: FAIL - - [font.color: IDL set to null followed by getAttribute()] - expected: FAIL - - [font.color: IDL set to null followed by IDL get] - expected: FAIL - - [font.color: IDL set to object "test-toString" followed by getAttribute()] - expected: FAIL - - [font.color: IDL set to object "test-toString" followed by IDL get] - expected: FAIL - - [font.color: IDL set to object "test-valueOf" followed by IDL get] - expected: FAIL - [font.face: typeof IDL attribute] expected: FAIL From 6a197719b30a5731b168b4ca5b6351f3d487d651 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 13 May 2015 17:13:59 -0700 Subject: [PATCH 14/38] compositing: Implement display ports and avoid creating display lists for items outside it. This improves Servo's performance on large pages. --- components/compositing/compositor.rs | 58 +++++++++++++- components/compositing/pipeline.rs | 2 + components/gfx/paint_task.rs | 5 +- components/layout/block.rs | 63 +++++++++++---- components/layout/context.rs | 7 ++ components/layout/display_list_builder.rs | 36 +++++++-- components/layout/flow.rs | 25 ++++-- components/layout/inline.rs | 14 +++- components/layout/layout_task.rs | 94 ++++++++++++++++++++++- components/layout/list_item.rs | 4 +- components/layout/multicol.rs | 4 +- components/layout/table.rs | 4 +- components/layout/table_caption.rs | 8 +- components/layout/table_cell.rs | 8 +- components/layout/table_row.rs | 4 +- components/layout/table_rowgroup.rs | 4 +- components/layout/table_wrapper.rs | 4 +- components/layout/traversal.rs | 2 +- components/layout_traits/Cargo.toml | 3 + components/layout_traits/lib.rs | 11 ++- components/msg/compositor_msg.rs | 2 +- components/script/layout_interface.rs | 5 ++ components/servo/Cargo.lock | 1 + ports/cef/Cargo.lock | 1 + ports/gonk/Cargo.lock | 1 + tests/html/lipsum-large.html | 36 +++++++++ 26 files changed, 340 insertions(+), 66 deletions(-) create mode 100644 tests/html/lipsum-large.html diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index 4ba546fbe92..cd2c66e84b8 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -14,7 +14,7 @@ use windowing::{MouseWindowEvent, WindowEvent, WindowMethods, WindowNavigateMsg} use geom::point::{Point2D, TypedPoint2D}; use geom::rect::{Rect, TypedRect}; use geom::scale_factor::ScaleFactor; -use geom::size::TypedSize2D; +use geom::size::{Size2D, TypedSize2D}; use gfx::color; use gfx::paint_task::Msg as PaintMsg; use gfx::paint_task::PaintRequest; @@ -25,6 +25,7 @@ use layers::layers::{BufferRequest, Layer, LayerBuffer, LayerBufferSet}; use layers::rendergl::RenderContext; use layers::rendergl; use layers::scene::Scene; +use layout_traits::{LayoutControlChan, LayoutControlMsg}; use msg::compositor_msg::{Epoch, FrameTreeId, LayerId}; use msg::compositor_msg::{LayerProperties, ScrollPolicy}; use msg::constellation_msg::AnimationState; @@ -45,7 +46,7 @@ use std::sync::mpsc::Sender; use style::viewport::ViewportConstraints; use time::{precise_time_ns, precise_time_s}; use url::Url; -use util::geometry::{PagePx, ScreenPx, ViewportPx}; +use util::geometry::{Au, PagePx, ScreenPx, ViewportPx}; use util::opts; /// Holds the state when running reftests that determines when it is @@ -434,7 +435,8 @@ impl IOCompositor { self.remove_pipeline_root_layer(pipeline_id); } - (Msg::ViewportConstrained(pipeline_id, constraints), ShutdownState::NotShuttingDown) => { + (Msg::ViewportConstrained(pipeline_id, constraints), + ShutdownState::NotShuttingDown) => { self.constrain_viewport(pipeline_id, constraints); } @@ -701,7 +703,7 @@ impl IOCompositor { panic!("Compositor: Tried to scroll to fragment with unknown layer."); } - self.start_scrolling_timer_if_necessary(); + self.perform_updates_after_scroll(); } } @@ -937,9 +939,57 @@ impl IOCompositor { } } + /// Computes new display ports for each layer, taking the scroll position into account, and + /// sends them to layout as necessary. This ultimately triggers a rerender of the content. + fn send_updated_display_ports_to_layout(&mut self) { + fn process_layer(layer: &Layer, + window_size: &TypedSize2D, + new_display_ports: &mut HashMap)>>) { + let visible_rect = + Rect(Point2D::zero(), *window_size).translate(&-*layer.content_offset.borrow()) + .intersection(&*layer.bounds.borrow()) + .unwrap_or(Rect::zero()) + .to_untyped(); + let visible_rect = Rect(Point2D(Au::from_f32_px(visible_rect.origin.x), + Au::from_f32_px(visible_rect.origin.y)), + Size2D(Au::from_f32_px(visible_rect.size.width), + Au::from_f32_px(visible_rect.size.height))); + + let extra_layer_data = layer.extra_data.borrow(); + if !new_display_ports.contains_key(&extra_layer_data.pipeline_id) { + new_display_ports.insert(extra_layer_data.pipeline_id, Vec::new()); + } + new_display_ports.get_mut(&extra_layer_data.pipeline_id) + .unwrap() + .push((extra_layer_data.id, visible_rect)); + + for kid in layer.children.borrow().iter() { + process_layer(&*kid, window_size, new_display_ports) + } + } + + let dppx = self.page_zoom * self.device_pixels_per_screen_px(); + let window_size = self.window_size.as_f32() / dppx * ScaleFactor::new(1.0); + let mut new_visible_rects = HashMap::new(); + if let Some(ref layer) = self.scene.root { + process_layer(&**layer, &window_size, &mut new_visible_rects) + } + + for (pipeline_id, new_visible_rects) in new_visible_rects.iter() { + if let Some(pipeline_details) = self.pipeline_details.get(&pipeline_id) { + if let Some(ref pipeline) = pipeline_details.pipeline { + let LayoutControlChan(ref sender) = pipeline.layout_chan; + sender.send(LayoutControlMsg::SetVisibleRects((*new_visible_rects).clone())) + .unwrap() + } + } + } + } + /// Performs buffer requests and starts the scrolling timer or schedules a recomposite as /// necessary. fn perform_updates_after_scroll(&mut self) { + self.send_updated_display_ports_to_layout(); if self.send_buffer_requests_for_all_layers() { self.start_scrolling_timer_if_necessary(); } else { diff --git a/components/compositing/pipeline.rs b/components/compositing/pipeline.rs index 6ed96704be4..4adf2ae5ebd 100644 --- a/components/compositing/pipeline.rs +++ b/components/compositing/pipeline.rs @@ -52,6 +52,7 @@ pub struct Pipeline { pub struct CompositionPipeline { pub id: PipelineId, pub script_chan: ScriptControlChan, + pub layout_chan: LayoutControlChan, pub paint_chan: PaintChan, } @@ -245,6 +246,7 @@ impl Pipeline { CompositionPipeline { id: self.id.clone(), script_chan: self.script_chan.clone(), + layout_chan: self.layout_chan.clone(), paint_chan: self.paint_chan.clone(), } } diff --git a/components/gfx/paint_task.rs b/components/gfx/paint_task.rs index 4b9f2c6f6d1..62a368b18d9 100644 --- a/components/gfx/paint_task.rs +++ b/components/gfx/paint_task.rs @@ -245,7 +245,10 @@ impl PaintTask where C: PaintListener + Send + 'static { } debug!("PaintTask: returning surfaces"); - self.compositor.assign_painted_buffers(self.id, self.current_epoch.unwrap(), replies, frame_tree_id); + self.compositor.assign_painted_buffers(self.id, + self.current_epoch.unwrap(), + replies, + frame_tree_id); } Msg::UnusedBuffer(unused_buffers) => { debug!("PaintTask {:?}: Received {} unused buffers", self.id, unused_buffers.len()); diff --git a/components/layout/block.rs b/components/layout/block.rs index c77c9266345..dccee7cfe27 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -43,6 +43,7 @@ use flow::{CLEARS_LEFT, CLEARS_RIGHT}; use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo}; use incremental::{REFLOW, REFLOW_OUT_OF_FLOW}; use layout_debug; +use layout_task::DISPLAY_PORT_SIZE_FACTOR; use model::{IntrinsicISizes, MarginCollapseInfo}; use model::{MaybeAuto, CollapsibleMargins, specified, specified_or_none}; use wrapper::ThreadSafeLayoutNode; @@ -59,7 +60,7 @@ use style::computed_values::{position, text_align}; use style::properties::ComputedValues; use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto}; use style::values::computed::{LengthOrPercentageOrNone}; -use util::geometry::{Au, MAX_AU}; +use util::geometry::{Au, MAX_AU, MAX_RECT}; use util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode}; use util::opts; @@ -377,7 +378,9 @@ impl Iterator for CandidateBSizeIterator { Some(max_block_size) if self.candidate_value > max_block_size => { CandidateBSizeIteratorStatus::TryingMax } - _ if self.candidate_value < self.min_block_size => CandidateBSizeIteratorStatus::TryingMin, + _ if self.candidate_value < self.min_block_size => { + CandidateBSizeIteratorStatus::TryingMin + } _ => CandidateBSizeIteratorStatus::Found, } } @@ -718,13 +721,16 @@ impl BlockFlow { return } - let (block_start_margin_value, block_end_margin_value) = match self.base.collapsible_margins { - CollapsibleMargins::CollapseThrough(_) => panic!("Margins unexpectedly collapsed through root flow."), - CollapsibleMargins::Collapse(block_start_margin, block_end_margin) => { - (block_start_margin.collapse(), block_end_margin.collapse()) - } - CollapsibleMargins::None(block_start, block_end) => (block_start, block_end), - }; + let (block_start_margin_value, block_end_margin_value) = + match self.base.collapsible_margins { + CollapsibleMargins::CollapseThrough(_) => { + panic!("Margins unexpectedly collapsed through root flow.") + } + CollapsibleMargins::Collapse(block_start_margin, block_end_margin) => { + (block_start_margin.collapse(), block_end_margin.collapse()) + } + CollapsibleMargins::None(block_start, block_end) => (block_start, block_end), + }; // Shift all kids down (or up, if margins are negative) if necessary. if block_start_margin_value != Au(0) { @@ -757,7 +763,8 @@ impl BlockFlow { pub fn assign_block_size_block_base<'a>(&mut self, layout_context: &'a LayoutContext<'a>, margins_may_collapse: MarginsMayCollapseFlag) { - let _scope = layout_debug_scope!("assign_block_size_block_base {:x}", self.base.debug_id()); + let _scope = layout_debug_scope!("assign_block_size_block_base {:x}", + self.base.debug_id()); if self.base.restyle_damage.contains(REFLOW) { // Our current border-box position. @@ -1661,13 +1668,14 @@ impl Flow for BlockFlow { } } - fn compute_absolute_position(&mut self) { + fn compute_absolute_position(&mut self, layout_context: &LayoutContext) { // FIXME (mbrubeck): Get the real container size, taking the container writing mode into // account. Must handle vertical writing modes. let container_size = Size2D(self.base.block_container_inline_size, Au(0)); if self.is_root() { - self.base.clip = ClippingRegion::max() + self.base.clip = ClippingRegion::max(); + self.base.stacking_relative_position_of_display_port = MAX_RECT; } if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) { @@ -1761,7 +1769,8 @@ impl Flow for BlockFlow { let relative_offset = relative_offset.to_physical(self.base.writing_mode); let origin_for_children; let clip_in_child_coordinate_system; - if self.fragment.establishes_stacking_context() { + let is_stacking_context = self.fragment.establishes_stacking_context(); + if is_stacking_context { // We establish a stacking context, so the position of our children is vertically // correct, but has to be adjusted to accommodate horizontal margins. (Note the // calculation involving `position` below and recall that inline-direction flow @@ -1771,11 +1780,31 @@ impl Flow for BlockFlow { let margin = self.fragment.margin.to_physical(self.base.writing_mode); origin_for_children = Point2D(-margin.left, Au(0)) + relative_offset; clip_in_child_coordinate_system = - self.base.clip.translate(&-self.base.stacking_relative_position) + self.base.clip.translate(&-self.base.stacking_relative_position); } else { origin_for_children = self.base.stacking_relative_position + relative_offset; - clip_in_child_coordinate_system = self.base.clip.clone() + clip_in_child_coordinate_system = self.base.clip.clone(); } + + let stacking_relative_position_of_display_port_for_children = + if (is_stacking_context && self.will_get_layer()) || self.is_root() { + let visible_rect = + match layout_context.shared.visible_rects.get(&self.layer_id(0)) { + Some(visible_rect) => *visible_rect, + None => Rect(Point2D::zero(), layout_context.shared.screen_size), + }; + + let screen_size = layout_context.shared.screen_size; + visible_rect.inflate(screen_size.width * DISPLAY_PORT_SIZE_FACTOR, + screen_size.height * DISPLAY_PORT_SIZE_FACTOR) + } else if is_stacking_context { + self.base + .stacking_relative_position_of_display_port + .translate(&-self.base.stacking_relative_position) + } else { + self.base.stacking_relative_position_of_display_port + }; + let stacking_relative_border_box = self.fragment .stacking_relative_border_box(&self.base.stacking_relative_position, @@ -1820,7 +1849,9 @@ impl Flow for BlockFlow { } flow::mut_base(kid).absolute_position_info = absolute_position_info_for_children; - flow::mut_base(kid).clip = clip.clone() + flow::mut_base(kid).clip = clip.clone(); + flow::mut_base(kid).stacking_relative_position_of_display_port = + stacking_relative_position_of_display_port_for_children; } } diff --git a/components/layout/context.rs b/components/layout/context.rs index 9a7550fd2d6..e83f4453b04 100644 --- a/components/layout/context.rs +++ b/components/layout/context.rs @@ -12,17 +12,21 @@ use geom::{Rect, Size2D}; use gfx::display_list::OpaqueNode; use gfx::font_cache_task::FontCacheTask; use gfx::font_context::FontContext; +use msg::compositor_msg::LayerId; use msg::constellation_msg::ConstellationChan; use net_traits::image::base::Image; use net_traits::image_cache_task::{ImageCacheChan, ImageCacheTask, ImageState}; use script::layout_interface::{Animation, LayoutChan, ReflowGoal}; use std::boxed; use std::cell::Cell; +use std::collections::HashMap; +use std::collections::hash_state::DefaultState; use std::ptr; use std::sync::Arc; use std::sync::mpsc::{channel, Sender}; use style::selector_matching::Stylist; use url::Url; +use util::fnv::FnvHasher; use util::geometry::Au; use util::opts; @@ -99,6 +103,9 @@ pub struct SharedLayoutContext { /// sent. pub new_animations_sender: Sender, + /// The visible rects for each layer, as reported to us by the compositor. + pub visible_rects: Arc, DefaultState>>, + /// Why is this reflow occurring pub goal: ReflowGoal, } diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 3c615ed0e9d..aac8a7c2317 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -176,6 +176,8 @@ pub trait FragmentDisplayListBuilding { /// * `relative_containing_block_size`: The size of the containing block that /// `position: relative` makes use of. /// * `clip`: The region to clip the display items to. + /// * `stacking_relative_display_port`: The position and size of the display port with respect + /// to the nearest ancestor stacking context. fn build_display_list(&mut self, display_list: &mut DisplayList, layout_context: &LayoutContext, @@ -184,7 +186,8 @@ pub trait FragmentDisplayListBuilding { relative_containing_block_mode: WritingMode, border_painting_mode: BorderPaintingMode, background_and_border_level: BackgroundAndBorderLevel, - clip: &ClippingRegion); + clip: &ClippingRegion, + stacking_relative_display_port: &Rect); /// Sends the size and position of this iframe fragment to the constellation. This is out of /// line to guide inlining. @@ -866,7 +869,8 @@ impl FragmentDisplayListBuilding for Fragment { relative_containing_block_mode: WritingMode, border_painting_mode: BorderPaintingMode, background_and_border_level: BackgroundAndBorderLevel, - clip: &ClippingRegion) { + clip: &ClippingRegion, + stacking_relative_display_port: &Rect) { if self.style().get_inheritedbox().visibility != visibility::T::visible { return } @@ -888,6 +892,11 @@ impl FragmentDisplayListBuilding for Fragment { stacking_relative_flow_origin, self); + if !stacking_relative_border_box.intersects(stacking_relative_display_port) { + debug!("Fragment::build_display_list: outside display port"); + return + } + if !stacking_relative_border_box.intersects(&layout_context.shared.dirty) { debug!("Fragment::build_display_list: Did not intersect..."); return @@ -1076,7 +1085,8 @@ impl FragmentDisplayListBuilding for Fragment { let (sender, receiver) = channel::>(); let canvas_data = match canvas_fragment_info.renderer { Some(ref renderer) => { - renderer.lock().unwrap().send(CanvasMsg::Common(CanvasCommonMsg::SendPixelContents(sender))).unwrap(); + renderer.lock().unwrap().send(CanvasMsg::Common( + CanvasCommonMsg::SendPixelContents(sender))).unwrap(); receiver.recv().unwrap() }, None => repeat(0xFFu8).take(width * height * 4).collect(), @@ -1364,6 +1374,7 @@ pub trait BlockFlowDisplayListBuilding { display_list: Box, layout_context: &LayoutContext, border_painting_mode: BorderPaintingMode); + fn will_get_layer(&self) -> bool; } impl BlockFlowDisplayListBuilding for BlockFlow { @@ -1386,7 +1397,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow { self.base.absolute_position_info.relative_containing_block_mode, border_painting_mode, background_border_level, - &clip); + &clip, + &self.base.stacking_relative_position_of_display_port); // Add children. for kid in self.base.children.iter_mut() { @@ -1422,6 +1434,11 @@ impl BlockFlowDisplayListBuilding for BlockFlow { } } + fn will_get_layer(&self) -> bool { + self.base.absolute_position_info.layers_needed_for_positioned_flows || + self.base.flags.contains(NEEDS_LAYER) + } + fn build_display_list_for_absolutely_positioned_block( &mut self, mut display_list: Box, @@ -1432,8 +1449,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { border_painting_mode, BackgroundAndBorderLevel::RootOfStackingContext); - if !self.base.absolute_position_info.layers_needed_for_positioned_flows && - !self.base.flags.contains(NEEDS_LAYER) { + if !self.will_get_layer() { // We didn't need a layer. self.base.display_list_building_result = DisplayListBuildingResult::StackingContext(self.fragment.create_stacking_context( @@ -1524,7 +1540,8 @@ impl InlineFlowDisplayListBuilding for InlineFlow { .relative_containing_block_mode, BorderPaintingMode::Separate, BackgroundAndBorderLevel::Content, - &self.base.clip); + &self.base.clip, + &self.base.stacking_relative_position_of_display_port); has_stacking_context = fragment.establishes_stacking_context(); match fragment.specific { @@ -1597,7 +1614,10 @@ impl ListItemFlowDisplayListBuilding for ListItemFlow { .relative_containing_block_mode, BorderPaintingMode::Separate, BackgroundAndBorderLevel::Content, - &self.block_flow.base.clip); + &self.block_flow.base.clip, + &self.block_flow + .base + .stacking_relative_position_of_display_port); } // Draw the rest of the block. diff --git a/components/layout/flow.rs b/components/layout/flow.rs index 57edf9ccd45..11d1c017db6 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -271,7 +271,7 @@ pub trait Flow: fmt::Debug + Sync { } /// Phase 4 of reflow: computes absolute positions. - fn compute_absolute_position(&mut self) { + fn compute_absolute_position(&mut self, _: &LayoutContext) { // The default implementation is a no-op. } @@ -859,6 +859,12 @@ pub struct BaseFlow { /// The clipping region for this flow and its descendants, in layer coordinates. pub clip: ClippingRegion, + /// The stacking-relative position of the display port. + /// + /// FIXME(pcwalton): This might be faster as an Arc, since this varies only + /// per-stacking-context. + pub stacking_relative_position_of_display_port: Rect, + /// The results of display list building for this flow. pub display_list_building_result: DisplayListBuildingResult, @@ -909,10 +915,18 @@ impl Encodable for BaseFlow { FlowClass::Block => c.as_immutable_block().encode(e), FlowClass::Inline => c.as_immutable_inline().encode(e), FlowClass::Table => c.as_immutable_table().encode(e), - FlowClass::TableWrapper => c.as_immutable_table_wrapper().encode(e), - FlowClass::TableRowGroup => c.as_immutable_table_rowgroup().encode(e), - FlowClass::TableRow => c.as_immutable_table_row().encode(e), - FlowClass::TableCell => c.as_immutable_table_cell().encode(e), + FlowClass::TableWrapper => { + c.as_immutable_table_wrapper().encode(e) + } + FlowClass::TableRowGroup => { + c.as_immutable_table_rowgroup().encode(e) + } + FlowClass::TableRow => { + c.as_immutable_table_row().encode(e) + } + FlowClass::TableCell => { + c.as_immutable_table_cell().encode(e) + } _ => { Ok(()) } // TODO: Support captions } }) @@ -1024,6 +1038,7 @@ impl BaseFlow { display_list_building_result: DisplayListBuildingResult::None, absolute_position_info: AbsolutePositionInfo::new(writing_mode), clip: ClippingRegion::max(), + stacking_relative_position_of_display_port: Rect::zero(), flags: flags, writing_mode: writing_mode, thread_id: 0, diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 07a3068d65b..2ac426776a0 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -1464,7 +1464,7 @@ impl Flow for InlineFlow { self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW); } - fn compute_absolute_position(&mut self) { + fn compute_absolute_position(&mut self, _: &LayoutContext) { // First, gather up the positions of all the containing blocks (if any). let mut containing_block_positions = Vec::new(); let container_size = Size2D(self.base.block_container_inline_size, Au(0)); @@ -1504,14 +1504,18 @@ impl Flow for InlineFlow { 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 + stacking_relative_border_box.origin; + block_flow.base.stacking_relative_position_of_display_port = + self.base.stacking_relative_position_of_display_port; } SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut info) => { 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 + stacking_relative_border_box.origin; + block_flow.base.stacking_relative_position_of_display_port = + self.base.stacking_relative_position_of_display_port; } SpecificFragmentInfo::InlineAbsolute(ref mut info) => { @@ -1528,7 +1532,9 @@ impl Flow for InlineFlow { stacking_relative_position + *padding_box_origin; block_flow.base.stacking_relative_position = - stacking_relative_border_box.origin + stacking_relative_border_box.origin; + block_flow.base.stacking_relative_position_of_display_port = + self.base.stacking_relative_position_of_display_port; } _ => {} } diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 7b30e10e727..0bf583627d1 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -11,12 +11,12 @@ use animation; use construct::ConstructionResult; use context::{SharedLayoutContext, SharedLayoutContextWrapper}; use css::node_style::StyledNode; +use data::{LayoutDataAccess, LayoutDataWrapper}; use display_list_builder::ToGfxColor; use flow::{self, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils}; use flow_ref::FlowRef; use fragment::{Fragment, FragmentBorderBoxIterator}; use incremental::{LayoutDamageComputation, REFLOW, REFLOW_ENTIRE_DOCUMENT, REPAINT}; -use data::{LayoutDataAccess, LayoutDataWrapper}; use layout_debug; use opaque_node::OpaqueNodeMethods; use parallel::{self, UnsafeFlow}; @@ -39,7 +39,7 @@ use gfx::paint_task::Msg as PaintMsg; use gfx::paint_task::{PaintChan, PaintLayer}; use layout_traits::{LayoutControlMsg, LayoutTaskFactory}; use log; -use msg::compositor_msg::{Epoch, ScrollPolicy}; +use msg::compositor_msg::{Epoch, LayerId, ScrollPolicy}; use msg::constellation_msg::Msg as ConstellationMsg; use msg::constellation_msg::{ConstellationChan, Failure, PipelineExitType, PipelineId}; use profile_traits::mem::{self, Report, ReportsChan}; @@ -57,6 +57,8 @@ use script_traits::{ConstellationControlMsg, OpaqueScriptLayoutChannel}; use script_traits::{ScriptControlChan, StylesheetLoadResponder}; use std::borrow::ToOwned; use std::cell::Cell; +use std::collections::HashMap; +use std::collections::hash_state::DefaultState; use std::mem::transmute; use std::ops::{Deref, DerefMut}; use std::ptr; @@ -69,6 +71,7 @@ use style::selector_matching::Stylist; use style::stylesheets::{Origin, Stylesheet, CSSRuleIteratorExt}; use url::Url; use util::cursor::Cursor; +use util::fnv::FnvHasher; use util::geometry::{Au, MAX_RECT}; use util::logical_geometry::LogicalPoint; use util::mem::HeapSizeOf; @@ -77,6 +80,12 @@ use util::task::spawn_named_with_send_on_failure; use util::task_state; use util::workqueue::WorkQueue; +/// The number of screens of data we're allowed to generate display lists for in each direction. +pub const DISPLAY_PORT_SIZE_FACTOR: i32 = 8; + +/// The number of screens we have to traverse before we decide to generate new display lists. +const DISPLAY_PORT_THRESHOLD_SIZE_FACTOR: i32 = 4; + /// Mutable data belonging to the LayoutTask. /// /// This needs to be protected by a mutex so we can do fast RPCs. @@ -125,8 +134,12 @@ pub struct LayoutTaskData { /// sent. pub new_animations_sender: Sender, - /// A counter for epoch messages + /// A counter for epoch messages. epoch: Epoch, + + /// The position and size of the visible rect for each layer. We do not build display lists + /// for any areas more than `DISPLAY_PORT_SIZE_FACTOR` screens away from this area. + pub visible_rects: Arc, DefaultState>>, } /// Information needed by the layout task. @@ -330,6 +343,7 @@ impl LayoutTask { content_box_response: Rect::zero(), content_boxes_response: Vec::new(), running_animations: Vec::new(), + visible_rects: Arc::new(HashMap::with_hash_state(Default::default())), new_animations_receiver: new_animations_receiver, new_animations_sender: new_animations_sender, epoch: Epoch(0), @@ -365,6 +379,7 @@ impl LayoutTask { url: (*url).clone(), reflow_root: reflow_root.map(|node| OpaqueNodeMethods::from_layout_node(node)), dirty: Rect::zero(), + visible_rects: rw_data.visible_rects.clone(), generation: rw_data.generation, new_animations_sender: rw_data.new_animations_sender.clone(), goal: goal, @@ -406,6 +421,10 @@ impl LayoutTask { match port_to_read { PortToRead::Pipeline => { match self.pipeline_port.recv().unwrap() { + LayoutControlMsg::SetVisibleRects(new_visible_rects) => { + self.handle_request_helper(Msg::SetVisibleRects(new_visible_rects), + possibly_locked_rw_data) + } LayoutControlMsg::TickAnimations => { self.handle_request_helper(Msg::TickAnimations, possibly_locked_rw_data) } @@ -509,6 +528,9 @@ impl LayoutTask { || self.handle_reflow(&*data, possibly_locked_rw_data)); }, Msg::TickAnimations => self.tick_all_animations(possibly_locked_rw_data), + Msg::SetVisibleRects(new_visible_rects) => { + self.set_visible_rects(new_visible_rects, possibly_locked_rw_data); + } Msg::ReapLayoutData(dead_layout_data) => { unsafe { self.handle_reap_layout_data(dead_layout_data) @@ -964,6 +986,64 @@ impl LayoutTask { chan.send(ConstellationControlMsg::ReflowComplete(self.id, data.id)).unwrap(); } + fn set_visible_rects<'a>(&'a self, + new_visible_rects: Vec<(LayerId, Rect)>, + possibly_locked_rw_data: &mut Option>) + -> bool { + let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); + + // First, determine if we need to regenerate the display lists. This will happen if the + // layers have moved more than `DISPLAY_PORT_THRESHOLD_SIZE_FACTOR` away from their last + // positions. + let mut must_regenerate_display_lists = false; + let mut old_visible_rects = HashMap::with_hash_state(Default::default()); + let inflation_amount = + Size2D(rw_data.screen_size.width * DISPLAY_PORT_THRESHOLD_SIZE_FACTOR, + rw_data.screen_size.height * DISPLAY_PORT_THRESHOLD_SIZE_FACTOR); + for &(ref layer_id, ref new_visible_rect) in new_visible_rects.iter() { + match rw_data.visible_rects.get(layer_id) { + None => { + old_visible_rects.insert(*layer_id, *new_visible_rect); + } + Some(old_visible_rect) => { + old_visible_rects.insert(*layer_id, *old_visible_rect); + + if !old_visible_rect.inflate(inflation_amount.width, inflation_amount.height) + .intersects(new_visible_rect) { + must_regenerate_display_lists = true; + } + } + } + } + + if !must_regenerate_display_lists { + // Update `visible_rects` in case there are new layers that were discovered. + rw_data.visible_rects = Arc::new(old_visible_rects); + return true + } + + debug!("regenerating display lists!"); + for &(ref layer_id, ref new_visible_rect) in new_visible_rects.iter() { + old_visible_rects.insert(*layer_id, *new_visible_rect); + } + rw_data.visible_rects = Arc::new(old_visible_rects); + + // Regenerate the display lists. + let reflow_info = Reflow { + goal: ReflowGoal::ForDisplay, + page_clip_rect: MAX_RECT, + }; + + let mut layout_context = self.build_shared_layout_context(&*rw_data, + false, + None, + &self.url, + reflow_info.goal); + + self.perform_post_main_layout_passes(&reflow_info, &mut *rw_data, &mut layout_context); + true + } + fn tick_all_animations<'a>(&'a self, possibly_locked_rw_data: &mut Option>) { @@ -1045,7 +1125,15 @@ impl LayoutTask { } }); + self.perform_post_main_layout_passes(data, rw_data, layout_context); + } + + fn perform_post_main_layout_passes<'a>(&'a self, + data: &Reflow, + rw_data: &mut LayoutTaskData, + layout_context: &mut SharedLayoutContext) { // Build the display list if necessary, and send it to the painter. + let mut root_flow = (*rw_data.root_flow.as_ref().unwrap()).clone(); self.compute_abs_pos_and_build_display_list(data, &mut root_flow, &mut *layout_context, diff --git a/components/layout/list_item.rs b/components/layout/list_item.rs index c348986c69c..1840cc1fbde 100644 --- a/components/layout/list_item.rs +++ b/components/layout/list_item.rs @@ -117,8 +117,8 @@ impl Flow for ListItemFlow { } } - fn compute_absolute_position(&mut self) { - self.block_flow.compute_absolute_position() + fn compute_absolute_position(&mut self, layout_context: &LayoutContext) { + self.block_flow.compute_absolute_position(layout_context) } fn place_float_if_applicable<'a>(&mut self, layout_context: &'a LayoutContext<'a>) { diff --git a/components/layout/multicol.rs b/components/layout/multicol.rs index f33b2774a40..1ce84a365f1 100644 --- a/components/layout/multicol.rs +++ b/components/layout/multicol.rs @@ -63,8 +63,8 @@ impl Flow for MulticolFlow { self.block_flow.assign_block_size(ctx); } - fn compute_absolute_position(&mut self) { - self.block_flow.compute_absolute_position() + fn compute_absolute_position(&mut self, layout_context: &LayoutContext) { + self.block_flow.compute_absolute_position(layout_context) } fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) { diff --git a/components/layout/table.rs b/components/layout/table.rs index 3c9b832b190..9bb86eb9129 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -503,8 +503,8 @@ impl Flow for TableFlow { self.block_flow.assign_block_size_for_table_like_flow(layout_context, vertical_spacing) } - fn compute_absolute_position(&mut self) { - self.block_flow.compute_absolute_position() + fn compute_absolute_position(&mut self, layout_context: &LayoutContext) { + self.block_flow.compute_absolute_position(layout_context) } fn generated_containing_block_size(&self, flow: OpaqueFlow) -> LogicalSize { diff --git a/components/layout/table_caption.rs b/components/layout/table_caption.rs index 628b90c41c5..ab98e9b3261 100644 --- a/components/layout/table_caption.rs +++ b/components/layout/table_caption.rs @@ -59,13 +59,13 @@ impl Flow for TableCaptionFlow { self.block_flow.assign_inline_sizes(ctx); } - fn assign_block_size<'a>(&mut self, ctx: &'a LayoutContext<'a>) { + fn assign_block_size<'a>(&mut self, layout_context: &'a LayoutContext<'a>) { debug!("assign_block_size: assigning block_size for table_caption"); - self.block_flow.assign_block_size(ctx); + self.block_flow.assign_block_size(layout_context); } - fn compute_absolute_position(&mut self) { - self.block_flow.compute_absolute_position() + fn compute_absolute_position(&mut self, layout_context: &LayoutContext) { + self.block_flow.compute_absolute_position(layout_context) } fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) { diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs index 54ebe61c212..d44de741e60 100644 --- a/components/layout/table_cell.rs +++ b/components/layout/table_cell.rs @@ -160,13 +160,13 @@ impl Flow for TableCellFlow { |_, _, _, _, _, _| {}); } - fn assign_block_size<'a>(&mut self, ctx: &'a LayoutContext<'a>) { + fn assign_block_size<'a>(&mut self, layout_context: &'a LayoutContext<'a>) { debug!("assign_block_size: assigning block_size for table_cell"); - self.assign_block_size_table_cell_base(ctx); + self.assign_block_size_table_cell_base(layout_context); } - fn compute_absolute_position(&mut self) { - self.block_flow.compute_absolute_position() + fn compute_absolute_position(&mut self, layout_context: &LayoutContext) { + self.block_flow.compute_absolute_position(layout_context) } fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) { diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index b3a1ee93e91..ee9411a0513 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -403,8 +403,8 @@ impl Flow for TableRowFlow { self.assign_block_size_table_row_base(layout_context); } - fn compute_absolute_position(&mut self) { - self.block_flow.compute_absolute_position() + fn compute_absolute_position(&mut self, layout_context: &LayoutContext) { + self.block_flow.compute_absolute_position(layout_context) } fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) { diff --git a/components/layout/table_rowgroup.rs b/components/layout/table_rowgroup.rs index 088103188c7..2c76c30c832 100644 --- a/components/layout/table_rowgroup.rs +++ b/components/layout/table_rowgroup.rs @@ -203,8 +203,8 @@ impl Flow for TableRowGroupFlow { self.spacing.vertical) } - fn compute_absolute_position(&mut self) { - self.block_flow.compute_absolute_position() + fn compute_absolute_position(&mut self, layout_context: &LayoutContext) { + self.block_flow.compute_absolute_position(layout_context) } fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) { diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs index 592ad213f93..8f77e97dfd0 100644 --- a/components/layout/table_wrapper.rs +++ b/components/layout/table_wrapper.rs @@ -381,8 +381,8 @@ impl Flow for TableWrapperFlow { MarginsMayCollapseFlag::MarginsMayNotCollapse); } - fn compute_absolute_position(&mut self) { - self.block_flow.compute_absolute_position() + fn compute_absolute_position(&mut self, layout_context: &LayoutContext) { + self.block_flow.compute_absolute_position(layout_context) } fn place_float_if_applicable<'a>(&mut self, layout_context: &'a LayoutContext<'a>) { diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index 39169787cad..6106456876b 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -364,7 +364,7 @@ pub struct ComputeAbsolutePositions<'a> { impl<'a> PreorderFlowTraversal for ComputeAbsolutePositions<'a> { #[inline] fn process(&self, flow: &mut Flow) { - flow.compute_absolute_position(); + flow.compute_absolute_position(self.layout_context); } } diff --git a/components/layout_traits/Cargo.toml b/components/layout_traits/Cargo.toml index 17d706eeca3..0e0acf5da0a 100644 --- a/components/layout_traits/Cargo.toml +++ b/components/layout_traits/Cargo.toml @@ -7,6 +7,9 @@ authors = ["The Servo Project Developers"] name = "layout_traits" path = "lib.rs" +[dependencies.geom] +git = "https://github.com/servo/rust-geom" + [dependencies.gfx] path = "../gfx" diff --git a/components/layout_traits/lib.rs b/components/layout_traits/lib.rs index 7f374138079..df60e189438 100644 --- a/components/layout_traits/lib.rs +++ b/components/layout_traits/lib.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/. */ +extern crate geom; extern crate gfx; extern crate script_traits; extern crate msg; @@ -15,25 +16,29 @@ extern crate util; // The traits are here instead of in layout so // that these modules won't have to depend on layout. +use geom::rect::Rect; use gfx::font_cache_task::FontCacheTask; use gfx::paint_task::PaintChan; -use msg::compositor_msg::Epoch; +use msg::compositor_msg::{Epoch, LayerId}; use msg::constellation_msg::{ConstellationChan, Failure, PipelineId, PipelineExitType}; use profile_traits::mem; use profile_traits::time; use net_traits::image_cache_task::ImageCacheTask; -use url::Url; use script_traits::{ScriptControlChan, OpaqueScriptLayoutChannel}; use std::sync::mpsc::{Sender, Receiver}; +use util::geometry::Au; +use url::Url; -/// Messages sent to the layout task from the constellation +/// Messages sent to the layout task from the constellation and/or compositor. pub enum LayoutControlMsg { ExitNow(PipelineExitType), GetCurrentEpoch(Sender), TickAnimations, + SetVisibleRects(Vec<(LayerId, Rect)>), } /// A channel wrapper for constellation messages +#[derive(Clone)] pub struct LayoutControlChan(pub Sender); // A static method creating a layout task diff --git a/components/msg/compositor_msg.rs b/components/msg/compositor_msg.rs index 0ecd8f293ae..ed7844dd995 100644 --- a/components/msg/compositor_msg.rs +++ b/components/msg/compositor_msg.rs @@ -34,7 +34,7 @@ impl FrameTreeId { } } -#[derive(Clone, PartialEq, Eq, Copy)] +#[derive(Clone, PartialEq, Eq, Copy, Hash)] pub struct LayerId(pub usize, pub u32); impl Debug for LayerId { diff --git a/components/script/layout_interface.rs b/components/script/layout_interface.rs index ad474a0daed..2ebb00d5cf8 100644 --- a/components/script/layout_interface.rs +++ b/components/script/layout_interface.rs @@ -11,6 +11,7 @@ use dom::node::LayoutData; use geom::point::Point2D; use geom::rect::Rect; use libc::uintptr_t; +use msg::compositor_msg::LayerId; use msg::constellation_msg::{PipelineExitType, WindowSizeData}; use msg::compositor_msg::Epoch; use net_traits::PendingAsyncLoad; @@ -47,6 +48,10 @@ pub enum Msg { /// Requests that the layout task render the next frame of all animations. TickAnimations, + /// Updates the layout visible rects, affecting the area that display lists will be constructed + /// for. + SetVisibleRects(Vec<(LayerId, Rect)>), + /// Destroys layout data associated with a DOM node. /// /// TODO(pcwalton): Maybe think about batching to avoid message traffic. diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index fc3bf6baa8b..f2184517738 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -674,6 +674,7 @@ dependencies = [ name = "layout_traits" version = "0.0.1" dependencies = [ + "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gfx 0.0.1", "msg 0.0.1", "net_traits 0.0.1", diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index 1630fcca163..ac322cc6079 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -676,6 +676,7 @@ dependencies = [ name = "layout_traits" version = "0.0.1" dependencies = [ + "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gfx 0.0.1", "msg 0.0.1", "net_traits 0.0.1", diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock index 0a272d5fd01..815e6cf8af0 100644 --- a/ports/gonk/Cargo.lock +++ b/ports/gonk/Cargo.lock @@ -574,6 +574,7 @@ dependencies = [ name = "layout_traits" version = "0.0.1" dependencies = [ + "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gfx 0.0.1", "msg 0.0.1", "net_traits 0.0.1", diff --git a/tests/html/lipsum-large.html b/tests/html/lipsum-large.html new file mode 100644 index 00000000000..26458c34b3e --- /dev/null +++ b/tests/html/lipsum-large.html @@ -0,0 +1,36 @@ + +
+ + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat feugiat fermentum. Curabitur luctus consequat urna a tincidunt. Nullam vitae velit eu arcu congue volutpat in a diam. Pellentesque lacus ipsum, gravida et tristique sit amet, varius eu ipsum. Duis venenatis sem id nibh commodo tempor. Curabitur risus tellus, cursus quis pellentesque sed, elementum eget neque. Sed ultricies, orci et adipiscing dapibus, mauris nisi condimentum felis, ac euismod tellus nunc vel felis. Aliquam egestas accumsan turpis, a volutpat dui fermentum id. Aliquam erat volutpat. Nunc vel auctor odio. Donec eu posuere dolor. Donec vitae justo purus, nec bibendum lectus. Quisque elit tortor, tristique vel ultricies sed, euismod sed tellus. Nullam dolor purus, porta et hendrerit id, rhoncus eu lectus. Nam vel lorem at dui mattis pretium eget a nisi. + +Quisque eleifend risus non metus gravida ac semper odio aliquam. Praesent sed risus in tellus congue convallis. Quisque et magna tellus, in ornare leo. Nunc tempor interdum tortor, non blandit risus rhoncus et. Aliquam pulvinar est sed massa ornare sit amet ornare ligula commodo. Nunc porta ultricies tempor. Phasellus gravida accumsan auctor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin quis enim tortor. Curabitur pretium diam a arcu rutrum sed sagittis velit placerat. Ut ut mauris quam, luctus iaculis sem. Nulla quis purus quis lacus cursus imperdiet a quis dolor. Nullam hendrerit eros faucibus ante dignissim vel pharetra ligula viverra. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + +Nunc gravida massa quis nisl venenatis interdum. Integer non dui tortor, non volutpat nisi. In porta accumsan scelerisque. Nunc elementum urna non metus scelerisque ac condimentum eros volutpat. Donec eget nibh condimentum quam tempor vulputate non vel turpis. Quisque suscipit blandit mi quis iaculis. Ut iaculis, nisi ac tristique fringilla, nulla dui interdum lectus, a consectetur mi sapien a metus. Cras eu dolor non dolor imperdiet faucibus. Vestibulum porta risus vel neque convallis elementum. Aenean auctor, turpis eu molestie ultrices, mauris felis sodales est, at iaculis augue libero eu turpis. Curabitur sit amet est quis orci volutpat viverra dignissim in elit. Cras suscipit tristique quam in tincidunt. Aliquam imperdiet libero id dolor egestas viverra egestas arcu posuere. Pellentesque enim risus, accumsan quis ullamcorper ac, malesuada vitae leo. + +Cras ullamcorper vestibulum eros nec suscipit. Vivamus tincidunt, metus at tristique sodales, metus massa sagittis elit, eu scelerisque tortor ante ut sapien. Curabitur rutrum fringilla purus, eget commodo neque tincidunt ut. Etiam ac leo sed nisi ultricies ultrices sed in urna. Fusce blandit fermentum ipsum, vitae dapibus eros tempus vel. Praesent ullamcorper nulla sed nisl facilisis aliquam. Mauris consequat dui quis elit pulvinar vitae pellentesque sapien tempor. Sed accumsan consequat tortor, eget hendrerit lectus rhoncus nec. Mauris diam neque, congue ut laoreet a, hendrerit sit amet sem. Donec eget diam orci, ac vehicula orci. Ut sollicitudin ultricies arcu ut faucibus. Nulla felis nisl, auctor eget adipiscing sit amet, sagittis et est. Cras elit nisi, placerat quis tincidunt at, dapibus et arcu. Donec fermentum eleifend pretium. Nullam at posuere nulla. Phasellus at urna a arcu aliquam ullamcorper eget et ligula. + +Curabitur fermentum libero vitae libero mattis pulvinar. Vivamus luctus laoreet vulputate. Nunc dictum eros a nulla fringilla quis vestibulum ante malesuada. Suspendisse aliquam vulputate consequat. Duis eu sem eu justo convallis dictum sed ut arcu. Mauris porttitor nulla a augue iaculis posuere euismod mi scelerisque. Maecenas sodales nisi eu turpis fermentum dapibus. Morbi viverra iaculis magna, sed congue justo semper at. Nunc in mi enim. Ut aliquam mi et ligula molestie ac bibendum leo egestas. Nullam molestie, urna ac interdum auctor, dolor diam aliquam ligula, vitae gravida mi orci a tortor. Donec et felis turpis, id lobortis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer feugiat sagittis dictum. Donec mauris ante, feugiat sed ultricies ut, elementum a purus. Sed porta lectus et sem blandit vehicula. + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat feugiat fermentum. Curabitur luctus consequat urna a tincidunt. Nullam vitae velit eu arcu congue volutpat in a diam. Pellentesque lacus ipsum, gravida et tristique sit amet, varius eu ipsum. Duis venenatis sem id nibh commodo tempor. Curabitur risus tellus, cursus quis pellentesque sed, elementum eget neque. Sed ultricies, orci et adipiscing dapibus, mauris nisi condimentum felis, ac euismod tellus nunc vel felis. Aliquam egestas accumsan turpis, a volutpat dui fermentum id. Aliquam erat volutpat. Nunc vel auctor odio. Donec eu posuere dolor. Donec vitae justo purus, nec bibendum lectus. Quisque elit tortor, tristique vel ultricies sed, euismod sed tellus. Nullam dolor purus, porta et hendrerit id, rhoncus eu lectus. Nam vel lorem at dui mattis pretium eget a nisi. + +Quisque eleifend risus non metus gravida ac semper odio aliquam. Praesent sed risus in tellus congue convallis. Quisque et magna tellus, in ornare leo. Nunc tempor interdum tortor, non blandit risus rhoncus et. Aliquam pulvinar est sed massa ornare sit amet ornare ligula commodo. Nunc porta ultricies tempor. Phasellus gravida accumsan auctor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin quis enim tortor. Curabitur pretium diam a arcu rutrum sed sagittis velit placerat. Ut ut mauris quam, luctus iaculis sem. Nulla quis purus quis lacus cursus imperdiet a quis dolor. Nullam hendrerit eros faucibus ante dignissim vel pharetra ligula viverra. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + +Nunc gravida massa quis nisl venenatis interdum. Integer non dui tortor, non volutpat nisi. In porta accumsan scelerisque. Nunc elementum urna non metus scelerisque ac condimentum eros volutpat. Donec eget nibh condimentum quam tempor vulputate non vel turpis. Quisque suscipit blandit mi quis iaculis. Ut iaculis, nisi ac tristique fringilla, nulla dui interdum lectus, a consectetur mi sapien a metus. Cras eu dolor non dolor imperdiet faucibus. Vestibulum porta risus vel neque convallis elementum. Aenean auctor, turpis eu molestie ultrices, mauris felis sodales est, at iaculis augue libero eu turpis. Curabitur sit amet est quis orci volutpat viverra dignissim in elit. Cras suscipit tristique quam in tincidunt. Aliquam imperdiet libero id dolor egestas viverra egestas arcu posuere. Pellentesque enim risus, accumsan quis ullamcorper ac, malesuada vitae leo. + +Cras ullamcorper vestibulum eros nec suscipit. Vivamus tincidunt, metus at tristique sodales, metus massa sagittis elit, eu scelerisque tortor ante ut sapien. Curabitur rutrum fringilla purus, eget commodo neque tincidunt ut. Etiam ac leo sed nisi ultricies ultrices sed in urna. Fusce blandit fermentum ipsum, vitae dapibus eros tempus vel. Praesent ullamcorper nulla sed nisl facilisis aliquam. Mauris consequat dui quis elit pulvinar vitae pellentesque sapien tempor. Sed accumsan consequat tortor, eget hendrerit lectus rhoncus nec. Mauris diam neque, congue ut laoreet a, hendrerit sit amet sem. Donec eget diam orci, ac vehicula orci. Ut sollicitudin ultricies arcu ut faucibus. Nulla felis nisl, auctor eget adipiscing sit amet, sagittis et est. Cras elit nisi, placerat quis tincidunt at, dapibus et arcu. Donec fermentum eleifend pretium. Nullam at posuere nulla. Phasellus at urna a arcu aliquam ullamcorper eget et ligula. + +Curabitur fermentum libero vitae libero mattis pulvinar. Vivamus luctus laoreet vulputate. Nunc dictum eros a nulla fringilla quis vestibulum ante malesuada. Suspendisse aliquam vulputate consequat. Duis eu sem eu justo convallis dictum sed ut arcu. Mauris porttitor nulla a augue iaculis posuere euismod mi scelerisque. Maecenas sodales nisi eu turpis fermentum dapibus. Morbi viverra iaculis magna, sed congue justo semper at. Nunc in mi enim. Ut aliquam mi et ligula molestie ac bibendum leo egestas. Nullam molestie, urna ac interdum auctor, dolor diam aliquam ligula, vitae gravida mi orci a tortor. Donec et felis turpis, id lobortis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer feugiat sagittis dictum. Donec mauris ante, feugiat sed ultricies ut, elementum a purus. Sed porta lectus et sem blandit vehicula. + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat feugiat fermentum. Curabitur luctus consequat urna a tincidunt. Nullam vitae velit eu arcu congue volutpat in a diam. Pellentesque lacus ipsum, gravida et tristique sit amet, varius eu ipsum. Duis venenatis sem id nibh commodo tempor. Curabitur risus tellus, cursus quis pellentesque sed, elementum eget neque. Sed ultricies, orci et adipiscing dapibus, mauris nisi condimentum felis, ac euismod tellus nunc vel felis. Aliquam egestas accumsan turpis, a volutpat dui fermentum id. Aliquam erat volutpat. Nunc vel auctor odio. Donec eu posuere dolor. Donec vitae justo purus, nec bibendum lectus. Quisque elit tortor, tristique vel ultricies sed, euismod sed tellus. Nullam dolor purus, porta et hendrerit id, rhoncus eu lectus. Nam vel lorem at dui mattis pretium eget a nisi. + +Quisque eleifend risus non metus gravida ac semper odio aliquam. Praesent sed risus in tellus congue convallis. Quisque et magna tellus, in ornare leo. Nunc tempor interdum tortor, non blandit risus rhoncus et. Aliquam pulvinar est sed massa ornare sit amet ornare ligula commodo. Nunc porta ultricies tempor. Phasellus gravida accumsan auctor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin quis enim tortor. Curabitur pretium diam a arcu rutrum sed sagittis velit placerat. Ut ut mauris quam, luctus iaculis sem. Nulla quis purus quis lacus cursus imperdiet a quis dolor. Nullam hendrerit eros faucibus ante dignissim vel pharetra ligula viverra. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + +Nunc gravida massa quis nisl venenatis interdum. Integer non dui tortor, non volutpat nisi. In porta accumsan scelerisque. Nunc elementum urna non metus scelerisque ac condimentum eros volutpat. Donec eget nibh condimentum quam tempor vulputate non vel turpis. Quisque suscipit blandit mi quis iaculis. Ut iaculis, nisi ac tristique fringilla, nulla dui interdum lectus, a consectetur mi sapien a metus. Cras eu dolor non dolor imperdiet faucibus. Vestibulum porta risus vel neque convallis elementum. Aenean auctor, turpis eu molestie ultrices, mauris felis sodales est, at iaculis augue libero eu turpis. Curabitur sit amet est quis orci volutpat viverra dignissim in elit. Cras suscipit tristique quam in tincidunt. Aliquam imperdiet libero id dolor egestas viverra egestas arcu posuere. Pellentesque enim risus, accumsan quis ullamcorper ac, malesuada vitae leo. + +Cras ullamcorper vestibulum eros nec suscipit. Vivamus tincidunt, metus at tristique sodales, metus massa sagittis elit, eu scelerisque tortor ante ut sapien. Curabitur rutrum fringilla purus, eget commodo neque tincidunt ut. Etiam ac leo sed nisi ultricies ultrices sed in urna. Fusce blandit fermentum ipsum, vitae dapibus eros tempus vel. Praesent ullamcorper nulla sed nisl facilisis aliquam. Mauris consequat dui quis elit pulvinar vitae pellentesque sapien tempor. Sed accumsan consequat tortor, eget hendrerit lectus rhoncus nec. Mauris diam neque, congue ut laoreet a, hendrerit sit amet sem. Donec eget diam orci, ac vehicula orci. Ut sollicitudin ultricies arcu ut faucibus. Nulla felis nisl, auctor eget adipiscing sit amet, sagittis et est. Cras elit nisi, placerat quis tincidunt at, dapibus et arcu. Donec fermentum eleifend pretium. Nullam at posuere nulla. Phasellus at urna a arcu aliquam ullamcorper eget et ligula. + +Curabitur fermentum libero vitae libero mattis pulvinar. Vivamus luctus laoreet vulputate. Nunc dictum eros a nulla fringilla quis vestibulum ante malesuada. Suspendisse aliquam vulputate consequat. Duis eu sem eu justo convallis dictum sed ut arcu. Mauris porttitor nulla a augue iaculis posuere euismod mi scelerisque. Maecenas sodales nisi eu turpis fermentum dapibus. Morbi viverra iaculis magna, sed congue justo semper at. Nunc in mi enim. Ut aliquam mi et ligula molestie ac bibendum leo egestas. Nullam molestie, urna ac interdum auctor, dolor diam aliquam ligula, vitae gravida mi orci a tortor. Donec et felis turpis, id lobortis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer feugiat sagittis dictum. Donec mauris ante, feugiat sed ultricies ut, elementum a purus. Sed porta lectus et sem blandit vehicula. + +
+ From 51503a28162d2305c3e7a6f914689a8702c9aace Mon Sep 17 00:00:00 2001 From: Michael Wu Date: Tue, 19 May 2015 19:37:52 -0400 Subject: [PATCH 15/38] Avoid selecting bitmap fonts from fontconfig --- components/gfx/platform/freetype/font_list.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/components/gfx/platform/freetype/font_list.rs b/components/gfx/platform/freetype/font_list.rs index 9f939fa9391..ea9a0cbcb48 100644 --- a/components/gfx/platform/freetype/font_list.rs +++ b/components/gfx/platform/freetype/font_list.rs @@ -31,6 +31,7 @@ use std::ptr; static FC_FAMILY: &'static [u8] = b"family\0"; static FC_FILE: &'static [u8] = b"file\0"; static FC_INDEX: &'static [u8] = b"index\0"; +static FC_FONTFORMAT: &'static [u8] = b"fontformat\0"; pub fn get_available_families(mut callback: F) where F: FnMut(String) { unsafe { @@ -39,7 +40,20 @@ pub fn get_available_families(mut callback: F) where F: FnMut(String) { for i in 0..((*fontSet).nfont as isize) { let font = (*fontSet).fonts.offset(i); let mut family: *mut FcChar8 = ptr::null_mut(); + let mut format: *mut FcChar8 = ptr::null_mut(); let mut v: c_int = 0; + if FcPatternGetString(*font, FC_FONTFORMAT.as_ptr() as *mut c_char, v, &mut format) != FcResultMatch { + continue; + } + + // Skip bitmap fonts. They aren't supported by FreeType. + let fontformat = c_str_to_string(format as *const c_char); + if fontformat != "TrueType" && + fontformat != "CFF" && + fontformat != "Type 1" { + continue; + } + 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); From 3351ddf21377ced7baeacae2eae4d34b16fd7801 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Mon, 18 May 2015 19:01:38 -0400 Subject: [PATCH 16/38] Implement fetch (partial #4576) --- components/net/fetch/request.rs | 75 +++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 13 deletions(-) diff --git a/components/net/fetch/request.rs b/components/net/fetch/request.rs index 7c44e5f14d5..c6fe52ed135 100644 --- a/components/net/fetch/request.rs +++ b/components/net/fetch/request.rs @@ -5,22 +5,24 @@ use url::Url; use hyper::method::Method; use hyper::mime::{Mime, TopLevel, SubLevel, Attr, Value}; -use hyper::header::{Headers, ContentType, IfModifiedSince, IfNoneMatch, Accept}; -use hyper::header::{IfUnmodifiedSince, IfMatch, IfRange, Location, HeaderView}; -use hyper::header::{AcceptLanguage, ContentLanguage}; +use hyper::header::{Header, Headers, ContentType, IfModifiedSince, IfNoneMatch}; +use hyper::header::{Accept, IfUnmodifiedSince, IfMatch, IfRange, Location}; +use hyper::header::{HeaderView, AcceptLanguage, ContentLanguage, Language}; +use hyper::header::{QualityItem, qitem, q}; use hyper::status::StatusCode; use fetch::cors_cache::{CORSCache, CacheRequestDetails}; use fetch::response::{Response, ResponseType}; use std::ascii::AsciiExt; +use std::str::FromStr; /// A [request context](https://fetch.spec.whatwg.org/#concept-request-context) #[derive(Copy, Clone, PartialEq)] pub enum Context { Audio, Beacon, CSPreport, Download, Embed, Eventsource, Favicon, Fetch, Font, Form, Frame, Hyperlink, IFrame, Image, - ImageSet, Import, Internal, Location, Manifest, Object, Ping, - Plugin, Prefetch, Script, ServiceWorker, SharedWorker, Subresource, - Style, Track, Video, Worker, XMLHttpRequest, XSLT + ImageSet, Import, Internal, Location, Manifest, MetaRefresh, Object, + Ping, Plugin, Prefetch, PreRender, Script, ServiceWorker, SharedWorker, + Subresource, Style, Track, Video, Worker, XMLHttpRequest, XSLT } /// A [request context frame type](https://fetch.spec.whatwg.org/#concept-request-context-frame-type) @@ -143,9 +145,56 @@ impl Request { } } - // [Fetch](https://fetch.spec.whatwg.org#concept-fetch) - pub fn fetch(&mut self, _cors_flag: bool) -> Response { - // TODO: Implement fetch spec + /// [Fetch](https://fetch.spec.whatwg.org#concept-fetch) + pub fn fetch(&mut self, cors_flag: bool) -> Response { + // Step 1 + if self.context != Context::Fetch && !self.headers.has::() { + // Substep 1 + let value = match self.context { + Context::Favicon | Context::Image | Context::ImageSet + => vec![qitem(Mime(TopLevel::Image, SubLevel::Png, vec![])), + // FIXME: This should properly generate a MimeType that has a + // SubLevel of svg+xml (https://github.com/hyperium/mime.rs/issues/22) + qitem(Mime(TopLevel::Image, SubLevel::Ext("svg+xml".to_string()), vec![])), + QualityItem::new(Mime(TopLevel::Image, SubLevel::Star, vec![]), q(0.8)), + QualityItem::new(Mime(TopLevel::Star, SubLevel::Star, vec![]), q(0.5))], + Context::Form | Context::Frame | Context::Hyperlink | + Context::IFrame | Context::Location | Context::MetaRefresh | + Context::PreRender + => vec![qitem(Mime(TopLevel::Text, SubLevel::Html, vec![])), + // FIXME: This should properly generate a MimeType that has a + // SubLevel of xhtml+xml (https://github.com/hyperium/mime.rs/issues/22) + qitem(Mime(TopLevel::Application, SubLevel::Ext("xhtml+xml".to_string()), vec![])), + QualityItem::new(Mime(TopLevel::Application, SubLevel::Xml, vec![]), q(0.9)), + QualityItem::new(Mime(TopLevel::Star, SubLevel::Star, vec![]), q(0.8))], + Context::Internal if self.context_frame_type != ContextFrameType::ContextNone + => vec![qitem(Mime(TopLevel::Text, SubLevel::Html, vec![])), + // FIXME: This should properly generate a MimeType that has a + // SubLevel of xhtml+xml (https://github.com/hyperium/mime.rs/issues/22) + qitem(Mime(TopLevel::Application, SubLevel::Ext("xhtml+xml".to_string()), vec![])), + QualityItem::new(Mime(TopLevel::Application, SubLevel::Xml, vec![]), q(0.9)), + QualityItem::new(Mime(TopLevel::Star, SubLevel::Star, vec![]), q(0.8))], + Context::Style + => vec![qitem(Mime(TopLevel::Text, SubLevel::Css, vec![])), + QualityItem::new(Mime(TopLevel::Star, SubLevel::Star, vec![]), q(0.1))], + _ => vec![qitem(Mime(TopLevel::Star, SubLevel::Star, vec![]))] + }; + // Substep 2 + self.headers.set(Accept(value)); + } + // Step 2 + if self.context != Context::Fetch && !self.headers.has::() { + self.headers.set(AcceptLanguage(vec![qitem(Language::from_str("en-US").unwrap())])); + } + // TODO: Figure out what a Priority object is + // Step 3 + // Step 4 + self.main_fetch(cors_flag) + } + + /// [Main fetch](https://fetch.spec.whatwg.org/#concept-main-fetch) + pub fn main_fetch(&mut self, _cors_flag: bool) -> Response { + // TODO: Implement main fetch spec Response::network_error() } @@ -174,7 +223,7 @@ impl Request { } } - // [HTTP fetch](https://fetch.spec.whatwg.org#http-fetch) + /// [HTTP fetch](https://fetch.spec.whatwg.org#http-fetch) pub fn http_fetch(&mut self, cors_flag: bool, cors_preflight_flag: bool, authentication_fetch_flag: bool) -> Response { // Step 1 let mut response: Option = None; @@ -337,19 +386,19 @@ impl Request { response } - // [HTTP network or cache fetch](https://fetch.spec.whatwg.org#http-network-or-cache-fetch) + /// [HTTP network or cache fetch](https://fetch.spec.whatwg.org#http-network-or-cache-fetch) pub fn http_network_or_cache_fetch(&mut self, _credentials_flag: bool, _authentication_fetch_flag: bool) -> Response { // TODO: Implement HTTP network or cache fetch spec Response::network_error() } - // [CORS preflight fetch](https://fetch.spec.whatwg.org#cors-preflight-fetch) + /// [CORS preflight fetch](https://fetch.spec.whatwg.org#cors-preflight-fetch) pub fn preflight_fetch(&mut self) -> Response { // TODO: Implement preflight fetch spec Response::network_error() } - // [CORS check](https://fetch.spec.whatwg.org#concept-cors-check) + /// [CORS check](https://fetch.spec.whatwg.org#concept-cors-check) pub fn cors_check(&mut self, response: &Response) -> Result<(), ()> { // TODO: Implement CORS check spec Err(()) From 31b709a7c23c0fc7096c72d6024169c1f166f82d Mon Sep 17 00:00:00 2001 From: Paul Faria Date: Sun, 17 May 2015 16:20:30 -0400 Subject: [PATCH 17/38] Initial work on #6061. --- components/script/dom/websocket.rs | 135 ++++++++++++++++-- .../Create-Secure-url-with-space.htm.ini | 3 - .../websockets/Create-invalid-urls.htm.ini | 3 - .../Create-non-absolute-url.htm.ini | 3 - .../websockets/Create-wrong-scheme.htm.ini | 3 - .../websockets/constructor/002.html.ini | 3 - .../websockets/constructor/006.html.ini | 3 +- 7 files changed, 129 insertions(+), 24 deletions(-) delete mode 100644 tests/wpt/metadata/websockets/Create-Secure-url-with-space.htm.ini delete mode 100644 tests/wpt/metadata/websockets/Create-invalid-urls.htm.ini delete mode 100644 tests/wpt/metadata/websockets/Create-non-absolute-url.htm.ini delete mode 100644 tests/wpt/metadata/websockets/Create-wrong-scheme.htm.ini delete mode 100644 tests/wpt/metadata/websockets/constructor/002.html.ini diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index 75c868b50db..b4e00457714 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -9,8 +9,7 @@ use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use dom::bindings::codegen::InheritTypes::EventTargetCast; use dom::bindings::codegen::InheritTypes::EventCast; use dom::bindings::error::{Error, Fallible}; -use dom::bindings::error::Error::InvalidAccess; -use dom::bindings::error::Error::Syntax; +use dom::bindings::error::Error::{InvalidAccess, Syntax}; use dom::bindings::global::{GlobalField, GlobalRef}; use dom::bindings::js::{Temporary, JSRef, Rootable}; use dom::bindings::refcounted::Trusted; @@ -33,6 +32,7 @@ use websocket::stream::WebSocketStream; use websocket::client::request::Url; use websocket::Client; +use url::{SchemeData, SchemeType, UrlParser}; #[derive(PartialEq, Copy, Clone)] #[jstraceable] @@ -63,6 +63,112 @@ pub struct WebSocket { sendCloseFrame: Cell } +fn web_socket_scheme_types(scheme: &str) -> SchemeType { + match scheme { + "ws" => SchemeType::Relative(80), + "wss" => SchemeType::Relative(443), + _ => SchemeType::NonRelative, + } +} + +fn parse_web_socket_url(url_str: &str) -> Fallible<(Url, String, u16, String, bool)> { + // https://html.spec.whatwg.org/multipage/comms.html#parse-a-websocket-url's-components + // 1. No basepath specified, so it's absolute by default + // 2. UrlParser defaults to UTF-8 encoding + // 3. Specifying only ws and wss + let parsed_url = UrlParser::new() + .scheme_type_mapper(web_socket_scheme_types) + .parse(url_str); + + if parsed_url.is_err(){ + return Err(Error::Syntax); + } + + let parsed_url = parsed_url.unwrap(); + + // 3. Didn't match ws or wss + if let SchemeData::NonRelative(_) = parsed_url.scheme_data { + return Err(Error::Syntax); + } + + // 4. If the parsed url has a non-null fragment, fail + if parsed_url.fragment != None { + return Err(Error::Syntax); + } + + // 5. Set secure false if scheme is ws otherwise if scheme is wss set true + let secure = match parsed_url.scheme.as_ref() { + "ws" => false, + "wss" => true, + _ => unreachable!() + }; + + // 6. Set host to parsed url's host + let host = parsed_url.host().unwrap().serialize(); + + // 7. If the resulting parsed URL has a port component that is not the empty + // string, then let port be that component's value; otherwise, there is no + // explicit port. + let port = match parsed_url.port() { + Some(p) => p, + + // 8. If there is no explicit port, then: if secure is false, let port + // be 80, otherwise let port be 443. + None => if secure { + 443 + } else { + 80 + }, + }; + + // 9. Let resource name be the value of the resulting parsed URL's path + // component (which might be empty). + let base_resource = parsed_url.path().unwrap().connect("/"); + let mut resource = base_resource.as_ref(); + + // 10. If resource name is the empty string, set it to a single character + // U+002F SOLIDUS (/). + if resource == "" { + resource = "/"; + } + + let mut resource = resource.to_owned(); + + // 11. If the resulting parsed URL has a non-null query component, then + // append a single U+003F QUESTION MARK character (?) to resource name, + // followed by the value of the query component. + match parsed_url.query_pairs() { + Some(pairs) => { + let mut joined_pairs = pairs.iter() + .map(|pair| { + let mut keyValue = String::new(); + keyValue.push_str(pair.0.as_ref()); + keyValue.push('='); + keyValue.push_str(pair.1.as_ref()); + keyValue + }); + + let mut base_pair = String::new(); + base_pair.push_str(joined_pairs.next().unwrap().as_ref()); + + resource.push('?'); + + let query_string = joined_pairs.fold(base_pair, |mut current, next| { + current.push('&'); + current.push_str(next.as_ref()); + current + }); + + resource.push_str(query_string.as_ref()); + }, + None => (), + } + + // 12. Return host, port, resource name, and secure. + // FIXME remove parsed_url once it's no longer used in WebSocket::new + Ok((parsed_url, host, port, resource.to_string(), secure)) +} + impl WebSocket { pub fn new_inherited(global: GlobalRef, url: DOMString) -> WebSocket { WebSocket { @@ -83,11 +189,12 @@ impl WebSocket { } - pub fn new(global: GlobalRef, url: DOMString) -> Temporary { + pub fn new(global: GlobalRef, url: DOMString) -> Fallible> { /*TODO: This constructor is only a prototype, it does not accomplish the specs defined here: http://html.spec.whatwg.org - All 9 items must be satisfied. + Item 1 is already satisfied. + The remaining 8 items must be satisfied. TODO: This constructor should be responsible for spawning a thread for the receive loop after ws_root.r().Open() - See comment */ @@ -95,7 +202,18 @@ impl WebSocket { global, WebSocketBinding::Wrap).root(); let ws_root = ws_root.r(); - let parsed_url = Url::parse(&ws_root.url).unwrap(); + + let parse_url_result = parse_web_socket_url(&ws_root.url); + if let Err(e) = parse_url_result { + return Err(e); + } + + // FIXME extract the right variables once Client::connect implementation is + // fixed to follow the RFC 6455 properly + let Ok((parsed_url, _, _, _, _)) = parse_url_result; + + // TODO Client::connect does not conform to RFC 6455 + // see https://github.com/cyderize/rust-websocket/issues/38 let request = Client::connect(parsed_url).unwrap(); let response = request.send().unwrap(); response.validate().unwrap(); @@ -106,8 +224,9 @@ impl WebSocket { let failed = ws_root.failed.get(); if failed && (ready_state == WebSocketRequestState::Closed || ready_state == WebSocketRequestState::Closing) { //Do nothing else. Let the close finish. - return Temporary::from_rooted(ws_root); + return Ok(Temporary::from_rooted(ws_root)); } + let (temp_sender, temp_receiver) = response.begin().split(); let mut other_sender = ws_root.sender.borrow_mut(); let mut other_receiver = ws_root.receiver.borrow_mut(); @@ -132,11 +251,11 @@ impl WebSocket { it confirms the websocket is now closed. This requires the close event to be fired (dispatch_close fires the close event - see implementation below) */ - Temporary::from_rooted(ws_root) + Ok(Temporary::from_rooted(ws_root)) } pub fn Constructor(global: GlobalRef, url: DOMString) -> Fallible> { - Ok(WebSocket::new(global, url)) + WebSocket::new(global, url) } } diff --git a/tests/wpt/metadata/websockets/Create-Secure-url-with-space.htm.ini b/tests/wpt/metadata/websockets/Create-Secure-url-with-space.htm.ini deleted file mode 100644 index d474af4b3d8..00000000000 --- a/tests/wpt/metadata/websockets/Create-Secure-url-with-space.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[Create-Secure-url-with-space.htm] - type: testharness - expected: TIMEOUT diff --git a/tests/wpt/metadata/websockets/Create-invalid-urls.htm.ini b/tests/wpt/metadata/websockets/Create-invalid-urls.htm.ini deleted file mode 100644 index fd3312d40fa..00000000000 --- a/tests/wpt/metadata/websockets/Create-invalid-urls.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[Create-invalid-urls.htm] - type: testharness - expected: TIMEOUT diff --git a/tests/wpt/metadata/websockets/Create-non-absolute-url.htm.ini b/tests/wpt/metadata/websockets/Create-non-absolute-url.htm.ini deleted file mode 100644 index 8524afa5027..00000000000 --- a/tests/wpt/metadata/websockets/Create-non-absolute-url.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[Create-non-absolute-url.htm] - type: testharness - expected: TIMEOUT diff --git a/tests/wpt/metadata/websockets/Create-wrong-scheme.htm.ini b/tests/wpt/metadata/websockets/Create-wrong-scheme.htm.ini deleted file mode 100644 index d10bc32841e..00000000000 --- a/tests/wpt/metadata/websockets/Create-wrong-scheme.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[Create-wrong-scheme.htm] - type: testharness - expected: TIMEOUT diff --git a/tests/wpt/metadata/websockets/constructor/002.html.ini b/tests/wpt/metadata/websockets/constructor/002.html.ini deleted file mode 100644 index 29a2058d988..00000000000 --- a/tests/wpt/metadata/websockets/constructor/002.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[002.html] - type: testharness - expected: TIMEOUT diff --git a/tests/wpt/metadata/websockets/constructor/006.html.ini b/tests/wpt/metadata/websockets/constructor/006.html.ini index 9701e26d8e9..e4bcc3871c2 100644 --- a/tests/wpt/metadata/websockets/constructor/006.html.ini +++ b/tests/wpt/metadata/websockets/constructor/006.html.ini @@ -1,3 +1,4 @@ [006.html] type: testharness - expected: TIMEOUT + [WebSockets: converting first arguments] + expected: FAIL From 0362d254b8ba111f1f09886b8ec6802ce4c50464 Mon Sep 17 00:00:00 2001 From: Paul Faria Date: Mon, 18 May 2015 17:28:16 -0400 Subject: [PATCH 18/38] Removing trailing whitespace --- components/script/dom/websocket.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index b4e00457714..5c1ea116c26 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -133,7 +133,7 @@ fn parse_web_socket_url(url_str: &str) -> Fallible<(Url, String, u16, String, bo } let mut resource = resource.to_owned(); - + // 11. If the resulting parsed URL has a non-null query component, then // append a single U+003F QUESTION MARK character (?) to resource name, // followed by the value of the query component. @@ -150,7 +150,7 @@ fn parse_web_socket_url(url_str: &str) -> Fallible<(Url, String, u16, String, bo let mut base_pair = String::new(); base_pair.push_str(joined_pairs.next().unwrap().as_ref()); - + resource.push('?'); let query_string = joined_pairs.fold(base_pair, |mut current, next| { @@ -158,7 +158,7 @@ fn parse_web_socket_url(url_str: &str) -> Fallible<(Url, String, u16, String, bo current.push_str(next.as_ref()); current }); - + resource.push_str(query_string.as_ref()); }, None => (), @@ -226,7 +226,7 @@ impl WebSocket { //Do nothing else. Let the close finish. return Ok(Temporary::from_rooted(ws_root)); } - + let (temp_sender, temp_receiver) = response.begin().split(); let mut other_sender = ws_root.sender.borrow_mut(); let mut other_receiver = ws_root.receiver.borrow_mut(); From 8e78564dc335f625b74eaf067889733ba292b3d7 Mon Sep 17 00:00:00 2001 From: Paul Faria Date: Mon, 18 May 2015 17:39:19 -0400 Subject: [PATCH 19/38] Fixing one missed trailing whitespace, and fixed url --- components/script/dom/websocket.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index 5c1ea116c26..26f3066e511 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -72,14 +72,14 @@ fn web_socket_scheme_types(scheme: &str) -> SchemeType { } fn parse_web_socket_url(url_str: &str) -> Fallible<(Url, String, u16, String, bool)> { - // https://html.spec.whatwg.org/multipage/comms.html#parse-a-websocket-url's-components + // https://html.spec.whatwg.org/multipage/#parse-a-websocket-url's-components // 1. No basepath specified, so it's absolute by default // 2. UrlParser defaults to UTF-8 encoding // 3. Specifying only ws and wss let parsed_url = UrlParser::new() .scheme_type_mapper(web_socket_scheme_types) .parse(url_str); - + if parsed_url.is_err(){ return Err(Error::Syntax); } From fe0b77d6692e5f551cb7d2559487a5ee5a36ed0f Mon Sep 17 00:00:00 2001 From: Paul Faria Date: Tue, 19 May 2015 10:04:02 -0400 Subject: [PATCH 20/38] Responded to code review comments, general cleanup --- components/script/dom/websocket.rs | 80 +++++++++++------------------- 1 file changed, 29 insertions(+), 51 deletions(-) diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index 26f3066e511..1f757f5859f 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -73,47 +73,41 @@ fn web_socket_scheme_types(scheme: &str) -> SchemeType { fn parse_web_socket_url(url_str: &str) -> Fallible<(Url, String, u16, String, bool)> { // https://html.spec.whatwg.org/multipage/#parse-a-websocket-url's-components - // 1. No basepath specified, so it's absolute by default - // 2. UrlParser defaults to UTF-8 encoding - // 3. Specifying only ws and wss + // Steps 1, 2, and 3 let parsed_url = UrlParser::new() .scheme_type_mapper(web_socket_scheme_types) .parse(url_str); - if parsed_url.is_err(){ - return Err(Error::Syntax); - } - - let parsed_url = parsed_url.unwrap(); + let parsed_url = match parsed_url { + Ok(parsed_url) => parsed_url, + Err(_) => return Err(Error::Syntax), + }; // 3. Didn't match ws or wss if let SchemeData::NonRelative(_) = parsed_url.scheme_data { return Err(Error::Syntax); } - // 4. If the parsed url has a non-null fragment, fail + // Step 4 if parsed_url.fragment != None { return Err(Error::Syntax); } - // 5. Set secure false if scheme is ws otherwise if scheme is wss set true + // Step 5 let secure = match parsed_url.scheme.as_ref() { "ws" => false, "wss" => true, _ => unreachable!() }; - // 6. Set host to parsed url's host + // Step 6 let host = parsed_url.host().unwrap().serialize(); - // 7. If the resulting parsed URL has a port component that is not the empty - // string, then let port be that component's value; otherwise, there is no - // explicit port. + // Step 7 let port = match parsed_url.port() { Some(p) => p, - // 8. If there is no explicit port, then: if secure is false, let port - // be 80, otherwise let port be 443. + // Step 8 None => if secure { 443 } else { @@ -121,52 +115,41 @@ fn parse_web_socket_url(url_str: &str) -> Fallible<(Url, String, u16, String, bo }, }; - // 9. Let resource name be the value of the resulting parsed URL's path - // component (which might be empty). - let base_resource = parsed_url.path().unwrap().connect("/"); - let mut resource = base_resource.as_ref(); + // Step 9 + let mut resource = parsed_url.path().unwrap().connect("/"); - // 10. If resource name is the empty string, set it to a single character - // U+002F SOLIDUS (/). + // Step 10 if resource == "" { - resource = "/"; + resource = "/".to_owned(); } - let mut resource = resource.to_owned(); - - // 11. If the resulting parsed URL has a non-null query component, then - // append a single U+003F QUESTION MARK character (?) to resource name, - // followed by the value of the query component. + // Step 11 match parsed_url.query_pairs() { Some(pairs) => { - let mut joined_pairs = pairs.iter() - .map(|pair| { - let mut keyValue = String::new(); - keyValue.push_str(pair.0.as_ref()); - keyValue.push('='); - keyValue.push_str(pair.1.as_ref()); - keyValue - }); - - let mut base_pair = String::new(); - base_pair.push_str(joined_pairs.next().unwrap().as_ref()); + fn append_query_components(s: &mut String, key: &str, value: &str) { + s.push_str(key); + s.push('='); + s.push_str(value); + } resource.push('?'); - let query_string = joined_pairs.fold(base_pair, |mut current, next| { + let mut iterator = pairs.iter(); + let first = iterator.next().unwrap(); + append_query_components(&mut resource, first.0.as_ref(), first.1.as_ref()); + + iterator.fold(&mut resource, |mut current, next| { current.push('&'); - current.push_str(next.as_ref()); + append_query_components(&mut current, next.0.as_ref(), next.1.as_ref()); current }); - - resource.push_str(query_string.as_ref()); }, None => (), } - // 12. Return host, port, resource name, and secure. + // Step 12 // FIXME remove parsed_url once it's no longer used in WebSocket::new - Ok((parsed_url, host, port, resource.to_string(), secure)) + Ok((parsed_url, host, port, resource, secure)) } impl WebSocket { @@ -203,14 +186,9 @@ impl WebSocket { WebSocketBinding::Wrap).root(); let ws_root = ws_root.r(); - let parse_url_result = parse_web_socket_url(&ws_root.url); - if let Err(e) = parse_url_result { - return Err(e); - } - // FIXME extract the right variables once Client::connect implementation is // fixed to follow the RFC 6455 properly - let Ok((parsed_url, _, _, _, _)) = parse_url_result; + let (parsed_url, _, _, _, _) = try!(parse_web_socket_url(&ws_root.url)); // TODO Client::connect does not conform to RFC 6455 // see https://github.com/cyderize/rust-websocket/issues/38 From 51ae7334f52b1133dbecf455ba71e89fa0152ef1 Mon Sep 17 00:00:00 2001 From: Paul Faria Date: Tue, 19 May 2015 17:54:14 -0400 Subject: [PATCH 21/38] Responded to more code review comments. Simplified code a lot. --- components/script/dom/websocket.rs | 76 +++++------------------------- 1 file changed, 12 insertions(+), 64 deletions(-) diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index 1f757f5859f..10146c5062c 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -32,8 +32,6 @@ use websocket::stream::WebSocketStream; use websocket::client::request::Url; use websocket::Client; -use url::{SchemeData, SchemeType, UrlParser}; - #[derive(PartialEq, Copy, Clone)] #[jstraceable] enum WebSocketRequestState { @@ -63,88 +61,38 @@ pub struct WebSocket { sendCloseFrame: Cell } -fn web_socket_scheme_types(scheme: &str) -> SchemeType { - match scheme { - "ws" => SchemeType::Relative(80), - "wss" => SchemeType::Relative(443), - _ => SchemeType::NonRelative, - } -} - fn parse_web_socket_url(url_str: &str) -> Fallible<(Url, String, u16, String, bool)> { // https://html.spec.whatwg.org/multipage/#parse-a-websocket-url's-components - // Steps 1, 2, and 3 - let parsed_url = UrlParser::new() - .scheme_type_mapper(web_socket_scheme_types) - .parse(url_str); - + // Steps 1 and 2 + let parsed_url = Url::parse(url_str); let parsed_url = match parsed_url { Ok(parsed_url) => parsed_url, Err(_) => return Err(Error::Syntax), }; - // 3. Didn't match ws or wss - if let SchemeData::NonRelative(_) = parsed_url.scheme_data { - return Err(Error::Syntax); - } - // Step 4 if parsed_url.fragment != None { return Err(Error::Syntax); } - // Step 5 + // Steps 3 and 5 let secure = match parsed_url.scheme.as_ref() { "ws" => false, "wss" => true, - _ => unreachable!() + _ => return Err(Error::Syntax), // step 3 }; - // Step 6 - let host = parsed_url.host().unwrap().serialize(); - - // Step 7 - let port = match parsed_url.port() { - Some(p) => p, - - // Step 8 - None => if secure { - 443 - } else { - 80 - }, - }; - - // Step 9 - let mut resource = parsed_url.path().unwrap().connect("/"); - - // Step 10 - if resource == "" { - resource = "/".to_owned(); + let host = parsed_url.host().unwrap().serialize(); // Step 6 + let port = parsed_url.port_or_default().unwrap(); // Step 7 + let mut resource = parsed_url.path().unwrap().connect("/"); // Step 9 + if resource.is_empty() { + resource = "/".to_owned(); // Step 10 } // Step 11 - match parsed_url.query_pairs() { - Some(pairs) => { - fn append_query_components(s: &mut String, key: &str, value: &str) { - s.push_str(key); - s.push('='); - s.push_str(value); - } - - resource.push('?'); - - let mut iterator = pairs.iter(); - let first = iterator.next().unwrap(); - append_query_components(&mut resource, first.0.as_ref(), first.1.as_ref()); - - iterator.fold(&mut resource, |mut current, next| { - current.push('&'); - append_query_components(&mut current, next.0.as_ref(), next.1.as_ref()); - current - }); - }, - None => (), + if let Some(ref query) = parsed_url.query { + resource.push('?'); + resource.push_str(query); } // Step 12 From 66e9b33a527b10f1f775f2f0aeab34a07150ecda Mon Sep 17 00:00:00 2001 From: Paul Faria Date: Sat, 16 May 2015 14:10:10 -0400 Subject: [PATCH 22/38] Fixed definition of Close and Send in WebSocket.webidl and updated implementation in websocket.rs. --- components/script/dom/webidls/WebSocket.webidl | 6 +++--- components/script/dom/websocket.rs | 11 ++++++----- .../Close-reason-unpaired-surrogates.htm.ini | 2 ++ .../websockets/Send-Unpaired-Surrogates.htm.ini | 4 ++++ .../websockets/interfaces/WebSocket/send/006.html.ini | 2 ++ 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/components/script/dom/webidls/WebSocket.webidl b/components/script/dom/webidls/WebSocket.webidl index 6067ca30c4f..3fd2fcd403d 100644 --- a/components/script/dom/webidls/WebSocket.webidl +++ b/components/script/dom/webidls/WebSocket.webidl @@ -21,13 +21,13 @@ interface WebSocket : EventTarget { attribute EventHandler onclose; //readonly attribute DOMString extensions; //readonly attribute DOMString protocol; - //[Throws] void close([Clamp] optional unsigned short code, optional DOMString reason); //Clamp doesn't work - [Throws] void close(optional unsigned short code, optional DOMString reason); //No clamp version - works + //[Throws] void close([Clamp] optional unsigned short code, optional USVString reason); //Clamp doesn't work + [Throws] void close(optional unsigned short code, optional USVString reason); //No clamp version - works //messaging //attribute EventHandler onmessage; //attribute BinaryType binaryType; - [Throws] void send(optional DOMString data); + [Throws] void send(optional USVString data); //void send(Blob data); //void send(ArrayBuffer data); //void send(ArrayBufferView data); diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index 75c868b50db..c9061457a81 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -14,6 +14,7 @@ use dom::bindings::error::Error::Syntax; use dom::bindings::global::{GlobalField, GlobalRef}; use dom::bindings::js::{Temporary, JSRef, Rootable}; use dom::bindings::refcounted::Trusted; +use dom::bindings::str::USVString; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::reflect_dom_object; use dom::closeevent::CloseEvent; @@ -153,7 +154,7 @@ impl<'a> WebSocketMethods for JSRef<'a, WebSocket> { self.ready_state.get() as u16 } - fn Send(self, data: Option)-> Fallible<()>{ + fn Send(self, data: Option)-> Fallible<()>{ /*TODO: This is not up to spec see http://html.spec.whatwg.org/multipage/comms.html search for "If argument is a string" TODO: Need to buffer data TODO: bufferedAmount attribute returns the size of the buffer in bytes - @@ -168,11 +169,11 @@ impl<'a> WebSocketMethods for JSRef<'a, WebSocket> { let _ = my_sender.send_message(Message::Close(None)); return Ok(()); } - let _ = my_sender.send_message(Message::Text(data.unwrap())); + let _ = my_sender.send_message(Message::Text(data.unwrap().0)); return Ok(()) } - fn Close(self, code: Option, reason: Option) -> Fallible<()>{ + fn Close(self, code: Option, reason: Option) -> Fallible<()>{ if let Some(code) = code { //Check code is NOT 1000 NOR in the range of 3000-4999 (inclusive) if code != 1000 && (code < 3000 || code > 4999) { @@ -180,7 +181,7 @@ impl<'a> WebSocketMethods for JSRef<'a, WebSocket> { } } if let Some(ref reason) = reason { - if reason.as_bytes().len() > 123 { //reason cannot be larger than 123 bytes + if reason.0.as_bytes().len() > 123 { //reason cannot be larger than 123 bytes return Err(Error::Syntax); } } @@ -205,7 +206,7 @@ impl<'a> WebSocketMethods for JSRef<'a, WebSocket> { self.code.set(code); } if let Some(reason) = reason { - *self.reason.borrow_mut() = reason; + *self.reason.borrow_mut() = reason.0; } self.ready_state.set(WebSocketRequestState::Closing); self.sendCloseFrame.set(true); diff --git a/tests/wpt/metadata/websockets/Close-reason-unpaired-surrogates.htm.ini b/tests/wpt/metadata/websockets/Close-reason-unpaired-surrogates.htm.ini index 562ee256ea0..d2ce371b39f 100644 --- a/tests/wpt/metadata/websockets/Close-reason-unpaired-surrogates.htm.ini +++ b/tests/wpt/metadata/websockets/Close-reason-unpaired-surrogates.htm.ini @@ -1,3 +1,5 @@ [Close-reason-unpaired-surrogates.htm] type: testharness expected: TIMEOUT + [W3C WebSocket API - Create WebSocket - Close the Connection - close(reason with unpaired surrogates) - connection should get closed] + expected: NOTRUN diff --git a/tests/wpt/metadata/websockets/Send-Unpaired-Surrogates.htm.ini b/tests/wpt/metadata/websockets/Send-Unpaired-Surrogates.htm.ini index b46ddc67b95..265e9aa9093 100644 --- a/tests/wpt/metadata/websockets/Send-Unpaired-Surrogates.htm.ini +++ b/tests/wpt/metadata/websockets/Send-Unpaired-Surrogates.htm.ini @@ -1,3 +1,7 @@ [Send-Unpaired-Surrogates.htm] type: testharness expected: TIMEOUT + [W3C WebSocket API - Send unpaired surrogates on a WebSocket - Message should be received] + expected: NOTRUN + [W3C WebSocket API - Send unpaired surrogates on a WebSocket - Connection should be closed] + expected: NOTRUN diff --git a/tests/wpt/metadata/websockets/interfaces/WebSocket/send/006.html.ini b/tests/wpt/metadata/websockets/interfaces/WebSocket/send/006.html.ini index 9701e26d8e9..7a904fb6732 100644 --- a/tests/wpt/metadata/websockets/interfaces/WebSocket/send/006.html.ini +++ b/tests/wpt/metadata/websockets/interfaces/WebSocket/send/006.html.ini @@ -1,3 +1,5 @@ [006.html] type: testharness expected: TIMEOUT + [WebSockets: send() with unpaired surrogate when readyState is OPEN] + expected: TIMEOUT From 1c96eed54410b45e0d0401941d4d156c5c8c9c78 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 9 Apr 2015 15:59:57 -0400 Subject: [PATCH 23/38] fixes #5603, adds support for tabindex --- components/script/dom/element.rs | 11 +++- components/script/dom/htmlelement.rs | 62 ++++++++++++++++++- components/script/dom/node.rs | 3 + components/script/dom/virtualmethods.rs | 8 +++ .../disabledElement.html.ini | 5 -- .../selectors/pseudo-classes/focus.html.ini | 7 --- 6 files changed, 80 insertions(+), 16 deletions(-) delete mode 100644 tests/wpt/metadata/html/semantics/disabled-elements/disabledElement.html.ini diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index f0ff55e2e5b..f80fd19a502 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -51,7 +51,7 @@ use dom::htmltablecellelement::{HTMLTableCellElement, HTMLTableCellElementHelper use dom::htmltablerowelement::{HTMLTableRowElement, HTMLTableRowElementHelpers}; use dom::htmltablesectionelement::{HTMLTableSectionElement, HTMLTableSectionElementHelpers}; use dom::htmltextareaelement::{HTMLTextAreaElement, RawLayoutHTMLTextAreaElementHelpers}; -use dom::node::{CLICK_IN_PROGRESS, LayoutNodeHelpers, Node, NodeHelpers, NodeTypeId}; +use dom::node::{CLICK_IN_PROGRESS, LayoutNodeHelpers, Node, NodeHelpers, NodeTypeId, SEQUENTIALLY_FOCUSABLE}; use dom::node::{document_from_node, NodeDamage}; use dom::node::{window_from_node}; use dom::nodelist::NodeList; @@ -712,9 +712,11 @@ impl<'a> FocusElementHelpers for JSRef<'a, Element> { return false; } // TODO: Check whether the element is being rendered (i.e. not hidden). - // TODO: Check the tabindex focus flag. - // https://html.spec.whatwg.org/multipage/#specially-focusable let node: JSRef = NodeCast::from_ref(self); + if node.get_flag(SEQUENTIALLY_FOCUSABLE) { + return true; + } + // https://html.spec.whatwg.org/multipage/#specially-focusable match node.type_id() { NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) | NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) | @@ -934,6 +936,9 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { self.attrs.borrow_mut().remove(idx); attr.r().set_owner(None); + if attr.r().namespace() == &ns!("") { + vtable_for(&NodeCast::from_ref(self)).after_remove_attr(attr.r().name()); + } let node: JSRef = NodeCast::from_ref(self); if node.is_in_doc() { diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs index ce70535de74..b3ffe4b056f 100644 --- a/components/script/dom/htmlelement.rs +++ b/components/script/dom/htmlelement.rs @@ -4,6 +4,7 @@ use dom::attr::Attr; use dom::attr::AttrHelpers; +use dom::attr::AttrValue; use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use dom::bindings::codegen::Bindings::HTMLElementBinding; use dom::bindings::codegen::Bindings::HTMLElementBinding::HTMLElementMethods; @@ -24,7 +25,7 @@ use dom::eventtarget::{EventTarget, EventTargetHelpers, EventTargetTypeId}; use dom::htmlinputelement::HTMLInputElement; use dom::htmlmediaelement::HTMLMediaElementTypeId; use dom::htmltablecellelement::HTMLTableCellElementTypeId; -use dom::node::{Node, NodeHelpers, NodeTypeId, document_from_node, window_from_node}; +use dom::node::{Node, NodeHelpers, NodeTypeId, document_from_node, window_from_node, SEQUENTIALLY_FOCUSABLE}; use dom::virtualmethods::VirtualMethods; use dom::window::WindowHelpers; @@ -70,6 +71,7 @@ impl HTMLElement { trait PrivateHTMLElementHelpers { fn is_body_or_frameset(self) -> bool; + fn update_sequentially_focusable_status(self); } impl<'a> PrivateHTMLElementHelpers for JSRef<'a, HTMLElement> { @@ -77,6 +79,44 @@ impl<'a> PrivateHTMLElementHelpers for JSRef<'a, HTMLElement> { let eventtarget: JSRef = EventTargetCast::from_ref(self); eventtarget.is_htmlbodyelement() || eventtarget.is_htmlframesetelement() } + + fn update_sequentially_focusable_status(self) { + let element = ElementCast::from_ref(self); + let node = NodeCast::from_ref(self); + if element.has_attribute(&atom!("tabindex")) { + node.set_flag(SEQUENTIALLY_FOCUSABLE, true); + } else { + match node.type_id() { + NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) | + NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSelectElement)) | + NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLIFrameElement)) | + NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement)) + => node.set_flag(SEQUENTIALLY_FOCUSABLE, true), + NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLinkElement)) | + NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) => { + if element.has_attribute(&atom!("href")) { + node.set_flag(SEQUENTIALLY_FOCUSABLE, true); + } + }, + _ => { + if let Some(attr) = element.get_attribute(&ns!(""), &atom!("draggable")) { + let attr = attr.root(); + let attr = attr.r(); + let value = attr.value(); + let is_true = match *value { + AttrValue::String(ref string) => string == "true", + _ => false, + }; + node.set_flag(SEQUENTIALLY_FOCUSABLE, is_true); + } else { + node.set_flag(SEQUENTIALLY_FOCUSABLE, false); + } + //TODO set SEQUENTIALLY_FOCUSABLE flag if editing host + //TODO set SEQUENTIALLY_FOCUSABLE flag if "sorting interface th elements" + }, + } + } + } } impl<'a> HTMLElementMethods for JSRef<'a, HTMLElement> { @@ -220,6 +260,19 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLElement> { Some(element as &VirtualMethods) } + fn before_remove_attr(&self, attr: JSRef) { + if let Some(ref s) = self.super_type() { + s.before_remove_attr(attr); + } + } + + fn after_remove_attr(&self, name: &Atom) { + if let Some(ref s) = self.super_type() { + s.after_remove_attr(name); + } + self.update_sequentially_focusable_status(); + } + fn after_set_attr(&self, attr: JSRef) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); @@ -236,6 +289,13 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLElement> { &name[2..], (**attr.value()).to_owned()); } + self.update_sequentially_focusable_status(); + } + fn bind_to_tree(&self, tree_in_doc: bool) { + if let Some(ref s) = self.super_type() { + s.bind_to_tree(tree_in_doc); + } + self.update_sequentially_focusable_status(); } } diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index f7401c99b11..786401edc4d 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -158,6 +158,9 @@ bitflags! { const CLICK_IN_PROGRESS = 0x100, #[doc = "Specifies whether this node has the focus."] const IN_FOCUS_STATE = 0x200, + #[doc = "Specifies whether this node is focusable and whether it is supposed \ + to be reachable with using sequential focus navigation."] + const SEQUENTIALLY_FOCUSABLE = 0x400, } } diff --git a/components/script/dom/virtualmethods.rs b/components/script/dom/virtualmethods.rs index 2147ee07c48..e871fdd1894 100644 --- a/components/script/dom/virtualmethods.rs +++ b/components/script/dom/virtualmethods.rs @@ -88,6 +88,14 @@ pub trait VirtualMethods { } } + /// Called when changing or removing attributes, after all modification + /// has taken place. + fn after_remove_attr(&self, name: &Atom) { + if let Some(ref s) = self.super_type() { + s.after_remove_attr(name); + } + } + /// Returns the right AttrValue variant for the attribute with name `name` /// on this element. fn parse_plain_attribute(&self, name: &Atom, value: DOMString) -> AttrValue { diff --git a/tests/wpt/metadata/html/semantics/disabled-elements/disabledElement.html.ini b/tests/wpt/metadata/html/semantics/disabled-elements/disabledElement.html.ini deleted file mode 100644 index cffbca16463..00000000000 --- a/tests/wpt/metadata/html/semantics/disabled-elements/disabledElement.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[disabledElement.html] - type: testharness - [A disabled should be focusable] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/selectors/pseudo-classes/focus.html.ini b/tests/wpt/metadata/html/semantics/selectors/pseudo-classes/focus.html.ini index f3529fc646d..387c512ce75 100644 --- a/tests/wpt/metadata/html/semantics/selectors/pseudo-classes/focus.html.ini +++ b/tests/wpt/metadata/html/semantics/selectors/pseudo-classes/focus.html.ini @@ -3,12 +3,5 @@ [input3 has the attribute autofocus] expected: FAIL - [tabindex attribute makes the element focusable] - expected: FAIL - [editable elements are focusable] expected: FAIL - - [':focus' matches focussed body with tabindex] - expected: FAIL - From 717b443eec9dac822d4599f93c723440f1c4ec9d Mon Sep 17 00:00:00 2001 From: Peter Date: Fri, 15 May 2015 16:27:07 -0400 Subject: [PATCH 24/38] fixes #6069 --- components/plugins/Cargo.toml | 4 ++-- components/plugins/lints/unrooted_must_root.rs | 8 ++++++-- components/servo/Cargo.lock | 6 +++--- ports/cef/Cargo.lock | 6 +++--- ports/gonk/Cargo.lock | 6 +++--- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/components/plugins/Cargo.toml b/components/plugins/Cargo.toml index 133bad303a5..946394fbe10 100644 --- a/components/plugins/Cargo.toml +++ b/components/plugins/Cargo.toml @@ -8,5 +8,5 @@ name = "plugins" path = "lib.rs" plugin = true -[dependencies.tenacious] -git = "https://github.com/Manishearth/rust-tenacious.git" \ No newline at end of file +[dependencies] +tenacious = "*" diff --git a/components/plugins/lints/unrooted_must_root.rs b/components/plugins/lints/unrooted_must_root.rs index 7a39f6cc4d5..e819f8d0e4d 100644 --- a/components/plugins/lints/unrooted_must_root.rs +++ b/components/plugins/lints/unrooted_must_root.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 syntax::{ast, codemap, visit}; +use syntax::{ast, codemap, visit, ast_map}; use syntax::attr::AttrMetaMethods; use rustc::lint::{Context, LintPass, LintArray}; use rustc::middle::ty::expr_ty; @@ -52,7 +52,11 @@ impl LintPass for UnrootedPass { } /// All structs containing #[must_root] types must be #[must_root] themselves fn check_struct_def(&mut self, cx: &Context, def: &ast::StructDef, _i: ast::Ident, _gen: &ast::Generics, id: ast::NodeId) { - if cx.tcx.map.expect_item(id).attrs.iter().all(|a| !a.check_name("must_root")) { + let item = match cx.tcx.map.get(id) { + ast_map::Node::NodeItem(item) => item, + _ => cx.tcx.map.expect_item(cx.tcx.map.get_parent(id)), + }; + if item.attrs.iter().all(|a| !a.check_name("must_root")) { for ref field in def.fields.iter() { lint_unrooted_ty(cx, &*field.node.ty, "Type must be rooted, use #[must_root] on the struct definition to propagate"); diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 3202bcf3859..03ba6d80a09 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -937,7 +937,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "plugins" version = "0.0.1" dependencies = [ - "tenacious 0.0.1 (git+https://github.com/Manishearth/rust-tenacious.git)", + "tenacious 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1185,8 +1185,8 @@ dependencies = [ [[package]] name = "tenacious" -version = "0.0.1" -source = "git+https://github.com/Manishearth/rust-tenacious.git#5112359cd36682cd7df3a7bb9a963299890be26c" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "time" diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index ce8b96337e1..041b4b2a25d 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -927,7 +927,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "plugins" version = "0.0.1" dependencies = [ - "tenacious 0.0.1 (git+https://github.com/Manishearth/rust-tenacious.git)", + "tenacious 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1178,8 +1178,8 @@ dependencies = [ [[package]] name = "tenacious" -version = "0.0.1" -source = "git+https://github.com/Manishearth/rust-tenacious.git#5112359cd36682cd7df3a7bb9a963299890be26c" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "time" diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock index 0a272d5fd01..1427e97c9c1 100644 --- a/ports/gonk/Cargo.lock +++ b/ports/gonk/Cargo.lock @@ -798,7 +798,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "plugins" version = "0.0.1" dependencies = [ - "tenacious 0.0.1 (git+https://github.com/Manishearth/rust-tenacious.git)", + "tenacious 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1048,8 +1048,8 @@ dependencies = [ [[package]] name = "tenacious" -version = "0.0.1" -source = "git+https://github.com/Manishearth/rust-tenacious.git#5112359cd36682cd7df3a7bb9a963299890be26c" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "time" From 9355186fa6fe88319847f485c15300591ed5947c Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Wed, 20 May 2015 08:17:02 -0700 Subject: [PATCH 25/38] Remove "experimental" from direction:rtl reftests No longer needed after #6138. --- tests/ref/basic.list | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/ref/basic.list b/tests/ref/basic.list index e27f3ff41b6..27d5b8aa0ce 100644 --- a/tests/ref/basic.list +++ b/tests/ref/basic.list @@ -225,7 +225,7 @@ flaky_cpu == linebreak_simple_a.html linebreak_simple_b.html == outset.html outset_ref.html != outset_blackborder.html blackborder_ref.html # Should be == with expected failure. See #2797 -experimental != overconstrained_block.html overconstrained_block_ref.html +!= overconstrained_block.html overconstrained_block_ref.html == overflow_auto.html overflow_simple_b.html == overflow_scroll.html overflow_simple_b.html == overflow_simple_a.html overflow_simple_b.html @@ -265,11 +265,11 @@ experimental != overconstrained_block.html overconstrained_block_ref.html == root_height_a.html root_height_b.html == root_margin_collapse_a.html root_margin_collapse_b.html == root_pseudo_a.html root_pseudo_b.html -experimental == rtl_body.html rtl_body_ref.html -experimental == rtl_float_a.html rtl_float_ref.html -experimental == rtl_margin_a.html rtl_margin_ref.html -experimental == rtl_simple.html rtl_simple_ref.html -experimental == rtl_table_a.html rtl_table_ref.html +== rtl_body.html rtl_body_ref.html +== rtl_float_a.html rtl_float_ref.html +== rtl_margin_a.html rtl_margin_ref.html +== rtl_simple.html rtl_simple_ref.html +== rtl_table_a.html rtl_table_ref.html == servo_center_a.html servo_center_ref.html == setattribute_id_restyle_a.html setattribute_id_restyle_b.html == stacking_context_overflow_a.html stacking_context_overflow_ref.html @@ -288,12 +288,12 @@ experimental == rtl_table_a.html rtl_table_ref.html == table_padding_a.html table_padding_ref.html == table_percentage_capping_a.html table_percentage_capping_ref.html == table_percentage_width_a.html table_percentage_width_ref.html -experimental == table_row_direction_a.html table_row_direction_ref.html +== table_row_direction_a.html table_row_direction_ref.html == table_width_attribute_a.html table_width_attribute_ref.html == text_align_complex_a.html text_align_complex_ref.html == text_align_justify_a.html text_align_justify_ref.html -experimental == text_align_rtl.html text_align_rtl_ref.html -experimental == text_align_start_end.html text_align_start_end_ref.html +== text_align_rtl.html text_align_rtl_ref.html +== text_align_start_end.html text_align_start_end_ref.html == text_decoration_cached.html text_decoration_cached_ref.html # text_decoration_propagation_a.html text_decoration_propagation_b.html != text_decoration_smoke_a.html text_decoration_smoke_ref.html From 3350522306ee087f892108ee82aeb9d58ee2363d Mon Sep 17 00:00:00 2001 From: ecoal95 Date: Wed, 20 May 2015 10:29:08 +0200 Subject: [PATCH 26/38] Layerize canvas Note that this keeps using readback right now, `NativeSurface` painting will be implemented soon. Also see https://github.com/servo/servo/issues/6142 --- components/canvas/Cargo.toml | 11 +- components/canvas/canvas_msg.rs | 83 ---- components/canvas/canvas_paint_task.rs | 353 +------------- components/canvas/lib.rs | 5 +- components/canvas/webgl_paint_task.rs | 20 +- components/canvas_traits/Cargo.toml | 23 + components/canvas_traits/lib.rs | 433 ++++++++++++++++++ components/compositing/Cargo.toml | 3 + components/compositing/compositor.rs | 2 +- components/compositing/lib.rs | 1 + components/gfx/Cargo.toml | 6 + components/gfx/lib.rs | 5 +- components/gfx/paint_context.rs | 2 +- components/gfx/paint_task.rs | 14 +- components/gfx_traits/Cargo.toml | 11 + components/{gfx => gfx_traits}/color.rs | 0 components/gfx_traits/lib.rs | 9 + components/layout/Cargo.toml | 6 + components/layout/context.rs | 8 +- components/layout/display_list_builder.rs | 116 +++-- components/layout/fragment.rs | 13 +- components/layout/layout_task.rs | 24 +- components/layout/lib.rs | 3 +- components/layout/wrapper.rs | 2 +- components/msg/Cargo.toml | 1 - components/script/Cargo.toml | 3 + components/script/dom/bindings/trace.rs | 4 +- components/script/dom/canvasgradient.rs | 2 +- .../script/dom/canvasrenderingcontext2d.rs | 8 +- components/script/dom/htmlcanvaselement.rs | 2 +- .../script/dom/webglrenderingcontext.rs | 2 +- components/script/lib.rs | 1 + components/servo/Cargo.lock | 31 +- ports/cef/Cargo.lock | 31 +- ports/gonk/Cargo.lock | 31 +- 35 files changed, 769 insertions(+), 500 deletions(-) delete mode 100644 components/canvas/canvas_msg.rs create mode 100644 components/canvas_traits/Cargo.toml create mode 100644 components/canvas_traits/lib.rs create mode 100644 components/gfx_traits/Cargo.toml rename components/{gfx => gfx_traits}/color.rs (100%) create mode 100644 components/gfx_traits/lib.rs diff --git a/components/canvas/Cargo.toml b/components/canvas/Cargo.toml index 52557fca98b..fd0072cb29e 100644 --- a/components/canvas/Cargo.toml +++ b/components/canvas/Cargo.toml @@ -13,17 +13,24 @@ git = "https://github.com/servo/rust-azure" [dependencies.geom] git = "https://github.com/servo/rust-geom" +[dependencies.layers] +git = "https://github.com/servo/rust-layers" + [dependencies.gleam] git = "https://github.com/servo/gleam" +[dependencies.canvas_traits] +path = "../canvas_traits" + [dependencies.util] path = "../util" -[dependencies.gfx] -path = "../gfx" +[dependencies.gfx_traits] +path = "../gfx_traits" [dependencies.offscreen_gl_context] git = "https://github.com/ecoal95/rust-offscreen-rendering-context" +features = ["texture_surface"] [dependencies] cssparser = "0.3.1" diff --git a/components/canvas/canvas_msg.rs b/components/canvas/canvas_msg.rs deleted file mode 100644 index aa0df80eb22..00000000000 --- a/components/canvas/canvas_msg.rs +++ /dev/null @@ -1,83 +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 canvas_paint_task::{FillOrStrokeStyle, LineCapStyle, LineJoinStyle, CompositionOrBlending}; -use geom::matrix2d::Matrix2D; -use geom::point::Point2D; -use geom::rect::Rect; -use geom::size::Size2D; -use std::sync::mpsc::{Sender}; - -#[derive(Clone)] -pub enum CanvasMsg { - Canvas2d(Canvas2dMsg), - Common(CanvasCommonMsg), - WebGL(CanvasWebGLMsg), -} - -#[derive(Clone)] -pub enum Canvas2dMsg { - Arc(Point2D, f32, f32, f32, bool), - ArcTo(Point2D, Point2D, f32), - DrawImage(Vec, Size2D, Rect, Rect, bool), - DrawImageSelf(Size2D, Rect, Rect, bool), - BeginPath, - BezierCurveTo(Point2D, Point2D, Point2D), - ClearRect(Rect), - Clip, - ClosePath, - Fill, - FillRect(Rect), - GetImageData(Rect, Size2D, Sender>), - LineTo(Point2D), - MoveTo(Point2D), - PutImageData(Vec, Rect, Option>), - QuadraticCurveTo(Point2D, Point2D), - Rect(Rect), - RestoreContext, - SaveContext, - StrokeRect(Rect), - Stroke, - SetFillStyle(FillOrStrokeStyle), - SetStrokeStyle(FillOrStrokeStyle), - SetLineWidth(f32), - SetLineCap(LineCapStyle), - SetLineJoin(LineJoinStyle), - SetMiterLimit(f32), - SetGlobalAlpha(f32), - SetGlobalComposition(CompositionOrBlending), - SetTransform(Matrix2D), -} - -#[derive(Clone)] -pub enum CanvasWebGLMsg { - AttachShader(u32, u32), - BindBuffer(u32, u32), - BufferData(u32, Vec, u32), - Clear(u32), - ClearColor(f32, f32, f32, f32), - CompileShader(u32), - CreateBuffer(Sender), - CreateProgram(Sender), - CreateShader(u32, Sender), - DrawArrays(u32, i32, i32), - EnableVertexAttribArray(u32), - GetAttribLocation(u32, String, Sender), - GetShaderInfoLog(u32, Sender), - GetShaderParameter(u32, u32, Sender), - GetUniformLocation(u32, String, Sender), - LinkProgram(u32), - ShaderSource(u32, Vec), - Uniform4fv(u32, Vec), - UseProgram(u32), - VertexAttribPointer2f(u32, i32, bool, i32, i64), - Viewport(i32, i32, i32, i32), -} - -#[derive(Clone)] -pub enum CanvasCommonMsg { - Close, - Recreate(Size2D), - SendPixelContents(Sender>), -} diff --git a/components/canvas/canvas_paint_task.rs b/components/canvas/canvas_paint_task.rs index 6906b96aa5c..07860fe93cc 100644 --- a/components/canvas/canvas_paint_task.rs +++ b/components/canvas/canvas_paint_task.rs @@ -5,19 +5,18 @@ use azure::azure::AzFloat; use azure::azure_hl::{DrawTarget, SurfaceFormat, BackendType, StrokeOptions, DrawOptions, Pattern}; use azure::azure_hl::{ColorPattern, PathBuilder, DrawSurfaceOptions, Filter}; -use azure::azure_hl::{GradientStop, LinearGradientPattern, RadialGradientPattern, ExtendMode}; -use azure::azure_hl::{JoinStyle, CapStyle, CompositionOp}; -use canvas_msg::{CanvasMsg, Canvas2dMsg, CanvasCommonMsg}; +use azure::azure_hl::{JoinStyle, CapStyle}; +use canvas_traits::*; use geom::matrix2d::Matrix2D; use geom::point::Point2D; use geom::rect::Rect; use geom::size::Size2D; -use gfx::color; +use layers::platform::surface::NativeSurface; +use gfx_traits::color; use num::ToPrimitive; use util::task::spawn_named; use util::vec::byte_swap; -use cssparser::RGBA; use std::borrow::ToOwned; use std::mem; use std::sync::mpsc::{channel, Sender}; @@ -257,6 +256,8 @@ impl<'a> CanvasPaintTask<'a> { CanvasCommonMsg::Recreate(size) => painter.recreate(size), CanvasCommonMsg::SendPixelContents(chan) => painter.send_pixel_contents(chan), + CanvasCommonMsg::SendNativeSurface(chan) => + painter.send_native_surface(chan), } }, CanvasMsg::WebGL(_) => panic!("Wrong message sent to Canvas2D task"), @@ -497,6 +498,14 @@ impl<'a> CanvasPaintTask<'a> { }) } + fn send_native_surface(&self, chan: Sender) { + let mut native_surface: NativeSurface = + NativeSurface::from_draw_target_backing(self.drawtarget.backing.clone()); + native_surface.mark_wont_leak(); + + chan.send(native_surface).unwrap(); + } + fn get_image_data(&self, mut dest_rect: Rect, canvas_size: Size2D, chan: Sender>) { if dest_rect.size.width < 0.0 { dest_rect.size.width = -dest_rect.size.width; @@ -566,340 +575,6 @@ impl<'a> CanvasPaintTask<'a> { } } -#[derive(Clone)] -pub struct CanvasGradientStop { - pub offset: f64, - pub color: RGBA, -} - -#[derive(Clone)] -pub struct LinearGradientStyle { - pub x0: f64, - pub y0: f64, - pub x1: f64, - pub y1: f64, - pub stops: Vec -} - -impl LinearGradientStyle { - pub fn new(x0: f64, y0: f64, x1: f64, y1: f64, stops: Vec) - -> LinearGradientStyle { - LinearGradientStyle { - x0: x0, - y0: y0, - x1: x1, - y1: y1, - stops: stops, - } - } -} - -#[derive(Clone)] -pub struct RadialGradientStyle { - pub x0: f64, - pub y0: f64, - pub r0: f64, - pub x1: f64, - pub y1: f64, - pub r1: f64, - pub stops: Vec -} - -impl RadialGradientStyle { - pub fn new(x0: f64, y0: f64, r0: f64, x1: f64, y1: f64, r1: f64, stops: Vec) - -> RadialGradientStyle { - RadialGradientStyle { - x0: x0, - y0: y0, - r0: r0, - x1: x1, - y1: y1, - r1: r1, - stops: stops, - } - } -} - -#[derive(Clone)] -pub enum FillOrStrokeStyle { - Color(RGBA), - LinearGradient(LinearGradientStyle), - RadialGradient(RadialGradientStyle), -} - -impl FillOrStrokeStyle { - fn to_azure_pattern(&self, drawtarget: &DrawTarget) -> Pattern { - match *self { - FillOrStrokeStyle::Color(ref color) => { - Pattern::Color(ColorPattern::new(color::new(color.red, - color.green, - color.blue, - color.alpha))) - }, - FillOrStrokeStyle::LinearGradient(ref linear_gradient_style) => { - let gradient_stops: Vec = linear_gradient_style.stops.iter().map(|s| { - GradientStop { - offset: s.offset as AzFloat, - color: color::new(s.color.red, s.color.green, s.color.blue, s.color.alpha) - } - }).collect(); - - Pattern::LinearGradient(LinearGradientPattern::new( - &Point2D(linear_gradient_style.x0 as AzFloat, linear_gradient_style.y0 as AzFloat), - &Point2D(linear_gradient_style.x1 as AzFloat, linear_gradient_style.y1 as AzFloat), - drawtarget.create_gradient_stops(&gradient_stops, ExtendMode::Clamp), - &Matrix2D::identity())) - }, - FillOrStrokeStyle::RadialGradient(ref radial_gradient_style) => { - let gradient_stops: Vec = radial_gradient_style.stops.iter().map(|s| { - GradientStop { - offset: s.offset as AzFloat, - color: color::new(s.color.red, s.color.green, s.color.blue, s.color.alpha) - } - }).collect(); - - Pattern::RadialGradient(RadialGradientPattern::new( - &Point2D(radial_gradient_style.x0 as AzFloat, radial_gradient_style.y0 as AzFloat), - &Point2D(radial_gradient_style.x1 as AzFloat, radial_gradient_style.y1 as AzFloat), - radial_gradient_style.r0 as AzFloat, radial_gradient_style.r1 as AzFloat, - drawtarget.create_gradient_stops(&gradient_stops, ExtendMode::Clamp), - &Matrix2D::identity())) - } - } - } -} - -#[derive(Copy, Clone, PartialEq)] -pub enum LineCapStyle { - Butt = 0, - Round = 1, - Square = 2, -} - -impl LineCapStyle { - fn to_azure_style(&self) -> CapStyle { - match *self { - LineCapStyle::Butt => CapStyle::Butt, - LineCapStyle::Round => CapStyle::Round, - LineCapStyle::Square => CapStyle::Square, - } - } - - pub fn from_str(string: &str) -> Option { - match string { - "butt" => Some(LineCapStyle::Butt), - "round" => Some(LineCapStyle::Round), - "square" => Some(LineCapStyle::Square), - _ => None - } - } -} - -#[derive(Copy, Clone, PartialEq)] -pub enum LineJoinStyle { - Round = 0, - Bevel = 1, - Miter = 2, -} - -impl LineJoinStyle { - fn to_azure_style(&self) -> JoinStyle { - match *self { - LineJoinStyle::Round => JoinStyle::Round, - LineJoinStyle::Bevel => JoinStyle::Bevel, - LineJoinStyle::Miter => JoinStyle::Miter, - } - } - - pub fn from_str(string: &str) -> Option { - match string { - "round" => Some(LineJoinStyle::Round), - "bevel" => Some(LineJoinStyle::Bevel), - "miter" => Some(LineJoinStyle::Miter), - _ => None - } - } -} - -#[derive(Copy, Clone, PartialEq)] -pub enum CompositionStyle { - SrcIn, - SrcOut, - SrcOver, - SrcAtop, - DestIn, - DestOut, - DestOver, - DestAtop, - Copy, - Lighter, - Xor, -} - -impl CompositionStyle { - fn to_azure_style(&self) -> CompositionOp { - match *self { - CompositionStyle::SrcIn => CompositionOp::In, - CompositionStyle::SrcOut => CompositionOp::Out, - CompositionStyle::SrcOver => CompositionOp::Over, - CompositionStyle::SrcAtop => CompositionOp::Atop, - CompositionStyle::DestIn => CompositionOp::DestIn, - CompositionStyle::DestOut => CompositionOp::DestOut, - CompositionStyle::DestOver => CompositionOp::DestOver, - CompositionStyle::DestAtop => CompositionOp::DestAtop, - CompositionStyle::Copy => CompositionOp::Source, - CompositionStyle::Lighter => CompositionOp::Add, - CompositionStyle::Xor => CompositionOp::Xor, - } - } - - pub fn from_str(string: &str) -> Option { - match string { - "source-in" => Some(CompositionStyle::SrcIn), - "source-out" => Some(CompositionStyle::SrcOut), - "source-over" => Some(CompositionStyle::SrcOver), - "source-atop" => Some(CompositionStyle::SrcAtop), - "destination-in" => Some(CompositionStyle::DestIn), - "destination-out" => Some(CompositionStyle::DestOut), - "destination-over" => Some(CompositionStyle::DestOver), - "destination-atop" => Some(CompositionStyle::DestAtop), - "copy" => Some(CompositionStyle::Copy), - "lighter" => Some(CompositionStyle::Lighter), - "xor" => Some(CompositionStyle::Xor), - _ => None - } - } - - pub fn to_str(&self) -> &str { - match *self { - CompositionStyle::SrcIn => "source-in", - CompositionStyle::SrcOut => "source-out", - CompositionStyle::SrcOver => "source-over", - CompositionStyle::SrcAtop => "source-atop", - CompositionStyle::DestIn => "destination-in", - CompositionStyle::DestOut => "destination-out", - CompositionStyle::DestOver => "destination-over", - CompositionStyle::DestAtop => "destination-atop", - CompositionStyle::Copy => "copy", - CompositionStyle::Lighter => "lighter", - CompositionStyle::Xor => "xor", - } - } -} - -#[derive(Copy, Clone, PartialEq)] -pub enum BlendingStyle { - Multiply, - Screen, - Overlay, - Darken, - Lighten, - ColorDodge, - ColorBurn, - HardLight, - SoftLight, - Difference, - Exclusion, - Hue, - Saturation, - Color, - Luminosity, -} - -impl BlendingStyle { - fn to_azure_style(&self) -> CompositionOp { - match *self { - BlendingStyle::Multiply => CompositionOp::Multiply, - BlendingStyle::Screen => CompositionOp::Screen, - BlendingStyle::Overlay => CompositionOp::Overlay, - BlendingStyle::Darken => CompositionOp::Darken, - BlendingStyle::Lighten => CompositionOp::Lighten, - BlendingStyle::ColorDodge => CompositionOp::ColorDodge, - BlendingStyle::ColorBurn => CompositionOp::ColorBurn, - BlendingStyle::HardLight => CompositionOp::HardLight, - BlendingStyle::SoftLight => CompositionOp::SoftLight, - BlendingStyle::Difference => CompositionOp::Difference, - BlendingStyle::Exclusion => CompositionOp::Exclusion, - BlendingStyle::Hue => CompositionOp::Hue, - BlendingStyle::Saturation => CompositionOp::Saturation, - BlendingStyle::Color => CompositionOp::Color, - BlendingStyle::Luminosity => CompositionOp::Luminosity, - } - } - - pub fn from_str(string: &str) -> Option { - match string { - "multiply" => Some(BlendingStyle::Multiply), - "screen" => Some(BlendingStyle::Screen), - "overlay" => Some(BlendingStyle::Overlay), - "darken" => Some(BlendingStyle::Darken), - "lighten" => Some(BlendingStyle::Lighten), - "color-dodge" => Some(BlendingStyle::ColorDodge), - "color-burn" => Some(BlendingStyle::ColorBurn), - "hard-light" => Some(BlendingStyle::HardLight), - "soft-light" => Some(BlendingStyle::SoftLight), - "difference" => Some(BlendingStyle::Difference), - "exclusion" => Some(BlendingStyle::Exclusion), - "hue" => Some(BlendingStyle::Hue), - "saturation" => Some(BlendingStyle::Saturation), - "color" => Some(BlendingStyle::Color), - "luminosity" => Some(BlendingStyle::Luminosity), - _ => None - } - } - - pub fn to_str(&self) -> &str { - match *self { - BlendingStyle::Multiply => "multiply", - BlendingStyle::Screen => "screen", - BlendingStyle::Overlay => "overlay", - BlendingStyle::Darken => "darken", - BlendingStyle::Lighten => "lighten", - BlendingStyle::ColorDodge => "color-dodge", - BlendingStyle::ColorBurn => "color-burn", - BlendingStyle::HardLight => "hard-light", - BlendingStyle::SoftLight => "soft-light", - BlendingStyle::Difference => "difference", - BlendingStyle::Exclusion => "exclusion", - BlendingStyle::Hue => "hue", - BlendingStyle::Saturation => "saturation", - BlendingStyle::Color => "color", - BlendingStyle::Luminosity => "luminosity", - } - } -} - -#[derive(Copy, Clone, PartialEq)] -pub enum CompositionOrBlending { - Composition(CompositionStyle), - Blending(BlendingStyle), -} - -impl CompositionOrBlending { - fn to_azure_style(&self) -> CompositionOp { - match *self { - CompositionOrBlending::Composition(op) => op.to_azure_style(), - CompositionOrBlending::Blending(op) => op.to_azure_style(), - } - } - - pub fn default() -> CompositionOrBlending { - CompositionOrBlending::Composition(CompositionStyle::SrcOver) - } - - pub fn from_str(string: &str) -> Option { - if let Some(op) = CompositionStyle::from_str(string) { - return Some(CompositionOrBlending::Composition(op)); - } - - if let Some(op) = BlendingStyle::from_str(string) { - return Some(CompositionOrBlending::Blending(op)); - } - - None - } -} - /// Used by drawImage to get rid of the extra pixels of the image data that /// won't be copied to the canvas /// image_data: Color pixel data of the image diff --git a/components/canvas/lib.rs b/components/canvas/lib.rs index 2fb0ea8b8f5..962231581ef 100644 --- a/components/canvas/lib.rs +++ b/components/canvas/lib.rs @@ -6,13 +6,15 @@ #![feature(collections)] #![feature(rustc_private)] +extern crate canvas_traits; extern crate azure; extern crate cssparser; extern crate geom; -extern crate gfx; +extern crate gfx_traits; extern crate util; extern crate gleam; extern crate num; +extern crate layers; extern crate offscreen_gl_context; #[macro_use] @@ -20,4 +22,3 @@ extern crate log; pub mod canvas_paint_task; pub mod webgl_paint_task; -pub mod canvas_msg; diff --git a/components/canvas/webgl_paint_task.rs b/components/canvas/webgl_paint_task.rs index 155cbde2297..c98f30ebbad 100644 --- a/components/canvas/webgl_paint_task.rs +++ b/components/canvas/webgl_paint_task.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 canvas_msg::{CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg}; +use canvas_traits::{CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg}; use geom::size::Size2D; use gleam::gl; @@ -14,7 +14,8 @@ use std::borrow::ToOwned; use std::slice::bytes::copy_memory; use std::sync::mpsc::{channel, Sender}; use util::vec::byte_swap; -use offscreen_gl_context::{GLContext, GLContextAttributes}; +use layers::platform::surface::NativeSurface; +use offscreen_gl_context::{GLContext, GLContextAttributes, ColorAttachmentType}; pub struct WebGLPaintTask { size: Size2D, @@ -29,7 +30,9 @@ unsafe impl Send for WebGLPaintTask {} impl WebGLPaintTask { fn new(size: Size2D) -> Result { // TODO(ecoal95): Get the GLContextAttributes from the `GetContext` call - let context = try!(GLContext::create_offscreen(size, GLContextAttributes::default())); + let context = try!(GLContext::create_offscreen_with_color_attachment(size, + GLContextAttributes::default(), + ColorAttachmentType::TextureWithSurface)); Ok(WebGLPaintTask { size: size, original_context_size: size, @@ -76,7 +79,10 @@ impl WebGLPaintTask { CanvasMsg::Common(message) => { match message { CanvasCommonMsg::Close => break, - CanvasCommonMsg::SendPixelContents(chan) => painter.send_pixel_contents(chan), + CanvasCommonMsg::SendPixelContents(chan) => + painter.send_pixel_contents(chan), + CanvasCommonMsg::SendNativeSurface(chan) => + painter.send_native_surface(chan), // TODO(ecoal95): handle error nicely CanvasCommonMsg::Recreate(size) => painter.recreate(size).unwrap(), } @@ -184,6 +190,12 @@ impl WebGLPaintTask { chan.send(pixels).unwrap(); } + fn send_native_surface(&self, _: Sender) { + // FIXME(ecoal95): We need to make a clone of the surface in order to + // implement this + unimplemented!() + } + fn shader_source(&self, shader_id: u32, source_lines: Vec) { let mut lines: Vec<&[u8]> = source_lines.iter().map(|line| line.as_bytes()).collect(); gl::shader_source(shader_id, &mut lines); diff --git a/components/canvas_traits/Cargo.toml b/components/canvas_traits/Cargo.toml new file mode 100644 index 00000000000..8b9a0a518e8 --- /dev/null +++ b/components/canvas_traits/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "canvas_traits" +version = "0.0.1" +authors = ["The Servo Project Developers"] + +[lib] +name = "canvas_traits" +path = "lib.rs" + +[dependencies.gfx_traits] +path = "../gfx_traits" + +[dependencies.geom] +git = "https://github.com/servo/rust-geom" + +[dependencies.azure] +git = "https://github.com/servo/rust-azure" + +[dependencies.layers] +git = "https://github.com/servo/rust-layers" + +[dependencies] +cssparser = "0.3.1" diff --git a/components/canvas_traits/lib.rs b/components/canvas_traits/lib.rs new file mode 100644 index 00000000000..611274ef48a --- /dev/null +++ b/components/canvas_traits/lib.rs @@ -0,0 +1,433 @@ +/* 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/. */ + +#![crate_name = "canvas_traits"] +#![crate_type = "rlib"] +extern crate azure; +extern crate geom; +extern crate cssparser; +extern crate gfx_traits; +extern crate layers; + +use azure::azure::AzFloat; +use azure::azure_hl::{DrawTarget, Pattern, ColorPattern}; +use azure::azure_hl::{GradientStop, LinearGradientPattern, RadialGradientPattern, ExtendMode}; +use azure::azure_hl::{JoinStyle, CapStyle, CompositionOp}; +use cssparser::RGBA; +use geom::matrix2d::Matrix2D; +use geom::point::Point2D; +use geom::rect::Rect; +use geom::size::Size2D; +use gfx_traits::color; +use std::sync::mpsc::{Sender}; +use layers::platform::surface::NativeSurface; + +#[derive(Clone)] +pub enum CanvasMsg { + Canvas2d(Canvas2dMsg), + Common(CanvasCommonMsg), + WebGL(CanvasWebGLMsg), +} + +#[derive(Clone)] +pub enum Canvas2dMsg { + Arc(Point2D, f32, f32, f32, bool), + ArcTo(Point2D, Point2D, f32), + DrawImage(Vec, Size2D, Rect, Rect, bool), + DrawImageSelf(Size2D, Rect, Rect, bool), + BeginPath, + BezierCurveTo(Point2D, Point2D, Point2D), + ClearRect(Rect), + Clip, + ClosePath, + Fill, + FillRect(Rect), + GetImageData(Rect, Size2D, Sender>), + LineTo(Point2D), + MoveTo(Point2D), + PutImageData(Vec, Rect, Option>), + QuadraticCurveTo(Point2D, Point2D), + Rect(Rect), + RestoreContext, + SaveContext, + StrokeRect(Rect), + Stroke, + SetFillStyle(FillOrStrokeStyle), + SetStrokeStyle(FillOrStrokeStyle), + SetLineWidth(f32), + SetLineCap(LineCapStyle), + SetLineJoin(LineJoinStyle), + SetMiterLimit(f32), + SetGlobalAlpha(f32), + SetGlobalComposition(CompositionOrBlending), + SetTransform(Matrix2D), +} + +#[derive(Clone)] +pub enum CanvasWebGLMsg { + AttachShader(u32, u32), + BindBuffer(u32, u32), + BufferData(u32, Vec, u32), + Clear(u32), + ClearColor(f32, f32, f32, f32), + CompileShader(u32), + CreateBuffer(Sender), + CreateProgram(Sender), + CreateShader(u32, Sender), + DrawArrays(u32, i32, i32), + EnableVertexAttribArray(u32), + GetAttribLocation(u32, String, Sender), + GetShaderInfoLog(u32, Sender), + GetShaderParameter(u32, u32, Sender), + GetUniformLocation(u32, String, Sender), + LinkProgram(u32), + ShaderSource(u32, Vec), + Uniform4fv(u32, Vec), + UseProgram(u32), + VertexAttribPointer2f(u32, i32, bool, i32, i64), + Viewport(i32, i32, i32, i32), +} + +#[derive(Clone)] +pub enum CanvasCommonMsg { + Close, + Recreate(Size2D), + SendPixelContents(Sender>), + SendNativeSurface(Sender), +} + + +#[derive(Clone)] +pub struct CanvasGradientStop { + pub offset: f64, + pub color: RGBA, +} + +#[derive(Clone)] +pub struct LinearGradientStyle { + pub x0: f64, + pub y0: f64, + pub x1: f64, + pub y1: f64, + pub stops: Vec +} + +impl LinearGradientStyle { + pub fn new(x0: f64, y0: f64, x1: f64, y1: f64, stops: Vec) + -> LinearGradientStyle { + LinearGradientStyle { + x0: x0, + y0: y0, + x1: x1, + y1: y1, + stops: stops, + } + } +} + +#[derive(Clone)] +pub struct RadialGradientStyle { + pub x0: f64, + pub y0: f64, + pub r0: f64, + pub x1: f64, + pub y1: f64, + pub r1: f64, + pub stops: Vec +} + +impl RadialGradientStyle { + pub fn new(x0: f64, y0: f64, r0: f64, x1: f64, y1: f64, r1: f64, stops: Vec) + -> RadialGradientStyle { + RadialGradientStyle { + x0: x0, + y0: y0, + r0: r0, + x1: x1, + y1: y1, + r1: r1, + stops: stops, + } + } +} + +#[derive(Clone)] +pub enum FillOrStrokeStyle { + Color(RGBA), + LinearGradient(LinearGradientStyle), + RadialGradient(RadialGradientStyle), +} + +impl FillOrStrokeStyle { + pub fn to_azure_pattern(&self, drawtarget: &DrawTarget) -> Pattern { + match *self { + FillOrStrokeStyle::Color(ref color) => { + Pattern::Color(ColorPattern::new(color::new(color.red, + color.green, + color.blue, + color.alpha))) + }, + FillOrStrokeStyle::LinearGradient(ref linear_gradient_style) => { + let gradient_stops: Vec = linear_gradient_style.stops.iter().map(|s| { + GradientStop { + offset: s.offset as AzFloat, + color: color::new(s.color.red, s.color.green, s.color.blue, s.color.alpha) + } + }).collect(); + + Pattern::LinearGradient(LinearGradientPattern::new( + &Point2D(linear_gradient_style.x0 as AzFloat, linear_gradient_style.y0 as AzFloat), + &Point2D(linear_gradient_style.x1 as AzFloat, linear_gradient_style.y1 as AzFloat), + drawtarget.create_gradient_stops(&gradient_stops, ExtendMode::Clamp), + &Matrix2D::identity())) + }, + FillOrStrokeStyle::RadialGradient(ref radial_gradient_style) => { + let gradient_stops: Vec = radial_gradient_style.stops.iter().map(|s| { + GradientStop { + offset: s.offset as AzFloat, + color: color::new(s.color.red, s.color.green, s.color.blue, s.color.alpha) + } + }).collect(); + + Pattern::RadialGradient(RadialGradientPattern::new( + &Point2D(radial_gradient_style.x0 as AzFloat, radial_gradient_style.y0 as AzFloat), + &Point2D(radial_gradient_style.x1 as AzFloat, radial_gradient_style.y1 as AzFloat), + radial_gradient_style.r0 as AzFloat, radial_gradient_style.r1 as AzFloat, + drawtarget.create_gradient_stops(&gradient_stops, ExtendMode::Clamp), + &Matrix2D::identity())) + } + } + } +} + +#[derive(Copy, Clone, PartialEq)] +pub enum LineCapStyle { + Butt = 0, + Round = 1, + Square = 2, +} + +impl LineCapStyle { + pub fn to_azure_style(&self) -> CapStyle { + match *self { + LineCapStyle::Butt => CapStyle::Butt, + LineCapStyle::Round => CapStyle::Round, + LineCapStyle::Square => CapStyle::Square, + } + } + + pub fn from_str(string: &str) -> Option { + match string { + "butt" => Some(LineCapStyle::Butt), + "round" => Some(LineCapStyle::Round), + "square" => Some(LineCapStyle::Square), + _ => None + } + } +} + +#[derive(Copy, Clone, PartialEq)] +pub enum LineJoinStyle { + Round = 0, + Bevel = 1, + Miter = 2, +} + +impl LineJoinStyle { + pub fn to_azure_style(&self) -> JoinStyle { + match *self { + LineJoinStyle::Round => JoinStyle::Round, + LineJoinStyle::Bevel => JoinStyle::Bevel, + LineJoinStyle::Miter => JoinStyle::Miter, + } + } + + pub fn from_str(string: &str) -> Option { + match string { + "round" => Some(LineJoinStyle::Round), + "bevel" => Some(LineJoinStyle::Bevel), + "miter" => Some(LineJoinStyle::Miter), + _ => None + } + } +} + +#[derive(Copy, Clone, PartialEq)] +pub enum CompositionStyle { + SrcIn, + SrcOut, + SrcOver, + SrcAtop, + DestIn, + DestOut, + DestOver, + DestAtop, + Copy, + Lighter, + Xor, +} + +impl CompositionStyle { + pub fn to_azure_style(&self) -> CompositionOp { + match *self { + CompositionStyle::SrcIn => CompositionOp::In, + CompositionStyle::SrcOut => CompositionOp::Out, + CompositionStyle::SrcOver => CompositionOp::Over, + CompositionStyle::SrcAtop => CompositionOp::Atop, + CompositionStyle::DestIn => CompositionOp::DestIn, + CompositionStyle::DestOut => CompositionOp::DestOut, + CompositionStyle::DestOver => CompositionOp::DestOver, + CompositionStyle::DestAtop => CompositionOp::DestAtop, + CompositionStyle::Copy => CompositionOp::Source, + CompositionStyle::Lighter => CompositionOp::Add, + CompositionStyle::Xor => CompositionOp::Xor, + } + } + + pub fn from_str(string: &str) -> Option { + match string { + "source-in" => Some(CompositionStyle::SrcIn), + "source-out" => Some(CompositionStyle::SrcOut), + "source-over" => Some(CompositionStyle::SrcOver), + "source-atop" => Some(CompositionStyle::SrcAtop), + "destination-in" => Some(CompositionStyle::DestIn), + "destination-out" => Some(CompositionStyle::DestOut), + "destination-over" => Some(CompositionStyle::DestOver), + "destination-atop" => Some(CompositionStyle::DestAtop), + "copy" => Some(CompositionStyle::Copy), + "lighter" => Some(CompositionStyle::Lighter), + "xor" => Some(CompositionStyle::Xor), + _ => None + } + } + + pub fn to_str(&self) -> &str { + match *self { + CompositionStyle::SrcIn => "source-in", + CompositionStyle::SrcOut => "source-out", + CompositionStyle::SrcOver => "source-over", + CompositionStyle::SrcAtop => "source-atop", + CompositionStyle::DestIn => "destination-in", + CompositionStyle::DestOut => "destination-out", + CompositionStyle::DestOver => "destination-over", + CompositionStyle::DestAtop => "destination-atop", + CompositionStyle::Copy => "copy", + CompositionStyle::Lighter => "lighter", + CompositionStyle::Xor => "xor", + } + } +} + +#[derive(Copy, Clone, PartialEq)] +pub enum BlendingStyle { + Multiply, + Screen, + Overlay, + Darken, + Lighten, + ColorDodge, + ColorBurn, + HardLight, + SoftLight, + Difference, + Exclusion, + Hue, + Saturation, + Color, + Luminosity, +} + +impl BlendingStyle { + pub fn to_azure_style(&self) -> CompositionOp { + match *self { + BlendingStyle::Multiply => CompositionOp::Multiply, + BlendingStyle::Screen => CompositionOp::Screen, + BlendingStyle::Overlay => CompositionOp::Overlay, + BlendingStyle::Darken => CompositionOp::Darken, + BlendingStyle::Lighten => CompositionOp::Lighten, + BlendingStyle::ColorDodge => CompositionOp::ColorDodge, + BlendingStyle::ColorBurn => CompositionOp::ColorBurn, + BlendingStyle::HardLight => CompositionOp::HardLight, + BlendingStyle::SoftLight => CompositionOp::SoftLight, + BlendingStyle::Difference => CompositionOp::Difference, + BlendingStyle::Exclusion => CompositionOp::Exclusion, + BlendingStyle::Hue => CompositionOp::Hue, + BlendingStyle::Saturation => CompositionOp::Saturation, + BlendingStyle::Color => CompositionOp::Color, + BlendingStyle::Luminosity => CompositionOp::Luminosity, + } + } + + pub fn from_str(string: &str) -> Option { + match string { + "multiply" => Some(BlendingStyle::Multiply), + "screen" => Some(BlendingStyle::Screen), + "overlay" => Some(BlendingStyle::Overlay), + "darken" => Some(BlendingStyle::Darken), + "lighten" => Some(BlendingStyle::Lighten), + "color-dodge" => Some(BlendingStyle::ColorDodge), + "color-burn" => Some(BlendingStyle::ColorBurn), + "hard-light" => Some(BlendingStyle::HardLight), + "soft-light" => Some(BlendingStyle::SoftLight), + "difference" => Some(BlendingStyle::Difference), + "exclusion" => Some(BlendingStyle::Exclusion), + "hue" => Some(BlendingStyle::Hue), + "saturation" => Some(BlendingStyle::Saturation), + "color" => Some(BlendingStyle::Color), + "luminosity" => Some(BlendingStyle::Luminosity), + _ => None + } + } + + pub fn to_str(&self) -> &str { + match *self { + BlendingStyle::Multiply => "multiply", + BlendingStyle::Screen => "screen", + BlendingStyle::Overlay => "overlay", + BlendingStyle::Darken => "darken", + BlendingStyle::Lighten => "lighten", + BlendingStyle::ColorDodge => "color-dodge", + BlendingStyle::ColorBurn => "color-burn", + BlendingStyle::HardLight => "hard-light", + BlendingStyle::SoftLight => "soft-light", + BlendingStyle::Difference => "difference", + BlendingStyle::Exclusion => "exclusion", + BlendingStyle::Hue => "hue", + BlendingStyle::Saturation => "saturation", + BlendingStyle::Color => "color", + BlendingStyle::Luminosity => "luminosity", + } + } +} + +#[derive(Copy, Clone, PartialEq)] +pub enum CompositionOrBlending { + Composition(CompositionStyle), + Blending(BlendingStyle), +} + +impl CompositionOrBlending { + pub fn to_azure_style(&self) -> CompositionOp { + match *self { + CompositionOrBlending::Composition(op) => op.to_azure_style(), + CompositionOrBlending::Blending(op) => op.to_azure_style(), + } + } + + pub fn default() -> CompositionOrBlending { + CompositionOrBlending::Composition(CompositionStyle::SrcOver) + } + + pub fn from_str(string: &str) -> Option { + if let Some(op) = CompositionStyle::from_str(string) { + return Some(CompositionOrBlending::Composition(op)); + } + + if let Some(op) = BlendingStyle::from_str(string) { + return Some(CompositionOrBlending::Blending(op)); + } + + None + } +} diff --git a/components/compositing/Cargo.toml b/components/compositing/Cargo.toml index a16df45f0ed..54be36997f9 100644 --- a/components/compositing/Cargo.toml +++ b/components/compositing/Cargo.toml @@ -10,6 +10,9 @@ path = "lib.rs" [dependencies.gfx] path = "../gfx" +[dependencies.gfx_traits] +path = "../gfx_traits" + [dependencies.layout_traits] path = "../layout_traits" diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index cd2c66e84b8..6f3d24087a8 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -15,7 +15,7 @@ use geom::point::{Point2D, TypedPoint2D}; use geom::rect::{Rect, TypedRect}; use geom::scale_factor::ScaleFactor; use geom::size::{Size2D, TypedSize2D}; -use gfx::color; +use gfx_traits::color; use gfx::paint_task::Msg as PaintMsg; use gfx::paint_task::PaintRequest; use gleam::gl::types::{GLint, GLsizei}; diff --git a/components/compositing/lib.rs b/components/compositing/lib.rs index 4bfdf0fe2a9..db6726bb668 100644 --- a/components/compositing/lib.rs +++ b/components/compositing/lib.rs @@ -23,6 +23,7 @@ extern crate net; extern crate num; extern crate profile_traits; extern crate net_traits; +extern crate gfx_traits; extern crate style; #[macro_use] extern crate util; diff --git a/components/gfx/Cargo.toml b/components/gfx/Cargo.toml index 5e26c6a7e0c..d912508a523 100644 --- a/components/gfx/Cargo.toml +++ b/components/gfx/Cargo.toml @@ -11,9 +11,15 @@ path = "lib.rs" [dependencies.plugins] path = "../plugins" +[dependencies.gfx_traits] +path = "../gfx_traits" + [dependencies.net_traits] path = "../net_traits" +[dependencies.canvas_traits] +path = "../canvas_traits" + [dependencies.util] path = "../util" diff --git a/components/gfx/lib.rs b/components/gfx/lib.rs index 57633303bfb..738174d1390 100644 --- a/components/gfx/lib.rs +++ b/components/gfx/lib.rs @@ -38,6 +38,9 @@ extern crate skia; extern crate time; extern crate url; +extern crate gfx_traits; +extern crate canvas_traits; + // Eventually we would like the shaper to be pluggable, as many operating systems have their own // shapers. For now, however, this is a hard dependency. extern crate harfbuzz; @@ -59,8 +62,6 @@ pub use paint_context::PaintContext; // Private painting modules mod paint_context; -// Painting -pub mod color; #[path="display_list/mod.rs"] pub mod display_list; pub mod paint_task; diff --git a/components/gfx/paint_context.rs b/components/gfx/paint_context.rs index 24e7f1f7958..490e3ae3f6a 100644 --- a/components/gfx/paint_context.rs +++ b/components/gfx/paint_context.rs @@ -4,7 +4,7 @@ //! Painting of display lists using Moz2D/Azure. -use color; +use gfx_traits::color; use display_list::TextOrientation::{SidewaysLeft, SidewaysRight, Upright}; use display_list::{BLUR_INFLATION_FACTOR, BorderRadii, BoxShadowClipMode, ClippingRegion}; use display_list::{TextDisplayItem}; diff --git a/components/gfx/paint_task.rs b/components/gfx/paint_task.rs index 04570f14c80..10f748e7b5c 100644 --- a/components/gfx/paint_task.rs +++ b/components/gfx/paint_task.rs @@ -20,6 +20,7 @@ use layers::platform::surface::{NativeGraphicsMetadata, NativePaintingGraphicsCo use layers::platform::surface::NativeSurface; use layers::layers::{BufferRequest, LayerBuffer, LayerBufferSet}; use layers; +use canvas_traits::CanvasMsg; use msg::compositor_msg::{Epoch, FrameTreeId, LayerId}; use msg::compositor_msg::{LayerProperties, PaintListener, ScrollPolicy}; use msg::constellation_msg::Msg as ConstellationMsg; @@ -30,8 +31,9 @@ use rand::{self, Rng}; use skia::SkiaGrGLNativeContextRef; use std::borrow::ToOwned; use std::mem; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::sync::mpsc::{Receiver, Sender, channel}; +use std::collections::HashMap; use util::geometry::{Au, ZERO_POINT}; use util::opts; use util::task::spawn_named_with_send_on_failure; @@ -69,6 +71,7 @@ pub struct PaintRequest { pub enum Msg { PaintInit(Epoch, Arc), + CanvasLayer(LayerId, Arc>>), Paint(Vec, FrameTreeId), UnusedBuffer(Vec>), PaintPermissionGranted, @@ -125,6 +128,9 @@ pub struct PaintTask { /// Tracks the number of buffers that the compositor currently owns. The /// PaintTask waits to exit until all buffers are returned. used_buffer_count: usize, + + /// A map to track the canvas specific layers + canvas_map: HashMap>>>, } // If we implement this as a function, we get borrowck errors from borrowing @@ -170,6 +176,7 @@ impl PaintTask where C: PaintListener + Send + 'static { buffer_map: BufferMap::new(10000000), worker_threads: worker_threads, used_buffer_count: 0, + canvas_map: HashMap::new() }; paint_task.start(); @@ -216,6 +223,11 @@ impl PaintTask where C: PaintListener + Send + 'static { self.initialize_layers(); } + // Inserts a new canvas renderer to the layer map + Msg::CanvasLayer(layer_id, canvas_renderer) => { + debug!("Renderer received for canvas with layer {:?}", layer_id); + self.canvas_map.insert(layer_id, canvas_renderer); + } Msg::Paint(requests, frame_tree_id) => { if !self.paint_permission { debug!("PaintTask: paint ready msg"); diff --git a/components/gfx_traits/Cargo.toml b/components/gfx_traits/Cargo.toml new file mode 100644 index 00000000000..913e973d163 --- /dev/null +++ b/components/gfx_traits/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "gfx_traits" +version = "0.0.1" +authors = ["The Servo Project Developers"] + +[lib] +name = "gfx_traits" +path = "lib.rs" + +[dependencies.azure] +git = "https://github.com/servo/rust-azure" diff --git a/components/gfx/color.rs b/components/gfx_traits/color.rs similarity index 100% rename from components/gfx/color.rs rename to components/gfx_traits/color.rs diff --git a/components/gfx_traits/lib.rs b/components/gfx_traits/lib.rs new file mode 100644 index 00000000000..ea77933ce89 --- /dev/null +++ b/components/gfx_traits/lib.rs @@ -0,0 +1,9 @@ +/* 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/. */ + +#![crate_name = "gfx_traits"] +#![crate_type = "rlib"] +extern crate azure; + +pub mod color; diff --git a/components/layout/Cargo.toml b/components/layout/Cargo.toml index fa527f4d5c9..d3ae3fd878a 100644 --- a/components/layout/Cargo.toml +++ b/components/layout/Cargo.toml @@ -13,9 +13,15 @@ git = "https://github.com/servo/rust-azure" [dependencies.canvas] path = "../canvas" +[dependencies.canvas_traits] +path = "../canvas_traits" + [dependencies.gfx] path = "../gfx" +[dependencies.gfx_traits] +path = "../gfx_traits" + [dependencies.msg] path = "../msg" diff --git a/components/layout/context.rs b/components/layout/context.rs index e83f4453b04..cf909115048 100644 --- a/components/layout/context.rs +++ b/components/layout/context.rs @@ -8,11 +8,12 @@ use css::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache}; +use canvas_traits::CanvasMsg; +use msg::compositor_msg::LayerId; use geom::{Rect, Size2D}; use gfx::display_list::OpaqueNode; use gfx::font_cache_task::FontCacheTask; use gfx::font_context::FontContext; -use msg::compositor_msg::LayerId; use msg::constellation_msg::ConstellationChan; use net_traits::image::base::Image; use net_traits::image_cache_task::{ImageCacheChan, ImageCacheTask, ImageState}; @@ -22,7 +23,7 @@ use std::cell::Cell; use std::collections::HashMap; use std::collections::hash_state::DefaultState; use std::ptr; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::sync::mpsc::{channel, Sender}; use style::selector_matching::Stylist; use url::Url; @@ -103,6 +104,9 @@ pub struct SharedLayoutContext { /// sent. pub new_animations_sender: Sender, + /// A channel to send canvas renderers to paint task, in order to correctly paint the layers + pub canvas_layers_sender: Sender<(LayerId, Option>>>)>, + /// The visible rects for each layer, as reported to us by the compositor. pub visible_rects: Arc, DefaultState>>, diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index aac8a7c2317..fbbb46b68b9 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -12,7 +12,6 @@ use azure::azure_hl::Color; use block::BlockFlow; -use canvas::canvas_msg::{CanvasMsg, CanvasCommonMsg}; use context::LayoutContext; use flow::{self, BaseFlow, Flow, IS_ABSOLUTELY_POSITIONED, NEEDS_LAYER}; use fragment::{CoordinateSystem, Fragment, IframeFragmentInfo, ImageFragmentInfo}; @@ -23,7 +22,7 @@ use model::{self, MaybeAuto, ToGfxMatrix}; use table_cell::CollapsedBordersForCell; use geom::{Matrix2D, Point2D, Rect, Size2D, SideOffsets2D}; -use gfx::color; +use gfx_traits::color; use gfx::display_list::{BLUR_INFLATION_FACTOR, BaseDisplayItem, BorderDisplayItem}; use gfx::display_list::{BorderRadii, BoxShadowClipMode, BoxShadowDisplayItem, ClippingRegion}; use gfx::display_list::{DisplayItem, DisplayList, DisplayItemMetadata}; @@ -32,7 +31,7 @@ use gfx::display_list::{GradientStop, ImageDisplayItem, LineDisplayItem}; use gfx::display_list::{OpaqueNode, SolidColorDisplayItem}; use gfx::display_list::{StackingContext, TextDisplayItem, TextOrientation}; use gfx::paint_task::{PaintLayer, THREAD_TINT_COLORS}; -use msg::compositor_msg::ScrollPolicy; +use msg::compositor_msg::{ScrollPolicy, LayerId}; use msg::constellation_msg::ConstellationChan; use msg::constellation_msg::Msg as ConstellationMsg; use png::{self, PixelsByColorType}; @@ -40,7 +39,6 @@ use std::cmp; use std::default::Default; use std::iter::repeat; use std::sync::Arc; -use std::sync::mpsc::channel; use style::computed_values::filter::Filter; use style::computed_values::transform::ComputedMatrix; use style::computed_values::{background_attachment, background_clip, background_origin, background_repeat, background_size}; @@ -56,6 +54,15 @@ use util::geometry::{Au, ZERO_POINT}; use util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode}; use util::opts; +use canvas_traits::{CanvasMsg, CanvasCommonMsg}; +use std::sync::mpsc::channel; + +/// A possible `PaintLayer` for an stacking context +pub enum StackingContextLayer { + Existing(PaintLayer), + IfCanvas(LayerId), +} + /// The results of display list building for a single flow. pub enum DisplayListBuildingResult { None, @@ -240,7 +247,8 @@ pub trait FragmentDisplayListBuilding { fn create_stacking_context(&self, base_flow: &BaseFlow, display_list: Box, - layer: Option>) + layout_context: &LayoutContext, + layer: StackingContextLayer) -> Arc; } @@ -1077,11 +1085,11 @@ impl FragmentDisplayListBuilding for Fragment { } } SpecificFragmentInfo::Canvas(ref canvas_fragment_info) => { + // TODO(ecoal95): make the canvas with a renderer use the custom layer let width = canvas_fragment_info.replaced_image_fragment_info .computed_inline_size.map_or(0, |w| w.to_px() as usize); let height = canvas_fragment_info.replaced_image_fragment_info .computed_block_size.map_or(0, |h| h.to_px() as usize); - let (sender, receiver) = channel::>(); let canvas_data = match canvas_fragment_info.renderer { Some(ref renderer) => { @@ -1091,12 +1099,11 @@ impl FragmentDisplayListBuilding for Fragment { }, None => repeat(0xFFu8).take(width * height * 4).collect(), }; - - let canvas_display_item = box ImageDisplayItem { + display_list.content.push_back(DisplayItem::ImageClass(box ImageDisplayItem{ base: BaseDisplayItem::new(stacking_relative_content_box, DisplayItemMetadata::new(self.node, - &*self.style, - Cursor::DefaultCursor), + &*self.style, + Cursor::DefaultCursor), (*clip).clone()), image: Arc::new(png::Image { width: width as u32, @@ -1105,9 +1112,7 @@ impl FragmentDisplayListBuilding for Fragment { }), stretch_size: stacking_relative_content_box.size, image_rendering: image_rendering::T::Auto, - }; - - display_list.content.push_back(DisplayItem::ImageClass(canvas_display_item)); + })); } SpecificFragmentInfo::UnscannedText(_) => { panic!("Shouldn't see unscanned fragments here.") @@ -1121,7 +1126,8 @@ impl FragmentDisplayListBuilding for Fragment { fn create_stacking_context(&self, base_flow: &BaseFlow, display_list: Box, - layer: Option>) + layout_context: &LayoutContext, + layer: StackingContextLayer) -> Arc { let border_box = self.stacking_relative_border_box(&base_flow.stacking_relative_position, &base_flow.absolute_position_info @@ -1153,6 +1159,28 @@ impl FragmentDisplayListBuilding for Fragment { filters.push(Filter::Opacity(effects.opacity)) } + // Ensure every canvas has a layer + let layer = match layer { + StackingContextLayer::Existing(existing_layer) => Some(existing_layer), + StackingContextLayer::IfCanvas(layer_id) => { + if let SpecificFragmentInfo::Canvas(_) = self.specific { + Some(PaintLayer::new(layer_id, color::transparent(), ScrollPolicy::Scrollable)) + } else { + None + } + } + }; + + // If it's a canvas we must propagate the layer and the renderer to the paint + // task + if let SpecificFragmentInfo::Canvas(ref fragment_info) = self.specific { + let layer_id = layer.as_ref().unwrap().id; + layout_context.shared.canvas_layers_sender + .send((layer_id, fragment_info.renderer.clone())).unwrap(); + } + + let layer = layer.map(|l| Arc::new(l)); + Arc::new(StackingContext::new(display_list, &border_box, &overflow, @@ -1419,10 +1447,11 @@ impl BlockFlowDisplayListBuilding for BlockFlow { background_border_level); self.base.display_list_building_result = if self.fragment.establishes_stacking_context() { - DisplayListBuildingResult::StackingContext(self.fragment.create_stacking_context( - &self.base, - display_list, - None)) + DisplayListBuildingResult::StackingContext( + self.fragment.create_stacking_context(&self.base, + display_list, + layout_context, + StackingContextLayer::IfCanvas(self.layer_id(0)))) } else { match self.fragment.style.get_box().position { position::T::static_ => {} @@ -1452,10 +1481,11 @@ impl BlockFlowDisplayListBuilding for BlockFlow { if !self.will_get_layer() { // We didn't need a layer. self.base.display_list_building_result = - DisplayListBuildingResult::StackingContext(self.fragment.create_stacking_context( - &self.base, - display_list, - None)); + DisplayListBuildingResult::StackingContext( + self.fragment.create_stacking_context(&self.base, + display_list, + layout_context, + StackingContextLayer::IfCanvas(self.layer_id(0)))); return } @@ -1466,11 +1496,11 @@ impl BlockFlowDisplayListBuilding for BlockFlow { ScrollPolicy::Scrollable }; - let transparent = color::transparent(); - let stacking_context = self.fragment.create_stacking_context( - &self.base, - display_list, - Some(Arc::new(PaintLayer::new(self.layer_id(0), transparent, scroll_policy)))); + let paint_layer = PaintLayer::new(self.layer_id(0), color::transparent(), scroll_policy); + let stacking_context = self.fragment.create_stacking_context(&self.base, + display_list, + layout_context, + StackingContextLayer::Existing(paint_layer)); self.base.display_list_building_result = DisplayListBuildingResult::StackingContext(stacking_context) } @@ -1487,7 +1517,10 @@ impl BlockFlowDisplayListBuilding for BlockFlow { self.base.display_list_building_result = if self.fragment.establishes_stacking_context() { DisplayListBuildingResult::StackingContext( - self.fragment.create_stacking_context(&self.base, display_list, None)) + self.fragment.create_stacking_context(&self.base, + display_list, + layout_context, + StackingContextLayer::IfCanvas(self.layer_id(0)))) } else { DisplayListBuildingResult::Normal(display_list) } @@ -1544,6 +1577,7 @@ impl InlineFlowDisplayListBuilding for InlineFlow { &self.base.stacking_relative_position_of_display_port); has_stacking_context = fragment.establishes_stacking_context(); + match fragment.specific { SpecificFragmentInfo::InlineBlock(ref mut block_flow) => { let block_flow = &mut *block_flow.flow_ref; @@ -1571,17 +1605,23 @@ impl InlineFlowDisplayListBuilding for InlineFlow { // FIXME(Savago): fix Fragment::establishes_stacking_context() for absolute positioned item // and remove the check for filter presence. Further details on #5812. - if has_stacking_context && - !self.fragments.fragments[0].style().get_effects().filter.is_empty() { - self.base.display_list_building_result = - DisplayListBuildingResult::StackingContext( - self.fragments.fragments[0].create_stacking_context(&self.base, - display_list, - None)); + has_stacking_context = has_stacking_context && { + if let SpecificFragmentInfo::Canvas(_) = self.fragments.fragments[0].specific { + true + } else { + !self.fragments.fragments[0].style().get_effects().filter.is_empty() + } + }; + + self.base.display_list_building_result = if has_stacking_context { + DisplayListBuildingResult::StackingContext( + self.fragments.fragments[0].create_stacking_context(&self.base, + display_list, + layout_context, + StackingContextLayer::IfCanvas(self.layer_id(0)))) } else { - self.base.display_list_building_result = - DisplayListBuildingResult::Normal(display_list); - } + DisplayListBuildingResult::Normal(display_list) + }; if opts::get().validate_display_list_geometry { self.base.validate_display_list_geometry(); diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index c8d496c04bf..426ea8e60d8 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -6,7 +6,7 @@ #![deny(unsafe_code)] -use canvas::canvas_msg::CanvasMsg; +use canvas_traits::CanvasMsg; use css::node_style::StyledNode; use context::LayoutContext; use floats::ClearType; @@ -195,9 +195,7 @@ impl SpecificFragmentInfo { SpecificFragmentInfo::Iframe(_) => "SpecificFragmentInfo::Iframe", SpecificFragmentInfo::Image(_) => "SpecificFragmentInfo::Image", SpecificFragmentInfo::InlineAbsolute(_) => "SpecificFragmentInfo::InlineAbsolute", - SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => { - "SpecificFragmentInfo::InlineAbsoluteHypothetical" - } + SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => "SpecificFragmentInfo::InlineAbsoluteHypothetical", SpecificFragmentInfo::InlineBlock(_) => "SpecificFragmentInfo::InlineBlock", SpecificFragmentInfo::ScannedText(_) => "SpecificFragmentInfo::ScannedText", SpecificFragmentInfo::Table => "SpecificFragmentInfo::Table", @@ -1993,6 +1991,13 @@ impl Fragment { if self.style().get_effects().transform.is_some() { return true } + + // Canvas always layerizes, as an special case + // FIXME(pcwalton): Don't unconditionally form stacking contexts for each canvas. + if let SpecificFragmentInfo::Canvas(_) = self.specific { + return true + } + match self.style().get_box().position { position::T::absolute | position::T::fixed => { // FIXME(pcwalton): This should only establish a new stacking context when diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 702c28f887d..b0ed2bc3c64 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -24,6 +24,7 @@ use sequential; use wrapper::{LayoutNode, TLayoutNode}; use azure::azure::AzColor; +use canvas_traits::CanvasMsg; use encoding::EncodingRef; use encoding::all::UTF_8; use geom::matrix2d::Matrix2D; @@ -31,7 +32,7 @@ use geom::point::Point2D; use geom::rect::Rect; use geom::scale_factor::ScaleFactor; use geom::size::Size2D; -use gfx::color; +use gfx_traits::color; use gfx::display_list::{ClippingRegion, DisplayItemMetadata, DisplayList, OpaqueNode}; use gfx::display_list::{StackingContext}; use gfx::font_cache_task::FontCacheTask; @@ -39,7 +40,7 @@ use gfx::paint_task::Msg as PaintMsg; use gfx::paint_task::{PaintChan, PaintLayer}; use layout_traits::{LayoutControlMsg, LayoutTaskFactory}; use log; -use msg::compositor_msg::{Epoch, LayerId, ScrollPolicy}; +use msg::compositor_msg::{Epoch, ScrollPolicy, LayerId}; use msg::constellation_msg::Msg as ConstellationMsg; use msg::constellation_msg::{ConstellationChan, Failure, PipelineExitType, PipelineId}; use profile_traits::mem::{self, Report, ReportsChan}; @@ -134,7 +135,7 @@ pub struct LayoutTaskData { /// sent. pub new_animations_sender: Sender, - /// A counter for epoch messages. + /// A counter for epoch messages epoch: Epoch, /// The position and size of the visible rect for each layer. We do not build display lists @@ -195,6 +196,11 @@ pub struct LayoutTask { /// Is this the first reflow in this LayoutTask? pub first_reflow: Cell, + /// To receive a canvas renderer associated to a layer, this message is propagated + /// to the paint chan + pub canvas_layers_receiver: Receiver<(LayerId, Option>>>)>, + pub canvas_layers_sender: Sender<(LayerId, Option>>>)>, + /// A mutex to allow for fast, read-only RPC of layout's internal data /// structures, while still letting the LayoutTask modify them. /// @@ -310,6 +316,7 @@ impl LayoutTask { // Create the channel on which new animations can be sent. let (new_animations_sender, new_animations_receiver) = channel(); let (image_cache_sender, image_cache_receiver) = channel(); + let (canvas_layers_sender, canvas_layers_receiver) = channel(); LayoutTask { id: id, @@ -329,6 +336,8 @@ impl LayoutTask { first_reflow: Cell::new(true), image_cache_receiver: image_cache_receiver, image_cache_sender: ImageCacheChan(image_cache_sender), + canvas_layers_receiver: canvas_layers_receiver, + canvas_layers_sender: canvas_layers_sender, rw_data: Arc::new(Mutex::new( LayoutTaskData { root_flow: None, @@ -375,6 +384,7 @@ impl LayoutTask { constellation_chan: rw_data.constellation_chan.clone(), layout_chan: self.chan.clone(), font_cache_task: self.font_cache_task.clone(), + canvas_layers_sender: self.canvas_layers_sender.clone(), stylist: &*rw_data.stylist, url: (*url).clone(), reflow_root: reflow_root.map(|node| OpaqueNodeMethods::from_layout_node(node)), @@ -960,6 +970,14 @@ impl LayoutTask { animation::process_new_animations(&mut *rw_data, self.id); } + // Send new canvas renderers to the paint task + while let Ok((layer_id, renderer)) = self.canvas_layers_receiver.try_recv() { + // Just send if there's an actual renderer + if let Some(renderer) = renderer { + self.paint_chan.send(PaintMsg::CanvasLayer(layer_id, renderer)); + } + } + // Perform post-style recalculation layout passes. self.perform_post_style_recalc_layout_passes(&data.reflow_info, &mut rw_data, diff --git a/components/layout/lib.rs b/components/layout/lib.rs index b394c5db88a..ec4bcbe0a85 100644 --- a/components/layout/lib.rs +++ b/components/layout/lib.rs @@ -39,13 +39,14 @@ extern crate util; extern crate rustc_serialize; extern crate alloc; extern crate azure; -extern crate canvas; +extern crate canvas_traits; extern crate clock_ticks; extern crate collections; extern crate cssparser; extern crate encoding; extern crate geom; extern crate gfx; +extern crate gfx_traits; extern crate layout_traits; extern crate libc; extern crate msg; diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index 256aca623e0..cf65ec3c6c0 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -32,7 +32,7 @@ #![allow(unsafe_code)] -use canvas::canvas_msg::CanvasMsg; +use canvas_traits::CanvasMsg; use context::SharedLayoutContext; use css::node_style::StyledNode; use incremental::RestyleDamage; diff --git a/components/msg/Cargo.toml b/components/msg/Cargo.toml index af1da0b3b7c..fa70fe5463e 100644 --- a/components/msg/Cargo.toml +++ b/components/msg/Cargo.toml @@ -1,5 +1,4 @@ [package] - name = "msg" version = "0.0.1" authors = ["The Servo Project Developers"] diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index 5db6d535d75..54f83eb9cfc 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -42,6 +42,9 @@ path = "../gfx" [dependencies.canvas] path = "../canvas" +[dependencies.canvas_traits] +path = "../canvas_traits" + [dependencies.webdriver_traits] path = "../webdriver_traits" diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index d3da922c640..9b7d83c2c26 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -34,8 +34,8 @@ use dom::bindings::refcounted::Trusted; use dom::bindings::utils::{Reflectable, Reflector, WindowProxyHandler}; use script_task::ScriptChan; -use canvas::canvas_paint_task::{CanvasGradientStop, LinearGradientStyle, RadialGradientStyle}; -use canvas::canvas_paint_task::{LineCapStyle, LineJoinStyle, CompositionOrBlending}; +use canvas_traits::{CanvasGradientStop, LinearGradientStyle, RadialGradientStyle}; +use canvas_traits::{LineCapStyle, LineJoinStyle, CompositionOrBlending}; use cssparser::RGBA; use encoding::types::EncodingRef; use geom::matrix2d::Matrix2D; diff --git a/components/script/dom/canvasgradient.rs b/components/script/dom/canvasgradient.rs index eec31c3fc79..b0a7ea924da 100644 --- a/components/script/dom/canvasgradient.rs +++ b/components/script/dom/canvasgradient.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use cssparser::RGBA; -use canvas::canvas_paint_task::{CanvasGradientStop, FillOrStrokeStyle, LinearGradientStyle, RadialGradientStyle}; +use canvas_traits::{CanvasGradientStop, FillOrStrokeStyle, LinearGradientStyle, RadialGradientStyle}; use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::CanvasGradientBinding; use dom::bindings::codegen::Bindings::CanvasGradientBinding::CanvasGradientMethods; diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index 6353479b116..147c8646e2e 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -28,10 +28,10 @@ use geom::point::Point2D; use geom::rect::Rect; use geom::size::Size2D; -use canvas::canvas_msg::{CanvasMsg, Canvas2dMsg, CanvasCommonMsg}; -use canvas::canvas_paint_task::{CanvasPaintTask, FillOrStrokeStyle}; -use canvas::canvas_paint_task::{LinearGradientStyle, RadialGradientStyle}; -use canvas::canvas_paint_task::{LineCapStyle, LineJoinStyle, CompositionOrBlending}; +use canvas_traits::{CanvasMsg, Canvas2dMsg, CanvasCommonMsg}; +use canvas_traits::{FillOrStrokeStyle, LinearGradientStyle, RadialGradientStyle}; +use canvas_traits::{LineCapStyle, LineJoinStyle, CompositionOrBlending}; +use canvas::canvas_paint_task::CanvasPaintTask; use net_traits::image::base::Image; use net_traits::image_cache_task::ImageCacheChan; diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index 47431248294..5d3b01427bf 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.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 canvas::canvas_msg::CanvasMsg; +use canvas_traits::CanvasMsg; use dom::attr::Attr; use dom::attr::AttrHelpers; use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding; diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 82dfc614f52..939225caa66 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use canvas::webgl_paint_task::WebGLPaintTask; -use canvas::canvas_msg::{CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg}; +use canvas_traits::{CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg}; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{ WebGLRenderingContextMethods, WebGLRenderingContextConstants}; use dom::bindings::global::{GlobalRef, GlobalField}; diff --git a/components/script/lib.rs b/components/script/lib.rs index 403d53fccbe..290c0793cb0 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -40,6 +40,7 @@ extern crate png; extern crate rustc_serialize; extern crate time; extern crate canvas; +extern crate canvas_traits; extern crate profile_traits; extern crate script_traits; extern crate selectors; diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index f2184517738..8f9c9cc9db5 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -69,15 +69,28 @@ name = "canvas" version = "0.0.1" dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", + "canvas_traits 0.0.1", "cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", - "gfx 0.0.1", + "gfx_traits 0.0.1", "gleam 0.0.1 (git+https://github.com/servo/gleam)", + "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "num 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "offscreen_gl_context 0.0.1 (git+https://github.com/ecoal95/rust-offscreen-rendering-context)", "util 0.0.1", ] +[[package]] +name = "canvas_traits" +version = "0.0.1" +dependencies = [ + "azure 0.1.0 (git+https://github.com/servo/rust-azure)", + "cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "geom 0.1.0 (git+https://github.com/servo/rust-geom)", + "gfx_traits 0.0.1", + "layers 0.1.0 (git+https://github.com/servo/rust-layers)", +] + [[package]] name = "cgl" version = "0.0.1" @@ -115,6 +128,7 @@ dependencies = [ "devtools_traits 0.0.1", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gfx 0.0.1", + "gfx_traits 0.0.1", "gleam 0.0.1 (git+https://github.com/servo/gleam)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "layout_traits 0.0.1", @@ -355,12 +369,14 @@ version = "0.0.1" dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "canvas_traits 0.0.1", "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)", "core_text 0.1.0 (git+https://github.com/servo/rust-core-text)", "fontconfig 0.1.0 (git+https://github.com/servo/rust-fontconfig)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", + "gfx_traits 0.0.1", "harfbuzz 0.1.0 (git+https://github.com/servo/rust-harfbuzz)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -388,6 +404,13 @@ dependencies = [ "gfx 0.0.1", ] +[[package]] +name = "gfx_traits" +version = "0.0.1" +dependencies = [ + "azure 0.1.0 (git+https://github.com/servo/rust-azure)", +] + [[package]] name = "gl" version = "0.0.12" @@ -647,11 +670,13 @@ dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "canvas 0.0.1", + "canvas_traits 0.0.1", "clock_ticks 0.0.5 (git+https://github.com/tomaka/clock_ticks)", "cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gfx 0.0.1", + "gfx_traits 0.0.1", "layout_traits 0.0.1", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", @@ -853,13 +878,14 @@ dependencies = [ [[package]] name = "offscreen_gl_context" version = "0.0.1" -source = "git+https://github.com/ecoal95/rust-offscreen-rendering-context#c2b3dfd7fe344384e4206672b99c296141f5b4d6" +source = "git+https://github.com/ecoal95/rust-offscreen-rendering-context#97eacf34b72f69b10130a0de016529e98ee32f04" dependencies = [ "cgl 0.0.1 (git+https://github.com/servo/rust-cgl)", "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gleam 0.0.1 (git+https://github.com/servo/gleam)", "glx 0.0.1 (git+https://github.com/servo/rust-glx)", + "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "xlib 0.1.0 (git+https://github.com/servo/rust-xlib)", @@ -1021,6 +1047,7 @@ version = "0.0.1" dependencies = [ "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "canvas 0.0.1", + "canvas_traits 0.0.1", "cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "devtools_traits 0.0.1", "encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index ac322cc6079..1b09503afdc 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -68,15 +68,28 @@ name = "canvas" version = "0.0.1" dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", + "canvas_traits 0.0.1", "cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", - "gfx 0.0.1", + "gfx_traits 0.0.1", "gleam 0.0.1 (git+https://github.com/servo/gleam)", + "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "num 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "offscreen_gl_context 0.0.1 (git+https://github.com/ecoal95/rust-offscreen-rendering-context)", "util 0.0.1", ] +[[package]] +name = "canvas_traits" +version = "0.0.1" +dependencies = [ + "azure 0.1.0 (git+https://github.com/servo/rust-azure)", + "cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "geom 0.1.0 (git+https://github.com/servo/rust-geom)", + "gfx_traits 0.0.1", + "layers 0.1.0 (git+https://github.com/servo/rust-layers)", +] + [[package]] name = "cgl" version = "0.0.1" @@ -124,6 +137,7 @@ dependencies = [ "devtools_traits 0.0.1", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gfx 0.0.1", + "gfx_traits 0.0.1", "gleam 0.0.1 (git+https://github.com/servo/gleam)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "layout_traits 0.0.1", @@ -364,12 +378,14 @@ version = "0.0.1" dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "canvas_traits 0.0.1", "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)", "core_text 0.1.0 (git+https://github.com/servo/rust-core-text)", "fontconfig 0.1.0 (git+https://github.com/servo/rust-fontconfig)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", + "gfx_traits 0.0.1", "harfbuzz 0.1.0 (git+https://github.com/servo/rust-harfbuzz)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -390,6 +406,13 @@ dependencies = [ "util 0.0.1", ] +[[package]] +name = "gfx_traits" +version = "0.0.1" +dependencies = [ + "azure 0.1.0 (git+https://github.com/servo/rust-azure)", +] + [[package]] name = "gl" version = "0.0.12" @@ -649,11 +672,13 @@ dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "canvas 0.0.1", + "canvas_traits 0.0.1", "clock_ticks 0.0.5 (git+https://github.com/tomaka/clock_ticks)", "cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gfx 0.0.1", + "gfx_traits 0.0.1", "layout_traits 0.0.1", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", @@ -843,13 +868,14 @@ dependencies = [ [[package]] name = "offscreen_gl_context" version = "0.0.1" -source = "git+https://github.com/ecoal95/rust-offscreen-rendering-context#c2b3dfd7fe344384e4206672b99c296141f5b4d6" +source = "git+https://github.com/ecoal95/rust-offscreen-rendering-context#97eacf34b72f69b10130a0de016529e98ee32f04" dependencies = [ "cgl 0.0.1 (git+https://github.com/servo/rust-cgl)", "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gleam 0.0.1 (git+https://github.com/servo/gleam)", "glx 0.0.1 (git+https://github.com/servo/rust-glx)", + "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "xlib 0.1.0 (git+https://github.com/servo/rust-xlib)", @@ -1011,6 +1037,7 @@ version = "0.0.1" dependencies = [ "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "canvas 0.0.1", + "canvas_traits 0.0.1", "cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "devtools_traits 0.0.1", "encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock index 815e6cf8af0..183fe99a97e 100644 --- a/ports/gonk/Cargo.lock +++ b/ports/gonk/Cargo.lock @@ -55,15 +55,28 @@ name = "canvas" version = "0.0.1" dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", + "canvas_traits 0.0.1", "cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", - "gfx 0.0.1", + "gfx_traits 0.0.1", "gleam 0.0.1 (git+https://github.com/servo/gleam)", + "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "num 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "offscreen_gl_context 0.0.1 (git+https://github.com/ecoal95/rust-offscreen-rendering-context)", "util 0.0.1", ] +[[package]] +name = "canvas_traits" +version = "0.0.1" +dependencies = [ + "azure 0.1.0 (git+https://github.com/servo/rust-azure)", + "cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "geom 0.1.0 (git+https://github.com/servo/rust-geom)", + "gfx_traits 0.0.1", + "layers 0.1.0 (git+https://github.com/servo/rust-layers)", +] + [[package]] name = "cgl" version = "0.0.1" @@ -101,6 +114,7 @@ dependencies = [ "devtools_traits 0.0.1", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gfx 0.0.1", + "gfx_traits 0.0.1", "gleam 0.0.1 (git+https://github.com/servo/gleam)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "layout_traits 0.0.1", @@ -343,12 +357,14 @@ version = "0.0.1" dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "canvas_traits 0.0.1", "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)", "core_text 0.1.0 (git+https://github.com/servo/rust-core-text)", "fontconfig 0.1.0 (git+https://github.com/servo/rust-fontconfig)", "freetype 0.1.0 (git+https://github.com/servo/rust-freetype)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", + "gfx_traits 0.0.1", "harfbuzz 0.1.0 (git+https://github.com/servo/rust-harfbuzz)", "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -369,6 +385,13 @@ dependencies = [ "util 0.0.1", ] +[[package]] +name = "gfx_traits" +version = "0.0.1" +dependencies = [ + "azure 0.1.0 (git+https://github.com/servo/rust-azure)", +] + [[package]] name = "gl_common" version = "0.0.4" @@ -547,11 +570,13 @@ dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "canvas 0.0.1", + "canvas_traits 0.0.1", "clock_ticks 0.0.5 (git+https://github.com/tomaka/clock_ticks)", "cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gfx 0.0.1", + "gfx_traits 0.0.1", "layout_traits 0.0.1", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", @@ -724,13 +749,14 @@ dependencies = [ [[package]] name = "offscreen_gl_context" version = "0.0.1" -source = "git+https://github.com/ecoal95/rust-offscreen-rendering-context#c2b3dfd7fe344384e4206672b99c296141f5b4d6" +source = "git+https://github.com/ecoal95/rust-offscreen-rendering-context#97eacf34b72f69b10130a0de016529e98ee32f04" dependencies = [ "cgl 0.0.1 (git+https://github.com/servo/rust-cgl)", "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "gleam 0.0.1 (git+https://github.com/servo/gleam)", "glx 0.0.1 (git+https://github.com/servo/rust-glx)", + "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "xlib 0.1.0 (git+https://github.com/servo/rust-xlib)", @@ -882,6 +908,7 @@ version = "0.0.1" dependencies = [ "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "canvas 0.0.1", + "canvas_traits 0.0.1", "cssparser 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "devtools_traits 0.0.1", "encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", From 0098d9e9e8de666b40113b023255915388ecef22 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 15 May 2015 15:07:26 -0700 Subject: [PATCH 27/38] compositing: Support multiple events per frame. Improves scrolling performance on Mac. --- components/compositing/compositor.rs | 23 +++++++--- components/compositing/compositor_layer.rs | 3 +- components/compositing/compositor_task.rs | 2 +- components/compositing/headless.rs | 2 +- components/compositing/lib.rs | 5 +-- components/servo/lib.rs | 8 ++-- components/servo/main.rs | 11 ++--- ports/cef/browser.rs | 4 +- ports/cef/window.rs | 4 +- ports/glutin/window.rs | 52 +++++++++++----------- ports/gonk/src/main.rs | 8 ++-- ports/gonk/src/window.rs | 4 +- 12 files changed, 67 insertions(+), 59 deletions(-) diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index cd2c66e84b8..84ef6deed95 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -1003,7 +1003,8 @@ impl IOCompositor { if pipeline_details.animations_running || pipeline_details.animation_callbacks_running { - self.constellation_chan.0.send(ConstellationMsg::TickAnimation(*pipeline_id)).unwrap(); + self.constellation_chan.0.send(ConstellationMsg::TickAnimation(*pipeline_id)) + .unwrap(); } } } @@ -1064,7 +1065,10 @@ impl IOCompositor { if let Some(min_zoom) = self.min_viewport_zoom.as_ref() { viewport_zoom = min_zoom.get().max(viewport_zoom) } - let viewport_zoom = self.max_viewport_zoom.as_ref().map_or(1., |z| z.get()).min(viewport_zoom); + let viewport_zoom = self.max_viewport_zoom + .as_ref() + .map_or(1., |z| z.get()) + .min(viewport_zoom); let viewport_zoom = ScaleFactor::new(viewport_zoom); self.viewport_zoom = viewport_zoom; @@ -1355,7 +1359,12 @@ impl IOCompositor { rv } - fn draw_png(&self, framebuffer_ids: Vec, texture_ids: Vec, width: usize, height: usize) -> png::Image { + fn draw_png(&self, + framebuffer_ids: Vec, + texture_ids: Vec, + width: usize, + height: usize) + -> png::Image { let mut pixels = gl::read_pixels(0, 0, width as gl::GLsizei, height as gl::GLsizei, @@ -1489,7 +1498,7 @@ fn find_layer_with_pipeline_and_layer_id_for_layer(layer: Rc CompositorEventListener for IOCompositor where Window: WindowMethods { - fn handle_event(&mut self, msg: WindowEvent) -> bool { + fn handle_events(&mut self, messages: Vec) -> bool { // Check for new messages coming from the other tasks in the system. loop { match self.port.try_recv_compositor_msg() { @@ -1509,8 +1518,10 @@ impl CompositorEventListener for IOCompositor where Window: Wind return false; } - // Handle the message coming from the windowing system. - self.handle_window_message(msg); + // Handle any messages coming from the windowing system. + for message in messages.into_iter() { + self.handle_window_message(message); + } // If a pinch-zoom happened recently, ask for tiles at the new resolution if self.zoom_action && precise_time_s() - self.zoom_time > 0.3 { diff --git a/components/compositing/compositor_layer.rs b/components/compositing/compositor_layer.rs index 36e78aef207..0a37340c4f9 100644 --- a/components/compositing/compositor_layer.rs +++ b/components/compositing/compositor_layer.rs @@ -87,7 +87,8 @@ pub trait CompositorLayer { /// 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) where Window: WindowMethods; + fn clear_all_tiles(&self, compositor: &IOCompositor) + where Window: WindowMethods; /// Removes the root layer (and any children) for a given pipeline from the /// compositor. Buffers that the compositor is holding are returned to the diff --git a/components/compositing/compositor_task.rs b/components/compositing/compositor_task.rs index 10a49fa3928..904e69da83b 100644 --- a/components/compositing/compositor_task.rs +++ b/components/compositing/compositor_task.rs @@ -254,7 +254,7 @@ impl CompositorTask { } pub trait CompositorEventListener { - fn handle_event(&mut self, event: WindowEvent) -> bool; + fn handle_events(&mut self, events: Vec) -> bool; fn repaint_synchronously(&mut self); fn shutdown(&mut self); fn pinch_zoom_level(&self) -> f32; diff --git a/components/compositing/headless.rs b/components/compositing/headless.rs index 37aca5d1883..2f9aa30e744 100644 --- a/components/compositing/headless.rs +++ b/components/compositing/headless.rs @@ -66,7 +66,7 @@ impl NullCompositor { } impl CompositorEventListener for NullCompositor { - fn handle_event(&mut self, _: WindowEvent) -> bool { + fn handle_events(&mut self, _: Vec) -> bool { match self.port.recv_compositor_msg() { Msg::Exit(chan) => { debug!("shutting down the constellation"); diff --git a/components/compositing/lib.rs b/components/compositing/lib.rs index 4bfdf0fe2a9..bffe3c401f1 100644 --- a/components/compositing/lib.rs +++ b/components/compositing/lib.rs @@ -45,12 +45,11 @@ pub use constellation::Constellation; pub mod compositor_task; mod compositor_layer; -mod scrolling; - mod compositor; mod headless; +mod scrolling; pub mod pipeline; pub mod constellation; - pub mod windowing; + diff --git a/components/servo/lib.rs b/components/servo/lib.rs index c00f36eacbf..4f254d5f682 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -75,9 +75,9 @@ pub struct Browser { /// application Servo is embedded in. Clients then create an event /// loop to pump messages between the embedding application and /// various browser components. -impl Browser { +impl Browser { pub fn new(window: Option>) -> Browser - where Window: WindowMethods + 'static { + where Window: WindowMethods + 'static { // Global configuration options, parsed from the command line. let opts = opts::get(); @@ -124,8 +124,8 @@ impl Browser { } } - pub fn handle_event(&mut self, event: WindowEvent) -> bool { - self.compositor.handle_event(event) + pub fn handle_events(&mut self, events: Vec) -> bool { + self.compositor.handle_events(events) } pub fn repaint_synchronously(&mut self) { diff --git a/components/servo/main.rs b/components/servo/main.rs index bee05978b42..ef12ef2171a 100644 --- a/components/servo/main.rs +++ b/components/servo/main.rs @@ -64,17 +64,14 @@ fn main() { maybe_register_glutin_resize_handler(&window, &mut browser); - browser.browser.handle_event(WindowEvent::InitializeCompositing); + browser.browser.handle_events(vec![WindowEvent::InitializeCompositing]); // Feed events from the window to the browser until the browser // says to stop. loop { let should_continue = match window { - None => browser.browser.handle_event(WindowEvent::Idle), - Some(ref window) => { - let event = window.wait_events(); - browser.browser.handle_event(event) - } + None => browser.browser.handle_events(Vec::new()), + Some(ref window) => browser.browser.handle_events(window.wait_events()), }; if !should_continue { break @@ -123,7 +120,7 @@ impl app::NestedEventLoopListener for BrowserWrapper { WindowEvent::Resize(..) => true, _ => false, }; - if !self.browser.handle_event(event) { + if !self.browser.handle_events(vec![event]) { return false } if is_resize { diff --git a/ports/cef/browser.rs b/ports/cef/browser.rs index 0885897c8f7..8b2ab3b2b0f 100644 --- a/ports/cef/browser.rs +++ b/ports/cef/browser.rs @@ -32,8 +32,8 @@ pub enum ServoBrowser { impl ServoBrowser { fn handle_event(&mut self, event: WindowEvent) { match *self { - ServoBrowser::OnScreen(ref mut browser) => { browser.handle_event(event); } - ServoBrowser::OffScreen(ref mut browser) => { browser.handle_event(event); } + ServoBrowser::OnScreen(ref mut browser) => { browser.handle_events(vec![event]); } + ServoBrowser::OffScreen(ref mut browser) => { browser.handle_events(vec![event]); } ServoBrowser::Invalid => {} } } diff --git a/ports/cef/window.rs b/ports/cef/window.rs index e6d51118497..06104484475 100644 --- a/ports/cef/window.rs +++ b/ports/cef/window.rs @@ -100,8 +100,8 @@ impl Window { } /// Currently unimplemented. - pub fn wait_events(&self) -> WindowEvent { - WindowEvent::Idle + pub fn wait_events(&self) -> Vec { + vec![WindowEvent::Idle] } fn cursor_type_for_cursor(&self, cursor: Cursor) -> cef_cursor_type_t { diff --git a/ports/glutin/window.rs b/ports/glutin/window.rs index fa81f3b5db4..1878389ced3 100644 --- a/ports/glutin/window.rs +++ b/ports/glutin/window.rs @@ -14,13 +14,15 @@ use layers::geometry::DevicePixel; use layers::platform::surface::NativeGraphicsMetadata; use msg::constellation_msg; use msg::constellation_msg::Key; -use NestedEventLoopListener; +use std::mem; use std::rc::Rc; use std::sync::mpsc::{channel, Sender}; use url::Url; use util::cursor::Cursor; use util::geometry::ScreenPx; +use NestedEventLoopListener; + #[cfg(feature = "window")] use compositing::windowing::{MouseWindowEvent, WindowNavigateMsg}; #[cfg(feature = "window")] @@ -259,7 +261,16 @@ impl Window { #[cfg(target_os="macos")] fn handle_next_event(&self) -> bool { let event = self.window.wait_events().next().unwrap(); - self.handle_window_event(event) + let mut close = self.handle_window_event(event); + if !close { + while let Some(event) = self.window.poll_events().next() { + if self.handle_window_event(event) { + close = true; + break + } + } + } + close } #[cfg(any(target_os="linux", target_os="android"))] @@ -283,7 +294,9 @@ impl Window { // // See https://github.com/servo/servo/issues/5780 // - match self.window.poll_events().next() { + let first_event = self.window.poll_events().next(); + + match first_event { Some(event) => { self.handle_window_event(event) } @@ -294,40 +307,27 @@ impl Window { } } - 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); - } - } - + pub fn wait_events(&self) -> Vec { + let mut events = mem::replace(&mut *self.event_queue.borrow_mut(), Vec::new()); 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; - } + while let Some(event) = self.window.poll_events().next() { + close_event = self.handle_window_event(event) || close_event; } } else { close_event = self.handle_next_event(); } 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) - } + events.push(WindowEvent::Quit) } + + events.extend(mem::replace(&mut *self.event_queue.borrow_mut(), Vec::new()).into_iter()); + events } pub unsafe fn set_nested_event_loop_listener( @@ -634,8 +634,8 @@ impl Window { Rc::new(window) } - pub fn wait_events(&self) -> WindowEvent { - WindowEvent::Idle + pub fn wait_events(&self) -> Vec { + vec![WindowEvent::Idle] } pub unsafe fn set_nested_event_loop_listener( diff --git a/ports/gonk/src/main.rs b/ports/gonk/src/main.rs index 335fdd361b6..f8324d531fc 100644 --- a/ports/gonk/src/main.rs +++ b/ports/gonk/src/main.rs @@ -76,16 +76,16 @@ fn main() { Some(ref window) => input::run_input_loop(&window.event_send) } - browser.browser.handle_event(WindowEvent::InitializeCompositing); + browser.browser.handle_events(vec![WindowEvent::InitializeCompositing]); // Feed events from the window to the browser until the browser // says to stop. loop { let should_continue = match window { - None => browser.browser.handle_event(WindowEvent::Idle), + None => browser.browser.handle_events(vec![WindowEvent::Idle]), Some(ref window) => { - let event = window.wait_events(); - browser.browser.handle_event(event) + let events = window.wait_events(); + browser.browser.handle_events(events) } }; if !should_continue { diff --git a/ports/gonk/src/window.rs b/ports/gonk/src/window.rs index a718123e6de..c6c60088232 100644 --- a/ports/gonk/src/window.rs +++ b/ports/gonk/src/window.rs @@ -754,8 +754,8 @@ impl Window { Rc::new(window) } - pub fn wait_events(&self) -> WindowEvent { - self.event_recv.recv().unwrap() + pub fn wait_events(&self) -> Vec { + vec![self.event_recv.recv().unwrap()] } } From 1a3395e0776d7a716dd97c0dd3e91e5e7d6025ac Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 7 Apr 2015 10:47:19 -0700 Subject: [PATCH 28/38] =?UTF-8?q?script:=20Implement=20the=20`width`=20and?= =?UTF-8?q?=20`height`=20attributes=20for=20iframes=20per=20HTML5=20=C2=A7?= =?UTF-8?q?=204.8.6.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improves Amazon and Ars Technica. --- components/layout/construct.rs | 4 +- components/layout/fragment.rs | 24 +- components/script/dom/attr.rs | 6 + components/script/dom/element.rs | 39 ++- components/script/dom/htmliframeelement.rs | 47 +++- .../dom/webidls/HTMLIFrameElement.webidl | 4 +- components/util/str.rs | 2 +- tests/ref/basic.list | 2 + tests/ref/iframe/size_attributes.html | 14 + tests/ref/iframe/size_attributes_ref.html | 18 ++ ...size_attributes_vertical_writing_mode.html | 20 ++ .../wpt/metadata/html/dom/interfaces.html.ini | 6 - .../html/dom/reflection-embedded.html.ini | 258 ------------------ 13 files changed, 154 insertions(+), 290 deletions(-) create mode 100644 tests/ref/iframe/size_attributes.html create mode 100644 tests/ref/iframe/size_attributes_ref.html create mode 100644 tests/ref/iframe/size_attributes_vertical_writing_mode.html diff --git a/components/layout/construct.rs b/components/layout/construct.rs index ba9f077c785..dfce640c19c 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -49,17 +49,17 @@ use script::dom::element::ElementTypeId; use script::dom::htmlelement::HTMLElementTypeId; use script::dom::htmlobjectelement::is_image_data; use script::dom::node::NodeTypeId; -use util::opts; use std::borrow::ToOwned; use std::collections::LinkedList; use std::mem; +use std::sync::Arc; use std::sync::atomic::Ordering; use style::computed_values::content::ContentItem; use style::computed_values::{caption_side, display, empty_cells, float, list_style_position}; use style::computed_values::{position}; use style::properties::{self, ComputedValues}; -use std::sync::Arc; use url::Url; +use util::opts; /// The results of flow construction for a DOM node. #[derive(Clone)] diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index c8d496c04bf..9700459f894 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -566,7 +566,8 @@ impl IframeFragmentInfo { } #[inline] - pub fn calculate_replaced_inline_size(style: &ComputedValues, containing_size: Au) -> Au { + pub fn calculate_replaced_inline_size(&self, style: &ComputedValues, containing_size: Au) + -> Au { // Calculate the replaced inline size (or default) as per CSS 2.1 § 10.3.2 IframeFragmentInfo::calculate_replaced_size(style.content_inline_size(), style.min_inline_size(), @@ -576,7 +577,8 @@ impl IframeFragmentInfo { } #[inline] - pub fn calculate_replaced_block_size(style: &ComputedValues, containing_size: Au) -> Au { + pub fn calculate_replaced_block_size(&self, style: &ComputedValues, containing_size: Au) + -> Au { // Calculate the replaced block size (or default) as per CSS 2.1 § 10.3.2 IframeFragmentInfo::calculate_replaced_size(style.content_block_size(), style.min_block_size(), @@ -589,7 +591,8 @@ impl IframeFragmentInfo { fn calculate_replaced_size(content_size: LengthOrPercentageOrAuto, style_min_size: LengthOrPercentage, style_max_size: LengthOrPercentageOrNone, - containing_size: Au, default_size: Au) -> Au { + containing_size: Au, + default_size: Au) -> Au { let computed_size = match MaybeAuto::from_style(content_size, containing_size) { MaybeAuto::Specified(length) => length, MaybeAuto::Auto => default_size, @@ -1702,9 +1705,10 @@ impl Fragment { fragment_inline_size, fragment_block_size); } - SpecificFragmentInfo::Iframe(_) => { - self.border_box.size.inline = IframeFragmentInfo::calculate_replaced_inline_size( - style, container_inline_size) + + SpecificFragmentInfo::Iframe(ref iframe_fragment_info) => { + self.border_box.size.inline = + iframe_fragment_info.calculate_replaced_inline_size(style, + container_inline_size) + noncontent_inline_size; } _ => panic!("this case should have been handled above"), @@ -1786,10 +1790,10 @@ impl Fragment { self.border_box.size.block = block_flow.base.position.size.block + block_flow.fragment.margin.block_start_end() } - SpecificFragmentInfo::Iframe(_) => { - self.border_box.size.block = IframeFragmentInfo::calculate_replaced_block_size( - style, containing_block_block_size) + - noncontent_block_size; + SpecificFragmentInfo::Iframe(ref info) => { + self.border_box.size.block = + info.calculate_replaced_block_size(style, containing_block_block_size) + + noncontent_block_size; } _ => panic!("should have been handled above"), } diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs index 8995f63ec2d..299d7408eaf 100644 --- a/components/script/dom/attr.rs +++ b/components/script/dom/attr.rs @@ -311,6 +311,7 @@ pub trait AttrHelpersForLayout { unsafe fn value_atom_forever(&self) -> Option; unsafe fn value_tokens_forever(&self) -> Option<&'static [Atom]>; unsafe fn local_name_atom_forever(&self) -> Atom; + unsafe fn value(&self) -> &AttrValue; } #[allow(unsafe_code)] @@ -351,4 +352,9 @@ impl AttrHelpersForLayout for Attr { unsafe fn local_name_atom_forever(&self) -> Atom { self.local_name.clone() } + + #[inline] + unsafe fn value(&self) -> &AttrValue { + self.value.borrow_for_layout() + } } diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index e8ae592e63c..a666a28e627 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -18,7 +18,7 @@ use dom::bindings::codegen::Bindings::NamedNodeMapBinding::NamedNodeMapMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::InheritTypes::{ElementCast, ElementDerived, EventTargetCast}; use dom::bindings::codegen::InheritTypes::{HTMLBodyElementDerived, HTMLFontElementDerived}; -use dom::bindings::codegen::InheritTypes::{HTMLInputElementCast}; +use dom::bindings::codegen::InheritTypes::{HTMLIFrameElementDerived, HTMLInputElementCast}; use dom::bindings::codegen::InheritTypes::{HTMLInputElementDerived, HTMLTableElementCast}; use dom::bindings::codegen::InheritTypes::{HTMLTableElementDerived, HTMLTableCellElementDerived}; use dom::bindings::codegen::InheritTypes::{HTMLTableRowElementDerived, HTMLTextAreaElementDerived}; @@ -47,6 +47,7 @@ use dom::htmlbodyelement::{HTMLBodyElement, HTMLBodyElementHelpers}; use dom::htmlcollection::HTMLCollection; use dom::htmlelement::HTMLElementTypeId; use dom::htmlfontelement::{HTMLFontElement, HTMLFontElementHelpers}; +use dom::htmliframeelement::{HTMLIFrameElement, RawHTMLIFrameElementHelpers}; use dom::htmlinputelement::{HTMLInputElement, RawLayoutHTMLInputElementHelpers, HTMLInputElementHelpers}; use dom::htmltableelement::{HTMLTableElement, HTMLTableElementHelpers}; use dom::htmltablecellelement::{HTMLTableCellElement, HTMLTableCellElementHelpers}; @@ -64,7 +65,7 @@ use style; use style::legacy::{UnsignedIntegerAttribute, from_declaration}; use style::properties::{PropertyDeclarationBlock, PropertyDeclaration, parse_style_attribute}; use style::properties::DeclaredValue::SpecifiedValue; -use style::properties::longhands::{self, border_spacing}; +use style::properties::longhands::{self, border_spacing, height}; use style::values::CSSFloat; use style::values::specified::{self, CSSColor, CSSRGBA}; use util::geometry::Au; @@ -181,7 +182,8 @@ pub trait RawLayoutElementHelpers { #[inline] #[allow(unsafe_code)] -unsafe fn get_attr_for_layout(elem: &Element, namespace: &Namespace, name: &Atom) -> Option> { +pub unsafe fn get_attr_for_layout<'a>(elem: &'a Element, namespace: &Namespace, name: &Atom) + -> Option> { // cast to point to T in RefCell directly let attrs = elem.attrs.borrow_for_layout(); attrs.iter().find(|attr: & &JS| { @@ -331,7 +333,10 @@ impl RawLayoutElementHelpers for Element { } - let width = if self.is_htmltableelement() { + let width = if self.is_htmliframeelement() { + let this: &HTMLIFrameElement = mem::transmute(self); + this.get_width() + } else if self.is_htmltableelement() { let this: &HTMLTableElement = mem::transmute(self); this.get_width() } else if self.is_htmltabledatacellelement() { @@ -349,13 +354,37 @@ impl RawLayoutElementHelpers for Element { PropertyDeclaration::Width(SpecifiedValue(width_value)))); } LengthOrPercentageOrAuto::Length(length) => { - let width_value = specified::LengthOrPercentageOrAuto::Length(specified::Length::Absolute(length)); + let width_value = specified::LengthOrPercentageOrAuto::Length( + specified::Length::Absolute(length)); hints.push(from_declaration( PropertyDeclaration::Width(SpecifiedValue(width_value)))); } } + let height = if self.is_htmliframeelement() { + let this: &HTMLIFrameElement = mem::transmute(self); + this.get_height() + } else { + LengthOrPercentageOrAuto::Auto + }; + + match height { + LengthOrPercentageOrAuto::Auto => {} + LengthOrPercentageOrAuto::Percentage(percentage) => { + let width_value = specified::LengthOrPercentageOrAuto::Percentage(percentage); + hints.push(from_declaration(PropertyDeclaration::Height(SpecifiedValue( + height::SpecifiedValue(width_value))))); + } + LengthOrPercentageOrAuto::Length(length) => { + let width_value = specified::LengthOrPercentageOrAuto::Length( + specified::Length::Absolute(length)); + hints.push(from_declaration(PropertyDeclaration::Height(SpecifiedValue( + height::SpecifiedValue(width_value))))); + } + } + + let cols = if self.is_htmltextareaelement() { let this: &HTMLTextAreaElement = mem::transmute(self); match this.get_cols_for_layout() { diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 685f46db48e..fe09197e06b 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -2,9 +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::attr::Attr; -use dom::attr::AttrValue; -use dom::attr::AttrHelpers; +use dom::attr::{Attr, AttrHelpers, AttrHelpersForLayout, AttrValue}; use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding; use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding::HTMLIFrameElementMethods; use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; @@ -17,8 +15,7 @@ use dom::bindings::global::GlobalRef; use dom::bindings::js::{JSRef, OptionalRootable, Rootable, Temporary}; use dom::customevent::CustomEvent; use dom::document::Document; -use dom::element::Element; -use dom::element::AttributeHandlers; +use dom::element::{self, AttributeHandlers, Element}; use dom::event::{Event, EventHelpers}; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -40,6 +37,7 @@ use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::cell::Cell; use url::{Url, UrlParser}; +use util::str::{self, LengthOrPercentageOrAuto}; enum SandboxAllowance { AllowNothing = 0x00, @@ -76,6 +74,11 @@ pub trait HTMLIFrameElementHelpers { fn update_subpage_id(self, new_subpage_id: SubpageId); } +pub trait RawHTMLIFrameElementHelpers { + fn get_width(&self) -> LengthOrPercentageOrAuto; + fn get_height(&self) -> LengthOrPercentageOrAuto; +} + impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> { fn is_sandboxed(self) -> bool { self.sandbox.get().is_some() @@ -163,6 +166,30 @@ impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> { } } +impl RawHTMLIFrameElementHelpers for HTMLIFrameElement { + #[allow(unsafe_code)] + fn get_width(&self) -> LengthOrPercentageOrAuto { + unsafe { + element::get_attr_for_layout(ElementCast::from_actual(&*self), + &ns!(""), + &atom!("width")).map(|attribute| { + str::parse_length(&**(*attribute.unsafe_get()).value()) + }).unwrap_or(LengthOrPercentageOrAuto::Auto) + } + } + + #[allow(unsafe_code)] + fn get_height(&self) -> LengthOrPercentageOrAuto { + unsafe { + element::get_attr_for_layout(ElementCast::from_actual(&*self), + &ns!(""), + &atom!("height")).map(|attribute| { + str::parse_length(&**(*attribute.unsafe_get()).value()) + }).unwrap_or(LengthOrPercentageOrAuto::Auto) + } + } +} + impl HTMLIFrameElement { fn new_inherited(localName: DOMString, prefix: Option, document: JSRef) -> HTMLIFrameElement { HTMLIFrameElement { @@ -317,6 +344,14 @@ impl<'a> HTMLIFrameElementMethods for JSRef<'a, HTMLIFrameElement> { fn Stop(self) -> Fallible<()> { Err(NotSupported) } + + make_getter!(Width); + + make_setter!(SetWidth, "width"); + + make_getter!(Height); + + make_setter!(SetHeight, "height"); } impl<'a> VirtualMethods for JSRef<'a, HTMLIFrameElement> { @@ -347,7 +382,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLIFrameElement> { } } self.sandbox.set(Some(modes)); - }, + } &atom!("src") => { let node: JSRef = NodeCast::from_ref(*self); if node.is_in_doc() { diff --git a/components/script/dom/webidls/HTMLIFrameElement.webidl b/components/script/dom/webidls/HTMLIFrameElement.webidl index 528ee2aa47b..e230cea4063 100644 --- a/components/script/dom/webidls/HTMLIFrameElement.webidl +++ b/components/script/dom/webidls/HTMLIFrameElement.webidl @@ -12,8 +12,8 @@ interface HTMLIFrameElement : HTMLElement { attribute DOMString sandbox; // attribute boolean seamless; // attribute boolean allowFullscreen; - // attribute DOMString width; - // attribute DOMString height; + attribute DOMString width; + attribute DOMString height; readonly attribute Document? contentDocument; //readonly attribute WindowProxy? contentWindow; readonly attribute Window? contentWindow; diff --git a/components/util/str.rs b/components/util/str.rs index afa4b85c24c..5b996cce6a9 100644 --- a/components/util/str.rs +++ b/components/util/str.rs @@ -127,7 +127,7 @@ pub fn parse_unsigned_integer>(input: T) -> Option { }) } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub enum LengthOrPercentageOrAuto { Auto, Percentage(f32), diff --git a/tests/ref/basic.list b/tests/ref/basic.list index 27d5b8aa0ce..73bc8bbb1b3 100644 --- a/tests/ref/basic.list +++ b/tests/ref/basic.list @@ -125,6 +125,8 @@ flaky_cpu == append_style_a.html append_style_b.html == iframe/simple_inline_width.html iframe/simple_inline_width_ref.html == iframe/simple_inline_width_height.html iframe/simple_inline_width_height_ref.html == iframe/simple_inline_width_percentage.html iframe/simple_inline_width_percentage_ref.html +== iframe/size_attributes.html iframe/size_attributes_ref.html +experimental == iframe/size_attributes_vertical_writing_mode.html iframe/size_attributes_ref.html != image_rendering_auto_a.html image_rendering_pixelated_a.html == image_rendering_pixelated_a.html image_rendering_pixelated_ref.html diff --git a/tests/ref/iframe/size_attributes.html b/tests/ref/iframe/size_attributes.html new file mode 100644 index 00000000000..72e1d1d63d0 --- /dev/null +++ b/tests/ref/iframe/size_attributes.html @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/tests/ref/iframe/size_attributes_ref.html b/tests/ref/iframe/size_attributes_ref.html new file mode 100644 index 00000000000..f1864342ae7 --- /dev/null +++ b/tests/ref/iframe/size_attributes_ref.html @@ -0,0 +1,18 @@ + + + + + + + + + + diff --git a/tests/ref/iframe/size_attributes_vertical_writing_mode.html b/tests/ref/iframe/size_attributes_vertical_writing_mode.html new file mode 100644 index 00000000000..1c35036b6c5 --- /dev/null +++ b/tests/ref/iframe/size_attributes_vertical_writing_mode.html @@ -0,0 +1,20 @@ + + + + + + + + + + diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini index 6dfe517ace6..6b4044775cd 100644 --- a/tests/wpt/metadata/html/dom/interfaces.html.ini +++ b/tests/wpt/metadata/html/dom/interfaces.html.ini @@ -2922,12 +2922,6 @@ [HTMLIFrameElement interface: attribute allowFullscreen] expected: FAIL - [HTMLIFrameElement interface: attribute width] - expected: FAIL - - [HTMLIFrameElement interface: attribute height] - expected: FAIL - [HTMLIFrameElement interface: attribute align] expected: FAIL diff --git a/tests/wpt/metadata/html/dom/reflection-embedded.html.ini b/tests/wpt/metadata/html/dom/reflection-embedded.html.ini index 01a2c1106a7..1b4b1e10f3c 100644 --- a/tests/wpt/metadata/html/dom/reflection-embedded.html.ini +++ b/tests/wpt/metadata/html/dom/reflection-embedded.html.ini @@ -2547,264 +2547,6 @@ [iframe.allowFullscreen: IDL set to object "test-valueOf" followed by IDL get] expected: FAIL - [iframe.width: typeof IDL attribute] - expected: FAIL - - [iframe.width: IDL get with DOM attribute unset] - expected: FAIL - - [iframe.width: setAttribute() to "" followed by IDL get] - expected: FAIL - - [iframe.width: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by IDL get] - expected: FAIL - - [iframe.width: setAttribute() to undefined followed by IDL get] - expected: FAIL - - [iframe.width: setAttribute() to 7 followed by IDL get] - expected: FAIL - - [iframe.width: setAttribute() to 1.5 followed by IDL get] - expected: FAIL - - [iframe.width: setAttribute() to true followed by IDL get] - expected: FAIL - - [iframe.width: setAttribute() to false followed by IDL get] - expected: FAIL - - [iframe.width: setAttribute() to object "[object Object\]" followed by IDL get] - expected: FAIL - - [iframe.width: setAttribute() to NaN followed by IDL get] - expected: FAIL - - [iframe.width: setAttribute() to Infinity followed by IDL get] - expected: FAIL - - [iframe.width: setAttribute() to -Infinity followed by IDL get] - expected: FAIL - - [iframe.width: setAttribute() to "\\0" followed by IDL get] - expected: FAIL - - [iframe.width: setAttribute() to null followed by IDL get] - expected: FAIL - - [iframe.width: setAttribute() to object "test-toString" followed by IDL get] - expected: FAIL - - [iframe.width: setAttribute() to object "test-valueOf" followed by IDL get] - expected: FAIL - - [iframe.width: IDL set to "" followed by getAttribute()] - expected: FAIL - - [iframe.width: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by getAttribute()] - expected: FAIL - - [iframe.width: IDL set to undefined followed by getAttribute()] - expected: FAIL - - [iframe.width: IDL set to undefined followed by IDL get] - expected: FAIL - - [iframe.width: IDL set to 7 followed by getAttribute()] - expected: FAIL - - [iframe.width: IDL set to 7 followed by IDL get] - expected: FAIL - - [iframe.width: IDL set to 1.5 followed by getAttribute()] - expected: FAIL - - [iframe.width: IDL set to 1.5 followed by IDL get] - expected: FAIL - - [iframe.width: IDL set to true followed by getAttribute()] - expected: FAIL - - [iframe.width: IDL set to true followed by IDL get] - expected: FAIL - - [iframe.width: IDL set to false followed by getAttribute()] - expected: FAIL - - [iframe.width: IDL set to false followed by IDL get] - expected: FAIL - - [iframe.width: IDL set to object "[object Object\]" followed by getAttribute()] - expected: FAIL - - [iframe.width: IDL set to object "[object Object\]" followed by IDL get] - expected: FAIL - - [iframe.width: IDL set to NaN followed by getAttribute()] - expected: FAIL - - [iframe.width: IDL set to NaN followed by IDL get] - expected: FAIL - - [iframe.width: IDL set to Infinity followed by getAttribute()] - expected: FAIL - - [iframe.width: IDL set to Infinity followed by IDL get] - expected: FAIL - - [iframe.width: IDL set to -Infinity followed by getAttribute()] - expected: FAIL - - [iframe.width: IDL set to -Infinity followed by IDL get] - expected: FAIL - - [iframe.width: IDL set to "\\0" followed by getAttribute()] - expected: FAIL - - [iframe.width: IDL set to null followed by getAttribute()] - expected: FAIL - - [iframe.width: IDL set to null followed by IDL get] - expected: FAIL - - [iframe.width: IDL set to object "test-toString" followed by getAttribute()] - expected: FAIL - - [iframe.width: IDL set to object "test-toString" followed by IDL get] - expected: FAIL - - [iframe.width: IDL set to object "test-valueOf" followed by IDL get] - expected: FAIL - - [iframe.height: typeof IDL attribute] - expected: FAIL - - [iframe.height: IDL get with DOM attribute unset] - expected: FAIL - - [iframe.height: setAttribute() to "" followed by IDL get] - expected: FAIL - - [iframe.height: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by IDL get] - expected: FAIL - - [iframe.height: setAttribute() to undefined followed by IDL get] - expected: FAIL - - [iframe.height: setAttribute() to 7 followed by IDL get] - expected: FAIL - - [iframe.height: setAttribute() to 1.5 followed by IDL get] - expected: FAIL - - [iframe.height: setAttribute() to true followed by IDL get] - expected: FAIL - - [iframe.height: setAttribute() to false followed by IDL get] - expected: FAIL - - [iframe.height: setAttribute() to object "[object Object\]" followed by IDL get] - expected: FAIL - - [iframe.height: setAttribute() to NaN followed by IDL get] - expected: FAIL - - [iframe.height: setAttribute() to Infinity followed by IDL get] - expected: FAIL - - [iframe.height: setAttribute() to -Infinity followed by IDL get] - expected: FAIL - - [iframe.height: setAttribute() to "\\0" followed by IDL get] - expected: FAIL - - [iframe.height: setAttribute() to null followed by IDL get] - expected: FAIL - - [iframe.height: setAttribute() to object "test-toString" followed by IDL get] - expected: FAIL - - [iframe.height: setAttribute() to object "test-valueOf" followed by IDL get] - expected: FAIL - - [iframe.height: IDL set to "" followed by getAttribute()] - expected: FAIL - - [iframe.height: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by getAttribute()] - expected: FAIL - - [iframe.height: IDL set to undefined followed by getAttribute()] - expected: FAIL - - [iframe.height: IDL set to undefined followed by IDL get] - expected: FAIL - - [iframe.height: IDL set to 7 followed by getAttribute()] - expected: FAIL - - [iframe.height: IDL set to 7 followed by IDL get] - expected: FAIL - - [iframe.height: IDL set to 1.5 followed by getAttribute()] - expected: FAIL - - [iframe.height: IDL set to 1.5 followed by IDL get] - expected: FAIL - - [iframe.height: IDL set to true followed by getAttribute()] - expected: FAIL - - [iframe.height: IDL set to true followed by IDL get] - expected: FAIL - - [iframe.height: IDL set to false followed by getAttribute()] - expected: FAIL - - [iframe.height: IDL set to false followed by IDL get] - expected: FAIL - - [iframe.height: IDL set to object "[object Object\]" followed by getAttribute()] - expected: FAIL - - [iframe.height: IDL set to object "[object Object\]" followed by IDL get] - expected: FAIL - - [iframe.height: IDL set to NaN followed by getAttribute()] - expected: FAIL - - [iframe.height: IDL set to NaN followed by IDL get] - expected: FAIL - - [iframe.height: IDL set to Infinity followed by getAttribute()] - expected: FAIL - - [iframe.height: IDL set to Infinity followed by IDL get] - expected: FAIL - - [iframe.height: IDL set to -Infinity followed by getAttribute()] - expected: FAIL - - [iframe.height: IDL set to -Infinity followed by IDL get] - expected: FAIL - - [iframe.height: IDL set to "\\0" followed by getAttribute()] - expected: FAIL - - [iframe.height: IDL set to null followed by getAttribute()] - expected: FAIL - - [iframe.height: IDL set to null followed by IDL get] - expected: FAIL - - [iframe.height: IDL set to object "test-toString" followed by getAttribute()] - expected: FAIL - - [iframe.height: IDL set to object "test-toString" followed by IDL get] - expected: FAIL - - [iframe.height: IDL set to object "test-valueOf" followed by IDL get] - expected: FAIL - [iframe.align: typeof IDL attribute] expected: FAIL From 8082df7d0da97f1951ae125956b962b92c98e69f Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Wed, 11 Mar 2015 10:44:59 -0400 Subject: [PATCH 29/38] Make external script sources load asynchronously, yet still block further parsing. Hook up document loading to async networking events. --- components/net_traits/lib.rs | 18 +- components/script/document_loader.rs | 13 +- components/script/dom/document.rs | 25 +- components/script/dom/domparser.rs | 4 +- components/script/dom/htmlscriptelement.rs | 101 ++++++-- components/script/dom/servohtmlparser.rs | 237 +++++++++++++++++- components/script/parse/html.rs | 109 ++------ components/script/parse/mod.rs | 4 +- components/script/script_task.rs | 94 ++++--- .../the-script-element/async_006.htm.ini | 5 - .../Opera/script_scheduling/015.html.ini | 5 - .../Opera/script_scheduling/015a.html.ini | 5 - .../Opera/script_scheduling/017.html.ini | 5 - .../Opera/script_scheduling/020.html.ini | 5 - .../Opera/script_scheduling/022.html.ini | 5 - .../Opera/script_scheduling/023.html.ini | 6 - .../Opera/script_scheduling/024.html.ini | 5 - .../Opera/script_scheduling/038.html.ini | 5 - .../Opera/script_scheduling/046.html.ini | 5 - .../Opera/script_scheduling/047.html.ini | 5 - .../Opera/script_scheduling/049.html.ini | 5 - .../Opera/script_scheduling/050.html.ini | 5 - .../Opera/script_scheduling/051.html.ini | 5 - .../Opera/script_scheduling/053.html.ini | 5 - .../Opera/script_scheduling/069.html.ini | 5 - .../Opera/script_scheduling/076.html.ini | 5 - .../Opera/script_scheduling/078.html.ini | 5 - .../Opera/script_scheduling/095.html.ini | 4 + .../Opera/script_scheduling/105.html.ini | 4 + .../Opera/script_scheduling/123.html.ini | 4 + .../Opera/script_scheduling/126.html.ini | 4 + .../Opera/script_scheduling/134.html.ini | 5 - 32 files changed, 441 insertions(+), 276 deletions(-) delete mode 100644 tests/wpt/metadata/html/semantics/scripting-1/the-script-element/async_006.htm.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/015.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/015a.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/017.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/020.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/022.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/023.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/024.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/038.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/046.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/047.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/049.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/050.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/051.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/053.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/069.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/076.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/078.html.ini create mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/095.html.ini create mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/105.html.ini create mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/123.html.ini create mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/126.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/134.html.ini diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs index 46fcc476843..d2ecae532be 100644 --- a/components/net_traits/lib.rs +++ b/components/net_traits/lib.rs @@ -132,8 +132,6 @@ pub struct PendingAsyncLoad { resource_task: ResourceTask, url: Url, pipeline: Option, - input_sender: Sender, - input_receiver: Receiver, guard: PendingLoadGuard, } @@ -156,13 +154,10 @@ impl Drop for PendingLoadGuard { impl PendingAsyncLoad { pub fn new(resource_task: ResourceTask, url: Url, pipeline: Option) -> PendingAsyncLoad { - let (sender, receiver) = channel(); PendingAsyncLoad { resource_task: resource_task, url: url, pipeline: pipeline, - input_sender: sender, - input_receiver: receiver, guard: PendingLoadGuard { loaded: false, }, } } @@ -171,9 +166,18 @@ impl PendingAsyncLoad { pub fn load(mut self) -> Receiver { self.guard.neuter(); let load_data = LoadData::new(self.url, self.pipeline); - let consumer = LoadConsumer::Channel(self.input_sender); + let (sender, receiver) = channel(); + let consumer = LoadConsumer::Channel(sender); + self.resource_task.send(ControlMsg::Load(load_data, consumer)).unwrap(); + receiver + } + + /// Initiate the network request associated with this pending load, using the provided target. + pub fn load_async(mut self, listener: Box) { + self.guard.neuter(); + let load_data = LoadData::new(self.url, self.pipeline); + let consumer = LoadConsumer::Listener(listener); self.resource_task.send(ControlMsg::Load(load_data, consumer)).unwrap(); - self.input_receiver } } diff --git a/components/script/document_loader.rs b/components/script/document_loader.rs index 6b8dfcea801..14e107e9d02 100644 --- a/components/script/document_loader.rs +++ b/components/script/document_loader.rs @@ -7,13 +7,12 @@ use script_task::{ScriptMsg, ScriptChan}; use msg::constellation_msg::{PipelineId}; -use net_traits::{LoadResponse, Metadata, load_whole_resource, ResourceTask, PendingAsyncLoad}; +use net_traits::{Metadata, load_whole_resource, ResourceTask, PendingAsyncLoad}; +use net_traits::AsyncResponseTarget; use url::Url; -use std::sync::mpsc::Receiver; - #[jstraceable] -#[derive(PartialEq, Clone)] +#[derive(PartialEq, Clone, Debug)] pub enum LoadType { Image(Url), Script(Url), @@ -75,9 +74,9 @@ impl DocumentLoader { } /// Create and initiate a new network request. - pub fn load_async(&mut self, load: LoadType) -> Receiver { + pub fn load_async(&mut self, load: LoadType, listener: Box) { let pending = self.prepare_async_load(load); - pending.load() + pending.load_async(listener) } /// Create, initiate, and await the response for a new network request. @@ -91,7 +90,7 @@ impl DocumentLoader { /// Mark an in-progress network request complete. pub fn finish_load(&mut self, load: LoadType) { let idx = self.blocking_loads.iter().position(|unfinished| *unfinished == load); - self.blocking_loads.remove(idx.expect("unknown completed load")); + self.blocking_loads.remove(idx.expect(&format!("unknown completed load {:?}", load))); if let Some(NotifierData { ref script_chan, pipeline }) = self.notifier_data { if !self.is_blocked() { diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 19901c43796..7c7347772ba 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -61,6 +61,7 @@ use dom::nodelist::NodeList; use dom::text::Text; use dom::processinginstruction::ProcessingInstruction; use dom::range::Range; +use dom::servohtmlparser::ServoHTMLParser; use dom::treewalker::TreeWalker; use dom::uievent::UIEvent; use dom::window::{Window, WindowHelpers, ReflowReason}; @@ -73,7 +74,7 @@ use msg::constellation_msg::{ConstellationChan, FocusType, Key, KeyState, KeyMod use msg::constellation_msg::{SUPER, ALT, SHIFT, CONTROL}; use net_traits::CookieSource::NonHTTP; use net_traits::ControlMsg::{SetCookiesForUrl, GetCookiesForUrl}; -use net_traits::{Metadata, LoadResponse, PendingAsyncLoad}; +use net_traits::{Metadata, PendingAsyncLoad, AsyncResponseTarget}; use script_task::Runnable; use script_traits::{MouseButton, UntrustedNodeAddress}; use util::opts; @@ -96,7 +97,7 @@ use std::ascii::AsciiExt; use std::cell::{Cell, Ref, RefMut, RefCell}; use std::default::Default; use std::ptr; -use std::sync::mpsc::{Receiver, channel}; +use std::sync::mpsc::channel; use time; #[derive(PartialEq)] @@ -145,6 +146,8 @@ pub struct Document { animation_frame_list: RefCell>>, /// Tracks all outstanding loads related to this document. loader: DOMRefCell, + /// The current active HTML parser, to allow resuming after interruptions. + current_parser: MutNullableHeap>, } impl DocumentDerived for EventTarget { @@ -263,9 +266,11 @@ pub trait DocumentHelpers<'a> { /// http://w3c.github.io/animation-timing/#dfn-invoke-callbacks-algorithm fn invoke_animation_callbacks(self); fn prepare_async_load(self, load: LoadType) -> PendingAsyncLoad; - fn load_async(self, load: LoadType) -> Receiver; + fn load_async(self, load: LoadType, listener: Box); fn load_sync(self, load: LoadType) -> Result<(Metadata, Vec), String>; fn finish_load(self, load: LoadType); + fn set_current_parser(self, script: Option>); + fn get_current_parser(self) -> Option>; } impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { @@ -892,9 +897,9 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { loader.prepare_async_load(load) } - fn load_async(self, load: LoadType) -> Receiver { + fn load_async(self, load: LoadType, listener: Box) { let mut loader = self.loader.borrow_mut(); - loader.load_async(load) + loader.load_async(load, listener) } fn load_sync(self, load: LoadType) -> Result<(Metadata, Vec), String> { @@ -906,6 +911,14 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { let mut loader = self.loader.borrow_mut(); loader.finish_load(load); } + + fn set_current_parser(self, script: Option>) { + self.current_parser.set(script.map(JS::from_rooted)); + } + + fn get_current_parser(self) -> Option> { + self.current_parser.get().map(Temporary::from_rooted) + } } pub enum MouseEventType { @@ -914,6 +927,7 @@ pub enum MouseEventType { MouseUp, } + #[derive(PartialEq)] pub enum DocumentSource { FromParser, @@ -987,6 +1001,7 @@ impl Document { animation_frame_ident: Cell::new(0), animation_frame_list: RefCell::new(HashMap::new()), loader: DOMRefCell::new(doc_loader), + current_parser: Default::default(), } } diff --git a/components/script/dom/domparser.rs b/components/script/dom/domparser.rs index 5685c3f324f..40c9d8f436c 100644 --- a/components/script/dom/domparser.rs +++ b/components/script/dom/domparser.rs @@ -15,7 +15,7 @@ use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::document::{Document, DocumentHelpers, IsHTMLDocument}; use dom::document::DocumentSource; use dom::window::{Window, WindowHelpers}; -use parse::html::{HTMLInput, parse_html}; +use parse::html::{ParseContext, parse_html}; use util::str::DOMString; use std::borrow::ToOwned; @@ -64,7 +64,7 @@ impl<'a> DOMParserMethods for JSRef<'a, DOMParser> { None, DocumentSource::FromParser, loader).root(); - parse_html(document.r(), HTMLInput::InputString(s), &url, None); + parse_html(document.r(), s, &url, ParseContext::Owner(None)); document.r().set_ready_state(DocumentReadyState::Complete); Ok(Temporary::from_rooted(document.r())) } diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 2f7a52ec272..365d1a75e85 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -28,17 +28,21 @@ use dom::event::{Event, EventBubbles, EventCancelable, EventHelpers}; use dom::element::ElementTypeId; use dom::htmlelement::{HTMLElement, HTMLElementTypeId}; use dom::node::{Node, NodeHelpers, NodeTypeId, document_from_node, window_from_node, CloneChildrenFlag}; +use dom::servohtmlparser::ServoHTMLParserHelpers; use dom::virtualmethods::VirtualMethods; use dom::window::{WindowHelpers, ScriptHelpers}; -use script_task::{ScriptMsg, Runnable}; +use network_listener::{NetworkListener, PreInvoke}; +use script_task::{ScriptChan, ScriptMsg, Runnable}; use encoding::all::UTF_8; use encoding::label::encoding_from_whatwg_label; use encoding::types::{Encoding, EncodingRef, DecoderTrap}; -use net_traits::Metadata; +use net_traits::{Metadata, AsyncResponseListener}; use util::str::{DOMString, HTML_SPACE_CHARACTERS, StaticStringVec}; -use std::borrow::ToOwned; -use std::cell::Cell; +use html5ever::tree_builder::NextParserState; +use std::cell::{RefCell, Cell}; +use std::mem; +use std::sync::{Arc, Mutex}; use string_cache::Atom; use url::{Url, UrlParser}; @@ -99,7 +103,7 @@ impl HTMLScriptElement { pub trait HTMLScriptElementHelpers { /// Prepare a script () - fn prepare(self); + fn prepare(self) -> NextParserState; /// [Execute a script block] /// (https://html.spec.whatwg.org/multipage/#execute-the-script-block) @@ -153,12 +157,52 @@ pub enum ScriptOrigin { External(Result<(Metadata, Vec), String>), } +/// The context required for asynchronously loading an external script source. +struct ScriptContext { + /// The element that initiated the request. + elem: Trusted, + /// The response body received to date. + data: RefCell>, + /// The response metadata received to date. + metadata: RefCell>, + /// Whether the owning document's parser should resume once the response completes. + resume_on_completion: bool, +} + +impl AsyncResponseListener for ScriptContext { + fn headers_available(&self, metadata: Metadata) { + *self.metadata.borrow_mut() = Some(metadata); + } + + fn data_available(&self, payload: Vec) { + self.data.borrow_mut().extend(payload.into_iter()); + } + + fn response_complete(&self, status: Result<(), String>) { + let load = status.map(|_| { + let data = mem::replace(&mut *self.data.borrow_mut(), vec!()); + let metadata = self.metadata.borrow_mut().take().unwrap(); + (metadata, data) + }); + let elem = self.elem.to_temporary().root(); + + elem.r().execute(ScriptOrigin::External(load)); + + if self.resume_on_completion { + let document = document_from_node(elem.r()).root(); + document.r().get_current_parser().unwrap().root().r().resume(); + } + } +} + +impl PreInvoke for ScriptContext {} + impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { - fn prepare(self) { + fn prepare(self) -> NextParserState { // https://html.spec.whatwg.org/multipage/#prepare-a-script // Step 1. if self.already_started.get() { - return; + return NextParserState::Continue; } // Step 2. let was_parser_inserted = self.parser_inserted.get(); @@ -172,16 +216,16 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { // Step 4. let text = self.Text(); if text.len() == 0 && !element.has_attribute(&atom!("src")) { - return; + return NextParserState::Continue; } // Step 5. let node: JSRef = NodeCast::from_ref(self); if !node.is_in_doc() { - return; + return NextParserState::Continue; } // Step 6, 7. if !self.is_javascript() { - return; + return NextParserState::Continue; } // Step 8. if was_parser_inserted { @@ -195,12 +239,12 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { let document_from_node_ref = document_from_node(self).root(); let document_from_node_ref = document_from_node_ref.r(); if self.parser_inserted.get() && self.parser_document.root().r() != document_from_node_ref { - return; + return NextParserState::Continue; } // Step 11. if !document_from_node_ref.is_scripting_enabled() { - return; + return NextParserState::Continue; } // Step 12. @@ -212,13 +256,13 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { .to_ascii_lowercase(); let for_value = for_value.trim_matches(HTML_SPACE_CHARACTERS); if for_value != "window" { - return; + return NextParserState::Continue; } let event_value = event_attribute.Value().to_ascii_lowercase(); let event_value = event_value.trim_matches(HTML_SPACE_CHARACTERS); if event_value != "onload" && event_value != "onload()" { - return; + return NextParserState::Continue; } }, (_, _) => (), @@ -245,7 +289,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { // Step 14.2 if src.is_empty() { self.queue_error_event(); - return; + return NextParserState::Continue; } // Step 14.3 @@ -254,7 +298,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { // Step 14.4 error!("error parsing URL for script {}", src); self.queue_error_event(); - return; + return NextParserState::Continue; } Ok(url) => { // Step 14.5 @@ -263,8 +307,28 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { // the origin of the script element's node document, and the default origin // behaviour set to taint. let doc = document_from_node(self).root(); - let contents = doc.r().load_sync(LoadType::Script(url)); - ScriptOrigin::External(contents) + + let script_chan = window.script_chan(); + let elem = Trusted::new(window.get_cx(), self, script_chan.clone()); + + let context = Arc::new(Mutex::new(ScriptContext { + elem: elem, + data: RefCell::new(vec!()), + metadata: RefCell::new(None), + resume_on_completion: self.parser_inserted.get(), + })); + + let listener = box NetworkListener { + context: context, + script_chan: script_chan, + }; + + doc.r().load_async(LoadType::Script(url), listener); + + if self.parser_inserted.get() { + doc.r().get_current_parser().unwrap().root().r().suspend(); + } + return NextParserState::Suspend; } } }, @@ -275,6 +339,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { // TODO: Add support for the `defer` and `async` attributes. (For now, we fetch all // scripts synchronously and execute them immediately.) self.execute(load); + NextParserState::Continue } fn execute(self, load: ScriptOrigin) { diff --git a/components/script/dom/servohtmlparser.rs b/components/script/dom/servohtmlparser.rs index 199c06dca35..c4779a5666d 100644 --- a/components/script/dom/servohtmlparser.rs +++ b/components/script/dom/servohtmlparser.rs @@ -5,24 +5,35 @@ //! The bulk of the HTML parser integration is in `script::parse::html`. //! This module is mostly about its interaction with DOM memory management. +use document_loader::LoadType; use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::ServoHTMLParserBinding; use dom::bindings::global::GlobalRef; use dom::bindings::trace::JSTraceable; use dom::bindings::js::{JS, JSRef, Rootable, Temporary}; +use dom::bindings::refcounted::Trusted; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::document::{Document, DocumentHelpers}; -use dom::node::Node; +use dom::node::{window_from_node, Node}; +use dom::window::Window; +use network_listener::PreInvoke; use parse::Parser; +use script_task::{ScriptTask, ScriptChan}; -use util::task_state; +use msg::constellation_msg::{PipelineId, SubpageId}; +use net_traits::{Metadata, AsyncResponseListener}; +use encoding::all::UTF_8; +use encoding::types::{Encoding, DecoderTrap}; +use std::cell::{Cell, RefCell}; use std::default::Default; use url::Url; use js::jsapi::JSTracer; use html5ever::tokenizer; use html5ever::tree_builder; use html5ever::tree_builder::{TreeBuilder, TreeBuilderOpts}; +use hyper::header::ContentType; +use hyper::mime::{Mime, TopLevel, SubLevel}; #[must_root] #[jstraceable] @@ -41,6 +52,110 @@ pub struct FragmentContext<'a> { pub type Tokenizer = tokenizer::Tokenizer, Sink>>; +/// The context required for asynchronously fetching a document and parsing it progressively. +pub struct ParserContext { + /// The parser that initiated the request. + parser: RefCell>>, + /// Is this document a synthesized document for a single image? + is_image_document: Cell, + /// The pipeline associated with this document. + id: PipelineId, + /// The subpage associated with this document. + subpage: Option, + /// The target event loop for the response notifications. + script_chan: Box, + /// The URL for this document. + url: Url, +} + +impl ParserContext { + pub fn new(id: PipelineId, subpage: Option, script_chan: Box, + url: Url) -> ParserContext { + ParserContext { + parser: RefCell::new(None), + is_image_document: Cell::new(false), + id: id, + subpage: subpage, + script_chan: script_chan, + url: url, + } + } +} + +impl AsyncResponseListener for ParserContext { + fn headers_available(&self, metadata: Metadata) { + let content_type = metadata.content_type.clone(); + + let parser = ScriptTask::page_fetch_complete(self.id.clone(), self.subpage.clone(), + metadata); + let parser = match parser { + Some(parser) => parser, + None => return, + }.root(); + + let parser = parser.r(); + let win = parser.window().root(); + *self.parser.borrow_mut() = Some(Trusted::new(win.r().get_cx(), parser, + self.script_chan.clone())); + + match content_type { + Some(ContentType(Mime(TopLevel::Image, _, _))) => { + self.is_image_document.set(true); + let page = format!("", + self.url.serialize()); + parser.pending_input.borrow_mut().push(page); + parser.parse_sync(); + } + Some(ContentType(Mime(TopLevel::Text, SubLevel::Plain, _))) => { + // FIXME: When servo/html5ever#109 is fixed remove usage and + // replace with fix from that issue. + + // text/plain documents require setting the tokenizer into PLAINTEXT mode. + // This is done by using a <plaintext> element as the html5ever tokenizer + // provides no other way to change to that state. + // Spec for text/plain handling is: + // https://html.spec.whatwg.org/multipage/#read-text + let page = format!("<pre>\u{000A}<plaintext>"); + parser.pending_input.borrow_mut().push(page); + parser.parse_sync(); + }, + _ => {} + } + } + + fn data_available(&self, payload: Vec<u8>) { + if !self.is_image_document.get() { + // FIXME: use Vec<u8> (html5ever #34) + let data = UTF_8.decode(&payload, DecoderTrap::Replace).unwrap(); + let parser = match self.parser.borrow().as_ref() { + Some(parser) => parser.to_temporary(), + None => return, + }.root(); + parser.r().parse_chunk(data); + } + } + + fn response_complete(&self, status: Result<(), String>) { + let parser = match self.parser.borrow().as_ref() { + Some(parser) => parser.to_temporary(), + None => return, + }.root(); + let doc = parser.r().document.root(); + doc.r().finish_load(LoadType::PageSource(self.url.clone())); + + if let Err(err) = status { + debug!("Failed to load page URL {}, error: {}", self.url.serialize(), err); + // TODO(Savago): we should send a notification to callers #5463. + } + + parser.r().last_chunk_received.set(true); + parser.r().parse_sync(); + } +} + +impl PreInvoke for ParserContext { +} + // NB: JSTraceable is *not* auto-derived. // You must edit the impl below if you add fields! #[must_root] @@ -48,20 +163,46 @@ pub type Tokenizer = tokenizer::Tokenizer<TreeBuilder<JS<Node>, Sink>>; pub struct ServoHTMLParser { reflector_: Reflector, tokenizer: DOMRefCell<Tokenizer>, + /// Input chunks received but not yet passed to the parser. + pending_input: DOMRefCell<Vec<String>>, + /// The document associated with this parser. + document: JS<Document>, + /// True if this parser should avoid passing any further data to the tokenizer. + suspended: Cell<bool>, + /// Whether to expect any further input from the associated network request. + last_chunk_received: Cell<bool>, + /// The pipeline associated with this parse, unavailable if this parse does not + /// correspond to a page load. + pipeline: Option<PipelineId>, } -impl Parser for ServoHTMLParser{ - fn parse_chunk(&self, input: String) { - self.tokenizer().borrow_mut().feed(input); +impl<'a> Parser for JSRef<'a, ServoHTMLParser> { + fn parse_chunk(self, input: String) { + self.document.root().r().set_current_parser(Some(self)); + self.pending_input.borrow_mut().push(input); + self.parse_sync(); } - fn finish(&self){ + + fn finish(self) { + assert!(!self.suspended.get()); + assert!(self.pending_input.borrow().is_empty()); + self.tokenizer().borrow_mut().end(); + debug!("finished parsing"); + + let document = self.document.root(); + document.r().set_current_parser(None); + + if let Some(pipeline) = self.pipeline { + ScriptTask::parsing_complete(pipeline); + } } } impl ServoHTMLParser { #[allow(unrooted_must_root)] - pub fn new(base_url: Option<Url>, document: JSRef<Document>) -> Temporary<ServoHTMLParser> { + pub fn new(base_url: Option<Url>, document: JSRef<Document>, pipeline: Option<PipelineId>) + -> Temporary<ServoHTMLParser> { let window = document.window().root(); let sink = Sink { base_url: base_url, @@ -78,6 +219,11 @@ impl ServoHTMLParser { let parser = ServoHTMLParser { reflector_: Reflector::new(), tokenizer: DOMRefCell::new(tok), + pending_input: DOMRefCell::new(vec!()), + document: JS::from_rooted(document), + suspended: Cell::new(false), + last_chunk_received: Cell::new(false), + pipeline: pipeline, }; reflect_dom_object(box parser, GlobalRef::Window(window.r()), @@ -111,6 +257,11 @@ impl ServoHTMLParser { let parser = ServoHTMLParser { reflector_: Reflector::new(), tokenizer: DOMRefCell::new(tok), + pending_input: DOMRefCell::new(vec!()), + document: JS::from_rooted(document), + suspended: Cell::new(false), + last_chunk_received: Cell::new(true), + pipeline: None, }; reflect_dom_object(box parser, GlobalRef::Window(window.r()), @@ -129,6 +280,73 @@ impl Reflectable for ServoHTMLParser { } } +trait PrivateServoHTMLParserHelpers { + /// Synchronously run the tokenizer parse loop until explicitly suspended or + /// the tokenizer runs out of input. + fn parse_sync(self); + /// Retrieve the window object associated with this parser. + fn window(self) -> Temporary<Window>; +} + +impl<'a> PrivateServoHTMLParserHelpers for JSRef<'a, ServoHTMLParser> { + fn parse_sync(self) { + let mut first = true; + + // This parser will continue to parse while there is either pending input or + // the parser remains unsuspended. + loop { + if self.suspended.get() { + return; + } + + if self.pending_input.borrow().is_empty() && !first { + break; + } + + let mut pending_input = self.pending_input.borrow_mut(); + if !pending_input.is_empty() { + let chunk = pending_input.remove(0); + self.tokenizer.borrow_mut().feed(chunk); + } else { + self.tokenizer.borrow_mut().run(); + } + + first = false; + } + + if self.last_chunk_received.get() { + self.finish(); + } + } + + fn window(self) -> Temporary<Window> { + let doc = self.document.root(); + window_from_node(doc.r()) + } +} + +pub trait ServoHTMLParserHelpers { + /// Cause the parser to interrupt next time the tokenizer reaches a quiescent state. + /// No further parsing will occur after that point until the `resume` method is called. + /// Panics if the parser is already suspended. + fn suspend(self); + /// Immediately resume a suspended parser. Panics if the parser is not suspended. + fn resume(self); +} + +impl<'a> ServoHTMLParserHelpers for JSRef<'a, ServoHTMLParser> { + fn suspend(self) { + assert!(!self.suspended.get()); + self.suspended.set(true); + } + + fn resume(self) { + assert!(self.suspended.get()); + self.suspended.set(false); + self.parse_sync(); + } +} + struct Tracer { trc: *mut JSTracer, } @@ -152,11 +370,6 @@ impl JSTraceable for ServoHTMLParser { let tracer = &tracer as &tree_builder::Tracer<Handle=JS<Node>>; unsafe { - // Assertion: If the parser is mutably borrowed, we're in the - // parsing code paths. - debug_assert!(task_state::get().contains(task_state::IN_HTML_PARSER) - || !self.tokenizer.is_mutably_borrowed()); - let tokenizer = self.tokenizer.borrow_for_gc_trace(); let tree_builder = tokenizer.sink(); tree_builder.trace_handles(tracer); diff --git a/components/script/parse/html.rs b/components/script/parse/html.rs index 80885acf300..a9e125f7da9 100644 --- a/components/script/parse/html.rs +++ b/components/script/parse/html.rs @@ -4,7 +4,7 @@ #![allow(unsafe_code, unrooted_must_root)] -use document_loader::{DocumentLoader, LoadType}; +use document_loader::DocumentLoader; use dom::attr::AttrHelpers; use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; @@ -32,13 +32,10 @@ use dom::servohtmlparser::{ServoHTMLParser, FragmentContext}; use dom::text::Text; use parse::Parser; -use encoding::all::UTF_8; -use encoding::types::{Encoding, DecoderTrap}; +use encoding::types::Encoding; -use net_traits::{ProgressMsg, LoadResponse}; +use msg::constellation_msg::PipelineId; use util::str::DOMString; -use util::task_state; -use util::task_state::IN_HTML_PARSER; use std::borrow::Cow; use std::io::{self, Write}; use url::Url; @@ -49,14 +46,6 @@ use html5ever::serialize::TraversalScope::{IncludeNode, ChildrenOnly}; use html5ever::tree_builder::{TreeSink, QuirksMode, NodeOrText, AppendNode, AppendText, NextParserState}; use string_cache::QualName; -use hyper::header::ContentType; -use hyper::mime::{Mime, TopLevel, SubLevel}; - -pub enum HTMLInput { - InputString(String), - InputUrl(LoadResponse), -} - trait SinkHelpers { fn get_or_create(&self, child: NodeOrText<JS<Node>>) -> Temporary<Node>; } @@ -183,7 +172,9 @@ impl<'a> TreeSink for servohtmlparser::Sink { fn complete_script(&mut self, node: JS<Node>) -> NextParserState { let node: Root<Node> = node.root(); let script: Option<JSRef<HTMLScriptElement>> = HTMLScriptElementCast::to_ref(node.r()); - script.map(|script| script.prepare()); + if let Some(script) = script { + return script.prepare(); + } NextParserState::Continue } @@ -272,80 +263,22 @@ impl<'a> Serializable for JSRef<'a, Node> { } } +pub enum ParseContext<'a> { + Fragment(FragmentContext<'a>), + Owner(Option<PipelineId>), +} + pub fn parse_html(document: JSRef<Document>, - input: HTMLInput, + input: String, url: &Url, - fragment_context: Option<FragmentContext>) { - let parser = match fragment_context { - None => ServoHTMLParser::new(Some(url.clone()), document).root(), - Some(fc) => ServoHTMLParser::new_for_fragment(Some(url.clone()), document, fc).root(), - }; - let parser: JSRef<ServoHTMLParser> = parser.r(); - - let nested_parse = task_state::get().contains(task_state::IN_HTML_PARSER); - if !nested_parse { - task_state::enter(IN_HTML_PARSER); - } - - fn parse_progress(document: JSRef<Document>, parser: JSRef<ServoHTMLParser>, url: &Url, load_response: &LoadResponse) { - for msg in load_response.progress_port.iter() { - match msg { - ProgressMsg::Payload(data) => { - // FIXME: use Vec<u8> (html5ever #34) - let data = UTF_8.decode(&data, DecoderTrap::Replace).unwrap(); - parser.parse_chunk(data); - } - ProgressMsg::Done(Err(err)) => { - debug!("Failed to load page URL {}, error: {}", url.serialize(), err); - // TODO(Savago): we should send a notification to callers #5463. - break; - } - ProgressMsg::Done(Ok(())) => { - document.finish_load(LoadType::PageSource(url.clone())); - break; - } - } - } - }; - - match input { - HTMLInput::InputString(s) => { - parser.parse_chunk(s); - } - HTMLInput::InputUrl(load_response) => { - match load_response.metadata.content_type { - Some(ContentType(Mime(TopLevel::Image, _, _))) => { - let page = format!("<html><body><img src='{}' /></body></html>", url.serialize()); - parser.parse_chunk(page); - document.finish_load(LoadType::PageSource(url.clone())); - }, - Some(ContentType(Mime(TopLevel::Text, SubLevel::Plain, _))) => { - // FIXME: When servo/html5ever#109 is fixed remove <plaintext> usage and - // replace with fix from that issue. - - // text/plain documents require setting the tokenizer into PLAINTEXT mode. - // This is done by using a <plaintext> element as the html5ever tokenizer - // provides no other way to change to that state. - // Spec for text/plain handling is: - // https://html.spec.whatwg.org/multipage/#read-text - let page = format!("<pre>\u{000A}<plaintext>"); - parser.parse_chunk(page); - parse_progress(document, parser, url, &load_response); - }, - _ => { - parse_progress(document, parser, url, &load_response); - } - } - } - } - - parser.finish(); - - if !nested_parse { - task_state::exit(IN_HTML_PARSER); - } - - debug!("finished parsing"); + context: ParseContext) { + let parser = match context { + ParseContext::Owner(owner) => + ServoHTMLParser::new(Some(url.clone()), document, owner), + ParseContext::Fragment(fc) => + ServoHTMLParser::new_for_fragment(Some(url.clone()), document, fc), + }.root(); + parser.r().parse_chunk(input); } // https://html.spec.whatwg.org/multipage/#parsing-html-fragments @@ -376,7 +309,7 @@ pub fn parse_html_fragment(context_node: JSRef<Node>, context_elem: context_node, form_elem: form.r(), }; - parse_html(document.r(), HTMLInput::InputString(input), &url, Some(fragment_context)); + parse_html(document.r(), input, &url, ParseContext::Fragment(fragment_context)); // Step 14. let root_element = document.r().GetDocumentElement().expect("no document element").root(); diff --git a/components/script/parse/mod.rs b/components/script/parse/mod.rs index 6111f196053..fa93dbc157f 100644 --- a/components/script/parse/mod.rs +++ b/components/script/parse/mod.rs @@ -5,6 +5,6 @@ pub mod html; pub trait Parser { - fn parse_chunk(&self,input: String); - fn finish(&self); + fn parse_chunk(self, input: String); + fn finish(self); } diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 014e32f2f97..d7b785403cd 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -39,11 +39,13 @@ use dom::htmliframeelement::{HTMLIFrameElement, HTMLIFrameElementHelpers}; use dom::uievent::UIEvent; use dom::eventtarget::EventTarget; use dom::node::{Node, NodeHelpers, NodeDamage, window_from_node}; +use dom::servohtmlparser::{ServoHTMLParser, ParserContext}; use dom::window::{Window, WindowHelpers, ScriptHelpers, ReflowReason}; use dom::worker::TrustedWorkerAddress; -use parse::html::{HTMLInput, parse_html}; +use parse::html::{ParseContext, parse_html}; use layout_interface::{ScriptLayoutChan, LayoutChan, ReflowGoal, ReflowQueryType}; use layout_interface; +use network_listener::NetworkListener; use page::{Page, IterablePage, Frame}; use timers::TimerId; use devtools; @@ -65,13 +67,13 @@ use msg::constellation_msg::{ConstellationChan, FocusType}; use msg::constellation_msg::{LoadData, PipelineId, SubpageId, MozBrowserEvent, WorkerId}; use msg::constellation_msg::{Failure, WindowSizeData, PipelineExitType}; use msg::constellation_msg::Msg as ConstellationMsg; -use net_traits::{ResourceTask, LoadResponse, LoadConsumer, ControlMsg}; +use net_traits::{ResourceTask, LoadConsumer, ControlMsg, Metadata}; use net_traits::LoadData as NetLoadData; use net_traits::image_cache_task::{ImageCacheChan, ImageCacheTask, ImageCacheResult}; use net_traits::storage_task::StorageTask; use string_cache::Atom; use util::str::DOMString; -use util::task::{spawn_named, spawn_named_with_send_on_failure}; +use util::task::spawn_named_with_send_on_failure; use util::task_state; use geom::Rect; @@ -92,6 +94,7 @@ use std::option::Option; use std::ptr; use std::rc::Rc; use std::result::Result; +use std::sync::{Arc, Mutex}; use std::sync::mpsc::{channel, Sender, Receiver, Select}; use time::Tm; @@ -188,8 +191,6 @@ pub enum ScriptMsg { MainThreadRunnableMsg(Box<MainThreadRunnable+Send>), /// A DOM object's last pinned reference was removed (dispatched to all tasks). RefcountCleanup(TrustedReference), - /// The final network response for a page has arrived. - PageFetchComplete(PipelineId, Option<SubpageId>, LoadResponse), /// Notify a document that all pending loads are complete. DocumentLoadsComplete(PipelineId), } @@ -427,6 +428,21 @@ unsafe extern "C" fn debug_gc_callback(_rt: *mut JSRuntime, status: JSGCStatus) } impl ScriptTask { + pub fn page_fetch_complete(id: PipelineId, subpage: Option<SubpageId>, metadata: Metadata) + -> Option<Temporary<ServoHTMLParser>> { + SCRIPT_TASK_ROOT.with(|root| { + let script_task = unsafe { &*root.borrow().unwrap() }; + script_task.handle_page_fetch_complete(id, subpage, metadata) + }) + } + + pub fn parsing_complete(id: PipelineId) { + SCRIPT_TASK_ROOT.with(|root| { + let script_task = unsafe { &*root.borrow().unwrap() }; + script_task.handle_parsing_complete(id); + }); + } + pub fn process_event(msg: ScriptMsg) { SCRIPT_TASK_ROOT.with(|root| { if let Some(script_task) = *root.borrow() { @@ -765,8 +781,6 @@ impl ScriptTask { runnable.handler(self), ScriptMsg::RefcountCleanup(addr) => LiveDOMReferences::cleanup(self.get_cx(), addr), - ScriptMsg::PageFetchComplete(id, subpage, response) => - self.handle_page_fetch_complete(id, subpage, response), ScriptMsg::DocumentLoadsComplete(id) => self.handle_loads_complete(id), } @@ -1069,7 +1083,7 @@ impl ScriptTask { /// We have received notification that the response associated with a load has completed. /// Kick off the document and frame tree creation process using the result. fn handle_page_fetch_complete(&self, id: PipelineId, subpage: Option<SubpageId>, - response: LoadResponse) { + metadata: Metadata) -> Option<Temporary<ServoHTMLParser>> { let idx = self.incomplete_loads.borrow().iter().position(|load| { load.pipeline_id == id && load.parent_info.map(|info| info.1) == subpage }); @@ -1078,10 +1092,11 @@ impl ScriptTask { match idx { Some(idx) => { let load = self.incomplete_loads.borrow_mut().remove(idx); - self.load(response, load); + Some(self.load(metadata, load)) } None => { assert!(self.closed_pipelines.borrow().contains(&id)); + None } } } @@ -1148,8 +1163,8 @@ impl ScriptTask { /// The entry point to document loading. Defines bindings, sets up the window and document /// objects, parses HTML and CSS, and kicks off initial layout. - fn load(&self, response: LoadResponse, incomplete: InProgressLoad) { - let final_url = response.metadata.final_url.clone(); + fn load(&self, metadata: Metadata, incomplete: InProgressLoad) -> Temporary<ServoHTMLParser> { + let final_url = metadata.final_url.clone(); debug!("ScriptTask: loading {} on page {:?}", incomplete.url.serialize(), incomplete.pipeline_id); // We should either be initializing a root page or loading a child page of an @@ -1249,11 +1264,11 @@ impl ScriptTask { incomplete.parent_info, incomplete.window_size).root(); - let last_modified: Option<DOMString> = response.metadata.headers.as_ref().and_then(|headers| { + let last_modified: Option<DOMString> = metadata.headers.as_ref().and_then(|headers| { headers.get().map(|&LastModified(HttpDate(ref tm))| dom_last_modified(tm)) }); - let content_type = match response.metadata.content_type { + let content_type = match metadata.content_type { Some(ContentType(Mime(TopLevel::Text, SubLevel::Plain, _))) => Some("text/plain".to_owned()), _ => None }; @@ -1264,7 +1279,7 @@ impl ScriptTask { }; let loader = DocumentLoader::new_with_task(self.resource_task.clone(), Some(notifier_data), - Some(final_url.clone())); + Some(incomplete.url.clone())); let document = Document::new(window.r(), Some(final_url.clone()), IsHTMLDocument::HTMLDocument, @@ -1288,14 +1303,17 @@ 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("".to_owned())) + strval.unwrap_or("".to_owned()) } else { - HTMLInput::InputUrl(response) + "".to_owned() }; - parse_html(document.r(), parse_input, &final_url, None); - self.handle_parsing_complete(incomplete.pipeline_id); + parse_html(document.r(), parse_input, &final_url, + ParseContext::Owner(Some(incomplete.pipeline_id))); + page_remover.neuter(); + + document.r().get_current_parser().unwrap() } fn notify_devtools(&self, title: DOMString, url: Url, ids: (PipelineId, Option<WorkerId>)) { @@ -1480,29 +1498,26 @@ impl ScriptTask { let script_chan = self.chan.clone(); let resource_task = self.resource_task.clone(); - spawn_named(format!("fetch for {:?}", load_data.url.serialize()), move || { - if load_data.url.scheme == "javascript" { - load_data.url = Url::parse("about:blank").unwrap(); - } + let context = Arc::new(Mutex::new(ParserContext::new(id, subpage, script_chan.clone(), + load_data.url.clone()))); + let listener = box NetworkListener { + context: context, + script_chan: script_chan.clone(), + }; - let (input_chan, input_port) = channel(); - resource_task.send(ControlMsg::Load(NetLoadData { - url: load_data.url, - method: load_data.method, - headers: Headers::new(), - preserved_headers: load_data.headers, - data: load_data.data, - cors: None, - pipeline_id: Some(id), - }, LoadConsumer::Channel(input_chan))).unwrap(); + if load_data.url.scheme == "javascript" { + load_data.url = Url::parse("about:blank").unwrap(); + } - let load_response = input_port.recv().unwrap(); - if script_chan.send(ScriptMsg::PageFetchComplete(id, subpage, load_response)).is_err() { - // TODO(gw): This should be handled by aborting - // the load before the script task exits. - debug!("PageFetchComplete: script channel has exited"); - } - }); + resource_task.send(ControlMsg::Load(NetLoadData { + url: load_data.url, + method: load_data.method, + headers: Headers::new(), + preserved_headers: load_data.headers, + data: load_data.data, + cors: None, + pipeline_id: Some(id), + }, LoadConsumer::Listener(listener))).unwrap(); self.incomplete_loads.borrow_mut().push(incomplete); } @@ -1541,6 +1556,7 @@ impl ScriptTask { // Kick off the initial reflow of the page. debug!("kicking off initial reflow of {:?}", final_url); + document.r().content_changed(NodeCast::from_ref(document.r()), NodeDamage::OtherNodeDamage); let window = window_from_node(document.r()).root(); diff --git a/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/async_006.htm.ini b/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/async_006.htm.ini deleted file mode 100644 index 37604f00b8e..00000000000 --- a/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/async_006.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[async_006.htm] - type: testharness - [dynamically created external script executes asynchronously] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/015.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/015.html.ini deleted file mode 100644 index 0eb052e7dda..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/015.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[015.html] - type: testharness - [ scheduler: DOM added inline+external+inline script earlier in document] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/015a.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/015a.html.ini deleted file mode 100644 index f13a4ad5783..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/015a.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[015a.html] - type: testharness - [ scheduler: DOM added inline+external+inline script earlier in document] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/017.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/017.html.ini deleted file mode 100644 index c53367410e5..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/017.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[017.html] - type: testharness - [ scheduler: multiple DOM added scripts later in document] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/020.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/020.html.ini deleted file mode 100644 index 5fe0007df72..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/020.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[020.html] - type: testharness - [ scheduler: DOM added script with data: URL ] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/022.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/022.html.ini deleted file mode 100644 index 86432e7f001..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/022.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[022.html] - type: testharness - [ scheduler: DOM added script, late .src ] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/023.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/023.html.ini deleted file mode 100644 index f0fbd642ec7..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/023.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[023.html] - type: testharness - expected: TIMEOUT - [ scheduler: DOM added script, even later .src ] - expected: TIMEOUT - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/024.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/024.html.ini deleted file mode 100644 index 34063b39d78..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/024.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[024.html] - type: testharness - [ scheduler: DOM added script, .src set twice] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/038.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/038.html.ini deleted file mode 100644 index 174d761ea84..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/038.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[038.html] - type: testharness - [ scheduler: DOM movement with appendChild, external] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/046.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/046.html.ini deleted file mode 100644 index 75d42b69a57..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/046.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[046.html] - type: testharness - [ scheduler: no readystatechange events when adding external scripts ] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/047.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/047.html.ini deleted file mode 100644 index 9c1ceeaa4d9..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/047.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[047.html] - type: testharness - [ scheduler: adding and removing external script ] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/049.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/049.html.ini deleted file mode 100644 index fcc9435392a..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/049.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[049.html] - type: testharness - [ scheduler: adding external script but removeAttribute( src ) before it runs] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/050.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/050.html.ini deleted file mode 100644 index 2bfc46d9285..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/050.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[050.html] - type: testharness - [ scheduler: adding external script that removes all scripts from document] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/051.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/051.html.ini deleted file mode 100644 index c524ee1bc17..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/051.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[051.html] - type: testharness - [ scheduler: interaction of parsing and script execution - script added through DOM] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/053.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/053.html.ini deleted file mode 100644 index 552647fe0a4..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/053.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[053.html] - type: testharness - [ scheduler: adding external script that removes itself from document when loading] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/069.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/069.html.ini deleted file mode 100644 index 602df71772f..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/069.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[069.html] - type: testharness - [scheduler: external files added through DOM should not block further parsing while loading] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/076.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/076.html.ini deleted file mode 100644 index 6da81e6bb68..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/076.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[076.html] - type: testharness - [ scheduler: adding and removing external and inline scripts ] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/078.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/078.html.ini deleted file mode 100644 index 6ce0192273a..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/078.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[078.html] - type: testharness - [ adding several types of scripts through the DOM and removing some of them confuses scheduler (slow-loading scripts) ] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/095.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/095.html.ini new file mode 100644 index 00000000000..ceab463aa64 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/095.html.ini @@ -0,0 +1,4 @@ +[095.html] + type: testharness + [ scheduler: slow-loading script added from defer blocking load event] + expected: FAIL diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/105.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/105.html.ini new file mode 100644 index 00000000000..19b0eb955c4 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/105.html.ini @@ -0,0 +1,4 @@ +[105.html] + type: testharness + [ scheduler: adding async attribute at runtime] + expected: FAIL diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/123.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/123.html.ini new file mode 100644 index 00000000000..1d440d08c75 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/123.html.ini @@ -0,0 +1,4 @@ +[123.html] + type: testharness + [scheduler: altering the type attribute and adding/removing external script with async=false ] + expected: FAIL diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/126.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/126.html.ini new file mode 100644 index 00000000000..12530634ca8 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/126.html.ini @@ -0,0 +1,4 @@ +[126.html] + type: testharness + [scheduler: altering the type attribute and changing script data external script async=false ] + expected: FAIL diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/134.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/134.html.ini deleted file mode 100644 index a01a182559d..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/134.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[134.html] - type: testharness - [scheduler: external HTML script added by SVG script ] - expected: FAIL - From 7e7675c1dcbd8148527d018b56883c6d83886fec Mon Sep 17 00:00:00 2001 From: Patrick Walton <pcwalton@mimiga.net> Date: Fri, 3 Apr 2015 14:24:22 -0700 Subject: [PATCH 30/38] net: Don't load the placeholder image for background images, only for image fragments. This also changes the way the placeholder is handled in the image cache task to decode it up front instead of each time an image fails to load, both because it was more convenient to implement that way and because it saves CPU cycles to do so. This matches the behavior of Gecko and WebKit. It improves the look of our cached copy of Wikipedia. --- components/layout/context.rs | 15 ++++-- components/layout/display_list_builder.rs | 3 +- components/layout/fragment.rs | 5 +- components/net/image_cache_task.rs | 54 +++++++++++++------ components/net_traits/image_cache_task.rs | 29 ++++++++-- .../script/dom/canvasrenderingcontext2d.rs | 12 ++--- components/script/dom/htmlimageelement.rs | 11 ++-- components/script/script_task.rs | 2 +- tests/ref/basic.list | 1 + tests/ref/no_image_background_a.html | 21 ++++++++ tests/ref/no_image_background_ref.html | 20 +++++++ 11 files changed, 135 insertions(+), 38 deletions(-) create mode 100644 tests/ref/no_image_background_a.html create mode 100644 tests/ref/no_image_background_ref.html diff --git a/components/layout/context.rs b/components/layout/context.rs index e83f4453b04..08114bec3e8 100644 --- a/components/layout/context.rs +++ b/components/layout/context.rs @@ -15,7 +15,8 @@ use gfx::font_context::FontContext; use msg::compositor_msg::LayerId; use msg::constellation_msg::ConstellationChan; use net_traits::image::base::Image; -use net_traits::image_cache_task::{ImageCacheChan, ImageCacheTask, ImageState}; +use net_traits::image_cache_task::{ImageCacheChan, ImageCacheTask, ImageResponse, ImageState}; +use net_traits::image_cache_task::{UsePlaceholder}; use script::layout_interface::{Animation, LayoutChan, ReflowGoal}; use std::boxed; use std::cell::Cell; @@ -154,9 +155,11 @@ impl<'a> LayoutContext<'a> { } } - pub fn get_or_request_image(&self, url: Url) -> Option<Arc<Image>> { + pub fn get_or_request_image(&self, url: Url, use_placeholder: UsePlaceholder) + -> Option<Arc<Image>> { // See if the image is already available - let result = self.shared.image_cache_task.get_image_if_available(url.clone()); + let result = self.shared.image_cache_task.get_image_if_available(url.clone(), + use_placeholder); match result { Ok(image) => Some(image), @@ -174,7 +177,11 @@ impl<'a> LayoutContext<'a> { self.shared.image_cache_task.request_image(url, ImageCacheChan(sync_tx), None); - sync_rx.recv().unwrap().image + match sync_rx.recv().unwrap().image_response { + ImageResponse::Loaded(image) | + ImageResponse::PlaceholderLoaded(image) => Some(image), + ImageResponse::None => None, + } } // Not yet requested, async mode - request image from the cache (ImageState::NotRequested, false) => { diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index aac8a7c2317..dc1ba50699c 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -35,6 +35,7 @@ use gfx::paint_task::{PaintLayer, THREAD_TINT_COLORS}; use msg::compositor_msg::ScrollPolicy; use msg::constellation_msg::ConstellationChan; use msg::constellation_msg::Msg as ConstellationMsg; +use net_traits::image_cache_task::UsePlaceholder; use png::{self, PixelsByColorType}; use std::cmp; use std::default::Default; @@ -432,7 +433,7 @@ impl FragmentDisplayListBuilding for Fragment { clip: &ClippingRegion, image_url: &Url) { let background = style.get_background(); - let image = layout_context.get_or_request_image(image_url.clone()); + let image = layout_context.get_or_request_image(image_url.clone(), UsePlaceholder::No); if let Some(image) = image { debug!("(building display list) building background image"); diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index c8d496c04bf..b7b80c2da53 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -27,6 +27,7 @@ use gfx::text::glyph::CharIndex; use gfx::text::text_run::{TextRun, TextRunSlice}; use msg::constellation_msg::{ConstellationChan, Msg, PipelineId, SubpageId}; use net_traits::image::base::Image; +use net_traits::image_cache_task::UsePlaceholder; use rustc_serialize::{Encodable, Encoder}; use script_traits::UntrustedNodeAddress; use std::borrow::ToOwned; @@ -337,7 +338,9 @@ impl ImageFragmentInfo { .map(Au::from_px) } - let image = url.and_then(|url| layout_context.get_or_request_image(url)); + let image = url.and_then(|url| { + layout_context.get_or_request_image(url, UsePlaceholder::Yes) + }); ImageFragmentInfo { replaced_image_fragment_info: ReplacedImageFragmentInfo::new(node, diff --git a/components/net/image_cache_task.rs b/components/net/image_cache_task.rs index 66636487542..7b322f85b40 100644 --- a/components/net/image_cache_task.rs +++ b/components/net/image_cache_task.rs @@ -4,7 +4,8 @@ use collections::borrow::ToOwned; use net_traits::image::base::{Image, load_from_memory}; -use net_traits::image_cache_task::{ImageState, ImageCacheTask, ImageCacheChan, ImageCacheCommand, ImageCacheResult}; +use net_traits::image_cache_task::{ImageState, ImageCacheTask, ImageCacheChan, ImageCacheCommand}; +use net_traits::image_cache_task::{ImageCacheResult, ImageResponse, UsePlaceholder}; use net_traits::load_whole_resource; use std::collections::HashMap; use std::collections::hash_map::Entry::{Occupied, Vacant}; @@ -53,13 +54,13 @@ impl PendingLoad { /// failure) are still stored here, so that they aren't /// fetched again. struct CompletedLoad { - image: Option<Arc<Image>>, + image_response: ImageResponse, } impl CompletedLoad { - fn new(image: Option<Arc<Image>>) -> CompletedLoad { + fn new(image_response: ImageResponse) -> CompletedLoad { CompletedLoad { - image: image, + image_response: image_response, } } } @@ -79,11 +80,11 @@ impl ImageListener { } } - fn notify(self, image: Option<Arc<Image>>) { + fn notify(self, image_response: ImageResponse) { let ImageCacheChan(ref sender) = self.sender; let msg = ImageCacheResult { responder: self.responder, - image: image, + image_response: image_response, }; sender.send(msg).ok(); } @@ -210,10 +211,19 @@ impl ImageCache { ImageCacheCommand::RequestImage(url, result_chan, responder) => { self.request_image(url, result_chan, responder); } - ImageCacheCommand::GetImageIfAvailable(url, consumer) => { + ImageCacheCommand::GetImageIfAvailable(url, use_placeholder, consumer) => { let result = match self.completed_loads.get(&url) { Some(completed_load) => { - completed_load.image.clone().ok_or(ImageState::LoadError) + match (completed_load.image_response.clone(), use_placeholder) { + (ImageResponse::Loaded(image), _) | + (ImageResponse::PlaceholderLoaded(image), UsePlaceholder::Yes) => { + Ok(image) + } + (ImageResponse::PlaceholderLoaded(_), UsePlaceholder::No) | + (ImageResponse::None, _) => { + Err(ImageState::LoadError) + } + } } None => { let pending_load = self.pending_loads.get(&url); @@ -255,8 +265,13 @@ impl ImageCache { }); } Err(_) => { - let placeholder_image = self.placeholder_image.clone(); - self.complete_load(msg.url, placeholder_image); + match self.placeholder_image.clone() { + Some(placeholder_image) => { + self.complete_load(msg.url, ImageResponse::PlaceholderLoaded( + placeholder_image)) + } + None => self.complete_load(msg.url, ImageResponse::None), + } } } } @@ -265,31 +280,37 @@ impl ImageCache { // Handle a message from one of the decoder worker threads fn handle_decoder(&mut self, msg: DecoderMsg) { - let image = msg.image.map(Arc::new); + let image = match msg.image { + None => ImageResponse::None, + Some(image) => ImageResponse::Loaded(Arc::new(image)), + }; self.complete_load(msg.url, image); } // Change state of a url from pending -> loaded. - fn complete_load(&mut self, url: Url, image: Option<Arc<Image>>) { + fn complete_load(&mut self, url: Url, image_response: ImageResponse) { let pending_load = self.pending_loads.remove(&url).unwrap(); - let completed_load = CompletedLoad::new(image.clone()); + let completed_load = CompletedLoad::new(image_response.clone()); self.completed_loads.insert(url, completed_load); for listener in pending_load.listeners.into_iter() { - listener.notify(image.clone()); + listener.notify(image_response.clone()); } } // Request an image from the cache - fn request_image(&mut self, url: Url, result_chan: ImageCacheChan, responder: Option<Box<ImageResponder>>) { + fn request_image(&mut self, + url: Url, + result_chan: ImageCacheChan, + responder: Option<Box<ImageResponder>>) { let image_listener = ImageListener::new(result_chan, responder); // Check if already completed match self.completed_loads.get(&url) { Some(completed_load) => { // It's already completed, return a notify straight away - image_listener.notify(completed_load.image.clone()); + image_listener.notify(completed_load.image_response.clone()); } None => { // Check if the load is already pending @@ -366,3 +387,4 @@ pub fn new_image_cache_task(resource_task: ResourceTask) -> ImageCacheTask { ImageCacheTask::new(cmd_sender) } + diff --git a/components/net_traits/image_cache_task.rs b/components/net_traits/image_cache_task.rs index dd6bb3c98ff..3614cf4d58a 100644 --- a/components/net_traits/image_cache_task.rs +++ b/components/net_traits/image_cache_task.rs @@ -12,7 +12,7 @@ use std::sync::mpsc::{channel, Sender}; /// image load completes. It is typically used to trigger a reflow /// and/or repaint. pub trait ImageResponder : Send { - fn respond(&self, Option<Arc<Image>>); + fn respond(&self, ImageResponse); } /// The current state of an image in the cache. @@ -23,6 +23,17 @@ pub enum ImageState { NotRequested, } +/// The returned image. +#[derive(Clone)] +pub enum ImageResponse { + /// The requested image was loaded. + Loaded(Arc<Image>), + /// The requested image failed to load, so a placeholder was loaded instead. + PlaceholderLoaded(Arc<Image>), + /// Neither the requested image nor the placeholder could be loaded. + None +} + /// Channel for sending commands to the image cache. #[derive(Clone)] pub struct ImageCacheChan(pub Sender<ImageCacheResult>); @@ -31,7 +42,7 @@ pub struct ImageCacheChan(pub Sender<ImageCacheResult>); /// caller. pub struct ImageCacheResult { pub responder: Option<Box<ImageResponder>>, - pub image: Option<Arc<Image>>, + pub image_response: ImageResponse, } /// Commands that the image cache understands. @@ -45,12 +56,18 @@ pub enum ImageCacheCommand { /// TODO(gw): Profile this on some real world sites and see /// if it's worth caching the results of this locally in each /// layout / paint task. - GetImageIfAvailable(Url, Sender<Result<Arc<Image>, ImageState>>), + GetImageIfAvailable(Url, UsePlaceholder, Sender<Result<Arc<Image>, ImageState>>), /// Clients must wait for a response before shutting down the ResourceTask Exit(Sender<()>), } +#[derive(Copy, Clone, PartialEq)] +pub enum UsePlaceholder { + No, + Yes, +} + /// The client side of the image cache task. This can be safely cloned /// and passed to different tasks. #[derive(Clone)] @@ -78,9 +95,10 @@ impl ImageCacheTask { } /// Get the current state of an image. See ImageCacheCommand::GetImageIfAvailable. - pub fn get_image_if_available(&self, url: Url) -> Result<Arc<Image>, ImageState> { + pub fn get_image_if_available(&self, url: Url, use_placeholder: UsePlaceholder) + -> Result<Arc<Image>, ImageState> { let (sender, receiver) = channel(); - let msg = ImageCacheCommand::GetImageIfAvailable(url, sender); + let msg = ImageCacheCommand::GetImageIfAvailable(url, use_placeholder, sender); self.chan.send(msg).unwrap(); receiver.recv().unwrap() } @@ -92,3 +110,4 @@ impl ImageCacheTask { response_port.recv().unwrap(); } } + diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index 6353479b116..ad49955c64f 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -33,14 +33,12 @@ use canvas::canvas_paint_task::{CanvasPaintTask, FillOrStrokeStyle}; use canvas::canvas_paint_task::{LinearGradientStyle, RadialGradientStyle}; use canvas::canvas_paint_task::{LineCapStyle, LineJoinStyle, CompositionOrBlending}; -use net_traits::image::base::Image; -use net_traits::image_cache_task::ImageCacheChan; +use net_traits::image_cache_task::{ImageCacheChan, ImageResponse}; use png::PixelsByColorType; use num::{Float, ToPrimitive}; use std::borrow::ToOwned; use std::cell::RefCell; -use std::sync::{Arc}; use std::sync::mpsc::{channel, Sender}; use util::str::DOMString; @@ -260,8 +258,8 @@ impl CanvasRenderingContext2D { }; let img = match self.request_image_from_cache(url) { - Some(img) => img, - None => return None, + ImageResponse::Loaded(img) => img, + ImageResponse::PlaceholderLoaded(_) | ImageResponse::None => return None, }; let image_size = Size2D(img.width as f64, img.height as f64); @@ -277,7 +275,7 @@ impl CanvasRenderingContext2D { return Some((image_data, image_size)); } - fn request_image_from_cache(&self, url: Url) -> Option<Arc<Image>> { + fn request_image_from_cache(&self, url: Url) -> ImageResponse { let canvas = self.canvas.root(); let window = window_from_node(canvas.r()).root(); let window = window.r(); @@ -285,7 +283,7 @@ impl CanvasRenderingContext2D { let (response_chan, response_port) = channel(); image_cache.request_image(url, ImageCacheChan(response_chan), None); let result = response_port.recv().unwrap(); - result.image + result.image_response } fn create_drawable_rect(&self, x: f64, y: f64, w: f64, h: f64) -> Option<Rect<f32>> { diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index a88f4b5ea7b..09b6c950da4 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -25,7 +25,7 @@ use util::str::DOMString; use string_cache::Atom; use net_traits::image::base::Image; -use net_traits::image_cache_task::ImageResponder; +use net_traits::image_cache_task::{ImageResponder, ImageResponse}; use url::{Url, UrlParser}; use std::borrow::ToOwned; @@ -74,11 +74,16 @@ impl Responder { } impl ImageResponder for Responder { - fn respond(&self, image: Option<Arc<Image>>) { + fn respond(&self, image: ImageResponse) { // Update the image field let element = self.element.to_temporary().root(); let element_ref = element.r(); - *element_ref.image.borrow_mut() = image; + *element_ref.image.borrow_mut() = match image { + ImageResponse::Loaded(image) | ImageResponse::PlaceholderLoaded(image) => { + Some(image) + } + ImageResponse::None => None, + }; // Mark the node dirty let node = NodeCast::from_ref(element.r()); diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 014e32f2f97..df049115e20 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -799,7 +799,7 @@ impl ScriptTask { } fn handle_msg_from_image_cache(&self, msg: ImageCacheResult) { - msg.responder.unwrap().respond(msg.image); + msg.responder.unwrap().respond(msg.image_response); } fn handle_webdriver_msg(&self, pipeline_id: PipelineId, msg: WebDriverScriptCommand) { diff --git a/tests/ref/basic.list b/tests/ref/basic.list index 27d5b8aa0ce..139d3adedc1 100644 --- a/tests/ref/basic.list +++ b/tests/ref/basic.list @@ -205,6 +205,7 @@ flaky_cpu == linebreak_simple_a.html linebreak_simple_b.html == negative_margin_uncle_a.html negative_margin_uncle_b.html == negative_margins_a.html negative_margins_b.html == no-image.html no-image-ref.html +== no_image_background_a.html no_image_background_ref.html == noscript.html noscript_ref.html != noteq_attr_exists_selector.html attr_exists_selector_ref.html == nth_child_pseudo_a.html nth_child_pseudo_b.html diff --git a/tests/ref/no_image_background_a.html b/tests/ref/no_image_background_a.html new file mode 100644 index 00000000000..188112e3dc1 --- /dev/null +++ b/tests/ref/no_image_background_a.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> +<head> +<style> +body { + background: peachpuff; +} +section { + display: block; + width: 256px; + height: 256px; + border: solid black 1px; + background: url(bogusybogusbogus.jpg); +} +</style> +</head> +<body> +<section></section> +</body> +</html> + diff --git a/tests/ref/no_image_background_ref.html b/tests/ref/no_image_background_ref.html new file mode 100644 index 00000000000..d1793b43b86 --- /dev/null +++ b/tests/ref/no_image_background_ref.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> +<head> +<style> +body { + background: peachpuff; +} +section { + display: block; + width: 256px; + height: 256px; + border: solid black 1px; +} +</style> +</head> +<body> +<section></section> +</body> +</html> + From 4bc9445b9ef4304fffc48276f958a4f922048bdb Mon Sep 17 00:00:00 2001 From: Manish Goregaokar <manishsmail@gmail.com> Date: Wed, 6 May 2015 12:21:46 +0530 Subject: [PATCH 31/38] Upgrade rust to 716f920b7e234b450f272346fea961832505c06e (Tue May 19 05:39:29 2015 +0000) --- components/plugins/jstraceable.rs | 6 +- components/plugins/lib.rs | 4 +- components/servo/Cargo.lock | 226 +++++++++++++---------------- ports/cef/Cargo.lock | 230 ++++++++++++++---------------- ports/gonk/Cargo.lock | 171 ++++++++++------------ rust-snapshot-hash | 2 +- tests/reftest.rs | 2 +- 7 files changed, 289 insertions(+), 352 deletions(-) diff --git a/components/plugins/jstraceable.rs b/components/plugins/jstraceable.rs index 0ef1cecea3d..7f4757816e0 100644 --- a/components/plugins/jstraceable.rs +++ b/components/plugins/jstraceable.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 syntax::ext::base::ExtCtxt; +use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::codemap::Span; use syntax::ptr::P; use syntax::ast::{Item, MetaItem, Expr}; @@ -27,7 +27,7 @@ pub fn expand_dom_struct(cx: &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: &mut FnMut(P<Item>)) { +pub fn expand_jstraceable(cx: &mut ExtCtxt, span: Span, mitem: &MetaItem, item: Annotatable, push: &mut FnMut(Annotatable)) { let trait_def = TraitDef { span: span, attributes: Vec::new(), @@ -47,7 +47,7 @@ pub fn expand_jstraceable(cx: &mut ExtCtxt, span: Span, mitem: &MetaItem, item: ], associated_types: vec![], }; - trait_def.expand(cx, mitem, item, push) + trait_def.expand(cx, mitem, &item, push) } // Mostly copied from syntax::ext::deriving::hash diff --git a/components/plugins/lib.rs b/components/plugins/lib.rs index a8bf2ad8b20..887e78689a9 100644 --- a/components/plugins/lib.rs +++ b/components/plugins/lib.rs @@ -23,7 +23,7 @@ extern crate tenacious; use rustc::lint::LintPassObject; use rustc::plugin::Registry; -use syntax::ext::base::{Decorator, Modifier}; +use syntax::ext::base::*; use syntax::parse::token::intern; @@ -40,7 +40,7 @@ pub mod casing; #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { reg.register_syntax_extension(intern("dom_struct"), Modifier(box jstraceable::expand_dom_struct)); - reg.register_syntax_extension(intern("jstraceable"), Decorator(box jstraceable::expand_jstraceable)); + reg.register_syntax_extension(intern("jstraceable"), MultiDecorator(box jstraceable::expand_jstraceable)); reg.register_syntax_extension(intern("_generate_reflector"), Decorator(box reflector::expand_reflector)); reg.register_macro("to_lower", casing::expand_lower); reg.register_macro("to_upper", casing::expand_upper); diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 0b52ce6a521..bbf2a3e0739 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -23,7 +23,7 @@ dependencies = [ "script_tests 0.0.1", "style_tests 0.0.1", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "util_tests 0.0.1", "webdriver_server 0.0.1", @@ -142,20 +142,20 @@ dependencies = [ "script_traits 0.0.1", "style 0.0.1", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "webdriver_traits 0.0.1", ] [[package]] name = "cookie" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "openssl 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -169,7 +169,7 @@ dependencies = [ [[package]] name = "core_graphics" version = "0.1.0" -source = "git+https://github.com/servo/rust-core-graphics#da0d2fe947412afea55b438454194b2183c21594" +source = "git+https://github.com/servo/rust-core-graphics#2d8d665c5bdd116b4a1addbe5c415735fb78e1a9" dependencies = [ "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -178,7 +178,7 @@ dependencies = [ [[package]] name = "core_text" version = "0.1.0" -source = "git+https://github.com/servo/rust-core-text#bc6994c3765f0660e9c04f5488ba194a9354e8fb" +source = "git+https://github.com/servo/rust-core-text#2b4b546718310a9d3fe4273a1df092c79d9fb2c2" 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)", @@ -206,9 +206,9 @@ dependencies = [ "devtools_traits 0.0.1", "hyper 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -218,9 +218,9 @@ version = "0.0.1" dependencies = [ "hyper 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -292,7 +292,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "expat-sys" version = "2.1.0" -source = "git+https://github.com/servo/libexpat#5f798cfbb74650a5e1d95e4c03a9e41e55e28625" +source = "git+https://github.com/servo/libexpat#91775ceb69adaea0ce903271b185079a2c484f57" [[package]] name = "flate2" @@ -341,7 +341,7 @@ source = "git+https://github.com/servo/libfreetype2#50c1cf412d87f20ccbb940e39a14 [[package]] name = "gcc" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -360,7 +360,7 @@ dependencies = [ "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -386,14 +386,14 @@ dependencies = [ "png 0.1.0 (git+https://github.com/servo/rust-png)", "profile_traits 0.0.1", "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "script_traits 0.0.1", "skia 0.0.20130412 (git+https://github.com/servo/skia)", "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)", "string_cache 0.1.0 (git+https://github.com/servo/string-cache)", "style 0.0.1", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -411,17 +411,6 @@ dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", ] -[[package]] -name = "gl" -version = "0.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "gl_common 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "gl_generator 0.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "khronos_api 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "gl_common" version = "0.0.4" @@ -432,7 +421,7 @@ dependencies = [ [[package]] name = "gl_generator" -version = "0.0.24" +version = "0.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "khronos_api 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -446,7 +435,7 @@ version = "0.0.1" source = "git+https://github.com/servo/gleam#f2edabf2ef0474bb270b107e5e68c2727c4a422d" dependencies = [ "gl_common 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "gl_generator 0.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "gl_generator 0.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "khronos_api 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -454,24 +443,24 @@ dependencies = [ [[package]] name = "glutin" version = "0.0.26" -source = "git+https://github.com/servo/glutin?branch=servo#33f26a11d73cb4a3969059c57471f9f7b151dc1d" +source = "git+https://github.com/servo/glutin?branch=servo#ec7a5e40c1cc7b8176eb1e1f7bf70c8a19559400" dependencies = [ "android_glue 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "gdi32-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "gl_common 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "gl_generator 0.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "glutin_cocoa 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "gl_generator 0.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "glutin_cocoa 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "glutin_core_foundation 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "glutin_core_graphics 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "glutin_core_graphics 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "khronos_api 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "objc 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "osmesa-sys 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "objc 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "osmesa-sys 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "user32-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "x11 0.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "x11 0.0.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -490,18 +479,18 @@ dependencies = [ "msg 0.0.1", "script_traits 0.0.1", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "glutin_cocoa" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "objc 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "objc 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -514,7 +503,7 @@ dependencies = [ [[package]] name = "glutin_core_graphics" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "glutin_core_foundation 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -527,7 +516,7 @@ version = "0.0.1" source = "git+https://github.com/servo/rust-glx#60ac0aee2438eadb4b51ddc8eac6fc4b5ca8e447" dependencies = [ "gl_common 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "gl_generator 0.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "gl_generator 0.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "khronos_api 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -543,7 +532,7 @@ dependencies = [ [[package]] name = "html5ever" version = "0.0.0" -source = "git+https://github.com/servo/html5ever#74dc5f5a36451cfbe789488b20d51bef97c63898" +source = "git+https://github.com/servo/html5ever#7ddaa598b84e5e7fb9bf5313c02c1aaca970cb4b" dependencies = [ "html5ever_macros 0.0.0 (git+https://github.com/servo/html5ever)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -558,10 +547,10 @@ dependencies = [ [[package]] name = "html5ever_macros" version = "0.0.0" -source = "git+https://github.com/servo/html5ever#74dc5f5a36451cfbe789488b20d51bef97c63898" +source = "git+https://github.com/servo/html5ever#7ddaa598b84e5e7fb9bf5313c02c1aaca970cb4b" dependencies = [ "mac 0.0.2 (git+https://github.com/reem/rust-mac)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -569,42 +558,23 @@ name = "httparse" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "hyper" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cookie 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "typeable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "hyper" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cookie 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", + "cookie 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "typeable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -627,7 +597,7 @@ dependencies = [ "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "mozjs_sys 0.0.0 (git+https://github.com/servo/mozjs)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -658,7 +628,7 @@ dependencies = [ "io_surface 0.1.0 (git+https://github.com/servo/rust-io-surface)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "skia 0.0.20130412 (git+https://github.com/servo/skia)", "xlib 0.1.0 (git+https://github.com/servo/rust-xlib)", ] @@ -684,14 +654,14 @@ dependencies = [ "plugins 0.0.1", "png 0.1.0 (git+https://github.com/servo/rust-png)", "profile_traits 0.0.1", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "script 0.0.1", "script_traits 0.0.1", "selectors 0.1.0 (git+https://github.com/servo/rust-selectors)", "string_cache 0.1.0 (git+https://github.com/servo/string-cache)", "string_cache_plugin 0.1.1 (git+https://github.com/servo/string-cache)", "style 0.0.1", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -705,7 +675,7 @@ dependencies = [ "net_traits 0.0.1", "profile_traits 0.0.1", "script_traits 0.0.1", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -760,7 +730,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "mime" -version = "0.0.10" +version = "0.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -771,7 +741,7 @@ name = "miniz-sys" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -798,7 +768,7 @@ dependencies = [ "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "png 0.1.0 (git+https://github.com/servo/rust-png)", "style 0.0.1", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "webdriver_traits 0.0.1", ] @@ -807,19 +777,19 @@ dependencies = [ name = "net" version = "0.0.1" dependencies = [ - "cookie 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", + "cookie 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "devtools_traits 0.0.1", "flate2 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "hyper 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "net_traits 0.0.1", - "openssl 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "png 0.1.0 (git+https://github.com/servo/rust-png)", "regex 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", "regex_macros 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "uuid 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -828,11 +798,11 @@ dependencies = [ name = "net_tests" version = "0.0.1" dependencies = [ - "cookie 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", + "cookie 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "net 0.0.1", "net_traits 0.0.1", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -845,7 +815,7 @@ dependencies = [ "msg 0.0.1", "png 0.1.0 (git+https://github.com/servo/rust-png)", "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -855,7 +825,7 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -868,7 +838,7 @@ dependencies = [ [[package]] name = "objc" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -893,34 +863,33 @@ dependencies = [ [[package]] name = "openssl" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl-sys" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "libressl-pnacl-sys 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "osmesa-sys" -version = "0.0.3" +version = "0.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gl 0.0.12 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "shared_library 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -957,7 +926,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "pkg-config" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -980,7 +949,7 @@ name = "png" version = "0.1.0" source = "git+https://github.com/servo/rust-png#34fca101357da41b2b8c95f3efe6cb88a2b36bca" dependencies = [ - "gcc 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "png-sys 1.6.16 (git+https://github.com/servo/rust-png)", ] @@ -1007,7 +976,7 @@ name = "profile_traits" version = "0.0.1" dependencies = [ "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1038,7 +1007,7 @@ dependencies = [ [[package]] name = "rustc-serialize" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1063,7 +1032,7 @@ dependencies = [ "plugins 0.0.1", "png 0.1.0 (git+https://github.com/servo/rust-png)", "profile_traits 0.0.1", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "script_traits 0.0.1", "selectors 0.1.0 (git+https://github.com/servo/rust-selectors)", "string_cache 0.1.0 (git+https://github.com/servo/string-cache)", @@ -1071,11 +1040,11 @@ dependencies = [ "style 0.0.1", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "uuid 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "webdriver_traits 0.0.1", - "websocket 0.11.10 (registry+https://github.com/rust-lang/crates.io-index)", + "websocket 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1095,7 +1064,7 @@ dependencies = [ "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net_traits 0.0.1", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "webdriver_traits 0.0.1", ] @@ -1114,6 +1083,15 @@ dependencies = [ "string_cache_plugin 0.1.1 (git+https://github.com/servo/string-cache)", ] +[[package]] +name = "shared_library" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "skia" version = "0.0.20130412" @@ -1177,11 +1155,11 @@ dependencies = [ "mod_path 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.1.0 (git+https://github.com/servo/rust-selectors)", "string_cache 0.1.0 (git+https://github.com/servo/string-cache)", "string_cache_plugin 0.1.1 (git+https://github.com/servo/string-cache)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -1195,7 +1173,7 @@ dependencies = [ "string_cache 0.1.0 (git+https://github.com/servo/string-cache)", "string_cache_plugin 0.1.1 (git+https://github.com/servo/string-cache)", "style 0.0.1", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -1221,7 +1199,7 @@ name = "time" version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1242,11 +1220,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "url" -version = "0.2.31" +version = "0.2.33" 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.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1273,13 +1251,13 @@ dependencies = [ "num_cpus 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.1.0 (git+https://github.com/servo/rust-selectors)", "smallvec 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.1.0 (git+https://github.com/servo/string-cache)", "string_cache_plugin 0.1.1 (git+https://github.com/servo/string-cache)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1296,18 +1274,18 @@ version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "webdriver" -version = "0.1.0" -source = "git+https://github.com/jgraham/webdriver-rust.git#4065017191f1054b62f8c17c2b07c412111e0022" +version = "0.2.0" +source = "git+https://github.com/jgraham/webdriver-rust.git#038c1828c5dd4ab7b8f70b3d859c0ff988e6ca25" dependencies = [ - "hyper 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1317,11 +1295,11 @@ version = "0.0.1" dependencies = [ "msg 0.0.1", "png 0.1.0 (git+https://github.com/servo/rust-png)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "uuid 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "webdriver 0.1.0 (git+https://github.com/jgraham/webdriver-rust.git)", + "webdriver 0.2.0 (git+https://github.com/jgraham/webdriver-rust.git)", "webdriver_traits 0.0.1", ] @@ -1329,22 +1307,22 @@ dependencies = [ name = "webdriver_traits" version = "0.0.1" dependencies = [ - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "websocket" -version = "0.11.10" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1357,7 +1335,7 @@ dependencies = [ [[package]] name = "x11" -version = "0.0.32" +version = "0.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index 0280b275b83..cecb4d20dd0 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net 0.0.1", - "objc 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "objc 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "png 0.1.0 (git+https://github.com/servo/rust-png)", "script 0.0.1", @@ -27,7 +27,7 @@ dependencies = [ "servo 0.0.1", "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)", "style 0.0.1", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "x11 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -119,11 +119,11 @@ dependencies = [ [[package]] name = "cocoa" version = "0.1.1" -source = "git+https://github.com/servo/rust-cocoa#26d02e3f3606223645dde173a7bb924bce4836de" +source = "git+https://github.com/servo/rust-cocoa#493594f4e23a5f534a28be83748b6a0c058e2373" dependencies = [ "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "objc 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "objc 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -151,20 +151,20 @@ dependencies = [ "script_traits 0.0.1", "style 0.0.1", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "webdriver_traits 0.0.1", ] [[package]] name = "cookie" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "openssl 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -178,7 +178,7 @@ dependencies = [ [[package]] name = "core_graphics" version = "0.1.0" -source = "git+https://github.com/servo/rust-core-graphics#da0d2fe947412afea55b438454194b2183c21594" +source = "git+https://github.com/servo/rust-core-graphics#2d8d665c5bdd116b4a1addbe5c415735fb78e1a9" dependencies = [ "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -187,7 +187,7 @@ dependencies = [ [[package]] name = "core_text" version = "0.1.0" -source = "git+https://github.com/servo/rust-core-text#bc6994c3765f0660e9c04f5488ba194a9354e8fb" +source = "git+https://github.com/servo/rust-core-text#2b4b546718310a9d3fe4273a1df092c79d9fb2c2" 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)", @@ -215,9 +215,9 @@ dependencies = [ "devtools_traits 0.0.1", "hyper 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -227,9 +227,9 @@ version = "0.0.1" dependencies = [ "hyper 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -301,7 +301,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "expat-sys" version = "2.1.0" -source = "git+https://github.com/servo/libexpat#5f798cfbb74650a5e1d95e4c03a9e41e55e28625" +source = "git+https://github.com/servo/libexpat#91775ceb69adaea0ce903271b185079a2c484f57" [[package]] name = "flate2" @@ -350,7 +350,7 @@ source = "git+https://github.com/servo/libfreetype2#50c1cf412d87f20ccbb940e39a14 [[package]] name = "gcc" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -369,7 +369,7 @@ dependencies = [ "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -395,14 +395,14 @@ dependencies = [ "png 0.1.0 (git+https://github.com/servo/rust-png)", "profile_traits 0.0.1", "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "script_traits 0.0.1", "skia 0.0.20130412 (git+https://github.com/servo/skia)", "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)", "string_cache 0.1.0 (git+https://github.com/servo/string-cache)", "style 0.0.1", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -413,17 +413,6 @@ dependencies = [ "azure 0.1.0 (git+https://github.com/servo/rust-azure)", ] -[[package]] -name = "gl" -version = "0.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "gl_common 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "gl_generator 0.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "khronos_api 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "gl_common" version = "0.0.4" @@ -434,7 +423,7 @@ dependencies = [ [[package]] name = "gl_generator" -version = "0.0.24" +version = "0.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "khronos_api 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -448,7 +437,7 @@ version = "0.0.1" source = "git+https://github.com/servo/gleam#f2edabf2ef0474bb270b107e5e68c2727c4a422d" dependencies = [ "gl_common 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "gl_generator 0.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "gl_generator 0.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "khronos_api 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -456,24 +445,24 @@ dependencies = [ [[package]] name = "glutin" version = "0.0.26" -source = "git+https://github.com/servo/glutin?branch=servo#33f26a11d73cb4a3969059c57471f9f7b151dc1d" +source = "git+https://github.com/servo/glutin?branch=servo#ec7a5e40c1cc7b8176eb1e1f7bf70c8a19559400" dependencies = [ "android_glue 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "gdi32-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "gl_common 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "gl_generator 0.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "glutin_cocoa 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "gl_generator 0.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "glutin_cocoa 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "glutin_core_foundation 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "glutin_core_graphics 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "glutin_core_graphics 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "khronos_api 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "objc 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "osmesa-sys 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "objc 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "osmesa-sys 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "user32-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "x11 0.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "x11 0.0.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -492,18 +481,18 @@ dependencies = [ "msg 0.0.1", "script_traits 0.0.1", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] [[package]] name = "glutin_cocoa" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "objc 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "objc 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -516,7 +505,7 @@ dependencies = [ [[package]] name = "glutin_core_graphics" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "glutin_core_foundation 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -529,7 +518,7 @@ version = "0.0.1" source = "git+https://github.com/servo/rust-glx#60ac0aee2438eadb4b51ddc8eac6fc4b5ca8e447" dependencies = [ "gl_common 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "gl_generator 0.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "gl_generator 0.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "khronos_api 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -545,7 +534,7 @@ dependencies = [ [[package]] name = "html5ever" version = "0.0.0" -source = "git+https://github.com/servo/html5ever#74dc5f5a36451cfbe789488b20d51bef97c63898" +source = "git+https://github.com/servo/html5ever#7ddaa598b84e5e7fb9bf5313c02c1aaca970cb4b" dependencies = [ "html5ever_macros 0.0.0 (git+https://github.com/servo/html5ever)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -560,10 +549,10 @@ dependencies = [ [[package]] name = "html5ever_macros" version = "0.0.0" -source = "git+https://github.com/servo/html5ever#74dc5f5a36451cfbe789488b20d51bef97c63898" +source = "git+https://github.com/servo/html5ever#7ddaa598b84e5e7fb9bf5313c02c1aaca970cb4b" dependencies = [ "mac 0.0.2 (git+https://github.com/reem/rust-mac)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -571,42 +560,23 @@ name = "httparse" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "hyper" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cookie 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "typeable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "hyper" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cookie 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", + "cookie 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "typeable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -629,7 +599,7 @@ dependencies = [ "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "mozjs_sys 0.0.0 (git+https://github.com/servo/mozjs)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -660,7 +630,7 @@ dependencies = [ "io_surface 0.1.0 (git+https://github.com/servo/rust-io-surface)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "skia 0.0.20130412 (git+https://github.com/servo/skia)", "xlib 0.1.0 (git+https://github.com/servo/rust-xlib)", ] @@ -686,14 +656,14 @@ dependencies = [ "plugins 0.0.1", "png 0.1.0 (git+https://github.com/servo/rust-png)", "profile_traits 0.0.1", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "script 0.0.1", "script_traits 0.0.1", "selectors 0.1.0 (git+https://github.com/servo/rust-selectors)", "string_cache 0.1.0 (git+https://github.com/servo/string-cache)", "string_cache_plugin 0.1.1 (git+https://github.com/servo/string-cache)", "style 0.0.1", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -707,7 +677,7 @@ dependencies = [ "net_traits 0.0.1", "profile_traits 0.0.1", "script_traits 0.0.1", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -762,7 +732,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "mime" -version = "0.0.10" +version = "0.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -773,7 +743,7 @@ name = "miniz-sys" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -800,7 +770,7 @@ dependencies = [ "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "png 0.1.0 (git+https://github.com/servo/rust-png)", "style 0.0.1", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "webdriver_traits 0.0.1", ] @@ -809,19 +779,19 @@ dependencies = [ name = "net" version = "0.0.1" dependencies = [ - "cookie 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", + "cookie 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "devtools_traits 0.0.1", "flate2 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "hyper 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "net_traits 0.0.1", - "openssl 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "png 0.1.0 (git+https://github.com/servo/rust-png)", "regex 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", "regex_macros 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "uuid 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -835,7 +805,7 @@ dependencies = [ "msg 0.0.1", "png 0.1.0 (git+https://github.com/servo/rust-png)", "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -845,7 +815,7 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -858,7 +828,7 @@ dependencies = [ [[package]] name = "objc" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -883,34 +853,33 @@ dependencies = [ [[package]] name = "openssl" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl-sys" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "libressl-pnacl-sys 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "osmesa-sys" -version = "0.0.3" +version = "0.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gl 0.0.12 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "shared_library 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -947,7 +916,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "pkg-config" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -970,7 +939,7 @@ name = "png" version = "0.1.0" source = "git+https://github.com/servo/rust-png#34fca101357da41b2b8c95f3efe6cb88a2b36bca" dependencies = [ - "gcc 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "png-sys 1.6.16 (git+https://github.com/servo/rust-png)", ] @@ -997,7 +966,7 @@ name = "profile_traits" version = "0.0.1" dependencies = [ "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1028,7 +997,7 @@ dependencies = [ [[package]] name = "rustc-serialize" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1053,7 +1022,7 @@ dependencies = [ "plugins 0.0.1", "png 0.1.0 (git+https://github.com/servo/rust-png)", "profile_traits 0.0.1", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "script_traits 0.0.1", "selectors 0.1.0 (git+https://github.com/servo/rust-selectors)", "string_cache 0.1.0 (git+https://github.com/servo/string-cache)", @@ -1061,11 +1030,11 @@ dependencies = [ "style 0.0.1", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "uuid 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "webdriver_traits 0.0.1", - "websocket 0.11.10 (registry+https://github.com/rust-lang/crates.io-index)", + "websocket 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1077,7 +1046,7 @@ dependencies = [ "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net_traits 0.0.1", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "webdriver_traits 0.0.1", ] @@ -1116,11 +1085,20 @@ dependencies = [ "profile_traits 0.0.1", "script 0.0.1", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "webdriver_server 0.0.1", ] +[[package]] +name = "shared_library" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "skia" version = "0.0.20130412" @@ -1184,11 +1162,11 @@ dependencies = [ "mod_path 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.1.0 (git+https://github.com/servo/rust-selectors)", "string_cache 0.1.0 (git+https://github.com/servo/string-cache)", "string_cache_plugin 0.1.1 (git+https://github.com/servo/string-cache)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -1214,7 +1192,7 @@ name = "time" version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1235,11 +1213,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "url" -version = "0.2.31" +version = "0.2.33" 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.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1266,13 +1244,13 @@ dependencies = [ "num_cpus 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.1.0 (git+https://github.com/servo/rust-selectors)", "smallvec 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.1.0 (git+https://github.com/servo/string-cache)", "string_cache_plugin 0.1.1 (git+https://github.com/servo/string-cache)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1281,18 +1259,18 @@ version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "webdriver" -version = "0.1.0" -source = "git+https://github.com/jgraham/webdriver-rust.git#4065017191f1054b62f8c17c2b07c412111e0022" +version = "0.2.0" +source = "git+https://github.com/jgraham/webdriver-rust.git#038c1828c5dd4ab7b8f70b3d859c0ff988e6ca25" dependencies = [ - "hyper 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1302,11 +1280,11 @@ version = "0.0.1" dependencies = [ "msg 0.0.1", "png 0.1.0 (git+https://github.com/servo/rust-png)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "uuid 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "webdriver 0.1.0 (git+https://github.com/jgraham/webdriver-rust.git)", + "webdriver 0.2.0 (git+https://github.com/jgraham/webdriver-rust.git)", "webdriver_traits 0.0.1", ] @@ -1314,22 +1292,22 @@ dependencies = [ name = "webdriver_traits" version = "0.0.1" dependencies = [ - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "websocket" -version = "0.11.10" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1342,7 +1320,7 @@ dependencies = [ [[package]] name = "x11" -version = "0.0.32" +version = "0.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1354,7 +1332,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock index 79fa4d849df..168f839f5fd 100644 --- a/ports/gonk/Cargo.lock +++ b/ports/gonk/Cargo.lock @@ -20,7 +20,7 @@ dependencies = [ "script_traits 0.0.1", "servo 0.0.1", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -128,20 +128,20 @@ dependencies = [ "script_traits 0.0.1", "style 0.0.1", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "webdriver_traits 0.0.1", ] [[package]] name = "cookie" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "openssl 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -155,7 +155,7 @@ dependencies = [ [[package]] name = "core_graphics" version = "0.1.0" -source = "git+https://github.com/servo/rust-core-graphics#da0d2fe947412afea55b438454194b2183c21594" +source = "git+https://github.com/servo/rust-core-graphics#2d8d665c5bdd116b4a1addbe5c415735fb78e1a9" dependencies = [ "core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -164,7 +164,7 @@ dependencies = [ [[package]] name = "core_text" version = "0.1.0" -source = "git+https://github.com/servo/rust-core-text#bc6994c3765f0660e9c04f5488ba194a9354e8fb" +source = "git+https://github.com/servo/rust-core-text#2b4b546718310a9d3fe4273a1df092c79d9fb2c2" 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)", @@ -192,9 +192,9 @@ dependencies = [ "devtools_traits 0.0.1", "hyper 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -204,9 +204,9 @@ version = "0.0.1" dependencies = [ "hyper 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -288,7 +288,7 @@ dependencies = [ [[package]] name = "expat-sys" version = "2.1.0" -source = "git+https://github.com/servo/libexpat#5f798cfbb74650a5e1d95e4c03a9e41e55e28625" +source = "git+https://github.com/servo/libexpat#91775ceb69adaea0ce903271b185079a2c484f57" [[package]] name = "flate2" @@ -337,7 +337,7 @@ source = "git+https://github.com/servo/libfreetype2#50c1cf412d87f20ccbb940e39a14 [[package]] name = "gcc" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -348,7 +348,7 @@ dependencies = [ "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -374,14 +374,14 @@ dependencies = [ "png 0.1.0 (git+https://github.com/servo/rust-png)", "profile_traits 0.0.1", "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "script_traits 0.0.1", "skia 0.0.20130412 (git+https://github.com/servo/skia)", "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)", "string_cache 0.1.0 (git+https://github.com/servo/string-cache)", "style 0.0.1", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -402,7 +402,7 @@ dependencies = [ [[package]] name = "gl_generator" -version = "0.0.24" +version = "0.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "khronos_api 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -416,7 +416,7 @@ version = "0.0.1" source = "git+https://github.com/servo/gleam#f2edabf2ef0474bb270b107e5e68c2727c4a422d" dependencies = [ "gl_common 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "gl_generator 0.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "gl_generator 0.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "khronos_api 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -427,7 +427,7 @@ version = "0.0.1" source = "git+https://github.com/servo/rust-glx#60ac0aee2438eadb4b51ddc8eac6fc4b5ca8e447" dependencies = [ "gl_common 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "gl_generator 0.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "gl_generator 0.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "khronos_api 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -443,7 +443,7 @@ dependencies = [ [[package]] name = "html5ever" version = "0.0.0" -source = "git+https://github.com/servo/html5ever#74dc5f5a36451cfbe789488b20d51bef97c63898" +source = "git+https://github.com/servo/html5ever#7ddaa598b84e5e7fb9bf5313c02c1aaca970cb4b" dependencies = [ "html5ever_macros 0.0.0 (git+https://github.com/servo/html5ever)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -458,10 +458,10 @@ dependencies = [ [[package]] name = "html5ever_macros" version = "0.0.0" -source = "git+https://github.com/servo/html5ever#74dc5f5a36451cfbe789488b20d51bef97c63898" +source = "git+https://github.com/servo/html5ever#7ddaa598b84e5e7fb9bf5313c02c1aaca970cb4b" dependencies = [ "mac 0.0.2 (git+https://github.com/reem/rust-mac)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -469,42 +469,23 @@ name = "httparse" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "hyper" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cookie 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "typeable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "hyper" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cookie 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", + "cookie 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "typeable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -527,7 +508,7 @@ dependencies = [ "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "mozjs_sys 0.0.0 (git+https://github.com/servo/mozjs)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -558,7 +539,7 @@ dependencies = [ "io_surface 0.1.0 (git+https://github.com/servo/rust-io-surface)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "skia 0.0.20130412 (git+https://github.com/servo/skia)", "xlib 0.1.0 (git+https://github.com/servo/rust-xlib)", ] @@ -584,14 +565,14 @@ dependencies = [ "plugins 0.0.1", "png 0.1.0 (git+https://github.com/servo/rust-png)", "profile_traits 0.0.1", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "script 0.0.1", "script_traits 0.0.1", "selectors 0.1.0 (git+https://github.com/servo/rust-selectors)", "string_cache 0.1.0 (git+https://github.com/servo/string-cache)", "string_cache_plugin 0.1.1 (git+https://github.com/servo/string-cache)", "style 0.0.1", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -605,7 +586,7 @@ dependencies = [ "net_traits 0.0.1", "profile_traits 0.0.1", "script_traits 0.0.1", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -652,7 +633,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "mime" -version = "0.0.10" +version = "0.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -663,7 +644,7 @@ name = "miniz-sys" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -690,7 +671,7 @@ dependencies = [ "layers 0.1.0 (git+https://github.com/servo/rust-layers)", "png 0.1.0 (git+https://github.com/servo/rust-png)", "style 0.0.1", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "webdriver_traits 0.0.1", ] @@ -699,19 +680,19 @@ dependencies = [ name = "net" version = "0.0.1" dependencies = [ - "cookie 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", + "cookie 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "devtools_traits 0.0.1", "flate2 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "geom 0.1.0 (git+https://github.com/servo/rust-geom)", "hyper 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "net_traits 0.0.1", - "openssl 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "png 0.1.0 (git+https://github.com/servo/rust-png)", "regex 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", "regex_macros 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "uuid 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -725,7 +706,7 @@ dependencies = [ "msg 0.0.1", "png 0.1.0 (git+https://github.com/servo/rust-png)", "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -735,7 +716,7 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -764,24 +745,24 @@ dependencies = [ [[package]] name = "openssl" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl-sys" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "libressl-pnacl-sys 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -818,7 +799,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "pkg-config" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -841,7 +822,7 @@ name = "png" version = "0.1.0" source = "git+https://github.com/servo/rust-png#34fca101357da41b2b8c95f3efe6cb88a2b36bca" dependencies = [ - "gcc 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "png-sys 1.6.16 (git+https://github.com/servo/rust-png)", ] @@ -868,7 +849,7 @@ name = "profile_traits" version = "0.0.1" dependencies = [ "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -899,7 +880,7 @@ dependencies = [ [[package]] name = "rustc-serialize" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -924,7 +905,7 @@ dependencies = [ "plugins 0.0.1", "png 0.1.0 (git+https://github.com/servo/rust-png)", "profile_traits 0.0.1", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "script_traits 0.0.1", "selectors 0.1.0 (git+https://github.com/servo/rust-selectors)", "string_cache 0.1.0 (git+https://github.com/servo/string-cache)", @@ -932,11 +913,11 @@ dependencies = [ "style 0.0.1", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "uuid 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "webdriver_traits 0.0.1", - "websocket 0.11.10 (registry+https://github.com/rust-lang/crates.io-index)", + "websocket 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -948,7 +929,7 @@ dependencies = [ "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net_traits 0.0.1", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "webdriver_traits 0.0.1", ] @@ -986,7 +967,7 @@ dependencies = [ "profile_traits 0.0.1", "script 0.0.1", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "webdriver_server 0.0.1", ] @@ -1054,11 +1035,11 @@ dependencies = [ "mod_path 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.1.0 (git+https://github.com/servo/rust-selectors)", "string_cache 0.1.0 (git+https://github.com/servo/string-cache)", "string_cache_plugin 0.1.1 (git+https://github.com/servo/string-cache)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", ] @@ -1084,7 +1065,7 @@ name = "time" version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1105,11 +1086,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "url" -version = "0.2.31" +version = "0.2.33" 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.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1128,13 +1109,13 @@ dependencies = [ "num_cpus 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.1.0 (git+https://github.com/servo/rust-selectors)", "smallvec 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.1.0 (git+https://github.com/servo/string-cache)", "string_cache_plugin 0.1.1 (git+https://github.com/servo/string-cache)", "time 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1143,18 +1124,18 @@ version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "webdriver" -version = "0.1.0" -source = "git+https://github.com/jgraham/webdriver-rust.git#4065017191f1054b62f8c17c2b07c412111e0022" +version = "0.2.0" +source = "git+https://github.com/jgraham/webdriver-rust.git#038c1828c5dd4ab7b8f70b3d859c0ff988e6ca25" dependencies = [ - "hyper 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1164,11 +1145,11 @@ version = "0.0.1" dependencies = [ "msg 0.0.1", "png 0.1.0 (git+https://github.com/servo/rust-png)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", "uuid 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "webdriver 0.1.0 (git+https://github.com/jgraham/webdriver-rust.git)", + "webdriver 0.2.0 (git+https://github.com/jgraham/webdriver-rust.git)", "webdriver_traits 0.0.1", ] @@ -1176,22 +1157,22 @@ dependencies = [ name = "webdriver_traits" version = "0.0.1" dependencies = [ - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "websocket" -version = "0.11.10" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/rust-snapshot-hash b/rust-snapshot-hash index 377c6efc0b2..4a2a4452cf6 100644 --- a/rust-snapshot-hash +++ b/rust-snapshot-hash @@ -1 +1 @@ -551a74dddd84cf01440ee84148ebd18bc68bd7c8/rustc-1.1.0-dev +716f920b7e234b450f272346fea961832505c06e/rustc-1.1.0-dev diff --git a/tests/reftest.rs b/tests/reftest.rs index d7932a783bd..547fe548234 100644 --- a/tests/reftest.rs +++ b/tests/reftest.rs @@ -85,7 +85,7 @@ fn main() { run_ignored: false, logfile: None, run_tests: true, - run_benchmarks: false, + bench_benchmarks: false, nocapture: false, color: AutoColor, }; From b84c6fa5db6d7930a6340ed05fd453f7a91aaed8 Mon Sep 17 00:00:00 2001 From: Glenn Watson <gw@intuitionlibrary.com> Date: Thu, 21 May 2015 08:05:58 +1000 Subject: [PATCH 32/38] Fix document load event firing after pipeline is closed. --- components/gfx/paint_task.rs | 2 +- components/script/dom/document.rs | 18 +++++++++++------- components/script/dom/window.rs | 21 ++++++++++++++++++++- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/components/gfx/paint_task.rs b/components/gfx/paint_task.rs index 04570f14c80..50da56d45a3 100644 --- a/components/gfx/paint_task.rs +++ b/components/gfx/paint_task.rs @@ -296,7 +296,7 @@ impl<C> PaintTask<C> where C: PaintListener + Send + 'static { // If we own buffers in the compositor and we are not exiting completely, wait // for the compositor to return buffers, so that we can release them properly. // When doing a complete exit, the compositor lets all buffers leak. - println!("PaintTask {:?}: Saw ExitMsg, {} buffers in use", self.id, self.used_buffer_count); + debug!("PaintTask {:?}: Saw ExitMsg, {} buffers in use", self.id, self.used_buffer_count); waiting_for_compositor_buffers_to_exit = true; exit_response_channel = response_channel; } diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 19901c43796..9fabde71dd9 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -1830,13 +1830,17 @@ impl DocumentProgressHandler { impl Runnable for DocumentProgressHandler { fn handler(self: Box<DocumentProgressHandler>) { - match self.task { - DocumentProgressTask::DOMContentLoaded => { - self.dispatch_dom_content_loaded(); - } - DocumentProgressTask::Load => { - self.set_ready_state_complete(); - self.dispatch_load(); + let document = self.addr.to_temporary().root(); + let window = document.r().window().root(); + if window.r().is_alive() { + match self.task { + DocumentProgressTask::DOMContentLoaded => { + self.dispatch_dom_content_loaded(); + } + DocumentProgressTask::Load => { + self.set_ready_state_complete(); + self.dispatch_load(); + } } } } diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index f791464366d..b8e0ffb86e7 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -69,6 +69,14 @@ use std::sync::mpsc::{channel, Receiver, Sender}; use std::sync::mpsc::TryRecvError::{Empty, Disconnected}; use time; +/// Current state of the window object +#[derive(Copy, Clone, Debug, PartialEq)] +#[jstraceable] +enum WindowState { + Alive, + Zombie, // Pipeline is closed, but the window hasn't been GCed yet. +} + /// Extra information concerning the reason for reflowing. #[derive(Debug)] pub enum ReflowReason { @@ -170,7 +178,10 @@ pub struct Window { pending_reflow_count: Cell<u32>, /// A channel for communicating results of async scripts back to the webdriver server - webdriver_script_chan: RefCell<Option<Sender<WebDriverJSResult>>> + webdriver_script_chan: RefCell<Option<Sender<WebDriverJSResult>>>, + + /// The current state of the window object + current_state: Cell<WindowState>, } impl Window { @@ -179,6 +190,7 @@ impl Window { unsafe { *self.js_runtime.borrow_for_script_deallocation() = None; *self.browser_context.borrow_for_script_deallocation() = None; + self.current_state.set(WindowState::Zombie); } } @@ -544,6 +556,7 @@ pub trait WindowHelpers { fn set_devtools_timeline_marker(self, marker: TimelineMarkerType, reply: Sender<TimelineMarker>); fn drop_devtools_timeline_markers(self); fn set_webdriver_script_chan(self, chan: Option<Sender<WebDriverJSResult>>); + fn is_alive(self) -> bool; } pub trait ScriptHelpers { @@ -595,6 +608,7 @@ impl<'a> WindowHelpers for JSRef<'a, Window> { // which causes a panic! self.Gc(); + self.current_state.set(WindowState::Zombie); *self.js_runtime.borrow_mut() = None; *self.browser_context.borrow_mut() = None; } @@ -916,6 +930,10 @@ impl<'a> WindowHelpers for JSRef<'a, Window> { fn set_webdriver_script_chan(self, chan: Option<Sender<WebDriverJSResult>>) { *self.webdriver_script_chan.borrow_mut() = chan; } + + fn is_alive(self) -> bool { + self.current_state.get() == WindowState::Alive + } } impl Window { @@ -979,6 +997,7 @@ impl Window { layout_join_port: DOMRefCell::new(None), window_size: Cell::new(window_size), pending_reflow_count: Cell::new(0), + current_state: Cell::new(WindowState::Alive), devtools_marker_sender: RefCell::new(None), devtools_markers: RefCell::new(HashSet::new()), From d4be93613ba632c12689678d213a2690ee67814e Mon Sep 17 00:00:00 2001 From: Paul Faria <pauldfaria@gmail.com> Date: Wed, 20 May 2015 22:17:07 -0400 Subject: [PATCH 33/38] Adding in a missed algorithm step number in the comments. --- components/script/dom/websocket.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index f96c2706a20..e902d1ac034 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -84,7 +84,7 @@ fn parse_web_socket_url(url_str: &str) -> Fallible<(Url, String, u16, String, bo }; let host = parsed_url.host().unwrap().serialize(); // Step 6 - let port = parsed_url.port_or_default().unwrap(); // Step 7 + let port = parsed_url.port_or_default().unwrap(); // Steps 7 and 8 let mut resource = parsed_url.path().unwrap().connect("/"); // Step 9 if resource.is_empty() { resource = "/".to_owned(); // Step 10 From ef8a1271561b9ee7ea4be8ac2e0548d3c8669fb2 Mon Sep 17 00:00:00 2001 From: Josh Matthews <josh@joshmatthews.net> Date: Thu, 21 May 2015 09:53:19 -0400 Subject: [PATCH 34/38] Update test expectations. Mark script loads as complete when the response is complete. --- components/script/document_loader.rs | 1 + components/script/dom/htmlscriptelement.rs | 10 ++++++++-- .../scripting-1/the-script-element/async_008.htm.ini | 5 ----- .../submission/Opera/script_scheduling/081.html.ini | 5 ----- .../submission/Opera/script_scheduling/082.html.ini | 5 ----- .../submission/Opera/script_scheduling/092.html.ini | 5 ----- .../submission/Opera/script_scheduling/095.html.ini | 4 ---- .../submission/Opera/script_scheduling/122.html.ini | 3 --- .../submission/Opera/script_scheduling/125.html.ini | 5 ----- .../submission/Opera/script_scheduling/130.html.ini | 5 ----- .../submission/Opera/script_scheduling/134.html.ini | 5 +++++ 11 files changed, 14 insertions(+), 39 deletions(-) delete mode 100644 tests/wpt/metadata/html/semantics/scripting-1/the-script-element/async_008.htm.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/081.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/082.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/092.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/095.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/125.html.ini delete mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/130.html.ini create mode 100644 tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/134.html.ini diff --git a/components/script/document_loader.rs b/components/script/document_loader.rs index 14e107e9d02..7520bac32cb 100644 --- a/components/script/document_loader.rs +++ b/components/script/document_loader.rs @@ -100,6 +100,7 @@ impl DocumentLoader { } pub fn is_blocked(&self) -> bool { + //TODO: Ensure that we report blocked if parsing is still ongoing. !self.blocking_loads.is_empty() } diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 365d1a75e85..2011a31bf66 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -167,6 +167,8 @@ struct ScriptContext { metadata: RefCell<Option<Metadata>>, /// Whether the owning document's parser should resume once the response completes. resume_on_completion: bool, + /// The initial URL requested. + url: Url, } impl AsyncResponseListener for ScriptContext { @@ -175,7 +177,8 @@ impl AsyncResponseListener for ScriptContext { } fn data_available(&self, payload: Vec<u8>) { - self.data.borrow_mut().extend(payload.into_iter()); + let mut payload = payload; + self.data.borrow_mut().append(&mut payload); } fn response_complete(&self, status: Result<(), String>) { @@ -188,8 +191,10 @@ impl AsyncResponseListener for ScriptContext { elem.r().execute(ScriptOrigin::External(load)); + let document = document_from_node(elem.r()).root(); + document.r().finish_load(LoadType::Script(self.url.clone())); + if self.resume_on_completion { - let document = document_from_node(elem.r()).root(); document.r().get_current_parser().unwrap().root().r().resume(); } } @@ -316,6 +321,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { data: RefCell::new(vec!()), metadata: RefCell::new(None), resume_on_completion: self.parser_inserted.get(), + url: url.clone(), })); let listener = box NetworkListener { diff --git a/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/async_008.htm.ini b/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/async_008.htm.ini deleted file mode 100644 index b32fda7d128..00000000000 --- a/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/async_008.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[async_008.htm] - type: testharness - [Async script element execution delays the window's load event] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/081.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/081.html.ini deleted file mode 100644 index 298e96afb43..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/081.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[081.html] - type: testharness - [ scheduler: slow loading external script added with DOM (appendChild)] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/082.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/082.html.ini deleted file mode 100644 index 8b8e5f9f8c4..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/082.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[082.html] - type: testharness - [ scheduler: multiple slow loading external scripts added with DOM (appendChild)] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/092.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/092.html.ini deleted file mode 100644 index 53ace1e41ae..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/092.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[092.html] - type: testharness - [ scheduler: defer script and slow-loading non-async external script] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/095.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/095.html.ini deleted file mode 100644 index ceab463aa64..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/095.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[095.html] - type: testharness - [ scheduler: slow-loading script added from defer blocking load event] - expected: FAIL diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/122.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/122.html.ini index 941e581f20c..6432a9d5140 100644 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/122.html.ini +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/122.html.ini @@ -1,8 +1,5 @@ [122.html] type: testharness - [scheduler: altering the type attribute and adding/removing external script ] - expected: FAIL - [Reinserted script async IDL attribute] expected: FAIL diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/125.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/125.html.ini deleted file mode 100644 index e6269fe2954..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/125.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[125.html] - type: testharness - [scheduler: altering the type attribute and changing script data external script ] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/130.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/130.html.ini deleted file mode 100644 index 07a5de2740e..00000000000 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/130.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[130.html] - type: testharness - [scheduler: appending external script element to script ] - expected: FAIL - diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/134.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/134.html.ini new file mode 100644 index 00000000000..a836fbc66c9 --- /dev/null +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/134.html.ini @@ -0,0 +1,5 @@ +[134.html] + type: testharness + [scheduler: external HTML script added by SVG script] + expected: FAIL + From 512927eb343eb477cea45ebcf6d6820a2fe70a55 Mon Sep 17 00:00:00 2001 From: Josh Matthews <josh@joshmatthews.net> Date: Thu, 21 May 2015 09:57:24 -0400 Subject: [PATCH 35/38] fixup! Update test expectations. Mark script loads as complete when the response is complete. --- .../old-tests/submission/Opera/script_scheduling/134.html.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/134.html.ini b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/134.html.ini index a836fbc66c9..a01a182559d 100644 --- a/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/134.html.ini +++ b/tests/wpt/metadata/old-tests/submission/Opera/script_scheduling/134.html.ini @@ -1,5 +1,5 @@ [134.html] type: testharness - [scheduler: external HTML script added by SVG script] + [scheduler: external HTML script added by SVG script ] expected: FAIL From 3d30dfc652cf09c6a406ec3fe7bcb54ce14e21f5 Mon Sep 17 00:00:00 2001 From: Lars Bergstrom <lars@lars.com> Date: Thu, 21 May 2015 10:13:27 -0500 Subject: [PATCH 36/38] Upgrade to a 1.2.0 rust compiler --- rust-snapshot-hash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-snapshot-hash b/rust-snapshot-hash index 4a2a4452cf6..eb07c90a5fd 100644 --- a/rust-snapshot-hash +++ b/rust-snapshot-hash @@ -1 +1 @@ -716f920b7e234b450f272346fea961832505c06e/rustc-1.1.0-dev +b301e02f37127da993dd2cf370aa1066d48b042e/rustc-1.2.0-dev From fd4afc93a838bd4535300ef3e321e3a9281d0d36 Mon Sep 17 00:00:00 2001 From: Lars Bergstrom <lars@lars.com> Date: Thu, 21 May 2015 10:13:48 -0500 Subject: [PATCH 37/38] Update plugins API --- components/plugins/jstraceable.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/components/plugins/jstraceable.rs b/components/plugins/jstraceable.rs index 7f4757816e0..4c23a1897a5 100644 --- a/components/plugins/jstraceable.rs +++ b/components/plugins/jstraceable.rs @@ -42,6 +42,7 @@ pub fn expand_jstraceable(cx: &mut ExtCtxt, span: Span, mitem: &MetaItem, item: args: vec!(ty::Ptr(box ty::Literal(ty::Path::new(vec!("js","jsapi","JSTracer"))), ty::Raw(ast::MutMutable))), ret_ty: ty::nil_ty(), attributes: vec![quote_attr!(cx, #[inline(always)])], + is_unsafe: false, combine_substructure: combine_substructure(box jstraceable_substructure) } ], From 8394b8235071c69a949f4c73b421b177a51ba09f Mon Sep 17 00:00:00 2001 From: Manish Goregaokar <manishsmail@gmail.com> Date: Thu, 21 May 2015 23:10:54 +0530 Subject: [PATCH 38/38] Fix deprecated plugin APIs --- components/plugins/jstraceable.rs | 29 +++++++------ components/plugins/lib.rs | 4 +- components/plugins/reflector.rs | 67 ++++++++++++++++--------------- 3 files changed, 53 insertions(+), 47 deletions(-) diff --git a/components/plugins/jstraceable.rs b/components/plugins/jstraceable.rs index 4c23a1897a5..d11b0956bae 100644 --- a/components/plugins/jstraceable.rs +++ b/components/plugins/jstraceable.rs @@ -5,23 +5,28 @@ use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::codemap::Span; use syntax::ptr::P; -use syntax::ast::{Item, MetaItem, Expr}; +use syntax::ast::{MetaItem, Expr}; use syntax::ast; use syntax::ext::build::AstBuilder; use syntax::ext::deriving::generic::{combine_substructure, EnumMatching, FieldInfo, MethodDef, Struct, Substructure, TraitDef, ty}; -pub fn expand_dom_struct(cx: &mut ExtCtxt, _: Span, _: &MetaItem, item: P<Item>) -> P<Item> { - let mut item2 = (*item).clone(); - item2.attrs.push(quote_attr!(cx, #[must_root])); - item2.attrs.push(quote_attr!(cx, #[privatize])); - item2.attrs.push(quote_attr!(cx, #[jstraceable])); +pub fn expand_dom_struct(cx: &mut ExtCtxt, sp: Span, _: &MetaItem, anno: Annotatable) -> Annotatable { + if let Annotatable::Item(item) = anno { + let mut item2 = (*item).clone(); + item2.attrs.push(quote_attr!(cx, #[must_root])); + item2.attrs.push(quote_attr!(cx, #[privatize])); + item2.attrs.push(quote_attr!(cx, #[jstraceable])); - // The following attributes are only for internal usage - item2.attrs.push(quote_attr!(cx, #[_generate_reflector])); - // #[dom_struct] gets consumed, so this lets us keep around a residue - // Do NOT register a modifier/decorator on this attribute - item2.attrs.push(quote_attr!(cx, #[_dom_struct_marker])); - P(item2) + // The following attributes are only for internal usage + item2.attrs.push(quote_attr!(cx, #[_generate_reflector])); + // #[dom_struct] gets consumed, so this lets us keep around a residue + // Do NOT register a modifier/decorator on this attribute + item2.attrs.push(quote_attr!(cx, #[_dom_struct_marker])); + Annotatable::Item(P(item2)) + } else { + cx.span_err(sp, "#[dom_struct] applied to something other than a struct"); + anno + } } /// Provides the hook to expand `#[jstraceable]` into an implementation of `JSTraceable` diff --git a/components/plugins/lib.rs b/components/plugins/lib.rs index 887e78689a9..a74cbe83f30 100644 --- a/components/plugins/lib.rs +++ b/components/plugins/lib.rs @@ -39,9 +39,9 @@ pub mod casing; #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_syntax_extension(intern("dom_struct"), Modifier(box jstraceable::expand_dom_struct)); + reg.register_syntax_extension(intern("dom_struct"), MultiModifier(box jstraceable::expand_dom_struct)); reg.register_syntax_extension(intern("jstraceable"), MultiDecorator(box jstraceable::expand_jstraceable)); - reg.register_syntax_extension(intern("_generate_reflector"), Decorator(box reflector::expand_reflector)); + reg.register_syntax_extension(intern("_generate_reflector"), MultiDecorator(box reflector::expand_reflector)); reg.register_macro("to_lower", casing::expand_lower); reg.register_macro("to_upper", casing::expand_upper); reg.register_lint_pass(box lints::transmute_type::TransmutePass as LintPassObject); diff --git a/components/plugins/reflector.rs b/components/plugins/reflector.rs index 6c2213cdabc..d369dcbd3f3 100644 --- a/components/plugins/reflector.rs +++ b/components/plugins/reflector.rs @@ -2,45 +2,46 @@ * 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 syntax::ext::base::ExtCtxt; +use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::codemap::Span; -use syntax::ptr::P; -use syntax::ast::{Item, MetaItem}; +use syntax::ast::MetaItem; use syntax::ast; use utils::match_ty_unwrap; -pub fn expand_reflector(cx: &mut ExtCtxt, span: Span, _: &MetaItem, item: &Item, push: &mut 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 - match def.fields.iter().find(|f| match_ty_unwrap(&*f.node.ty, &["dom", "bindings", "utils", "Reflector"]).is_some()) { - // If it has a field that is a Reflector, use that - Some(f) => { - let field_name = f.node.ident(); - let impl_item = quote_item!(cx, - impl ::dom::bindings::utils::Reflectable for $struct_name { - fn reflector<'a>(&'a self) -> &'a ::dom::bindings::utils::Reflector { - &self.$field_name +pub fn expand_reflector(cx: &mut ExtCtxt, span: Span, _: &MetaItem, annotatable: Annotatable, push: &mut FnMut(Annotatable)) { + if let Annotatable::Item(item) = annotatable { + 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 + match def.fields.iter().find(|f| match_ty_unwrap(&*f.node.ty, &["dom", "bindings", "utils", "Reflector"]).is_some()) { + // If it has a field that is a Reflector, use that + Some(f) => { + let field_name = f.node.ident(); + let impl_item = quote_item!(cx, + impl ::dom::bindings::utils::Reflectable for $struct_name { + fn reflector<'a>(&'a self) -> &'a ::dom::bindings::utils::Reflector { + &self.$field_name + } } - } - ); - impl_item.map(|it| push(it)) - }, - // Or just call it on the first field (supertype). - None => { - let field_name = def.fields[0].node.ident(); - let impl_item = quote_item!(cx, - impl ::dom::bindings::utils::Reflectable for $struct_name { - fn reflector<'a>(&'a self) -> &'a ::dom::bindings::utils::Reflector { - self.$field_name.reflector() + ); + impl_item.map(|it| push(Annotatable::Item(it))) + }, + // Or just call it on the first field (supertype). + None => { + let field_name = def.fields[0].node.ident(); + let impl_item = quote_item!(cx, + impl ::dom::bindings::utils::Reflectable for $struct_name { + fn reflector<'a>(&'a self) -> &'a ::dom::bindings::utils::Reflector { + self.$field_name.reflector() + } } - } - ); - impl_item.map(|it| push(it)) - } - }; - } else { - cx.span_err(span, "#[dom_struct] seems to have been applied to a non-struct"); + ); + impl_item.map(|it| push(Annotatable::Item(it))) + } + }; + } else { + cx.span_err(span, "#[dom_struct] seems to have been applied to a non-struct"); + } } }