summaryrefslogtreecommitdiff
path: root/Source/WebCore/css/StyleProperties.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/css/StyleProperties.cpp')
-rw-r--r--Source/WebCore/css/StyleProperties.cpp814
1 files changed, 465 insertions, 349 deletions
diff --git a/Source/WebCore/css/StyleProperties.cpp b/Source/WebCore/css/StyleProperties.cpp
index bb3570f73..ea1f9f109 100644
--- a/Source/WebCore/css/StyleProperties.cpp
+++ b/Source/WebCore/css/StyleProperties.cpp
@@ -24,13 +24,17 @@
#include "StyleProperties.h"
#include "CSSComputedStyleDeclaration.h"
+#include "CSSCustomPropertyValue.h"
+#include "CSSDeferredParser.h"
#include "CSSParser.h"
+#include "CSSPendingSubstitutionValue.h"
#include "CSSValueKeywords.h"
#include "CSSValueList.h"
#include "CSSValuePool.h"
#include "Document.h"
#include "PropertySetCSSStyleDeclaration.h"
#include "StylePropertyShorthand.h"
+#include "StylePropertyShorthandFunctions.h"
#include "StyleSheetContents.h"
#include <bitset>
#include <wtf/text/StringBuilder.h>
@@ -50,32 +54,30 @@ static size_t sizeForImmutableStylePropertiesWithPropertyCount(unsigned count)
static bool isInitialOrInherit(const String& value)
{
- DEFINE_STATIC_LOCAL(String, initial, ("initial"));
- DEFINE_STATIC_LOCAL(String, inherit, ("inherit"));
- return value.length() == 7 && (value == initial || value == inherit);
+ return value.length() == 7 && (value == "initial" || value == "inherit");
}
-PassRef<ImmutableStyleProperties> ImmutableStyleProperties::create(const CSSProperty* properties, unsigned count, CSSParserMode cssParserMode)
+Ref<ImmutableStyleProperties> ImmutableStyleProperties::create(const CSSProperty* properties, unsigned count, CSSParserMode cssParserMode)
{
void* slot = WTF::fastMalloc(sizeForImmutableStylePropertiesWithPropertyCount(count));
return adoptRef(*new (NotNull, slot) ImmutableStyleProperties(properties, count, cssParserMode));
}
-PassRef<ImmutableStyleProperties> StyleProperties::immutableCopyIfNeeded() const
+Ref<ImmutableStyleProperties> StyleProperties::immutableCopyIfNeeded() const
{
- if (!isMutable())
- return static_cast<ImmutableStyleProperties&>(const_cast<StyleProperties&>(*this));
- const MutableStyleProperties& mutableThis = static_cast<const MutableStyleProperties&>(*this);
+ if (is<ImmutableStyleProperties>(*this))
+ return downcast<ImmutableStyleProperties>(const_cast<StyleProperties&>(*this));
+ const MutableStyleProperties& mutableThis = downcast<MutableStyleProperties>(*this);
return ImmutableStyleProperties::create(mutableThis.m_propertyVector.data(), mutableThis.m_propertyVector.size(), cssParserMode());
}
MutableStyleProperties::MutableStyleProperties(CSSParserMode cssParserMode)
- : StyleProperties(cssParserMode)
+ : StyleProperties(cssParserMode, MutablePropertiesType)
{
}
MutableStyleProperties::MutableStyleProperties(const CSSProperty* properties, unsigned length)
- : StyleProperties(CSSStrictMode)
+ : StyleProperties(HTMLStandardMode, MutablePropertiesType)
{
m_propertyVector.reserveInitialCapacity(length);
for (unsigned i = 0; i < length; ++i)
@@ -106,14 +108,17 @@ ImmutableStyleProperties::~ImmutableStyleProperties()
}
MutableStyleProperties::MutableStyleProperties(const StyleProperties& other)
- : StyleProperties(other.cssParserMode())
+ : StyleProperties(other.cssParserMode(), MutablePropertiesType)
{
- if (other.isMutable())
- m_propertyVector = static_cast<const MutableStyleProperties&>(other).m_propertyVector;
+ ASSERT(other.type() != DeferredPropertiesType);
+ if (is<MutableStyleProperties>(other))
+ m_propertyVector = downcast<MutableStyleProperties>(other).m_propertyVector;
else {
- m_propertyVector.reserveInitialCapacity(other.propertyCount());
- for (unsigned i = 0; i < other.propertyCount(); ++i)
- m_propertyVector.uncheckedAppend(other.propertyAt(i).toCSSProperty());
+ const auto& immutableOther = downcast<ImmutableStyleProperties>(other);
+ unsigned propertyCount = immutableOther.propertyCount();
+ m_propertyVector.reserveInitialCapacity(propertyCount);
+ for (unsigned i = 0; i < propertyCount; ++i)
+ m_propertyVector.uncheckedAppend(immutableOther.propertyAt(i).toCSSProperty());
}
}
@@ -123,8 +128,21 @@ String StyleProperties::getPropertyValue(CSSPropertyID propertyID) const
if (value)
return value->cssText();
+ const StylePropertyShorthand& shorthand = shorthandForProperty(propertyID);
+ if (shorthand.length()) {
+ RefPtr<CSSValue> value = getPropertyCSSValueInternal(shorthand.properties()[0]);
+ if (!value)
+ return String();
+ if (value->isPendingSubstitutionValue())
+ return downcast<CSSPendingSubstitutionValue>(*value).shorthandValue()->cssText();
+ }
+
// Shorthand and 4-values properties
switch (propertyID) {
+ case CSSPropertyAll:
+ return getCommonValue(allShorthand());
+ case CSSPropertyAnimation:
+ return getLayeredShorthandValue(animationShorthand());
case CSSPropertyBorderSpacing:
return borderSpacingValue(borderSpacingShorthand());
case CSSPropertyBackgroundPosition:
@@ -151,20 +169,24 @@ String StyleProperties::getPropertyValue(CSSPropertyID propertyID) const
return get4Values(borderWidthShorthand());
case CSSPropertyBorderStyle:
return get4Values(borderStyleShorthand());
- case CSSPropertyWebkitColumnRule:
- return getShorthandValue(webkitColumnRuleShorthand());
- case CSSPropertyWebkitColumns:
- return getShorthandValue(webkitColumnsShorthand());
- case CSSPropertyWebkitFlex:
- return getShorthandValue(webkitFlexShorthand());
- case CSSPropertyWebkitFlexFlow:
- return getShorthandValue(webkitFlexFlowShorthand());
- case CSSPropertyWebkitGridArea:
- return getShorthandValue(webkitGridAreaShorthand());
- case CSSPropertyWebkitGridColumn:
- return getShorthandValue(webkitGridColumnShorthand());
- case CSSPropertyWebkitGridRow:
- return getShorthandValue(webkitGridRowShorthand());
+ case CSSPropertyColumnRule:
+ return getShorthandValue(columnRuleShorthand());
+ case CSSPropertyColumns:
+ return getShorthandValue(columnsShorthand());
+ case CSSPropertyFlex:
+ return getShorthandValue(flexShorthand());
+ case CSSPropertyFlexFlow:
+ return getShorthandValue(flexFlowShorthand());
+ case CSSPropertyGridArea:
+ return getShorthandValue(gridAreaShorthand());
+ case CSSPropertyGridTemplate:
+ return getShorthandValue(gridTemplateShorthand());
+ case CSSPropertyGrid:
+ return getShorthandValue(gridShorthand());
+ case CSSPropertyGridColumn:
+ return getShorthandValue(gridColumnShorthand());
+ case CSSPropertyGridRow:
+ return getShorthandValue(gridRowShorthand());
case CSSPropertyFont:
return fontValue();
case CSSPropertyMargin:
@@ -191,31 +213,41 @@ String StyleProperties::getPropertyValue(CSSPropertyID propertyID) const
return getShorthandValue(webkitTextEmphasisShorthand());
case CSSPropertyWebkitTextStroke:
return getShorthandValue(webkitTextStrokeShorthand());
- case CSSPropertyWebkitTransformOrigin:
- return getShorthandValue(webkitTransformOriginShorthand());
- case CSSPropertyWebkitTransition:
- return getLayeredShorthandValue(webkitTransitionShorthand());
- case CSSPropertyWebkitAnimation:
- return getLayeredShorthandValue(webkitAnimationShorthand());
-#if ENABLE(SVG)
+ case CSSPropertyPerspectiveOrigin:
+ return getShorthandValue(perspectiveOriginShorthand());
+ case CSSPropertyTransformOrigin:
+ return getShorthandValue(transformOriginShorthand());
case CSSPropertyMarker: {
- RefPtr<CSSValue> value = getPropertyCSSValue(CSSPropertyMarkerStart);
+ RefPtr<CSSValue> value = getPropertyCSSValueInternal(CSSPropertyMarkerStart);
if (value)
return value->cssText();
return String();
}
-#endif
case CSSPropertyBorderRadius:
return get4Values(borderRadiusShorthand());
+#if ENABLE(CSS_SCROLL_SNAP)
+ case CSSPropertyScrollSnapMargin:
+ return get4Values(scrollSnapMarginShorthand());
+ case CSSPropertyScrollPadding:
+ return get4Values(scrollPaddingShorthand());
+#endif
default:
return String();
}
}
+String StyleProperties::getCustomPropertyValue(const String& propertyName) const
+{
+ RefPtr<CSSValue> value = getCustomPropertyCSSValue(propertyName);
+ if (value)
+ return value->cssText();
+ return String();
+}
+
String StyleProperties::borderSpacingValue(const StylePropertyShorthand& shorthand) const
{
- RefPtr<CSSValue> horizontalValue = getPropertyCSSValue(shorthand.properties()[0]);
- RefPtr<CSSValue> verticalValue = getPropertyCSSValue(shorthand.properties()[1]);
+ RefPtr<CSSValue> horizontalValue = getPropertyCSSValueInternal(shorthand.properties()[0]);
+ RefPtr<CSSValue> verticalValue = getPropertyCSSValueInternal(shorthand.properties()[1]);
// While standard border-spacing property does not allow specifying border-spacing-vertical without
// specifying border-spacing-horizontal <http://www.w3.org/TR/CSS21/tables.html#separated-borders>,
@@ -246,7 +278,7 @@ void StyleProperties::appendFontLonghandValueIfExplicit(CSSPropertyID propertyID
case CSSPropertyFontStyle:
break; // No prefix.
case CSSPropertyFontFamily:
- case CSSPropertyFontVariant:
+ case CSSPropertyFontVariantCaps:
case CSSPropertyFontWeight:
prefix = ' ';
break;
@@ -280,7 +312,7 @@ String StyleProperties::fontValue() const
String commonValue = fontSizeProperty.value()->cssText();
StringBuilder result;
appendFontLonghandValueIfExplicit(CSSPropertyFontStyle, result, commonValue);
- appendFontLonghandValueIfExplicit(CSSPropertyFontVariant, result, commonValue);
+ appendFontLonghandValueIfExplicit(CSSPropertyFontVariantCaps, result, commonValue);
appendFontLonghandValueIfExplicit(CSSPropertyFontWeight, result, commonValue);
if (!result.isEmpty())
result.append(' ');
@@ -358,13 +390,17 @@ String StyleProperties::getLayeredShorthandValue(const StylePropertyShorthand& s
size_t numLayers = 0;
for (unsigned i = 0; i < size; ++i) {
- values[i] = getPropertyCSSValue(shorthand.properties()[i]);
- if (values[i]) {
- if (values[i]->isBaseValueList())
- numLayers = std::max(toCSSValueList(values[i].get())->length(), numLayers);
- else
- numLayers = std::max<size_t>(1U, numLayers);
+ values[i] = getPropertyCSSValueInternal(shorthand.properties()[i]);
+ if (!values[i]) {
+ // We don't have all longhand properties defined as required for the shorthand
+ // property and thus should not serialize to a shorthand value. See spec at
+ // http://www.w3.org/TR/cssom-1/#serialize-a-css-declaration-block.
+ return String();
}
+ if (values[i]->isBaseValueList())
+ numLayers = std::max(downcast<CSSValueList>(*values[i]).length(), numLayers);
+ else
+ numLayers = std::max<size_t>(1U, numLayers);
}
String commonValue;
@@ -382,16 +418,16 @@ String StyleProperties::getLayeredShorthandValue(const StylePropertyShorthand& s
RefPtr<CSSValue> value;
if (values[j]) {
if (values[j]->isBaseValueList())
- value = toCSSValueList(values[j].get())->item(i);
+ value = downcast<CSSValueList>(*values[j]).item(i);
else {
value = values[j];
// Color only belongs in the last layer.
if (shorthand.properties()[j] == CSSPropertyBackgroundColor) {
if (i != numLayers - 1)
- value = 0;
+ value = nullptr;
} else if (i) // Other singletons only belong in the first layer.
- value = 0;
+ value = nullptr;
}
}
@@ -406,27 +442,29 @@ String StyleProperties::getLayeredShorthandValue(const StylePropertyShorthand& s
|| (j < size - 1 && shorthand.properties()[j + 1] == CSSPropertyWebkitMaskRepeatY && value)) {
RefPtr<CSSValue> yValue;
RefPtr<CSSValue> nextValue = values[j + 1];
- if (nextValue->isValueList())
- yValue = toCSSValueList(nextValue.get())->itemWithoutBoundsCheck(i);
- else
- yValue = nextValue;
+ if (nextValue) {
+ if (is<CSSValueList>(*nextValue))
+ yValue = downcast<CSSValueList>(*nextValue).itemWithoutBoundsCheck(i);
+ else
+ yValue = nextValue;
- if (!value->isPrimitiveValue() || !yValue->isPrimitiveValue())
- continue;
+ if (!is<CSSPrimitiveValue>(*value) || !is<CSSPrimitiveValue>(*yValue))
+ continue;
- CSSValueID xId = toCSSPrimitiveValue(value.get())->getValueID();
- CSSValueID yId = toCSSPrimitiveValue(yValue.get())->getValueID();
- if (xId != yId) {
- if (xId == CSSValueRepeat && yId == CSSValueNoRepeat) {
- useRepeatXShorthand = true;
+ CSSValueID xId = downcast<CSSPrimitiveValue>(*value).valueID();
+ CSSValueID yId = downcast<CSSPrimitiveValue>(*yValue).valueID();
+ if (xId != yId) {
+ if (xId == CSSValueRepeat && yId == CSSValueNoRepeat) {
+ useRepeatXShorthand = true;
+ ++j;
+ } else if (xId == CSSValueNoRepeat && yId == CSSValueRepeat) {
+ useRepeatYShorthand = true;
+ continue;
+ }
+ } else {
+ useSingleWordShorthand = true;
++j;
- } else if (xId == CSSValueNoRepeat && yId == CSSValueRepeat) {
- useRepeatYShorthand = true;
- continue;
}
- } else {
- useSingleWordShorthand = true;
- ++j;
}
}
}
@@ -494,7 +532,7 @@ String StyleProperties::getShorthandValue(const StylePropertyShorthand& shorthan
StringBuilder result;
for (unsigned i = 0; i < shorthand.length(); ++i) {
if (!isPropertyImplicit(shorthand.properties()[i])) {
- RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i]);
+ RefPtr<CSSValue> value = getPropertyCSSValueInternal(shorthand.properties()[i]);
if (!value)
return String();
String valueText = value->cssText();
@@ -523,10 +561,10 @@ String StyleProperties::getCommonValue(const StylePropertyShorthand& shorthand)
String res;
bool lastPropertyWasImportant = false;
for (unsigned i = 0; i < shorthand.length(); ++i) {
- RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i]);
- // FIXME: CSSInitialValue::cssText should generate the right value.
+ RefPtr<CSSValue> value = getPropertyCSSValueInternal(shorthand.properties()[i]);
if (!value)
return String();
+ // FIXME: CSSInitialValue::cssText should generate the right value.
String text = value->cssText();
if (text.isNull())
return String();
@@ -571,11 +609,24 @@ String StyleProperties::borderPropertyValue(CommonValueMode valueMode) const
return result.isEmpty() ? String() : result.toString();
}
-PassRefPtr<CSSValue> StyleProperties::getPropertyCSSValue(CSSPropertyID propertyID) const
+RefPtr<CSSValue> StyleProperties::getPropertyCSSValue(CSSPropertyID propertyID) const
+{
+ return getPropertyCSSValueInternal(propertyID);
+}
+
+RefPtr<CSSValue> StyleProperties::getPropertyCSSValueInternal(CSSPropertyID propertyID) const
{
int foundPropertyIndex = findPropertyIndex(propertyID);
if (foundPropertyIndex == -1)
- return 0;
+ return nullptr;
+ return propertyAt(foundPropertyIndex).value();
+}
+
+RefPtr<CSSValue> StyleProperties::getCustomPropertyCSSValue(const String& propertyName) const
+{
+ int foundPropertyIndex = findCustomPropertyIndex(propertyName);
+ if (foundPropertyIndex == -1)
+ return nullptr;
return propertyAt(foundPropertyIndex).value();
}
@@ -585,14 +636,7 @@ bool MutableStyleProperties::removeShorthandProperty(CSSPropertyID propertyID)
if (!shorthand.length())
return false;
- bool ret = removePropertiesInSet(shorthand.properties(), shorthand.length());
-
- CSSPropertyID prefixingVariant = prefixingVariantForPropertyId(propertyID);
- if (prefixingVariant == propertyID)
- return ret;
-
- StylePropertyShorthand shorthandPrefixingVariant = shorthandForProperty(prefixingVariant);
- return removePropertiesInSet(shorthandPrefixingVariant.properties(), shorthandPrefixingVariant.length());
+ return removePropertiesInSet(shorthand.properties(), shorthand.length());
}
bool MutableStyleProperties::removeProperty(CSSPropertyID propertyID, String* returnText)
@@ -600,14 +644,14 @@ bool MutableStyleProperties::removeProperty(CSSPropertyID propertyID, String* re
if (removeShorthandProperty(propertyID)) {
// FIXME: Return an equivalent shorthand when possible.
if (returnText)
- *returnText = "";
+ *returnText = emptyString();
return true;
}
int foundPropertyIndex = findPropertyIndex(propertyID);
if (foundPropertyIndex == -1) {
if (returnText)
- *returnText = "";
+ *returnText = emptyString();
return false;
}
@@ -618,17 +662,26 @@ bool MutableStyleProperties::removeProperty(CSSPropertyID propertyID, String* re
// and sweeping them when the vector grows too big.
m_propertyVector.remove(foundPropertyIndex);
- removePrefixedOrUnprefixedProperty(propertyID);
-
return true;
}
-void MutableStyleProperties::removePrefixedOrUnprefixedProperty(CSSPropertyID propertyID)
+bool MutableStyleProperties::removeCustomProperty(const String& propertyName, String* returnText)
{
- int foundPropertyIndex = findPropertyIndex(prefixingVariantForPropertyId(propertyID));
- if (foundPropertyIndex == -1)
- return;
+ int foundPropertyIndex = findCustomPropertyIndex(propertyName);
+ if (foundPropertyIndex == -1) {
+ if (returnText)
+ *returnText = emptyString();
+ return false;
+ }
+
+ if (returnText)
+ *returnText = propertyAt(foundPropertyIndex).value()->cssText();
+
+ // A more efficient removal strategy would involve marking entries as empty
+ // and sweeping them when the vector grows too big.
m_propertyVector.remove(foundPropertyIndex);
+
+ return true;
}
bool StyleProperties::propertyIsImportant(CSSPropertyID propertyID) const
@@ -648,6 +701,14 @@ bool StyleProperties::propertyIsImportant(CSSPropertyID propertyID) const
return true;
}
+bool StyleProperties::customPropertyIsImportant(const String& propertyName) const
+{
+ int foundPropertyIndex = findCustomPropertyIndex(propertyName);
+ if (foundPropertyIndex != -1)
+ return propertyAt(foundPropertyIndex).isImportant();
+ return false;
+}
+
String StyleProperties::getPropertyShorthand(CSSPropertyID propertyID) const
{
int foundPropertyIndex = findPropertyIndex(propertyID);
@@ -664,110 +725,122 @@ bool StyleProperties::isPropertyImplicit(CSSPropertyID propertyID) const
return propertyAt(foundPropertyIndex).isImplicit();
}
-bool MutableStyleProperties::setProperty(CSSPropertyID propertyID, const String& value, bool important, StyleSheetContents* contextStyleSheet)
+bool MutableStyleProperties::setProperty(CSSPropertyID propertyID, const String& value, bool important, CSSParserContext parserContext)
{
// 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())
return removeProperty(propertyID);
+ parserContext.mode = cssParserMode();
+
// When replacing an existing property value, this moves the property to the end of the list.
// Firefox preserves the position, and MSIE moves the property to the beginning.
- return CSSParser::parseValue(this, propertyID, value, important, cssParserMode(), contextStyleSheet);
+ return CSSParser::parseValue(*this, propertyID, value, important, parserContext) == CSSParser::ParseResult::Changed;
}
-void MutableStyleProperties::setProperty(CSSPropertyID propertyID, PassRefPtr<CSSValue> prpValue, bool important)
+bool MutableStyleProperties::setProperty(CSSPropertyID propertyID, const String& value, bool important)
+{
+ CSSParserContext parserContext(cssParserMode());
+ return setProperty(propertyID, value, important, parserContext);
+}
+
+bool MutableStyleProperties::setCustomProperty(const String& propertyName, const String& value, bool important, CSSParserContext parserContext)
+{
+ // 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())
+ return removeCustomProperty(propertyName);
+
+ parserContext.mode = cssParserMode();
+ // When replacing an existing property value, this moves the property to the end of the list.
+ // Firefox preserves the position, and MSIE moves the property to the beginning.
+ return CSSParser::parseCustomPropertyValue(*this, propertyName, value, important, parserContext) == CSSParser::ParseResult::Changed;
+}
+
+void MutableStyleProperties::setProperty(CSSPropertyID propertyID, RefPtr<CSSValue>&& value, bool important)
{
StylePropertyShorthand shorthand = shorthandForProperty(propertyID);
if (!shorthand.length()) {
- setProperty(CSSProperty(propertyID, prpValue, important));
+ setProperty(CSSProperty(propertyID, WTFMove(value), important));
return;
}
removePropertiesInSet(shorthand.properties(), shorthand.length());
- RefPtr<CSSValue> value = prpValue;
for (unsigned i = 0; i < shorthand.length(); ++i)
- m_propertyVector.append(CSSProperty(shorthand.properties()[i], value, important));
+ m_propertyVector.append(CSSProperty(shorthand.properties()[i], value.copyRef(), important));
}
-void MutableStyleProperties::setProperty(const CSSProperty& property, CSSProperty* slot)
+bool MutableStyleProperties::setProperty(const CSSProperty& property, CSSProperty* slot)
{
if (!removeShorthandProperty(property.id())) {
- CSSProperty* toReplace = slot ? slot : findCSSPropertyWithID(property.id());
+ CSSProperty* toReplace = slot;
+ if (!slot) {
+ if (property.id() == CSSPropertyCustom) {
+ if (property.value())
+ toReplace = findCustomCSSPropertyWithName(downcast<CSSCustomPropertyValue>(*property.value()).name());
+ } else
+ toReplace = findCSSPropertyWithID(property.id());
+ }
+
if (toReplace) {
+ if (*toReplace == property)
+ return false;
+
*toReplace = property;
- setPrefixingVariantProperty(property);
- return;
+ return true;
}
}
- appendPrefixingVariantProperty(property);
-}
-
-static unsigned getIndexInShorthandVectorForPrefixingVariant(const CSSProperty& property, CSSPropertyID prefixingVariant)
-{
- if (!property.isSetFromShorthand())
- return 0;
- CSSPropertyID prefixedShorthand = prefixingVariantForPropertyId(property.shorthandID());
- return indexOfShorthandForLonghand(prefixedShorthand, matchingShorthandsForLonghand(prefixingVariant));
-}
-
-void MutableStyleProperties::appendPrefixingVariantProperty(const CSSProperty& property)
-{
m_propertyVector.append(property);
- CSSPropertyID prefixingVariant = prefixingVariantForPropertyId(property.id());
- if (prefixingVariant == property.id())
- return;
-
- m_propertyVector.append(CSSProperty(prefixingVariant, property.value(), property.isImportant(), property.isSetFromShorthand(), getIndexInShorthandVectorForPrefixingVariant(property, prefixingVariant), property.metadata().m_implicit));
-}
-
-void MutableStyleProperties::setPrefixingVariantProperty(const CSSProperty& property)
-{
- CSSPropertyID prefixingVariant = prefixingVariantForPropertyId(property.id());
- CSSProperty* toReplace = findCSSPropertyWithID(prefixingVariant);
- if (toReplace && prefixingVariant != property.id())
- *toReplace = CSSProperty(prefixingVariant, property.value(), property.isImportant(), property.isSetFromShorthand(), getIndexInShorthandVectorForPrefixingVariant(property, prefixingVariant), property.metadata().m_implicit);
+ return true;
}
bool MutableStyleProperties::setProperty(CSSPropertyID propertyID, CSSValueID identifier, bool important)
{
- setProperty(CSSProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important));
- return true;
+ return setProperty(CSSProperty(propertyID, CSSValuePool::singleton().createIdentifierValue(identifier), important));
}
bool MutableStyleProperties::setProperty(CSSPropertyID propertyID, CSSPropertyID identifier, bool important)
{
- setProperty(CSSProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important));
- return true;
+ return setProperty(CSSProperty(propertyID, CSSValuePool::singleton().createIdentifierValue(identifier), important));
}
-void MutableStyleProperties::parseDeclaration(const String& styleDeclaration, StyleSheetContents* contextStyleSheet)
+bool MutableStyleProperties::parseDeclaration(const String& styleDeclaration, CSSParserContext context)
{
+ auto oldProperties = WTFMove(m_propertyVector);
m_propertyVector.clear();
- CSSParserContext context(cssParserMode());
- if (contextStyleSheet) {
- context = contextStyleSheet->parserContext();
- context.mode = cssParserMode();
- }
+ context.mode = cssParserMode();
+
CSSParser parser(context);
- parser.parseDeclaration(this, styleDeclaration, 0, contextStyleSheet);
+ parser.parseDeclaration(*this, styleDeclaration);
+
+ // We could do better. Just changing property order does not require style invalidation.
+ return oldProperties != m_propertyVector;
}
-void MutableStyleProperties::addParsedProperties(const Vector<CSSProperty>& properties)
+bool MutableStyleProperties::addParsedProperties(const ParsedPropertyVector& properties)
{
+ bool anyChanged = false;
m_propertyVector.reserveCapacity(m_propertyVector.size() + properties.size());
- for (unsigned i = 0; i < properties.size(); ++i)
- addParsedProperty(properties[i]);
+ for (const auto& property : properties) {
+ if (addParsedProperty(property))
+ anyChanged = true;
+ }
+
+ return anyChanged;
}
-void MutableStyleProperties::addParsedProperty(const CSSProperty& property)
+bool MutableStyleProperties::addParsedProperty(const CSSProperty& property)
{
- // Only add properties that have no !important counterpart present
- if (!propertyIsImportant(property.id()) || property.isImportant())
- setProperty(property);
+ if (property.id() == CSSPropertyCustom) {
+ if ((property.value() && !customPropertyIsImportant(downcast<CSSCustomPropertyValue>(*property.value()).name())) || property.isImportant())
+ return setProperty(property);
+ return false;
+ }
+ return setProperty(property);
}
String StyleProperties::asText() const
@@ -790,146 +863,167 @@ String StyleProperties::asText() const
CSSPropertyID shorthandPropertyID = CSSPropertyInvalid;
CSSPropertyID borderFallbackShorthandProperty = CSSPropertyInvalid;
String value;
-
- switch (propertyID) {
- case CSSPropertyBackgroundPositionX:
- positionXPropertyIndex = n;
- continue;
- case CSSPropertyBackgroundPositionY:
- positionYPropertyIndex = n;
- continue;
- case CSSPropertyBackgroundRepeatX:
- repeatXPropertyIndex = n;
- continue;
- case CSSPropertyBackgroundRepeatY:
- repeatYPropertyIndex = n;
- continue;
- case CSSPropertyBorderTopWidth:
- case CSSPropertyBorderRightWidth:
- case CSSPropertyBorderBottomWidth:
- case CSSPropertyBorderLeftWidth:
- if (!borderFallbackShorthandProperty)
- borderFallbackShorthandProperty = CSSPropertyBorderWidth;
- FALLTHROUGH;
- case CSSPropertyBorderTopStyle:
- case CSSPropertyBorderRightStyle:
- case CSSPropertyBorderBottomStyle:
- case CSSPropertyBorderLeftStyle:
- if (!borderFallbackShorthandProperty)
- borderFallbackShorthandProperty = CSSPropertyBorderStyle;
- FALLTHROUGH;
- case CSSPropertyBorderTopColor:
- case CSSPropertyBorderRightColor:
- case CSSPropertyBorderBottomColor:
- case CSSPropertyBorderLeftColor:
- if (!borderFallbackShorthandProperty)
- borderFallbackShorthandProperty = CSSPropertyBorderColor;
-
- // FIXME: Deal with cases where only some of border-(top|right|bottom|left) are specified.
- if (!shorthandPropertyAppeared.test(CSSPropertyBorder - firstCSSProperty)) {
- value = borderPropertyValue(ReturnNullOnUncommonValues);
- if (value.isNull())
- shorthandPropertyAppeared.set(CSSPropertyBorder - firstCSSProperty);
- else
+
+ if (property.value() && property.value()->isPendingSubstitutionValue()) {
+ auto& substitutionValue = downcast<CSSPendingSubstitutionValue>(*property.value());
+ shorthandPropertyID = substitutionValue.shorthandPropertyId();
+ value = substitutionValue.shorthandValue()->cssText();
+ } else {
+ switch (propertyID) {
+ case CSSPropertyAnimationName:
+ case CSSPropertyAnimationDuration:
+ case CSSPropertyAnimationTimingFunction:
+ case CSSPropertyAnimationDelay:
+ case CSSPropertyAnimationIterationCount:
+ case CSSPropertyAnimationDirection:
+ case CSSPropertyAnimationFillMode:
+ case CSSPropertyAnimationPlayState:
+ shorthandPropertyID = CSSPropertyAnimation;
+ break;
+ case CSSPropertyBackgroundPositionX:
+ positionXPropertyIndex = n;
+ continue;
+ case CSSPropertyBackgroundPositionY:
+ positionYPropertyIndex = n;
+ continue;
+ case CSSPropertyBackgroundRepeatX:
+ repeatXPropertyIndex = n;
+ continue;
+ case CSSPropertyBackgroundRepeatY:
+ repeatYPropertyIndex = n;
+ continue;
+ case CSSPropertyBorderTopWidth:
+ case CSSPropertyBorderRightWidth:
+ case CSSPropertyBorderBottomWidth:
+ case CSSPropertyBorderLeftWidth:
+ if (!borderFallbackShorthandProperty)
+ borderFallbackShorthandProperty = CSSPropertyBorderWidth;
+ FALLTHROUGH;
+ case CSSPropertyBorderTopStyle:
+ case CSSPropertyBorderRightStyle:
+ case CSSPropertyBorderBottomStyle:
+ case CSSPropertyBorderLeftStyle:
+ if (!borderFallbackShorthandProperty)
+ borderFallbackShorthandProperty = CSSPropertyBorderStyle;
+ FALLTHROUGH;
+ case CSSPropertyBorderTopColor:
+ case CSSPropertyBorderRightColor:
+ case CSSPropertyBorderBottomColor:
+ case CSSPropertyBorderLeftColor:
+ if (!borderFallbackShorthandProperty)
+ borderFallbackShorthandProperty = CSSPropertyBorderColor;
+
+ // FIXME: Deal with cases where only some of border-(top|right|bottom|left) are specified.
+ ASSERT(CSSPropertyBorder - firstCSSProperty < shorthandPropertyAppeared.size());
+ if (!shorthandPropertyAppeared[CSSPropertyBorder - firstCSSProperty]) {
+ value = borderPropertyValue(ReturnNullOnUncommonValues);
+ if (value.isNull())
+ shorthandPropertyAppeared.set(CSSPropertyBorder - firstCSSProperty);
+ else
+ shorthandPropertyID = CSSPropertyBorder;
+ } else if (shorthandPropertyUsed[CSSPropertyBorder - firstCSSProperty])
shorthandPropertyID = CSSPropertyBorder;
- } else if (shorthandPropertyUsed.test(CSSPropertyBorder - firstCSSProperty))
- shorthandPropertyID = CSSPropertyBorder;
- if (!shorthandPropertyID)
- shorthandPropertyID = borderFallbackShorthandProperty;
- break;
- case CSSPropertyWebkitBorderHorizontalSpacing:
- case CSSPropertyWebkitBorderVerticalSpacing:
- shorthandPropertyID = CSSPropertyBorderSpacing;
- break;
- case CSSPropertyFontFamily:
- case CSSPropertyLineHeight:
- case CSSPropertyFontSize:
- case CSSPropertyFontStyle:
- case CSSPropertyFontVariant:
- case CSSPropertyFontWeight:
- // Don't use CSSPropertyFont because old UAs can't recognize them but are important for editing.
- break;
- case CSSPropertyListStyleType:
- case CSSPropertyListStylePosition:
- case CSSPropertyListStyleImage:
- shorthandPropertyID = CSSPropertyListStyle;
- break;
- case CSSPropertyMarginTop:
- case CSSPropertyMarginRight:
- case CSSPropertyMarginBottom:
- case CSSPropertyMarginLeft:
- shorthandPropertyID = CSSPropertyMargin;
- break;
- case CSSPropertyOutlineWidth:
- case CSSPropertyOutlineStyle:
- case CSSPropertyOutlineColor:
- shorthandPropertyID = CSSPropertyOutline;
- break;
- case CSSPropertyOverflowX:
- case CSSPropertyOverflowY:
- shorthandPropertyID = CSSPropertyOverflow;
- break;
- case CSSPropertyPaddingTop:
- case CSSPropertyPaddingRight:
- case CSSPropertyPaddingBottom:
- case CSSPropertyPaddingLeft:
- shorthandPropertyID = CSSPropertyPadding;
- break;
- case CSSPropertyTransitionProperty:
- case CSSPropertyTransitionDuration:
- case CSSPropertyTransitionTimingFunction:
- case CSSPropertyTransitionDelay:
- shorthandPropertyID = CSSPropertyTransition;
- break;
- case CSSPropertyWebkitAnimationName:
- case CSSPropertyWebkitAnimationDuration:
- case CSSPropertyWebkitAnimationTimingFunction:
- case CSSPropertyWebkitAnimationDelay:
- case CSSPropertyWebkitAnimationIterationCount:
- case CSSPropertyWebkitAnimationDirection:
- case CSSPropertyWebkitAnimationFillMode:
- shorthandPropertyID = CSSPropertyWebkitAnimation;
- break;
- case CSSPropertyWebkitFlexDirection:
- case CSSPropertyWebkitFlexWrap:
- shorthandPropertyID = CSSPropertyWebkitFlexFlow;
- break;
- case CSSPropertyWebkitFlexBasis:
- case CSSPropertyWebkitFlexGrow:
- case CSSPropertyWebkitFlexShrink:
- shorthandPropertyID = CSSPropertyWebkitFlex;
- break;
- case CSSPropertyWebkitMaskPositionX:
- case CSSPropertyWebkitMaskPositionY:
- case CSSPropertyWebkitMaskRepeatX:
- case CSSPropertyWebkitMaskRepeatY:
- case CSSPropertyWebkitMaskImage:
- case CSSPropertyWebkitMaskRepeat:
- case CSSPropertyWebkitMaskPosition:
- case CSSPropertyWebkitMaskClip:
- case CSSPropertyWebkitMaskOrigin:
- shorthandPropertyID = CSSPropertyWebkitMask;
- break;
- case CSSPropertyWebkitTransformOriginX:
- case CSSPropertyWebkitTransformOriginY:
- case CSSPropertyWebkitTransformOriginZ:
- shorthandPropertyID = CSSPropertyWebkitTransformOrigin;
- break;
- case CSSPropertyWebkitTransitionProperty:
- case CSSPropertyWebkitTransitionDuration:
- case CSSPropertyWebkitTransitionTimingFunction:
- case CSSPropertyWebkitTransitionDelay:
- shorthandPropertyID = CSSPropertyWebkitTransition;
- break;
- default:
- break;
+ if (!shorthandPropertyID)
+ shorthandPropertyID = borderFallbackShorthandProperty;
+ break;
+ case CSSPropertyWebkitBorderHorizontalSpacing:
+ case CSSPropertyWebkitBorderVerticalSpacing:
+ shorthandPropertyID = CSSPropertyBorderSpacing;
+ break;
+ case CSSPropertyFontFamily:
+ case CSSPropertyLineHeight:
+ case CSSPropertyFontSize:
+ case CSSPropertyFontStyle:
+ case CSSPropertyFontVariantCaps:
+ case CSSPropertyFontWeight:
+ // Don't use CSSPropertyFont because old UAs can't recognize them but are important for editing.
+ break;
+ case CSSPropertyListStyleType:
+ case CSSPropertyListStylePosition:
+ case CSSPropertyListStyleImage:
+ shorthandPropertyID = CSSPropertyListStyle;
+ break;
+ case CSSPropertyMarginTop:
+ case CSSPropertyMarginRight:
+ case CSSPropertyMarginBottom:
+ case CSSPropertyMarginLeft:
+ shorthandPropertyID = CSSPropertyMargin;
+ break;
+ case CSSPropertyOutlineWidth:
+ case CSSPropertyOutlineStyle:
+ case CSSPropertyOutlineColor:
+ shorthandPropertyID = CSSPropertyOutline;
+ break;
+ case CSSPropertyOverflowX:
+ case CSSPropertyOverflowY:
+ shorthandPropertyID = CSSPropertyOverflow;
+ break;
+ case CSSPropertyPaddingTop:
+ case CSSPropertyPaddingRight:
+ case CSSPropertyPaddingBottom:
+ case CSSPropertyPaddingLeft:
+ shorthandPropertyID = CSSPropertyPadding;
+ break;
+#if ENABLE(CSS_SCROLL_SNAP)
+ case CSSPropertyScrollPaddingTop:
+ case CSSPropertyScrollPaddingRight:
+ case CSSPropertyScrollPaddingBottom:
+ case CSSPropertyScrollPaddingLeft:
+ shorthandPropertyID = CSSPropertyScrollPadding;
+ break;
+ case CSSPropertyScrollSnapMarginTop:
+ case CSSPropertyScrollSnapMarginRight:
+ case CSSPropertyScrollSnapMarginBottom:
+ case CSSPropertyScrollSnapMarginLeft:
+ shorthandPropertyID = CSSPropertyScrollSnapMargin;
+ break;
+#endif
+ case CSSPropertyTransitionProperty:
+ case CSSPropertyTransitionDuration:
+ case CSSPropertyTransitionTimingFunction:
+ case CSSPropertyTransitionDelay:
+ shorthandPropertyID = CSSPropertyTransition;
+ break;
+ case CSSPropertyFlexDirection:
+ case CSSPropertyFlexWrap:
+ shorthandPropertyID = CSSPropertyFlexFlow;
+ break;
+ case CSSPropertyFlexBasis:
+ case CSSPropertyFlexGrow:
+ case CSSPropertyFlexShrink:
+ shorthandPropertyID = CSSPropertyFlex;
+ break;
+ case CSSPropertyWebkitMaskPositionX:
+ case CSSPropertyWebkitMaskPositionY:
+ case CSSPropertyWebkitMaskRepeatX:
+ case CSSPropertyWebkitMaskRepeatY:
+ case CSSPropertyWebkitMaskImage:
+ case CSSPropertyWebkitMaskRepeat:
+ case CSSPropertyWebkitMaskPosition:
+ case CSSPropertyWebkitMaskClip:
+ case CSSPropertyWebkitMaskOrigin:
+ shorthandPropertyID = CSSPropertyWebkitMask;
+ break;
+ case CSSPropertyPerspectiveOriginX:
+ case CSSPropertyPerspectiveOriginY:
+ shorthandPropertyID = CSSPropertyPerspectiveOrigin;
+ break;
+ case CSSPropertyTransformOriginX:
+ case CSSPropertyTransformOriginY:
+ case CSSPropertyTransformOriginZ:
+ shorthandPropertyID = CSSPropertyTransformOrigin;
+ break;
+ default:
+ break;
+ }
}
unsigned shortPropertyIndex = shorthandPropertyID - firstCSSProperty;
if (shorthandPropertyID) {
- if (shorthandPropertyUsed.test(shortPropertyIndex))
+ ASSERT(shortPropertyIndex < shorthandPropertyUsed.size());
+ if (shorthandPropertyUsed[shortPropertyIndex])
continue;
- if (!shorthandPropertyAppeared.test(shortPropertyIndex) && value.isNull())
+ if (!shorthandPropertyAppeared[shortPropertyIndex] && value.isNull())
value = getPropertyValue(shorthandPropertyID);
shorthandPropertyAppeared.set(shortPropertyIndex);
}
@@ -940,12 +1034,17 @@ String StyleProperties::asText() const
} else
value = property.value()->cssText();
- if (value == "initial" && !CSSProperty::isInheritedProperty(propertyID))
+ if (propertyID != CSSPropertyCustom && value == "initial" && !CSSProperty::isInheritedProperty(propertyID))
continue;
if (numDecls++)
result.append(' ');
- result.append(getPropertyName(propertyID));
+
+ if (propertyID == CSSPropertyCustom)
+ result.append(downcast<CSSCustomPropertyValue>(*property.value()).name());
+ else
+ result.append(getPropertyName(propertyID));
+
result.appendLiteral(": ");
result.append(value);
if (property.isImportant())
@@ -1024,7 +1123,7 @@ String StyleProperties::asText() const
bool StyleProperties::hasCSSOMWrapper() const
{
- return m_isMutable && static_cast<const MutableStyleProperties*>(this)->m_cssomWrapper;
+ return is<MutableStyleProperties>(*this) && downcast<MutableStyleProperties>(*this).m_cssomWrapper;
}
void MutableStyleProperties::mergeAndOverrideOnConflict(const StyleProperties& other)
@@ -1034,18 +1133,11 @@ void MutableStyleProperties::mergeAndOverrideOnConflict(const StyleProperties& o
addParsedProperty(other.propertyAt(i).toCSSProperty());
}
-void StyleProperties::addSubresourceStyleURLs(ListHashSet<URL>& urls, StyleSheetContents* contextStyleSheet) const
-{
- unsigned size = propertyCount();
- for (unsigned i = 0; i < size; ++i)
- propertyAt(i).value()->addSubresourceStyleURLs(urls, contextStyleSheet);
-}
-
-bool StyleProperties::hasFailedOrCanceledSubresources() const
+bool StyleProperties::traverseSubresources(const std::function<bool (const CachedResource&)>& handler) const
{
unsigned size = propertyCount();
for (unsigned i = 0; i < size; ++i) {
- if (propertyAt(i).value()->hasFailedOrCanceledSubresources())
+ if (propertyAt(i).value()->traverseSubresources(handler))
return true;
}
return false;
@@ -1057,15 +1149,15 @@ static const CSSPropertyID blockProperties[] = {
CSSPropertyOrphans,
CSSPropertyOverflow, // This can be also be applied to replaced elements
CSSPropertyWebkitAspectRatio,
- CSSPropertyWebkitColumnCount,
- CSSPropertyWebkitColumnGap,
- CSSPropertyWebkitColumnRuleColor,
- CSSPropertyWebkitColumnRuleStyle,
- CSSPropertyWebkitColumnRuleWidth,
+ CSSPropertyColumnCount,
+ CSSPropertyColumnGap,
+ CSSPropertyColumnRuleColor,
+ CSSPropertyColumnRuleStyle,
+ CSSPropertyColumnRuleWidth,
CSSPropertyWebkitColumnBreakBefore,
CSSPropertyWebkitColumnBreakAfter,
CSSPropertyWebkitColumnBreakInside,
- CSSPropertyWebkitColumnWidth,
+ CSSPropertyColumnWidth,
CSSPropertyPageBreakAfter,
CSSPropertyPageBreakBefore,
CSSPropertyPageBreakInside,
@@ -1090,7 +1182,7 @@ void MutableStyleProperties::clear()
const unsigned numBlockProperties = WTF_ARRAY_LENGTH(blockProperties);
-PassRef<MutableStyleProperties> StyleProperties::copyBlockProperties() const
+Ref<MutableStyleProperties> StyleProperties::copyBlockProperties() const
{
return copyPropertiesInSet(blockProperties, numBlockProperties);
}
@@ -1110,23 +1202,10 @@ bool MutableStyleProperties::removePropertiesInSet(const CSSPropertyID* set, uns
for (unsigned i = 0; i < length; ++i)
toRemove.add(set[i]);
- Vector<CSSProperty> newProperties;
- newProperties.reserveInitialCapacity(m_propertyVector.size());
-
- unsigned size = m_propertyVector.size();
- for (unsigned n = 0; n < size; ++n) {
- const CSSProperty& property = m_propertyVector.at(n);
+ return m_propertyVector.removeAllMatching([&toRemove] (const CSSProperty& property) {
// 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_propertyVector.size();
- m_propertyVector = newProperties;
- return changed;
+ return !property.isImportant() && toRemove.contains(property.id());
+ }) > 0;
}
int ImmutableStyleProperties::findPropertyIndex(CSSPropertyID propertyID) const
@@ -1155,6 +1234,40 @@ int MutableStyleProperties::findPropertyIndex(CSSPropertyID propertyID) const
return -1;
}
+int ImmutableStyleProperties::findCustomPropertyIndex(const String& propertyName) const
+{
+ // Convert the propertyID into an uint16_t to compare it with the metadata's m_propertyID to avoid
+ // the compiler converting it to an int multiple times in the loop.
+ for (int n = m_arraySize - 1 ; n >= 0; --n) {
+ if (metadataArray()[n].m_propertyID == CSSPropertyCustom) {
+ // We found a custom property. See if the name matches.
+ if (!valueArray()[n])
+ continue;
+ if (downcast<CSSCustomPropertyValue>(*valueArray()[n]).name() == propertyName)
+ return n;
+ }
+ }
+
+ return -1;
+}
+
+int MutableStyleProperties::findCustomPropertyIndex(const String& propertyName) const
+{
+ // Convert the propertyID into an uint16_t to compare it with the metadata's m_propertyID to avoid
+ // the compiler converting it to an int multiple times in the loop.
+ for (int n = m_propertyVector.size() - 1 ; n >= 0; --n) {
+ if (m_propertyVector.at(n).metadata().m_propertyID == CSSPropertyCustom) {
+ // We found a custom property. See if the name matches.
+ if (!m_propertyVector.at(n).value())
+ continue;
+ if (downcast<CSSCustomPropertyValue>(*m_propertyVector.at(n).value()).name() == propertyName)
+ return n;
+ }
+ }
+
+ return -1;
+}
+
CSSProperty* MutableStyleProperties::findCSSPropertyWithID(CSSPropertyID propertyID)
{
int foundPropertyIndex = findPropertyIndex(propertyID);
@@ -1163,6 +1276,14 @@ CSSProperty* MutableStyleProperties::findCSSPropertyWithID(CSSPropertyID propert
return &m_propertyVector.at(foundPropertyIndex);
}
+CSSProperty* MutableStyleProperties::findCustomCSSPropertyWithName(const String& propertyName)
+{
+ int foundPropertyIndex = findCustomPropertyIndex(propertyName);
+ if (foundPropertyIndex == -1)
+ return 0;
+ return &m_propertyVector.at(foundPropertyIndex);
+}
+
bool StyleProperties::propertyMatches(CSSPropertyID propertyID, const CSSValue* propertyValue) const
{
int foundPropertyIndex = findPropertyIndex(propertyID);
@@ -1171,47 +1292,18 @@ bool StyleProperties::propertyMatches(CSSPropertyID propertyID, const CSSValue*
return propertyAt(foundPropertyIndex).value()->equals(*propertyValue);
}
-void MutableStyleProperties::removeEquivalentProperties(const StyleProperties* style)
-{
- Vector<CSSPropertyID> propertiesToRemove;
- unsigned size = m_propertyVector.size();
- for (unsigned i = 0; i < size; ++i) {
- PropertyReference property = propertyAt(i);
- if (style->propertyMatches(property.id(), property.value()))
- propertiesToRemove.append(property.id());
- }
- // FIXME: This should use mass removal.
- for (unsigned i = 0; i < propertiesToRemove.size(); ++i)
- removeProperty(propertiesToRemove[i]);
-}
-
-void MutableStyleProperties::removeEquivalentProperties(const ComputedStyleExtractor* computedStyle)
-{
- Vector<CSSPropertyID> propertiesToRemove;
- unsigned size = m_propertyVector.size();
- for (unsigned i = 0; i < size; ++i) {
- PropertyReference property = propertyAt(i);
- if (computedStyle->propertyMatches(property.id(), property.value()))
- propertiesToRemove.append(property.id());
- }
- // FIXME: This should use mass removal.
- for (unsigned i = 0; i < propertiesToRemove.size(); ++i)
- removeProperty(propertiesToRemove[i]);
-}
-
-PassRef<MutableStyleProperties> StyleProperties::mutableCopy() const
+Ref<MutableStyleProperties> StyleProperties::mutableCopy() const
{
return adoptRef(*new MutableStyleProperties(*this));
}
-PassRef<MutableStyleProperties> StyleProperties::copyPropertiesInSet(const CSSPropertyID* set, unsigned length) const
+Ref<MutableStyleProperties> StyleProperties::copyPropertiesInSet(const CSSPropertyID* set, unsigned length) const
{
Vector<CSSProperty, 256> list;
list.reserveInitialCapacity(length);
for (unsigned i = 0; i < length; ++i) {
- RefPtr<CSSValue> value = getPropertyCSSValue(set[i]);
- if (value)
- list.append(CSSProperty(set[i], value.release(), false));
+ if (auto value = getPropertyCSSValueInternal(set[i]))
+ list.uncheckedAppend(CSSProperty(set[i], WTFMove(value), false));
}
return MutableStyleProperties::create(list.data(), list.size());
}
@@ -1261,18 +1353,20 @@ void StyleProperties::showStyle()
}
#endif
-PassRef<MutableStyleProperties> MutableStyleProperties::create(CSSParserMode cssParserMode)
+Ref<MutableStyleProperties> MutableStyleProperties::create(CSSParserMode cssParserMode)
{
return adoptRef(*new MutableStyleProperties(cssParserMode));
}
-PassRef<MutableStyleProperties> MutableStyleProperties::create(const CSSProperty* properties, unsigned count)
+Ref<MutableStyleProperties> MutableStyleProperties::create(const CSSProperty* properties, unsigned count)
{
return adoptRef(*new MutableStyleProperties(properties, count));
}
String StyleProperties::PropertyReference::cssName() const
{
+ if (id() == CSSPropertyCustom)
+ return downcast<CSSCustomPropertyValue>(*value()).name();
return getPropertyNameString(id());
}
@@ -1281,12 +1375,34 @@ String StyleProperties::PropertyReference::cssText() const
StringBuilder result;
result.append(cssName());
result.appendLiteral(": ");
- result.append(propertyValue()->cssText());
+ result.append(m_value->cssText());
if (isImportant())
result.appendLiteral(" !important");
result.append(';');
return result.toString();
}
+
+Ref<DeferredStyleProperties> DeferredStyleProperties::create(const CSSParserTokenRange& tokenRange, CSSDeferredParser& parser)
+{
+ return adoptRef(*new DeferredStyleProperties(tokenRange, parser));
+}
+DeferredStyleProperties::DeferredStyleProperties(const CSSParserTokenRange& range, CSSDeferredParser& parser)
+ : StylePropertiesBase(parser.mode(), DeferredPropertiesType)
+ , m_parser(parser)
+{
+ size_t length = range.end() - range.begin();
+ m_tokens.reserveCapacity(length);
+ m_tokens.append(range.begin(), length);
+}
+
+DeferredStyleProperties::~DeferredStyleProperties()
+{
+}
+
+Ref<ImmutableStyleProperties> DeferredStyleProperties::parseDeferredProperties()
+{
+ return m_parser->parseDeclaration(m_tokens);
+}
} // namespace WebCore