diff options
-rw-r--r-- | components/layout/block.rs | 10 | ||||
-rw-r--r-- | components/layout/display_list_builder.rs | 8 | ||||
-rw-r--r-- | components/layout/sequential.rs | 27 | ||||
-rw-r--r-- | tests/wpt/metadata/MANIFEST.json | 10 | ||||
-rw-r--r-- | tests/wpt/web-platform-tests/cssom/GetBoundingRect.html | 30 |
5 files changed, 67 insertions, 18 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs index adeb04730a3..9cd6978097e 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -31,7 +31,7 @@ use app_units::{Au, MAX_AU}; use context::LayoutContext; use display_list_builder::{BorderPaintingMode, DisplayListBuildState}; use display_list_builder::BlockFlowDisplayListBuilding; -use euclid::{Point2D, Size2D}; +use euclid::{Point2D, Size2D, Rect}; use floats::{ClearType, FloatKind, Floats, PlacementInfo}; use flow::{self, BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ForceNonfloatedFlag}; use flow::{BLOCK_POSITION_IS_STATIC, CLEARS_LEFT, CLEARS_RIGHT}; @@ -647,6 +647,14 @@ impl BlockFlow { &mut self.fragment } + pub fn stacking_relative_position(&self, coor: CoordinateSystem) -> Rect<Au> { + return self.fragment.stacking_relative_border_box( + &self.base.stacking_relative_position, + &self.base.early_absolute_position_info.relative_containing_block_size, + self.base.early_absolute_position_info.relative_containing_block_mode, + coor); + } + /// Return the size of the containing block for the given immediate absolute descendant of this /// flow. /// diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 13829e8830d..b3c888463a8 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -2221,13 +2221,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { if state.clip_stack.is_empty() { return; } - - let border_box = self.fragment.stacking_relative_border_box( - &self.base.stacking_relative_position, - &self.base.early_absolute_position_info.relative_containing_block_size, - self.base.early_absolute_position_info.relative_containing_block_mode, - CoordinateSystem::Parent); - + let border_box = self.stacking_relative_position(CoordinateSystem::Parent); let transform = match self.fragment.transform_matrix(&border_box) { Some(transform) => transform, None => return, diff --git a/components/layout/sequential.rs b/components/layout/sequential.rs index 6452be7b544..404d29a44d1 100644 --- a/components/layout/sequential.rs +++ b/components/layout/sequential.rs @@ -12,7 +12,7 @@ use floats::SpeculatedFloatPlacement; use flow::{self, Flow, ImmutableFlowUtils, InorderFlowTraversal, MutableFlowUtils}; use flow::{PostorderFlowTraversal, PreorderFlowTraversal}; use flow::IS_ABSOLUTELY_POSITIONED; -use fragment::FragmentBorderBoxIterator; +use fragment::{FragmentBorderBoxIterator, CoordinateSystem}; use generated_content::ResolveGeneratedContent; use incremental::RelayoutMode; use servo_config::opts; @@ -105,15 +105,22 @@ pub fn iterate_through_flow_tree_fragment_border_boxes(root: &mut Flow, iterator flow.iterate_through_fragment_border_boxes(iterator, level, stacking_context_position); for kid in flow::mut_base(flow).child_iter_mut() { - let stacking_context_position = if kid.is_block_flow() && - kid.as_block().fragment.establishes_stacking_context() { - let margin = Point2D::new(kid.as_block().fragment.margin.inline_start, Au(0)); - *stacking_context_position + flow::base(kid).stacking_relative_position + margin - } else { - *stacking_context_position - }; - - // FIXME(#2795): Get the real container size. + let mut stacking_context_position = *stacking_context_position; + if kid.is_block_flow() && kid.as_block().fragment.establishes_stacking_context() { + stacking_context_position = Point2D::new(kid.as_block().fragment.margin.inline_start, Au(0)) + + flow::base(kid).stacking_relative_position + + stacking_context_position; + let relative_position = kid.as_block() + .stacking_relative_position(CoordinateSystem::Own); + if let Some(matrix) = kid.as_block() + .fragment + .transform_matrix(&relative_position) { + let transform_matrix = matrix.transform_point(&Point2D::zero()); + stacking_context_position = stacking_context_position + + Point2D::new(Au::from_f32_px(transform_matrix.x), + Au::from_f32_px(transform_matrix.y)) + } + } doit(kid, level + 1, iterator, &stacking_context_position); } } diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json index 191c2a3d1c1..56f3fc086d6 100644 --- a/tests/wpt/metadata/MANIFEST.json +++ b/tests/wpt/metadata/MANIFEST.json @@ -321172,6 +321172,12 @@ {} ] ], + "cssom/GetBoundingRect.html": [ + [ + "/cssom/GetBoundingRect.html", + {} + ] + ], "cssom/MediaList.html": [ [ "/cssom/MediaList.html", @@ -553765,6 +553771,10 @@ "f0d47464da9d30e70733f09af78f3e9f982c4406", "testharness" ], + "cssom/GetBoundingRect.html": [ + "7e5a8b25753ac970c2d192376c9dd93943b3dbb5", + "testharness" + ], "cssom/MediaList.html": [ "21d9e43514fb3a7fbf8933429242dc544224ef24", "testharness" diff --git a/tests/wpt/web-platform-tests/cssom/GetBoundingRect.html b/tests/wpt/web-platform-tests/cssom/GetBoundingRect.html new file mode 100644 index 00000000000..6ab5e4c9b3f --- /dev/null +++ b/tests/wpt/web-platform-tests/cssom/GetBoundingRect.html @@ -0,0 +1,30 @@ +<!doctype html> +<html> + <head> + <meta charset="utf-8"> + <title>getBoundingClientRect</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + + <style> + #foo { + margin: 0px 0px 0px 5px; + transform: translate(10px, 200px); + position: fixed; + left: 5px; + background-color: red; + } + </style> + </head> + <body> + <div id="foo"> + FOO + </div> + <script> + test(function () { + var foo = document.getElementById("foo").getBoundingClientRect(); + assert_equals(foo.left, 20); + }); + </script> + </body> +</html> |