summaryrefslogtreecommitdiffstats
path: root/WebCore/css/CSSMutableStyleDeclaration.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/css/CSSMutableStyleDeclaration.cpp')
-rw-r--r--WebCore/css/CSSMutableStyleDeclaration.cpp452
1 files changed, 193 insertions, 259 deletions
diff --git a/WebCore/css/CSSMutableStyleDeclaration.cpp b/WebCore/css/CSSMutableStyleDeclaration.cpp
index 1f29eba..2e2064a 100644
--- a/WebCore/css/CSSMutableStyleDeclaration.cpp
+++ b/WebCore/css/CSSMutableStyleDeclaration.cpp
@@ -24,7 +24,9 @@
#include "CSSImageValue.h"
#include "CSSParser.h"
#include "CSSProperty.h"
+#include "CSSPropertyLonghand.h"
#include "CSSPropertyNames.h"
+#include "CSSRule.h"
#include "CSSStyleSheet.h"
#include "CSSValueList.h"
#include "Document.h"
@@ -38,6 +40,10 @@ namespace WebCore {
CSSMutableStyleDeclaration::CSSMutableStyleDeclaration()
: m_node(0)
, m_variableDependentValueCount(0)
+ , m_strictParsing(false)
+#ifndef NDEBUG
+ , m_iteratorCount(0)
+#endif
{
}
@@ -45,15 +51,24 @@ CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent)
: CSSStyleDeclaration(parent)
, m_node(0)
, m_variableDependentValueCount(0)
+ , m_strictParsing(!parent || parent->useStrictParsing())
+#ifndef NDEBUG
+ , m_iteratorCount(0)
+#endif
{
}
-CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent, const DeprecatedValueList<CSSProperty>& values, unsigned variableDependentValueCount)
+CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent, const Vector<CSSProperty>& properties, unsigned variableDependentValueCount)
: CSSStyleDeclaration(parent)
- , m_values(values)
+ , m_properties(properties)
, m_node(0)
, m_variableDependentValueCount(variableDependentValueCount)
+ , m_strictParsing(!parent || parent->useStrictParsing())
+#ifndef NDEBUG
+ , m_iteratorCount(0)
+#endif
{
+ m_properties.shrinkToFit();
// FIXME: This allows duplicate properties.
}
@@ -61,10 +76,15 @@ CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent, const CS
: CSSStyleDeclaration(parent)
, m_node(0)
, m_variableDependentValueCount(0)
+ , m_strictParsing(!parent || parent->useStrictParsing())
+#ifndef NDEBUG
+ , m_iteratorCount(0)
+#endif
{
+ m_properties.reserveCapacity(numProperties);
for (int i = 0; i < numProperties; ++i) {
ASSERT(properties[i]);
- m_values.append(*properties[i]);
+ m_properties.append(*properties[i]);
if (properties[i]->value()->isVariableDependentValue())
m_variableDependentValueCount++;
}
@@ -73,8 +93,10 @@ CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent, const CS
CSSMutableStyleDeclaration& CSSMutableStyleDeclaration::operator=(const CSSMutableStyleDeclaration& other)
{
+ ASSERT(!m_iteratorCount);
// don't attach it to the same node, just leave the current m_node value
- m_values = other.m_values;
+ m_properties = other.m_properties;
+ m_strictParsing = other.m_strictParsing;
return *this;
}
@@ -194,6 +216,22 @@ String CSSMutableStyleDeclaration::getPropertyValue(int propertyID) const
CSSPropertyWebkitMaskOrigin };
return getLayeredShorthandValue(properties, 6);
}
+ case CSSPropertyWebkitTransformOrigin: {
+ const int properties[2] = { CSSPropertyWebkitTransformOriginX,
+ CSSPropertyWebkitTransformOriginY };
+ return getShorthandValue(properties, 2);
+ }
+ case CSSPropertyWebkitTransition: {
+ const int properties[4] = { CSSPropertyWebkitTransitionProperty, CSSPropertyWebkitTransitionDuration,
+ CSSPropertyWebkitTransitionTimingFunction, CSSPropertyWebkitTransitionDelay };
+ return getLayeredShorthandValue(properties, 4);
+ }
+ case CSSPropertyWebkitAnimation: {
+ const int properties[6] = { CSSPropertyWebkitAnimationName, CSSPropertyWebkitAnimationDuration,
+ CSSPropertyWebkitAnimationTimingFunction, CSSPropertyWebkitAnimationDelay,
+ CSSPropertyWebkitAnimationIterationCount, CSSPropertyWebkitAnimationDirection };
+ return getLayeredShorthandValue(properties, 6);
+ }
#if ENABLE(SVG)
case CSSPropertyMarker: {
RefPtr<CSSValue> value = getPropertyCSSValue(CSSPropertyMarkerStart);
@@ -205,7 +243,7 @@ String CSSMutableStyleDeclaration::getPropertyValue(int propertyID) const
return String();
}
-String CSSMutableStyleDeclaration::get4Values( const int* properties ) const
+String CSSMutableStyleDeclaration::get4Values(const int* properties) const
{
String res;
for (int i = 0; i < 4; ++i) {
@@ -321,212 +359,44 @@ String CSSMutableStyleDeclaration::getCommonValue(const int* properties, int num
PassRefPtr<CSSValue> CSSMutableStyleDeclaration::getPropertyCSSValue(int propertyID) const
{
- DeprecatedValueListConstIterator<CSSProperty> end;
- for (DeprecatedValueListConstIterator<CSSProperty> it = m_values.fromLast(); it != end; --it) {
- if (propertyID == (*it).m_id)
- return (*it).value();
- }
- return 0;
+ const CSSProperty* property = findPropertyWithId(propertyID);
+ return property ? property->value() : 0;
}
-struct PropertyLonghand {
- PropertyLonghand()
- : m_properties(0)
- , m_length(0)
- {
- }
-
- PropertyLonghand(const int* firstProperty, unsigned numProperties)
- : m_properties(firstProperty)
- , m_length(numProperties)
- {
+bool CSSMutableStyleDeclaration::removeShorthandProperty(int propertyID, bool notifyChanged)
+{
+ CSSPropertyLonghand longhand = longhandForProperty(propertyID);
+ if (longhand.length()) {
+ removePropertiesInSet(longhand.properties(), longhand.length(), notifyChanged);
+ return true;
}
-
- const int* properties() const { return m_properties; }
- unsigned length() const { return m_length; }
-
-private:
- const int* m_properties;
- unsigned m_length;
-};
-
-static void initShorthandMap(HashMap<int, PropertyLonghand>& shorthandMap)
-{
- #define SET_SHORTHAND_MAP_ENTRY(map, propID, array) \
- map.set(propID, PropertyLonghand(array, sizeof(array) / sizeof(array[0])))
-
- // FIXME: The 'font' property has "shorthand nature" but is not parsed as a shorthand.
-
- // Do not change the order of the following four shorthands, and keep them together.
- static const int borderProperties[4][3] = {
- { CSSPropertyBorderTopColor, CSSPropertyBorderTopStyle, CSSPropertyBorderTopWidth },
- { CSSPropertyBorderRightColor, CSSPropertyBorderRightStyle, CSSPropertyBorderRightWidth },
- { CSSPropertyBorderBottomColor, CSSPropertyBorderBottomStyle, CSSPropertyBorderBottomWidth },
- { CSSPropertyBorderLeftColor, CSSPropertyBorderLeftStyle, CSSPropertyBorderLeftWidth }
- };
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderTop, borderProperties[0]);
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderRight, borderProperties[1]);
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderBottom, borderProperties[2]);
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderLeft, borderProperties[3]);
-
- shorthandMap.set(CSSPropertyBorder, PropertyLonghand(borderProperties[0], sizeof(borderProperties) / sizeof(borderProperties[0][0])));
-
- static const int borderColorProperties[] = {
- CSSPropertyBorderTopColor,
- CSSPropertyBorderRightColor,
- CSSPropertyBorderBottomColor,
- CSSPropertyBorderLeftColor
- };
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderColor, borderColorProperties);
-
- static const int borderStyleProperties[] = {
- CSSPropertyBorderTopStyle,
- CSSPropertyBorderRightStyle,
- CSSPropertyBorderBottomStyle,
- CSSPropertyBorderLeftStyle
- };
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderStyle, borderStyleProperties);
-
- static const int borderWidthProperties[] = {
- CSSPropertyBorderTopWidth,
- CSSPropertyBorderRightWidth,
- CSSPropertyBorderBottomWidth,
- CSSPropertyBorderLeftWidth
- };
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderWidth, borderWidthProperties);
-
- static const int backgroundPositionProperties[] = { CSSPropertyBackgroundPositionX, CSSPropertyBackgroundPositionY };
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBackgroundPosition, backgroundPositionProperties);
-
- static const int borderSpacingProperties[] = { CSSPropertyWebkitBorderHorizontalSpacing, CSSPropertyWebkitBorderVerticalSpacing };
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderSpacing, borderSpacingProperties);
-
- static const int listStyleProperties[] = {
- CSSPropertyListStyleImage,
- CSSPropertyListStylePosition,
- CSSPropertyListStyleType
- };
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyListStyle, listStyleProperties);
-
- static const int marginProperties[] = {
- CSSPropertyMarginTop,
- CSSPropertyMarginRight,
- CSSPropertyMarginBottom,
- CSSPropertyMarginLeft
- };
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyMargin, marginProperties);
-
- static const int marginCollapseProperties[] = { CSSPropertyWebkitMarginTopCollapse, CSSPropertyWebkitMarginBottomCollapse };
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitMarginCollapse, marginCollapseProperties);
-
- static const int marqueeProperties[] = {
- CSSPropertyWebkitMarqueeDirection,
- CSSPropertyWebkitMarqueeIncrement,
- CSSPropertyWebkitMarqueeRepetition,
- CSSPropertyWebkitMarqueeStyle,
- CSSPropertyWebkitMarqueeSpeed
- };
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitMarquee, marqueeProperties);
-
- static const int outlineProperties[] = {
- CSSPropertyOutlineColor,
- CSSPropertyOutlineOffset,
- CSSPropertyOutlineStyle,
- CSSPropertyOutlineWidth
- };
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyOutline, outlineProperties);
-
- static const int paddingProperties[] = {
- CSSPropertyPaddingTop,
- CSSPropertyPaddingRight,
- CSSPropertyPaddingBottom,
- CSSPropertyPaddingLeft
- };
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyPadding, paddingProperties);
-
- static const int textStrokeProperties[] = { CSSPropertyWebkitTextStrokeColor, CSSPropertyWebkitTextStrokeWidth };
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitTextStroke, textStrokeProperties);
-
- static const int backgroundProperties[] = {
- CSSPropertyBackgroundAttachment,
- CSSPropertyWebkitBackgroundClip,
- CSSPropertyBackgroundColor,
- CSSPropertyBackgroundImage,
- CSSPropertyWebkitBackgroundOrigin,
- CSSPropertyBackgroundPositionX,
- CSSPropertyBackgroundPositionY,
- CSSPropertyBackgroundRepeat,
- };
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBackground, backgroundProperties);
-
- static const int columnsProperties[] = { CSSPropertyWebkitColumnWidth, CSSPropertyWebkitColumnCount };
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitColumns, columnsProperties);
-
- static const int columnRuleProperties[] = {
- CSSPropertyWebkitColumnRuleColor,
- CSSPropertyWebkitColumnRuleStyle,
- CSSPropertyWebkitColumnRuleWidth
- };
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitColumnRule, columnRuleProperties);
-
- static const int overflowProperties[] = { CSSPropertyOverflowX, CSSPropertyOverflowY };
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyOverflow, overflowProperties);
-
- static const int borderRadiusProperties[] = {
- CSSPropertyWebkitBorderTopRightRadius,
- CSSPropertyWebkitBorderTopLeftRadius,
- CSSPropertyWebkitBorderBottomLeftRadius,
- CSSPropertyWebkitBorderBottomRightRadius
- };
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitBorderRadius, borderRadiusProperties);
-
- static const int maskPositionProperties[] = { CSSPropertyWebkitMaskPositionX, CSSPropertyWebkitMaskPositionY };
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitMaskPosition, maskPositionProperties);
-
- static const int maskProperties[] = {
- CSSPropertyWebkitMaskAttachment,
- CSSPropertyWebkitMaskClip,
- CSSPropertyWebkitMaskImage,
- CSSPropertyWebkitMaskOrigin,
- CSSPropertyWebkitMaskPositionX,
- CSSPropertyWebkitMaskPositionY,
- CSSPropertyWebkitMaskRepeat,
- };
- SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyWebkitMask, maskProperties);
-
- #undef SET_SHORTHAND_MAP_ENTRY
+ return false;
}
-String CSSMutableStyleDeclaration::removeProperty(int propertyID, bool notifyChanged, bool returnText, ExceptionCode& ec)
+String CSSMutableStyleDeclaration::removeProperty(int propertyID, bool notifyChanged, bool returnText)
{
- ec = 0;
-
- static HashMap<int, PropertyLonghand> shorthandMap;
- if (shorthandMap.isEmpty())
- initShorthandMap(shorthandMap);
+ ASSERT(!m_iteratorCount);
- PropertyLonghand longhand = shorthandMap.get(propertyID);
- if (longhand.length()) {
- removePropertiesInSet(longhand.properties(), longhand.length(), notifyChanged);
+ if (removeShorthandProperty(propertyID, notifyChanged)) {
// FIXME: Return an equivalent shorthand when possible.
return String();
}
+
+ CSSProperty* foundProperty = findPropertyWithId(propertyID);
+ if (!foundProperty)
+ return String();
+
+ String value = returnText ? foundProperty->value()->cssText() : String();
- String value;
-
- DeprecatedValueListIterator<CSSProperty> end;
- for (DeprecatedValueListIterator<CSSProperty> it = m_values.fromLast(); it != end; --it) {
- if (propertyID == (*it).m_id) {
- if (returnText)
- value = (*it).value()->cssText();
- if ((*it).value()->isVariableDependentValue())
- m_variableDependentValueCount--;
- m_values.remove(it);
- if (notifyChanged)
- setChanged();
- break;
- }
- }
+ if (foundProperty->value()->isVariableDependentValue())
+ m_variableDependentValueCount--;
+
+ // A more efficient removal strategy would involve marking entries as empty
+ // and sweeping them when the vector grows too big.
+ m_properties.remove(foundProperty - m_properties.data());
+
+ if (notifyChanged)
+ setChanged();
return value;
}
@@ -556,53 +426,43 @@ void CSSMutableStyleDeclaration::setChanged()
bool CSSMutableStyleDeclaration::getPropertyPriority(int propertyID) const
{
- DeprecatedValueListConstIterator<CSSProperty> end;
- for (DeprecatedValueListConstIterator<CSSProperty> it = m_values.begin(); it != end; ++it) {
- if (propertyID == (*it).id())
- return (*it).isImportant();
- }
- return false;
+ const CSSProperty* property = findPropertyWithId(propertyID);
+ return property ? property->isImportant() : false;
}
int CSSMutableStyleDeclaration::getPropertyShorthand(int propertyID) const
{
- DeprecatedValueListConstIterator<CSSProperty> end;
- for (DeprecatedValueListConstIterator<CSSProperty> it = m_values.begin(); it != end; ++it) {
- if (propertyID == (*it).id())
- return (*it).shorthandID();
- }
- return false;
+ const CSSProperty* property = findPropertyWithId(propertyID);
+ return property ? property->shorthandID() : 0;
}
bool CSSMutableStyleDeclaration::isPropertyImplicit(int propertyID) const
{
- DeprecatedValueListConstIterator<CSSProperty> end;
- for (DeprecatedValueListConstIterator<CSSProperty> it = m_values.begin(); it != end; ++it) {
- if (propertyID == (*it).id())
- return (*it).isImplicit();
- }
- return false;
+ const CSSProperty* property = findPropertyWithId(propertyID);
+ return property ? property->isImplicit() : false;
}
void CSSMutableStyleDeclaration::setProperty(int propertyID, const String& value, bool important, ExceptionCode& ec)
{
- setProperty(propertyID, value, important, true, ec);
+ ec = 0;
+ setProperty(propertyID, value, important, true);
}
String CSSMutableStyleDeclaration::removeProperty(int propertyID, ExceptionCode& ec)
{
- return removeProperty(propertyID, true, true, ec);
+ ec = 0;
+ return removeProperty(propertyID, true, true);
}
-bool CSSMutableStyleDeclaration::setProperty(int propertyID, const String& value, bool important, bool notifyChanged, ExceptionCode& ec)
+bool CSSMutableStyleDeclaration::setProperty(int propertyID, const String& value, bool important, bool notifyChanged)
{
- ec = 0;
+ ASSERT(!m_iteratorCount);
// Setting the value to an empty string just removes the property in both IE and Gecko.
// Setting it to null seems to produce less consistent results, but we treat it just the same.
if (value.isEmpty()) {
- removeProperty(propertyID, notifyChanged, false, ec);
- return ec == 0;
+ removeProperty(propertyID, notifyChanged, false);
+ return true;
}
// When replacing an existing property value, this moves the property to the end of the list.
@@ -614,14 +474,28 @@ bool CSSMutableStyleDeclaration::setProperty(int propertyID, const String& value
// see <http://bugs.webkit.org/show_bug.cgi?id=7296>.
} else if (notifyChanged)
setChanged();
- ASSERT(!ec);
+
return success;
}
+
+void CSSMutableStyleDeclaration::setPropertyInternal(const CSSProperty& property, CSSProperty* slot)
+{
+ ASSERT(!m_iteratorCount);
+
+ if (!removeShorthandProperty(property.id(), false)) {
+ CSSProperty* toReplace = slot ? slot : findPropertyWithId(property.id());
+ if (toReplace) {
+ *toReplace = property;
+ return;
+ }
+ }
+ m_properties.append(property);
+}
bool CSSMutableStyleDeclaration::setProperty(int propertyID, int value, bool important, bool notifyChanged)
{
- removeProperty(propertyID);
- m_values.append(CSSProperty(propertyID, CSSPrimitiveValue::createIdentifier(value), important));
+ CSSProperty property(propertyID, CSSPrimitiveValue::createIdentifier(value), important);
+ setPropertyInternal(property);
if (notifyChanged)
setChanged();
return true;
@@ -629,21 +503,25 @@ bool CSSMutableStyleDeclaration::setProperty(int propertyID, int value, bool imp
void CSSMutableStyleDeclaration::setStringProperty(int propertyId, const String &value, CSSPrimitiveValue::UnitTypes type, bool important)
{
- removeProperty(propertyId);
- m_values.append(CSSProperty(propertyId, CSSPrimitiveValue::create(value, type), important));
+ ASSERT(!m_iteratorCount);
+
+ setPropertyInternal(CSSProperty(propertyId, CSSPrimitiveValue::create(value, type), important));
setChanged();
}
void CSSMutableStyleDeclaration::setImageProperty(int propertyId, const String& url, bool important)
{
- removeProperty(propertyId);
- m_values.append(CSSProperty(propertyId, CSSImageValue::create(url), important));
+ ASSERT(!m_iteratorCount);
+
+ setPropertyInternal(CSSProperty(propertyId, CSSImageValue::create(url), important));
setChanged();
}
void CSSMutableStyleDeclaration::parseDeclaration(const String& styleDeclaration)
{
- m_values.clear();
+ ASSERT(!m_iteratorCount);
+
+ m_properties.clear();
CSSParser parser(useStrictParsing());
parser.parseDeclaration(this, styleDeclaration);
setChanged();
@@ -651,12 +529,16 @@ void CSSMutableStyleDeclaration::parseDeclaration(const String& styleDeclaration
void CSSMutableStyleDeclaration::addParsedProperties(const CSSProperty* const* properties, int numProperties)
{
+ ASSERT(!m_iteratorCount);
+
+ m_properties.reserveCapacity(numProperties);
+
for (int i = 0; i < numProperties; ++i) {
// Only add properties that have no !important counterpart present
if (!getPropertyPriority(properties[i]->id()) || properties[i]->isImportant()) {
removeProperty(properties[i]->id(), false);
ASSERT(properties[i]);
- m_values.append(*properties[i]);
+ m_properties.append(*properties[i]);
if (properties[i]->value()->isVariableDependentValue())
m_variableDependentValueCount++;
}
@@ -667,12 +549,15 @@ void CSSMutableStyleDeclaration::addParsedProperties(const CSSProperty* const* p
void CSSMutableStyleDeclaration::addParsedProperty(const CSSProperty& property)
{
- removeProperty(property.id(), false);
- m_values.append(property);
+ ASSERT(!m_iteratorCount);
+
+ setPropertyInternal(property);
}
void CSSMutableStyleDeclaration::setLengthProperty(int propertyId, const String& value, bool important, bool /*multiLength*/)
{
+ ASSERT(!m_iteratorCount);
+
bool parseMode = useStrictParsing();
setStrictParsing(false);
setProperty(propertyId, value, important);
@@ -681,14 +566,14 @@ void CSSMutableStyleDeclaration::setLengthProperty(int propertyId, const String&
unsigned CSSMutableStyleDeclaration::length() const
{
- return m_values.count();
+ return m_properties.size();
}
String CSSMutableStyleDeclaration::item(unsigned i) const
{
- if (i >= m_values.count())
+ if (i >= m_properties.size())
return String();
- return getPropertyName(static_cast<CSSPropertyID>(m_values[i].id()));
+ return getPropertyName(static_cast<CSSPropertyID>(m_properties[i].id()));
}
String CSSMutableStyleDeclaration::cssText() const
@@ -697,10 +582,10 @@ String CSSMutableStyleDeclaration::cssText() const
const CSSProperty* positionXProp = 0;
const CSSProperty* positionYProp = 0;
-
- DeprecatedValueListConstIterator<CSSProperty> end;
- for (DeprecatedValueListConstIterator<CSSProperty> it = m_values.begin(); it != end; ++it) {
- const CSSProperty& prop = *it;
+
+ unsigned size = m_properties.size();
+ for (unsigned n = 0; n < size; ++n) {
+ const CSSProperty& prop = m_properties[n];
if (prop.id() == CSSPropertyBackgroundPositionX)
positionXProp = &prop;
else if (prop.id() == CSSPropertyBackgroundPositionY)
@@ -733,8 +618,10 @@ String CSSMutableStyleDeclaration::cssText() const
void CSSMutableStyleDeclaration::setCssText(const String& text, ExceptionCode& ec)
{
+ ASSERT(!m_iteratorCount);
+
ec = 0;
- m_values.clear();
+ m_properties.clear();
CSSParser parser(useStrictParsing());
parser.parseDeclaration(this, text);
// FIXME: Detect syntax errors and set ec.
@@ -743,21 +630,31 @@ void CSSMutableStyleDeclaration::setCssText(const String& text, ExceptionCode& e
void CSSMutableStyleDeclaration::merge(CSSMutableStyleDeclaration* other, bool argOverridesOnConflict)
{
- DeprecatedValueListConstIterator<CSSProperty> end;
- for (DeprecatedValueListConstIterator<CSSProperty> it = other->valuesIterator(); it != end; ++it) {
- const CSSProperty& property = *it;
- RefPtr<CSSValue> value = getPropertyCSSValue(property.id());
- if (value) {
- if (!argOverridesOnConflict)
+ ASSERT(!m_iteratorCount);
+
+ unsigned size = other->m_properties.size();
+ for (unsigned n = 0; n < size; ++n) {
+ CSSProperty& toMerge = other->m_properties[n];
+ CSSProperty* old = findPropertyWithId(toMerge.id());
+ if (old) {
+ if (!argOverridesOnConflict && old->value())
continue;
- removeProperty(property.id());
- }
- m_values.append(property);
+ setPropertyInternal(toMerge, old);
+ } else
+ m_properties.append(toMerge);
}
// FIXME: This probably should have a call to setChanged() if something changed. We may also wish to add
// a notifyChanged argument to this function to follow the model of other functions in this class.
}
+void CSSMutableStyleDeclaration::addSubresourceStyleURLs(ListHashSet<KURL>& urls)
+{
+ CSSStyleSheet* sheet = static_cast<CSSStyleSheet*>(stylesheet());
+ size_t size = m_properties.size();
+ for (size_t i = 0; i < size; ++i)
+ m_properties[i].value()->addSubresourceStyleURLs(urls, sheet);
+}
+
// This is the list of properties we want to copy in the copyBlockProperties() function.
// It is the list of CSS properties that apply specially to block-level elements.
static const int blockProperties[] = {
@@ -794,14 +691,33 @@ void CSSMutableStyleDeclaration::removeBlockProperties()
void CSSMutableStyleDeclaration::removePropertiesInSet(const int* set, unsigned length, bool notifyChanged)
{
- bool changed = false;
- for (unsigned i = 0; i < length; i++) {
- RefPtr<CSSValue> value = getPropertyCSSValue(set[i]);
- if (value) {
- m_values.remove(CSSProperty(set[i], value.release(), false));
- changed = true;
+ ASSERT(!m_iteratorCount);
+
+ if (m_properties.isEmpty())
+ return;
+
+ // FIXME: This is always used with static sets and in that case constructing the hash repeatedly is pretty pointless.
+ HashSet<int> toRemove;
+ for (unsigned i = 0; i < length; ++i)
+ toRemove.add(set[i]);
+
+ Vector<CSSProperty> newProperties;
+ newProperties.reserveCapacity(m_properties.size());
+
+ unsigned size = m_properties.size();
+ for (unsigned n = 0; n < size; ++n) {
+ const CSSProperty& property = m_properties[n];
+ // Not quite sure if the isImportant test is needed but it matches the existing behavior.
+ if (!property.isImportant()) {
+ if (toRemove.contains(property.id()))
+ continue;
}
+ newProperties.append(property);
}
+
+ bool changed = newProperties.size() != m_properties.size();
+ m_properties = newProperties;
+
if (changed && notifyChanged)
setChanged();
}
@@ -813,7 +729,25 @@ PassRefPtr<CSSMutableStyleDeclaration> CSSMutableStyleDeclaration::makeMutable()
PassRefPtr<CSSMutableStyleDeclaration> CSSMutableStyleDeclaration::copy() const
{
- return adoptRef(new CSSMutableStyleDeclaration(0, m_values, m_variableDependentValueCount));
+ return adoptRef(new CSSMutableStyleDeclaration(0, m_properties, m_variableDependentValueCount));
+}
+
+const CSSProperty* CSSMutableStyleDeclaration::findPropertyWithId(int propertyID) const
+{
+ for (int n = m_properties.size() - 1 ; n >= 0; --n) {
+ if (propertyID == m_properties[n].m_id)
+ return &m_properties[n];
+ }
+ return 0;
+}
+
+CSSProperty* CSSMutableStyleDeclaration::findPropertyWithId(int propertyID)
+{
+ for (int n = m_properties.size() - 1 ; n >= 0; --n) {
+ if (propertyID == m_properties[n].m_id)
+ return &m_properties[n];
+ }
+ return 0;
}
} // namespace WebCore