diff options
Diffstat (limited to 'WebCore/editing/ApplyStyleCommand.cpp')
-rw-r--r-- | WebCore/editing/ApplyStyleCommand.cpp | 150 |
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. |