diff --git a/layout/style/Declaration.cpp b/layout/style/Declaration.cpp index c6f679a8cb43..53b920782b44 100644 --- a/layout/style/Declaration.cpp +++ b/layout/style/Declaration.cpp @@ -1022,7 +1022,7 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue, // which isn't a value that the shorthand can express. Bail. return; } - const GridTemplateAreasValue& areas = areasValue.GetGridTemplateAreas(); + const GridTemplateAreasValue* areas = areasValue.GetGridTemplateAreas(); const nsCSSValueList* rowsItem = rowsValue.GetListValue(); uint32_t nRowItems = 0; while (rowsItem) { @@ -1030,7 +1030,7 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue, rowsItem = rowsItem->mNext; } MOZ_ASSERT(nRowItems % 2 == 1, "expected an odd number of items"); - if ((nRowItems - 1) / 2 != areas.NRows()) { + if ((nRowItems - 1) / 2 != areas->NRows()) { // Not serializable, bail. return; } @@ -1057,7 +1057,7 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue, aValue.AppendLiteral(")"); } else { - nsStyleUtil::AppendEscapedCSSString(areas.mTemplates[row++], aValue); + nsStyleUtil::AppendEscapedCSSString(areas->mTemplates[row++], aValue); aValue.Append(char16_t(' ')); // diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index e6cd085742b6..8d94aa940848 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -673,7 +673,7 @@ protected: // |aAreaIndices| is a lookup table to help us parse faster, // mapping area names to indices in |aResult.mNamedAreas|. bool ParseGridTemplateAreasLine(const nsAutoString& aInput, - css::GridTemplateAreasValue& aResult, + css::GridTemplateAreasValue* aResult, nsDataHashtable& aAreaIndices); bool ParseGridTemplateAreas(); bool ParseGridTemplate(); @@ -7156,15 +7156,15 @@ CSSParserImpl::ParseGridTemplateColumnsRows(nsCSSProperty aPropID) bool CSSParserImpl::ParseGridTemplateAreasLine(const nsAutoString& aInput, - css::GridTemplateAreasValue& aAreas, + css::GridTemplateAreasValue* aAreas, nsDataHashtable& aAreaIndices) { - aAreas.mTemplates.AppendElement(mToken.mIdent); + aAreas->mTemplates.AppendElement(mToken.mIdent); nsCSSGridTemplateAreaScanner scanner(aInput); nsCSSGridTemplateAreaToken token; css::GridNamedArea* currentArea = nullptr; - uint32_t row = aAreas.NRows(); + uint32_t row = aAreas->NRows(); uint32_t column; for (column = 1; scanner.Next(token); column++) { if (token.isTrash) { @@ -7194,9 +7194,9 @@ CSSParserImpl::ParseGridTemplateAreasLine(const nsAutoString& aInput, // Check if this is the continuation of an existing named area: uint32_t index; if (aAreaIndices.Get(token.mName, &index)) { - MOZ_ASSERT(index < aAreas.mNamedAreas.Length(), + MOZ_ASSERT(index < aAreas->mNamedAreas.Length(), "Invalid aAreaIndices hash table"); - currentArea = &aAreas.mNamedAreas[index]; + currentArea = &aAreas->mNamedAreas[index]; if (currentArea->mColumnStart != column || currentArea->mRowEnd != row) { // Existing named area, but not forming a rectangle @@ -7206,8 +7206,8 @@ CSSParserImpl::ParseGridTemplateAreasLine(const nsAutoString& aInput, currentArea->mRowEnd++; } else { // New named area - aAreaIndices.Put(token.mName, aAreas.mNamedAreas.Length()); - currentArea = aAreas.mNamedAreas.AppendElement(); + aAreaIndices.Put(token.mName, aAreas->mNamedAreas.Length()); + currentArea = aAreas->mNamedAreas.AppendElement(); currentArea->mName = token.mName; // For column or row N (starting at 1), // the start line is N, the end line is N + 1 @@ -7230,8 +7230,8 @@ CSSParserImpl::ParseGridTemplateAreasLine(const nsAutoString& aInput, // On other rows, check that the number of columns is consistent // between rows. if (row == 1) { - aAreas.mNColumns = column; - } else if (aAreas.mNColumns != column) { + aAreas->mNColumns = column; + } else if (aAreas->mNColumns != column) { return false; } return true; @@ -7246,7 +7246,8 @@ CSSParserImpl::ParseGridTemplateAreas() return true; } - css::GridTemplateAreasValue& areas = value.SetGridTemplateAreas(); + nsRefPtr areas = + new css::GridTemplateAreasValue(); nsDataHashtable areaIndices; for (;;) { if (!GetToken(true)) { @@ -7261,11 +7262,11 @@ CSSParserImpl::ParseGridTemplateAreas() } } - if (areas.NRows() == 0) { + if (areas->NRows() == 0) { return false; } - AppendValue(eCSSProperty_grid_template_areas, value); + AppendValue(eCSSProperty_grid_template_areas, nsCSSValue(areas)); return true; } @@ -7366,9 +7367,9 @@ CSSParserImpl::ParseGridTemplateAfterString(const nsCSSValue& aFirstLineNames) MOZ_ASSERT(mToken.mType == eCSSToken_String, "ParseGridTemplateAfterString called with a non-string token"); - nsCSSValue areasValue; nsCSSValue rowsValue; - css::GridTemplateAreasValue& areas = areasValue.SetGridTemplateAreas(); + nsRefPtr areas = + new css::GridTemplateAreasValue(); nsDataHashtable areaIndices; nsCSSValueList* rowsItem = rowsValue.SetListValue(); rowsItem->mValue = aFirstLineNames; @@ -7410,7 +7411,7 @@ CSSParserImpl::ParseGridTemplateAfterString(const nsCSSValue& aFirstLineNames) } } - AppendValue(eCSSProperty_grid_template_areas, areasValue); + AppendValue(eCSSProperty_grid_template_areas, nsCSSValue(areas)); AppendValue(eCSSProperty_grid_template_rows, rowsValue); return true; } diff --git a/layout/style/nsCSSValue.cpp b/layout/style/nsCSSValue.cpp index fa25349bd768..712ec1c958e7 100644 --- a/layout/style/nsCSSValue.cpp +++ b/layout/style/nsCSSValue.cpp @@ -104,6 +104,13 @@ nsCSSValue::nsCSSValue(nsCSSValueTokenStream* aValue) mValue.mTokenStream->AddRef(); } +nsCSSValue::nsCSSValue(mozilla::css::GridTemplateAreasValue* aValue) + : mUnit(eCSSUnit_GridTemplateAreas) +{ + mValue.mGridTemplateAreas = aValue; + mValue.mGridTemplateAreas->AddRef(); +} + nsCSSValue::nsCSSValue(const nsCSSValue& aCopy) : mUnit(aCopy.mUnit) { @@ -460,6 +467,14 @@ void nsCSSValue::SetTokenStreamValue(nsCSSValueTokenStream* aValue) mValue.mTokenStream->AddRef(); } +void nsCSSValue::SetGridTemplateAreas(mozilla::css::GridTemplateAreasValue* aValue) +{ + Reset(); + mUnit = eCSSUnit_GridTemplateAreas; + mValue.mGridTemplateAreas = aValue; + mValue.mGridTemplateAreas->AddRef(); +} + void nsCSSValue::SetPairValue(const nsCSSValuePair* aValue) { // pairs should not be used for null/inherit/initial values @@ -596,15 +611,6 @@ void nsCSSValue::SetDependentPairListValue(nsCSSValuePairList* aList) } } -mozilla::css::GridTemplateAreasValue& nsCSSValue::SetGridTemplateAreas() -{ - Reset(); - mUnit = eCSSUnit_GridTemplateAreas; - mValue.mGridTemplateAreas = new mozilla::css::GridTemplateAreasValue; - mValue.mGridTemplateAreas->AddRef(); - return *mValue.mGridTemplateAreas; -} - void nsCSSValue::SetAutoValue() { Reset(); @@ -1345,13 +1351,13 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult, break; } } else if (eCSSUnit_GridTemplateAreas == unit) { - const mozilla::css::GridTemplateAreasValue& areas = GetGridTemplateAreas(); - MOZ_ASSERT(!areas.mTemplates.IsEmpty(), + const mozilla::css::GridTemplateAreasValue* areas = GetGridTemplateAreas(); + MOZ_ASSERT(!areas->mTemplates.IsEmpty(), "Unexpected empty array in GridTemplateAreasValue"); - nsStyleUtil::AppendEscapedCSSString(areas.mTemplates[0], aResult); - for (uint32_t i = 1; i < areas.mTemplates.Length(); i++) { + nsStyleUtil::AppendEscapedCSSString(areas->mTemplates[0], aResult); + for (uint32_t i = 1; i < areas->mTemplates.Length(); i++) { aResult.Append(char16_t(' ')); - nsStyleUtil::AppendEscapedCSSString(areas.mTemplates[i], aResult); + nsStyleUtil::AppendEscapedCSSString(areas->mTemplates[i], aResult); } } diff --git a/layout/style/nsCSSValue.h b/layout/style/nsCSSValue.h index 01fa40073cd0..753938ce9d9d 100644 --- a/layout/style/nsCSSValue.h +++ b/layout/style/nsCSSValue.h @@ -144,7 +144,7 @@ struct GridNamedArea { uint32_t mRowEnd; }; -struct GridTemplateAreasValue { +struct GridTemplateAreasValue MOZ_FINAL { // Parsed value nsTArray mNamedAreas; @@ -168,13 +168,6 @@ struct GridTemplateAreasValue { { } - void Reset() - { - mNamedAreas.Clear(); - mTemplates.Clear(); - mNColumns = 0; - } - bool operator==(const GridTemplateAreasValue& aOther) const { return mTemplates == aOther.mTemplates; @@ -188,6 +181,17 @@ struct GridTemplateAreasValue { NS_INLINE_DECL_REFCOUNTING(GridTemplateAreasValue) size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + +private: + // Private destructor to make sure this isn't used as a stack variable + // or member variable. + ~GridTemplateAreasValue() + { + } + + GridTemplateAreasValue(const GridTemplateAreasValue& aOther) MOZ_DELETE; + GridTemplateAreasValue& + operator=(const GridTemplateAreasValue& aOther) MOZ_DELETE; }; } @@ -247,6 +251,8 @@ enum nsCSSUnit { eCSSUnit_Image = 41, // (nsCSSValue::Image*) value eCSSUnit_Gradient = 42, // (nsCSSValueGradient*) value eCSSUnit_TokenStream = 43, // (nsCSSValueTokenStream*) value + eCSSUnit_GridTemplateAreas = 44, // (GridTemplateAreasValue*) + // for grid-template-areas eCSSUnit_Pair = 50, // (nsCSSValuePair*) pair of values eCSSUnit_Triplet = 51, // (nsCSSValueTriplet*) triplet of values @@ -260,8 +266,6 @@ enum nsCSSUnit { eCSSUnit_PairListDep = 57, // (nsCSSValuePairList*) same as PairList // but does not own the list - eCSSUnit_GridTemplateAreas = 60, // (GridTemplateAreasValue*) for grid-template-areas - eCSSUnit_Integer = 70, // (int) simple value eCSSUnit_Enumerated = 71, // (int) value has enumerated meaning @@ -359,6 +363,7 @@ public: explicit nsCSSValue(mozilla::css::ImageValue* aValue); explicit nsCSSValue(nsCSSValueGradient* aValue); explicit nsCSSValue(nsCSSValueTokenStream* aValue); + explicit nsCSSValue(mozilla::css::GridTemplateAreasValue* aValue); nsCSSValue(const nsCSSValue& aCopy); ~nsCSSValue() { Reset(); } @@ -553,8 +558,6 @@ public: inline nsCSSValueTriplet& GetTripletValue(); inline const nsCSSValueTriplet& GetTripletValue() const; - inline mozilla::css::GridTemplateAreasValue& GetGridTemplateAreas(); - inline const mozilla::css::GridTemplateAreasValue& GetGridTemplateAreas() const; mozilla::css::URLValue* GetURLStructValue() const { @@ -570,6 +573,13 @@ public: return mValue.mImage; } + mozilla::css::GridTemplateAreasValue* GetGridTemplateAreas() const + { + NS_ABORT_IF_FALSE(mUnit == eCSSUnit_GridTemplateAreas, + "not a grid-template-areas value"); + return mValue.mGridTemplateAreas; + } + const char16_t* GetOriginalURLValue() const { NS_ABORT_IF_FALSE(mUnit == eCSSUnit_URL || mUnit == eCSSUnit_Image, @@ -611,6 +621,7 @@ public: void SetImageValue(mozilla::css::ImageValue* aImage); void SetGradientValue(nsCSSValueGradient* aGradient); void SetTokenStreamValue(nsCSSValueTokenStream* aTokenStream); + void SetGridTemplateAreas(mozilla::css::GridTemplateAreasValue* aValue); void SetPairValue(const nsCSSValuePair* aPair); void SetPairValue(const nsCSSValue& xValue, const nsCSSValue& yValue); void SetSharedListValue(nsCSSValueSharedList* aList); @@ -634,7 +645,6 @@ public: nsCSSRect& SetRectValue(); nsCSSValueList* SetListValue(); nsCSSValuePairList* SetPairListValue(); - mozilla::css::GridTemplateAreasValue& SetGridTemplateAreas(); void StartImageLoad(nsIDocument* aDocument) const; // Only pretend const @@ -1246,22 +1256,6 @@ nsCSSValue::GetPairListValue() const } } -inline mozilla::css::GridTemplateAreasValue& -nsCSSValue::GetGridTemplateAreas() -{ - NS_ABORT_IF_FALSE (mUnit == eCSSUnit_GridTemplateAreas, - "not a grid-template-areas value"); - return *mValue.mGridTemplateAreas; -} - -inline const mozilla::css::GridTemplateAreasValue& -nsCSSValue::GetGridTemplateAreas() const -{ - NS_ABORT_IF_FALSE (mUnit == eCSSUnit_GridTemplateAreas, - "not a grid-template-areas value"); - return *mValue.mGridTemplateAreas; -} - struct nsCSSValueGradientStop { public: nsCSSValueGradientStop(); diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index ef2d5c681019..2aca0edf1420 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -2274,18 +2274,20 @@ nsComputedDOMStyle::DoGetBackgroundSize() CSSValue* nsComputedDOMStyle::DoGetGridTemplateAreas() { - const nsTArray& templates = - StylePosition()->mGridTemplateAreas.mTemplates; - if (templates.IsEmpty()) { + const css::GridTemplateAreasValue* areas = + StylePosition()->mGridTemplateAreas; + if (!areas) { nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; val->SetIdent(eCSSKeyword_none); return val; } + MOZ_ASSERT(!areas->mTemplates.IsEmpty(), + "Unexpected empty array in GridTemplateAreasValue"); nsDOMCSSValueList *valueList = GetROCSSValueList(false); - for (uint32_t i = 0; i < templates.Length(); i++) { + for (uint32_t i = 0; i < areas->mTemplates.Length(); i++) { nsAutoString str; - nsStyleUtil::AppendEscapedCSSString(templates[i], str); + nsStyleUtil::AppendEscapedCSSString(areas->mTemplates[i], str); nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; val->SetString(str); valueList->AppendCSSValue(val); diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index d3ec80d084af..81081c122c24 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -7234,8 +7234,8 @@ SetGridTrackList(const nsCSSValue& aValue, static void SetGridTemplateAreas(const nsCSSValue& aValue, - css::GridTemplateAreasValue& aResult, - const css::GridTemplateAreasValue& aParentValue, + nsRefPtr* aResult, + css::GridTemplateAreasValue* aParentValue, bool& aCanStoreInRuleTree) { switch (aValue.GetUnit()) { @@ -7244,17 +7244,17 @@ SetGridTemplateAreas(const nsCSSValue& aValue, case eCSSUnit_Inherit: aCanStoreInRuleTree = false; - aResult = aParentValue; + *aResult = aParentValue; break; case eCSSUnit_Initial: case eCSSUnit_Unset: case eCSSUnit_None: - aResult.Reset(); + *aResult = nullptr; break; default: - aResult = aValue.GetGridTemplateAreas(); + *aResult = aValue.GetGridTemplateAreas(); } } @@ -7521,7 +7521,8 @@ nsRuleNode::ComputePositionData(void* aStartStruct, // grid-tempate-areas SetGridTemplateAreas(*aRuleData->ValueForGridTemplateAreas(), - pos->mGridTemplateAreas, parentPos->mGridTemplateAreas, + &pos->mGridTemplateAreas, + parentPos->mGridTemplateAreas, canStoreInRuleTree); // grid-auto-position diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index e8ac7646338a..8bb041faa631 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -1254,12 +1254,11 @@ nsStylePosition::nsStylePosition(void) mZIndex.SetAutoValue(); mGridAutoPositionColumn.SetToInteger(1); mGridAutoPositionRow.SetToInteger(1); - // mGridTemplateRows, mGridTemplateColumns, and mGridTemplateAreas - // get their default constructors - // which initialize them to empty arrays, - // which represent the properties' initial value 'none'. - - // mGrid{Column,Row}{Start,End} get their default constructor, 'auto' + // Other members get their default constructors + // which initialize them to representations of their respective initial value. + // mGridTemplateAreas: nullptr for 'none' + // mGridTemplate{Rows,Columns}: empty arrays for 'none' + // mGrid{Column,Row}{Start,End}: false/0/empty values for 'auto' } nsStylePosition::~nsStylePosition(void) diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 14c914258e0b..e388e0f3bd06 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -1300,7 +1300,9 @@ struct nsStylePosition { // in nsStyleStruct.cpp nsStyleGridTrackList mGridTemplateColumns; nsStyleGridTrackList mGridTemplateRows; - mozilla::css::GridTemplateAreasValue mGridTemplateAreas; + + // nullptr for 'none' + nsRefPtr mGridTemplateAreas; // We represent the "grid-auto-position" property in two parts: nsStyleGridLine mGridAutoPositionColumn;