Skip to content

Commit

Permalink
Trigger reflow on document.elementsFromPoint
Browse files Browse the repository at this point in the history
  • Loading branch information
ferjm committed Mar 2, 2017
1 parent d0856fd commit 7426d90
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 33 deletions.
2 changes: 1 addition & 1 deletion components/layout/lib.rs
Expand Up @@ -73,7 +73,7 @@ mod linked_list;
mod list_item;
mod model;
mod multicol;
mod opaque_node;
pub mod opaque_node;
pub mod parallel;
mod persistent_list;
pub mod query;
Expand Down
38 changes: 9 additions & 29 deletions components/layout/query.rs
Expand Up @@ -94,6 +94,9 @@ pub struct LayoutThreadData {

/// A list of images requests that need to be initiated.
pub pending_images: Vec<PendingImage>,

/// A queued response for the list of nodes at a given point.
pub nodes_from_point_response: Vec<UntrustedNodeAddress>,
}

pub struct LayoutRPCImpl(pub Arc<Mutex<LayoutThreadData>>);
Expand Down Expand Up @@ -144,33 +147,10 @@ impl LayoutRPC for LayoutRPCImpl {
}
}

fn nodes_from_point(&self,
page_point: Point2D<f32>,
client_point: Point2D<f32>) -> Vec<UntrustedNodeAddress> {
let page_point = Point2D::new(Au::from_f32_px(page_point.x),
Au::from_f32_px(page_point.y));
let client_point = Point2D::new(Au::from_f32_px(client_point.x),
Au::from_f32_px(client_point.y));

let nodes_from_point_list = {
let &LayoutRPCImpl(ref rw_data) = self;
let rw_data = rw_data.lock().unwrap();
let result = match rw_data.display_list {
None => panic!("Tried to hit test without a DisplayList"),
Some(ref display_list) => {
display_list.hit_test(&page_point,
&client_point,
&rw_data.stacking_context_scroll_offsets)
}
};

result
};

nodes_from_point_list.iter()
.rev()
.map(|metadata| metadata.node.to_untrusted_node_address())
.collect()
fn nodes_from_point(&self) -> Vec<UntrustedNodeAddress> {
let &LayoutRPCImpl(ref rw_data) = self;
let rw_data = rw_data.lock().unwrap();
rw_data.nodes_from_point_response.clone()
}

fn node_geometry(&self) -> NodeGeometryResponse {
Expand All @@ -193,8 +173,8 @@ impl LayoutRPC for LayoutRPCImpl {

fn node_scroll_root_id(&self) -> NodeScrollRootIdResponse {
NodeScrollRootIdResponse(self.0.lock()
.unwrap().scroll_root_id_response
.expect("scroll_root_id is not correctly fetched"))
.unwrap().scroll_root_id_response
.expect("scroll_root_id is not correctly fetched"))
}

/// Retrieves the resolved value for a CSS style property.
Expand Down
31 changes: 30 additions & 1 deletion components/layout_thread/lib.rs
Expand Up @@ -63,6 +63,7 @@ use layout::flow::{self, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwne
use layout::flow_ref::FlowRef;
use layout::incremental::{LayoutDamageComputation, REFLOW_ENTIRE_DOCUMENT};
use layout::layout_debug;
use layout::opaque_node::OpaqueNodeMethods;
use layout::parallel;
use layout::query::{LayoutRPCImpl, LayoutThreadData, process_content_box_request, process_content_boxes_request};
use layout::query::{process_margin_style_query, process_node_overflow_request, process_resolved_style_request};
Expand Down Expand Up @@ -459,6 +460,7 @@ impl LayoutThread {
stacking_context_scroll_offsets: HashMap::new(),
text_index_response: TextIndexResponse(None),
pending_images: vec![],
nodes_from_point_response: vec![],
})),
error_reporter: CSSErrorReporter {
pipelineid: id,
Expand Down Expand Up @@ -977,6 +979,9 @@ impl LayoutThread {
ReflowQueryType::HitTestQuery(..) => {
rw_data.hit_test_response = (None, false);
},
ReflowQueryType::NodesFromPoint(..) => {
rw_data.nodes_from_point_response = Vec::new();
},
ReflowQueryType::NodeGeometryQuery(_) => {
rw_data.client_rect_response = Rect::zero();
},
Expand Down Expand Up @@ -1279,6 +1284,29 @@ impl LayoutThread {
let node = unsafe { ServoLayoutNode::new(&node) };
rw_data.margin_style_response = process_margin_style_query(node);
},
ReflowQueryType::NodesFromPoint(page_point, client_point) => {
let page_point = Point2D::new(Au::from_f32_px(page_point.x),
Au::from_f32_px(page_point.y));
let client_point = Point2D::new(Au::from_f32_px(client_point.x),
Au::from_f32_px(client_point.y));
let nodes_from_point_list = {
let result = match rw_data.display_list {
None => panic!("Tried to hit test without a DisplayList"),
Some(ref display_list) => {
display_list.hit_test(&page_point,
&client_point,
&rw_data.stacking_context_scroll_offsets)
}
};

result
};

rw_data.nodes_from_point_response = nodes_from_point_list.iter()
.rev()
.map(|metadata| metadata.node.to_untrusted_node_address())
.collect()
},
ReflowQueryType::NoQuery => {}
}
}
Expand Down Expand Up @@ -1585,7 +1613,8 @@ fn get_ua_stylesheets() -> Result<UserAgentStylesheets, &'static str> {
/// or false if it only needs stacking-relative positions.
fn reflow_query_type_needs_display_list(query_type: &ReflowQueryType) -> bool {
match *query_type {
ReflowQueryType::HitTestQuery(..) | ReflowQueryType::TextIndexQuery(..) => true,
ReflowQueryType::HitTestQuery(..) | ReflowQueryType::TextIndexQuery(..) |
ReflowQueryType::NodesFromPoint(..) => true,
ReflowQueryType::ContentBoxQuery(_) | ReflowQueryType::ContentBoxesQuery(_) |
ReflowQueryType::NodeGeometryQuery(_) | ReflowQueryType::NodeScrollGeometryQuery(_) |
ReflowQueryType::NodeOverflowQuery(_) | ReflowQueryType::NodeScrollRootIdQuery(_) |
Expand Down
8 changes: 7 additions & 1 deletion components/script/dom/document.rs
Expand Up @@ -1877,7 +1877,13 @@ impl Document {
Point2D::new(client_point.x + self.window.PageXOffset() as f32,
client_point.y + self.window.PageYOffset() as f32);

self.window.layout().nodes_from_point(page_point, *client_point)
if !self.window.reflow(ReflowGoal::ForScriptQuery,
ReflowQueryType::NodesFromPoint(page_point, *client_point),
ReflowReason::Query) {
return vec!();
};

self.window.layout().nodes_from_point()
}
}

Expand Down
1 change: 1 addition & 0 deletions components/script/dom/window.rs
Expand Up @@ -1811,6 +1811,7 @@ fn debug_reflow_events(id: PipelineId, goal: &ReflowGoal, query_type: &ReflowQue
ReflowQueryType::ContentBoxQuery(_n) => "\tContentBoxQuery",
ReflowQueryType::ContentBoxesQuery(_n) => "\tContentBoxesQuery",
ReflowQueryType::HitTestQuery(..) => "\tHitTestQuery",
ReflowQueryType::NodesFromPoint(..) => "\tNodesFromPoint",
ReflowQueryType::NodeGeometryQuery(_n) => "\tNodeGeometryQuery",
ReflowQueryType::NodeOverflowQuery(_n) => "\tNodeOverFlowQuery",
ReflowQueryType::NodeScrollGeometryQuery(_n) => "\tNodeScrollGeometryQuery",
Expand Down
1 change: 1 addition & 0 deletions components/script_layout_interface/message.rs
Expand Up @@ -101,6 +101,7 @@ pub enum ReflowQueryType {
OffsetParentQuery(TrustedNodeAddress),
MarginStyleQuery(TrustedNodeAddress),
TextIndexQuery(TrustedNodeAddress, i32, i32),
NodesFromPoint(Point2D<f32>, Point2D<f32>),
}

/// Information needed for a reflow.
Expand Down
3 changes: 2 additions & 1 deletion components/script_layout_interface/rpc.rs
Expand Up @@ -40,7 +40,8 @@ pub trait LayoutRPC {
fn margin_style(&self) -> MarginStyleResponse;
/// Requests the list of not-yet-loaded images that were encountered in the last reflow.
fn pending_images(&self) -> Vec<PendingImage>;
fn nodes_from_point(&self, page_point: Point2D<f32>, client_point: Point2D<f32>) -> Vec<UntrustedNodeAddress>;
/// Requests the list of nodes from the given point.
fn nodes_from_point(&self) -> Vec<UntrustedNodeAddress>;

fn text_index(&self) -> TextIndexResponse;
}
Expand Down
25 changes: 25 additions & 0 deletions tests/wpt/mozilla/meta/MANIFEST.json
Expand Up @@ -6341,6 +6341,18 @@
{}
]
],
"mozilla/document_elementsFromPoint.html": [
[
"/_mozilla/mozilla/document_elementsFromPoint.html",
[
[
"/_mozilla/mozilla/document_elementsFromPoint_ref.html",
"=="
]
],
{}
]
],
"mozilla/iframe/resize_after_load.html": [
[
"/_mozilla/mozilla/iframe/resize_after_load.html",
Expand Down Expand Up @@ -9388,6 +9400,11 @@
{}
]
],
"mozilla/document_elementsFromPoint_ref.html": [
[
{}
]
],
"mozilla/form_submit_about_frame.html": [
[
{}
Expand Down Expand Up @@ -25137,6 +25154,14 @@
"12eef74e9ba1a62b0302df79633cab5c48f4977f",
"testharness"
],
"mozilla/document_elementsFromPoint.html": [
"2349e1d102552a46bb8e3dd36c0b3396e0d6530b",
"reftest"
],
"mozilla/document_elementsFromPoint_ref.html": [
"4d1a1d0acc16bcb123781cbed47184ff308f3097",
"support"
],
"mozilla/document_getElementById.html": [
"ae5270afde878c8fbe9b4a89c5c3f8ff609220dc",
"testharness"
Expand Down
@@ -0,0 +1,7 @@
<!doctype html>
<meta charset="utf-8">
<title></title>
<link rel="match" href="document_elementsFromPoint_ref.html">
<script>
var elements = document.elementsFromPoint(10, 10);
</script>
@@ -0,0 +1,3 @@
<!doctype html>
<meta charset="utf-8">
<title></title>

0 comments on commit 7426d90

Please sign in to comment.