Auto merge of #6662 - tschneidereit:client-geometry, r=glennw,pcwatson

Implement Element.client{Top,Left,Width,Height}

This isn't done, but contains a working implementation of at least `clientTop`. Feedback would be much appreciated: it's probably far from ideal.

Implementing `clientLeft` is straight-forward, I think, but `clientWidth` and `clientHeight` require accessing the `border_box` - and I don't know how that works, yet.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/6662)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2015-07-27 20:45:05 -06:00
commit e0bd80f807
8 changed files with 217 additions and 1 deletions

View file

@ -1317,6 +1317,26 @@ impl<'a> ElementMethods for &'a Element {
rect.origin.x + rect.size.width)
}
fn ClientTop(self) -> i32 {
let node = NodeCast::from_ref(self);
node.get_client_rect().origin.y
}
fn ClientLeft(self) -> i32 {
let node = NodeCast::from_ref(self);
node.get_client_rect().origin.x
}
fn ClientWidth(self) -> i32 {
let node = NodeCast::from_ref(self);
node.get_client_rect().size.width
}
fn ClientHeight(self) -> i32 {
let node = NodeCast::from_ref(self);
node.get_client_rect().size.height
}
// https://dvcs.w3.org/hg/innerhtml/raw-file/tip/index.html#widl-Element-innerHTML
fn GetInnerHTML(self) -> Fallible<DOMString> {
//XXX TODO: XML case

View file

@ -492,6 +492,7 @@ pub trait NodeHelpers {
fn get_bounding_content_box(self) -> Rect<Au>;
fn get_content_boxes(self) -> Vec<Rect<Au>>;
fn get_client_rect(self) -> Rect<i32>;
fn before(self, nodes: Vec<NodeOrString>) -> ErrorResult;
fn after(self, nodes: Vec<NodeOrString>) -> ErrorResult;
@ -794,6 +795,10 @@ impl<'a> NodeHelpers for &'a Node {
window_from_node(self).r().content_boxes_query(self.to_trusted_node_address())
}
fn get_client_rect(self) -> Rect<i32> {
window_from_node(self).r().client_rect_query(self.to_trusted_node_address())
}
// https://dom.spec.whatwg.org/#dom-childnode-before
fn before(self, nodes: Vec<NodeOrString>) -> ErrorResult {
match self.parent_node.get() {

View file

@ -59,6 +59,11 @@ interface Element : Node {
partial interface Element {
DOMRectList getClientRects();
DOMRect getBoundingClientRect();
readonly attribute long clientTop;
readonly attribute long clientLeft;
readonly attribute long clientWidth;
readonly attribute long clientHeight;
};
// https://domparsing.spec.whatwg.org/#extensions-to-the-element-interface

View file

@ -540,6 +540,7 @@ pub trait WindowHelpers {
fn layout(&self) -> &LayoutRPC;
fn content_box_query(self, content_box_request: TrustedNodeAddress) -> Rect<Au>;
fn content_boxes_query(self, content_boxes_request: TrustedNodeAddress) -> Vec<Rect<Au>>;
fn client_rect_query(self, node_geometry_request: TrustedNodeAddress) -> Rect<i32>;
fn handle_reflow_complete_msg(self, reflow_id: u32);
fn set_fragment_name(self, fragment: Option<String>);
fn steal_fragment_name(self) -> Option<String>;
@ -771,6 +772,13 @@ impl<'a> WindowHelpers for &'a Window {
rects
}
fn client_rect_query(self, node_geometry_request: TrustedNodeAddress) -> Rect<i32> {
self.reflow(ReflowGoal::ForScriptQuery,
ReflowQueryType::NodeGeometryQuery(node_geometry_request),
ReflowReason::Query);
self.layout_rpc.node_geometry().client_rect
}
fn handle_reflow_complete_msg(self, reflow_id: u32) {
let last_reflow_id = self.last_reflow_id.get();
if last_reflow_id == reflow_id {
@ -1077,6 +1085,7 @@ fn debug_reflow_events(goal: &ReflowGoal, query_type: &ReflowQueryType, reason:
ReflowQueryType::NoQuery => "\tNoQuery",
ReflowQueryType::ContentBoxQuery(_n) => "\tContentBoxQuery",
ReflowQueryType::ContentBoxesQuery(_n) => "\tContentBoxesQuery",
ReflowQueryType::NodeGeometryQuery(_n) => "\tNodeGeometryQuery",
});
debug_msg.push_str(match *reason {

View file

@ -95,6 +95,8 @@ pub trait LayoutRPC {
fn content_box(&self) -> ContentBoxResponse;
/// Requests the dimensions of all the content boxes, as in the `getClientRects()` call.
fn content_boxes(&self) -> ContentBoxesResponse;
/// Requests the geometry of this node. Used by APIs such as `clientTop`.
fn node_geometry(&self) -> NodeGeometryResponse;
/// Requests the node containing the point of interest
fn hit_test(&self, node: TrustedNodeAddress, point: Point2D<f32>) -> Result<HitTestResponse, ()>;
fn mouse_over(&self, node: TrustedNodeAddress, point: Point2D<f32>) -> Result<MouseOverResponse, ()>;
@ -102,6 +104,9 @@ pub trait LayoutRPC {
pub struct ContentBoxResponse(pub Rect<Au>);
pub struct ContentBoxesResponse(pub Vec<Rect<Au>>);
pub struct NodeGeometryResponse {
pub client_rect: Rect<i32>,
}
pub struct HitTestResponse(pub UntrustedNodeAddress);
pub struct MouseOverResponse(pub Vec<UntrustedNodeAddress>);
@ -120,6 +125,7 @@ pub enum ReflowQueryType {
NoQuery,
ContentBoxQuery(TrustedNodeAddress),
ContentBoxesQuery(TrustedNodeAddress),
NodeGeometryQuery(TrustedNodeAddress),
}
/// Information needed for a reflow.