From 21d468ee65279f48ae83ae5fa1c375ff364b2bdd Mon Sep 17 00:00:00 2001 From: FranklinDM Date: Sun, 5 Mar 2023 00:24:59 +0800 Subject: [PATCH] Issue #2136 - Part 1: Implement CSS inset property --- layout/style/Declaration.cpp | 21 +++++++++++++-------- layout/style/nsCSSParser.cpp | 16 ++++++++++++++++ layout/style/nsCSSPropList.h | 7 +++++++ layout/style/nsCSSProps.cpp | 9 +++++++++ layout/style/nsDOMCSSAttrDeclaration.cpp | 1 + layout/style/nsDOMCSSDeclaration.cpp | 1 + layout/style/test/property_database.js | 12 ++++++++++++ 7 files changed, 59 insertions(+), 8 deletions(-) diff --git a/layout/style/Declaration.cpp b/layout/style/Declaration.cpp index 29cae7a3b6..6ef53f5db1 100644 --- a/layout/style/Declaration.cpp +++ b/layout/style/Declaration.cpp @@ -643,6 +643,7 @@ Declaration::GetPropertyValueInternal( nsCSSCompressedDataBlock *data = importantCount ? mImportantData : mData; switch (aProperty) { + case eCSSProperty_inset: case eCSSProperty_margin: case eCSSProperty_padding: case eCSSProperty_border_color: @@ -650,14 +651,18 @@ Declaration::GetPropertyValueInternal( case eCSSProperty_border_width: { const nsCSSPropertyID* subprops = nsCSSProps::SubpropertyEntryFor(aProperty); - MOZ_ASSERT(nsCSSProps::GetStringValue(subprops[0]).Find("-top") != - kNotFound, "first subprop must be top"); - MOZ_ASSERT(nsCSSProps::GetStringValue(subprops[1]).Find("-right") != - kNotFound, "second subprop must be right"); - MOZ_ASSERT(nsCSSProps::GetStringValue(subprops[2]).Find("-bottom") != - kNotFound, "third subprop must be bottom"); - MOZ_ASSERT(nsCSSProps::GetStringValue(subprops[3]).Find("-left") != - kNotFound, "fourth subprop must be left"); + // These assertions don't apply to the inset shorthand because + // they don't start with a dash and are simply just the sides. + if (aProperty != eCSSProperty_inset) { + MOZ_ASSERT(nsCSSProps::GetStringValue(subprops[0]).Find("-top") != + kNotFound, "first subprop must be top"); + MOZ_ASSERT(nsCSSProps::GetStringValue(subprops[1]).Find("-right") != + kNotFound, "second subprop must be right"); + MOZ_ASSERT(nsCSSProps::GetStringValue(subprops[2]).Find("-bottom") != + kNotFound, "third subprop must be bottom"); + MOZ_ASSERT(nsCSSProps::GetStringValue(subprops[3]).Find("-left") != + kNotFound, "fourth subprop must be left"); + } const nsCSSValue* vals[4] = { data->ValueFor(subprops[0]), data->ValueFor(subprops[1]), diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index ba8eedaf03..a88bfc764e 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -1045,6 +1045,7 @@ protected: bool ParseFontSrc(nsCSSValue& aValue); bool ParseFontSrcFormat(InfallibleTArray& values); bool ParseFontRanges(nsCSSValue& aValue); + bool ParseInset(); bool ParseListStyle(); bool ParseListStyleType(nsCSSValue& aValue); bool ParseMargin(); @@ -11815,6 +11816,8 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSPropertyID aPropID) return ParseInitialLetter(); case eCSSProperty_justify_items: return ParseJustifyItems(); + case eCSSProperty_inset: + return ParseInset(); case eCSSProperty_list_style: return ParseListStyle(); case eCSSProperty_margin: @@ -15243,6 +15246,19 @@ CSSParserImpl::ParseListStyle() return true; } +bool +CSSParserImpl::ParseInset() +{ + static const nsCSSPropertyID kInsetSideIDs[] = { + eCSSProperty_top, + eCSSProperty_right, + eCSSProperty_bottom, + eCSSProperty_left + }; + + return ParseBoxProperties(kInsetSideIDs); +} + bool CSSParserImpl::ParseListStyleType(nsCSSValue& aValue) { diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index bd749df5b4..f2903273e5 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -2334,6 +2334,13 @@ CSS_PROP_LOGICAL( Position, CSS_PROP_NO_OFFSET, eStyleAnimType_None) +CSS_PROP_SHORTHAND( + inset, + inset, + Inset, + CSS_PROPERTY_PARSE_FUNCTION | + CSS_PROPERTY_UNITLESS_LENGTH_QUIRK, + "") CSS_PROP_DISPLAY( isolation, isolation, diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index 0663a7f15f..0f3a1daeda 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -2902,6 +2902,15 @@ static const nsCSSPropertyID gFontVariantSubpropTable[] = { eCSSProperty_UNKNOWN }; +static const nsCSSPropertyID gInsetSubpropTable[] = { + // Code relies on these being in top-right-bottom-left order. + eCSSProperty_top, + eCSSProperty_right, + eCSSProperty_bottom, + eCSSProperty_left, + eCSSProperty_UNKNOWN +}; + static const nsCSSPropertyID gListStyleSubpropTable[] = { eCSSProperty_list_style_type, eCSSProperty_list_style_image, diff --git a/layout/style/nsDOMCSSAttrDeclaration.cpp b/layout/style/nsDOMCSSAttrDeclaration.cpp index 652bd4ad17..d79d2f8e2f 100644 --- a/layout/style/nsDOMCSSAttrDeclaration.cpp +++ b/layout/style/nsDOMCSSAttrDeclaration.cpp @@ -199,6 +199,7 @@ nsDOMCSSAttributeDeclaration::SetPropertyValue(const nsCSSPropertyID aPropID, // FIXME: This is missing the margin shorthand and the logical versions of // the margin properties, see bug 1266287. if (aPropID == eCSSProperty_opacity || aPropID == eCSSProperty_transform || + aPropID == eCSSProperty_inset || aPropID == eCSSProperty_left || aPropID == eCSSProperty_top || aPropID == eCSSProperty_right || aPropID == eCSSProperty_bottom || aPropID == eCSSProperty_margin_left || aPropID == eCSSProperty_margin_top || diff --git a/layout/style/nsDOMCSSDeclaration.cpp b/layout/style/nsDOMCSSDeclaration.cpp index 51ce8c335c..ca4dda5ab7 100644 --- a/layout/style/nsDOMCSSDeclaration.cpp +++ b/layout/style/nsDOMCSSDeclaration.cpp @@ -64,6 +64,7 @@ nsDOMCSSDeclaration::SetPropertyValue(const nsCSSPropertyID aPropID, case eCSSProperty_background_position_x: case eCSSProperty_background_position_y: case eCSSProperty_transform: + case eCSSProperty_inset: case eCSSProperty_top: case eCSSProperty_left: case eCSSProperty_bottom: diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index 9eb7efc38c..46ef89ba0c 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -5403,6 +5403,18 @@ var gCSSProperties = { ], invalid_values: [ "none", "5" ] }, + "inset": { + domProp: "inset", + inherited: false, + type: CSS_TYPE_TRUE_SHORTHAND, + subproperties: [ "top", "right", "bottom", "left" ], + /* FIXME: run tests with multiple prerequisites */ + prerequisites: { "position": "relative" }, + initial_values: [ "auto" ], + other_values: [ "3px 0", "2em 4px 2pt", "1em 2em 3px 4px", "1em calc(2em + 3px) 4ex 5cm" ], + invalid_values: [ "1px calc(nonsense)", "1px red", "3" ], + unbalanced_values: [ "1px calc(" ], + }, "inset-block-end": { domProp: "insetBlockEnd", inherited: false,