diff options
author | Ben Murdoch <benm@google.com> | 2011-06-02 12:07:03 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-06-10 10:47:21 +0100 |
commit | 2daae5fd11344eaa88a0d92b0f6d65f8d2255c00 (patch) | |
tree | e4964fbd1cb70599f7718ff03e50ea1dab33890b /Source/WebCore/editing/ApplyStyleCommand.cpp | |
parent | 87bdf0060a247bfbe668342b87e0874182e0ffa9 (diff) | |
download | external_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.zip external_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.tar.gz external_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.tar.bz2 |
Merge WebKit at r84325: Initial merge by git.
Change-Id: Ic1a909300ecc0a13ddc6b4e784371d2ac6e3d59b
Diffstat (limited to 'Source/WebCore/editing/ApplyStyleCommand.cpp')
-rw-r--r-- | Source/WebCore/editing/ApplyStyleCommand.cpp | 325 |
1 files changed, 0 insertions, 325 deletions
diff --git a/Source/WebCore/editing/ApplyStyleCommand.cpp b/Source/WebCore/editing/ApplyStyleCommand.cpp index 59540ec..c9649d0 100644 --- a/Source/WebCore/editing/ApplyStyleCommand.cpp +++ b/Source/WebCore/editing/ApplyStyleCommand.cpp @@ -54,242 +54,6 @@ namespace WebCore { using namespace HTMLNames; -static RGBA32 getRGBAFontColor(CSSStyleDeclaration* style) -{ - RefPtr<CSSValue> colorValue = style->getPropertyCSSValue(CSSPropertyColor); - if (!colorValue || !colorValue->isPrimitiveValue()) - return Color::transparent; - - CSSPrimitiveValue* primitiveColor = static_cast<CSSPrimitiveValue*>(colorValue.get()); - RGBA32 rgba = 0; - if (primitiveColor->primitiveType() != CSSPrimitiveValue::CSS_RGBCOLOR) { - CSSParser::parseColor(rgba, colorValue->cssText()); - // Need to take care of named color such as green and black - // This code should be removed after https://bugs.webkit.org/show_bug.cgi?id=28282 is fixed. - } else - rgba = primitiveColor->getRGBA32Value(); - - return rgba; -} - -class StyleChange { -public: - StyleChange(EditingStyle*, const Position&); - - String cssStyle() const { return m_cssStyle; } - bool applyBold() const { return m_applyBold; } - bool applyItalic() const { return m_applyItalic; } - bool applyUnderline() const { return m_applyUnderline; } - bool applyLineThrough() const { return m_applyLineThrough; } - bool applySubscript() const { return m_applySubscript; } - bool applySuperscript() const { return m_applySuperscript; } - bool applyFontColor() const { return m_applyFontColor.length() > 0; } - bool applyFontFace() const { return m_applyFontFace.length() > 0; } - bool applyFontSize() const { return m_applyFontSize.length() > 0; } - - String fontColor() { return m_applyFontColor; } - String fontFace() { return m_applyFontFace; } - String fontSize() { return m_applyFontSize; } - - bool operator==(const StyleChange& other) - { - return m_cssStyle == other.m_cssStyle - && m_applyBold == other.m_applyBold - && m_applyItalic == other.m_applyItalic - && m_applyUnderline == other.m_applyUnderline - && m_applyLineThrough == other.m_applyLineThrough - && m_applySubscript == other.m_applySubscript - && m_applySuperscript == other.m_applySuperscript - && m_applyFontColor == other.m_applyFontColor - && m_applyFontFace == other.m_applyFontFace - && m_applyFontSize == other.m_applyFontSize; - } - bool operator!=(const StyleChange& other) - { - return !(*this == other); - } -private: - void init(EditingStyle*, const Position&); - void reconcileTextDecorationProperties(CSSMutableStyleDeclaration*); - void extractTextStyles(Document*, CSSMutableStyleDeclaration*, bool shouldUseFixedFontDefaultSize); - - String m_cssStyle; - bool m_applyBold; - bool m_applyItalic; - bool m_applyUnderline; - bool m_applyLineThrough; - bool m_applySubscript; - bool m_applySuperscript; - String m_applyFontColor; - String m_applyFontFace; - String m_applyFontSize; -}; - - -StyleChange::StyleChange(EditingStyle* style, const Position& position) - : m_applyBold(false) - , m_applyItalic(false) - , m_applyUnderline(false) - , m_applyLineThrough(false) - , m_applySubscript(false) - , m_applySuperscript(false) -{ - init(style, position); -} - -void StyleChange::init(EditingStyle* style, const Position& position) -{ - Document* document = position.anchorNode() ? position.anchorNode()->document() : 0; - if (!style || !style->style() || !document || !document->frame()) - return; - - RefPtr<CSSComputedStyleDeclaration> computedStyle = position.computedStyle(); - RefPtr<CSSMutableStyleDeclaration> mutableStyle = getPropertiesNotIn(style->style(), computedStyle.get()); - - reconcileTextDecorationProperties(mutableStyle.get()); - if (!document->frame()->editor()->shouldStyleWithCSS()) - extractTextStyles(document, mutableStyle.get(), computedStyle->useFixedFontDefaultSize()); - - // Changing the whitespace style in a tab span would collapse the tab into a space. - if (isTabSpanTextNode(position.deprecatedNode()) || isTabSpanNode((position.deprecatedNode()))) - 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 getPropertiesNotIn? - if (mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi) && !style->style()->getPropertyCSSValue(CSSPropertyDirection)) - mutableStyle->setProperty(CSSPropertyDirection, style->style()->getPropertyValue(CSSPropertyDirection)); - - // Save the result for later - m_cssStyle = mutableStyle->cssText().stripWhiteSpace(); -} - -void StyleChange::reconcileTextDecorationProperties(CSSMutableStyleDeclaration* style) -{ - RefPtr<CSSValue> textDecorationsInEffect = style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect); - RefPtr<CSSValue> textDecoration = style->getPropertyCSSValue(CSSPropertyTextDecoration); - // We shouldn't have both text-decoration and -webkit-text-decorations-in-effect because that wouldn't make sense. - ASSERT(!textDecorationsInEffect || !textDecoration); - if (textDecorationsInEffect) { - style->setProperty(CSSPropertyTextDecoration, textDecorationsInEffect->cssText()); - style->removeProperty(CSSPropertyWebkitTextDecorationsInEffect); - textDecoration = textDecorationsInEffect; - } - - // If text-decoration is set to "none", remove the property because we don't want to add redundant "text-decoration: none". - if (textDecoration && !textDecoration->isValueList()) - style->removeProperty(CSSPropertyTextDecoration); -} - -static int getIdentifierValue(CSSStyleDeclaration* style, int propertyID) -{ - if (!style) - return 0; - - RefPtr<CSSValue> value = style->getPropertyCSSValue(propertyID); - if (!value || !value->isPrimitiveValue()) - return 0; - - return static_cast<CSSPrimitiveValue*>(value.get())->getIdent(); -} - -static void setTextDecorationProperty(CSSMutableStyleDeclaration* style, const CSSValueList* newTextDecoration, int propertyID) -{ - if (newTextDecoration->length()) - style->setProperty(propertyID, newTextDecoration->cssText(), style->getPropertyPriority(propertyID)); - else { - // text-decoration: none is redundant since it does not remove any text decorations. - ASSERT(!style->getPropertyPriority(propertyID)); - style->removeProperty(propertyID); - } -} - -static bool isCSSValueLength(CSSPrimitiveValue* value) -{ - return value->primitiveType() >= CSSPrimitiveValue::CSS_PX && value->primitiveType() <= CSSPrimitiveValue::CSS_PC; -} - -int legacyFontSizeFromCSSValue(Document* document, CSSPrimitiveValue* value, bool shouldUseFixedFontDefaultSize, LegacyFontSizeMode mode) -{ - if (isCSSValueLength(value)) { - int pixelFontSize = value->getIntValue(CSSPrimitiveValue::CSS_PX); - int legacyFontSize = CSSStyleSelector::legacyFontSize(document, pixelFontSize, shouldUseFixedFontDefaultSize); - // Use legacy font size only if pixel value matches exactly to that of legacy font size. - int cssPrimitiveEquivalent = legacyFontSize - 1 + CSSValueXSmall; - if (mode == AlwaysUseLegacyFontSize || CSSStyleSelector::fontSizeForKeyword(document, cssPrimitiveEquivalent, shouldUseFixedFontDefaultSize) == pixelFontSize) - return legacyFontSize; - - return 0; - } - - if (CSSValueXSmall <= value->getIdent() && value->getIdent() <= CSSValueWebkitXxxLarge) - return value->getIdent() - CSSValueXSmall + 1; - - return 0; -} - -void StyleChange::extractTextStyles(Document* document, CSSMutableStyleDeclaration* style, bool shouldUseFixedFontDefaultSize) -{ - ASSERT(style); - - if (getIdentifierValue(style, CSSPropertyFontWeight) == CSSValueBold) { - style->removeProperty(CSSPropertyFontWeight); - m_applyBold = true; - } - - int fontStyle = getIdentifierValue(style, CSSPropertyFontStyle); - if (fontStyle == CSSValueItalic || fontStyle == CSSValueOblique) { - style->removeProperty(CSSPropertyFontStyle); - m_applyItalic = true; - } - - // 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. - 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))); - - RefPtr<CSSValueList> newTextDecoration = static_cast<CSSValueList*>(textDecoration.get())->copy(); - if (newTextDecoration->removeAll(underline.get())) - m_applyUnderline = true; - if (newTextDecoration->removeAll(lineThrough.get())) - m_applyLineThrough = true; - - // If trimTextDecorations, delete underline and line-through - setTextDecorationProperty(style, newTextDecoration.get(), CSSPropertyTextDecoration); - } - - int verticalAlign = getIdentifierValue(style, CSSPropertyVerticalAlign); - switch (verticalAlign) { - case CSSValueSub: - style->removeProperty(CSSPropertyVerticalAlign); - m_applySubscript = true; - break; - case CSSValueSuper: - style->removeProperty(CSSPropertyVerticalAlign); - m_applySuperscript = true; - break; - } - - if (style->getPropertyCSSValue(CSSPropertyColor)) { - m_applyFontColor = Color(getRGBAFontColor(style)).serialized(); - style->removeProperty(CSSPropertyColor); - } - - m_applyFontFace = style->getPropertyValue(CSSPropertyFontFamily); - style->removeProperty(CSSPropertyFontFamily); - - if (RefPtr<CSSValue> fontSize = style->getPropertyCSSValue(CSSPropertyFontSize)) { - if (!fontSize->isPrimitiveValue()) - style->removeProperty(CSSPropertyFontSize); // Can't make sense of the number. Put no font size. - else if (int legacyFontSize = legacyFontSizeFromCSSValue(document, static_cast<CSSPrimitiveValue*>(fontSize.get()), - shouldUseFixedFontDefaultSize, UseLegacyFontSizeOnlyIfPixelValuesMatch)) { - m_applyFontSize = String::number(legacyFontSize); - style->removeProperty(CSSPropertyFontSize); - } - } -} - static String& styleSpanClassString() { DEFINE_STATIC_LOCAL(String, styleSpanClassString, ((AppleStyleSpanClass))); @@ -354,95 +118,6 @@ PassRefPtr<HTMLElement> createStyleSpanElement(Document* document) return styleElement.release(); } -static void diffTextDecorations(CSSMutableStyleDeclaration* style, int propertID, CSSValue* refTextDecoration) -{ - RefPtr<CSSValue> textDecoration = style->getPropertyCSSValue(propertID); - if (!textDecoration || !textDecoration->isValueList() || !refTextDecoration || !refTextDecoration->isValueList()) - return; - - RefPtr<CSSValueList> newTextDecoration = static_cast<CSSValueList*>(textDecoration.get())->copy(); - CSSValueList* valuesInRefTextDecoration = static_cast<CSSValueList*>(refTextDecoration); - - for (size_t i = 0; i < valuesInRefTextDecoration->length(); i++) - newTextDecoration->removeAll(valuesInRefTextDecoration->item(i)); - - setTextDecorationProperty(style, newTextDecoration.get(), propertID); -} - -static bool fontWeightIsBold(CSSStyleDeclaration* style) -{ - ASSERT(style); - RefPtr<CSSValue> fontWeight = style->getPropertyCSSValue(CSSPropertyFontWeight); - - if (!fontWeight) - return false; - if (!fontWeight->isPrimitiveValue()) - return false; - - // Because b tag can only bold text, there are only two states in plain html: bold and not bold. - // Collapse all other values to either one of these two states for editing purposes. - switch (static_cast<CSSPrimitiveValue*>(fontWeight.get())->getIdent()) { - case CSSValue100: - case CSSValue200: - case CSSValue300: - case CSSValue400: - case CSSValue500: - case CSSValueNormal: - return false; - case CSSValueBold: - case CSSValue600: - case CSSValue700: - case CSSValue800: - case CSSValue900: - return true; - } - - ASSERT_NOT_REACHED(); // For CSSValueBolder and CSSValueLighter - return false; // Make compiler happy -} - -static int getTextAlignment(CSSStyleDeclaration* style) -{ - int textAlign = getIdentifierValue(style, CSSPropertyTextAlign); - switch (textAlign) { - case CSSValueCenter: - case CSSValueWebkitCenter: - return CSSValueCenter; - case CSSValueJustify: - return CSSValueJustify; - 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> baseTextDecorationsInEffect = baseStyle->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect); - diffTextDecorations(result.get(), CSSPropertyTextDecoration, baseTextDecorationsInEffect.get()); - diffTextDecorations(result.get(), CSSPropertyWebkitTextDecorationsInEffect, baseTextDecorationsInEffect.get()); - - if (fontWeightIsBold(result.get()) == fontWeightIsBold(baseStyle)) - result->removeProperty(CSSPropertyFontWeight); - - if (getRGBAFontColor(result.get()) == getRGBAFontColor(baseStyle)) - result->removeProperty(CSSPropertyColor); - - if (getTextAlignment(result.get()) == getTextAlignment(baseStyle)) - result->removeProperty(CSSPropertyTextAlign); - - return result; -} - ApplyStyleCommand::ApplyStyleCommand(Document* document, const EditingStyle* style, EditAction editingAction, EPropertyLevel propertyLevel) : CompositeEditCommand(document) , m_style(style->copy()) |