diff options
author | Zhen Zhang <izgzhen@gmail.com> | 2016-04-03 15:41:37 +0800 |
---|---|---|
committer | Zhen Zhang <izgzhen@gmail.com> | 2016-04-19 12:27:35 +0800 |
commit | fefdaf76ded7675c0c67fd33f5abfbb5f74ac30f (patch) | |
tree | 90131ccb368cc04b279f82b085052ae4236495e2 | |
parent | f73c6143d5375db80fd2e0b7de96a99c78b5866b (diff) | |
download | servo-fefdaf76ded7675c0c67fd33f5abfbb5f74ac30f.tar.gz servo-fefdaf76ded7675c0c67fd33f5abfbb5f74ac30f.zip |
Implement ScrollTop and ScrollLeft getters:
Add new compositor message to get scroll_offset;
Add new layout query for computed value of overflow-x/y;
Implement layer_id method for ThreadSafeLayoutNode;
Add new layout query for layer_id;
Implement script interface for getting scrollTop and scrollLeft, as well as relavant helper functions.
-rw-r--r-- | components/compositing/compositor.rs | 10 | ||||
-rw-r--r-- | components/compositing/compositor_thread.rs | 7 | ||||
-rw-r--r-- | components/layout/layout_thread.rs | 28 | ||||
-rw-r--r-- | components/layout/query.rs | 30 | ||||
-rw-r--r-- | components/layout/wrapper.rs | 16 | ||||
-rw-r--r-- | components/script/dom/element.rs | 95 | ||||
-rw-r--r-- | components/script/dom/node.rs | 6 | ||||
-rw-r--r-- | components/script/dom/webidls/Element.webidl | 2 | ||||
-rw-r--r-- | components/script/dom/window.rs | 22 | ||||
-rw-r--r-- | components/script/layout_interface.rs | 15 | ||||
-rw-r--r-- | components/script_traits/lib.rs | 2 | ||||
-rw-r--r-- | tests/html/simple-overflow-scroll.html | 19 |
12 files changed, 243 insertions, 9 deletions
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index 71528e8b88a..bfc2fa1abc6 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -714,6 +714,16 @@ impl<Window: WindowMethods> IOCompositor<Window> { let _ = sender.send(()); } + (Msg::GetScrollOffset(pipeline_id, layer_id, sender), ShutdownState::NotShuttingDown) => { + match self.find_layer_with_pipeline_and_layer_id(pipeline_id, layer_id) { + Some(ref layer) => { + let typed = layer.extra_data.borrow().scroll_offset; + let _ = sender.send(Point2D::new(typed.x.get(), typed.y.get())); + }, + None => {}, + } + } + // When we are shutting_down, we need to avoid performing operations // such as Paint that may crash because we have begun tearing down // the rest of our resources. diff --git a/components/compositing/compositor_thread.rs b/components/compositing/compositor_thread.rs index fdfd4c633bf..d624e0212a9 100644 --- a/components/compositing/compositor_thread.rs +++ b/components/compositing/compositor_thread.rs @@ -98,6 +98,10 @@ pub fn run_script_listener_thread(compositor_proxy: Box<CompositorProxy + 'stati compositor_proxy.send(Msg::TouchEventProcessed(result)) } + ScriptToCompositorMsg::GetScrollOffset(pid, lid, send) => { + compositor_proxy.send(Msg::GetScrollOffset(pid, lid, send)); + } + ScriptToCompositorMsg::Exited => break, } } @@ -231,6 +235,8 @@ pub enum Msg { MoveTo(Point2D<i32>), /// Resize the window to size ResizeTo(Size2D<u32>), + /// Get scroll offset of a layer + GetScrollOffset(PipelineId, LayerId, IpcSender<Point2D<f32>>), /// A pipeline was shut down. // This message acts as a synchronization point between the constellation, // when it shuts down a pipeline, to the compositor; when the compositor @@ -272,6 +278,7 @@ impl Debug for Msg { Msg::MoveTo(..) => write!(f, "MoveTo"), Msg::ResizeTo(..) => write!(f, "ResizeTo"), Msg::PipelineExited(..) => write!(f, "PipelineExited"), + Msg::GetScrollOffset(..) => write!(f, "GetScrollOffset"), } } } diff --git a/components/layout/layout_thread.rs b/components/layout/layout_thread.rs index d226188f698..3befa6b46cf 100644 --- a/components/layout/layout_thread.rs +++ b/components/layout/layout_thread.rs @@ -45,10 +45,11 @@ use profile_traits::mem::{self, Report, ReportKind, ReportsChan}; use profile_traits::time::{TimerMetadataFrameType, TimerMetadataReflowType}; use profile_traits::time::{self, TimerMetadata, profile}; use query::{LayoutRPCImpl, process_content_box_request, process_content_boxes_request}; -use query::{process_node_geometry_request, process_node_scroll_area_request, process_offset_parent_query}; -use query::{process_resolved_style_request, process_margin_style_query}; +use query::{process_node_geometry_request, process_node_layer_id_request, process_node_scroll_area_request}; +use query::{process_node_overflow_request, process_resolved_style_request, process_margin_style_query}; +use query::{process_offset_parent_query}; use script::dom::node::OpaqueStyleAndLayoutData; -use script::layout_interface::{LayoutRPC, OffsetParentResponse, MarginStyleResponse}; +use script::layout_interface::{LayoutRPC, OffsetParentResponse, NodeOverflowResponse, MarginStyleResponse}; use script::layout_interface::{Msg, NewLayoutThreadInfo, Reflow, ReflowQueryType}; use script::layout_interface::{ScriptLayoutChan, ScriptReflow}; use script::reporter::CSSErrorReporter; @@ -117,9 +118,14 @@ pub struct LayoutThreadData { /// A queued response for the client {top, left, width, height} of a node in pixels. pub client_rect_response: Rect<i32>, + pub layer_id_response: Option<LayerId>, + /// A queued response for the node at a given point pub hit_test_response: (Option<DisplayItemMetadata>, bool), + /// A pair of overflow property in x and y + pub overflow_response: NodeOverflowResponse, + /// A queued response for the scroll {top, left, width, height} of a node in pixels. pub scroll_area_response: Rect<i32>, @@ -463,8 +469,10 @@ impl LayoutThread { content_box_response: Rect::zero(), content_boxes_response: Vec::new(), client_rect_response: Rect::zero(), + layer_id_response: None, hit_test_response: (None, false), scroll_area_response: Rect::zero(), + overflow_response: NodeOverflowResponse(None), resolved_style_response: None, offset_parent_response: OffsetParentResponse::empty(), margin_style_response: MarginStyleResponse::empty(), @@ -1015,9 +1023,15 @@ impl LayoutThread { ReflowQueryType::NodeGeometryQuery(_) => { rw_data.client_rect_response = Rect::zero(); }, + ReflowQueryType::NodeLayerIdQuery(_) => { + rw_data.layer_id_response = None; + }, ReflowQueryType::NodeScrollGeometryQuery(_) => { rw_data.scroll_area_response = Rect::zero(); }, + ReflowQueryType::NodeOverflowQuery(_) => { + rw_data.overflow_response = NodeOverflowResponse(None); + }, ReflowQueryType::ResolvedStyleQuery(_, _, _) => { rw_data.resolved_style_response = None; }, @@ -1177,6 +1191,14 @@ impl LayoutThread { let node = unsafe { ServoLayoutNode::new(&node) }; rw_data.scroll_area_response = process_node_scroll_area_request(node, &mut root_flow); }, + ReflowQueryType::NodeOverflowQuery(node) => { + let node = unsafe { ServoLayoutNode::new(&node) }; + rw_data.overflow_response = process_node_overflow_request(node); + }, + ReflowQueryType::NodeLayerIdQuery(node) => { + let node = unsafe { ServoLayoutNode::new(&node) }; + rw_data.layer_id_response = Some(process_node_layer_id_request(node)); + }, ReflowQueryType::ResolvedStyleQuery(node, ref pseudo, ref property) => { let node = unsafe { ServoLayoutNode::new(&node) }; rw_data.resolved_style_response = diff --git a/components/layout/query.rs b/components/layout/query.rs index 1485e54f065..5b28acfa462 100644 --- a/components/layout/query.rs +++ b/components/layout/query.rs @@ -13,11 +13,12 @@ use flow; use flow_ref::FlowRef; use fragment::{Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo}; use gfx::display_list::OpaqueNode; +use gfx_traits::{LayerId}; use layout_thread::LayoutThreadData; use msg::constellation_msg::ConstellationChan; use opaque_node::OpaqueNodeMethods; -use script::layout_interface::{ContentBoxResponse, ContentBoxesResponse, NodeGeometryResponse}; -use script::layout_interface::{HitTestResponse, LayoutRPC, OffsetParentResponse}; +use script::layout_interface::{ContentBoxResponse, NodeOverflowResponse, ContentBoxesResponse, NodeGeometryResponse}; +use script::layout_interface::{HitTestResponse, LayoutRPC, OffsetParentResponse, NodeLayerIdResponse}; use script::layout_interface::{ResolvedStyleResponse, ScriptLayoutChan, MarginStyleResponse}; use script_traits::LayoutMsg as ConstellationMsg; use script_traits::UntrustedNodeAddress; @@ -112,12 +113,23 @@ impl LayoutRPC for LayoutRPCImpl { } } + fn node_overflow(&self) -> NodeOverflowResponse { + NodeOverflowResponse(self.0.lock().unwrap().overflow_response.0) + } + fn node_scroll_area(&self) -> NodeGeometryResponse { NodeGeometryResponse { client_rect: self.0.lock().unwrap().scroll_area_response } } + fn node_layer_id(&self) -> NodeLayerIdResponse { + NodeLayerIdResponse { + layer_id: self.0.lock().unwrap().layer_id_response + .expect("layer_id is not correctly fetched, see PR #9968") + } + } + /// Retrieves the resolved value for a CSS style property. fn resolved_style(&self) -> ResolvedStyleResponse { let &LayoutRPCImpl(ref rw_data) = self; @@ -425,6 +437,7 @@ impl FragmentBorderBoxIterator for UnioningFragmentScrollAreaIterator { let bottom_padding = (border_box.size.height - bottom_border - top_border).to_px(); let top_padding = top_border.to_px(); let left_padding = left_border.to_px(); + match self.level { Some(start_level) if level <= start_level => { self.is_child = false; } Some(_) => { @@ -517,6 +530,11 @@ pub fn process_node_geometry_request<N: LayoutNode>(requested_node: N, layout_ro iterator.client_rect } +pub fn process_node_layer_id_request<N: LayoutNode>(requested_node: N) -> LayerId { + let layout_node = requested_node.to_threadsafe(); + layout_node.layer_id() +} + pub fn process_node_scroll_area_request< N: LayoutNode>(requested_node: N, layout_root: &mut FlowRef) -> Rect<i32> { let mut iterator = UnioningFragmentScrollAreaIterator::new(requested_node.opaque()); @@ -691,6 +709,14 @@ pub fn process_offset_parent_query<N: LayoutNode>(requested_node: N, layout_root } } +pub fn process_node_overflow_request<N: LayoutNode>(requested_node: N) -> NodeOverflowResponse { + let layout_node = requested_node.to_threadsafe(); + let style = &*layout_node.style(); + let style_box = style.get_box(); + + NodeOverflowResponse(Some((Point2D::new(style_box.overflow_x, style_box.overflow_y.0)))) +} + pub fn process_margin_style_query<N: LayoutNode>(requested_node: N) -> MarginStyleResponse { let layout_node = requested_node.to_threadsafe(); diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index e76af843ea0..6bf95fad735 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -34,6 +34,7 @@ use core::nonzero::NonZero; use data::{LayoutDataFlags, PrivateLayoutData}; use gfx::display_list::OpaqueNode; use gfx::text::glyph::CharIndex; +use gfx_traits::{LayerId, LayerType}; use incremental::RestyleDamage; use msg::constellation_msg::PipelineId; use opaque_node::OpaqueNodeMethods; @@ -851,6 +852,21 @@ pub trait ThreadSafeLayoutNode : Clone + Copy + Sized + PartialEq { fn iframe_pipeline_id(&self) -> PipelineId; fn get_colspan(&self) -> u32; + + fn layer_id(&self) -> LayerId { + let layer_type = match self.get_pseudo_element_type() { + PseudoElementType::Normal => LayerType::FragmentBody, + PseudoElementType::Before(_) => LayerType::BeforePseudoContent, + PseudoElementType::After(_) => LayerType::AfterPseudoContent, + PseudoElementType::DetailsSummary(_) => LayerType::FragmentBody, + PseudoElementType::DetailsContent(_) => LayerType::FragmentBody, + }; + LayerId::new_of_type(layer_type, self.opaque().id() as usize) + } + + fn layer_id_for_overflow_scroll(&self) -> LayerId { + LayerId::new_of_type(LayerType::OverflowScroll, self.opaque().id() as usize) + } } // This trait is only public so that it can be implemented by the gecko wrapper. diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index e14e1af0d97..8fa454c0e73 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -19,6 +19,7 @@ use dom::bindings::codegen::Bindings::EventBinding::EventMethods; use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementMethods; use dom::bindings::codegen::Bindings::HTMLTemplateElementBinding::HTMLTemplateElementMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; +use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::codegen::UnionTypes::NodeOrString; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::global::GlobalRef; @@ -39,6 +40,7 @@ use dom::htmlanchorelement::HTMLAnchorElement; use dom::htmlbodyelement::{HTMLBodyElement, HTMLBodyElementLayoutHelpers}; use dom::htmlbuttonelement::HTMLButtonElement; use dom::htmlcollection::HTMLCollection; +use dom::htmlelement::HTMLElement; use dom::htmlfieldsetelement::HTMLFieldSetElement; use dom::htmlfontelement::{HTMLFontElement, HTMLFontElementLayoutHelpers}; use dom::htmlhrelement::{HTMLHRElement, HTMLHRLayoutHelpers}; @@ -86,7 +88,7 @@ use string_cache::{Atom, Namespace, QualName}; use style::element_state::*; use style::error_reporting::ParseErrorReporter; use style::properties::DeclaredValue; -use style::properties::longhands::{self, background_image, border_spacing, font_family, font_size}; +use style::properties::longhands::{self, background_image, border_spacing, font_family, overflow_x, font_size}; use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute}; use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl}; use style::values::CSSFloat; @@ -164,6 +166,35 @@ impl Element { document, ElementBinding::Wrap) } + + // https://drafts.csswg.org/cssom-view/#css-layout-box + // Elements that have a computed value of the display property + // that is table-column or table-column-group + // FIXME: Currently, it is assumed to be true always + fn has_css_layout_box(&self) -> bool { + true + } + + // https://drafts.csswg.org/cssom-view/#potentially-scrollable + fn potentially_scrollable(&self) -> bool { + self.has_css_layout_box() && + !self.overflow_x_is_visible() && + !self.overflow_y_is_visible() + } + + // used value of overflow-x is "visible" + fn overflow_x_is_visible(&self) -> bool { + let window = window_from_node(self); + let overflow_pair = window.overflow_query(self.upcast::<Node>().to_trusted_node_address()); + overflow_pair.x == overflow_x::computed_value::T::visible + } + + // used value of overflow-y is "visible" + fn overflow_y_is_visible(&self) -> bool { + let window = window_from_node(self); + let overflow_pair = window.overflow_query(self.upcast::<Node>().to_trusted_node_address()); + overflow_pair.y != overflow_x::computed_value::T::visible + } } #[allow(unsafe_code)] @@ -1452,6 +1483,68 @@ impl ElementMethods for Element { rect.size.height.to_f64_px()) } + // https://drafts.csswg.org/cssom-view/#dom-element-scrolltop + fn ScrollTop(&self) -> f64 { + let node = self.upcast::<Node>(); + + // 1. Let document be the element’s node document. + let doc = node.owner_doc(); + + // 2. If the document is not the active document, return zero and terminate these steps. + if !doc.is_fully_active() { + return 0.0; + } else { + // 3. Let window be the value of document’s defaultView attribute. + let win = doc.DefaultView(); + + // 5. If the element is the root element and document is in quirks mode, + // return zero and terminate these steps. + if *self.root_element() == *self { + if doc.quirks_mode() == Quirks { + return 0.0; + } + + // 6. If the element is the root element return the value of scrollY on window. + return (*win).ScrollY() as f64; + } + + // 7. If the element is the HTML body element, document is in quirks mode, + // and the element is not potentially scrollable, return the value of scrollY on window. + if doc.GetBody().r() == self.downcast::<HTMLElement>() && + doc.quirks_mode() == Quirks && + !self.potentially_scrollable() { + return (*win).ScrollY() as f64; + } + + + // 8. If the element does not have any associated CSS layout box, return zero and terminate these steps. + if !self.has_css_layout_box() { + return 0.0; + } + + // 9. Return the y-coordinate of the scrolling area at the alignment point + // with the top of the padding edge of the element. + let point = node.scroll_offset(); + return -point.y as f64; + } + } + + // https://drafts.csswg.org/cssom-view/#dom-element-scrolltop + fn SetScrollTop(&self, _scroll_top: f64) { + unimplemented!() + } + + // https://drafts.csswg.org/cssom-view/#dom-element-scrollleft + fn ScrollLeft(&self) -> f64 { + let point = self.upcast::<Node>().scroll_offset(); + return -point.x as f64; + } + + // https://drafts.csswg.org/cssom-view/#dom-element-scrollleft + fn SetScrollLeft(&self, _scroll_left: f64) { + unimplemented!() + } + // https://drafts.csswg.org/cssom-view/#dom-element-scrollwidth fn ScrollWidth(&self) -> i32 { self.upcast::<Node>().scroll_area().size.width diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 1e71966e4e7..d8c23b559d9 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -614,6 +614,12 @@ impl Node { } } + pub fn scroll_offset(&self) -> Point2D<f32> { + let document = self.owner_doc(); + let window = document.window(); + window.scroll_offset_query(self.to_trusted_node_address()) + } + // https://dom.spec.whatwg.org/#dom-childnode-before pub fn before(&self, nodes: Vec<NodeOrString>) -> ErrorResult { // Step 1. diff --git a/components/script/dom/webidls/Element.webidl b/components/script/dom/webidls/Element.webidl index 9bc5ff64597..b161a782a55 100644 --- a/components/script/dom/webidls/Element.webidl +++ b/components/script/dom/webidls/Element.webidl @@ -81,6 +81,8 @@ partial interface Element { DOMRectList getClientRects(); DOMRect getBoundingClientRect(); + attribute unrestricted double scrollTop; + attribute unrestricted double scrollLeft; readonly attribute long scrollWidth; readonly attribute long scrollHeight; diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 8a3affefe06..75c7089fac3 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -74,6 +74,7 @@ use std::sync::{Arc, Mutex}; use string_cache::Atom; use style::context::ReflowGoal; use style::error_reporting::ParseErrorReporter; +use style::properties::longhands::{overflow_x}; use style::selector_impl::PseudoElement; use task_source::TaskSource; use task_source::dom_manipulation::{DOMManipulationTaskSource, DOMManipulationTask}; @@ -1122,6 +1123,25 @@ impl Window { self.layout_rpc.node_scroll_area().client_rect } + pub fn overflow_query(&self, node: TrustedNodeAddress) -> Point2D<overflow_x::computed_value::T> { + self.reflow(ReflowGoal::ForScriptQuery, + ReflowQueryType::NodeOverflowQuery(node), + ReflowReason::Query); + self.layout_rpc.node_overflow().0.unwrap() + } + + pub fn scroll_offset_query(&self, node: TrustedNodeAddress) -> Point2D<f32> { + self.reflow(ReflowGoal::ForScriptQuery, + ReflowQueryType::NodeLayerIdQuery(node), + ReflowReason::Query); + let layer_id = self.layout_rpc.node_layer_id().layer_id; + let pipeline_id = self.id; + + let (send, recv) = ipc::channel::<Point2D<f32>>().unwrap(); + self.compositor.send(ScriptToCompositorMsg::GetScrollOffset(pipeline_id, layer_id, send)).unwrap(); + recv.recv().unwrap_or(Point2D::zero()) + } + pub fn resolved_style_query(&self, element: TrustedNodeAddress, pseudo: Option<PseudoElement>, @@ -1476,6 +1496,8 @@ fn debug_reflow_events(id: PipelineId, goal: &ReflowGoal, query_type: &ReflowQue ReflowQueryType::ContentBoxesQuery(_n) => "\tContentBoxesQuery", ReflowQueryType::HitTestQuery(_n, _o) => "\tHitTestQuery", ReflowQueryType::NodeGeometryQuery(_n) => "\tNodeGeometryQuery", + ReflowQueryType::NodeLayerIdQuery(_n) => "\tNodeLayerIdQuery", + ReflowQueryType::NodeOverflowQuery(_n) => "\tNodeOverFlowQuery", ReflowQueryType::NodeScrollGeometryQuery(_n) => "\tNodeScrollGeometryQuery", ReflowQueryType::ResolvedStyleQuery(_, _, _) => "\tResolvedStyleQuery", ReflowQueryType::OffsetParentQuery(_n) => "\tOffsetParentQuery", diff --git a/components/script/layout_interface.rs b/components/script/layout_interface.rs index 07d8ac47edc..945fdbcbc7c 100644 --- a/components/script/layout_interface.rs +++ b/components/script/layout_interface.rs @@ -23,7 +23,7 @@ use std::sync::Arc; use std::sync::mpsc::{Receiver, Sender, channel}; use string_cache::Atom; use style::context::ReflowGoal; -use style::properties::longhands::{margin_top, margin_right, margin_bottom, margin_left}; +use style::properties::longhands::{margin_top, margin_right, margin_bottom, margin_left, overflow_x}; use style::selector_impl::PseudoElement; use style::servo::Stylesheet; use url::Url; @@ -104,8 +104,12 @@ pub trait LayoutRPC { fn content_boxes(&self) -> ContentBoxesResponse; /// Requests the geometry of this node. Used by APIs such as `clientTop`. fn node_geometry(&self) -> NodeGeometryResponse; + /// Requests the overflow-x and overflow-y of this node. Used by `scrollTop` etc. + fn node_overflow(&self) -> NodeOverflowResponse; /// Requests the scroll geometry of this node. Used by APIs such as `scrollTop`. fn node_scroll_area(&self) -> NodeGeometryResponse; + /// Requests the layer id of this node. Used by APIs such as `scrollTop` + fn node_layer_id(&self) -> NodeLayerIdResponse; /// Requests the node containing the point of interest fn hit_test(&self) -> HitTestResponse; /// Query layout for the resolved value of a given CSS property @@ -136,6 +140,8 @@ impl MarginStyleResponse { } } +pub struct NodeOverflowResponse(pub Option<Point2D<overflow_x::computed_value::T>>); + pub struct ContentBoxResponse(pub Rect<Au>); pub struct ContentBoxesResponse(pub Vec<Rect<Au>>); pub struct HitTestResponse { @@ -144,6 +150,11 @@ pub struct HitTestResponse { pub struct NodeGeometryResponse { pub client_rect: Rect<i32>, } + +pub struct NodeLayerIdResponse { + pub layer_id: LayerId, +} + pub struct ResolvedStyleResponse(pub Option<String>); #[derive(Clone)] @@ -167,8 +178,10 @@ pub enum ReflowQueryType { NoQuery, ContentBoxQuery(TrustedNodeAddress), ContentBoxesQuery(TrustedNodeAddress), + NodeOverflowQuery(TrustedNodeAddress), HitTestQuery(Point2D<f32>, bool), NodeGeometryQuery(TrustedNodeAddress), + NodeLayerIdQuery(TrustedNodeAddress), NodeScrollGeometryQuery(TrustedNodeAddress), ResolvedStyleQuery(TrustedNodeAddress, Option<PseudoElement>, Atom), OffsetParentQuery(TrustedNodeAddress), diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index 7175536f280..4cd24234a0a 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -376,6 +376,8 @@ pub enum ScriptToCompositorMsg { ResizeTo(Size2D<u32>), /// Script has handled a touch event, and either prevented or allowed default actions. TouchEventProcessed(EventResult), + /// Get Scroll Offset + GetScrollOffset(PipelineId, LayerId, IpcSender<Point2D<f32>>), /// Requests that the compositor shut down. Exit, /// Allow the compositor to free script-specific resources. diff --git a/tests/html/simple-overflow-scroll.html b/tests/html/simple-overflow-scroll.html index 0df956eb905..b8544cfec38 100644 --- a/tests/html/simple-overflow-scroll.html +++ b/tests/html/simple-overflow-scroll.html @@ -17,8 +17,14 @@ nav { top: 16px; left: 16px; } +div { + width: 400px; +} + </style> -<nav></nav><section>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ultricies tortor eu augue eleifend malesuada. Duis id condimentum urna. Duis vulputate urna a dignissim sodales. Aenean et magna id dui rutrum suscipit. Etiam metus mauris, congue ac suscipit dapibus, mattis non neque. Donec porttitor eros sed mauris tristique, non condimentum augue feugiat. Suspendisse iaculis faucibus nunc at porttitor. Integer convallis enim in feugiat molestie. Ut eget tincidunt mi, vel malesuada lectus. Quisque fermentum neque a sapien interdum consectetur. Nam tincidunt leo sit amet tortor ornare, sit amet ultrices ante semper. Fusce malesuada mi vitae venenatis sagittis. Duis eget urna quam. +<nav></nav><section id="section"> + + <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ultricies tortor eu augue eleifend malesuada. Duis id condimentum urna. Duis vulputate urna a dignissim sodales. Aenean et magna id dui rutrum suscipit. Etiam metus mauris, congue ac suscipit dapibus, mattis non neque. Donec porttitor eros sed mauris tristique, non condimentum augue feugiat. Suspendisse iaculis faucibus nunc at porttitor. Integer convallis enim in feugiat molestie. Ut eget tincidunt mi, vel malesuada lectus. Quisque fermentum neque a sapien interdum consectetur. Nam tincidunt leo sit amet tortor ornare, sit amet ultrices ante semper. Fusce malesuada mi vitae venenatis sagittis. Duis eget urna quam. Sed lacinia aliquam tortor quis elementum. Cras vitae mauris erat. Vestibulum posuere justo et dolor condimentum feugiat. Sed at magna nunc. Suspendisse est nunc, ultrices sed enim lobortis, vulputate rutrum mauris. Fusce ultrices eget erat blandit porta. Sed eros nulla, tristique eget porta a, viverra vel velit. Praesent sit amet odio eleifend, tempor arcu ut, elementum tellus. Suspendisse lorem tortor, sodales eget nulla a, rhoncus lobortis magna. Phasellus purus ante, rhoncus a ipsum nec, condimentum lacinia purus. Cras lobortis posuere nisi, vitae dapibus ante feugiat et. Quisque ornare nisi quis erat congue viverra. Vestibulum a nunc odio. @@ -26,5 +32,14 @@ Sed id venenatis tortor. Curabitur sit amet mauris eget mi semper rutrum vel et Sed sed ante aliquam, rutrum nisl quis, fermentum tellus. Proin ac leo molestie, euismod mauris sed, consequat nunc. Vivamus ut leo a nunc pharetra accumsan a non lorem. Aliquam iaculis mattis augue, in eleifend est accumsan vel. Pellentesque efficitur pulvinar leo vel ornare. Pellentesque non fermentum enim, ut efficitur elit. Duis risus quam, congue vel nulla a, blandit egestas erat. Suspendisse at sodales dolor. Vivamus auctor, lorem et ultrices venenatis, erat ex mollis nisi, quis maximus libero quam a libero. -Curabitur elit lacus, bibendum non tempus a, bibendum sit amet ante. Mauris eget nibh quis leo rhoncus consequat. Integer iaculis sed sapien eu pellentesque. In aliquet elementum lorem, ut consequat elit ultrices id. Phasellus vestibulum ex ex, ac sagittis tortor convallis et. Curabitur placerat id lectus at aliquam. Morbi sed nisl sem. Nam sit amet arcu maximus, volutpat nisl ac, dignissim neque. Etiam nec efficitur libero. Quisque tristique pulvinar est, eget dictum ex vehicula non. Nam dignissim non felis a iaculis. Nullam vel dolor vitae libero aliquet congue. Donec mi eros, semper non lectus at, commodo ullamcorper ligula. Donec commodo, sem vel lacinia porttitor, elit orci maximus felis, eget eleifend est velit id lorem. +Curabitur elit lacus, bibendum non tempus a, bibendum sit amet ante. Mauris eget nibh quis leo rhoncus consequat. Integer iaculis sed sapien eu pellentesque. In aliquet elementum lorem, ut consequat elit ultrices id. Phasellus vestibulum ex ex, ac sagittis tortor convallis et. Curabitur placerat id lectus at aliquam. Morbi sed nisl sem. Nam sit amet arcu maximus, volutpat nisl ac, dignissim neque. Etiam nec efficitur libero. Quisque tristique pulvinar est, eget dictum ex vehicula non. Nam dignissim non felis a iaculis. Nullam vel dolor vitae libero aliquet congue. Donec mi eros, semper non lectus at, commodo ullamcorper ligula. Donec commodo, sem vel lacinia porttitor, elit orci maximus felis, eget eleifend est velit id lorem. + </div> +<script> +var section = document.getElementById("section"); + +window.setInterval(function () { + console.log("scrollTop: " + section.scrollTop); + console.log("scrollLeft: " + section.scrollLeft); +}, 1000); +</script> |