aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/layout/block.rs47
-rw-r--r--components/layout/display_list_builder.rs55
-rw-r--r--tests/wpt/mozilla/meta/MANIFEST.json24
-rw-r--r--tests/wpt/mozilla/tests/css/translate_clip_nested.html16
-rw-r--r--tests/wpt/mozilla/tests/css/translate_clip_nested_ref.html13
5 files changed, 108 insertions, 47 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs
index 07b70070f47..763698d85a4 100644
--- a/components/layout/block.rs
+++ b/components/layout/block.rs
@@ -48,13 +48,13 @@ use incremental::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT};
use layout_debug;
use layout_thread::DISPLAY_PORT_SIZE_FACTOR;
use model::{CollapsibleMargins, MaybeAuto, specified, specified_or_none};
-use model::{IntrinsicISizes, MarginCollapseInfo};
+use model::{self, IntrinsicISizes, MarginCollapseInfo};
use rustc_serialize::{Encodable, Encoder};
use std::cmp::{max, min};
use std::fmt;
use std::sync::Arc;
use style::computed_values::{border_collapse, box_sizing, display, float, overflow_x, overflow_y};
-use style::computed_values::{position, text_align, transform_style};
+use style::computed_values::{position, text_align, transform, transform_style};
use style::context::StyleContext;
use style::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode};
use style::properties::{ComputedValues, ServoComputedValues};
@@ -1965,7 +1965,48 @@ impl Flow for BlockFlow {
flow::mut_base(kid).late_absolute_position_info =
late_absolute_position_info_for_children;
- flow::mut_base(kid).clip = clip.clone();
+ let clip = if kid.is_block_like() {
+ let mut clip = clip.clone();
+ let kid = kid.as_block();
+ // TODO(notriddle): To properly support transformations, we either need
+ // non-rectangular clipping regions in display lists, or clipping
+ // regions in terms of the parent coordinate system instead of the
+ // child coordinate system.
+ //
+ // This is a workaround for a common idiom of transform: translate().
+ if let Some(ref operations) = kid.fragment.style().get_effects().transform.0 {
+ for operation in operations {
+ match *operation {
+ transform::ComputedOperation::Translate(tx, ty, _) => {
+ // N.B. When the clipping value comes from us, it
+ // shouldn't be transformed.
+ let tx = if let overflow_x::T::hidden = kid.fragment.style().get_box()
+ .overflow_x {
+ Au(0)
+ } else {
+ model::specified(tx, kid.base.block_container_inline_size)
+ };
+ let ty = if let overflow_x::T::hidden = kid.fragment.style().get_box()
+ .overflow_y.0 {
+ Au(0)
+ } else {
+ model::specified(
+ ty,
+ kid.base.block_container_explicit_block_size.unwrap_or(Au(0))
+ )
+ };
+ let off = Point2D::new(tx, ty);
+ clip = clip.translate(&-off);
+ }
+ _ => {}
+ };
+ }
+ }
+ clip
+ } else {
+ clip.clone()
+ };
+ flow::mut_base(kid).clip = clip;
flow::mut_base(kid).stacking_relative_position_of_display_port =
stacking_relative_position_of_display_port_for_children;
}
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs
index 9b1c5bd0262..1767f2ca287 100644
--- a/components/layout/display_list_builder.rs
+++ b/components/layout/display_list_builder.rs
@@ -1461,15 +1461,15 @@ impl FragmentDisplayListBuilding for Fragment {
return
}
- let tmp;
+ let overflow_clip_rect_owner;
let overflow_clip_rect = match self.style.get_box()._servo_overflow_clip_box {
overflow_clip_box::T::padding_box => {
// FIXME(SimonSapin): should be the padding box, not border box.
stacking_relative_border_box
}
overflow_clip_box::T::content_box => {
- tmp = self.stacking_relative_content_box(stacking_relative_border_box);
- &tmp
+ overflow_clip_rect_owner = self.stacking_relative_content_box(stacking_relative_border_box);
+ &overflow_clip_rect_owner
}
};
@@ -1743,46 +1743,13 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
};
// Add the box that starts the block context.
- let mut clip = self.base.clip.clone();
-
- if establishes_stacking_context {
- clip = clip.translate(&-self.base.stacking_relative_position)
- }
-
- // TODO(notriddle): To properly support transformations, we either need
- // non-rectangular clipping regions in display lists, or clipping
- // regions in terms of the parent coordinate system instead of the
- // child coordinate system.
- //
- // This is a workaround for a common idiom of transform: translate().
- if let Some(ref operations) = self.fragment.style().get_effects().transform.0 {
- for operation in operations {
- match *operation {
- transform::ComputedOperation::Translate(tx, ty, _) => {
- // N.B. When the clipping value comes from us, it
- // shouldn't be transformed.
- let tx = if let overflow_x::T::hidden = self.fragment.style().get_box()
- .overflow_x {
- Au(0)
- } else {
- model::specified(tx, self.base.block_container_inline_size)
- };
- let ty = if let overflow_x::T::hidden = self.fragment.style().get_box()
- .overflow_y.0 {
- Au(0)
- } else {
- model::specified(
- ty,
- self.base.block_container_explicit_block_size.unwrap_or(Au(0))
- )
- };
- let off = Point2D::new(tx, ty);
- clip = clip.translate(&-off);
- }
- _ => {}
- };
- }
- }
+ let clip_owner;
+ let clip = if establishes_stacking_context {
+ clip_owner = self.base.clip.translate(&-self.base.stacking_relative_position);
+ &clip_owner
+ } else {
+ &self.base.clip
+ };
self.fragment
.build_display_list(state,
@@ -1795,7 +1762,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
.relative_containing_block_mode,
border_painting_mode,
background_border_section,
- &clip,
+ clip,
&self.base.stacking_relative_position_of_display_port);
self.base.build_display_items_for_debugging_tint(state, self.fragment.node);
diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json
index 6bb6318f051..0e0e983b54f 100644
--- a/tests/wpt/mozilla/meta/MANIFEST.json
+++ b/tests/wpt/mozilla/meta/MANIFEST.json
@@ -5043,6 +5043,18 @@
"url": "/_mozilla/css/translate_clip.html"
}
],
+ "css/translate_clip_nested.html": [
+ {
+ "path": "css/translate_clip_nested.html",
+ "references": [
+ [
+ "/_mozilla/css/translate_clip_nested_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/translate_clip_nested.html"
+ }
+ ],
"css/upper_id_attr.html": [
{
"path": "css/upper_id_attr.html",
@@ -11549,6 +11561,18 @@
"url": "/_mozilla/css/translate_clip.html"
}
],
+ "css/translate_clip_nested.html": [
+ {
+ "path": "css/translate_clip_nested.html",
+ "references": [
+ [
+ "/_mozilla/css/translate_clip_nested_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/translate_clip_nested.html"
+ }
+ ],
"css/upper_id_attr.html": [
{
"path": "css/upper_id_attr.html",
diff --git a/tests/wpt/mozilla/tests/css/translate_clip_nested.html b/tests/wpt/mozilla/tests/css/translate_clip_nested.html
new file mode 100644
index 00000000000..fc3baf2affd
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/translate_clip_nested.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset="utf-8">
+<link rel="match" href="translate_clip_nested_ref.html">
+<style>
+ div {
+ height: 200px;
+ width: 200px;
+ }
+</style>
+<div style="position: relative; overflow: hidden; background: red;">
+ <div style="transform: translateX(-100px);">
+ <div style="position: absolute; right: -100px; background: green;">
+ 1 2 3 4 5 6 7 8 9 10 11 12 13
+ </div>
+ </div>
+</div>
diff --git a/tests/wpt/mozilla/tests/css/translate_clip_nested_ref.html b/tests/wpt/mozilla/tests/css/translate_clip_nested_ref.html
new file mode 100644
index 00000000000..4ae8afe85d4
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/translate_clip_nested_ref.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<meta charset="utf-8">
+<style>
+ div {
+ height: 200px;
+ width: 200px;
+ }
+</style>
+<div style="position: relative; overflow: hidden; background: red;">
+ <div style="position: absolute; right: 0; background: green;">
+ 1 2 3 4 5 6 7 8 9 10 11 12 13
+ </div>
+</div>