diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index b93c3c56c15..71411009272 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -44,6 +44,7 @@ use std::default::Default; use std::sync::Arc; use std::{cmp, f32}; use style::computed_values::filter::Filter; +use style::computed_values::{_servo_overflow_clip_box as overflow_clip_box}; use style::computed_values::{background_attachment, background_clip, background_origin}; use style::computed_values::{background_repeat, background_size}; use style::computed_values::{border_style, image_rendering, overflow_x, position}; @@ -1430,6 +1431,25 @@ impl FragmentDisplayListBuilding for Fragment { // Account for style-specified `clip`. self.adjust_clip_for_style(current_clip, stacking_relative_border_box); + let overflow_x = self.style.get_box().overflow_x; + let overflow_y = self.style.get_box().overflow_y.0; + + if let (overflow_x::T::visible, overflow_x::T::visible) = (overflow_x, overflow_y) { + return + } + + let tmp; + 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 + } + }; + // Clip according to the values of `overflow-x` and `overflow-y`. // // TODO(pcwalton): Support scrolling of non-absolutely-positioned elements. @@ -1441,8 +1461,8 @@ impl FragmentDisplayListBuilding for Fragment { (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(), stacking_relative_border_box.max_x()); - bounds.origin.x = cmp::max(bounds.origin.x, stacking_relative_border_box.origin.x); + 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) } @@ -1453,8 +1473,8 @@ impl FragmentDisplayListBuilding for Fragment { (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(), stacking_relative_border_box.max_y()); - bounds.origin.y = cmp::max(bounds.origin.y, stacking_relative_border_box.origin.y); + 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) } diff --git a/components/style/properties.mako.rs b/components/style/properties.mako.rs index 890661f3d0d..7a453bd8ac3 100644 --- a/components/style/properties.mako.rs +++ b/components/style/properties.mako.rs @@ -51,26 +51,29 @@ def to_camel_case(ident): return re.sub("_([a-z])", lambda m: m.group(1).upper(), ident.strip("_").capitalize()) class Longhand(object): - def __init__(self, name, derived_from=None, custom_cascade=False, experimental=False): + def __init__(self, name, derived_from=None, custom_cascade=False, experimental=False, + internal=False): self.name = name self.ident = to_rust_ident(name) self.camel_case = to_camel_case(self.ident) self.style_struct = THIS_STYLE_STRUCT self.experimental = ("layout.%s.enabled" % name) if experimental else None self.custom_cascade = custom_cascade + self.internal = internal if derived_from is None: self.derived_from = None else: self.derived_from = [ to_rust_ident(name) for name in derived_from ] class Shorthand(object): - def __init__(self, name, sub_properties, experimental=False): + def __init__(self, name, sub_properties, experimental=False, internal=False): self.name = name self.ident = to_rust_ident(name) self.camel_case = to_camel_case(self.ident) self.derived_from = None self.experimental = ("layout.%s.enabled" % name) if experimental else None self.sub_properties = [LONGHANDS_BY_NAME[s] for s in sub_properties] + self.internal = internal class StyleStruct(object): def __init__(self, name, inherited): @@ -109,7 +112,8 @@ pub mod longhands { use parser::ParserContext; use values::specified; - <%def name="raw_longhand(name, derived_from=None, custom_cascade=False, experimental=False)"> + <%def name="raw_longhand(name, derived_from=None, custom_cascade=False, experimental=False, + internal=False)"> <% if derived_from is not None: derived_from = derived_from.split() @@ -117,7 +121,8 @@ pub mod longhands { property = Longhand(name, derived_from=derived_from, custom_cascade=custom_cascade, - experimental=experimental) + experimental=experimental, + internal=internal) property.style_struct = THIS_STYLE_STRUCT THIS_STYLE_STRUCT.longhands.append(property) LONGHANDS.append(property) @@ -234,9 +239,11 @@ pub mod longhands { } - <%def name="longhand(name, derived_from=None, custom_cascade=False, experimental=False)"> + <%def name="longhand(name, derived_from=None, custom_cascade=False, experimental=False, + internal=False)"> <%self:raw_longhand name="${name}" derived_from="${derived_from}" - custom_cascade="${custom_cascade}" experimental="${experimental}"> + custom_cascade="${custom_cascade}" experimental="${experimental}" + internal="${internal}"> ${caller.body()} % if derived_from is None: pub fn parse_specified(context: &ParserContext, input: &mut Parser) @@ -247,9 +254,10 @@ pub mod longhands { - <%def name="single_keyword_computed(name, values, custom_cascade=False, experimental=False)"> + <%def name="single_keyword_computed(name, values, custom_cascade=False, experimental=False, + internal=False)"> <%self:longhand name="${name}" custom_cascade="${custom_cascade}" - experimental="${experimental}"> + experimental="${experimental}" internal="${internal}"> pub use self::computed_value::T as SpecifiedValue; ${caller.body()} pub mod computed_value { @@ -269,10 +277,11 @@ pub mod longhands { - <%def name="single_keyword(name, values, experimental=False)"> + <%def name="single_keyword(name, values, experimental=False, internal=False)"> <%self:single_keyword_computed name="${name}" values="${values}" - experimental="${experimental}"> + experimental="${experimental}" + internal="${internal}"> use values::computed::ComputedValueAsSpecified; impl ComputedValueAsSpecified for SpecifiedValue {} @@ -845,6 +854,9 @@ pub mod longhands { // CSS 2.1, Section 11 - Visual effects + // Non-standard, see https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-clip-box#Specifications + ${single_keyword("-servo-overflow-clip-box", "padding-box content-box", internal=True)} + // FIXME(pcwalton, #2742): Implement scrolling for `scroll` and `auto`. <%self:single_keyword_computed name="overflow-x" values="visible hidden scroll auto"> use values::computed::Context; @@ -5629,6 +5641,7 @@ mod property_bit_field { % for property in LONGHANDS: % if property.derived_from is None: + #[allow(non_snake_case)] fn substitute_variables_${property.ident}( value: &DeclaredValue, custom_properties: &Option>, @@ -5652,6 +5665,7 @@ mod property_bit_field { } } + #[allow(non_snake_case)] #[inline(never)] fn substitute_variables_${property.ident}_slow( css: &String, @@ -6054,6 +6068,11 @@ impl PropertyDeclaration { % for property in LONGHANDS: % if property.derived_from is None: "${property.name}" => { + % if property.internal: + if context.stylesheet_origin != Origin::UserAgent { + return PropertyDeclarationParseResult::UnknownProperty + } + % endif % if property.experimental: if !::util::prefs::get_pref("${property.experimental}") .as_boolean().unwrap_or(false) { @@ -6074,6 +6093,11 @@ impl PropertyDeclaration { % endfor % for shorthand in SHORTHANDS: "${shorthand.name}" => { + % if shorthand.internal: + if context.stylesheet_origin != Origin::UserAgent { + return PropertyDeclarationParseResult::UnknownProperty + } + % endif % if shorthand.experimental: if !::util::prefs::get_pref("${shorthand.experimental}") .as_boolean().unwrap_or(false) { @@ -7011,7 +7035,7 @@ macro_rules! css_properties_accessors { ($macro_name: ident) => { $macro_name! { % for property in SHORTHANDS + LONGHANDS: - % if property.derived_from is None: + % if property.derived_from is None and not property.internal: % if '-' in property.name: [${property.ident.capitalize()}, Set${property.ident.capitalize()}, "${property.name}"], % endif diff --git a/resources/servo.css b/resources/servo.css index 26d8fe90af2..dbd3f30e72a 100644 --- a/resources/servo.css +++ b/resources/servo.css @@ -31,5 +31,9 @@ td[align="right"] { text-align: right; } center { text-align: -servo-center; } input:not([type=radio i]):not([type=checkbox i]):not([type=reset i]):not([type=button i]):not([type=submit i]), -textarea { cursor: text } +textarea { + cursor: text; + overflow: hidden; + -servo-overflow-clip-box: content-box; +}