From 0bfd1dc5c07d5639b6086bbb271ff7186b761fee Mon Sep 17 00:00:00 2001 From: Morgan Rae Reschenberg Date: Wed, 30 May 2018 07:49:31 -0700 Subject: [PATCH] style: Add contain:size and contain:content parsing functionality. Bug: 1463589 Reviewed-by: emilio MozReview-Commit-ID: 4fOqln3oOpC --- components/style/properties/gecko.mako.rs | 36 ++++++++++++++++++++--- components/style/values/specified/box.rs | 24 +++++++++++---- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index baa1ed015ee..741aa7b86b4 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -3626,10 +3626,13 @@ fn static_assert() { pub fn set_contain(&mut self, v: longhands::contain::computed_value::T) { use gecko_bindings::structs::NS_STYLE_CONTAIN_NONE; use gecko_bindings::structs::NS_STYLE_CONTAIN_STRICT; + use gecko_bindings::structs::NS_STYLE_CONTAIN_CONTENT; + use gecko_bindings::structs::NS_STYLE_CONTAIN_SIZE; use gecko_bindings::structs::NS_STYLE_CONTAIN_LAYOUT; use gecko_bindings::structs::NS_STYLE_CONTAIN_STYLE; use gecko_bindings::structs::NS_STYLE_CONTAIN_PAINT; use gecko_bindings::structs::NS_STYLE_CONTAIN_ALL_BITS; + use gecko_bindings::structs::NS_STYLE_CONTAIN_CONTENT_BITS; use properties::longhands::contain::SpecifiedValue; if v.is_empty() { @@ -3641,6 +3644,10 @@ fn static_assert() { self.gecko.mContain = (NS_STYLE_CONTAIN_STRICT | NS_STYLE_CONTAIN_ALL_BITS) as u8; return; } + if v.contains(SpecifiedValue::CONTENT) { + self.gecko.mContain = (NS_STYLE_CONTAIN_CONTENT | NS_STYLE_CONTAIN_CONTENT_BITS) as u8; + return; + } let mut bitfield = 0; if v.contains(SpecifiedValue::LAYOUT) { @@ -3652,36 +3659,57 @@ fn static_assert() { if v.contains(SpecifiedValue::PAINT) { bitfield |= NS_STYLE_CONTAIN_PAINT; } + if v.contains(SpecifiedValue::SIZE) { + bitfield |= NS_STYLE_CONTAIN_SIZE; + } self.gecko.mContain = bitfield as u8; } pub fn clone_contain(&self) -> longhands::contain::computed_value::T { use gecko_bindings::structs::NS_STYLE_CONTAIN_STRICT; + use gecko_bindings::structs::NS_STYLE_CONTAIN_CONTENT; + use gecko_bindings::structs::NS_STYLE_CONTAIN_SIZE; use gecko_bindings::structs::NS_STYLE_CONTAIN_LAYOUT; use gecko_bindings::structs::NS_STYLE_CONTAIN_STYLE; use gecko_bindings::structs::NS_STYLE_CONTAIN_PAINT; use gecko_bindings::structs::NS_STYLE_CONTAIN_ALL_BITS; + use gecko_bindings::structs::NS_STYLE_CONTAIN_CONTENT_BITS; use properties::longhands::contain::{self, SpecifiedValue}; let mut servo_flags = contain::computed_value::T::empty(); let gecko_flags = self.gecko.mContain; - if gecko_flags & (NS_STYLE_CONTAIN_STRICT as u8) != 0 && - gecko_flags & (NS_STYLE_CONTAIN_ALL_BITS as u8) != 0 { + if gecko_flags & (NS_STYLE_CONTAIN_STRICT as u8) != 0 { + debug_assert_eq!( + gecko_flags & (NS_STYLE_CONTAIN_ALL_BITS as u8), + NS_STYLE_CONTAIN_ALL_BITS as u8, + "When strict is specified, ALL_BITS should be specified as well" + ); servo_flags.insert(SpecifiedValue::STRICT | SpecifiedValue::STRICT_BITS); return servo_flags; } - + if gecko_flags & (NS_STYLE_CONTAIN_CONTENT as u8) != 0 { + debug_assert_eq!( + gecko_flags & (NS_STYLE_CONTAIN_CONTENT_BITS as u8), + NS_STYLE_CONTAIN_CONTENT_BITS as u8, + "When content is specified, CONTENT_BITS should be specified as well" + ); + servo_flags.insert(SpecifiedValue::CONTENT | SpecifiedValue::CONTENT_BITS); + return servo_flags; + } if gecko_flags & (NS_STYLE_CONTAIN_LAYOUT as u8) != 0 { servo_flags.insert(SpecifiedValue::LAYOUT); } - if gecko_flags & (NS_STYLE_CONTAIN_STYLE as u8) != 0{ + if gecko_flags & (NS_STYLE_CONTAIN_STYLE as u8) != 0 { servo_flags.insert(SpecifiedValue::STYLE); } if gecko_flags & (NS_STYLE_CONTAIN_PAINT as u8) != 0 { servo_flags.insert(SpecifiedValue::PAINT); } + if gecko_flags & (NS_STYLE_CONTAIN_SIZE as u8) != 0 { + servo_flags.insert(SpecifiedValue::SIZE); + } return servo_flags; } diff --git a/components/style/values/specified/box.rs b/components/style/values/specified/box.rs index d716e9e6798..f418b39ef7d 100644 --- a/components/style/values/specified/box.rs +++ b/components/style/values/specified/box.rs @@ -525,19 +525,25 @@ pub fn assert_touch_action_matches() { bitflags! { #[derive(MallocSizeOf, SpecifiedValueInfo, ToComputedValue)] - #[value_info(other_values = "none,strict,layout,style,paint")] + #[value_info(other_values = "none,strict,content,size,layout,style,paint")] /// Constants for contain: https://drafts.csswg.org/css-contain/#contain-property pub struct Contain: u8 { + /// 'size' variant, turns on size containment + const SIZE = 0x01; /// `layout` variant, turns on layout containment - const LAYOUT = 0x01; + const LAYOUT = 0x02; /// `style` variant, turns on style containment - const STYLE = 0x02; + const STYLE = 0x04; /// `paint` variant, turns on paint containment - const PAINT = 0x04; + const PAINT = 0x08; /// `strict` variant, turns on all types of containment - const STRICT = 0x8; + const STRICT = 0x10; + /// 'content' variant, turns on style, layout, and paint containment + const CONTENT = 0x20; /// variant with all the bits that contain: strict turns on - const STRICT_BITS = Contain::LAYOUT.bits | Contain::STYLE.bits | Contain::PAINT.bits; + const STRICT_BITS = Contain::LAYOUT.bits | Contain::STYLE.bits | Contain::PAINT.bits | Contain::SIZE.bits; + /// variant with all the bits that contain: content turns on + const CONTENT_BITS = Contain::STYLE.bits | Contain::LAYOUT.bits | Contain::PAINT.bits; } } @@ -552,6 +558,9 @@ impl ToCss for Contain { if self.contains(Contain::STRICT) { return dest.write_str("strict"); } + if self.contains(Contain::CONTENT) { + return dest.write_str("content"); + } let mut has_any = false; macro_rules! maybe_write_value { @@ -565,6 +574,7 @@ impl ToCss for Contain { } }; } + maybe_write_value!(Contain::SIZE => "size"); maybe_write_value!(Contain::LAYOUT => "layout"); maybe_write_value!(Contain::STYLE => "style"); maybe_write_value!(Contain::PAINT => "paint"); @@ -583,10 +593,12 @@ impl Parse for Contain { let mut result = Contain::empty(); while let Ok(name) = input.try(|i| i.expect_ident_cloned()) { let flag = match_ignore_ascii_case! { &name, + "size" => Some(Contain::SIZE), "layout" => Some(Contain::LAYOUT), "style" => Some(Contain::STYLE), "paint" => Some(Contain::PAINT), "strict" if result.is_empty() => return Ok(Contain::STRICT | Contain::STRICT_BITS), + "content" if result.is_empty() => return Ok(Contain::CONTENT | Contain::CONTENT_BITS), "none" if result.is_empty() => return Ok(result), _ => None };