mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Fix #6799: set stacking_context_position correctly on
fragment_border_iterator
This commit is contained in:
parent
2151a1f459
commit
33a46597ed
5 changed files with 67 additions and 18 deletions
|
@ -31,7 +31,7 @@ use app_units::{Au, MAX_AU};
|
||||||
use context::LayoutContext;
|
use context::LayoutContext;
|
||||||
use display_list_builder::{BorderPaintingMode, DisplayListBuildState};
|
use display_list_builder::{BorderPaintingMode, DisplayListBuildState};
|
||||||
use display_list_builder::BlockFlowDisplayListBuilding;
|
use display_list_builder::BlockFlowDisplayListBuilding;
|
||||||
use euclid::{Point2D, Size2D};
|
use euclid::{Point2D, Size2D, Rect};
|
||||||
use floats::{ClearType, FloatKind, Floats, PlacementInfo};
|
use floats::{ClearType, FloatKind, Floats, PlacementInfo};
|
||||||
use flow::{self, BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ForceNonfloatedFlag};
|
use flow::{self, BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ForceNonfloatedFlag};
|
||||||
use flow::{BLOCK_POSITION_IS_STATIC, CLEARS_LEFT, CLEARS_RIGHT};
|
use flow::{BLOCK_POSITION_IS_STATIC, CLEARS_LEFT, CLEARS_RIGHT};
|
||||||
|
@ -647,6 +647,14 @@ impl BlockFlow {
|
||||||
&mut self.fragment
|
&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
|
/// Return the size of the containing block for the given immediate absolute descendant of this
|
||||||
/// flow.
|
/// flow.
|
||||||
///
|
///
|
||||||
|
|
|
@ -2221,13 +2221,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
if state.clip_stack.is_empty() {
|
if state.clip_stack.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
let border_box = self.stacking_relative_position(CoordinateSystem::Parent);
|
||||||
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 transform = match self.fragment.transform_matrix(&border_box) {
|
let transform = match self.fragment.transform_matrix(&border_box) {
|
||||||
Some(transform) => transform,
|
Some(transform) => transform,
|
||||||
None => return,
|
None => return,
|
||||||
|
|
|
@ -12,7 +12,7 @@ use floats::SpeculatedFloatPlacement;
|
||||||
use flow::{self, Flow, ImmutableFlowUtils, InorderFlowTraversal, MutableFlowUtils};
|
use flow::{self, Flow, ImmutableFlowUtils, InorderFlowTraversal, MutableFlowUtils};
|
||||||
use flow::{PostorderFlowTraversal, PreorderFlowTraversal};
|
use flow::{PostorderFlowTraversal, PreorderFlowTraversal};
|
||||||
use flow::IS_ABSOLUTELY_POSITIONED;
|
use flow::IS_ABSOLUTELY_POSITIONED;
|
||||||
use fragment::FragmentBorderBoxIterator;
|
use fragment::{FragmentBorderBoxIterator, CoordinateSystem};
|
||||||
use generated_content::ResolveGeneratedContent;
|
use generated_content::ResolveGeneratedContent;
|
||||||
use incremental::RelayoutMode;
|
use incremental::RelayoutMode;
|
||||||
use servo_config::opts;
|
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);
|
flow.iterate_through_fragment_border_boxes(iterator, level, stacking_context_position);
|
||||||
|
|
||||||
for kid in flow::mut_base(flow).child_iter_mut() {
|
for kid in flow::mut_base(flow).child_iter_mut() {
|
||||||
let stacking_context_position = if kid.is_block_flow() &&
|
let mut stacking_context_position = *stacking_context_position;
|
||||||
kid.as_block().fragment.establishes_stacking_context() {
|
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 = Point2D::new(kid.as_block().fragment.margin.inline_start, Au(0)) +
|
||||||
*stacking_context_position + flow::base(kid).stacking_relative_position + margin
|
flow::base(kid).stacking_relative_position +
|
||||||
} else {
|
stacking_context_position;
|
||||||
*stacking_context_position
|
let relative_position = kid.as_block()
|
||||||
};
|
.stacking_relative_position(CoordinateSystem::Own);
|
||||||
|
if let Some(matrix) = kid.as_block()
|
||||||
// FIXME(#2795): Get the real container size.
|
.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);
|
doit(kid, level + 1, iterator, &stacking_context_position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -321172,6 +321172,12 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"cssom/GetBoundingRect.html": [
|
||||||
|
[
|
||||||
|
"/cssom/GetBoundingRect.html",
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"cssom/MediaList.html": [
|
"cssom/MediaList.html": [
|
||||||
[
|
[
|
||||||
"/cssom/MediaList.html",
|
"/cssom/MediaList.html",
|
||||||
|
@ -553765,6 +553771,10 @@
|
||||||
"f0d47464da9d30e70733f09af78f3e9f982c4406",
|
"f0d47464da9d30e70733f09af78f3e9f982c4406",
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
|
"cssom/GetBoundingRect.html": [
|
||||||
|
"7e5a8b25753ac970c2d192376c9dd93943b3dbb5",
|
||||||
|
"testharness"
|
||||||
|
],
|
||||||
"cssom/MediaList.html": [
|
"cssom/MediaList.html": [
|
||||||
"21d9e43514fb3a7fbf8933429242dc544224ef24",
|
"21d9e43514fb3a7fbf8933429242dc544224ef24",
|
||||||
"testharness"
|
"testharness"
|
||||||
|
|
30
tests/wpt/web-platform-tests/cssom/GetBoundingRect.html
Normal file
30
tests/wpt/web-platform-tests/cssom/GetBoundingRect.html
Normal file
|
@ -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>
|
Loading…
Add table
Add a link
Reference in a new issue