aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2016-04-07 21:30:13 +0530
committerbors-servo <lbergstrom+bors@mozilla.com>2016-04-07 21:30:13 +0530
commite66e437ae66346883cb2cc700f84d06c44962be1 (patch)
tree822d257e7f3f5ef17ff2a2dc2dc3f91af3ea49a8
parent72eae396795d61c0f68d5f09dd84f0835bf10c79 (diff)
parent3518472f7c5e4ad8eb61eb2b9263f151f8b6c797 (diff)
downloadservo-e66e437ae66346883cb2cc700f84d06c44962be1.tar.gz
servo-e66e437ae66346883cb2cc700f84d06c44962be1.zip
Auto merge of #10450 - pcwalton:overflow-scroll-non-positioned, r=mbrubeck
layout: Allow non-absolutely-positioned elements with `overflow: scroll` set to be scrolled. This makes them establish stacking contexts, which is a CSS 2.1 spec violation. However, we were already violating the spec here for absolutely-positioned elements with `overflow: scroll`. It will probably be easier to fix this spec violation once we either switch entirely to WebRender or we have multiple layers per stacking context. r? @mbrubeck <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/10450) <!-- Reviewable:end -->
-rw-r--r--components/gfx/display_list/mod.rs9
-rw-r--r--components/gfx_traits/lib.rs4
-rw-r--r--components/layout/block.rs4
-rw-r--r--components/layout/display_list_builder.rs35
-rw-r--r--tests/html/overflow_scroll_relative_position.html38
5 files changed, 62 insertions, 28 deletions
diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs
index 2a132cf7f61..16ac9a29ea7 100644
--- a/components/gfx/display_list/mod.rs
+++ b/components/gfx/display_list/mod.rs
@@ -725,8 +725,15 @@ impl fmt::Debug for StackingContext {
"Pseudo-StackingContext"
};
- write!(f, "{} at {:?} with overflow {:?}: {:?}",
+ let scrollable_string = if self.scrolls_overflow_area {
+ " (scrolls overflow area)"
+ } else {
+ ""
+ };
+
+ write!(f, "{}{} at {:?} with overflow {:?}: {:?}",
type_string,
+ scrollable_string,
self.bounds,
self.overflow,
self.id)
diff --git a/components/gfx_traits/lib.rs b/components/gfx_traits/lib.rs
index 5833e847a91..6f5abcb1963 100644
--- a/components/gfx_traits/lib.rs
+++ b/components/gfx_traits/lib.rs
@@ -105,6 +105,10 @@ impl LayerId {
let LayerId(layer_type, id, _) = *self;
LayerId(layer_type, id, 0)
}
+
+ pub fn kind(&self) -> LayerType {
+ self.0
+ }
}
/// All layer-specific information that the painting task sends to the compositor other than the
diff --git a/components/layout/block.rs b/components/layout/block.rs
index 390810e9831..519a76c08e7 100644
--- a/components/layout/block.rs
+++ b/components/layout/block.rs
@@ -1563,10 +1563,6 @@ impl BlockFlow {
}
pub fn has_scrolling_overflow(&self) -> bool {
- if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
- return false;
- }
-
match (self.fragment.style().get_box().overflow_x,
self.fragment.style().get_box().overflow_y.0) {
(overflow_x::T::auto, _) | (overflow_x::T::scroll, _) |
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs
index 7f8fe5df579..0c04c839450 100644
--- a/components/layout/display_list_builder.rs
+++ b/components/layout/display_list_builder.rs
@@ -1470,33 +1470,22 @@ impl FragmentDisplayListBuilding for Fragment {
// Clip according to the values of `overflow-x` and `overflow-y`.
//
- // TODO(pcwalton): Support scrolling of non-absolutely-positioned elements.
// FIXME(pcwalton): This may be more complex than it needs to be, since it seems to be
// impossible with the computed value rules as they are to have `overflow-x: visible` with
// `overflow-y: <scrolling>` or vice versa!
- match (self.style.get_box().overflow_x, is_absolutely_positioned) {
- (overflow_x::T::hidden, _) |
- (overflow_x::T::auto, false) |
- (overflow_x::T::scroll, false) => {
- let mut bounds = current_clip.bounding_rect();
- let max_x = cmp::min(bounds.max_x(), overflow_clip_rect.max_x());
- bounds.origin.x = cmp::max(bounds.origin.x, overflow_clip_rect.origin.x);
- bounds.size.width = max_x - bounds.origin.x;
- current_clip.intersect_rect(&bounds)
- }
- _ => {}
+ if let overflow_x::T::hidden = self.style.get_box().overflow_x {
+ let mut bounds = current_clip.bounding_rect();
+ let max_x = cmp::min(bounds.max_x(), overflow_clip_rect.max_x());
+ bounds.origin.x = cmp::max(bounds.origin.x, overflow_clip_rect.origin.x);
+ bounds.size.width = max_x - bounds.origin.x;
+ current_clip.intersect_rect(&bounds)
}
- match (self.style.get_box().overflow_y.0, is_absolutely_positioned) {
- (overflow_x::T::hidden, _) |
- (overflow_x::T::auto, false) |
- (overflow_x::T::scroll, false) => {
- let mut bounds = current_clip.bounding_rect();
- let max_y = cmp::min(bounds.max_y(), overflow_clip_rect.max_y());
- bounds.origin.y = cmp::max(bounds.origin.y, overflow_clip_rect.origin.y);
- bounds.size.height = max_y - bounds.origin.y;
- current_clip.intersect_rect(&bounds)
- }
- _ => {}
+ if let overflow_x::T::hidden = self.style.get_box().overflow_y.0 {
+ let mut bounds = current_clip.bounding_rect();
+ let max_y = cmp::min(bounds.max_y(), overflow_clip_rect.max_y());
+ bounds.origin.y = cmp::max(bounds.origin.y, overflow_clip_rect.origin.y);
+ bounds.size.height = max_y - bounds.origin.y;
+ current_clip.intersect_rect(&bounds)
}
let border_radii = build_border_radius(stacking_relative_border_box,
diff --git a/tests/html/overflow_scroll_relative_position.html b/tests/html/overflow_scroll_relative_position.html
new file mode 100644
index 00000000000..83c4b8c1675
--- /dev/null
+++ b/tests/html/overflow_scroll_relative_position.html
@@ -0,0 +1,38 @@
+<html>
+ <head>
+ <link rel=match href=overflow_simple_b.html>
+ <style>
+ #first {
+ height: 100px;
+ width: 100px;
+ overflow: scroll;
+ position: relative;
+ }
+ #second {
+ position: absolute;
+ height: 100px;
+ width: 90px;
+ top: 0;
+ left: 0;
+ background: green;
+ }
+ #third {
+ position: absolute;
+ height: 100px;
+ width: 110px;
+ top: 0;
+ left: 90px;
+ background: orange;
+ }
+ </style>
+ </head>
+ <body>
+ This element should be scrollable.
+ <div id="first">
+ <div id="second">
+ </div>
+ <div id="third">
+ </div>
+ </div>
+ </body>
+</html>