Bug 576044 (5/12): eliminate ValueList as a storage type. r=dbaron a2.0=dbaron

This commit is contained in:
Zack Weinberg 2010-08-19 15:33:44 -04:00
parent 69b647977d
commit ca47f883ec
16 changed files with 1104 additions and 1508 deletions

View File

@ -1916,7 +1916,8 @@ nsGenericHTMLElement::MapBackgroundInto(const nsMappedAttributes* aAttributes,
return;
nsPresContext* presContext = aData->mPresContext;
if (!aData->mColorData->mBackImage && presContext->UseDocumentColors()) {
if (aData->mColorData->mBackImage.GetUnit() == eCSSUnit_Null &&
presContext->UseDocumentColors()) {
// background
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::background);
if (value && value->Type() == nsAttrValue::eString) {
@ -1946,11 +1947,9 @@ nsGenericHTMLElement::MapBackgroundInto(const nsMappedAttributes* aAttributes,
doc->NodePrincipal(), doc);
buffer->Release();
if (NS_LIKELY(img != 0)) {
// Use nsRuleDataColor's temporary mTempBackImage to
// make a value list.
aData->mColorData->mTempBackImage.mValue.SetImageValue(img);
aData->mColorData->mBackImage =
&aData->mColorData->mTempBackImage;
nsCSSValueList* list =
aData->mColorData->mBackImage.SetListValue();
list->mValue.SetImageValue(img);
}
}
}
@ -1958,10 +1957,8 @@ nsGenericHTMLElement::MapBackgroundInto(const nsMappedAttributes* aAttributes,
else if (presContext->CompatibilityMode() == eCompatibility_NavQuirks) {
// in NavQuirks mode, allow the empty string to set the
// background to empty
// Use nsRuleDataColor's temporary mTempBackImage to make a value list.
aData->mColorData->mBackImage = nsnull;
aData->mColorData->mTempBackImage.mValue.SetNoneValue();
aData->mColorData->mBackImage = &aData->mColorData->mTempBackImage;
nsCSSValueList* list = aData->mColorData->mBackImage.SetListValue();
list->mValue.SetNoneValue();
}
}
}

View File

