diff options
-rw-r--r-- | components/layout/block.rs | 47 | ||||
-rw-r--r-- | components/layout/display_list_builder.rs | 55 | ||||
-rw-r--r-- | tests/wpt/mozilla/meta/MANIFEST.json | 24 | ||||
-rw-r--r-- | tests/wpt/mozilla/tests/css/translate_clip_nested.html | 16 | ||||
-rw-r--r-- | tests/wpt/mozilla/tests/css/translate_clip_nested_ref.html | 13 |
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> |