Bug 1463589 - Add contain:size parse functionality.
MozReview-Commit-ID: LriIVuQNzxT
--- a/layout/style/nsCSSKeywordList.h
+++ b/layout/style/nsCSSKeywordList.h
@@ -30,17 +30,17 @@
'name' entries *must* use only lowercase characters.
** Break these invariants and bad things will happen. **
******/
// OUTPUT_CLASS=nsCSSKeywords
// MACRO_NAME=CSS_KEY
-
+CSS_KEY(size, size)
CSS_KEY(-moz-activehyperlinktext, _moz_activehyperlinktext)
CSS_KEY(-moz-all, _moz_all)
CSS_KEY(-moz-alt-content, _moz_alt_content)
CSS_KEY(-moz-available, _moz_available)
CSS_KEY(-moz-box, _moz_box)
CSS_KEY(-moz-button, _moz_button)
CSS_KEY(-moz-buttondefault, _moz_buttondefault)
CSS_KEY(-moz-buttonhoverface, _moz_buttonhoverface)
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -1047,16 +1047,17 @@ const KTableEntry nsCSSProps::kListStyle
const KTableEntry nsCSSProps::kContainKTable[] = {
{ eCSSKeyword_none, NS_STYLE_CONTAIN_NONE },
{ eCSSKeyword_strict, NS_STYLE_CONTAIN_STRICT },
{ eCSSKeyword_content, NS_STYLE_CONTAIN_CONTENT },
{ eCSSKeyword_layout, NS_STYLE_CONTAIN_LAYOUT },
{ eCSSKeyword_style, NS_STYLE_CONTAIN_STYLE },
{ eCSSKeyword_paint, NS_STYLE_CONTAIN_PAINT },
+ { eCSSKeyword_size, NS_STYLE_CONTAIN_SIZE },
{ eCSSKeyword_UNKNOWN, -1 }
};
const KTableEntry nsCSSProps::kObjectFitKTable[] = {
{ eCSSKeyword_fill, NS_STYLE_OBJECT_FIT_FILL },
{ eCSSKeyword_contain, NS_STYLE_OBJECT_FIT_CONTAIN },
{ eCSSKeyword_cover, NS_STYLE_OBJECT_FIT_COVER },
{ eCSSKeyword_none, NS_STYLE_OBJECT_FIT_NONE },
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -5040,28 +5040,29 @@ nsComputedDOMStyle::DoGetContain()
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
int32_t mask = StyleDisplay()->mContain;
if (mask == 0) {
val->SetIdent(eCSSKeyword_none);
} else if (mask & NS_STYLE_CONTAIN_STRICT) {
NS_ASSERTION(mask == (NS_STYLE_CONTAIN_STRICT | NS_STYLE_CONTAIN_ALL_BITS),
- "contain: strict should imply contain: layout style paint");
+ "contain: strict should imply contain: size layout style paint");
val->SetIdent(eCSSKeyword_strict);
} else if (mask & NS_STYLE_CONTAIN_CONTENT) {
NS_ASSERTION(mask == (NS_STYLE_CONTAIN_CONTENT | NS_STYLE_CONTAIN_CONTENT_BITS),
"contain: content should imply contain: layout style paint");
val->SetIdent(eCSSKeyword_content);
} else {
nsAutoString valueStr;
nsStyleUtil::AppendBitmaskCSSValue(nsCSSProps::kContainKTable,
- mask, NS_STYLE_CONTAIN_LAYOUT,
- NS_STYLE_CONTAIN_PAINT, valueStr);
+ mask,
+ NS_STYLE_CONTAIN_SIZE, NS_STYLE_CONTAIN_PAINT,
+ valueStr);
val->SetString(valueStr);
}
return val.forget();
}
already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetPosition()
--- a/layout/style/nsStyleConsts.h
+++ b/layout/style/nsStyleConsts.h
@@ -453,16 +453,17 @@ enum class StyleDisplay : uint8_t {
MozPopup,
#endif
};
// See nsStyleDisplay
// If these are re-ordered, nsComputedDOMStyle::DoGetContain() and
// nsCSSValue::AppendToString() must be updated.
#define NS_STYLE_CONTAIN_NONE 0
+#define NS_STYLE_CONTAIN_SIZE 0x01
#define NS_STYLE_CONTAIN_LAYOUT 0x02
#define NS_STYLE_CONTAIN_STYLE 0x04
#define NS_STYLE_CONTAIN_PAINT 0x08
#define NS_STYLE_CONTAIN_STRICT 0x10
#define NS_STYLE_CONTAIN_CONTENT 0x20
// NS_STYLE_CONTAIN_ALL_BITS does not correspond to a keyword.
#define NS_STYLE_CONTAIN_ALL_BITS (NS_STYLE_CONTAIN_LAYOUT | \
NS_STYLE_CONTAIN_STYLE | \
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -7273,24 +7273,28 @@ if (IsCSSPropertyPrefEnabled("layout.css
domProp: "contain",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "none" ],
other_values: [
"strict",
"layout",
"style",
+ "size",
"content",
"layout style",
"style layout",
"paint",
"layout paint",
"paint layout",
"style paint",
"paint style",
+ "size layout",
+ "style size",
+ "paint size",
"layout style paint",
"layout paint style",
"style paint layout",
"paint style layout",
],
invalid_values: [
"none strict",
"strict layout",
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -3623,16 +3623,17 @@ fn static_assert() {
}
<% impl_shape_source("shape_outside", "mShapeOutside") %>
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() {
@@ -3654,23 +3655,27 @@ fn static_assert() {
bitfield |= NS_STYLE_CONTAIN_LAYOUT;
}
if v.contains(SpecifiedValue::STYLE) {
bitfield |= NS_STYLE_CONTAIN_STYLE;
}
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();
@@ -3691,16 +3696,19 @@ fn static_assert() {
servo_flags.insert(SpecifiedValue::LAYOUT);
}
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;
}
${impl_simple_copy("contain", "mContain")}
${impl_simple_type_with_conversion("touch_action")}
</%self:impl_trait>
--- a/servo/components/style/values/specified/box.rs
+++ b/servo/components/style/values/specified/box.rs
@@ -520,31 +520,33 @@ pub fn assert_touch_action_matches() {
NS_STYLE_TOUCH_ACTION_PAN_X => TouchAction::TOUCH_ACTION_PAN_X,
NS_STYLE_TOUCH_ACTION_PAN_Y => TouchAction::TOUCH_ACTION_PAN_Y,
NS_STYLE_TOUCH_ACTION_MANIPULATION => TouchAction::TOUCH_ACTION_MANIPULATION,
}
}
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 = 0x02;
/// `style` variant, turns on style containment
const STYLE = 0x04;
/// `paint` variant, turns on paint containment
const PAINT = 0x08;
/// `strict` variant, turns on all types of containment
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;
}
}
impl ToCss for Contain {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
@@ -567,16 +569,17 @@ impl ToCss for Contain {
if has_any {
dest.write_str(" ")?;
}
has_any = true;
dest.write_str($str)?;
}
};
}
+ maybe_write_value!(Contain::SIZE => "size");
maybe_write_value!(Contain::LAYOUT => "layout");
maybe_write_value!(Contain::STYLE => "style");
maybe_write_value!(Contain::PAINT => "paint");
debug_assert!(has_any);
Ok(())
}
}
@@ -585,16 +588,17 @@ impl Parse for Contain {
/// none | strict | content | [ size || layout || style || paint ]
fn parse<'i, 't>(
_context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Contain, ParseError<'i>> {
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
};