CSSMutableStyleDeclaration.cpp [plain text]
#include "config.h"
#include "CSSMutableStyleDeclaration.h"
#include "CSSImageValue.h"
#include "CSSParser.h"
#include "CSSProperty.h"
#include "CSSPropertyNames.h"
#include "CSSStyleSheet.h"
#include "CSSValueList.h"
#include "Document.h"
#include "ExceptionCode.h"
#include "StyledElement.h"
using namespace std;
namespace WebCore {
CSSMutableStyleDeclaration::CSSMutableStyleDeclaration()
: m_node(0)
{
}
CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent)
: CSSStyleDeclaration(parent)
, m_node(0)
{
}
CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent, const DeprecatedValueList<CSSProperty>& values)
: CSSStyleDeclaration(parent)
, m_values(values)
, m_node(0)
{
}
CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent, const CSSProperty* const * properties, int numProperties)
: CSSStyleDeclaration(parent)
, m_node(0)
{
for (int i = 0; i < numProperties; ++i) {
ASSERT(properties[i]);
m_values.append(*properties[i]);
}
}
CSSMutableStyleDeclaration& CSSMutableStyleDeclaration::operator=(const CSSMutableStyleDeclaration& other)
{
m_values = other.m_values;
return *this;
}
String CSSMutableStyleDeclaration::getPropertyValue(int propertyID) const
{
RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
if (value)
return value->cssText();
switch (propertyID) {
case CSS_PROP_BACKGROUND_POSITION: {
const int properties[2] = { CSS_PROP_BACKGROUND_POSITION_X,
CSS_PROP_BACKGROUND_POSITION_Y };
return getLayeredShorthandValue(properties, 2);
}
case CSS_PROP_BACKGROUND: {
const int properties[6] = { CSS_PROP_BACKGROUND_IMAGE, CSS_PROP_BACKGROUND_REPEAT,
CSS_PROP_BACKGROUND_ATTACHMENT, CSS_PROP_BACKGROUND_POSITION_X,
CSS_PROP_BACKGROUND_POSITION_Y, CSS_PROP_BACKGROUND_COLOR };
return getLayeredShorthandValue(properties, 6);
}
case CSS_PROP_BORDER: {
const int properties[3] = { CSS_PROP_BORDER_WIDTH, CSS_PROP_BORDER_STYLE,
CSS_PROP_BORDER_COLOR };
return getShorthandValue(properties, 3);
}
case CSS_PROP_BORDER_TOP: {
const int properties[3] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_TOP_STYLE,
CSS_PROP_BORDER_TOP_COLOR};
return getShorthandValue(properties, 3);
}
case CSS_PROP_BORDER_RIGHT: {
const int properties[3] = { CSS_PROP_BORDER_RIGHT_WIDTH, CSS_PROP_BORDER_RIGHT_STYLE,
CSS_PROP_BORDER_RIGHT_COLOR};
return getShorthandValue(properties, 3);
}
case CSS_PROP_BORDER_BOTTOM: {
const int properties[3] = { CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_BOTTOM_STYLE,
CSS_PROP_BORDER_BOTTOM_COLOR};
return getShorthandValue(properties, 3);
}
case CSS_PROP_BORDER_LEFT: {
const int properties[3] = { CSS_PROP_BORDER_LEFT_WIDTH, CSS_PROP_BORDER_LEFT_STYLE,
CSS_PROP_BORDER_LEFT_COLOR};
return getShorthandValue(properties, 3);
}
case CSS_PROP_OUTLINE: {
const int properties[3] = { CSS_PROP_OUTLINE_WIDTH, CSS_PROP_OUTLINE_STYLE,
CSS_PROP_OUTLINE_COLOR };
return getShorthandValue(properties, 3);
}
case CSS_PROP_BORDER_COLOR: {
const int properties[4] = { CSS_PROP_BORDER_TOP_COLOR, CSS_PROP_BORDER_RIGHT_COLOR,
CSS_PROP_BORDER_BOTTOM_COLOR, CSS_PROP_BORDER_LEFT_COLOR };
return get4Values(properties);
}
case CSS_PROP_BORDER_WIDTH: {
const int properties[4] = { CSS_PROP_BORDER_TOP_WIDTH, CSS_PROP_BORDER_RIGHT_WIDTH,
CSS_PROP_BORDER_BOTTOM_WIDTH, CSS_PROP_BORDER_LEFT_WIDTH };
return get4Values(properties);
}
case CSS_PROP_BORDER_STYLE: {
const int properties[4] = { CSS_PROP_BORDER_TOP_STYLE, CSS_PROP_BORDER_RIGHT_STYLE,
CSS_PROP_BORDER_BOTTOM_STYLE, CSS_PROP_BORDER_LEFT_STYLE };
return get4Values(properties);
}
case CSS_PROP_MARGIN: {
const int properties[4] = { CSS_PROP_MARGIN_TOP, CSS_PROP_MARGIN_RIGHT,
CSS_PROP_MARGIN_BOTTOM, CSS_PROP_MARGIN_LEFT };
return get4Values(properties);
}
case CSS_PROP_PADDING: {
const int properties[4] = { CSS_PROP_PADDING_TOP, CSS_PROP_PADDING_RIGHT,
CSS_PROP_PADDING_BOTTOM, CSS_PROP_PADDING_LEFT };
return get4Values(properties);
}
case CSS_PROP_LIST_STYLE: {
const int properties[3] = { CSS_PROP_LIST_STYLE_TYPE, CSS_PROP_LIST_STYLE_POSITION,
CSS_PROP_LIST_STYLE_IMAGE };
return getShorthandValue(properties, 3);
}
}
return String();
}
String CSSMutableStyleDeclaration::get4Values( const int* properties ) const
{
String res;
for (int i = 0; i < 4; ++i) {
if (!isPropertyImplicit(properties[i])) {
RefPtr<CSSValue> value = getPropertyCSSValue(properties[i]);
if (!value)
return String();
if (!res.isNull())
res += " ";
res += value->cssText();
}
}
return res;
}
String CSSMutableStyleDeclaration::getLayeredShorthandValue(const int* properties, unsigned number) const
{
String res;
unsigned i;
unsigned j;
Vector< RefPtr<CSSValue> > values(number);
unsigned numLayers = 0;
for (i = 0; i < number; ++i) {
values[i] = getPropertyCSSValue(properties[i]);
if (values[i]) {
if (values[i]->isValueList()) {
CSSValueList* valueList = static_cast<CSSValueList*>(values[i].get());
numLayers = max(valueList->length(), numLayers);
} else
numLayers = max(1U, numLayers);
}
}
for (i = 0; i < numLayers; i++) {
String layerRes;
for (j = 0; j < number; j++) {
RefPtr<CSSValue> value;
if (values[j]) {
if (values[j]->isValueList())
value = static_cast<CSSValueList*>(values[j].get())->item(i);
else {
value = values[j];
if (properties[j] == CSS_PROP_BACKGROUND_COLOR) {
if (i != numLayers - 1)
value = 0;
} else if (i != 0) value = 0;
}
}
if (value && !value->isImplicitInitialValue()) {
if (!layerRes.isNull())
layerRes += " ";
layerRes += value->cssText();
}
}
if (!layerRes.isNull()) {
if (!res.isNull())
res += ", ";
res += layerRes;
}
}
return res;
}
String CSSMutableStyleDeclaration::getShorthandValue(const int* properties, int number) const
{
String res;
for (int i = 0; i < number; ++i) {
if (!isPropertyImplicit(properties[i])) {
RefPtr<CSSValue> value = getPropertyCSSValue(properties[i]);
if (value) {
if (!res.isNull())
res += " ";
res += value->cssText();
}
}
}
return res;
}
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;
}
struct PropertyLonghand {
PropertyLonghand()
: m_properties(0)
, m_length(0)
{
}
PropertyLonghand(const int* firstProperty, unsigned numProperties)
: m_properties(firstProperty)
, m_length(numProperties)
{
}
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])))
static const int borderProperties[4][3] = {
{ CSS_PROP_BORDER_TOP_COLOR, CSS_PROP_BORDER_TOP_STYLE, CSS_PROP_BORDER_TOP_WIDTH },
{ CSS_PROP_BORDER_RIGHT_COLOR, CSS_PROP_BORDER_RIGHT_STYLE, CSS_PROP_BORDER_RIGHT_WIDTH },
{ CSS_PROP_BORDER_BOTTOM_COLOR, CSS_PROP_BORDER_BOTTOM_STYLE, CSS_PROP_BORDER_BOTTOM_WIDTH },
{ CSS_PROP_BORDER_LEFT_COLOR, CSS_PROP_BORDER_LEFT_STYLE, CSS_PROP_BORDER_LEFT_WIDTH }
};
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_BORDER_TOP, borderProperties[0]);
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_BORDER_RIGHT, borderProperties[1]);
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_BORDER_BOTTOM, borderProperties[2]);
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_BORDER_LEFT, borderProperties[3]);
shorthandMap.set(CSS_PROP_BORDER, PropertyLonghand(borderProperties[0], sizeof(borderProperties) / sizeof(borderProperties[0][0])));
static const int borderColorProperties[] = {
CSS_PROP_BORDER_TOP_COLOR,
CSS_PROP_BORDER_RIGHT_COLOR,
CSS_PROP_BORDER_BOTTOM_COLOR,
CSS_PROP_BORDER_LEFT_COLOR
};
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_BORDER_COLOR, borderColorProperties);
static const int borderStyleProperties[] = {
CSS_PROP_BORDER_TOP_STYLE,
CSS_PROP_BORDER_RIGHT_STYLE,
CSS_PROP_BORDER_BOTTOM_STYLE,
CSS_PROP_BORDER_LEFT_STYLE
};
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_BORDER_STYLE, borderStyleProperties);
static const int borderWidthProperties[] = {
CSS_PROP_BORDER_TOP_WIDTH,
CSS_PROP_BORDER_RIGHT_WIDTH,
CSS_PROP_BORDER_BOTTOM_WIDTH,
CSS_PROP_BORDER_LEFT_WIDTH
};
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_BORDER_WIDTH, borderWidthProperties);
static const int backgroundPositionProperties[] = { CSS_PROP_BACKGROUND_POSITION_X, CSS_PROP_BACKGROUND_POSITION_Y };
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_BACKGROUND_POSITION, backgroundPositionProperties);
static const int borderSpacingProperties[] = { CSS_PROP__WEBKIT_BORDER_HORIZONTAL_SPACING, CSS_PROP__WEBKIT_BORDER_VERTICAL_SPACING };
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_BORDER_SPACING, borderSpacingProperties);
static const int listStyleProperties[] = {
CSS_PROP_LIST_STYLE_IMAGE,
CSS_PROP_LIST_STYLE_POSITION,
CSS_PROP_LIST_STYLE_TYPE
};
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_LIST_STYLE, listStyleProperties);
static const int marginProperties[] = {
CSS_PROP_MARGIN_TOP,
CSS_PROP_MARGIN_RIGHT,
CSS_PROP_MARGIN_BOTTOM,
CSS_PROP_MARGIN_LEFT
};
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_MARGIN, marginProperties);
static const int marginCollapseProperties[] = { CSS_PROP__WEBKIT_MARGIN_TOP_COLLAPSE, CSS_PROP__WEBKIT_MARGIN_BOTTOM_COLLAPSE };
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP__WEBKIT_MARGIN_COLLAPSE, marginCollapseProperties);
static const int marqueeProperties[] = {
CSS_PROP__WEBKIT_MARQUEE_DIRECTION,
CSS_PROP__WEBKIT_MARQUEE_INCREMENT,
CSS_PROP__WEBKIT_MARQUEE_REPETITION,
CSS_PROP__WEBKIT_MARQUEE_STYLE,
CSS_PROP__WEBKIT_MARQUEE_SPEED
};
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP__WEBKIT_MARQUEE, marqueeProperties);
static const int outlineProperties[] = {
CSS_PROP_OUTLINE_COLOR,
CSS_PROP_OUTLINE_OFFSET,
CSS_PROP_OUTLINE_STYLE,
CSS_PROP_OUTLINE_WIDTH
};
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_OUTLINE, outlineProperties);
static const int paddingProperties[] = {
CSS_PROP_PADDING_TOP,
CSS_PROP_PADDING_RIGHT,
CSS_PROP_PADDING_BOTTOM,
CSS_PROP_PADDING_LEFT
};
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_PADDING, paddingProperties);
static const int textStrokeProperties[] = { CSS_PROP__WEBKIT_TEXT_STROKE_COLOR, CSS_PROP__WEBKIT_TEXT_STROKE_WIDTH };
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP__WEBKIT_TEXT_STROKE, textStrokeProperties);
static const int backgroundProperties[] = {
CSS_PROP_BACKGROUND_ATTACHMENT,
CSS_PROP_BACKGROUND_COLOR,
CSS_PROP_BACKGROUND_IMAGE,
CSS_PROP_BACKGROUND_POSITION_X,
CSS_PROP_BACKGROUND_POSITION_Y,
CSS_PROP_BACKGROUND_REPEAT,
CSS_PROP__WEBKIT_BACKGROUND_SIZE
};
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_BACKGROUND, backgroundProperties);
static const int columnsProperties[] = { CSS_PROP__WEBKIT_COLUMN_WIDTH, CSS_PROP__WEBKIT_COLUMN_COUNT };
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP__WEBKIT_COLUMNS, columnsProperties);
static const int columnRuleProperties[] = {
CSS_PROP__WEBKIT_COLUMN_RULE_COLOR,
CSS_PROP__WEBKIT_COLUMN_RULE_STYLE,
CSS_PROP__WEBKIT_COLUMN_RULE_WIDTH
};
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP__WEBKIT_COLUMN_RULE, columnRuleProperties);
static const int overflowProperties[] = { CSS_PROP_OVERFLOW_X, CSS_PROP_OVERFLOW_Y };
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP_OVERFLOW, overflowProperties);
static const int borderRadiusProperties[] = {
CSS_PROP__WEBKIT_BORDER_TOP_RIGHT_RADIUS,
CSS_PROP__WEBKIT_BORDER_TOP_LEFT_RADIUS,
CSS_PROP__WEBKIT_BORDER_BOTTOM_LEFT_RADIUS,
CSS_PROP__WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS
};
SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSS_PROP__WEBKIT_BORDER_RADIUS, borderRadiusProperties);
#undef SET_SHORTHAND_MAP_ENTRY
}
String CSSMutableStyleDeclaration::removeProperty(int propertyID, bool notifyChanged, bool returnText, ExceptionCode& ec)
{
ec = 0;
static HashMap<int, PropertyLonghand> shorthandMap;
if (shorthandMap.isEmpty())
initShorthandMap(shorthandMap);
PropertyLonghand longhand = shorthandMap.get(propertyID);
if (longhand.length()) {
removePropertiesInSet(longhand.properties(), longhand.length(), notifyChanged);
return 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();
m_values.remove(it);
if (notifyChanged)
setChanged();
break;
}
}
return value;
}
void CSSMutableStyleDeclaration::clear()
{
m_values.clear();
setChanged();
}
void CSSMutableStyleDeclaration::setChanged(StyleChangeType changeType)
{
if (m_node) {
m_node->setChanged(changeType);
if (m_node->isStyledElement() && this == static_cast<StyledElement*>(m_node)->inlineStyleDecl())
static_cast<StyledElement*>(m_node)->invalidateStyleAttribute();
return;
}
StyleBase* root = this;
while (StyleBase* parent = root->parent())
root = parent;
if (root->isCSSStyleSheet())
static_cast<CSSStyleSheet*>(root)->doc()->updateStyleSelector();
}
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;
}
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;
}
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;
}
void CSSMutableStyleDeclaration::setProperty(int propertyID, const String& value, bool important, ExceptionCode& ec)
{
setProperty(propertyID, value, important, true, ec);
}
String CSSMutableStyleDeclaration::removeProperty(int propertyID, ExceptionCode& ec)
{
return removeProperty(propertyID, true, true, ec);
}
bool CSSMutableStyleDeclaration::setProperty(int propertyID, const String& value, bool important, bool notifyChanged, ExceptionCode& ec)
{
ec = 0;
if (value.isEmpty()) {
removeProperty(propertyID, notifyChanged, false, ec);
return ec == 0;
}
CSSParser parser(useStrictParsing());
bool success = parser.parseValue(this, propertyID, value, important);
if (!success) {
} else if (notifyChanged)
setChanged(InlineStyleChange);
ASSERT(!ec);
return success;
}
bool CSSMutableStyleDeclaration::setProperty(int propertyID, int value, bool important, bool notifyChanged)
{
removeProperty(propertyID);
m_values.append(CSSProperty(propertyID, new CSSPrimitiveValue(value), important));
if (notifyChanged)
setChanged();
return true;
}
void CSSMutableStyleDeclaration::setStringProperty(int propertyId, const String &value, CSSPrimitiveValue::UnitTypes type, bool important)
{
removeProperty(propertyId);
m_values.append(CSSProperty(propertyId, new CSSPrimitiveValue(value, type), important));
setChanged();
}
void CSSMutableStyleDeclaration::setImageProperty(int propertyId, const String& url, bool important)
{
removeProperty(propertyId);
m_values.append(CSSProperty(propertyId, new CSSImageValue(url, this), important));
setChanged();
}
void CSSMutableStyleDeclaration::parseDeclaration(const String& styleDeclaration)
{
m_values.clear();
CSSParser parser(useStrictParsing());
parser.parseDeclaration(this, styleDeclaration);
setChanged();
}
void CSSMutableStyleDeclaration::addParsedProperties(const CSSProperty * const * properties, int numProperties)
{
for (int i = 0; i < numProperties; ++i) {
if (!getPropertyPriority(properties[i]->id()) || properties[i]->isImportant()) {
removeProperty(properties[i]->id(), false);
ASSERT(properties[i]);
m_values.append(*properties[i]);
}
}
}
void CSSMutableStyleDeclaration::setLengthProperty(int propertyId, const String& value, bool important, bool )
{
bool parseMode = useStrictParsing();
setStrictParsing(false);
setProperty(propertyId, value, important);
setStrictParsing(parseMode);
}
unsigned CSSMutableStyleDeclaration::length() const
{
return m_values.count();
}
String CSSMutableStyleDeclaration::item(unsigned i) const
{
if (i >= m_values.count())
return String();
return getPropertyName(static_cast<CSSPropertyID>(m_values[i].id()));
}
String CSSMutableStyleDeclaration::cssText() const
{
String result = "";
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;
if (prop.id() == CSS_PROP_BACKGROUND_POSITION_X)
positionXProp = ∝
else if (prop.id() == CSS_PROP_BACKGROUND_POSITION_Y)
positionYProp = ∝
else
result += prop.cssText();
}
if (positionXProp && positionYProp && positionXProp->isImportant() == positionYProp->isImportant()) {
String positionValue;
const int properties[2] = { CSS_PROP_BACKGROUND_POSITION_X, CSS_PROP_BACKGROUND_POSITION_Y };
if (positionXProp->value()->isValueList() || positionYProp->value()->isValueList())
positionValue = getLayeredShorthandValue(properties, 2);
else
positionValue = positionXProp->value()->cssText() + " " + positionYProp->value()->cssText();
result += "background-position: " + positionValue + (positionXProp->isImportant() ? " !important" : "") + "; ";
} else {
if (positionXProp)
result += positionXProp->cssText();
if (positionYProp)
result += positionYProp->cssText();
}
return result;
}
void CSSMutableStyleDeclaration::setCssText(const String& text, ExceptionCode& ec)
{
ec = 0;
m_values.clear();
CSSParser parser(useStrictParsing());
parser.parseDeclaration(this, text);
setChanged();
}
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)
continue;
removeProperty(property.id());
}
m_values.append(property);
}
}
static const int blockProperties[] = {
CSS_PROP_ORPHANS,
CSS_PROP_OVERFLOW, CSS_PROP__WEBKIT_COLUMN_COUNT,
CSS_PROP__WEBKIT_COLUMN_GAP,
CSS_PROP__WEBKIT_COLUMN_RULE_COLOR,
CSS_PROP__WEBKIT_COLUMN_RULE_STYLE,
CSS_PROP__WEBKIT_COLUMN_RULE_WIDTH,
CSS_PROP__WEBKIT_COLUMN_BREAK_BEFORE,
CSS_PROP__WEBKIT_COLUMN_BREAK_AFTER,
CSS_PROP__WEBKIT_COLUMN_BREAK_INSIDE,
CSS_PROP__WEBKIT_COLUMN_WIDTH,
CSS_PROP_PAGE_BREAK_AFTER,
CSS_PROP_PAGE_BREAK_BEFORE,
CSS_PROP_PAGE_BREAK_INSIDE,
CSS_PROP_TEXT_ALIGN,
CSS_PROP_TEXT_INDENT,
CSS_PROP_WIDOWS
};
const unsigned numBlockProperties = sizeof(blockProperties) / sizeof(blockProperties[0]);
PassRefPtr<CSSMutableStyleDeclaration> CSSMutableStyleDeclaration::copyBlockProperties() const
{
return copyPropertiesInSet(blockProperties, numBlockProperties);
}
void CSSMutableStyleDeclaration::removeBlockProperties()
{
removePropertiesInSet(blockProperties, numBlockProperties);
}
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;
}
}
if (changed && notifyChanged)
setChanged();
}
PassRefPtr<CSSMutableStyleDeclaration> CSSMutableStyleDeclaration::makeMutable()
{
return this;
}
PassRefPtr<CSSMutableStyleDeclaration> CSSMutableStyleDeclaration::copy() const
{
return new CSSMutableStyleDeclaration(0, m_values);
}
}