mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
element scroll setters
This commit is contained in:
parent
fefdaf76de
commit
11b12f677b
8 changed files with 364 additions and 41 deletions
|
@ -20,6 +20,7 @@ use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementM
|
|||
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::Bindings::WindowBinding::{ScrollBehavior, ScrollToOptions};
|
||||
use dom::bindings::codegen::UnionTypes::NodeOrString;
|
||||
use dom::bindings::error::{Error, ErrorResult, Fallible};
|
||||
use dom::bindings::global::GlobalRef;
|
||||
|
@ -1227,6 +1228,49 @@ impl Element {
|
|||
_ => Err(Error::Syntax)
|
||||
}
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-element-scroll
|
||||
pub fn scroll(&self, x_: f64, y_: f64, behavior: ScrollBehavior) {
|
||||
|
||||
// Step 1.2 or 2.3
|
||||
let x = if x_.is_finite() { x_ } else { 0.0f64 };
|
||||
let y = if y_.is_finite() { y_ } else { 0.0f64 };
|
||||
|
||||
let node = self.upcast::<Node>();
|
||||
|
||||
// Step 3
|
||||
let doc = node.owner_doc();
|
||||
|
||||
// Step 4
|
||||
if !doc.is_fully_active() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 5
|
||||
let win = doc.DefaultView();
|
||||
|
||||
// Step 7
|
||||
if *self.root_element() == *self {
|
||||
if doc.quirks_mode() != Quirks {
|
||||
win.scroll(x, y, behavior);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 9
|
||||
if doc.GetBody().r() == self.downcast::<HTMLElement>() &&
|
||||
doc.quirks_mode() == Quirks &&
|
||||
!self.potentially_scrollable() {
|
||||
win.scroll(x, y, behavior);
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 10 (TODO)
|
||||
|
||||
// Step 11
|
||||
win.scroll_node(node.to_trusted_node_address(), x, y, behavior);
|
||||
}
|
||||
}
|
||||
|
||||
impl ElementMethods for Element {
|
||||
|
@ -1483,66 +1527,218 @@ impl ElementMethods for Element {
|
|||
rect.size.height.to_f64_px())
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-element-scroll
|
||||
fn Scroll(&self, options: &ScrollToOptions) {
|
||||
// Step 1
|
||||
let left = options.left.unwrap_or(self.ScrollLeft());
|
||||
let top = options.top.unwrap_or(self.ScrollTop());
|
||||
self.scroll(left, top, options.parent.behavior);
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-element-scroll
|
||||
fn Scroll_(&self, x: f64, y: f64) {
|
||||
self.scroll(x, y, ScrollBehavior::Auto);
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrollto
|
||||
fn ScrollTo(&self, options: &ScrollToOptions) {
|
||||
self.Scroll(options);
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrollto
|
||||
fn ScrollTo_(&self, x: f64, y: f64) {
|
||||
self.Scroll_(x, y);
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrollby
|
||||
fn ScrollBy(&self, options: &ScrollToOptions) {
|
||||
// Step 2
|
||||
let delta_left = options.left.unwrap_or(0.0f64);
|
||||
let delta_top = options.top.unwrap_or(0.0f64);
|
||||
let left = self.ScrollLeft();
|
||||
let top = self.ScrollTop();
|
||||
self.scroll(left + delta_left, top + delta_top,
|
||||
options.parent.behavior);
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrollby
|
||||
fn ScrollBy_(&self, x: f64, y: f64) {
|
||||
let left = self.ScrollLeft();
|
||||
let top = self.ScrollTop();
|
||||
self.scroll(left + x, top + y, ScrollBehavior::Auto);
|
||||
}
|
||||
|
||||
// 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.
|
||||
// Step 1
|
||||
let doc = node.owner_doc();
|
||||
|
||||
// 2. If the document is not the active document, return zero and terminate these steps.
|
||||
// Step 2
|
||||
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;
|
||||
}
|
||||
// Step 3
|
||||
let win = doc.DefaultView();
|
||||
|
||||
// 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() {
|
||||
// Step 5
|
||||
if *self.root_element() == *self {
|
||||
if doc.quirks_mode() == Quirks {
|
||||
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;
|
||||
// Step 6
|
||||
return win.ScrollY() as f64;
|
||||
}
|
||||
|
||||
// Step 7
|
||||
if doc.GetBody().r() == self.downcast::<HTMLElement>() &&
|
||||
doc.quirks_mode() == Quirks &&
|
||||
!self.potentially_scrollable() {
|
||||
return win.ScrollY() as f64;
|
||||
}
|
||||
|
||||
|
||||
// Step 8
|
||||
if !self.has_css_layout_box() {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
// Step 9
|
||||
let point = node.scroll_offset();
|
||||
return point.y.abs() as f64;
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrolltop
|
||||
fn SetScrollTop(&self, _scroll_top: f64) {
|
||||
unimplemented!()
|
||||
fn SetScrollTop(&self, y_: f64) {
|
||||
let behavior = ScrollBehavior::Auto;
|
||||
|
||||
// Step 1, 2
|
||||
let y = if y_.is_finite() { y_ } else { 0.0f64 };
|
||||
|
||||
let node = self.upcast::<Node>();
|
||||
|
||||
// Step 3
|
||||
let doc = node.owner_doc();
|
||||
|
||||
// Step 4
|
||||
if !doc.is_fully_active() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 5
|
||||
let win = doc.DefaultView();
|
||||
|
||||
// Step 7
|
||||
if *self.root_element() == *self {
|
||||
if doc.quirks_mode() != Quirks {
|
||||
win.scroll(win.ScrollX() as f64, y, behavior);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 9
|
||||
if doc.GetBody().r() == self.downcast::<HTMLElement>() &&
|
||||
doc.quirks_mode() == Quirks &&
|
||||
!self.potentially_scrollable() {
|
||||
win.scroll(win.ScrollX() as f64, y, behavior);
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 10 (TODO)
|
||||
|
||||
// Step 11
|
||||
win.scroll_node(node.to_trusted_node_address(), self.ScrollLeft(), y, behavior);
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrollleft
|
||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrolltop
|
||||
fn ScrollLeft(&self) -> f64 {
|
||||
let point = self.upcast::<Node>().scroll_offset();
|
||||
return -point.x as f64;
|
||||
let node = self.upcast::<Node>();
|
||||
|
||||
// Step 1
|
||||
let doc = node.owner_doc();
|
||||
|
||||
// Step 2
|
||||
if !doc.is_fully_active() {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
// Step 3
|
||||
let win = doc.DefaultView();
|
||||
|
||||
// Step 5
|
||||
if *self.root_element() == *self {
|
||||
if doc.quirks_mode() != Quirks {
|
||||
// Step 6
|
||||
return win.ScrollX() as f64;
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
// Step 7
|
||||
if doc.GetBody().r() == self.downcast::<HTMLElement>() &&
|
||||
doc.quirks_mode() == Quirks &&
|
||||
!self.potentially_scrollable() {
|
||||
return win.ScrollX() as f64;
|
||||
}
|
||||
|
||||
|
||||
// Step 8
|
||||
if !self.has_css_layout_box() {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
// Step 9
|
||||
let point = node.scroll_offset();
|
||||
return point.x.abs() as f64;
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrollleft
|
||||
fn SetScrollLeft(&self, _scroll_left: f64) {
|
||||
unimplemented!()
|
||||
fn SetScrollLeft(&self, x_: f64) {
|
||||
let behavior = ScrollBehavior::Auto;
|
||||
|
||||
// Step 1, 2
|
||||
let x = if x_.is_finite() { x_ } else { 0.0f64 };
|
||||
|
||||
let node = self.upcast::<Node>();
|
||||
|
||||
// Step 3
|
||||
let doc = node.owner_doc();
|
||||
|
||||
// Step 4
|
||||
if !doc.is_fully_active() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 5
|
||||
let win = doc.DefaultView();
|
||||
|
||||
// Step 7
|
||||
if *self.root_element() == *self {
|
||||
if doc.quirks_mode() == Quirks {
|
||||
return;
|
||||
}
|
||||
|
||||
win.scroll(x, win.ScrollY() as f64, behavior);
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 9
|
||||
if doc.GetBody().r() == self.downcast::<HTMLElement>() &&
|
||||
doc.quirks_mode() == Quirks &&
|
||||
!self.potentially_scrollable() {
|
||||
win.scroll(x, win.ScrollY() as f64, behavior);
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 10 (TODO)
|
||||
|
||||
// Step 11
|
||||
win.scroll_node(node.to_trusted_node_address(), x, self.ScrollTop(), behavior);
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrollwidth
|
||||
|
|
|
@ -81,6 +81,13 @@ partial interface Element {
|
|||
DOMRectList getClientRects();
|
||||
DOMRect getBoundingClientRect();
|
||||
|
||||
void scroll(optional ScrollToOptions options);
|
||||
void scroll(unrestricted double x, unrestricted double y);
|
||||
|
||||
void scrollTo(optional ScrollToOptions options);
|
||||
void scrollTo(unrestricted double x, unrestricted double y);
|
||||
void scrollBy(optional ScrollToOptions options);
|
||||
void scrollBy(unrestricted double x, unrestricted double y);
|
||||
attribute unrestricted double scrollTop;
|
||||
attribute unrestricted double scrollLeft;
|
||||
readonly attribute long scrollWidth;
|
||||
|
|
|
@ -912,11 +912,13 @@ impl Window {
|
|||
//TODO Step 11
|
||||
//let document = self.Document();
|
||||
// Step 12
|
||||
self.perform_a_scroll(x.to_f32().unwrap_or(0.0f32), y.to_f32().unwrap_or(0.0f32), behavior, None);
|
||||
self.perform_a_scroll(x.to_f32().unwrap_or(0.0f32), y.to_f32().unwrap_or(0.0f32),
|
||||
LayerId::null(), behavior, None);
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/cssom-view/#perform-a-scroll
|
||||
pub fn perform_a_scroll(&self, x: f32, y: f32, behavior: ScrollBehavior, element: Option<&Element>) {
|
||||
pub fn perform_a_scroll(&self, x: f32, y: f32, layer_id: LayerId,
|
||||
behavior: ScrollBehavior, element: Option<&Element>) {
|
||||
//TODO Step 1
|
||||
let point = Point2D::new(x, y);
|
||||
let smooth = match behavior {
|
||||
|
@ -935,7 +937,7 @@ impl Window {
|
|||
self.current_viewport.set(Rect::new(Point2D::new(Au::from_f32_px(x), Au::from_f32_px(y)), size));
|
||||
|
||||
self.compositor.send(ScriptToCompositorMsg::ScrollFragmentPoint(
|
||||
self.pipeline(), LayerId::null(), point, smooth)).unwrap()
|
||||
self.pipeline(), layer_id, point, smooth)).unwrap()
|
||||
}
|
||||
|
||||
pub fn client_window(&self) -> (Size2D<u32>, Point2D<i32>) {
|
||||
|
@ -1142,6 +1144,21 @@ impl Window {
|
|||
recv.recv().unwrap_or(Point2D::zero())
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-element-scroll
|
||||
pub fn scroll_node(&self, node: TrustedNodeAddress,
|
||||
x_: f64, y_: f64, behavior: ScrollBehavior) {
|
||||
|
||||
self.reflow(ReflowGoal::ForScriptQuery,
|
||||
ReflowQueryType::NodeLayerIdQuery(node),
|
||||
ReflowReason::Query);
|
||||
|
||||
let layer_id = self.layout_rpc.node_layer_id().layer_id;
|
||||
|
||||
// Step 12
|
||||
self.perform_a_scroll(x_.to_f32().unwrap_or(0.0f32), y_.to_f32().unwrap_or(0.0f32),
|
||||
layer_id, behavior, None);
|
||||
}
|
||||
|
||||
pub fn resolved_style_query(&self,
|
||||
element: TrustedNodeAddress,
|
||||
pseudo: Option<PseudoElement>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue