aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEloy Coto <eloy.coto@gmail.com>2017-05-27 13:27:35 +0200
committerEloy Coto <eloy.coto@gmail.com>2017-05-30 09:38:37 +0200
commit33a46597ed0b5a6baec3444320dd3423f89a2294 (patch)
tree7586d6e0d2d8668b87e88ada0619d4b48e7398a1
parent2151a1f459cda91f5c6f7aa2fee1b3261b02ea7d (diff)
downloadservo-33a46597ed0b5a6baec3444320dd3423f89a2294.tar.gz
servo-33a46597ed0b5a6baec3444320dd3423f89a2294.zip
Fix #6799: set stacking_context_position correctly on
fragment_border_iterator
-rw-r--r--components/layout/block.rs10
-rw-r--r--components/layout/display_list_builder.rs8
-rw-r--r--components/layout/sequential.rs27
-rw-r--r--tests/wpt/metadata/MANIFEST.json10
-rw-r--r--tests/wpt/web-platform-tests/cssom/GetBoundingRect.html30
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>