Bug 1366735 part 1 - Change counter functions to use struct rather than nsCSSValue::Array. r=heycam

MozReview-Commit-ID: 4FiOxCOsjtD

--HG--
extra : rebase_source : 0a2ef777045603fe591ba3a74259699a2339cede
This commit is contained in:
Xidorn Quan 2017-05-22 22:51:20 +10:00
Родитель ec074c3fbb
Коммит 1dd9b6bad1
8 изменённых файлов: 113 добавлений и 102 удалений

Просмотреть файл

@ -1771,13 +1771,12 @@ nsCSSFrameConstructor::CreateGeneratedContent(nsFrameConstructorState& aState,
case eStyleContentType_Counter:
case eStyleContentType_Counters: {
nsCSSValue::Array* counters = data.GetCounters();
nsCounterList* counterList = mCounterManager.CounterListFor(
nsDependentString(counters->Item(0).GetStringBufferValue()));
nsStyleContentData::CounterFunction* counters = data.GetCounters();
nsCounterList* counterList =
mCounterManager.CounterListFor(counters->mIdent);
nsCounterUseNode* node =
new nsCounterUseNode(mPresShell->GetPresContext(),
counters, aContentIndex,
new nsCounterUseNode(counters, aContentIndex,
type == eStyleContentType_Counters);
nsGenConInitializer* initializer =

Просмотреть файл

@ -43,24 +43,6 @@ nsCounterUseNode::InitTextFrame(nsGenConList* aList,
return false;
}
CounterStyle*
nsCounterUseNode::GetCounterStyle()
{
if (!mCounterStyle) {
const nsCSSValue& style = mCounterFunction->Item(mAllCounters ? 2 : 1);
CounterStyleManager* manager = mPresContext->CounterStyleManager();
if (style.GetUnit() == eCSSUnit_AtomIdent) {
mCounterStyle = manager->BuildCounterStyle(style.GetAtomValue());
} else if (style.GetUnit() == eCSSUnit_Symbols) {
mCounterStyle = new AnonymousCounterStyle(style.GetArrayValue());
} else {
NS_NOTREACHED("Unknown counter style");
mCounterStyle = CounterStyleManager::GetDecimalStyle();
}
}
return mCounterStyle;
}
// assign the correct |mValueAfter| value to a node that has been inserted
// Should be called immediately after calling |Insert|.
void nsCounterUseNode::Calc(nsCounterList *aList)
@ -98,23 +80,17 @@ nsCounterUseNode::GetText(nsString& aResult)
for (nsCounterNode *n = mScopeStart; n->mScopePrev; n = n->mScopeStart)
stack.AppendElement(n->mScopePrev);
const char16_t* separator;
if (mAllCounters)
separator = mCounterFunction->Item(1).GetStringBufferValue();
CounterStyle* style = GetCounterStyle();
WritingMode wm = mPseudoFrame ?
mPseudoFrame->GetWritingMode() : WritingMode();
for (uint32_t i = stack.Length() - 1;; --i) {
nsCounterNode *n = stack[i];
nsAutoString text;
bool isTextRTL;
style->GetCounterText(n->mValueAfter, wm, text, isTextRTL);
mCounterStyle->GetCounterText(n->mValueAfter, wm, text, isTextRTL);
aResult.Append(text);
if (i == 0)
break;
NS_ASSERTION(mAllCounters, "yikes, separator is uninitialized");
aResult.Append(separator);
aResult.Append(mSeparator);
}
}

Просмотреть файл

@ -76,24 +76,18 @@ struct nsCounterNode : public nsGenConNode {
};
struct nsCounterUseNode : public nsCounterNode {
// The same structure passed through the style system: an array
// containing the values in the counter() or counters() in the order
// given in the CSS spec.
RefPtr<nsCSSValue::Array> mCounterFunction;
nsPresContext* mPresContext;
mozilla::CounterStylePtr mCounterStyle;
nsString mSeparator;
// false for counter(), true for counters()
bool mAllCounters;
// args go directly to member variables here and of nsGenConNode
nsCounterUseNode(nsPresContext* aPresContext,
nsCSSValue::Array* aCounterFunction,
nsCounterUseNode(nsStyleContentData::CounterFunction* aCounterFunction,
uint32_t aContentIndex, bool aAllCounters)
: nsCounterNode(aContentIndex, USE)
, mCounterFunction(aCounterFunction)
, mPresContext(aPresContext)
, mCounterStyle(aCounterFunction->mCounterStyle)
, mSeparator(aCounterFunction->mSeparator)
, mAllCounters(aAllCounters)
{
NS_ASSERTION(aContentIndex <= INT32_MAX, "out of range");
@ -102,7 +96,6 @@ struct nsCounterUseNode : public nsCounterNode {
virtual bool InitTextFrame(nsGenConList* aList,
nsIFrame* aPseudoFrame, nsIFrame* aTextFrame) override;
mozilla::CounterStyle* GetCounterStyle();
void SetCounterStyleDirty()
{
mCounterStyle = nullptr;

Просмотреть файл

@ -154,6 +154,11 @@ public:
AsAnonymous()->AddRef();
}
}
CounterStylePtr(CounterStylePtr&& aOther)
: mRaw(aOther.mRaw)
{
aOther.mRaw = 0;
}
~CounterStylePtr() { Reset(); }
CounterStylePtr& operator=(const CounterStylePtr& aOther)

Просмотреть файл

@ -1265,6 +1265,46 @@ nsComputedDOMStyle::DoGetColumnRuleColor()
return val.forget();
}
static void
AppendCounterStyle(CounterStyle* aStyle, nsAString& aString)
{
AnonymousCounterStyle* anonymous = aStyle->AsAnonymous();
if (!anonymous) {
// want SetIdent
nsString type;
aStyle->GetStyleName(type);
nsStyleUtil::AppendEscapedCSSIdent(type, aString);
} else if (anonymous->IsSingleString()) {
const nsTArray<nsString>& symbols = anonymous->GetSymbols();
MOZ_ASSERT(symbols.Length() == 1);
nsStyleUtil::AppendEscapedCSSString(symbols[0], aString);
} else {
aString.AppendLiteral("symbols(");
uint8_t system = anonymous->GetSystem();
NS_ASSERTION(system == NS_STYLE_COUNTER_SYSTEM_CYCLIC ||
system == NS_STYLE_COUNTER_SYSTEM_NUMERIC ||
system == NS_STYLE_COUNTER_SYSTEM_ALPHABETIC ||
system == NS_STYLE_COUNTER_SYSTEM_SYMBOLIC ||
system == NS_STYLE_COUNTER_SYSTEM_FIXED,
"Invalid system for anonymous counter style.");
if (system != NS_STYLE_COUNTER_SYSTEM_SYMBOLIC) {
AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(
system, nsCSSProps::kCounterSystemKTable), aString);
aString.Append(' ');
}
const nsTArray<nsString>& symbols = anonymous->GetSymbols();
NS_ASSERTION(symbols.Length() > 0,
"No symbols in the anonymous counter style");
for (size_t i = 0, iend = symbols.Length(); i < iend; i++) {
nsStyleUtil::AppendEscapedCSSString(symbols[i], aString);
aString.Append(' ');
}
aString.Replace(aString.Length() - 1, 1, char16_t(')'));
}
}
already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetContent()
{
@ -1323,26 +1363,15 @@ nsComputedDOMStyle::DoGetContent()
else {
str.AppendLiteral("counters(");
}
// WRITE ME
nsCSSValue::Array* a = data.GetCounters();
nsStyleUtil::AppendEscapedCSSIdent(
nsDependentString(a->Item(0).GetStringBufferValue()), str);
int32_t typeItem = 1;
nsStyleContentData::CounterFunction* counters = data.GetCounters();
nsStyleUtil::AppendEscapedCSSIdent(counters->mIdent, str);
if (type == eStyleContentType_Counters) {
typeItem = 2;
str.AppendLiteral(", ");
nsStyleUtil::AppendEscapedCSSString(
nsDependentString(a->Item(1).GetStringBufferValue()), str);
nsStyleUtil::AppendEscapedCSSString(counters->mSeparator, str);
}
MOZ_ASSERT(eCSSUnit_None != a->Item(typeItem).GetUnit(),
"'none' should be handled as identifier value");
nsString type;
a->Item(typeItem).AppendToString(eCSSProperty_list_style_type,
type, nsCSSValue::eNormalized);
if (!type.LowerCaseEqualsLiteral("decimal")) {
if (counters->mCounterStyle != CounterStyleManager::GetDecimalStyle()) {
str.AppendLiteral(", ");
str.Append(type);
AppendCounterStyle(counters->mCounterStyle, str);
}
str.Append(char16_t(')'));
@ -3751,43 +3780,8 @@ already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetListStyleType()
{
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
CounterStyle* style = StyleList()->mCounterStyle;
AnonymousCounterStyle* anonymous = style->AsAnonymous();
nsAutoString tmp;
if (!anonymous) {
// want SetIdent
nsString type;
style->GetStyleName(type);
nsStyleUtil::AppendEscapedCSSIdent(type, tmp);
} else if (anonymous->IsSingleString()) {
const nsTArray<nsString>& symbols = anonymous->GetSymbols();
MOZ_ASSERT(symbols.Length() == 1);
nsStyleUtil::AppendEscapedCSSString(symbols[0], tmp);
} else {
tmp.AppendLiteral("symbols(");
uint8_t system = anonymous->GetSystem();
NS_ASSERTION(system == NS_STYLE_COUNTER_SYSTEM_CYCLIC ||
system == NS_STYLE_COUNTER_SYSTEM_NUMERIC ||
system == NS_STYLE_COUNTER_SYSTEM_ALPHABETIC ||
system == NS_STYLE_COUNTER_SYSTEM_SYMBOLIC ||
system == NS_STYLE_COUNTER_SYSTEM_FIXED,
"Invalid system for anonymous counter style.");
if (system != NS_STYLE_COUNTER_SYSTEM_SYMBOLIC) {
AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(
system, nsCSSProps::kCounterSystemKTable), tmp);
tmp.Append(' ');
}
const nsTArray<nsString>& symbols = anonymous->GetSymbols();
NS_ASSERTION(symbols.Length() > 0,
"No symbols in the anonymous counter style");
for (size_t i = 0, iend = symbols.Length(); i < iend; i++) {
nsStyleUtil::AppendEscapedCSSString(symbols[i], tmp);
tmp.Append(' ');
}
tmp.Replace(tmp.Length() - 1, 1, char16_t(')'));
}
AppendCounterStyle(StyleList()->mCounterStyle, tmp);
val->SetString(tmp);
return val.forget();
}

Просмотреть файл

@ -8902,7 +8902,26 @@ nsRuleNode::ComputeContentData(void* aStartStruct,
nsStyleContentType type =
unit == eCSSUnit_Counter ? eStyleContentType_Counter
: eStyleContentType_Counters;
data.SetCounters(type, value.GetArrayValue());
RefPtr<nsStyleContentData::CounterFunction>
counterFunc = new nsStyleContentData::CounterFunction();
nsCSSValue::Array* arrayValue = value.GetArrayValue();
arrayValue->Item(0).GetStringValue(counterFunc->mIdent);
if (unit == eCSSUnit_Counters) {
arrayValue->Item(1).GetStringValue(counterFunc->mSeparator);
}
const nsCSSValue& style =
value.GetArrayValue()->Item(unit == eCSSUnit_Counters ? 2 : 1);
if (style.GetUnit() == eCSSUnit_AtomIdent) {
counterFunc->mCounterStyle = mPresContext->
CounterStyleManager()->BuildCounterStyle(style.GetAtomValue());
} else if (style.GetUnit() == eCSSUnit_Symbols) {
counterFunc->mCounterStyle =
new AnonymousCounterStyle(style.GetArrayValue());
} else {
MOZ_ASSERT_UNREACHABLE("Unknown counter style");
counterFunc->mCounterStyle = CounterStyleManager::GetDecimalStyle();
}
data.SetCounters(type, counterFunc.forget());
break;
}
case eCSSUnit_Enumerated:

Просмотреть файл

@ -3808,6 +3808,15 @@ nsStyleContentData::nsStyleContentData(const nsStyleContentData& aOther)
}
}
bool
nsStyleContentData::
CounterFunction::operator==(const CounterFunction& aOther) const
{
return mIdent == aOther.mIdent &&
mSeparator == aOther.mSeparator &&
mCounterStyle == aOther.mCounterStyle;
}
nsStyleContentData&
nsStyleContentData::operator=(const nsStyleContentData& aOther)
{

Просмотреть файл

@ -3043,7 +3043,24 @@ public:
return mContent.mString;
}
nsCSSValue::Array* GetCounters() const
struct CounterFunction
{
nsString mIdent;
// This is only used when it is a counters() function.
nsString mSeparator;
mozilla::CounterStylePtr mCounterStyle;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CounterFunction)
bool operator==(const CounterFunction& aOther) const;
bool operator!=(const CounterFunction& aOther) const {
return !(*this == aOther);
}
private:
~CounterFunction() {}
};
CounterFunction* GetCounters() const
{
MOZ_ASSERT(mType == eStyleContentType_Counter ||
mType == eStyleContentType_Counters);
@ -3084,17 +3101,16 @@ public:
mContent.mString = NS_strdup(aString);
}
void SetCounters(nsStyleContentType aType, nsCSSValue::Array* aCounters)
void SetCounters(nsStyleContentType aType,
already_AddRefed<CounterFunction> aCounterFunction)
{
MOZ_ASSERT(aType == eStyleContentType_Counter ||
aType == eStyleContentType_Counters);
MOZ_ASSERT(aCounters);
MOZ_ASSERT(aCounters->Count() == 2 || aCounters->Count() == 3);
MOZ_ASSERT(mType == eStyleContentType_Uninitialized,
"should only initialize nsStyleContentData once");
mType = aType;
mContent.mCounters = aCounters;
mContent.mCounters->AddRef();
mContent.mCounters = aCounterFunction.take();
MOZ_ASSERT(mContent.mCounters);
}
void SetImageRequest(already_AddRefed<nsStyleImageRequest> aRequest)
@ -3117,7 +3133,7 @@ private:
union {
char16_t *mString;
nsStyleImageRequest* mImage;
nsCSSValue::Array* mCounters;
CounterFunction* mCounters;
} mContent;
};