mirror of
https://github.com/servo/servo.git
synced 2025-06-24 17:14:33 +01:00
auto merge of #864 : jdm/servo/displaylist, r=metajack
This commit is contained in:
commit
b5dcbd287d
6 changed files with 74 additions and 43 deletions
|
@ -372,33 +372,42 @@ impl LayoutTask {
|
||||||
transmute(node)
|
transmute(node)
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = do node.read_layout_data |layout_data| {
|
fn box_for_node(node: AbstractNode<LayoutView>) -> Option<Rect<Au>> {
|
||||||
|
do node.read_layout_data |layout_data| {
|
||||||
match (layout_data.boxes.display_list.clone(), layout_data.boxes.range) {
|
match (layout_data.boxes.display_list.clone(), layout_data.boxes.range) {
|
||||||
(Some(display_list), Some(range)) => {
|
(Some(display_list), Some(range)) => {
|
||||||
let mut rect: Option<Rect<Au>> = None;
|
let mut rect: Option<Rect<Au>> = None;
|
||||||
for i in range.eachi() {
|
for i in range.eachi() {
|
||||||
rect = match rect {
|
rect = match rect {
|
||||||
Some(acc) => Some(acc.union(&display_list.get().list[i].bounds())),
|
Some(acc) => {
|
||||||
|
Some(acc.union(&display_list.get().list[i].bounds()))
|
||||||
|
}
|
||||||
None => Some(display_list.get().list[i].bounds())
|
None => Some(display_list.get().list[i].bounds())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rect
|
||||||
match rect {
|
|
||||||
None => {
|
|
||||||
error!("no boxes for node");
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
Some(rect) => Ok(ContentBoxResponse(rect))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
error!("no display list present");
|
let mut acc: Option<Rect<Au>> = None;
|
||||||
Err(())
|
for child in node.children() {
|
||||||
|
let rect = box_for_node(child);
|
||||||
|
match rect {
|
||||||
|
None => loop,
|
||||||
|
Some(rect) => acc = match acc {
|
||||||
|
Some(acc) => Some(acc.union(&rect)),
|
||||||
|
None => Some(rect)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
acc
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
reply_chan.send(response)
|
let rect = box_for_node(node).unwrap_or_default(Rect(Point2D(Au(0), Au(0)),
|
||||||
|
Size2D(Au(0), Au(0))));
|
||||||
|
reply_chan.send(ContentBoxResponse(rect))
|
||||||
}
|
}
|
||||||
ContentBoxesQuery(node, reply_chan) => {
|
ContentBoxesQuery(node, reply_chan) => {
|
||||||
// FIXME: Isolate this transmutation into a single "bridge" module.
|
// FIXME: Isolate this transmutation into a single "bridge" module.
|
||||||
|
@ -406,21 +415,30 @@ impl LayoutTask {
|
||||||
transmute(node)
|
transmute(node)
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = do node.read_layout_data |layout_data| {
|
fn boxes_for_node(node: AbstractNode<LayoutView>,
|
||||||
|
boxes: ~[Rect<Au>]) -> ~[Rect<Au>] {
|
||||||
|
let boxes = Cell::new(boxes);
|
||||||
|
do node.read_layout_data |layout_data| {
|
||||||
|
let mut boxes = boxes.take();
|
||||||
match (layout_data.boxes.display_list.clone(), layout_data.boxes.range) {
|
match (layout_data.boxes.display_list.clone(), layout_data.boxes.range) {
|
||||||
(Some(display_list), Some(range)) => {
|
(Some(display_list), Some(range)) => {
|
||||||
let mut boxes = ~[];
|
|
||||||
for i in range.eachi() {
|
for i in range.eachi() {
|
||||||
boxes.push(display_list.get().list[i].bounds());
|
boxes.push(display_list.get().list[i].bounds());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ContentBoxesResponse(boxes))
|
|
||||||
}
|
}
|
||||||
_ => Err(()),
|
_ => {
|
||||||
|
for child in node.children() {
|
||||||
|
boxes = boxes_for_node(child, boxes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
boxes
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
reply_chan.send(response)
|
let mut boxes = ~[];
|
||||||
|
boxes = boxes_for_node(node, boxes);
|
||||||
|
reply_chan.send(ContentBoxesResponse(boxes))
|
||||||
}
|
}
|
||||||
HitTestQuery(_, point, reply_chan) => {
|
HitTestQuery(_, point, reply_chan) => {
|
||||||
let response = {
|
let response = {
|
||||||
|
|
|
@ -265,7 +265,7 @@ impl Element {
|
||||||
let page = win.page;
|
let page = win.page;
|
||||||
let (port, chan) = comm::stream();
|
let (port, chan) = comm::stream();
|
||||||
match unsafe {(*page).query_layout(ContentBoxesQuery(node, chan), port)} {
|
match unsafe {(*page).query_layout(ContentBoxesQuery(node, chan), port)} {
|
||||||
Ok(ContentBoxesResponse(rects)) => {
|
ContentBoxesResponse(rects) => {
|
||||||
let cx = unsafe {(*page).js_info.get_ref().js_compartment.cx.ptr};
|
let cx = unsafe {(*page).js_info.get_ref().js_compartment.cx.ptr};
|
||||||
let cache = win.get_wrappercache();
|
let cache = win.get_wrappercache();
|
||||||
let scope = cache.get_wrapper();
|
let scope = cache.get_wrapper();
|
||||||
|
@ -280,10 +280,6 @@ impl Element {
|
||||||
};
|
};
|
||||||
Some((rects, cx, scope))
|
Some((rects, cx, scope))
|
||||||
},
|
},
|
||||||
Err(()) => {
|
|
||||||
debug!("layout query error");
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
@ -311,7 +307,7 @@ impl Element {
|
||||||
assert!(node.is_element());
|
assert!(node.is_element());
|
||||||
let (port, chan) = comm::stream();
|
let (port, chan) = comm::stream();
|
||||||
match unsafe{(*page).query_layout(ContentBoxQuery(node, chan), port)} {
|
match unsafe{(*page).query_layout(ContentBoxQuery(node, chan), port)} {
|
||||||
Ok(ContentBoxResponse(rect)) => {
|
ContentBoxResponse(rect) => {
|
||||||
let cx = unsafe {(*page).js_info.get_ref().js_compartment.cx.ptr};
|
let cx = unsafe {(*page).js_info.get_ref().js_compartment.cx.ptr};
|
||||||
let cache = win.get_wrappercache();
|
let cache = win.get_wrappercache();
|
||||||
let scope = cache.get_wrapper();
|
let scope = cache.get_wrapper();
|
||||||
|
@ -322,8 +318,7 @@ impl Element {
|
||||||
(rect.origin.x + rect.size.width).to_f32(),
|
(rect.origin.x + rect.size.width).to_f32(),
|
||||||
cx,
|
cx,
|
||||||
scope)
|
scope)
|
||||||
},
|
}
|
||||||
Err(()) => fail!("error querying layout")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => fail!("no window")
|
None => fail!("no window")
|
||||||
|
|
|
@ -38,9 +38,9 @@ pub enum Msg {
|
||||||
/// Synchronous messages that script can send to layout.
|
/// Synchronous messages that script can send to layout.
|
||||||
pub enum LayoutQuery {
|
pub enum LayoutQuery {
|
||||||
/// Requests the dimensions of the content box, as in the `getBoundingClientRect()` call.
|
/// Requests the dimensions of the content box, as in the `getBoundingClientRect()` call.
|
||||||
ContentBoxQuery(AbstractNode<ScriptView>, Chan<Result<ContentBoxResponse, ()>>),
|
ContentBoxQuery(AbstractNode<ScriptView>, Chan<ContentBoxResponse>),
|
||||||
/// Requests the dimensions of all the content boxes, as in the `getClientRects()` call.
|
/// Requests the dimensions of all the content boxes, as in the `getClientRects()` call.
|
||||||
ContentBoxesQuery(AbstractNode<ScriptView>, Chan<Result<ContentBoxesResponse, ()>>),
|
ContentBoxesQuery(AbstractNode<ScriptView>, Chan<ContentBoxesResponse>),
|
||||||
/// Requests the node containing the point of interest
|
/// Requests the node containing the point of interest
|
||||||
HitTestQuery(AbstractNode<ScriptView>, Point2D<f32>, Chan<Result<HitTestResponse, ()>>),
|
HitTestQuery(AbstractNode<ScriptView>, Point2D<f32>, Chan<Result<HitTestResponse, ()>>),
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,8 +231,8 @@ impl Page {
|
||||||
/// Sends the given query to layout.
|
/// Sends the given query to layout.
|
||||||
pub fn query_layout<T: Send>(&mut self,
|
pub fn query_layout<T: Send>(&mut self,
|
||||||
query: LayoutQuery,
|
query: LayoutQuery,
|
||||||
response_port: Port<Result<T, ()>>)
|
response_port: Port<T>)
|
||||||
-> Result<T,()> {
|
-> T {
|
||||||
self.join_layout();
|
self.join_layout();
|
||||||
self.layout_chan.send(QueryMsg(query));
|
self.layout_chan.send(QueryMsg(query));
|
||||||
response_port.recv()
|
response_port.recv()
|
||||||
|
|
6
src/test/html/content/test_empty_clientrect.html
Normal file
6
src/test/html/content/test_empty_clientrect.html
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script src="harness.js"></script>
|
||||||
|
<script src="test_empty_clientrect.js"></script>
|
||||||
|
</head>
|
||||||
|
</html>
|
12
src/test/html/content/test_empty_clientrect.js
Normal file
12
src/test/html/content/test_empty_clientrect.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
var rect = window.document.head.getBoundingClientRect();
|
||||||
|
var rects = window.document.head.getClientRects();
|
||||||
|
is(rect instanceof ClientRect, true);
|
||||||
|
is(rect.top, 0);
|
||||||
|
is(rect.bottom, 0);
|
||||||
|
is(rect.left, 0);
|
||||||
|
is(rect.right, 0);
|
||||||
|
is(rect.width, 0);
|
||||||
|
is(rect.height, 0);
|
||||||
|
is(rects instanceof ClientRectList, true);
|
||||||
|
is(rects.length, 0);
|
||||||
|
finish();
|
Loading…
Add table
Add a link
Reference in a new issue