summaryrefslogtreecommitdiffstats
path: root/WebCore/editing/ApplyStyleCommand.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/editing/ApplyStyleCommand.cpp')
-rw-r--r--WebCore/editing/ApplyStyleCommand.cpp150
1 files changed, 70 insertions, 80 deletions
diff --git a/WebCore/editing/ApplyStyleCommand.cpp b/WebCore/editing/ApplyStyleCommand.cpp
index b2e93ec..3ff7169 100644
--- a/WebCore/editing/ApplyStyleCommand.cpp
+++ b/WebCore/editing/ApplyStyleCommand.cpp
@@ -145,7 +145,7 @@ void StyleChange::init(PassRefPtr<CSSStyleDeclaration> style, const Position& po
return;
RefPtr<CSSComputedStyleDeclaration> computedStyle = position.computedStyle();
- RefPtr<CSSMutableStyleDeclaration> mutableStyle = getPropertiesNotInComputedStyle(style.get(), computedStyle.get());
+ RefPtr<CSSMutableStyleDeclaration> mutableStyle = getPropertiesNotIn(style.get(), computedStyle.get());
reconcileTextDecorationProperties(mutableStyle.get());
if (!document->frame()->editor()->shouldStyleWithCSS())
@@ -156,7 +156,7 @@ void StyleChange::init(PassRefPtr<CSSStyleDeclaration> style, const Position& po
mutableStyle->removeProperty(CSSPropertyWhiteSpace);
// If unicode-bidi is present in mutableStyle and direction is not, then add direction to mutableStyle.
- // FIXME: Shouldn't this be done in getPropertiesNotInComputedStyle?
+ // FIXME: Shouldn't this be done in getPropertiesNotIn?
if (mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi) && !style->getPropertyCSSValue(CSSPropertyDirection))
mutableStyle->setProperty(CSSPropertyDirection, style->getPropertyValue(CSSPropertyDirection));
@@ -221,8 +221,8 @@ void StyleChange::extractTextStyles(Document* document, CSSMutableStyleDeclarati
// Assuming reconcileTextDecorationProperties has been called, there should not be -webkit-text-decorations-in-effect
// Furthermore, text-decoration: none has been trimmed so that text-decoration property is always a CSSValueList.
- if (RefPtr<CSSValue> textDecoration = style->getPropertyCSSValue(CSSPropertyTextDecoration)) {
- ASSERT(textDecoration->isValueList());
+ RefPtr<CSSValue> textDecoration = style->getPropertyCSSValue(CSSPropertyTextDecoration);
+ if (textDecoration && textDecoration->isValueList()) {
DEFINE_STATIC_LOCAL(RefPtr<CSSPrimitiveValue>, underline, (CSSPrimitiveValue::createIdentifier(CSSValueUnderline)));
DEFINE_STATIC_LOCAL(RefPtr<CSSPrimitiveValue>, lineThrough, (CSSPrimitiveValue::createIdentifier(CSSValueLineThrough)));
@@ -388,23 +388,43 @@ static bool fontWeightIsBold(CSSStyleDeclaration* style)
return false; // Make compiler happy
}
-RefPtr<CSSMutableStyleDeclaration> getPropertiesNotInComputedStyle(CSSStyleDeclaration* style, CSSComputedStyleDeclaration* computedStyle)
+static int getTextAlignment(CSSStyleDeclaration* style)
{
- ASSERT(style);
- ASSERT(computedStyle);
- RefPtr<CSSMutableStyleDeclaration> result = style->copy();
- computedStyle->diff(result.get());
+ int textAlign = getIdentifierValue(style, CSSPropertyTextAlign);
+ switch (textAlign) {
+ case CSSValueCenter:
+ case CSSValueWebkitCenter:
+ return CSSValueCenter;
+ case CSSValueLeft:
+ case CSSValueWebkitLeft:
+ return CSSValueLeft;
+ case CSSValueRight:
+ case CSSValueWebkitRight:
+ return CSSValueRight;
+ }
+ return CSSValueInvalid;
+}
+
+RefPtr<CSSMutableStyleDeclaration> getPropertiesNotIn(CSSStyleDeclaration* styleWithRedundantProperties, CSSStyleDeclaration* baseStyle)
+{
+ ASSERT(styleWithRedundantProperties);
+ ASSERT(baseStyle);
+ RefPtr<CSSMutableStyleDeclaration> result = styleWithRedundantProperties->copy();
+ baseStyle->diff(result.get());
- RefPtr<CSSValue> computedTextDecorationsInEffect = computedStyle->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
- diffTextDecorations(result.get(), CSSPropertyTextDecoration, computedTextDecorationsInEffect.get());
- diffTextDecorations(result.get(), CSSPropertyWebkitTextDecorationsInEffect, computedTextDecorationsInEffect.get());
+ RefPtr<CSSValue> baseTextDecorationsInEffect = baseStyle->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
+ diffTextDecorations(result.get(), CSSPropertyTextDecoration, baseTextDecorationsInEffect.get());
+ diffTextDecorations(result.get(), CSSPropertyWebkitTextDecorationsInEffect, baseTextDecorationsInEffect.get());
- if (fontWeightIsBold(result.get()) == fontWeightIsBold(computedStyle))
+ if (fontWeightIsBold(result.get()) == fontWeightIsBold(baseStyle))
result->removeProperty(CSSPropertyFontWeight);
- if (getRGBAFontColor(result.get()) == getRGBAFontColor(computedStyle))
+ if (getRGBAFontColor(result.get()) == getRGBAFontColor(baseStyle))
result->removeProperty(CSSPropertyColor);
+ if (getTextAlignment(result.get()) == getTextAlignment(baseStyle))
+ result->removeProperty(CSSPropertyTextAlign);
+
return result;
}
@@ -439,6 +459,11 @@ static const int editingStyleProperties[] = {
};
size_t numEditingStyleProperties = sizeof(editingStyleProperties)/sizeof(editingStyleProperties[0]);
+RefPtr<CSSMutableStyleDeclaration> ApplyStyleCommand::removeNonEditingProperties(CSSStyleDeclaration* style)
+{
+ return style->copyPropertiesInSet(editingStyleProperties, numEditingStyleProperties);
+}
+
PassRefPtr<CSSMutableStyleDeclaration> ApplyStyleCommand::editingStyleAtPosition(Position pos, ShouldIncludeTypingStyle shouldIncludeTypingStyle)
{
RefPtr<CSSComputedStyleDeclaration> computedStyleAtPosition = pos.computedStyle();
@@ -446,7 +471,7 @@ PassRefPtr<CSSMutableStyleDeclaration> ApplyStyleCommand::editingStyleAtPosition
if (!computedStyleAtPosition)
style = CSSMutableStyleDeclaration::create();
else
- style = computedStyleAtPosition->copyPropertiesInSet(editingStyleProperties, numEditingStyleProperties);
+ style = removeNonEditingProperties(computedStyleAtPosition.get());
if (style && pos.node() && pos.node()->computedStyle()) {
RenderStyle* renderStyle = pos.node()->computedStyle();
@@ -1161,19 +1186,22 @@ bool ApplyStyleCommand::removeStyleFromRunBeforeApplyingStyle(CSSMutableStyleDec
return true;
}
-bool ApplyStyleCommand::removeInlineStyleFromElement(CSSMutableStyleDeclaration* style, HTMLElement* element, InlineStyleRemovalMode mode)
+bool ApplyStyleCommand::removeInlineStyleFromElement(CSSMutableStyleDeclaration* style, HTMLElement* element, InlineStyleRemovalMode mode, CSSMutableStyleDeclaration* extractedStyle)
{
ASSERT(style);
ASSERT(element);
if (m_styledInlineElement && element->hasTagName(m_styledInlineElement->tagQName())) {
- if (mode != RemoveNone)
+ if (mode != RemoveNone) {
+ if (extractedStyle && element->inlineStyleDecl())
+ extractedStyle->merge(element->inlineStyleDecl());
removeNodePreservingChildren(element);
+ }
return true;
}
bool removed = false;
- if (removeImplicitlyStyledElement(style, element, mode))
+ if (removeImplicitlyStyledElement(style, element, mode, extractedStyle))
removed = true;
if (!element->inDocument())
@@ -1181,7 +1209,7 @@ bool ApplyStyleCommand::removeInlineStyleFromElement(CSSMutableStyleDeclaration*
// If the node was converted to a span, the span may still contain relevant
// styles which must be removed (e.g. <b style='font-weight: bold'>)
- if (removeCSSStyle(style, element, mode))
+ if (removeCSSStyle(style, element, mode, extractedStyle))
removed = true;
return removed;
@@ -1313,27 +1341,35 @@ void ApplyStyleCommand::replaceWithSpanOrRemoveIfWithoutAttributes(HTMLElement*&
}
}
-bool ApplyStyleCommand::removeCSSStyle(CSSMutableStyleDeclaration* style, HTMLElement* elem, InlineStyleRemovalMode mode)
+bool ApplyStyleCommand::removeCSSStyle(CSSMutableStyleDeclaration* style, HTMLElement* element, InlineStyleRemovalMode mode, CSSMutableStyleDeclaration* extractedStyle)
{
ASSERT(style);
- ASSERT(elem);
+ ASSERT(element);
- CSSMutableStyleDeclaration* decl = elem->inlineStyleDecl();
+ CSSMutableStyleDeclaration* decl = element->inlineStyleDecl();
if (!decl)
return false;
bool removed = false;
CSSMutableStyleDeclaration::const_iterator end = style->end();
for (CSSMutableStyleDeclaration::const_iterator it = style->begin(); it != end; ++it) {
- CSSPropertyID propertyID = static_cast<CSSPropertyID>((*it).id());
+ CSSPropertyID propertyID = static_cast<CSSPropertyID>(it->id());
RefPtr<CSSValue> value = decl->getPropertyCSSValue(propertyID);
- if (value && (propertyID != CSSPropertyWhiteSpace || !isTabSpanNode(elem))) {
+ if (value && (propertyID != CSSPropertyWhiteSpace || !isTabSpanNode(element))) {
removed = true;
if (mode == RemoveNone)
return true;
- removeCSSProperty(elem, propertyID);
- if (propertyID == CSSPropertyUnicodeBidi && !decl->getPropertyValue(CSSPropertyDirection).isEmpty())
- removeCSSProperty(elem, CSSPropertyDirection);
+
+ ExceptionCode ec = 0;
+ if (extractedStyle)
+ extractedStyle->setProperty(propertyID, value->cssText(), decl->getPropertyPriority(propertyID), ec);
+ removeCSSProperty(element, propertyID);
+
+ if (propertyID == CSSPropertyUnicodeBidi && !decl->getPropertyValue(CSSPropertyDirection).isEmpty()) {
+ if (extractedStyle)
+ extractedStyle->setProperty(CSSPropertyDirection, decl->getPropertyValue(CSSPropertyDirection), decl->getPropertyPriority(CSSPropertyDirection), ec);
+ removeCSSProperty(element, CSSPropertyDirection);
+ }
}
}
@@ -1342,10 +1378,10 @@ bool ApplyStyleCommand::removeCSSStyle(CSSMutableStyleDeclaration* style, HTMLEl
// No need to serialize <foo style=""> if we just removed the last css property
if (decl->isEmpty())
- removeNodeAttribute(elem, styleAttr);
+ removeNodeAttribute(element, styleAttr);
- if (isSpanWithoutAttributesOrUnstyleStyleSpan(elem))
- removeNodePreservingChildren(elem);
+ if (isSpanWithoutAttributesOrUnstyleStyleSpan(element))
+ removeNodePreservingChildren(element);
return removed;
}
@@ -1370,51 +1406,6 @@ HTMLElement* ApplyStyleCommand::highestAncestorWithConflictingInlineStyle(CSSMut
return result;
}
-PassRefPtr<CSSMutableStyleDeclaration> ApplyStyleCommand::extractInlineStyleToPushDown(CSSMutableStyleDeclaration* styleToApply, Node* node, bool isStyledElement)
-{
- ASSERT(node);
- ASSERT(node->isElementNode());
-
- // non-html elements not handled yet
- if (!node->isHTMLElement())
- return 0;
-
- HTMLElement* element = static_cast<HTMLElement*>(node);
- RefPtr<CSSMutableStyleDeclaration> style = element->inlineStyleDecl();
- if (isStyledElement) {
- removeNodePreservingChildren(element);
- return style.release();
- }
-
- if (!style) {
- style = CSSMutableStyleDeclaration::create();
- removeImplicitlyStyledElement(styleToApply, element, RemoveIfNeeded, style.get());
- return style.release();
- }
-
- Vector<int> properties;
- CSSMutableStyleDeclaration::const_iterator end = styleToApply->end();
- for (CSSMutableStyleDeclaration::const_iterator it = styleToApply->begin(); it != end; ++it)
- properties.append(it->id());
-
- style = style->copyPropertiesInSet(properties.data(), properties.size());
- for (size_t i = 0; i < properties.size(); i++) {
- RefPtr<CSSValue> property = style->getPropertyCSSValue(properties[i]);
- if (property)
- removeCSSProperty(element, static_cast<CSSPropertyID>(properties[i]));
- }
-
- if (element->inlineStyleDecl() && element->inlineStyleDecl()->isEmpty())
- removeNodeAttribute(element, styleAttr);
-
- if (isSpanWithoutAttributesOrUnstyleStyleSpan(element))
- removeNodePreservingChildren(element);
-
- removeImplicitlyStyledElement(styleToApply, element, RemoveIfNeeded, style.get());
-
- return style.release();
-}
-
void ApplyStyleCommand::applyInlineStyleToPushDown(Node* node, CSSMutableStyleDeclaration* style)
{
ASSERT(node);
@@ -1437,11 +1428,9 @@ void ApplyStyleCommand::applyInlineStyleToPushDown(Node* node, CSSMutableStyleDe
newInlineStyle->setProperty(it->id(), it->value()->cssText(), it->isImportant(), ec);
// text-decorations adds up
- if (it->id() == CSSPropertyTextDecoration) {
- ASSERT(it->value()->isValueList());
+ if (it->id() == CSSPropertyTextDecoration && it->value()->isValueList()) {
RefPtr<CSSValue> textDecoration = newInlineStyle->getPropertyCSSValue(CSSPropertyTextDecoration);
- if (textDecoration) {
- ASSERT(textDecoration->isValueList());
+ if (textDecoration && textDecoration->isValueList()) {
CSSValueList* textDecorationOfInlineStyle = static_cast<CSSValueList*>(textDecoration.get());
CSSValueList* textDecorationOfStyleApplied = static_cast<CSSValueList*>(it->value());
@@ -1492,7 +1481,8 @@ void ApplyStyleCommand::pushDownInlineStyleAroundNode(CSSMutableStyleDeclaration
RefPtr<StyledElement> styledElement;
if (current->isStyledElement() && m_styledInlineElement && current->hasTagName(m_styledInlineElement->tagQName()))
styledElement = static_cast<StyledElement*>(current);
- RefPtr<CSSMutableStyleDeclaration> styleToPushDown = extractInlineStyleToPushDown(style, current, styledElement);
+ RefPtr<CSSMutableStyleDeclaration> styleToPushDown = CSSMutableStyleDeclaration::create();
+ removeInlineStyleFromElement(style, static_cast<HTMLElement*>(current), RemoveIfNeeded, styleToPushDown.get());
// The inner loop will go through children on each level
// FIXME: we should aggregate inline child elements together so that we don't wrap each child separately.