@ -58,6 +58,7 @@
#include "nsStyleUtil.h"
#include "nsStyleConsts.h"
#include "nsCOMPtr.h"
#include "nsPrintfCString.h"
namespace mozilla {
namespace css {
@ -138,10 +139,6 @@ PRBool Declaration::AppendValueToString(nsCSSProperty aProperty,
static_cast<const nsCSSValue*>(storage)->
AppendToString(aProperty, aResult);
break;
case eCSSType_ValueList:
(*static_cast<nsCSSValueList*const*>(storage))->
AppendToString(aProperty, aResult);
break;
}
return PR_TRUE;
}
@ -204,12 +201,6 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const
const nsCSSValue *val = static_cast<const nsCSSValue*>(storage);
unit = val->GetUnit();
} break;
case eCSSType_ValueList: {
const nsCSSValueList* item =
*static_cast<nsCSSValueList*const*>(storage);
NS_ABORT_IF_FALSE(item, "null not allowed in compressed block");
unit = item->mValue.GetUnit();
} break;
}
if (unit == eCSSUnit_Inherit) {
++inheritCount;
@ -419,18 +410,23 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const
// background-origin that are different and not the default
// values. (We omit them if they're both default.)
const nsCSSValueList *image =
* data->ValueListStorageFor(eCSSProperty_background_image);
data->ValueStorageFor(eCSSProperty_background_image)->
GetListValue();
const nsCSSValueList *repeat =
* data->ValueListStorageFor(eCSSProperty_background_repeat);
data->ValueStorageFor(eCSSProperty_background_repeat)->
GetListValue();
const nsCSSValueList *attachment =
* data->ValueListStorageFor(eCSSProperty_background_attachment);
data->ValueStorageFor(eCSSProperty_background_attachment)->
GetListValue();
const nsCSSValuePairList *position =
data->ValueStorageFor(eCSSProperty_background_position)->
GetPairListValue();
const nsCSSValueList *clip =
* data->ValueListStorageFor(eCSSProperty_background_clip);
data->ValueStorageFor(eCSSProperty_background_clip)->
GetListValue();
const nsCSSValueList *origin =
* data->ValueListStorageFor(eCSSProperty_background_origin);
data->ValueStorageFor(eCSSProperty_background_origin)->
GetListValue();
const nsCSSValuePairList *size =
data->ValueStorageFor(eCSSProperty_background_size)->
GetPairListValue();
@ -621,45 +617,80 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const
break;
}
case eCSSProperty_transition: {
#define NUM_TRANSITION_SUBPROPS 4
const nsCSSProperty* subprops =
nsCSSProps::SubpropertyEntryFor(aProperty);
#ifdef DEBUG
for (int i = 0; i < NUM_TRANSITION_SUBPROPS; ++i) {
NS_ASSERTION(nsCSSProps::kTypeTable[subprops[i]] == eCSSType_ValueList,
"type mismatch");
}
NS_ASSERTION(subprops[NUM_TRANSITION_SUBPROPS] == eCSSProperty_UNKNOWN,
"length mismatch");
#endif
const nsCSSValueList* val[NUM_TRANSITION_SUBPROPS];
for (int i = 0; i < NUM_TRANSITION_SUBPROPS; ++i) {
val[i] = *data->ValueListStorageFor(subprops[i]);
}
// Merge the lists of the subproperties into a single list.
for (;;) {
for (int i = 0; i < NUM_TRANSITION_SUBPROPS; ++i) {
val[i]->mValue.AppendToString(subprops[i], aValue);
const nsCSSValue &transProp =
*data->ValueStorageFor(eCSSProperty_transition_property);
const nsCSSValue &transDuration =
*data->ValueStorageFor(eCSSProperty_transition_duration);
const nsCSSValue &transTiming =
*data->ValueStorageFor(eCSSProperty_transition_timing_function);
const nsCSSValue &transDelay =
*data->ValueStorageFor(eCSSProperty_transition_delay);
NS_ABORT_IF_FALSE(transDuration.GetUnit() == eCSSUnit_List ||
transDuration.GetUnit() == eCSSUnit_ListDep,
nsPrintfCString(32, "bad t-duration unit %d",
transDuration.GetUnit()).get());
NS_ABORT_IF_FALSE(transTiming.GetUnit() == eCSSUnit_List ||
transTiming.GetUnit() == eCSSUnit_ListDep,
nsPrintfCString(32, "bad t-timing unit %d",
transTiming.GetUnit()).get());
NS_ABORT_IF_FALSE(transDelay.GetUnit() == eCSSUnit_List ||
transDelay.GetUnit() == eCSSUnit_ListDep,
nsPrintfCString(32, "bad t-delay unit %d",
transDelay.GetUnit()).get());
const nsCSSValueList* dur = transDuration.GetListValue();
const nsCSSValueList* tim = transTiming.GetListValue();
const nsCSSValueList* del = transDelay.GetListValue();
if (transProp.GetUnit() == eCSSUnit_None ||
transProp.GetUnit() == eCSSUnit_All) {
// If any of the other three lists has more than one element,
// we can't use the shorthand.
if (!dur->mNext && !tim->mNext && !del->mNext) {
transProp.AppendToString(eCSSProperty_transition_property, aValue);
aValue.Append(PRUnichar(' '));
val[i] = val[i]->mNext;
dur->mValue.AppendToString(eCSSProperty_transition_duration,aValue);
aValue.Append(PRUnichar(' '));
tim->mValue.AppendToString(eCSSProperty_transition_timing_function, aValue);
aValue.Append(PRUnichar(' '));
del->mValue.AppendToString(eCSSProperty_transition_delay, aValue);
aValue.Append(PRUnichar(' '));
} else {
aValue.Truncate();
}
// Remove the last space.
aValue.Truncate(aValue.Length() - 1);
PR_STATIC_ASSERT(NUM_TRANSITION_SUBPROPS == 4);
if (!val[0] || !val[1] || !val[2] || !val[3]) {
break;
} else {
NS_ABORT_IF_FALSE(transProp.GetUnit() == eCSSUnit_List ||
transProp.GetUnit() == eCSSUnit_ListDep,
nsPrintfCString(32, "bad t-prop unit %d",
transProp.GetUnit()).get());
const nsCSSValueList* pro = transProp.GetListValue();
for (;;) {
pro->mValue.AppendToString(eCSSProperty_transition_property,
aValue);
aValue.Append(PRUnichar(' '));
dur->mValue.AppendToString(eCSSProperty_transition_duration,
aValue);
aValue.Append(PRUnichar(' '));
tim->mValue.AppendToString(eCSSProperty_transition_timing_function,
aValue);
aValue.Append(PRUnichar(' '));
del->mValue.AppendToString(eCSSProperty_transition_delay,
aValue);
pro = pro->mNext;
dur = dur->mNext;
tim = tim->mNext;
del = del->mNext;
if (!pro || !dur || !tim || !del) {
break;
}
aValue.AppendLiteral(", ");
}
if (pro || dur || tim || del) {
// Lists not all the same length, can't use shorthand.
aValue.Truncate();
}
aValue.AppendLiteral(", ");
}
PR_STATIC_ASSERT(NUM_TRANSITION_SUBPROPS == 4);
if (val[0] || val[1] || val[2] || val[3]) {
// The sublists are different lengths, so this can't be
// represented as the shorthand.
aValue.Truncate();
}
#undef NUM_TRANSITION_SUBPROPS
break;
}

View File

@ -71,17 +71,8 @@ struct CDBValueStorage {
nsCSSValue value;
};
struct CDBPointerStorage {
nsCSSProperty property;
void *value;
};
enum {
CDBValueStorage_advance = sizeof(CDBValueStorage),
// round up using the closest estimate we can get of the alignment
// requirements of nsCSSValue:
CDBPointerStorage_advance = PR_ROUNDUP(sizeof(CDBPointerStorage),
sizeof(CDBValueStorage) - sizeof(nsCSSValue))
CDBValueStorage_advance = sizeof(CDBValueStorage)
};
/*
@ -108,34 +99,6 @@ inline const nsCSSValue* ValueAtCursor(const char *aCursor) {
return & reinterpret_cast<const CDBValueStorage*>(aCursor)->value;
}
inline void*& PointerAtCursor(char *aCursor) {
return reinterpret_cast<CDBPointerStorage*>(aCursor)->value;
}
inline void* PointerAtCursor(const char *aCursor) {
return reinterpret_cast<const CDBPointerStorage*>(aCursor)->value;
}
inline nsCSSValueList*& ValueListAtCursor(char *aCursor) {
return * reinterpret_cast<nsCSSValueList**>
(& reinterpret_cast<CDBPointerStorage*>(aCursor)->value);
}
inline nsCSSValueList* ValueListAtCursor(const char *aCursor) {
return static_cast<nsCSSValueList*>
(reinterpret_cast<const CDBPointerStorage*>(aCursor)->value);
}
inline nsCSSValuePairList*& ValuePairListAtCursor(char *aCursor) {
return * reinterpret_cast<nsCSSValuePairList**>
(& reinterpret_cast<CDBPointerStorage*>(aCursor)->value);
}
inline nsCSSValuePairList* ValuePairListAtCursor(const char *aCursor) {
return static_cast<nsCSSValuePairList*>
(reinterpret_cast<const CDBPointerStorage*>(aCursor)->value);
}
static PRBool
ShouldIgnoreColors(nsRuleData *aRuleData)
{
@ -168,7 +131,12 @@ static void
TryToStartImageLoad(const nsCSSValue& aValue, nsIDocument* aDocument,
nsCSSProperty aProperty)
{
if (nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_IMAGE_IS_IN_ARRAY_0)) {
if (aValue.GetUnit() == eCSSUnit_List) {
for (const nsCSSValueList* l = aValue.GetListValue(); l; l = l->mNext) {
TryToStartImageLoad(l->mValue, aDocument, aProperty);
}
} else if (nsCSSProps::PropHasFlags(aProperty,
CSS_PROPERTY_IMAGE_IS_IN_ARRAY_0)) {
if (aValue.GetUnit() == eCSSUnit_Array) {
TryToStartImageLoadOnValue(aValue.GetArrayValue()->Item(0), aDocument);
}
@ -246,40 +214,12 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
}
cursor += CDBValueStorage_advance;
} break;
case eCSSType_ValueList: {
void** target = static_cast<void**>(prop);
if (!*target) {
if (ShouldStartImageLoads(aRuleData, iProp)) {
for (nsCSSValueList* l = ValueListAtCursor(cursor);
l; l = l->mNext) {
TryToStartImageLoad(l->mValue, doc, iProp);
}
}
void* val = PointerAtCursor(cursor);
NS_ASSERTION(val, "oops");
*target = val;
if (nsCSSProps::PropHasFlags(iProp,
CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED) &&
ShouldIgnoreColors(aRuleData))
{
*target = nsnull;
}
}
cursor += CDBPointerStorage_advance;
} break;
}
} else {
switch (nsCSSProps::kTypeTable[iProp]) {
case eCSSType_Value: {
cursor += CDBValueStorage_advance;
} break;
case eCSSType_ValueList: {
cursor += CDBPointerStorage_advance;
} break;
}
}
}
@ -311,19 +251,12 @@ nsCSSCompressedDataBlock::StorageFor(nsCSSProperty aProperty) const
case eCSSType_Value: {
return ValueAtCursor(cursor);
}
case eCSSType_ValueList: {
return &PointerAtCursor(const_cast<char*>(cursor));
}
}
}
switch (nsCSSProps::kTypeTable[iProp]) {
case eCSSType_Value: {
cursor += CDBValueStorage_advance;
} break;
case eCSSType_ValueList: {
cursor += CDBPointerStorage_advance;
} break;
}
}
NS_ASSERTION(cursor == cursor_end, "inconsistent data");
@ -358,18 +291,6 @@ nsCSSCompressedDataBlock::Clone() const
cursor += CDBValueStorage_advance;
result_cursor += CDBValueStorage_advance;
} break;
case eCSSType_ValueList: {
void *copy = ValueListAtCursor(cursor)->Clone();
if (!copy) {
// so the destructor knows where to stop clearing
result->mBlockEnd = result_cursor;
return nsnull;
}
PointerAtCursor(result_cursor) = copy;
cursor += CDBPointerStorage_advance;
result_cursor += CDBPointerStorage_advance;
} break;
}
}
NS_ASSERTION(cursor == cursor_end, "inconsistent data");
@ -397,13 +318,6 @@ nsCSSCompressedDataBlock::~nsCSSCompressedDataBlock()
val->~nsCSSValue();
cursor += CDBValueStorage_advance;
} break;
case eCSSType_ValueList: {
nsCSSValueList* val = ValueListAtCursor(cursor);
NS_ASSERTION(val, "oops");
delete val;
cursor += CDBPointerStorage_advance;
} break;
}
}
NS_ASSERTION(cursor == cursor_end, "inconsistent data");
@ -432,16 +346,6 @@ nsCSSCompressedDataBlock::MoveValue(void *aSource, void *aDest,
memcpy(dest, source, sizeof(nsCSSValue));
new (source) nsCSSValue();
} break;
case eCSSType_ValueList: {
nsCSSValueList **source = static_cast<nsCSSValueList**>(aSource);
nsCSSValueList **dest = static_cast<nsCSSValueList**>(aDest);
if (**source != **dest)
*aChanged = PR_TRUE;
delete *dest;
*dest = *source;
*source = nsnull;
} break;
}
}
@ -500,15 +404,6 @@ nsCSSExpandedDataBlock::DoExpand(nsCSSCompressedDataBlock *aBlock,
memcpy(dest, val, sizeof(nsCSSValue));
cursor += CDBValueStorage_advance;
} break;
case eCSSType_ValueList: {
void* val = PointerAtCursor(cursor);
void** dest = static_cast<void**>(prop);
NS_ASSERTION(val, "oops");
NS_ASSERTION(!*dest, "expanding into non-empty block");
*dest = val;
cursor += CDBPointerStorage_advance;
} break;
}
}
NS_ASSERTION(cursor == cursor_end, "inconsistent data");
@ -557,14 +452,6 @@ nsCSSExpandedDataBlock::ComputeSize()
#endif
increment = CDBValueStorage_advance;
} break;
case eCSSType_ValueList: {
#ifdef DEBUG
void* val = *static_cast<void**>(prop);
NS_ASSERTION(val, "Null pointer while computing size");
#endif
increment = CDBPointerStorage_advance;
} break;
}
if (mPropertiesImportant.HasPropertyAt(iHigh, iLow))
result.important += increment;
@ -636,17 +523,6 @@ nsCSSExpandedDataBlock::Compress(nsCSSCompressedDataBlock **aNormalBlock,
new (val) nsCSSValue();
cursor += CDBValueStorage_advance;
} break;
case eCSSType_ValueList: {
void*& val = *static_cast<void**>(prop);
NS_ASSERTION(val, "Null pointer while compressing");
CDBPointerStorage *storage =
reinterpret_cast<CDBPointerStorage*>(cursor);
storage->property = iProp;
storage->value = val;
val = nsnull;
cursor += CDBPointerStorage_advance;
} break;
}
result->mStyleBits |=
nsCachedStyleData::GetBitForSID(nsCSSProps::kSIDTable[iProp]);
@ -713,14 +589,6 @@ nsCSSExpandedDataBlock::ClearLonghandProperty(nsCSSProperty aPropID)
nsCSSValue* val = static_cast<nsCSSValue*>(prop);
val->Reset();
} break;
case eCSSType_ValueList: {
nsCSSValueList*& val = *static_cast<nsCSSValueList**>(prop);
if (val) {
delete val;
val = nsnull;
}
} break;
}
}
@ -806,11 +674,6 @@ nsCSSExpandedDataBlock::DoAssertInitialState()
NS_ASSERTION(val->GetUnit() == eCSSUnit_Null,
"not initial state");
} break;
case eCSSType_ValueList: {
nsCSSValueList* val = *static_cast<nsCSSValueList**>(prop);
NS_ASSERTION(val == nsnull, "not initial state");
} break;
}
}
}

View File

@ -107,13 +107,6 @@ public:
"type mismatch");
return static_cast<const nsCSSValue*>(StorageFor(aProperty));
}
const nsCSSValueList*const*
ValueListStorageFor(nsCSSProperty aProperty) const {
NS_ABORT_IF_FALSE(nsCSSProps::kTypeTable[aProperty] ==
eCSSType_ValueList,
"type mismatch");
return static_cast<const nsCSSValueList*const*>(StorageFor(aProperty));
}
/**
* Clone this block, or return null on out-of-memory.

File diff suppressed because it is too large Load Diff

View File

@ -445,7 +445,7 @@ CSS_PROP_BACKGROUND(
CSS_PROPERTY_VALUE_LIST_USES_COMMAS,
Color,
mBackAttachment,
eCSSType_ValueList,
eCSSType_Value,
kBackgroundAttachmentKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
@ -457,7 +457,7 @@ CSS_PROP_BACKGROUND(
CSS_PROPERTY_VALUE_LIST_USES_COMMAS,
Color,
mBackClip,
eCSSType_ValueList,
eCSSType_Value,
kBackgroundOriginKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
@ -483,7 +483,7 @@ CSS_PROP_BACKGROUND(
CSS_PROPERTY_START_IMAGE_LOADS,
Color,
mBackImage,
eCSSType_ValueList,
eCSSType_Value,
nsnull,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
@ -506,7 +506,7 @@ CSS_PROP_BACKGROUND(
CSS_PROPERTY_VALUE_LIST_USES_COMMAS,
Color,
mBackOrigin,
eCSSType_ValueList,
eCSSType_Value,
kBackgroundOriginKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
@ -530,7 +530,7 @@ CSS_PROP_BACKGROUND(
CSS_PROPERTY_VALUE_LIST_USES_COMMAS,
Color,
mBackRepeat,
eCSSType_ValueList,
eCSSType_Value,
kBackgroundRepeatKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
@ -587,7 +587,7 @@ CSS_PROP_BORDER(
CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED,
Margin,
mBorderColors.mBottom,
eCSSType_ValueList,
eCSSType_Value,
nsnull,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
@ -760,7 +760,7 @@ CSS_PROP_BORDER(
CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED,
Margin,
mBorderColors.mLeft,
eCSSType_ValueList,
eCSSType_Value,
nsnull,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
@ -909,7 +909,7 @@ CSS_PROP_BORDER(
CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED,
Margin,
mBorderColors.mRight,
eCSSType_ValueList,
eCSSType_Value,
nsnull,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
@ -1099,7 +1099,7 @@ CSS_PROP_BORDER(
CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED,
Margin,
mBorderColors.mTop,
eCSSType_ValueList,
eCSSType_Value,
nsnull,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
@ -1150,7 +1150,7 @@ CSS_PROP_BORDER(
CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED,
Margin,
mBoxShadow,
eCSSType_ValueList,
eCSSType_Value,
kBoxShadowTypeKTable,
offsetof(nsStyleBorder, mBoxShadow),
eStyleAnimType_Shadow)
@ -1288,7 +1288,7 @@ CSS_PROP_CONTENT(
CSS_PROPERTY_START_IMAGE_LOADS,
Content,
mContent,
eCSSType_ValueList,
eCSSType_Value,
kContentKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
@ -1346,7 +1346,7 @@ CSS_PROP_USERINTERFACE(
CSS_PROPERTY_IMAGE_IS_IN_ARRAY_0,
UserInterface,
mCursor,
eCSSType_ValueList,
eCSSType_Value,
kCursorKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
@ -2354,7 +2354,7 @@ CSS_PROP_TEXT(
CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED,
Text,
mTextShadow,
eCSSType_ValueList,
eCSSType_Value,
nsnull,
offsetof(nsStyleText, mTextShadow),
eStyleAnimType_Shadow)
@ -2376,7 +2376,7 @@ CSS_PROP_DISPLAY(
0,
Display,
mTransform,
eCSSType_ValueList,
eCSSType_Value,
kDisplayKTable,
offsetof(nsStyleDisplay, mSpecifiedTransform),
eStyleAnimType_Custom)
@ -2414,7 +2414,7 @@ CSS_PROP_DISPLAY(
CSS_PROPERTY_VALUE_LIST_USES_COMMAS,
Display,
mTransitionDelay,
eCSSType_ValueList,
eCSSType_Value,
nsnull,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
@ -2425,7 +2425,7 @@ CSS_PROP_DISPLAY(
CSS_PROPERTY_VALUE_LIST_USES_COMMAS,
Display,
mTransitionDuration,
eCSSType_ValueList,
eCSSType_Value,
nsnull,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
@ -2436,7 +2436,7 @@ CSS_PROP_DISPLAY(
CSS_PROPERTY_VALUE_LIST_USES_COMMAS,
Display,
mTransitionProperty,
eCSSType_ValueList /* list of CSS properties that have transitions ? */,
eCSSType_Value /* list of CSS properties that have transitions ? */,
nsnull,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
@ -2447,7 +2447,7 @@ CSS_PROP_DISPLAY(
CSS_PROPERTY_VALUE_LIST_USES_COMMAS,
Display,
mTransitionTimingFunction,
eCSSType_ValueList,
eCSSType_Value,
kTransitionTimingFunctionKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
@ -2983,7 +2983,7 @@ CSS_PROP_SVG(
CSS_PROPERTY_VALUE_LIST_USES_COMMAS,
SVG,
mStrokeDasharray,
eCSSType_ValueList,
eCSSType_Value,
nsnull,
CSS_PROP_NO_OFFSET, /* property stored in 2 separate members */
eStyleAnimType_Custom)

View File

@ -82,8 +82,7 @@ enum nsCSSProperty {
// The types of values that can be in the nsCSS*/nsRuleData* structs.
// See nsCSSPropList.h for uses.
enum nsCSSType {
eCSSType_Value,
eCSSType_ValueList
eCSSType_Value
};
// The "descriptors" that can appear in a @font-face rule.

View File

@ -69,8 +69,10 @@
#define CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED (1<<4)
// A property that needs to have image loads started when a URL value
// for the property is used for an element. Supported only for
// eCSSType_Value and eCSSType_ValueList.
// for the property is used for an element. This is supported only
// for a few possible value formats: image directly in the value; list
// of images; and with CSS_PROPERTY_IMAGE_IS_IN_ARRAY_0, image in slot
// 0 of an array, or list of such arrays.
#define CSS_PROPERTY_START_IMAGE_LOADS (1<<5)
// Should be set only for properties with START_IMAGE_LOADS. Indicates

View File

@ -61,11 +61,6 @@ nsCSSFont::~nsCSSFont(void)
// --- nsCSSColor -----------------
nsCSSColor::nsCSSColor(void)
: mBackImage(nsnull)
, mBackRepeat(nsnull)
, mBackAttachment(nsnull)
, mBackClip(nsnull)
, mBackOrigin(nsnull)
{
MOZ_COUNT_CTOR(nsCSSColor);
}
@ -73,18 +68,11 @@ nsCSSColor::nsCSSColor(void)
nsCSSColor::~nsCSSColor(void)
{
MOZ_COUNT_DTOR(nsCSSColor);
delete mBackImage;
delete mBackRepeat;
delete mBackAttachment;
delete mBackClip;
delete mBackOrigin;
}
// --- nsCSSText -----------------
nsCSSText::nsCSSText(void)
: mTextShadow(nsnull)
{
MOZ_COUNT_CTOR(nsCSSText);
}
@ -92,7 +80,6 @@ nsCSSText::nsCSSText(void)
nsCSSText::~nsCSSText(void)
{
MOZ_COUNT_DTOR(nsCSSText);
delete mTextShadow;
}
// --- nsCSSCornerSizes -----------------
@ -135,47 +122,9 @@ nsCSSCornerSizes::corners[4] = {
&nsCSSCornerSizes::mBottomLeft,
};
// --- nsCSSValueListRect -----------------
nsCSSValueListRect::nsCSSValueListRect(void)
: mTop(nsnull),
mRight(nsnull),
mBottom(nsnull),
mLeft(nsnull)
{
MOZ_COUNT_CTOR(nsCSSValueListRect);
}
nsCSSValueListRect::nsCSSValueListRect(const nsCSSValueListRect& aCopy)
: mTop(aCopy.mTop),
mRight(aCopy.mRight),
mBottom(aCopy.mBottom),
mLeft(aCopy.mLeft)
{
MOZ_COUNT_CTOR(nsCSSValueListRect);
}
nsCSSValueListRect::~nsCSSValueListRect()
{
MOZ_COUNT_DTOR(nsCSSValueListRect);
}
/* static */ const nsCSSValueListRect::side_type
nsCSSValueListRect::sides[4] = {
&nsCSSValueListRect::mTop,
&nsCSSValueListRect::mRight,
&nsCSSValueListRect::mBottom,
&nsCSSValueListRect::mLeft,
};
// --- nsCSSDisplay -----------------
/* During allocation, null-out the transform list. */
nsCSSDisplay::nsCSSDisplay(void) : mTransform(nsnull)
, mTransitionProperty(nsnull)
, mTransitionDuration(nsnull)
, mTransitionTimingFunction(nsnull)
, mTransitionDelay(nsnull)
nsCSSDisplay::nsCSSDisplay(void)
{
MOZ_COUNT_CTOR(nsCSSDisplay);
}
@ -188,7 +137,6 @@ nsCSSDisplay::~nsCSSDisplay(void)
// --- nsCSSMargin -----------------
nsCSSMargin::nsCSSMargin(void)
: mBoxShadow(nsnull)
{
MOZ_COUNT_CTOR(nsCSSMargin);
}
@ -196,7 +144,6 @@ nsCSSMargin::nsCSSMargin(void)
nsCSSMargin::~nsCSSMargin(void)
{
MOZ_COUNT_DTOR(nsCSSMargin);
delete mBoxShadow;
}
// --- nsCSSPosition -----------------
@ -262,7 +209,6 @@ nsCSSPage::~nsCSSPage(void)
// --- nsCSSContent -----------------
nsCSSContent::nsCSSContent(void)
: mContent(nsnull)
{
MOZ_COUNT_CTOR(nsCSSContent);
}
@ -270,13 +216,11 @@ nsCSSContent::nsCSSContent(void)
nsCSSContent::~nsCSSContent(void)
{
MOZ_COUNT_DTOR(nsCSSContent);
delete mContent;
}
// --- nsCSSUserInterface -----------------
nsCSSUserInterface::nsCSSUserInterface(void)
: mCursor(nsnull)
{
MOZ_COUNT_CTOR(nsCSSUserInterface);
}
@ -284,7 +228,6 @@ nsCSSUserInterface::nsCSSUserInterface(void)
nsCSSUserInterface::~nsCSSUserInterface(void)
{
MOZ_COUNT_DTOR(nsCSSUserInterface);
delete mCursor;
}
// --- nsCSSAural -----------------
@ -325,7 +268,7 @@ nsCSSColumn::~nsCSSColumn(void)
// --- nsCSSSVG -----------------
nsCSSSVG::nsCSSSVG(void) : mStrokeDasharray(nsnull)
nsCSSSVG::nsCSSSVG(void)
{
MOZ_COUNT_CTOR(nsCSSSVG);
}
@ -333,5 +276,4 @@ nsCSSSVG::nsCSSSVG(void) : mStrokeDasharray(nsnull)
nsCSSSVG::~nsCSSSVG(void)
{
MOZ_COUNT_DTOR(nsCSSSVG);
delete mStrokeDasharray;
}

View File

@ -97,20 +97,6 @@ protected:
static const corner_type corners[4];
};
struct nsCSSValueListRect {
nsCSSValueListRect(void);
nsCSSValueListRect(const nsCSSValueListRect& aCopy);
~nsCSSValueListRect();
nsCSSValueList* mTop;
nsCSSValueList* mRight;
nsCSSValueList* mBottom;
nsCSSValueList* mLeft;
typedef nsCSSValueList* nsCSSValueListRect::*side_type;
static const side_type sides[4];
};
/****************************************************************************/
struct nsCSSStruct {
@ -164,27 +150,22 @@ struct nsCSSColor : public nsCSSStruct {
nsCSSColor(void);
~nsCSSColor(void);
nsCSSValue mColor;
nsCSSValue mBackColor;
nsCSSValueList* mBackImage;
nsCSSValueList* mBackRepeat;
nsCSSValueList* mBackAttachment;
nsCSSValue mBackPosition;
nsCSSValue mBackSize;
nsCSSValueList* mBackClip;
nsCSSValueList* mBackOrigin;
nsCSSValue mBackInlinePolicy;
nsCSSValue mColor;
nsCSSValue mBackColor;
nsCSSValue mBackImage;
nsCSSValue mBackRepeat;
nsCSSValue mBackAttachment;
nsCSSValue mBackPosition;
nsCSSValue mBackSize;
nsCSSValue mBackClip;
nsCSSValue mBackOrigin;
nsCSSValue mBackInlinePolicy;
private:
nsCSSColor(const nsCSSColor& aOther); // NOT IMPLEMENTED
};
struct nsRuleDataColor : public nsCSSColor {
nsRuleDataColor() {}
// A little bit of a hack here: now that background-image is
// represented by a value list, attribute mapping code needs a place
// to store one item in a value list in order to map a simple value.
nsCSSValueList mTempBackImage;
private:
nsRuleDataColor(const nsRuleDataColor& aOther); // NOT IMPLEMENTED
};
@ -201,7 +182,7 @@ struct nsCSSText : public nsCSSStruct {
nsCSSValue mTextAlign;
nsCSSValue mTextIndent;
nsCSSValue mDecoration;
nsCSSValueList* mTextShadow; // NEW
nsCSSValue mTextShadow; // NEW
nsCSSValue mUnicodeBidi; // NEW
nsCSSValue mLineHeight;
nsCSSValue mWhiteSpace;
@ -234,12 +215,12 @@ struct nsCSSDisplay : public nsCSSStruct {
nsCSSValue mPointerEvents;
nsCSSValue mVisibility;
nsCSSValue mOpacity;
nsCSSValueList *mTransform; // List of Arrays containing transform information
nsCSSValue mTransform; // List of Arrays containing transform information
nsCSSValue mTransformOrigin;
nsCSSValueList* mTransitionProperty;
nsCSSValueList* mTransitionDuration;
nsCSSValueList* mTransitionTimingFunction;
nsCSSValueList* mTransitionDelay;
nsCSSValue mTransitionProperty;
nsCSSValue mTransitionDuration;
nsCSSValue mTransitionTimingFunction;
nsCSSValue mTransitionDelay;
// temp fix for bug 24000
nsCSSValue mBreakBefore;
@ -288,7 +269,7 @@ struct nsCSSMargin : public nsCSSStruct {
nsCSSValue mBorderLeftColorRTLSource;
nsCSSValue mBorderRightColorLTRSource;
nsCSSValue mBorderRightColorRTLSource;
nsCSSValueListRect mBorderColors;
nsCSSRect mBorderColors;
nsCSSRect mBorderStyle;
nsCSSValue mBorderStartStyle;
nsCSSValue mBorderEndStyle;
@ -304,7 +285,7 @@ struct nsCSSMargin : public nsCSSStruct {
nsCSSCornerSizes mOutlineRadius;
nsCSSValue mFloatEdge; // NEW
nsCSSValue mBorderImage;
nsCSSValueList* mBoxShadow;
nsCSSValue mBoxShadow;
private:
nsCSSMargin(const nsCSSMargin& aOther); // NOT IMPLEMENTED
};
@ -419,11 +400,11 @@ struct nsCSSContent : public nsCSSStruct {
nsCSSContent(void);
~nsCSSContent(void);
nsCSSValueList* mContent;
nsCSSValue mCounterIncrement;
nsCSSValue mCounterReset;
nsCSSValue mMarkerOffset;
nsCSSValue mQuotes;
nsCSSValue mContent;
nsCSSValue mCounterIncrement;
nsCSSValue mCounterReset;
nsCSSValue mMarkerOffset;
nsCSSValue mQuotes;
private:
nsCSSContent(const nsCSSContent& aOther); // NOT IMPLEMENTED
};
@ -438,15 +419,15 @@ struct nsCSSUserInterface : public nsCSSStruct { // NEW
nsCSSUserInterface(void);
~nsCSSUserInterface(void);
nsCSSValue mUserInput;
nsCSSValue mUserModify;
nsCSSValue mUserSelect;
nsCSSValue mUserFocus;
nsCSSValueList* mCursor;
nsCSSValue mForceBrokenImageIcon;
nsCSSValue mIMEMode;
nsCSSValue mWindowShadow;
nsCSSValue mUserInput;
nsCSSValue mUserModify;
nsCSSValue mUserSelect;
nsCSSValue mUserFocus;
nsCSSValue mCursor;
nsCSSValue mForceBrokenImageIcon;
nsCSSValue mIMEMode;
nsCSSValue mWindowShadow;
private:
nsCSSUserInterface(const nsCSSUserInterface& aOther); // NOT IMPLEMENTED
};
@ -554,7 +535,7 @@ struct nsCSSSVG : public nsCSSStruct {
nsCSSValue mStopColor;
nsCSSValue mStopOpacity;
nsCSSValue mStroke;
nsCSSValueList *mStrokeDasharray;
nsCSSValue mStrokeDasharray;
nsCSSValue mStrokeDashoffset;
nsCSSValue mStrokeLinecap;
nsCSSValue mStrokeLinejoin;

View File

@ -166,6 +166,13 @@ nsCSSValue::nsCSSValue(const nsCSSValue& aCopy)
mValue.mRect = aCopy.mValue.mRect;
mValue.mRect->AddRef();
}
else if (eCSSUnit_List == mUnit) {
mValue.mList = aCopy.mValue.mList;
mValue.mList->AddRef();
}
else if (eCSSUnit_ListDep == mUnit) {
mValue.mListDependent = aCopy.mValue.mListDependent;
}
else if (eCSSUnit_PairList == mUnit) {
mValue.mPairList = aCopy.mValue.mPairList;
mValue.mPairList->AddRef();
@ -189,7 +196,9 @@ nsCSSValue& nsCSSValue::operator=(const nsCSSValue& aCopy)
PRBool nsCSSValue::operator==(const nsCSSValue& aOther) const
{
NS_ABORT_IF_FALSE(mUnit != eCSSUnit_PairListDep &&
NS_ABORT_IF_FALSE(mUnit != eCSSUnit_ListDep &&
aOther.mUnit != eCSSUnit_ListDep &&
mUnit != eCSSUnit_PairListDep &&
aOther.mUnit != eCSSUnit_PairListDep,
"don't use operator== with dependent lists");
@ -225,6 +234,9 @@ PRBool nsCSSValue::operator==(const nsCSSValue& aOther) const
else if (eCSSUnit_Rect == mUnit) {
return *mValue.mRect == *aOther.mValue.mRect;
}
else if (eCSSUnit_List == mUnit) {
return *mValue.mList == *aOther.mValue.mList;
}
else if (eCSSUnit_PairList == mUnit) {
return *mValue.mPairList == *aOther.mValue.mPairList;
}
@ -299,6 +311,8 @@ void nsCSSValue::DoReset()
mValue.mPair->Release();
} else if (eCSSUnit_Rect == mUnit) {
mValue.mRect->Release();
} else if (eCSSUnit_List == mUnit) {
mValue.mList->Release();
} else if (eCSSUnit_PairList == mUnit) {
mValue.mPairList->Release();
}
@ -433,6 +447,24 @@ nsCSSRect& nsCSSValue::SetRectValue()
return *mValue.mRect;
}
nsCSSValueList* nsCSSValue::SetListValue()
{
Reset();
mUnit = eCSSUnit_List;
mValue.mList = new nsCSSValueList_heap;
mValue.mList->AddRef();
return mValue.mList;
}
void nsCSSValue::SetDependentListValue(nsCSSValueList* aList)
{
Reset();
if (aList) {
mUnit = eCSSUnit_ListDep;
mValue.mListDependent = aList;
}
}
nsCSSValuePairList* nsCSSValue::SetPairListValue()
{
Reset();
@ -445,8 +477,10 @@ nsCSSValuePairList* nsCSSValue::SetPairListValue()
void nsCSSValue::SetDependentPairListValue(nsCSSValuePairList* aList)
{
Reset();
mUnit = eCSSUnit_PairListDep;
mValue.mPairListDependent = aList;
if (aList) {
mUnit = eCSSUnit_PairListDep;
mValue.mPairListDependent = aList;
}
}
void nsCSSValue::SetAutoValue()
@ -924,6 +958,8 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
GetPairValue().AppendToString(aProperty, aResult);
} else if (eCSSUnit_Rect == unit) {
GetRectValue().AppendToString(aProperty, aResult);
} else if (eCSSUnit_List == unit || eCSSUnit_ListDep == unit) {
GetListValue()->AppendToString(aProperty, aResult);
} else if (eCSSUnit_PairList == unit || eCSSUnit_PairListDep == unit) {
GetPairListValue()->AppendToString(aProperty, aResult);
}
@ -973,6 +1009,8 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
case eCSSUnit_Gradient: break;
case eCSSUnit_Pair: break;
case eCSSUnit_Rect: break;
case eCSSUnit_List: break;
case eCSSUnit_ListDep: break;
case eCSSUnit_PairList: break;
case eCSSUnit_PairListDep: break;

View File

@ -144,6 +144,9 @@ enum nsCSSUnit {
eCSSUnit_Pair = 50, // (nsCSSValuePair*) pair of values
eCSSUnit_Rect = 51, // (nsCSSRect*) rectangle (four values)
eCSSUnit_List = 52, // (nsCSSValueList*) list of values
eCSSUnit_ListDep = 53, // (nsCSSValueList*) same as List
// but does not own the list
eCSSUnit_PairList = 54, // (nsCSSValuePairList*) list of value pairs
eCSSUnit_PairListDep = 55, // (nsCSSValuePairList*) same as PairList
// but does not own the list
@ -194,6 +197,8 @@ struct nsCSSValuePair;
struct nsCSSValuePair_heap;
struct nsCSSRect;
struct nsCSSRect_heap;
struct nsCSSValueList;
struct nsCSSValueList_heap;
struct nsCSSValuePairList;
struct nsCSSValuePairList_heap;
@ -359,6 +364,9 @@ public:
inline nsCSSRect& GetRectValue();
inline const nsCSSRect& GetRectValue() const;
inline nsCSSValueList* GetListValue();
inline const nsCSSValueList* GetListValue() const;
inline nsCSSValuePairList* GetPairListValue();
inline const nsCSSValuePairList* GetPairListValue() const;
@ -407,6 +415,7 @@ public:
void SetGradientValue(nsCSSValueGradient* aGradient);
void SetPairValue(const nsCSSValuePair* aPair);
void SetPairValue(const nsCSSValue& xValue, const nsCSSValue& yValue);
void SetDependentListValue(nsCSSValueList* aList);
void SetDependentPairListValue(nsCSSValuePairList* aList);
void SetAutoValue();
void SetInheritValue();
@ -421,6 +430,7 @@ public:
// These are a little different - they allocate storage for you and
// return a handle.
nsCSSRect& SetRectValue();
nsCSSValueList* SetListValue();
nsCSSValuePairList* SetPairListValue();
void StartImageLoad(nsIDocument* aDocument) const; // Only pretend const
@ -507,6 +517,8 @@ protected:
nsCSSValueGradient* mGradient;
nsCSSValuePair_heap* mPair;
nsCSSRect_heap* mRect;
nsCSSValueList_heap* mList;
nsCSSValueList* mListDependent;
nsCSSValuePairList_heap* mPairList;
nsCSSValuePairList* mPairListDependent;
} mValue;
@ -638,6 +650,37 @@ private:
}
};
// nsCSSValueList_heap differs from nsCSSValueList only in being
// refcounted. It should not be necessary to use this class directly;
// it's an implementation detail of nsCSSValue.
struct nsCSSValueList_heap : public nsCSSValueList {
NS_INLINE_DECL_REFCOUNTING(nsCSSValueList_heap)
};
// This has to be here so that the relationship between nsCSSValueList
// and nsCSSValueList_heap is visible.
inline nsCSSValueList*
nsCSSValue::GetListValue()
{
if (mUnit == eCSSUnit_List)
return mValue.mList;
else {
NS_ABORT_IF_FALSE(mUnit == eCSSUnit_ListDep, "not a pairlist value");
return mValue.mListDependent;
}
}
inline const nsCSSValueList*
nsCSSValue::GetListValue() const
{
if (mUnit == eCSSUnit_List)
return mValue.mList;
else {
NS_ABORT_IF_FALSE(mUnit == eCSSUnit_ListDep, "not a pairlist value");
return mValue.mListDependent;
}
}
struct nsCSSRect {
nsCSSRect(void);
nsCSSRect(const nsCSSRect& aCopy);

File diff suppressed because it is too large Load Diff

View File

@ -690,7 +690,7 @@ protected:
const void* GetSVGResetData(nsStyleContext* aContext);
already_AddRefed<nsCSSShadowArray>
GetShadowData(nsCSSValueList* aList,
GetShadowData(const nsCSSValueList* aList,
nsStyleContext* aContext,
PRBool aIsBoxShadow,
PRBool& inherited);

View File

@ -1820,10 +1820,8 @@ nsStyleAnimation::UncomputeValue(nsCSSProperty aProperty,
case eUnit_Dasharray:
case eUnit_Shadow:
case eUnit_Transform:
NS_ABORT_IF_FALSE(nsCSSProps::kTypeTable[aProperty] ==
eCSSType_ValueList, "type mismatch");
*static_cast<nsCSSValueList**>(aSpecifiedValue) =
aComputedValue.GetCSSValueListValue();
static_cast<nsCSSValue*>(aSpecifiedValue)->
SetDependentListValue(aComputedValue.GetCSSValueListValue());
break;
case eUnit_CSSValuePairList:
static_cast<nsCSSValue*>(aSpecifiedValue)->
@ -1849,15 +1847,11 @@ nsStyleAnimation::UncomputeValue(nsCSSProperty aProperty,
return PR_TRUE;
}
nsCSSValue val;
nsCSSValueList* vl = nsnull;
void *storage;
switch (nsCSSProps::kTypeTable[aProperty]) {
case eCSSType_Value:
storage = &val;
break;
case eCSSType_ValueList:
storage = &vl;
break;
default:
NS_ABORT_IF_FALSE(PR_FALSE, "unexpected case");
storage = nsnull;
@ -1873,9 +1867,6 @@ nsStyleAnimation::UncomputeValue(nsCSSProperty aProperty,
case eCSSType_Value:
val.AppendToString(aProperty, aSpecifiedValue);
break;
case eCSSType_ValueList:
vl->AppendToString(aProperty, aSpecifiedValue);
break;
default:
NS_ABORT_IF_FALSE(PR_FALSE, "unexpected case");
return PR_FALSE;

View File

@ -1382,8 +1382,8 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
/* XXX needs to be on pseudo-elements */
initial_values: [ "normal", "none" ],
other_values: [ '""', "''", '"hello"', "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==)", "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==')", 'url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==")', 'counter(foo)', 'counter(bar, upper-roman)', 'counters(foo, ".")', "counters(bar, '-', lower-greek)", "'-' counter(foo) '.'", "attr(title)", "open-quote", "close-quote", "no-open-quote", "no-close-quote", "close-quote attr(title) counters(foo, '.', upper-alpha)", "counter(foo, none)", "counters(bar, '.', none)", "attr(\\32)", "attr(\\2)", "attr(-\\2)", "attr(-\\32)", "counter(\\2)", "counters(\\32, '.')", "counter(-\\32, upper-roman)", "counters(-\\2, '-', lower-greek)", "counter(\\()", "counters(a\\+b, '.')", "counter(\\}, upper-alpha)" ],
invalid_values: [ 'counters(foo)', 'counter(foo, ".")', 'attr("title")', "attr('title')", "attr(2)", "attr(-2)", "counter(2)", "counters(-2, '.')" ]
other_values: [ '""', "''", '"hello"', "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==)", "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==')", 'url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==")', 'counter(foo)', 'counter(bar, upper-roman)', 'counters(foo, ".")', "counters(bar, '-', lower-greek)", "'-' counter(foo) '.'", "attr(title)", "open-quote", "close-quote", "no-open-quote", "no-close-quote", "close-quote attr(title) counters(foo, '.', upper-alpha)", "counter(foo, none)", "counters(bar, '.', none)", "attr(\\32)", "attr(\\2)", "attr(-\\2)", "attr(-\\32)", "counter(\\2)", "counters(\\32, '.')", "counter(-\\32, upper-roman)", "counters(-\\2, '-', lower-greek)", "counter(\\()", "counters(a\\+b, '.')", "counter(\\}, upper-alpha)", "-moz-alt-content" ],
invalid_values: [ 'counters(foo)', 'counter(foo, ".")', 'attr("title")', "attr('title')", "attr(2)", "attr(-2)", "counter(2)", "counters(-2, '.')", "-moz-alt-content 'foo'", "'foo' -moz-alt-content" ]
},
"counter-increment": {
domProp: "counterIncrement",