aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/compositing/compositor.rs78
-rw-r--r--components/gfx/display_list/mod.rs33
-rw-r--r--components/gfx/paint_thread.rs3
-rw-r--r--components/gfx_traits/lib.rs55
-rw-r--r--components/layout/block.rs4
-rw-r--r--components/layout/display_list_builder.rs11
-rw-r--r--components/layout/flex.rs3
-rw-r--r--components/layout/flow.rs4
-rw-r--r--components/layout/fragment.rs4
-rw-r--r--components/layout/inline.rs3
-rw-r--r--components/layout/layout_thread.rs56
-rw-r--r--components/layout/list_item.rs3
-rw-r--r--components/layout/multicol.rs3
-rw-r--r--components/layout/table.rs3
-rw-r--r--components/layout/table_caption.rs3
-rw-r--r--components/layout/table_cell.rs3
-rw-r--r--components/layout/table_colgroup.rs3
-rw-r--r--components/layout/table_row.rs3
-rw-r--r--components/layout/table_rowgroup.rs3
-rw-r--r--components/layout/table_wrapper.rs3
-rw-r--r--components/layout/webrender_helpers.rs45
-rw-r--r--components/profile/time.rs1
-rw-r--r--components/profile_traits/time.rs1
-rw-r--r--components/script/dom/window.rs9
-rw-r--r--components/script/layout_interface.rs5
-rw-r--r--components/script/script_runtime.rs1
-rw-r--r--components/script/script_thread.rs23
-rw-r--r--components/script_traits/lib.rs14
-rw-r--r--components/servo/Cargo.lock4
-rw-r--r--ports/cef/Cargo.lock4
-rw-r--r--tests/wpt/mozilla/meta/MANIFEST.json6
-rw-r--r--tests/wpt/mozilla/tests/mozilla/scrollTo.html21
32 files changed, 317 insertions, 98 deletions
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs
index ed2f0879afa..d25fdb4b7d2 100644
--- a/components/compositing/compositor.rs
+++ b/components/compositing/compositor.rs
@@ -15,7 +15,8 @@ use euclid::scale_factor::ScaleFactor;
use euclid::size::TypedSize2D;
use euclid::{Matrix4D, Point2D, Rect, Size2D};
use gfx::paint_thread::{ChromeToPaintMsg, PaintRequest};
-use gfx_traits::{color, Epoch, FrameTreeId, LayerId, LayerKind, LayerProperties, ScrollPolicy};
+use gfx_traits::{ScrollPolicy, StackingContextId};
+use gfx_traits::{color, Epoch, FrameTreeId, FragmentType, LayerId, LayerKind, LayerProperties};
use gleam::gl;
use gleam::gl::types::{GLint, GLsizei};
use image::{DynamicImage, ImageFormat, RgbImage};
@@ -35,8 +36,8 @@ use profile_traits::mem::{self, ReportKind, Reporter, ReporterRequest};
use profile_traits::time::{self, ProfilerCategory, profile};
use script_traits::CompositorEvent::{MouseMoveEvent, MouseButtonEvent, TouchEvent};
use script_traits::{AnimationState, AnimationTickType, ConstellationControlMsg};
-use script_traits::{ConstellationMsg, LayoutControlMsg, MouseButton};
-use script_traits::{MouseEventType, TouchpadPressurePhase, TouchEventType, TouchId};
+use script_traits::{ConstellationMsg, LayoutControlMsg, MouseButton, MouseEventType};
+use script_traits::{StackingContextScrollState, TouchpadPressurePhase, TouchEventType, TouchId};
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::collections::{HashMap, HashSet};
use std::fs::File;
@@ -91,6 +92,32 @@ impl ConvertPipelineIdFromWebRender for webrender_traits::PipelineId {
}
}
+trait ConvertStackingContextFromWebRender {
+ fn from_webrender(&self) -> StackingContextId;
+}
+
+impl ConvertStackingContextFromWebRender for webrender_traits::ServoStackingContextId {
+ fn from_webrender(&self) -> StackingContextId {
+ StackingContextId::new_of_type(self.1, self.0.from_webrender())
+ }
+}
+
+trait ConvertFragmentTypeFromWebRender {
+ fn from_webrender(&self) -> FragmentType;
+}
+
+impl ConvertFragmentTypeFromWebRender for webrender_traits::FragmentType {
+ fn from_webrender(&self) -> FragmentType {
+ match *self {
+ webrender_traits::FragmentType::FragmentBody => FragmentType::FragmentBody,
+ webrender_traits::FragmentType::BeforePseudoContent => {
+ FragmentType::BeforePseudoContent
+ }
+ webrender_traits::FragmentType::AfterPseudoContent => FragmentType::AfterPseudoContent,
+ }
+ }
+}
+
/// Holds the state when running reftests that determines when it is
/// safe to save the output image.
#[derive(Copy, Clone, PartialEq)]
@@ -1620,12 +1647,12 @@ impl<Window: WindowMethods> IOCompositor<Window> {
self.perform_updates_after_scroll();
}
-
- if had_events {
- self.send_viewport_rects_for_all_layers();
- }
}
}
+
+ if had_events {
+ self.send_viewport_rects_for_all_layers();
+ }
}
/// Computes new display ports for each layer, taking the scroll position into account, and
@@ -1887,9 +1914,40 @@ impl<Window: WindowMethods> IOCompositor<Window> {
}
fn send_viewport_rects_for_all_layers(&self) {
- match self.scene.root {
- Some(ref root) => self.send_viewport_rect_for_layer(root.clone()),
- None => {},
+ if opts::get().use_webrender {
+ return self.send_webrender_viewport_rects()
+ }
+
+ if let Some(ref root) = self.scene.root {
+ self.send_viewport_rect_for_layer(root.clone())
+ }
+ }
+
+ fn send_webrender_viewport_rects(&self) {
+ let mut stacking_context_scroll_states_per_pipeline = HashMap::new();
+ if let Some(ref webrender_api) = self.webrender_api {
+ for scroll_layer_state in webrender_api.get_scroll_layer_state() {
+ let stacking_context_scroll_state = StackingContextScrollState {
+ stacking_context_id: scroll_layer_state.stacking_context_id.from_webrender(),
+ scroll_offset: scroll_layer_state.scroll_offset,
+ };
+ let pipeline_id = scroll_layer_state.pipeline_id;
+ match stacking_context_scroll_states_per_pipeline.entry(pipeline_id) {
+ Vacant(mut entry) => {
+ entry.insert(vec![stacking_context_scroll_state]);
+ }
+ Occupied(mut entry) => entry.get_mut().push(stacking_context_scroll_state),
+ }
+ }
+
+ for (pipeline_id, stacking_context_scroll_states) in
+ stacking_context_scroll_states_per_pipeline {
+ if let Some(pipeline) = self.pipeline(pipeline_id.from_webrender()) {
+ let msg = LayoutControlMsg::SetStackingContextScrollStates(
+ stacking_context_scroll_states);
+ let _ = pipeline.layout_chan.send(msg);
+ }
+ }
}
}
diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs
index d7463c31124..f60a5245cb1 100644
--- a/components/gfx/display_list/mod.rs
+++ b/components/gfx/display_list/mod.rs
@@ -22,7 +22,7 @@ use euclid::num::Zero;
use euclid::rect::TypedRect;
use euclid::{Matrix2D, Matrix4D, Point2D, Rect, SideOffsets2D, Size2D};
use fnv::FnvHasher;
-use gfx_traits::{LayerId, ScrollPolicy};
+use gfx_traits::{LayerId, ScrollPolicy, StackingContextId};
use ipc_channel::ipc::IpcSharedMemory;
use msg::constellation_msg::PipelineId;
use net_traits::image::base::{Image, PixelFormat};
@@ -1395,37 +1395,6 @@ impl fmt::Debug for DisplayItem {
}
}
-#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Deserialize, Serialize, HeapSizeOf, RustcEncodable)]
-pub enum FragmentType {
- /// A StackingContext for the fragment body itself.
- FragmentBody,
- /// A StackingContext created to contain ::before pseudo-element content.
- BeforePseudoContent,
- /// A StackingContext created to contain ::after pseudo-element content.
- AfterPseudoContent,
-}
-
-/// A unique ID for every stacking context.
-#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, HeapSizeOf, PartialEq, RustcEncodable, Serialize)]
-pub struct StackingContextId(
- /// The identifier for this StackingContext, derived from the Flow's memory address
- /// and fragment type. As a space optimization, these are combined into a single word.
- usize
-);
-
-impl StackingContextId {
- #[inline(always)]
- pub fn new(id: usize) -> StackingContextId {
- StackingContextId::new_of_type(id, FragmentType::FragmentBody)
- }
-
- #[inline(always)]
- pub fn new_of_type(id: usize, fragment_type: FragmentType) -> StackingContextId {
- debug_assert_eq!(id & fragment_type as usize, 0);
- StackingContextId(id | fragment_type as usize)
- }
-}
-
#[derive(Copy, Clone, HeapSizeOf, Deserialize, Serialize)]
pub struct WebRenderImageInfo {
pub width: u32,
diff --git a/components/gfx/paint_thread.rs b/components/gfx/paint_thread.rs
index bafe17ce015..3f86acfb4d6 100644
--- a/components/gfx/paint_thread.rs
+++ b/components/gfx/paint_thread.rs
@@ -8,13 +8,14 @@ use app_units::Au;
use azure::AzFloat;
use azure::azure_hl::{BackendType, Color, DrawTarget, SurfaceFormat};
use display_list::{DisplayItem, DisplayList, DisplayListTraversal};
-use display_list::{LayerInfo, StackingContext, StackingContextId, StackingContextType};
+use display_list::{LayerInfo, StackingContext, StackingContextType};
use euclid::Matrix4D;
use euclid::point::Point2D;
use euclid::rect::Rect;
use euclid::size::Size2D;
use font_cache_thread::FontCacheThread;
use font_context::FontContext;
+use gfx_traits::StackingContextId;
use gfx_traits::{Epoch, FrameTreeId, LayerId, LayerKind, LayerProperties, PaintListener};
use ipc_channel::ipc::IpcSender;
use layers::layers::{BufferRequest, LayerBuffer, LayerBufferSet};
diff --git a/components/gfx_traits/lib.rs b/components/gfx_traits/lib.rs
index 6065704648d..c1a8155a798 100644
--- a/components/gfx_traits/lib.rs
+++ b/components/gfx_traits/lib.rs
@@ -149,3 +149,58 @@ impl FrameTreeId {
self.0 += 1;
}
}
+
+/// A unique ID for every stacking context.
+#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, HeapSizeOf, PartialEq, Serialize)]
+pub struct StackingContextId(
+ /// The identifier for this StackingContext, derived from the Flow's memory address
+ /// and fragment type. As a space optimization, these are combined into a single word.
+ usize
+);
+
+impl StackingContextId {
+ #[inline(always)]
+ pub fn new(id: usize) -> StackingContextId {
+ StackingContextId::new_of_type(id, FragmentType::FragmentBody)
+ }
+
+ #[inline(always)]
+ pub fn new_of_type(id: usize, fragment_type: FragmentType) -> StackingContextId {
+ debug_assert_eq!(id & fragment_type as usize, 0);
+ StackingContextId(id | fragment_type as usize)
+ }
+
+ #[inline]
+ pub fn fragment_type(&self) -> FragmentType {
+ FragmentType::from_usize(self.0 & 3)
+ }
+
+ #[inline]
+ pub fn id(&self) -> usize {
+ self.0 & !3
+ }
+}
+
+
+#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Deserialize, Serialize, HeapSizeOf)]
+pub enum FragmentType {
+ /// A StackingContext for the fragment body itself.
+ FragmentBody,
+ /// A StackingContext created to contain ::before pseudo-element content.
+ BeforePseudoContent,
+ /// A StackingContext created to contain ::after pseudo-element content.
+ AfterPseudoContent,
+}
+
+impl FragmentType {
+ #[inline]
+ pub fn from_usize(n: usize) -> FragmentType {
+ debug_assert!(n < 3);
+ match n {
+ 0 => FragmentType::FragmentBody,
+ 1 => FragmentType::BeforePseudoContent,
+ _ => FragmentType::AfterPseudoContent,
+ }
+ }
+}
+
diff --git a/components/layout/block.rs b/components/layout/block.rs
index d5decf50c8d..2e0794913d3 100644
--- a/components/layout/block.rs
+++ b/components/layout/block.rs
@@ -43,8 +43,8 @@ use flow_list::FlowList;
use flow_ref::FlowRef;
use fragment::SpecificFragmentInfo;
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, HAS_LAYER, Overflow};
-use gfx::display_list::{ClippingRegion, StackingContext, StackingContextId};
-use gfx_traits::LayerId;
+use gfx::display_list::{ClippingRegion, StackingContext};
+use gfx_traits::{LayerId, StackingContextId};
use incremental::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT};
use layout_debug;
use layout_thread::DISPLAY_PORT_SIZE_FACTOR;
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs
index 8e1d10424db..c5e32ab7782 100644
--- a/components/layout/display_list_builder.rs
+++ b/components/layout/display_list_builder.rs
@@ -21,17 +21,16 @@ use flow::{BaseFlow, Flow, IS_ABSOLUTELY_POSITIONED};
use flow_ref;
use fragment::SpecificFragmentInfo;
use fragment::{CoordinateSystem, Fragment, HAS_LAYER, ImageFragmentInfo, ScannedTextFragmentInfo};
-use gfx::display_list::GradientDisplayItem;
use gfx::display_list::{BLUR_INFLATION_FACTOR, BaseDisplayItem, BorderDisplayItem};
use gfx::display_list::{BorderRadii, BoxShadowClipMode, BoxShadowDisplayItem, ClippingRegion};
-use gfx::display_list::{DisplayItem, DisplayItemMetadata, DisplayListSection};
-use gfx::display_list::{GradientStop, IframeDisplayItem, ImageDisplayItem, WebGLDisplayItem, LayeredItem, LayerInfo};
-use gfx::display_list::{LineDisplayItem, OpaqueNode, SolidColorDisplayItem};
-use gfx::display_list::{StackingContext, StackingContextId, StackingContextType};
+use gfx::display_list::{DisplayItem, DisplayItemMetadata, DisplayListSection, GradientDisplayItem};
+use gfx::display_list::{GradientStop, IframeDisplayItem, ImageDisplayItem, WebGLDisplayItem};
+use gfx::display_list::{LayeredItem, LayerInfo, LineDisplayItem, OpaqueNode};
+use gfx::display_list::{SolidColorDisplayItem, StackingContext, StackingContextType};
use gfx::display_list::{TextDisplayItem, TextOrientation, WebRenderImageInfo};
use gfx::paint_thread::THREAD_TINT_COLORS;
use gfx::text::glyph::ByteIndex;
-use gfx_traits::{color, ScrollPolicy};
+use gfx_traits::{color, ScrollPolicy, StackingContextId};
use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, LAST_FRAGMENT_OF_ELEMENT};
use ipc_channel::ipc;
use list_item::ListItemFlow;
diff --git a/components/layout/flex.rs b/components/layout/flex.rs
index 6d2a12fec62..5a89a627fbe 100644
--- a/components/layout/flex.rs
+++ b/components/layout/flex.rs
@@ -17,7 +17,8 @@ use flow::{Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow};
use flow::{INLINE_POSITION_IS_STATIC, IS_ABSOLUTELY_POSITIONED};
use flow_ref::{self, FlowRef};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
-use gfx::display_list::{StackingContext, StackingContextId};
+use gfx::display_list::StackingContext;
+use gfx_traits::StackingContextId;
use incremental::{REFLOW, REFLOW_OUT_OF_FLOW};
use layout_debug;
use model::{IntrinsicISizes, MaybeAuto, MinMaxConstraint};
diff --git a/components/layout/flow.rs b/components/layout/flow.rs
index 05e5814d0e0..1267ed31cf1 100644
--- a/components/layout/flow.rs
+++ b/components/layout/flow.rs
@@ -34,8 +34,8 @@ use floats::{Floats, SpeculatedFloatPlacement};
use flow_list::{FlowList, FlowListIterator, MutFlowListIterator};
use flow_ref::{self, FlowRef, WeakFlowRef};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow, SpecificFragmentInfo};
-use gfx::display_list::{ClippingRegion, StackingContext, StackingContextId};
-use gfx_traits::{LayerId, LayerType};
+use gfx::display_list::{ClippingRegion, StackingContext};
+use gfx_traits::{LayerId, LayerType, StackingContextId};
use incremental::{RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, RestyleDamage};
use inline::InlineFlow;
use model::{CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo};
diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs
index 3a5d90201bd..9868e141df1 100644
--- a/components/layout/fragment.rs
+++ b/components/layout/fragment.rs
@@ -14,10 +14,10 @@ use floats::ClearType;
use flow::{self, ImmutableFlowUtils};
use flow_ref::{self, FlowRef};
use gfx;
-use gfx::display_list::{BLUR_INFLATION_FACTOR, FragmentType, OpaqueNode, StackingContextId};
+use gfx::display_list::{BLUR_INFLATION_FACTOR, OpaqueNode};
use gfx::text::glyph::ByteIndex;
use gfx::text::text_run::{TextRun, TextRunSlice};
-use gfx_traits::{LayerId, LayerType};
+use gfx_traits::{FragmentType, LayerId, LayerType, StackingContextId};
use incremental::{RECONSTRUCT_FLOW, RestyleDamage};
use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFragmentContext, InlineFragmentNodeInfo};
use inline::{InlineMetrics, LAST_FRAGMENT_OF_ELEMENT};
diff --git a/components/layout/inline.rs b/components/layout/inline.rs
index 4615b728335..5ad86e54e05 100644
--- a/components/layout/inline.rs
+++ b/components/layout/inline.rs
@@ -17,9 +17,10 @@ use flow::{self, BaseFlow, Flow, FlowClass, ForceNonfloatedFlag, IS_ABSOLUTELY_P
use flow_ref;
use fragment::SpecificFragmentInfo;
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow};
-use gfx::display_list::{OpaqueNode, StackingContext, StackingContextId};
+use gfx::display_list::{OpaqueNode, StackingContext};
use gfx::font::FontMetrics;
use gfx::font_context::FontContext;
+use gfx_traits::StackingContextId;
use incremental::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, RESOLVE_GENERATED_CONTENT};
use layout_debug;
use model::IntrinsicISizesContribution;
diff --git a/components/layout/layout_thread.rs b/components/layout/layout_thread.rs
index 2509394db5a..779a23fba82 100644
--- a/components/layout/layout_thread.rs
+++ b/components/layout/layout_thread.rs
@@ -21,14 +21,13 @@ use euclid::size::Size2D;
use flow::{self, Flow, ImmutableFlowUtils, MutableOwnedFlowUtils};
use flow_ref::{self, FlowRef};
use fnv::FnvHasher;
-use gfx::display_list::WebRenderImageInfo;
use gfx::display_list::{ClippingRegion, DisplayItemMetadata, DisplayList, LayerInfo};
-use gfx::display_list::{OpaqueNode, StackingContext, StackingContextId, StackingContextType};
+use gfx::display_list::{OpaqueNode, StackingContext, StackingContextType, WebRenderImageInfo};
use gfx::font;
use gfx::font_cache_thread::FontCacheThread;
use gfx::font_context;
use gfx::paint_thread::LayoutToPaintMsg;
-use gfx_traits::{color, Epoch, LayerId, ScrollPolicy};
+use gfx_traits::{color, Epoch, LayerId, ScrollPolicy, StackingContextId};
use heapsize::HeapSizeOf;
use incremental::LayoutDamageComputation;
use incremental::{REPAINT, STORE_OVERFLOW, REFLOW_OUT_OF_FLOW, REFLOW, REFLOW_ENTIRE_DOCUMENT};
@@ -52,8 +51,8 @@ use script::dom::node::OpaqueStyleAndLayoutData;
use script::layout_interface::{LayoutRPC, OffsetParentResponse, NodeOverflowResponse, MarginStyleResponse};
use script::layout_interface::{Msg, NewLayoutThreadInfo, Reflow, ReflowQueryType, ScriptReflow};
use script::reporter::CSSErrorReporter;
-use script_traits::ConstellationControlMsg;
-use script_traits::{LayoutControlMsg, LayoutMsg as ConstellationMsg};
+use script_traits::StackingContextScrollState;
+use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg};
use sequential;
use serde_json;
use std::borrow::ToOwned;
@@ -559,6 +558,11 @@ impl LayoutThread {
self.handle_request_helper(Msg::SetVisibleRects(new_visible_rects),
possibly_locked_rw_data)
},
+ Request::FromPipeline(LayoutControlMsg::SetStackingContextScrollStates(
+ new_scroll_states)) => {
+ self.handle_request_helper(Msg::SetStackingContextScrollStates(new_scroll_states),
+ possibly_locked_rw_data)
+ },
Request::FromPipeline(LayoutControlMsg::TickAnimations) => {
self.handle_request_helper(Msg::TickAnimations, possibly_locked_rw_data)
},
@@ -644,6 +648,10 @@ impl LayoutThread {
Msg::SetVisibleRects(new_visible_rects) => {
self.set_visible_rects(new_visible_rects, possibly_locked_rw_data);
}
+ Msg::SetStackingContextScrollStates(new_scroll_states) => {
+ self.set_stacking_context_scroll_states(new_scroll_states,
+ possibly_locked_rw_data);
+ }
Msg::ReapStyleAndLayoutData(dead_data) => {
unsafe {
self.handle_reap_style_and_layout_data(dead_data)
@@ -883,19 +891,18 @@ impl LayoutThread {
if flow::base(&**layout_root).restyle_damage.contains(REPAINT) ||
rw_data.display_list.is_none() {
- let mut root_stacking_context =
- StackingContext::new(StackingContextId::new(0),
- StackingContextType::Real,
- &Rect::zero(),
- &Rect::zero(),
- 0,
- filter::T::new(Vec::new()),
- mix_blend_mode::T::normal,
- Matrix4D::identity(),
- Matrix4D::identity(),
- true,
- false,
- None);
+ let mut root_stacking_context = StackingContext::new(StackingContextId::new(0),
+ StackingContextType::Real,
+ &Rect::zero(),
+ &Rect::zero(),
+ 0,
+ filter::T::new(Vec::new()),
+ mix_blend_mode::T::normal,
+ Matrix4D::identity(),
+ Matrix4D::identity(),
+ true,
+ false,
+ None);
let display_list_entries =
sequential::build_display_list_for_subtree(layout_root,
@@ -1264,6 +1271,19 @@ impl LayoutThread {
true
}
+ fn set_stacking_context_scroll_states<'a, 'b>(
+ &mut self,
+ new_scroll_states: Vec<StackingContextScrollState>,
+ _: &mut RwData<'a, 'b>) {
+ for new_scroll_state in &new_scroll_states {
+ if self.root_flow.is_some() && new_scroll_state.stacking_context_id.id() == 0 {
+ let _ = self.script_chan.send(ConstellationControlMsg::SetScrollState(
+ self.id,
+ new_scroll_state.scroll_offset));
+ }
+ }
+ }
+
fn tick_all_animations<'a, 'b>(&mut self, possibly_locked_rw_data: &mut RwData<'a, 'b>) {
let mut rw_data = possibly_locked_rw_data.lock();
self.tick_animations(&mut rw_data);
diff --git a/components/layout/list_item.rs b/components/layout/list_item.rs
index 9b44ed78640..d32c19d5c37 100644
--- a/components/layout/list_item.rs
+++ b/components/layout/list_item.rs
@@ -17,7 +17,8 @@ use flow::{Flow, FlowClass, OpaqueFlow};
use fragment::Overflow;
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, GeneratedContentInfo};
use generated_content;
-use gfx::display_list::{StackingContext, StackingContextId};
+use gfx::display_list::StackingContext;
+use gfx_traits::StackingContextId;
use incremental::RESOLVE_GENERATED_CONTENT;
use inline::InlineMetrics;
use std::sync::Arc;
diff --git a/components/layout/multicol.rs b/components/layout/multicol.rs
index a4e532c3b0a..09f0efd1130 100644
--- a/components/layout/multicol.rs
+++ b/components/layout/multicol.rs
@@ -15,7 +15,8 @@ use floats::FloatKind;
use flow::{Flow, FlowClass, OpaqueFlow, mut_base, FragmentationContext};
use flow_ref::{self, FlowRef};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
-use gfx::display_list::{StackingContext, StackingContextId};
+use gfx::display_list::StackingContext;
+use gfx_traits::StackingContextId;
use std::cmp::{min, max};
use std::fmt;
use std::sync::Arc;
diff --git a/components/layout/table.rs b/components/layout/table.rs
index 9ed0dfd02d7..5b7f26eb9d9 100644
--- a/components/layout/table.rs
+++ b/components/layout/table.rs
@@ -16,7 +16,8 @@ use flow;
use flow::{BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow};
use flow_list::MutFlowListIterator;
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
-use gfx::display_list::{StackingContext, StackingContextId};
+use gfx::display_list::StackingContext;
+use gfx_traits::StackingContextId;
use incremental::{REFLOW, REFLOW_OUT_OF_FLOW};
use layout_debug;
use model::{IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto};
diff --git a/components/layout/table_caption.rs b/components/layout/table_caption.rs
index 2f26e7ea2ae..1c24491d06d 100644
--- a/components/layout/table_caption.rs
+++ b/components/layout/table_caption.rs
@@ -13,7 +13,8 @@ use display_list_builder::DisplayListBuildState;
use euclid::Point2D;
use flow::{Flow, FlowClass, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
-use gfx::display_list::{StackingContext, StackingContextId};
+use gfx::display_list::StackingContext;
+use gfx_traits::StackingContextId;
use std::fmt;
use std::sync::Arc;
use style::logical_geometry::LogicalSize;
diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs
index 06cb1e31ecc..a579ecb6c12 100644
--- a/components/layout/table_cell.rs
+++ b/components/layout/table_cell.rs
@@ -14,7 +14,8 @@ use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode, Dis
use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
use flow::{self, Flow, FlowClass, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
-use gfx::display_list::{StackingContext, StackingContextId};
+use gfx::display_list::StackingContext;
+use gfx_traits::StackingContextId;
use incremental::REFLOW;
use layout_debug;
use model::MaybeAuto;
diff --git a/components/layout/table_colgroup.rs b/components/layout/table_colgroup.rs
index 86192f75c52..6dce7bd56d1 100644
--- a/components/layout/table_colgroup.rs
+++ b/components/layout/table_colgroup.rs
@@ -12,7 +12,8 @@ use display_list_builder::DisplayListBuildState;
use euclid::Point2D;
use flow::{BaseFlow, Flow, FlowClass, ForceNonfloatedFlag, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow, SpecificFragmentInfo};
-use gfx::display_list::{StackingContext, StackingContextId};
+use gfx::display_list::StackingContext;
+use gfx_traits::StackingContextId;
use layout_debug;
use std::cmp::max;
use std::fmt;
diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs
index ca5b5133984..42257ec5a76 100644
--- a/components/layout/table_row.rs
+++ b/components/layout/table_row.rs
@@ -15,7 +15,8 @@ use euclid::Point2D;
use flow::{self, EarlyAbsolutePositionInfo, Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow};
use flow_list::MutFlowListIterator;
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
-use gfx::display_list::{StackingContext, StackingContextId};
+use gfx::display_list::StackingContext;
+use gfx_traits::StackingContextId;
use layout_debug;
use model::MaybeAuto;
use rustc_serialize::{Encodable, Encoder};
diff --git a/components/layout/table_rowgroup.rs b/components/layout/table_rowgroup.rs
index 202d604a758..e7e3e2fa938 100644
--- a/components/layout/table_rowgroup.rs
+++ b/components/layout/table_rowgroup.rs
@@ -13,7 +13,8 @@ use display_list_builder::DisplayListBuildState;
use euclid::Point2D;
use flow::{Flow, FlowClass, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
-use gfx::display_list::{StackingContext, StackingContextId};
+use gfx::display_list::StackingContext;
+use gfx_traits::StackingContextId;
use layout_debug;
use rustc_serialize::{Encodable, Encoder};
use std::fmt;
diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs
index 99bd3d29b64..9b3b6f5c062 100644
--- a/components/layout/table_wrapper.rs
+++ b/components/layout/table_wrapper.rs
@@ -22,7 +22,8 @@ use euclid::Point2D;
use floats::FloatKind;
use flow::{Flow, FlowClass, ImmutableFlowUtils, INLINE_POSITION_IS_STATIC, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
-use gfx::display_list::{StackingContext, StackingContextId};
+use gfx::display_list::StackingContext;
+use gfx_traits::StackingContextId;
use model::MaybeAuto;
use std::cmp::{max, min};
use std::fmt;
diff --git a/components/layout/webrender_helpers.rs b/components/layout/webrender_helpers.rs
index 59329147bcb..d7fd26513e5 100644
--- a/components/layout/webrender_helpers.rs
+++ b/components/layout/webrender_helpers.rs
@@ -11,13 +11,13 @@ use app_units::Au;
use azure::azure_hl::Color;
use euclid::{Point2D, Rect, Size2D};
use gfx::display_list::{BorderRadii, BoxShadowClipMode, ClippingRegion};
-use gfx::display_list::{DisplayItem, DisplayList};
-use gfx::display_list::{DisplayListTraversal, GradientStop, StackingContext, StackingContextType};
-use gfx_traits::ScrollPolicy;
+use gfx::display_list::{DisplayItem, DisplayList, DisplayListTraversal};
+use gfx::display_list::{GradientStop, StackingContext, StackingContextType};
+use gfx_traits::{FragmentType, ScrollPolicy, StackingContextId};
use style::computed_values::filter::{self, Filter};
use style::computed_values::{image_rendering, mix_blend_mode};
use style::values::computed::BorderStyle;
-use webrender_traits::{self, AuxiliaryListsBuilder, DisplayListId, PipelineId, StackingContextId};
+use webrender_traits::{self, AuxiliaryListsBuilder, DisplayListId, PipelineId};
trait WebRenderStackingContextConverter {
fn convert_to_webrender<'a>(&self,
@@ -315,8 +315,11 @@ impl WebRenderStackingContextConverter for StackingContext {
ScrollPolicy::FixedPosition => webrender_traits::ScrollPolicy::Fixed,
};
+ let webrender_stacking_context_id = self.id.convert_to_webrender();
+
let mut sc =
- webrender_traits::StackingContext::new(scroll_layer_id,
+ webrender_traits::StackingContext::new(webrender_stacking_context_id,
+ scroll_layer_id,
webrender_scroll_policy,
self.bounds.to_rectf(),
self.overflow.to_rectf(),
@@ -514,7 +517,8 @@ impl WebRenderDisplayItemConverter for DisplayItem {
}
pub struct WebRenderFrameBuilder {
- pub stacking_contexts: Vec<(StackingContextId, webrender_traits::StackingContext)>,
+ pub stacking_contexts: Vec<(webrender_traits::StackingContextId,
+ webrender_traits::StackingContext)>,
pub display_lists: Vec<(DisplayListId, webrender_traits::BuiltDisplayList)>,
pub auxiliary_lists_builder: AuxiliaryListsBuilder,
pub root_pipeline_id: PipelineId,
@@ -536,7 +540,7 @@ impl WebRenderFrameBuilder {
api: &mut webrender_traits::RenderApi,
pipeline_id: PipelineId,
stacking_context: webrender_traits::StackingContext)
- -> StackingContextId {
+ -> webrender_traits::StackingContextId {
assert!(pipeline_id == self.root_pipeline_id);
let id = api.next_stacking_context_id();
self.stacking_contexts.push((id, stacking_context));
@@ -561,5 +565,32 @@ impl WebRenderFrameBuilder {
self.next_scroll_layer_id += 1;
webrender_traits::ScrollLayerId::new(self.root_pipeline_id, scroll_layer_id)
}
+}
+
+trait WebRenderStackingContextIdConverter {
+ fn convert_to_webrender(&self) -> webrender_traits::ServoStackingContextId;
+}
+
+impl WebRenderStackingContextIdConverter for StackingContextId {
+ fn convert_to_webrender(&self) -> webrender_traits::ServoStackingContextId {
+ webrender_traits::ServoStackingContextId(self.fragment_type().convert_to_webrender(),
+ self.id())
+ }
+}
+trait WebRenderFragmentTypeConverter {
+ fn convert_to_webrender(&self) -> webrender_traits::FragmentType;
}
+
+impl WebRenderFragmentTypeConverter for FragmentType {
+ fn convert_to_webrender(&self) -> webrender_traits::FragmentType {
+ match *self {
+ FragmentType::FragmentBody => webrender_traits::FragmentType::FragmentBody,
+ FragmentType::BeforePseudoContent => {
+ webrender_traits::FragmentType::BeforePseudoContent
+ }
+ FragmentType::AfterPseudoContent => webrender_traits::FragmentType::AfterPseudoContent,
+ }
+ }
+}
+
diff --git a/components/profile/time.rs b/components/profile/time.rs
index f45e7df8c71..6271c8745e1 100644
--- a/components/profile/time.rs
+++ b/components/profile/time.rs
@@ -143,6 +143,7 @@ impl Formattable for ProfilerCategory {
ProfilerCategory::ScriptResize => "Script Resize",
ProfilerCategory::ScriptEvent => "Script Event",
ProfilerCategory::ScriptUpdateReplacedElement => "Script Update Replaced Element",
+ ProfilerCategory::ScriptSetScrollState => "Script Set Scroll State",
ProfilerCategory::ScriptSetViewport => "Script Set Viewport",
ProfilerCategory::ScriptTimerEvent => "Script Timer Event",
ProfilerCategory::ScriptStylesheetLoad => "Script Stylesheet Load",
diff --git a/components/profile_traits/time.rs b/components/profile_traits/time.rs
index 5d9a95ddd60..4083f3f3c14 100644
--- a/components/profile_traits/time.rs
+++ b/components/profile_traits/time.rs
@@ -73,6 +73,7 @@ pub enum ProfilerCategory {
ScriptParseHTML,
ScriptPlannedNavigation,
ScriptResize,
+ ScriptSetScrollState,
ScriptSetViewport,
ScriptTimerEvent,
ScriptStylesheetLoad,
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index 4862cb83c9e..3d6695986ae 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -995,13 +995,18 @@ impl Window {
};
// TODO (farodin91): Raise an event to stop the current_viewport
- let size = self.current_viewport.get().size;
- self.current_viewport.set(Rect::new(Point2D::new(Au::from_f32_px(x), Au::from_f32_px(y)), size));
+ self.update_viewport_for_scroll(x, y);
let message = ConstellationMsg::ScrollFragmentPoint(self.pipeline(), layer_id, point, smooth);
self.constellation_chan.send(message).unwrap();
}
+ pub fn update_viewport_for_scroll(&self, x: f32, y: f32) {
+ let size = self.current_viewport.get().size;
+ let new_viewport = Rect::new(Point2D::new(Au::from_f32_px(x), Au::from_f32_px(y)), size);
+ self.current_viewport.set(new_viewport)
+ }
+
pub fn client_window(&self) -> (Size2D<u32>, Point2D<i32>) {
let (send, recv) = ipc::channel::<(Size2D<u32>, Point2D<i32>)>().unwrap();
self.constellation_chan.send(ConstellationMsg::GetClientWindow(send)).unwrap();
diff --git a/components/script/layout_interface.rs b/components/script/layout_interface.rs
index b0327305665..29dff179525 100644
--- a/components/script/layout_interface.rs
+++ b/components/script/layout_interface.rs
@@ -15,8 +15,8 @@ use ipc_channel::ipc::{IpcReceiver, IpcSender};
use msg::constellation_msg::{PanicMsg, PipelineId, WindowSizeData};
use net_traits::image_cache_thread::ImageCacheThread;
use profile_traits::mem::ReportsChan;
-use script_traits::UntrustedNodeAddress;
use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg};
+use script_traits::{StackingContextScrollState, UntrustedNodeAddress};
use std::sync::Arc;
use std::sync::mpsc::{Receiver, Sender};
use string_cache::Atom;
@@ -85,6 +85,9 @@ pub enum Msg {
/// Set the final Url.
SetFinalUrl(Url),
+
+ /// Tells layout about the new scrolling offsets of each scrollable stacking context.
+ SetStackingContextScrollStates(Vec<StackingContextScrollState>),
}
/// Synchronous messages that script can send to layout.
diff --git a/components/script/script_runtime.rs b/components/script/script_runtime.rs
index 543574ccc62..061b80502b8 100644
--- a/components/script/script_runtime.rs
+++ b/components/script/script_runtime.rs
@@ -62,6 +62,7 @@ pub enum ScriptThreadEventCategory {
NetworkEvent,
Resize,
ScriptEvent,
+ SetScrollState,
SetViewport,
StylesheetLoad,
TimerEvent,
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index 20a8602a249..b913c5bbae0 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -708,6 +708,11 @@ impl ScriptThread {
self.handle_viewport(id, rect);
})
}
+ FromConstellation(ConstellationControlMsg::SetScrollState(id, scroll_offset)) => {
+ self.profile_event(ScriptThreadEventCategory::SetScrollState, || {
+ self.handle_set_scroll_state(id, &scroll_offset);
+ })
+ }
FromConstellation(ConstellationControlMsg::TickAllAnimations(
pipeline_id)) => {
if !animation_ticks.contains(&pipeline_id) {
@@ -850,6 +855,9 @@ impl ScriptThread {
ScriptThreadEventCategory::NetworkEvent => ProfilerCategory::ScriptNetworkEvent,
ScriptThreadEventCategory::Resize => ProfilerCategory::ScriptResize,
ScriptThreadEventCategory::ScriptEvent => ProfilerCategory::ScriptEvent,
+ ScriptThreadEventCategory::SetScrollState => {
+ ProfilerCategory::ScriptSetScrollState
+ }
ScriptThreadEventCategory::UpdateReplacedElement => {
ProfilerCategory::ScriptUpdateReplacedElement
}
@@ -877,6 +885,8 @@ impl ScriptThread {
self.handle_resize_inactive_msg(id, new_size),
ConstellationControlMsg::Viewport(..) =>
panic!("should have handled Viewport already"),
+ ConstellationControlMsg::SetScrollState(..) =>
+ panic!("should have handled SetScrollState already"),
ConstellationControlMsg::Resize(..) =>
panic!("should have handled Resize already"),
ConstellationControlMsg::ExitPipeline(..) =>
@@ -1077,6 +1087,19 @@ impl ScriptThread {
panic!("Page rect message sent to nonexistent pipeline");
}
+ fn handle_set_scroll_state(&self, id: PipelineId, scroll_state: &Point2D<f32>) {
+ let context = self.browsing_context.get();
+ if let Some(context) = context {
+ if let Some(inner_context) = context.find(id) {
+ let window = inner_context.active_window();
+ window.update_viewport_for_scroll(-scroll_state.x, -scroll_state.y);
+ return
+ }
+ }
+
+ panic!("Set scroll state message message sent to nonexistent pipeline: {:?}", id);
+ }
+
fn handle_new_layout(&self, new_layout_info: NewLayoutInfo) {
let NewLayoutInfo {
containing_pipeline_id,
diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs
index 529fc6ad715..da9c49f8834 100644
--- a/components/script_traits/lib.rs
+++ b/components/script_traits/lib.rs
@@ -39,6 +39,7 @@ use euclid::point::Point2D;
use euclid::rect::Rect;
use gfx_traits::Epoch;
use gfx_traits::LayerId;
+use gfx_traits::StackingContextId;
use ipc_channel::ipc::{IpcReceiver, IpcSender};
use libc::c_void;
use msg::constellation_msg::{FrameId, FrameType, Key, KeyModifiers, KeyState, LoadData};
@@ -76,6 +77,8 @@ pub enum LayoutControlMsg {
TickAnimations,
/// Informs layout as to which regions of the page are visible.
SetVisibleRects(Vec<(LayerId, Rect<Au>)>),
+ /// Tells layout about the new scrolling offsets of each scrollable stacking context.
+ SetStackingContextScrollStates(Vec<StackingContextScrollState>),
/// Requests the current load state of Web fonts. `true` is returned if fonts are still loading
/// and `false` is returned if all fonts have loaded.
GetWebFontLoadState(IpcSender<bool>),
@@ -122,6 +125,8 @@ pub enum ConstellationControlMsg {
SendEvent(PipelineId, CompositorEvent),
/// Notifies script of the viewport.
Viewport(PipelineId, Rect<f32>),
+ /// Notifies script of a new scroll offset.
+ SetScrollState(PipelineId, Point2D<f32>),
/// Requests that the script thread immediately send the constellation the title of a pipeline.
GetTitle(PipelineId),
/// Notifies script thread to suspend all its timers
@@ -463,6 +468,15 @@ pub enum AnimationTickType {
Layout,
}
+/// The scroll state of a stacking context.
+#[derive(Copy, Clone, Debug, Deserialize, Serialize)]
+pub struct StackingContextScrollState {
+ /// The ID of the stacking context.
+ pub stacking_context_id: StackingContextId,
+ /// The scrolling offset of this stacking context.
+ pub scroll_offset: Point2D<f32>,
+}
+
/// Messages to the constellation.
#[derive(Deserialize, Serialize)]
pub enum ConstellationMsg {
diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock
index 53875b3957c..b2ebec2e9cc 100644
--- a/components/servo/Cargo.lock
+++ b/components/servo/Cargo.lock
@@ -2517,7 +2517,7 @@ dependencies = [
[[package]]
name = "webrender"
version = "0.1.0"
-source = "git+https://github.com/servo/webrender#02bfa59b3f15145cfc559684deba8153dc33a5af"
+source = "git+https://github.com/servo/webrender#4ee826b19c23e63ecab7f5a8d0a68faa1f05b70c"
dependencies = [
"app_units 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2540,7 +2540,7 @@ dependencies = [
[[package]]
name = "webrender_traits"
version = "0.1.0"
-source = "git+https://github.com/servo/webrender_traits#f74a744614b4c0c2fc64d39916386848124f4d52"
+source = "git+https://github.com/servo/webrender_traits#e4cbde9880d118e50de425d37bd93d4e7c866e44"
dependencies = [
"app_units 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock
index 9029fa2cbfd..0925f658c70 100644
--- a/ports/cef/Cargo.lock
+++ b/ports/cef/Cargo.lock
@@ -2378,7 +2378,7 @@ dependencies = [
[[package]]
name = "webrender"
version = "0.1.0"
-source = "git+https://github.com/servo/webrender#02bfa59b3f15145cfc559684deba8153dc33a5af"
+source = "git+https://github.com/servo/webrender#4ee826b19c23e63ecab7f5a8d0a68faa1f05b70c"
dependencies = [
"app_units 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2401,7 +2401,7 @@ dependencies = [
[[package]]
name = "webrender_traits"
version = "0.1.0"
-source = "git+https://github.com/servo/webrender_traits#f74a744614b4c0c2fc64d39916386848124f4d52"
+source = "git+https://github.com/servo/webrender_traits#e4cbde9880d118e50de425d37bd93d4e7c866e44"
dependencies = [
"app_units 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json
index 05e8dc4ad7e..7fabf3c762c 100644
--- a/tests/wpt/mozilla/meta/MANIFEST.json
+++ b/tests/wpt/mozilla/meta/MANIFEST.json
@@ -6874,6 +6874,12 @@
"url": "/_mozilla/mozilla/script_type.html"
}
],
+ "mozilla/scrollTo.html": [
+ {
+ "path": "mozilla/scrollTo.html",
+ "url": "/_mozilla/mozilla/scrollTo.html"
+ }
+ ],
"mozilla/send-arraybuffer.htm": [
{
"path": "mozilla/send-arraybuffer.htm",
diff --git a/tests/wpt/mozilla/tests/mozilla/scrollTo.html b/tests/wpt/mozilla/tests/mozilla/scrollTo.html
new file mode 100644
index 00000000000..f1b4384e63b
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/scrollTo.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<meta charset="utf-8">
+<title></title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(function() {
+ scrollTo(0, 5000);
+ assert_equals(scrollX, 0);
+ assert_equals(pageXOffset, 0);
+ assert_equals(scrollY, 5000);
+ assert_equals(pageYOffset, 5000);
+
+ scrollTo(5000, 0);
+ assert_equals(scrollX, 5000);
+ assert_equals(pageXOffset, 5000);
+ assert_equals(scrollY, 0);
+ assert_equals(pageYOffset, 0);
+});
+</script>
+<div style="position: absolute; top: 0; left: 0; width: 10000px; height: 10000px; background: purple"></div>