зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1261754 - Part 2: Make quotes computed values shareable between different structs. r=dholbert
This commit is contained in:
Родитель
cde55115b7
Коммит
d340c36d57
|
@ -7661,6 +7661,9 @@ nsLayoutUtils::Shutdown()
|
|||
Preferences::UnregisterCallback(WebkitPrefixEnabledPrefChangeCallback,
|
||||
WEBKIT_PREFIXES_ENABLED_PREF_NAME);
|
||||
nsComputedDOMStyle::UnregisterPrefChangeCallbacks();
|
||||
|
||||
// so the cached initial quotes array doesn't appear to be a leak
|
||||
nsStyleQuotes::Shutdown();
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
|
|
@ -37,8 +37,9 @@ nsQuoteNode::Text()
|
|||
NS_ASSERTION(mType == eStyleContentType_OpenQuote ||
|
||||
mType == eStyleContentType_CloseQuote,
|
||||
"should only be called when mText should be non-null");
|
||||
const nsStyleQuotes* styleQuotes = mPseudoFrame->StyleQuotes();
|
||||
int32_t quotesCount = styleQuotes->QuotesCount(); // 0 if 'quotes:none'
|
||||
const nsStyleQuoteValues::QuotePairArray& quotePairs =
|
||||
mPseudoFrame->StyleQuotes()->GetQuotePairs();
|
||||
int32_t quotesCount = quotePairs.Length(); // 0 if 'quotes:none'
|
||||
int32_t quoteDepth = Depth();
|
||||
|
||||
// Reuse the last pair when the depth is greater than the number of
|
||||
|
@ -47,15 +48,15 @@ nsQuoteNode::Text()
|
|||
if (quoteDepth >= quotesCount)
|
||||
quoteDepth = quotesCount - 1;
|
||||
|
||||
const nsString *result;
|
||||
const nsString* result;
|
||||
if (quoteDepth == -1) {
|
||||
// close-quote from a depth of 0 or 'quotes: none' (we want a node
|
||||
// with the empty string so dynamic changes are easier to handle)
|
||||
result = & EmptyString();
|
||||
result = &EmptyString();
|
||||
} else {
|
||||
result = eStyleContentType_OpenQuote == mType
|
||||
? styleQuotes->OpenQuoteAt(quoteDepth)
|
||||
: styleQuotes->CloseQuoteAt(quoteDepth);
|
||||
? "ePairs[quoteDepth].first
|
||||
: "ePairs[quoteDepth].second;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1471,9 +1471,9 @@ nsComputedDOMStyle::DoGetCounterReset()
|
|||
already_AddRefed<CSSValue>
|
||||
nsComputedDOMStyle::DoGetQuotes()
|
||||
{
|
||||
const nsStyleQuotes *quotes = StyleQuotes();
|
||||
const auto& quotePairs = StyleQuotes()->GetQuotePairs();
|
||||
|
||||
if (quotes->QuotesCount() == 0) {
|
||||
if (quotePairs.IsEmpty()) {
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
val->SetIdent(eCSSKeyword_none);
|
||||
return val.forget();
|
||||
|
@ -1481,15 +1481,15 @@ nsComputedDOMStyle::DoGetQuotes()
|
|||
|
||||
RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
|
||||
|
||||
for (uint32_t i = 0, i_end = quotes->QuotesCount(); i < i_end; ++i) {
|
||||
for (const auto& quotePair : quotePairs) {
|
||||
RefPtr<nsROCSSPrimitiveValue> openVal = new nsROCSSPrimitiveValue;
|
||||
RefPtr<nsROCSSPrimitiveValue> closeVal = new nsROCSSPrimitiveValue;
|
||||
|
||||
nsString s;
|
||||
nsStyleUtil::AppendEscapedCSSString(*quotes->OpenQuoteAt(i), s);
|
||||
nsStyleUtil::AppendEscapedCSSString(quotePair.first, s);
|
||||
openVal->SetString(s);
|
||||
s.Truncate();
|
||||
nsStyleUtil::AppendEscapedCSSString(*quotes->CloseQuoteAt(i), s);
|
||||
nsStyleUtil::AppendEscapedCSSString(quotePair.second, s);
|
||||
closeVal->SetString(s);
|
||||
|
||||
valueList->AppendCSSValue(openVal.forget());
|
||||
|
|
|
@ -8854,34 +8854,33 @@ nsRuleNode::ComputeQuotesData(void* aStartStruct,
|
|||
case eCSSUnit_Inherit:
|
||||
case eCSSUnit_Unset:
|
||||
conditions.SetUncacheable();
|
||||
quotes->CopyFrom(*parentQuotes);
|
||||
quotes->SetQuotesInherit(parentQuotes);
|
||||
break;
|
||||
case eCSSUnit_Initial:
|
||||
quotes->SetInitial();
|
||||
quotes->SetQuotesInitial();
|
||||
break;
|
||||
case eCSSUnit_None:
|
||||
quotes->AllocateQuotes(0);
|
||||
quotes->SetQuotesNone();
|
||||
break;
|
||||
case eCSSUnit_PairList:
|
||||
case eCSSUnit_PairListDep: {
|
||||
const nsCSSValuePairList* ourQuotes
|
||||
= quotesValue->GetPairListValue();
|
||||
const nsCSSValuePairList* ourQuotes = quotesValue->GetPairListValue();
|
||||
|
||||
nsStyleQuoteValues::QuotePairArray quotePairs;
|
||||
quotePairs.SetLength(ListLength(ourQuotes));
|
||||
|
||||
size_t index = 0;
|
||||
nsAutoString buffer;
|
||||
nsAutoString closeBuffer;
|
||||
uint32_t count = ListLength(ourQuotes);
|
||||
if (NS_FAILED(quotes->AllocateQuotes(count))) {
|
||||
break;
|
||||
}
|
||||
count = 0;
|
||||
while (ourQuotes) {
|
||||
MOZ_ASSERT(ourQuotes->mXValue.GetUnit() == eCSSUnit_String &&
|
||||
ourQuotes->mYValue.GetUnit() == eCSSUnit_String,
|
||||
"improper list contents for quotes");
|
||||
ourQuotes->mXValue.GetStringValue(buffer);
|
||||
ourQuotes->mYValue.GetStringValue(closeBuffer);
|
||||
quotes->SetQuotesAt(count++, buffer, closeBuffer);
|
||||
quotePairs[index].first = ourQuotes->mXValue.GetStringValue(buffer);
|
||||
quotePairs[index].second = ourQuotes->mYValue.GetStringValue(buffer);
|
||||
++index;
|
||||
ourQuotes = ourQuotes->mNext;
|
||||
}
|
||||
quotes->SetQuotes(Move(quotePairs));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -3497,75 +3497,93 @@ nsresult nsStyleContent::AllocateContents(uint32_t aCount)
|
|||
//
|
||||
|
||||
nsStyleQuotes::nsStyleQuotes(StyleStructContext aContext)
|
||||
: mQuotesCount(0),
|
||||
mQuotes(nullptr)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsStyleQuotes);
|
||||
SetInitial();
|
||||
SetQuotesInitial();
|
||||
}
|
||||
|
||||
nsStyleQuotes::~nsStyleQuotes(void)
|
||||
nsStyleQuotes::~nsStyleQuotes()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsStyleQuotes);
|
||||
DELETE_ARRAY_IF(mQuotes);
|
||||
}
|
||||
|
||||
nsStyleQuotes::nsStyleQuotes(const nsStyleQuotes& aSource)
|
||||
: mQuotesCount(0),
|
||||
mQuotes(nullptr)
|
||||
: mQuotes(aSource.mQuotes)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsStyleQuotes);
|
||||
CopyFrom(aSource);
|
||||
}
|
||||
|
||||
void
|
||||
nsStyleQuotes::SetInitial()
|
||||
nsStyleQuotes::SetQuotesInherit(const nsStyleQuotes* aOther)
|
||||
{
|
||||
// The initial value for quotes is the en-US typographic convention:
|
||||
// outermost are LEFT and RIGHT DOUBLE QUOTATION MARK, alternating
|
||||
// with LEFT and RIGHT SINGLE QUOTATION MARK.
|
||||
static const char16_t initialQuotes[8] = {
|
||||
0x201C, 0, 0x201D, 0, 0x2018, 0, 0x2019, 0
|
||||
};
|
||||
|
||||
if (NS_SUCCEEDED(AllocateQuotes(2))) {
|
||||
SetQuotesAt(0,
|
||||
nsDependentString(&initialQuotes[0], 1),
|
||||
nsDependentString(&initialQuotes[2], 1));
|
||||
SetQuotesAt(1,
|
||||
nsDependentString(&initialQuotes[4], 1),
|
||||
nsDependentString(&initialQuotes[6], 1));
|
||||
}
|
||||
mQuotes = aOther->mQuotes;
|
||||
}
|
||||
|
||||
void
|
||||
nsStyleQuotes::CopyFrom(const nsStyleQuotes& aSource)
|
||||
nsStyleQuotes::SetQuotesInitial()
|
||||
{
|
||||
if (NS_SUCCEEDED(AllocateQuotes(aSource.QuotesCount()))) {
|
||||
uint32_t count = (mQuotesCount * 2);
|
||||
for (uint32_t index = 0; index < count; index += 2) {
|
||||
aSource.GetQuotesAt(index, mQuotes[index], mQuotes[index + 1]);
|
||||
}
|
||||
if (!sInitialQuotes) {
|
||||
// The initial value for quotes is the en-US typographic convention:
|
||||
// outermost are LEFT and RIGHT DOUBLE QUOTATION MARK, alternating
|
||||
// with LEFT and RIGHT SINGLE QUOTATION MARK.
|
||||
static const char16_t initialQuotes[8] = {
|
||||
0x201C, 0, 0x201D, 0, 0x2018, 0, 0x2019, 0
|
||||
};
|
||||
|
||||
sInitialQuotes = new nsStyleQuoteValues;
|
||||
sInitialQuotes->mQuotePairs.AppendElement(
|
||||
std::make_pair(nsDependentString(&initialQuotes[0], 1),
|
||||
nsDependentString(&initialQuotes[2], 1)));
|
||||
sInitialQuotes->mQuotePairs.AppendElement(
|
||||
std::make_pair(nsDependentString(&initialQuotes[4], 1),
|
||||
nsDependentString(&initialQuotes[6], 1)));
|
||||
}
|
||||
|
||||
mQuotes = sInitialQuotes;
|
||||
}
|
||||
|
||||
nsChangeHint nsStyleQuotes::CalcDifference(const nsStyleQuotes& aOther) const
|
||||
void
|
||||
nsStyleQuotes::SetQuotesNone()
|
||||
{
|
||||
if (!sNoneQuotes) {
|
||||
sNoneQuotes = new nsStyleQuoteValues;
|
||||
}
|
||||
mQuotes = sNoneQuotes;
|
||||
}
|
||||
|
||||
void
|
||||
nsStyleQuotes::SetQuotes(nsStyleQuoteValues::QuotePairArray&& aValues)
|
||||
{
|
||||
mQuotes = new nsStyleQuoteValues;
|
||||
mQuotes->mQuotePairs = Move(aValues);
|
||||
}
|
||||
|
||||
const nsStyleQuoteValues::QuotePairArray&
|
||||
nsStyleQuotes::GetQuotePairs() const
|
||||
{
|
||||
return mQuotes->mQuotePairs;
|
||||
}
|
||||
|
||||
nsChangeHint
|
||||
nsStyleQuotes::CalcDifference(const nsStyleQuotes& aOther) const
|
||||
{
|
||||
// If the quotes implementation is ever going to change we might not need
|
||||
// a framechange here and a reflow should be sufficient. See bug 35768.
|
||||
if (mQuotesCount == aOther.mQuotesCount) {
|
||||
uint32_t ix = (mQuotesCount * 2);
|
||||
while (0 < ix--) {
|
||||
if (mQuotes[ix] != aOther.mQuotes[ix]) {
|
||||
return NS_STYLE_HINT_FRAMECHANGE;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_STYLE_HINT_NONE;
|
||||
if (mQuotes != aOther.mQuotes &&
|
||||
mQuotes->mQuotePairs != aOther.mQuotes->mQuotePairs) {
|
||||
return NS_STYLE_HINT_FRAMECHANGE;
|
||||
}
|
||||
return NS_STYLE_HINT_FRAMECHANGE;
|
||||
|
||||
return NS_STYLE_HINT_NONE;
|
||||
}
|
||||
|
||||
StaticRefPtr<nsStyleQuoteValues>
|
||||
nsStyleQuotes::sInitialQuotes;
|
||||
|
||||
StaticRefPtr<nsStyleQuoteValues>
|
||||
nsStyleQuotes::sNoneQuotes;
|
||||
|
||||
|
||||
// --------------------
|
||||
// nsStyleTextReset
|
||||
//
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/CSSVariableValues.h"
|
||||
#include "mozilla/SheetType.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/StyleStructContext.h"
|
||||
#include "nsColor.h"
|
||||
#include "nsCoord.h"
|
||||
|
@ -33,6 +34,7 @@
|
|||
#include "Orientation.h"
|
||||
#include "CounterStyleManager.h"
|
||||
#include <cstddef> // offsetof()
|
||||
#include <utility>
|
||||
|
||||
class nsIFrame;
|
||||
class nsIURI;
|
||||
|
@ -2796,6 +2798,22 @@ struct nsStyleCounterData
|
|||
|
||||
#define DELETE_ARRAY_IF(array) if (array) { delete[] array; array = nullptr; }
|
||||
|
||||
/**
|
||||
* An object that allows sharing of arrays that store 'quotes' property
|
||||
* values. This is particularly important for inheritance, where we want
|
||||
* to share the same 'quotes' value with a parent style context.
|
||||
*/
|
||||
class nsStyleQuoteValues
|
||||
{
|
||||
public:
|
||||
typedef nsTArray<std::pair<nsString, nsString>> QuotePairArray;
|
||||
NS_INLINE_DECL_REFCOUNTING(nsStyleQuoteValues);
|
||||
QuotePairArray mQuotePairs;
|
||||
|
||||
private:
|
||||
~nsStyleQuoteValues() {}
|
||||
};
|
||||
|
||||
struct nsStyleQuotes
|
||||
{
|
||||
explicit nsStyleQuotes(StyleStructContext aContext);
|
||||
|
@ -2812,10 +2830,6 @@ struct nsStyleQuotes
|
|||
aContext->PresShell()->
|
||||
FreeByObjectID(mozilla::eArenaObjectID_nsStyleQuotes, this);
|
||||
}
|
||||
|
||||
void SetInitial();
|
||||
void CopyFrom(const nsStyleQuotes& aSource);
|
||||
|
||||
nsChangeHint CalcDifference(const nsStyleQuotes& aOther) const;
|
||||
static nsChangeHint MaxDifference() {
|
||||
return NS_STYLE_HINT_FRAMECHANGE;
|
||||
|
@ -2828,56 +2842,24 @@ struct nsStyleQuotes
|
|||
nsChangeHint_ClearAncestorIntrinsics;
|
||||
}
|
||||
|
||||
uint32_t QuotesCount(void) const { return mQuotesCount; } // [inherited]
|
||||
|
||||
const nsString* OpenQuoteAt(uint32_t aIndex) const
|
||||
{
|
||||
NS_ASSERTION(aIndex < mQuotesCount, "out of range");
|
||||
return mQuotes + (aIndex * 2);
|
||||
}
|
||||
const nsString* CloseQuoteAt(uint32_t aIndex) const
|
||||
{
|
||||
NS_ASSERTION(aIndex < mQuotesCount, "out of range");
|
||||
return mQuotes + (aIndex * 2 + 1);
|
||||
}
|
||||
nsresult GetQuotesAt(uint32_t aIndex, nsString& aOpen, nsString& aClose) const {
|
||||
if (aIndex < mQuotesCount) {
|
||||
aIndex *= 2;
|
||||
aOpen = mQuotes[aIndex];
|
||||
aClose = mQuotes[++aIndex];
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
static void Shutdown() {
|
||||
sInitialQuotes = nullptr;
|
||||
sNoneQuotes = nullptr;
|
||||
}
|
||||
|
||||
nsresult AllocateQuotes(uint32_t aCount) {
|
||||
if (aCount != mQuotesCount) {
|
||||
DELETE_ARRAY_IF(mQuotes);
|
||||
if (aCount) {
|
||||
mQuotes = new nsString[aCount * 2];
|
||||
if (! mQuotes) {
|
||||
mQuotesCount = 0;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
mQuotesCount = aCount;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
const nsStyleQuoteValues::QuotePairArray& GetQuotePairs() const;
|
||||
|
||||
nsresult SetQuotesAt(uint32_t aIndex, const nsString& aOpen, const nsString& aClose) {
|
||||
if (aIndex < mQuotesCount) {
|
||||
aIndex *= 2;
|
||||
mQuotes[aIndex] = aOpen;
|
||||
mQuotes[++aIndex] = aClose;
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
void SetQuotesInherit(const nsStyleQuotes* aOther);
|
||||
void SetQuotesInitial();
|
||||
void SetQuotesNone();
|
||||
void SetQuotes(nsStyleQuoteValues::QuotePairArray&& aValues);
|
||||
|
||||
protected:
|
||||
uint32_t mQuotesCount;
|
||||
nsString* mQuotes;
|
||||
private:
|
||||
RefPtr<nsStyleQuoteValues> mQuotes; // [inherited]
|
||||
|
||||
// nsStyleQuoteValues objects representing two common values, for sharing.
|
||||
static mozilla::StaticRefPtr<nsStyleQuoteValues> sInitialQuotes;
|
||||
static mozilla::StaticRefPtr<nsStyleQuoteValues> sNoneQuotes;
|
||||
};
|
||||
|
||||
struct nsStyleContent
|
||||
|
|
Загрузка…
Ссылка в новой задаче