Bug 1363699 part 1 - Make named CounterStyle objects not refcounted. r=heycam

This change does the following:
* Introduce a new smart pointer called CounterStylePtr which either
  holds an AnonymousCounterStyle strongly, or a named CounterStyle
  managed by CounterStyleManager weakly, and use it to replace all
  RefPtr<CounterStyle> around the codebase.
* Rename CounterStyleManager::mCacheTable to mStyles to reflect the
  fact that it is used to manage all styles, not just for caching.
* Add a retired styles list which collect all named CounterStyle
  evicted from mStyles, and post a PostRefreshObserver to destroy
  objects in that list after next flush.
* Remove helper functions for counter style in nsStyleList and expose
  mCounterStyle directly, to make code simpler with the new pointer.

Reason for adding a new smart pointer type rather than making their
AddRef/Release behave like BuiltinCounterStyle is that, it is possible
that after a flush, some stale style structs may still be alive. They
can contain pointer to destroyed CounterStyle objects. Although the
actual content may never be accessed anymore, RefPtr may still access
the object for refcounting during destruction.

MozReview-Commit-ID: xxegwSDhNb

--HG--
extra : rebase_source : bb5443f0eb56eee51cbdfd08e0400335648610e8
This commit is contained in:
Xidorn Quan 2017-05-13 21:42:23 +10:00
parent a58b13f27d
commit 8c54e3ce73
11 changed files with 213 additions and 115 deletions

View File

@ -82,7 +82,7 @@ struct nsCounterUseNode : public nsCounterNode {
RefPtr<nsCSSValue::Array> mCounterFunction;
nsPresContext* mPresContext;
RefPtr<mozilla::CounterStyle> mCounterStyle;
mozilla::CounterStylePtr mCounterStyle;
// false for counter(), true for counters()
bool mAllCounters;
@ -94,7 +94,6 @@ struct nsCounterUseNode : public nsCounterNode {
: nsCounterNode(aContentIndex, USE)
, mCounterFunction(aCounterFunction)
, mPresContext(aPresContext)
, mCounterStyle(nullptr)
, mAllCounters(aAllCounters)
{
NS_ASSERTION(aContentIndex <= INT32_MAX, "out of range");

View File

@ -2282,6 +2282,29 @@ nsPresContext::UserFontSetUpdated(gfxUserFontEntry* aUpdatedFont)
}
}
class CounterStyleCleaner : public nsAPostRefreshObserver
{
public:
CounterStyleCleaner(nsRefreshDriver* aRefreshDriver,
CounterStyleManager* aCounterStyleManager)
: mRefreshDriver(aRefreshDriver)
, mCounterStyleManager(aCounterStyleManager)
{
}
virtual ~CounterStyleCleaner() {}
void DidRefresh() final
{
mRefreshDriver->RemovePostRefreshObserver(this);
mCounterStyleManager->CleanRetiredStyles();
delete this;
}
private:
RefPtr<nsRefreshDriver> mRefreshDriver;
RefPtr<CounterStyleManager> mCounterStyleManager;
};
void
nsPresContext::FlushCounterStyles()
{
@ -2299,6 +2322,8 @@ nsPresContext::FlushCounterStyles()
PresShell()->NotifyCounterStylesAreDirty();
PostRebuildAllStyleDataEvent(NS_STYLE_HINT_REFLOW,
eRestyle_ForceDescendants);
RefreshDriver()->AddPostRefreshObserver(
new CounterStyleCleaner(RefreshDriver(), mCounterStyleManager));
}
mCounterStylesDirty = false;
}

View File

