From 801d4a2db8d078852b1b04ce9cafc1370ff11084 Mon Sep 17 00:00:00 2001 From: Francis Dominic Fajardo Date: Fri, 20 Jun 2025 10:33:40 +0800 Subject: [PATCH] Issue #2045 - Part 5: Serialize shorthands using "revert" like those containing "unset" --- layout/style/CSSVariableDeclarations.cpp | 32 +++++++++++------ layout/style/CSSVariableDeclarations.h | 16 +++++++-- layout/style/Declaration.cpp | 44 ++++++++++++++++++------ 3 files changed, 68 insertions(+), 24 deletions(-) diff --git a/layout/style/CSSVariableDeclarations.cpp b/layout/style/CSSVariableDeclarations.cpp index 34a2bb0357..70194892c3 100644 --- a/layout/style/CSSVariableDeclarations.cpp +++ b/layout/style/CSSVariableDeclarations.cpp @@ -11,12 +11,13 @@ #include "nsCSSScanner.h" #include "nsRuleData.h" -// These three special string values are used to represent specified values of -// 'initial', 'inherit' and 'unset'. (Note that none of these are valid -// variable values.) +// These four special string values are used to represent specified values of +// 'initial', 'inherit', 'unset', and 'revert'. (Note that none of these are +// valid variable values.) #define INITIAL_VALUE "!" #define INHERIT_VALUE ";" #define UNSET_VALUE ")" +#define REVERT_VALUE ">" namespace mozilla { @@ -83,6 +84,9 @@ CSSVariableDeclarations::Get(const nsAString& aName, } else if (value.EqualsLiteral(UNSET_VALUE)) { aType = eUnset; aTokenStream.Truncate(); + } else if (value.EqualsLiteral(REVERT_VALUE)) { + aType = eRevert; + aTokenStream.Truncate(); } else { aType = eTokenStream; aTokenStream = value; @@ -96,7 +100,8 @@ CSSVariableDeclarations::PutTokenStream(const nsAString& aName, { MOZ_ASSERT(!aTokenStream.EqualsLiteral(INITIAL_VALUE) && !aTokenStream.EqualsLiteral(INHERIT_VALUE) && - !aTokenStream.EqualsLiteral(UNSET_VALUE)); + !aTokenStream.EqualsLiteral(UNSET_VALUE) && + !aTokenStream.EqualsLiteral(REVERT_VALUE)); mVariables.Put(aName, aTokenStream); } @@ -118,6 +123,12 @@ CSSVariableDeclarations::PutUnset(const nsAString& aName) mVariables.Put(aName, NS_LITERAL_STRING(UNSET_VALUE)); } +void +CSSVariableDeclarations::PutRevert(const nsAString& aName) +{ + mVariables.Put(aName, NS_LITERAL_STRING(REVERT_VALUE)); +} + void CSSVariableDeclarations::Remove(const nsAString& aName) { @@ -160,12 +171,13 @@ CSSVariableDeclarations::AddVariablesToResolver( eCSSTokenSerialization_Nothing, false); } else if (value.EqualsLiteral(INHERIT_VALUE) || - value.EqualsLiteral(UNSET_VALUE)) { - // Values of 'inherit' and 'unset' don't need any handling, since it means - // we just need to keep whatever value is currently in the resolver. This - // is because the specified variable declarations already have only the - // winning declaration for the variable and no longer have any of the - // others. + value.EqualsLiteral(UNSET_VALUE) || + value.EqualsLiteral(REVERT_VALUE)) { + // Values of 'inherit', 'unset', and 'revert' don't need any handling, + // since it means we just need to keep whatever value is currently in + // the resolver. This is because the specified variable declarations + // already have only the winning declaration for the variable and no + // longer have any of the others. } else { // At this point, we don't know what token types are at the start and end // of the specified variable value. These will be determined later during diff --git a/layout/style/CSSVariableDeclarations.h b/layout/style/CSSVariableDeclarations.h index 294e71a004..833daa7639 100644 --- a/layout/style/CSSVariableDeclarations.h +++ b/layout/style/CSSVariableDeclarations.h @@ -42,7 +42,8 @@ public: eTokenStream, // a stream of CSS tokens (the usual type for variables) eInitial, // 'initial' eInherit, // 'inherit' - eUnset // 'unset' + eUnset, // 'unset' + eRevert // 'revert' }; /** @@ -53,8 +54,8 @@ public: * @param aType Out parameter into which the type of the variable value will * be stored. * @param aValue Out parameter into which the value of the variable will - * be stored. If the variable is 'initial', 'inherit' or 'unset', this will - * be the empty string. + * be stored. If the variable is 'initial', 'inherit', 'unset', or + * 'revert', this will be the empty string. * @return Whether a variable with the given name was found. When false * is returned, aType and aValue will not be modified. */ @@ -87,6 +88,15 @@ public: */ void PutUnset(const nsAString& aName); + /** + * Adds or modifies an existing entry in this set of variable declarations + * to have the value 'revert'. + * + * @param aName The variable name (not including any "--" prefix that would + * be part of the custom property name) whose value is to be set. + */ + void PutRevert(const nsAString& aName); + /** * Adds or modifies an existing entry in this set of variable declarations * to have a token stream value. diff --git a/layout/style/Declaration.cpp b/layout/style/Declaration.cpp index 5d88feee26..f4197439f8 100644 --- a/layout/style/Declaration.cpp +++ b/layout/style/Declaration.cpp @@ -558,9 +558,9 @@ Declaration::GetPropertyValueInternal( // (1) Since a shorthand sets all sub-properties, if some of its // subproperties were not specified, we must return the empty // string. - // (2) Since 'inherit', 'initial' and 'unset' can only be specified - // as the values for entire properties, we need to return the - // empty string if some but not all of the subproperties have one + // (2) Since 'inherit', 'initial', 'unset', and 'revert' can only be + // specified as the values for entire properties, we need to return + // the empty string if some but not all of the subproperties have one // of those values. // (3) Since a single value only makes sense with or without // !important, we return the empty string if some values are @@ -575,7 +575,7 @@ Declaration::GetPropertyValueInternal( // assigned to the shorthand. const nsCSSValue* tokenStream = nullptr; uint32_t totalCount = 0, importantCount = 0, - initialCount = 0, inheritCount = 0, unsetCount = 0, + initialCount = 0, inheritCount = 0, unsetCount = 0, revertCount = 0, matchingTokenStreamCount = 0, nonMatchingTokenStreamCount = 0; CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p, aProperty, CSSEnabledState::eForAllContent) { @@ -601,6 +601,8 @@ Declaration::GetPropertyValueInternal( ++initialCount; } else if (val->GetUnit() == eCSSUnit_Unset) { ++unsetCount; + } else if (val->GetUnit() == eCSSUnit_Revert) { + ++revertCount; } else if (val->GetUnit() == eCSSUnit_TokenStream) { if (val->GetTokenStreamValue()->mShorthandPropertyID == aProperty) { tokenStream = val; @@ -632,9 +634,15 @@ Declaration::GetPropertyValueInternal( nsCSSValue::eNormalized); return; } - if (initialCount != 0 || inheritCount != 0 || - unsetCount != 0 || nonMatchingTokenStreamCount != 0) { - // Case (2): partially initial, inherit, unset or token stream. + if (revertCount == totalCount) { + // Simplify serialization below by serializing revert up-front. + nsCSSValue(eCSSUnit_Revert).AppendToString(eCSSProperty_UNKNOWN, aValue, + nsCSSValue::eNormalized); + return; + } + if (initialCount != 0 || inheritCount != 0 || unsetCount != 0 || + revertCount != 0 || nonMatchingTokenStreamCount != 0) { + // Case (2): partially initial, inherit, unset, revert, or token stream. return; } if (tokenStream) { @@ -1455,6 +1463,7 @@ Declaration::GetPropertyValueInternal( case eCSSUnit_Inherit: case eCSSUnit_Initial: case eCSSUnit_Unset: + case eCSSUnit_Revert: return true; case eCSSUnit_Enumerated: // return false if there is a fallback value or @@ -1563,10 +1572,10 @@ Declaration::GetPropertyValueInternal( break; } case eCSSProperty_all: - // If we got here, then we didn't have all "inherit" or "initial" or - // "unset" values for all of the longhand property components of 'all'. - // There is no other possible value that is valid for all properties, - // so serialize as the empty string. + // If we got here, then we didn't have all "inherit", "initial", "unset", + // or "revert" values for all of the longhand property components of + // 'all'. There is no other possible value that is valid for all + // properties, so serialize as the empty string. break; default: MOZ_ASSERT(false, "no other shorthands"); @@ -1663,6 +1672,10 @@ Declaration::AppendVariableAndValueToString(const nsAString& aName, aResult.AppendLiteral("unset"); break; + case CSSVariableDeclarations::eRevert: + aResult.AppendLiteral("revert"); + break; + default: MOZ_ASSERT(false, "unexpected variable value type"); } @@ -1899,6 +1912,10 @@ Declaration::GetVariableValue(const nsAString& aName, nsAString& aValue) const aValue.AppendLiteral("unset"); break; + case CSSVariableDeclarations::eRevert: + aValue.AppendLiteral("revert"); + break; + default: MOZ_ASSERT(false, "unexpected variable value type"); } @@ -1964,6 +1981,11 @@ Declaration::AddVariable(const nsAString& aName, variables->PutUnset(aName); break; + case CSSVariableDeclarations::eRevert: + MOZ_ASSERT(aValue.IsEmpty()); + variables->PutRevert(aName); + break; + default: MOZ_ASSERT(false, "unexpected aType value"); }