Implement client{Top, Left, Height, Width} element properties

This commit is contained in:
Till Schneidereit 2015-07-19 15:04:50 +02:00
parent acf47a02cf
commit 162ecd0aac
8 changed files with 214 additions and 1 deletions

View file

@ -52,7 +52,7 @@ use net_traits::{load_bytes_iter, PendingAsyncLoad};
use net_traits::image_cache_task::{ImageCacheTask, ImageCacheResult, ImageCacheChan};
use script::dom::bindings::js::LayoutJS;
use script::dom::node::{LayoutData, Node};
use script::layout_interface::{Animation, ContentBoxResponse, ContentBoxesResponse};
use script::layout_interface::{Animation, ContentBoxResponse, ContentBoxesResponse, NodeGeometryResponse};
use script::layout_interface::{HitTestResponse, LayoutChan, LayoutRPC, MouseOverResponse};
use script::layout_interface::{NewLayoutTaskInfo, Msg, Reflow, ReflowGoal, ReflowQueryType};
use script::layout_interface::{ScriptLayoutChan, ScriptReflow, TrustedNodeAddress};
@ -126,6 +126,9 @@ pub struct LayoutTaskData {
/// A queued response for the content boxes of a node.
pub content_boxes_response: Vec<Rect<Au>>,
/// A queued response for the client {top, left, width, height} of a node.
pub client_rect_response: Rect<i32>,
/// The list of currently-running animations.
pub running_animations: Vec<Animation>,
@ -358,6 +361,7 @@ impl LayoutTask {
generation: 0,
content_box_response: Rect::zero(),
content_boxes_response: Vec::new(),
client_rect_response: Rect::zero(),
running_animations: Vec::new(),
visible_rects: Arc::new(HashMap::with_hash_state(Default::default())),
new_animations_receiver: new_animations_receiver,
@ -843,6 +847,16 @@ impl LayoutTask {
rw_data.content_boxes_response = iterator.rects;
}
fn process_node_geometry_request<'a>(&'a self,
requested_node: TrustedNodeAddress,
layout_root: &mut FlowRef,
rw_data: &mut RWGuard<'a>) {
let requested_node: OpaqueNode = OpaqueNodeMethods::from_script_node(requested_node);
let mut iterator = FragmentLocatingFragmentIterator::new(requested_node);
sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root, &mut iterator);
rw_data.client_rect_response = iterator.client_rect;
}
fn compute_abs_pos_and_build_display_list<'a>(&'a self,
data: &Reflow,
layout_root: &mut FlowRef,
@ -1039,6 +1053,9 @@ impl LayoutTask {
ReflowQueryType::ContentBoxesQuery(node) => {
self.process_content_boxes_request(node, &mut root_flow, &mut rw_data)
}
ReflowQueryType::NodeGeometryQuery(node) => {
self.process_node_geometry_request(node, &mut root_flow, &mut rw_data)
}
ReflowQueryType::NoQuery => {}
}
@ -1278,6 +1295,14 @@ impl LayoutRPC for LayoutRPCImpl {
ContentBoxesResponse(rw_data.content_boxes_response.clone())
}
fn node_geometry(&self) -> NodeGeometryResponse {
let &LayoutRPCImpl(ref rw_data) = self;
let rw_data = rw_data.lock().unwrap();
NodeGeometryResponse {
client_rect: rw_data.client_rect_response
}
}
/// Requests the node containing the point of interest.
fn hit_test(&self, _: TrustedNodeAddress, point: Point2D<f32>) -> Result<HitTestResponse, ()> {
let point = Point2D::new(Au::from_f32_px(point.x), Au::from_f32_px(point.y));
@ -1395,6 +1420,38 @@ impl FragmentBorderBoxIterator for CollectingFragmentBorderBoxIterator {
}
}
struct FragmentLocatingFragmentIterator {
node_address: OpaqueNode,
client_rect: Rect<i32>,
}
impl FragmentLocatingFragmentIterator {
fn new(node_address: OpaqueNode) -> FragmentLocatingFragmentIterator {
FragmentLocatingFragmentIterator {
node_address: node_address,
client_rect: Rect::zero()
}
}
}
impl FragmentBorderBoxIterator for FragmentLocatingFragmentIterator {
fn process(&mut self, fragment: &Fragment, border_box: &Rect<Au>) {
let border_style_struct = fragment.style.get_border();
let top_width = border_style_struct.border_top_width;
let right_width = border_style_struct.border_right_width;
let bottom_width = border_style_struct.border_bottom_width;
let left_width = border_style_struct.border_left_width;
self.client_rect.origin.y = top_width.to_px();
self.client_rect.origin.x = left_width.to_px();
self.client_rect.size.width = (border_box.size.width - left_width - right_width).to_px();
self.client_rect.size.height = (border_box.size.height - top_width - bottom_width).to_px();
}
fn should_process(&mut self, fragment: &Fragment) -> bool {
fragment.node == self.node_address
}
}
// The default computed value for background-color is transparent (see
// http://dev.w3.org/csswg/css-backgrounds/#background-color). However, we
// need to propagate the background color from the root HTML/Body