@ -133,7 +133,7 @@ FontSizeInflationListMarginAdjustment(const nsIFrame* aFrame)
blockFrame->HasBullet() &&
inflation > 1.0f) {
auto listStyleType = aFrame->StyleList()->GetCounterStyle()->GetStyle();
auto listStyleType = aFrame->StyleList()->mCounterStyle->GetStyle();
if (listStyleType != NS_STYLE_LIST_STYLE_NONE &&
listStyleType != NS_STYLE_LIST_STYLE_DISC &&
listStyleType != NS_STYLE_LIST_STYLE_CIRCLE &&

View File

@ -7055,7 +7055,7 @@ nsBlockFrame::SetInitialChildList(ChildListID aListID,
!GetPrevInFlow()) {
// Resolve style for the bullet frame
const nsStyleList* styleList = StyleList();
CounterStyle* style = styleList->GetCounterStyle();
CounterStyle* style = styleList->mCounterStyle;
CreateBulletFrameForListItem(
style->IsBullet(),
@ -7110,7 +7110,7 @@ nsBlockFrame::BulletIsEmpty() const
mozilla::StyleDisplay::ListItem && HasOutsideBullet(),
"should only care when we have an outside bullet");
const nsStyleList* list = StyleList();
return list->GetCounterStyle()->IsNone() &&
return list->mCounterStyle->IsNone() &&
!list->GetListStyleImage();
}

View File

@ -96,7 +96,7 @@ nsBulletFrame::IsEmpty()
bool
nsBulletFrame::IsSelfEmpty()
{
return StyleList()->GetCounterStyle()->IsNone();
return StyleList()->mCounterStyle->IsNone();
}
/* virtual */ void
@ -157,11 +157,11 @@ nsBulletFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
const nsStyleList* oldStyleList = aOldStyleContext->PeekStyleList();
if (oldStyleList) {
bool hadBullet = oldStyleList->GetListStyleImage() ||
!oldStyleList->GetCounterStyle()->IsNone();
!oldStyleList->mCounterStyle->IsNone();
const nsStyleList* newStyleList = StyleList();
bool hasBullet = newStyleList->GetListStyleImage() ||
!newStyleList->GetCounterStyle()->IsNone();
!newStyleList->mCounterStyle->IsNone();
if (hadBullet != hasBullet) {
accService->UpdateListBullet(PresContext()->GetPresShell(), mContent,
@ -696,7 +696,7 @@ Maybe<BulletRenderer>
nsBulletFrame::CreateBulletRenderer(nsRenderingContext& aRenderingContext, nsPoint aPt)
{
const nsStyleList* myList = StyleList();
CounterStyle* listStyleType = myList->GetCounterStyle();
CounterStyle* listStyleType = myList->mCounterStyle;
nsMargin padding = mPadding.GetPhysicalMargin(GetWritingMode());
if (myList->GetListStyleImage() && mImageRequest) {
@ -904,7 +904,7 @@ nsBulletFrame::SetListItemOrdinal(int32_t aNextOrdinal,
void
nsBulletFrame::GetListItemText(nsAString& aResult)
{
CounterStyle* style = StyleList()->GetCounterStyle();
CounterStyle* style = StyleList()->mCounterStyle;
NS_ASSERTION(style->GetStyle() != NS_STYLE_LIST_STYLE_NONE &&
style->GetStyle() != NS_STYLE_LIST_STYLE_DISC &&
style->GetStyle() != NS_STYLE_LIST_STYLE_CIRCLE &&
@ -991,7 +991,7 @@ nsBulletFrame::GetDesiredSize(nsPresContext* aCX,
nscoord bulletSize;
nsAutoString text;
switch (myList->GetCounterStyle()->GetStyle()) {
switch (myList->mCounterStyle->GetStyle()) {
case NS_STYLE_LIST_STYLE_NONE:
finalSize.ISize(wm) = finalSize.BSize(wm) = 0;
aMetrics.SetBlockStartAscent(0);
@ -1113,7 +1113,7 @@ IsIgnoreable(const nsIFrame* aFrame, nscoord aISize)
return false;
}
auto listStyle = aFrame->StyleList();
return listStyle->GetCounterStyle()->IsNone() &&
return listStyle->mCounterStyle->IsNone() &&
!listStyle->GetListStyleImage();
}
@ -1350,7 +1350,7 @@ nsBulletFrame::GetLogicalBaseline(WritingMode aWritingMode) const
} else {
RefPtr<nsFontMetrics> fm =
nsLayoutUtils::GetFontMetricsForFrame(this, GetFontSizeInflation());
CounterStyle* listStyleType = StyleList()->GetCounterStyle();
CounterStyle* listStyleType = StyleList()->mCounterStyle;
switch (listStyleType->GetStyle()) {
case NS_STYLE_LIST_STYLE_NONE:
break;
@ -1387,7 +1387,7 @@ nsBulletFrame::GetLogicalBaseline(WritingMode aWritingMode) const
void
nsBulletFrame::GetSpokenText(nsAString& aText)
{
CounterStyle* style = StyleList()->GetCounterStyle();
CounterStyle* style = StyleList()->mCounterStyle;
bool isBullet;
style->GetSpokenCounterText(mOrdinal, GetWritingMode(), aText, isBullet);
if (isBullet) {

View File

@ -611,10 +611,6 @@ public:
WritingMode aWritingMode,
nsSubstring& aResult,
bool& aIsRTL) override;
// Builtin counter style does not need refcount at all
NS_IMETHOD_(MozExternalRefCountType) AddRef() override { return 2; }
NS_IMETHOD_(MozExternalRefCountType) Release() override { return 2; }
};
/* virtual */ void
@ -962,8 +958,6 @@ BuiltinCounterStyle::GetInitialCounterText(CounterValue aOrdinal,
class DependentBuiltinCounterStyle final : public BuiltinCounterStyle
{
private:
~DependentBuiltinCounterStyle() {}
public:
DependentBuiltinCounterStyle(int32_t aStyle, CounterStyleManager* aManager)
: BuiltinCounterStyle(aStyle),
@ -975,18 +969,12 @@ public:
virtual CounterStyle* GetFallback() override;
// DependentBuiltinCounterStyle is managed in the same way as
// CustomCounterStyle.
NS_IMETHOD_(MozExternalRefCountType) AddRef() override;
NS_IMETHOD_(MozExternalRefCountType) Release() override;
void* operator new(size_t sz, nsPresContext* aPresContext)
{
return aPresContext->PresShell()->AllocateByObjectID(
eArenaObjectID_DependentBuiltinCounterStyle, sz);
}
private:
void Destroy()
{
nsIPresShell* shell = mManager->PresContext()->PresShell();
@ -994,15 +982,12 @@ private:
shell->FreeByObjectID(eArenaObjectID_DependentBuiltinCounterStyle, this);
}
private:
~DependentBuiltinCounterStyle() {}
CounterStyleManager* mManager;
nsAutoRefCnt mRefCnt;
NS_DECL_OWNINGTHREAD
};
NS_IMPL_ADDREF(DependentBuiltinCounterStyle)
NS_IMPL_RELEASE_WITH_DESTROY(DependentBuiltinCounterStyle, Destroy())
/* virtual */ CounterStyle*
DependentBuiltinCounterStyle::GetFallback()
{
@ -1029,8 +1014,6 @@ DependentBuiltinCounterStyle::GetFallback()
class CustomCounterStyle final : public CounterStyle
{
private:
~CustomCounterStyle() {}
public:
CustomCounterStyle(nsIAtom* aName,
CounterStyleManager* aManager,
@ -1095,19 +1078,12 @@ public:
return mSystem == NS_STYLE_COUNTER_SYSTEM_EXTENDS;
}
// CustomCounterStyle should be reference-counted because it may be
// dereferenced from the manager but still referenced by nodes and
// frames before the style change is propagated.
NS_IMETHOD_(MozExternalRefCountType) AddRef() override;
NS_IMETHOD_(MozExternalRefCountType) Release() override;
void* operator new(size_t sz, nsPresContext* aPresContext)
{
return aPresContext->PresShell()->AllocateByObjectID(
eArenaObjectID_CustomCounterStyle, sz);
}
private:
void Destroy()
{
nsIPresShell* shell = mManager->PresContext()->PresShell();
@ -1115,6 +1091,9 @@ private:
shell->FreeByObjectID(eArenaObjectID_CustomCounterStyle, this);
}
private:
~CustomCounterStyle() {}
const nsTArray<nsString>& GetSymbols();
const nsTArray<AdditiveSymbol>& GetAdditiveSymbols();
@ -1190,14 +1169,8 @@ private:
// counter must be either a builtin style or a style whose system is
// not 'extends'.
CounterStyle* mExtendsRoot;
nsAutoRefCnt mRefCnt;
NS_DECL_OWNINGTHREAD
};
NS_IMPL_ADDREF(CustomCounterStyle)
NS_IMPL_RELEASE_WITH_DESTROY(CustomCounterStyle, Destroy())
void
CustomCounterStyle::ResetCachedData()
{
@ -1987,8 +1960,8 @@ CounterStyleManager::CounterStyleManager(nsPresContext* aPresContext)
: mPresContext(aPresContext)
{
// Insert the static styles into cache table
mCacheTable.Put(nsGkAtoms::none, GetNoneStyle());
mCacheTable.Put(nsGkAtoms::decimal, GetDecimalStyle());
mStyles.Put(nsGkAtoms::none, GetNoneStyle());
mStyles.Put(nsGkAtoms::decimal, GetDecimalStyle());
}
CounterStyleManager::~CounterStyleManager()
@ -2004,26 +1977,38 @@ CounterStyleManager::InitializeBuiltinCounterStyles()
}
}
void
CounterStyleManager::DestroyCounterStyle(CounterStyle* aCounterStyle)
{
if (aCounterStyle->IsCustomStyle()) {
MOZ_ASSERT(!aCounterStyle->AsAnonymous(), "Anonymous counter styles "
"are not managed by CounterStyleManager");
static_cast<CustomCounterStyle*>(aCounterStyle)->Destroy();
} else if (aCounterStyle->IsDependentStyle()) {
static_cast<DependentBuiltinCounterStyle*>(aCounterStyle)->Destroy();
} else {
MOZ_ASSERT_UNREACHABLE("Builtin counter styles should not be destroyed");
}
}
void
CounterStyleManager::Disconnect()
{
#ifdef DEBUG
for (auto iter = mCacheTable.Iter(); !iter.Done(); iter.Next()) {
CounterStyle* style = iter.UserData();
style->AddRef();
auto refcnt = style->Release();
NS_ASSERTION(!style->IsDependentStyle() || refcnt == 1,
"Counter style is still referenced by other objects.");
CleanRetiredStyles();
for (auto iter = mStyles.Iter(); !iter.Done(); iter.Next()) {
CounterStyle* style = iter.Data();
if (style->IsDependentStyle()) {
DestroyCounterStyle(style);
}
}
#endif
mCacheTable.Clear();
mStyles.Clear();
mPresContext = nullptr;
}
CounterStyle*
CounterStyleManager::BuildCounterStyle(nsIAtom* aName)
{
CounterStyle* data = mCacheTable.GetWeak(aName);
CounterStyle* data = mStyles.Get(aName);
if (data) {
return data;
}
@ -2058,7 +2043,7 @@ CounterStyleManager::BuildCounterStyle(nsIAtom* aName)
if (!data) {
data = GetDecimalStyle();
}
mCacheTable.Put(aName, data);
mStyles.Put(aName, data);
return data;
}
@ -2076,9 +2061,8 @@ bool
CounterStyleManager::NotifyRuleChanged()
{
bool changed = false;
nsTArray<RefPtr<CounterStyle>> kungFuDeathGrip;
for (auto iter = mCacheTable.Iter(); !iter.Done(); iter.Next()) {
RefPtr<CounterStyle>& style = iter.Data();
for (auto iter = mStyles.Iter(); !iter.Done(); iter.Next()) {
CounterStyle* style = iter.Data();
bool toBeUpdated = false;
bool toBeRemoved = false;
// XXXheycam ServoStyleSets do not support custom counter styles yet. Bug
@ -2099,7 +2083,7 @@ CounterStyleManager::NotifyRuleChanged()
if (!style->IsCustomStyle()) {
toBeRemoved = true;
} else {
auto custom = static_cast<CustomCounterStyle*>(style.get());
auto custom = static_cast<CustomCounterStyle*>(style);
if (custom->GetRule() != newRule) {
toBeRemoved = true;
} else if (custom->GetRuleGeneration() != newRule->GetGeneration()) {
@ -2111,25 +2095,16 @@ CounterStyleManager::NotifyRuleChanged()
changed = changed || toBeUpdated || toBeRemoved;
if (toBeRemoved) {
if (style->IsDependentStyle()) {
if (style->IsCustomStyle()) {
// Since |style| is being removed from mCacheTable, it won't be
// visited by our post-removal iteration. So, we have to give it a
// manual ResetDependentData() call. (This only really matters if
// something else is holding a reference and keeping it alive.)
static_cast<CustomCounterStyle*>(style.get())->ResetDependentData();
}
// The object has to be held here so that it will not be released
// before all pointers that refer to it are reset. It will be released
// when kungFuDeathGrip goes out of scope at the end of this function.
kungFuDeathGrip.AppendElement(style);
// Add object to retired list so we can clean them up later.
mRetiredStyles.AppendElement(style);
}
iter.Remove();
}
}
if (changed) {
for (auto iter = mCacheTable.Iter(); !iter.Done(); iter.Next()) {
CounterStyle* style = iter.UserData();
for (auto iter = mStyles.Iter(); !iter.Done(); iter.Next()) {
CounterStyle* style = iter.Data();
if (style->IsCustomStyle()) {
CustomCounterStyle* custom = static_cast<CustomCounterStyle*>(style);
custom->ResetDependentData();
@ -2141,4 +2116,13 @@ CounterStyleManager::NotifyRuleChanged()
return changed;
}
void
CounterStyleManager::CleanRetiredStyles()
{
nsTArray<CounterStyle*> list(Move(mRetiredStyles));
for (CounterStyle* style : list) {
DestroyCounterStyle(style);
}
}
} // namespace mozilla

View File

@ -7,7 +7,7 @@
#define mozilla_CounterStyleManager_h_
#include "nsStringFwd.h"
#include "nsRefPtrHashtable.h"
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
#include "nsStyleConsts.h"
@ -96,8 +96,6 @@ public:
virtual AnonymousCounterStyle* AsAnonymous() { return nullptr; }
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
protected:
int32_t mStyle;
};
@ -132,7 +130,7 @@ public:
uint8_t GetSystem() const { return mSystem; }
const nsTArray<nsString>& GetSymbols() const { return mSymbols; }
NS_INLINE_DECL_REFCOUNTING(AnonymousCounterStyle, override)
NS_INLINE_DECL_REFCOUNTING(AnonymousCounterStyle)
private:
~AnonymousCounterStyle() {}
@ -142,6 +140,105 @@ private:
nsTArray<nsString> mSymbols;
};
// A smart pointer to CounterStyle. It either owns a reference to an
// anonymous counter style, or weakly refers to a named counter style
// managed by counter style manager.
class CounterStylePtr
{
public:
CounterStylePtr() : mRaw(0) {}
CounterStylePtr(const CounterStylePtr& aOther)
: mRaw(aOther.mRaw)
{
if (IsAnonymous()) {
AsAnonymous()->AddRef();
}
}
~CounterStylePtr() { Reset(); }
CounterStylePtr& operator=(const CounterStylePtr& aOther)
{
if (this != &aOther) {
Reset();
new (this) CounterStylePtr(aOther);
}
return *this;
}
CounterStylePtr& operator=(decltype(nullptr))
{
Reset();
return *this;
}
CounterStylePtr& operator=(AnonymousCounterStyle* aCounterStyle)
{
Reset();
if (aCounterStyle) {
CounterStyle* raw = do_AddRef(aCounterStyle).take();
AssertPointerAligned(raw);
mRaw = reinterpret_cast<uintptr_t>(raw) | kAnonymousFlag;
}
return *this;
}
CounterStylePtr& operator=(CounterStyle* aCounterStyle)
{
Reset();
if (aCounterStyle) {
MOZ_ASSERT(!aCounterStyle->AsAnonymous());
AssertPointerAligned(aCounterStyle);
mRaw = reinterpret_cast<uintptr_t>(aCounterStyle);
}
return *this;
}
operator CounterStyle*() const & { return Get(); }
operator CounterStyle*() const && = delete;
CounterStyle* operator->() const { return Get(); }
explicit operator bool() const { return !!mRaw; }
bool operator!() const { return !mRaw; }
bool operator==(const CounterStylePtr& aOther) const
{ return mRaw == aOther.mRaw; }
bool operator!=(const CounterStylePtr& aOther) const
{ return mRaw != aOther.mRaw; }
private:
CounterStyle* Get() const
{
return reinterpret_cast<CounterStyle*>(mRaw & ~kAnonymousFlag);
}
void AssertPointerAligned(CounterStyle* aPointer)
{
// This can be checked at compile time via
// > static_assert(alignof(CounterStyle) >= 2);
// but MSVC2015 doesn't support using alignof on an abstract class.
// Once we move to MSVC2017, we can replace this runtime check with
// the compile time check above.
MOZ_ASSERT(!(reinterpret_cast<uintptr_t>(aPointer) & kAnonymousFlag));
}
bool IsAnonymous() const { return !!(mRaw & kAnonymousFlag); }
AnonymousCounterStyle* AsAnonymous()
{
MOZ_ASSERT(IsAnonymous());
return static_cast<AnonymousCounterStyle*>(
reinterpret_cast<CounterStyle*>(mRaw & ~kAnonymousFlag));
}
void Reset()
{
if (IsAnonymous()) {
AsAnonymous()->Release();
}
mRaw = 0;
}
// mRaw contains the pointer, and its last bit is used for the flag.
// If the flag is set, this pointer owns an AnonymousCounterStyle,
// otherwise, it is a weak pointer referring a named counter style
// managed by CounterStyleManager.
static const uintptr_t kAnonymousFlag = 1;
uintptr_t mRaw;
};
class CounterStyleManager final
{
private:
@ -156,7 +253,7 @@ public:
bool IsInitial() const
{
// only 'none' and 'decimal'
return mCacheTable.Count() == 2;
return mStyles.Count() == 2;
}
CounterStyle* BuildCounterStyle(nsIAtom* aName);
@ -176,14 +273,21 @@ public:
// if any counter style is changed, false elsewise. This method should
// be called when any counter style may be affected.
bool NotifyRuleChanged();
// NotifyRuleChanged will evict no longer needed counter styles into
// mRetiredStyles, and this function destroys all objects listed there.
// It should be called only after no one may ever use those objects.
void CleanRetiredStyles();
nsPresContext* PresContext() const { return mPresContext; }
NS_INLINE_DECL_REFCOUNTING(CounterStyleManager)
private:
void DestroyCounterStyle(CounterStyle* aCounterStyle);
nsPresContext* mPresContext;
nsRefPtrHashtable<nsRefPtrHashKey<nsIAtom>, CounterStyle> mCacheTable;
nsDataHashtable<nsRefPtrHashKey<nsIAtom>, CounterStyle*> mStyles;
nsTArray<CounterStyle*> mRetiredStyles;
};
} // namespace mozilla

View File

@ -1112,17 +1112,15 @@ Gecko_CopyImageOrientationFrom(nsStyleVisibility* aDst,
}
void
Gecko_SetListStyleType(nsStyleList* style_struct, uint32_t type)
Gecko_SetListStyleType(nsStyleList* aList, uint32_t aType)
{
// Builtin counter styles are static and use no-op refcounting, and thus are
// safe to use off-main-thread.
style_struct->SetCounterStyle(CounterStyleManager::GetBuiltinStyle(type));
aList->mCounterStyle = CounterStyleManager::GetBuiltinStyle(aType);
}
void
Gecko_CopyListStyleTypeFrom(nsStyleList* dst, const nsStyleList* src)
Gecko_CopyListStyleTypeFrom(nsStyleList* aDst, const nsStyleList* aSrc)
{
dst->SetCounterStyle(src->GetCounterStyle());
aDst->mCounterStyle = aSrc->mCounterStyle;
}
already_AddRefed<css::URLValue>

View File

@ -3714,13 +3714,13 @@ already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetListStyleType()
{
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
CounterStyle* style = StyleList()->GetCounterStyle();
CounterStyle* style = StyleList()->mCounterStyle;
AnonymousCounterStyle* anonymous = style->AsAnonymous();
nsAutoString tmp;
if (!anonymous) {
// want SetIdent
nsString type;
StyleList()->GetListStyleType(type);
style->GetStyleName(type);
nsStyleUtil::AppendEscapedCSSIdent(type, tmp);
} else if (anonymous->IsSingleString()) {
const nsTArray<nsString>& symbols = anonymous->GetSymbols();

View File

@ -7954,24 +7954,28 @@ nsRuleNode::ComputeListData(void* aStartStruct,
// list-style-type: string, none, inherit, initial
const nsCSSValue* typeValue = aRuleData->ValueForListStyleType();
auto setListStyleType = [this, list](nsIAtom* type) {
list->mCounterStyle = mPresContext->
CounterStyleManager()->BuildCounterStyle(type);
};
switch (typeValue->GetUnit()) {
case eCSSUnit_Unset:
case eCSSUnit_Inherit: {
conditions.SetUncacheable();
list->SetCounterStyle(parentList->GetCounterStyle());
list->mCounterStyle = parentList->mCounterStyle;
break;
}
case eCSSUnit_Initial:
list->SetListStyleType(nsGkAtoms::disc, mPresContext);
setListStyleType(nsGkAtoms::disc);
break;
case eCSSUnit_AtomIdent: {
list->SetListStyleType(typeValue->GetAtomValue(), mPresContext);
setListStyleType(typeValue->GetAtomValue());
break;
}
case eCSSUnit_String: {
nsString str;
typeValue->GetStringValue(str);
list->SetCounterStyle(new AnonymousCounterStyle(str));
list->mCounterStyle = new AnonymousCounterStyle(str);
break;
}
case eCSSUnit_Enumerated: {
@ -7997,11 +8001,12 @@ nsRuleNode::ComputeListData(void* aStartStruct,
intValue, nsCSSProps::kListStyleKTable));
break;
}
list->SetListStyleType(name, mPresContext);
setListStyleType(name);
break;
}
case eCSSUnit_Symbols:
list->SetCounterStyle(new AnonymousCounterStyle(typeValue->GetArrayValue()));
list->mCounterStyle =
new AnonymousCounterStyle(typeValue->GetArrayValue());
break;
case eCSSUnit_Null:
break;

View File

@ -1476,23 +1476,6 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleList
already_AddRefed<nsIURI> GetListStyleImageURI() const;
void GetListStyleType(nsSubstring& aType) const { mCounterStyle->GetStyleName(aType); }
mozilla::CounterStyle* GetCounterStyle() const
{
return mCounterStyle.get();
}
void SetCounterStyle(mozilla::CounterStyle* aStyle)
{
// NB: This function is called off-main-thread during parallel restyle, but
// only with builtin styles that use dummy refcounting.
MOZ_ASSERT(NS_IsMainThread() || !aStyle->IsDependentStyle());
mCounterStyle = aStyle;
}
void SetListStyleType(nsIAtom* aType, nsPresContext* aPresContext)
{
SetCounterStyle(aPresContext->CounterStyleManager()->BuildCounterStyle(aType));
}
const nsStyleQuoteValues::QuotePairArray& GetQuotePairs() const;
void SetQuotesInherit(const nsStyleList* aOther);
@ -1502,8 +1485,8 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleList
uint8_t mListStylePosition; // [inherited]
RefPtr<nsStyleImageRequest> mListStyleImage; // [inherited]
mozilla::CounterStylePtr mCounterStyle; // [inherited]
private:
RefPtr<mozilla::CounterStyle> mCounterStyle; // [inherited]
RefPtr<nsStyleQuoteValues> mQuotes; // [inherited]
nsStyleList& operator=(const nsStyleList& aOther) = delete;
public: