Changeset 83618 in webkit
- Timestamp:
- Apr 12, 2011 12:02:11 PM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r83615 r83618 1 2011-04-12 Ryosuke Niwa <rniwa@webkit.org> 2 3 Reviewed by Eric Seidel. 4 5 Move StyleChange and other global functions from ApplyStyleCommand to EditingStyle 6 https://bugs.webkit.org/show_bug.cgi?id=55974 7 8 Moved StyleChange, getIdentifierValue, and legacyFontSizeFromCSSValue from ApplyStyleCommand 9 to EditingStyle. Also moved reconcileTextDecorationProperties, getIdentifierValue, 10 setTextDecorationProperty, isCSSValueLength, legacyFontSizeFromCSSValue, extractTextStyles, 11 diffTextDecorations, fontWeightIsBold, getTextAlignment, and getPropertiesNotIn. 12 13 Because of this move, getPropertiesNotIn is no longer visible outside of EditingStyle.cpp 14 15 * editing/ApplyStyleCommand.cpp: 16 * editing/ApplyStyleCommand.h: 17 * editing/EditingStyle.cpp: 18 (WebCore::reconcileTextDecorationProperties): 19 (WebCore::StyleChange::StyleChange): 20 (WebCore::setTextDecorationProperty): 21 (WebCore::getRGBAFontColor): 22 (WebCore::StyleChange::extractTextStyles): 23 (WebCore::diffTextDecorations): 24 (WebCore::fontWeightIsBold): 25 (WebCore::getTextAlignment): 26 (WebCore::getPropertiesNotIn): 27 (WebCore::getIdentifierValue): 28 (WebCore::isCSSValueLength): 29 (WebCore::legacyFontSizeFromCSSValue): 30 * editing/EditingStyle.h: 31 (WebCore::StyleChange::cssStyle): 32 (WebCore::StyleChange::applyBold): 33 (WebCore::StyleChange::applyItalic): 34 (WebCore::StyleChange::applyUnderline): 35 (WebCore::StyleChange::applyLineThrough): 36 (WebCore::StyleChange::applySubscript): 37 (WebCore::StyleChange::applySuperscript): 38 (WebCore::StyleChange::applyFontColor): 39 (WebCore::StyleChange::applyFontFace): 40 (WebCore::StyleChange::applyFontSize): 41 (WebCore::StyleChange::fontColor): 42 (WebCore::StyleChange::fontFace): 43 (WebCore::StyleChange::fontSize): 44 (WebCore::StyleChange::operator==): 45 (WebCore::StyleChange::operator!=): 46 1 47 2011-04-12 Diego Gonzalez <diegohcg@webkit.org> 2 48 -
trunk/Source/WebCore/editing/ApplyStyleCommand.cpp
r82503 r83618 55 55 using namespace HTMLNames; 56 56 57 static RGBA32 getRGBAFontColor(CSSStyleDeclaration* style)58 {59 RefPtr<CSSValue> colorValue = style->getPropertyCSSValue(CSSPropertyColor);60 if (!colorValue || !colorValue->isPrimitiveValue())61 return Color::transparent;62 63 CSSPrimitiveValue* primitiveColor = static_cast<CSSPrimitiveValue*>(colorValue.get());64 RGBA32 rgba = 0;65 if (primitiveColor->primitiveType() != CSSPrimitiveValue::CSS_RGBCOLOR) {66 CSSParser::parseColor(rgba, colorValue->cssText());67 // Need to take care of named color such as green and black68 // This code should be removed after https://bugs.webkit.org/show_bug.cgi?id=28282 is fixed.69 } else70 rgba = primitiveColor->getRGBA32Value();71 72 return rgba;73 }74 75 class StyleChange {76 public:77 StyleChange(EditingStyle*, const Position&);78 79 String cssStyle() const { return m_cssStyle; }80 bool applyBold() const { return m_applyBold; }81 bool applyItalic() const { return m_applyItalic; }82 bool applyUnderline() const { return m_applyUnderline; }83 bool applyLineThrough() const { return m_applyLineThrough; }84 bool applySubscript() const { return m_applySubscript; }85 bool applySuperscript() const { return m_applySuperscript; }86 bool applyFontColor() const { return m_applyFontColor.length() > 0; }87 bool applyFontFace() const { return m_applyFontFace.length() > 0; }88 bool applyFontSize() const { return m_applyFontSize.length() > 0; }89 90 String fontColor() { return m_applyFontColor; }91 String fontFace() { return m_applyFontFace; }92 String fontSize() { return m_applyFontSize; }93 94 bool operator==(const StyleChange& other)95 {96 return m_cssStyle == other.m_cssStyle97 && m_applyBold == other.m_applyBold98 && m_applyItalic == other.m_applyItalic99 && m_applyUnderline == other.m_applyUnderline100 && m_applyLineThrough == other.m_applyLineThrough101 && m_applySubscript == other.m_applySubscript102 && m_applySuperscript == other.m_applySuperscript103 && m_applyFontColor == other.m_applyFontColor104 && m_applyFontFace == other.m_applyFontFace105 && m_applyFontSize == other.m_applyFontSize;106 }107 bool operator!=(const StyleChange& other)108 {109 return !(*this == other);110 }111 private:112 void init(EditingStyle*, const Position&);113 void reconcileTextDecorationProperties(CSSMutableStyleDeclaration*);114 void extractTextStyles(Document*, CSSMutableStyleDeclaration*, bool shouldUseFixedFontDefaultSize);115 116 String m_cssStyle;117 bool m_applyBold;118 bool m_applyItalic;119 bool m_applyUnderline;120 bool m_applyLineThrough;121 bool m_applySubscript;122 bool m_applySuperscript;123 String m_applyFontColor;124 String m_applyFontFace;125 String m_applyFontSize;126 };127 128 129 StyleChange::StyleChange(EditingStyle* style, const Position& position)130 : m_applyBold(false)131 , m_applyItalic(false)132 , m_applyUnderline(false)133 , m_applyLineThrough(false)134 , m_applySubscript(false)135 , m_applySuperscript(false)136 {137 init(style, position);138 }139 140 void StyleChange::init(EditingStyle* style, const Position& position)141 {142 Document* document = position.anchorNode() ? position.anchorNode()->document() : 0;143 if (!style || !style->style() || !document || !document->frame())144 return;145 146 RefPtr<CSSComputedStyleDeclaration> computedStyle = position.computedStyle();147 RefPtr<CSSMutableStyleDeclaration> mutableStyle = getPropertiesNotIn(style->style(), computedStyle.get());148 149 reconcileTextDecorationProperties(mutableStyle.get());150 if (!document->frame()->editor()->shouldStyleWithCSS())151 extractTextStyles(document, mutableStyle.get(), computedStyle->useFixedFontDefaultSize());152 153 // Changing the whitespace style in a tab span would collapse the tab into a space.154 if (isTabSpanTextNode(position.deprecatedNode()) || isTabSpanNode((position.deprecatedNode())))155 mutableStyle->removeProperty(CSSPropertyWhiteSpace);156 157 // If unicode-bidi is present in mutableStyle and direction is not, then add direction to mutableStyle.158 // FIXME: Shouldn't this be done in getPropertiesNotIn?159 if (mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi) && !style->style()->getPropertyCSSValue(CSSPropertyDirection))160 mutableStyle->setProperty(CSSPropertyDirection, style->style()->getPropertyValue(CSSPropertyDirection));161 162 // Save the result for later163 m_cssStyle = mutableStyle->cssText().stripWhiteSpace();164 }165 166 void StyleChange::reconcileTextDecorationProperties(CSSMutableStyleDeclaration* style)167 {168 RefPtr<CSSValue> textDecorationsInEffect = style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);169 RefPtr<CSSValue> textDecoration = style->getPropertyCSSValue(CSSPropertyTextDecoration);170 // We shouldn't have both text-decoration and -webkit-text-decorations-in-effect because that wouldn't make sense.171 ASSERT(!textDecorationsInEffect || !textDecoration);172 if (textDecorationsInEffect) {173 style->setProperty(CSSPropertyTextDecoration, textDecorationsInEffect->cssText());174 style->removeProperty(CSSPropertyWebkitTextDecorationsInEffect);175 textDecoration = textDecorationsInEffect;176 }177 178 // If text-decoration is set to "none", remove the property because we don't want to add redundant "text-decoration: none".179 if (textDecoration && !textDecoration->isValueList())180 style->removeProperty(CSSPropertyTextDecoration);181 }182 183 static int getIdentifierValue(CSSStyleDeclaration* style, int propertyID)184 {185 if (!style)186 return 0;187 188 RefPtr<CSSValue> value = style->getPropertyCSSValue(propertyID);189 if (!value || !value->isPrimitiveValue())190 return 0;191 192 return static_cast<CSSPrimitiveValue*>(value.get())->getIdent();193 }194 195 static void setTextDecorationProperty(CSSMutableStyleDeclaration* style, const CSSValueList* newTextDecoration, int propertyID)196 {197 if (newTextDecoration->length())198 style->setProperty(propertyID, newTextDecoration->cssText(), style->getPropertyPriority(propertyID));199 else {200 // text-decoration: none is redundant since it does not remove any text decorations.201 ASSERT(!style->getPropertyPriority(propertyID));202 style->removeProperty(propertyID);203 }204 }205 206 static bool isCSSValueLength(CSSPrimitiveValue* value)207 {208 return value->primitiveType() >= CSSPrimitiveValue::CSS_PX && value->primitiveType() <= CSSPrimitiveValue::CSS_PC;209 }210 211 int legacyFontSizeFromCSSValue(Document* document, CSSPrimitiveValue* value, bool shouldUseFixedFontDefaultSize, LegacyFontSizeMode mode)212 {213 if (isCSSValueLength(value)) {214 int pixelFontSize = value->getIntValue(CSSPrimitiveValue::CSS_PX);215 int legacyFontSize = CSSStyleSelector::legacyFontSize(document, pixelFontSize, shouldUseFixedFontDefaultSize);216 // Use legacy font size only if pixel value matches exactly to that of legacy font size.217 int cssPrimitiveEquivalent = legacyFontSize - 1 + CSSValueXSmall;218 if (mode == AlwaysUseLegacyFontSize || CSSStyleSelector::fontSizeForKeyword(document, cssPrimitiveEquivalent, shouldUseFixedFontDefaultSize) == pixelFontSize)219 return legacyFontSize;220 221 return 0;222 }223 224 if (CSSValueXSmall <= value->getIdent() && value->getIdent() <= CSSValueWebkitXxxLarge)225 return value->getIdent() - CSSValueXSmall + 1;226 227 return 0;228 }229 230 void StyleChange::extractTextStyles(Document* document, CSSMutableStyleDeclaration* style, bool shouldUseFixedFontDefaultSize)231 {232 ASSERT(style);233 234 if (getIdentifierValue(style, CSSPropertyFontWeight) == CSSValueBold) {235 style->removeProperty(CSSPropertyFontWeight);236 m_applyBold = true;237 }238 239 int fontStyle = getIdentifierValue(style, CSSPropertyFontStyle);240 if (fontStyle == CSSValueItalic || fontStyle == CSSValueOblique) {241 style->removeProperty(CSSPropertyFontStyle);242 m_applyItalic = true;243 }244 245 // Assuming reconcileTextDecorationProperties has been called, there should not be -webkit-text-decorations-in-effect246 // Furthermore, text-decoration: none has been trimmed so that text-decoration property is always a CSSValueList.247 RefPtr<CSSValue> textDecoration = style->getPropertyCSSValue(CSSPropertyTextDecoration);248 if (textDecoration && textDecoration->isValueList()) {249 DEFINE_STATIC_LOCAL(RefPtr<CSSPrimitiveValue>, underline, (CSSPrimitiveValue::createIdentifier(CSSValueUnderline)));250 DEFINE_STATIC_LOCAL(RefPtr<CSSPrimitiveValue>, lineThrough, (CSSPrimitiveValue::createIdentifier(CSSValueLineThrough)));251 252 RefPtr<CSSValueList> newTextDecoration = static_cast<CSSValueList*>(textDecoration.get())->copy();253 if (newTextDecoration->removeAll(underline.get()))254 m_applyUnderline = true;255 if (newTextDecoration->removeAll(lineThrough.get()))256 m_applyLineThrough = true;257 258 // If trimTextDecorations, delete underline and line-through259 setTextDecorationProperty(style, newTextDecoration.get(), CSSPropertyTextDecoration);260 }261 262 int verticalAlign = getIdentifierValue(style, CSSPropertyVerticalAlign);263 switch (verticalAlign) {264 case CSSValueSub:265 style->removeProperty(CSSPropertyVerticalAlign);266 m_applySubscript = true;267 break;268 case CSSValueSuper:269 style->removeProperty(CSSPropertyVerticalAlign);270 m_applySuperscript = true;271 break;272 }273 274 if (style->getPropertyCSSValue(CSSPropertyColor)) {275 m_applyFontColor = Color(getRGBAFontColor(style)).serialized();276 style->removeProperty(CSSPropertyColor);277 }278 279 m_applyFontFace = style->getPropertyValue(CSSPropertyFontFamily);280 style->removeProperty(CSSPropertyFontFamily);281 282 if (RefPtr<CSSValue> fontSize = style->getPropertyCSSValue(CSSPropertyFontSize)) {283 if (!fontSize->isPrimitiveValue())284 style->removeProperty(CSSPropertyFontSize); // Can't make sense of the number. Put no font size.285 else if (int legacyFontSize = legacyFontSizeFromCSSValue(document, static_cast<CSSPrimitiveValue*>(fontSize.get()),286 shouldUseFixedFontDefaultSize, UseLegacyFontSizeOnlyIfPixelValuesMatch)) {287 m_applyFontSize = String::number(legacyFontSize);288 style->removeProperty(CSSPropertyFontSize);289 }290 }291 }292 293 57 static String& styleSpanClassString() 294 58 { … … 353 117 styleElement->setAttribute(classAttr, styleSpanClassString()); 354 118 return styleElement.release(); 355 }356 357 static void diffTextDecorations(CSSMutableStyleDeclaration* style, int propertID, CSSValue* refTextDecoration)358 {359 RefPtr<CSSValue> textDecoration = style->getPropertyCSSValue(propertID);360 if (!textDecoration || !textDecoration->isValueList() || !refTextDecoration || !refTextDecoration->isValueList())361 return;362 363 RefPtr<CSSValueList> newTextDecoration = static_cast<CSSValueList*>(textDecoration.get())->copy();364 CSSValueList* valuesInRefTextDecoration = static_cast<CSSValueList*>(refTextDecoration);365 366 for (size_t i = 0; i < valuesInRefTextDecoration->length(); i++)367 newTextDecoration->removeAll(valuesInRefTextDecoration->item(i));368 369 setTextDecorationProperty(style, newTextDecoration.get(), propertID);370 }371 372 static bool fontWeightIsBold(CSSStyleDeclaration* style)373 {374 ASSERT(style);375 RefPtr<CSSValue> fontWeight = style->getPropertyCSSValue(CSSPropertyFontWeight);376 377 if (!fontWeight)378 return false;379 if (!fontWeight->isPrimitiveValue())380 return false;381 382 // Because b tag can only bold text, there are only two states in plain html: bold and not bold.383 // Collapse all other values to either one of these two states for editing purposes.384 switch (static_cast<CSSPrimitiveValue*>(fontWeight.get())->getIdent()) {385 case CSSValue100:386 case CSSValue200:387 case CSSValue300:388 case CSSValue400:389 case CSSValue500:390 case CSSValueNormal:391 return false;392 case CSSValueBold:393 case CSSValue600:394 case CSSValue700:395 case CSSValue800:396 case CSSValue900:397 return true;398 }399 400 ASSERT_NOT_REACHED(); // For CSSValueBolder and CSSValueLighter401 return false; // Make compiler happy402 }403 404 static int getTextAlignment(CSSStyleDeclaration* style)405 {406 int textAlign = getIdentifierValue(style, CSSPropertyTextAlign);407 switch (textAlign) {408 case CSSValueCenter:409 case CSSValueWebkitCenter:410 return CSSValueCenter;411 case CSSValueJustify:412 return CSSValueJustify;413 case CSSValueLeft:414 case CSSValueWebkitLeft:415 return CSSValueLeft;416 case CSSValueRight:417 case CSSValueWebkitRight:418 return CSSValueRight;419 }420 return CSSValueInvalid;421 }422 423 RefPtr<CSSMutableStyleDeclaration> getPropertiesNotIn(CSSStyleDeclaration* styleWithRedundantProperties, CSSStyleDeclaration* baseStyle)424 {425 ASSERT(styleWithRedundantProperties);426 ASSERT(baseStyle);427 RefPtr<CSSMutableStyleDeclaration> result = styleWithRedundantProperties->copy();428 baseStyle->diff(result.get());429 430 RefPtr<CSSValue> baseTextDecorationsInEffect = baseStyle->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);431 diffTextDecorations(result.get(), CSSPropertyTextDecoration, baseTextDecorationsInEffect.get());432 diffTextDecorations(result.get(), CSSPropertyWebkitTextDecorationsInEffect, baseTextDecorationsInEffect.get());433 434 if (fontWeightIsBold(result.get()) == fontWeightIsBold(baseStyle))435 result->removeProperty(CSSPropertyFontWeight);436 437 if (getRGBAFontColor(result.get()) == getRGBAFontColor(baseStyle))438 result->removeProperty(CSSPropertyColor);439 440 if (getTextAlignment(result.get()) == getTextAlignment(baseStyle))441 result->removeProperty(CSSPropertyTextAlign);442 443 return result;444 119 } 445 120 -
trunk/Source/WebCore/editing/ApplyStyleCommand.h
r80580 r83618 35 35 class CSSPrimitiveValue; 36 36 class EditingStyle; 37 class HTMLElement;38 37 class StyleChange; 39 38 … … 131 130 }; 132 131 133 enum LegacyFontSizeMode { AlwaysUseLegacyFontSize, UseLegacyFontSizeOnlyIfPixelValuesMatch };134 int legacyFontSizeFromCSSValue(Document*, CSSPrimitiveValue*, bool shouldUseFixedFontDefaultSize, LegacyFontSizeMode);135 132 bool isStyleSpan(const Node*); 136 133 PassRefPtr<HTMLElement> createStyleSpanElement(Document*); 137 RefPtr<CSSMutableStyleDeclaration> getPropertiesNotIn(CSSStyleDeclaration* styleWithRedundantProperties, CSSStyleDeclaration* baseStyle);138 134 139 135 } // namespace WebCore -
trunk/Source/WebCore/editing/EditingStyle.cpp
r83247 r83618 31 31 #include "CSSComputedStyleDeclaration.h" 32 32 #include "CSSMutableStyleDeclaration.h" 33 #include "CSSParser.h" 34 #include "CSSStyleSelector.h" 33 35 #include "CSSValueKeywords.h" 34 36 #include "CSSValueList.h" … … 88 90 } 89 91 92 static RefPtr<CSSMutableStyleDeclaration> getPropertiesNotIn(CSSStyleDeclaration* styleWithRedundantProperties, CSSStyleDeclaration* baseStyle); 93 90 94 class HTMLElementEquivalent { 91 95 public: … … 774 778 } 775 779 776 } 780 static void reconcileTextDecorationProperties(CSSMutableStyleDeclaration* style) 781 { 782 RefPtr<CSSValue> textDecorationsInEffect = style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect); 783 RefPtr<CSSValue> textDecoration = style->getPropertyCSSValue(CSSPropertyTextDecoration); 784 // We shouldn't have both text-decoration and -webkit-text-decorations-in-effect because that wouldn't make sense. 785 ASSERT(!textDecorationsInEffect || !textDecoration); 786 if (textDecorationsInEffect) { 787 style->setProperty(CSSPropertyTextDecoration, textDecorationsInEffect->cssText()); 788 style->removeProperty(CSSPropertyWebkitTextDecorationsInEffect); 789 textDecoration = textDecorationsInEffect; 790 } 791 792 // If text-decoration is set to "none", remove the property because we don't want to add redundant "text-decoration: none". 793 if (textDecoration && !textDecoration->isValueList()) 794 style->removeProperty(CSSPropertyTextDecoration); 795 } 796 797 StyleChange::StyleChange(EditingStyle* style, const Position& position) 798 : m_applyBold(false) 799 , m_applyItalic(false) 800 , m_applyUnderline(false) 801 , m_applyLineThrough(false) 802 , m_applySubscript(false) 803 , m_applySuperscript(false) 804 { 805 Document* document = position.anchorNode() ? position.anchorNode()->document() : 0; 806 if (!style || !style->style() || !document || !document->frame()) 807 return; 808 809 RefPtr<CSSComputedStyleDeclaration> computedStyle = position.computedStyle(); 810 RefPtr<CSSMutableStyleDeclaration> mutableStyle = getPropertiesNotIn(style->style(), computedStyle.get()); 811 812 reconcileTextDecorationProperties(mutableStyle.get()); 813 if (!document->frame()->editor()->shouldStyleWithCSS()) 814 extractTextStyles(document, mutableStyle.get(), computedStyle->useFixedFontDefaultSize()); 815 816 // Changing the whitespace style in a tab span would collapse the tab into a space. 817 if (isTabSpanTextNode(position.deprecatedNode()) || isTabSpanNode((position.deprecatedNode()))) 818 mutableStyle->removeProperty(CSSPropertyWhiteSpace); 819 820 // If unicode-bidi is present in mutableStyle and direction is not, then add direction to mutableStyle. 821 // FIXME: Shouldn't this be done in getPropertiesNotIn? 822 if (mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi) && !style->style()->getPropertyCSSValue(CSSPropertyDirection)) 823 mutableStyle->setProperty(CSSPropertyDirection, style->style()->getPropertyValue(CSSPropertyDirection)); 824 825 // Save the result for later 826 m_cssStyle = mutableStyle->cssText().stripWhiteSpace(); 827 } 828 829 static void setTextDecorationProperty(CSSMutableStyleDeclaration* style, const CSSValueList* newTextDecoration, int propertyID) 830 { 831 if (newTextDecoration->length()) 832 style->setProperty(propertyID, newTextDecoration->cssText(), style->getPropertyPriority(propertyID)); 833 else { 834 // text-decoration: none is redundant since it does not remove any text decorations. 835 ASSERT(!style->getPropertyPriority(propertyID)); 836 style->removeProperty(propertyID); 837 } 838 } 839 840 static RGBA32 getRGBAFontColor(CSSStyleDeclaration* style) 841 { 842 RefPtr<CSSValue> colorValue = style->getPropertyCSSValue(CSSPropertyColor); 843 if (!colorValue || !colorValue->isPrimitiveValue()) 844 return Color::transparent; 845 846 CSSPrimitiveValue* primitiveColor = static_cast<CSSPrimitiveValue*>(colorValue.get()); 847 if (primitiveColor->primitiveType() == CSSPrimitiveValue::CSS_RGBCOLOR) 848 return primitiveColor->getRGBA32Value(); 849 850 // Need to take care of named color such as green and black 851 // This code should be removed after https://bugs.webkit.org/show_bug.cgi?id=28282 is fixed. 852 RGBA32 rgba = 0; 853 CSSParser::parseColor(rgba, colorValue->cssText()); 854 return rgba; 855 } 856 857 void StyleChange::extractTextStyles(Document* document, CSSMutableStyleDeclaration* style, bool shouldUseFixedFontDefaultSize) 858 { 859 ASSERT(style); 860 861 if (getIdentifierValue(style, CSSPropertyFontWeight) == CSSValueBold) { 862 style->removeProperty(CSSPropertyFontWeight); 863 m_applyBold = true; 864 } 865 866 int fontStyle = getIdentifierValue(style, CSSPropertyFontStyle); 867 if (fontStyle == CSSValueItalic || fontStyle == CSSValueOblique) { 868 style->removeProperty(CSSPropertyFontStyle); 869 m_applyItalic = true; 870 } 871 872 // Assuming reconcileTextDecorationProperties has been called, there should not be -webkit-text-decorations-in-effect 873 // Furthermore, text-decoration: none has been trimmed so that text-decoration property is always a CSSValueList. 874 RefPtr<CSSValue> textDecoration = style->getPropertyCSSValue(CSSPropertyTextDecoration); 875 if (textDecoration && textDecoration->isValueList()) { 876 DEFINE_STATIC_LOCAL(RefPtr<CSSPrimitiveValue>, underline, (CSSPrimitiveValue::createIdentifier(CSSValueUnderline))); 877 DEFINE_STATIC_LOCAL(RefPtr<CSSPrimitiveValue>, lineThrough, (CSSPrimitiveValue::createIdentifier(CSSValueLineThrough))); 878 879 RefPtr<CSSValueList> newTextDecoration = static_cast<CSSValueList*>(textDecoration.get())->copy(); 880 if (newTextDecoration->removeAll(underline.get())) 881 m_applyUnderline = true; 882 if (newTextDecoration->removeAll(lineThrough.get())) 883 m_applyLineThrough = true; 884 885 // If trimTextDecorations, delete underline and line-through 886 setTextDecorationProperty(style, newTextDecoration.get(), CSSPropertyTextDecoration); 887 } 888 889 int verticalAlign = getIdentifierValue(style, CSSPropertyVerticalAlign); 890 switch (verticalAlign) { 891 case CSSValueSub: 892 style->removeProperty(CSSPropertyVerticalAlign); 893 m_applySubscript = true; 894 break; 895 case CSSValueSuper: 896 style->removeProperty(CSSPropertyVerticalAlign); 897 m_applySuperscript = true; 898 break; 899 } 900 901 if (style->getPropertyCSSValue(CSSPropertyColor)) { 902 m_applyFontColor = Color(getRGBAFontColor(style)).serialized(); 903 style->removeProperty(CSSPropertyColor); 904 } 905 906 m_applyFontFace = style->getPropertyValue(CSSPropertyFontFamily); 907 style->removeProperty(CSSPropertyFontFamily); 908 909 if (RefPtr<CSSValue> fontSize = style->getPropertyCSSValue(CSSPropertyFontSize)) { 910 if (!fontSize->isPrimitiveValue()) 911 style->removeProperty(CSSPropertyFontSize); // Can't make sense of the number. Put no font size. 912 else if (int legacyFontSize = legacyFontSizeFromCSSValue(document, static_cast<CSSPrimitiveValue*>(fontSize.get()), 913 shouldUseFixedFontDefaultSize, UseLegacyFontSizeOnlyIfPixelValuesMatch)) { 914 m_applyFontSize = String::number(legacyFontSize); 915 style->removeProperty(CSSPropertyFontSize); 916 } 917 } 918 } 919 920 static void diffTextDecorations(CSSMutableStyleDeclaration* style, int propertID, CSSValue* refTextDecoration) 921 { 922 RefPtr<CSSValue> textDecoration = style->getPropertyCSSValue(propertID); 923 if (!textDecoration || !textDecoration->isValueList() || !refTextDecoration || !refTextDecoration->isValueList()) 924 return; 925 926 RefPtr<CSSValueList> newTextDecoration = static_cast<CSSValueList*>(textDecoration.get())->copy(); 927 CSSValueList* valuesInRefTextDecoration = static_cast<CSSValueList*>(refTextDecoration); 928 929 for (size_t i = 0; i < valuesInRefTextDecoration->length(); i++) 930 newTextDecoration->removeAll(valuesInRefTextDecoration->item(i)); 931 932 setTextDecorationProperty(style, newTextDecoration.get(), propertID); 933 } 934 935 static bool fontWeightIsBold(CSSStyleDeclaration* style) 936 { 937 ASSERT(style); 938 RefPtr<CSSValue> fontWeight = style->getPropertyCSSValue(CSSPropertyFontWeight); 939 940 if (!fontWeight) 941 return false; 942 if (!fontWeight->isPrimitiveValue()) 943 return false; 944 945 // Because b tag can only bold text, there are only two states in plain html: bold and not bold. 946 // Collapse all other values to either one of these two states for editing purposes. 947 switch (static_cast<CSSPrimitiveValue*>(fontWeight.get())->getIdent()) { 948 case CSSValue100: 949 case CSSValue200: 950 case CSSValue300: 951 case CSSValue400: 952 case CSSValue500: 953 case CSSValueNormal: 954 return false; 955 case CSSValueBold: 956 case CSSValue600: 957 case CSSValue700: 958 case CSSValue800: 959 case CSSValue900: 960 return true; 961 } 962 963 ASSERT_NOT_REACHED(); // For CSSValueBolder and CSSValueLighter 964 return false; // Make compiler happy 965 } 966 967 static int getTextAlignment(CSSStyleDeclaration* style) 968 { 969 int textAlign = getIdentifierValue(style, CSSPropertyTextAlign); 970 switch (textAlign) { 971 case CSSValueCenter: 972 case CSSValueWebkitCenter: 973 return CSSValueCenter; 974 case CSSValueJustify: 975 return CSSValueJustify; 976 case CSSValueLeft: 977 case CSSValueWebkitLeft: 978 return CSSValueLeft; 979 case CSSValueRight: 980 case CSSValueWebkitRight: 981 return CSSValueRight; 982 } 983 return CSSValueInvalid; 984 } 985 986 RefPtr<CSSMutableStyleDeclaration> getPropertiesNotIn(CSSStyleDeclaration* styleWithRedundantProperties, CSSStyleDeclaration* baseStyle) 987 { 988 ASSERT(styleWithRedundantProperties); 989 ASSERT(baseStyle); 990 RefPtr<CSSMutableStyleDeclaration> result = styleWithRedundantProperties->copy(); 991 baseStyle->diff(result.get()); 992 993 RefPtr<CSSValue> baseTextDecorationsInEffect = baseStyle->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect); 994 diffTextDecorations(result.get(), CSSPropertyTextDecoration, baseTextDecorationsInEffect.get()); 995 diffTextDecorations(result.get(), CSSPropertyWebkitTextDecorationsInEffect, baseTextDecorationsInEffect.get()); 996 997 if (fontWeightIsBold(result.get()) == fontWeightIsBold(baseStyle)) 998 result->removeProperty(CSSPropertyFontWeight); 999 1000 if (getRGBAFontColor(result.get()) == getRGBAFontColor(baseStyle)) 1001 result->removeProperty(CSSPropertyColor); 1002 1003 if (getTextAlignment(result.get()) == getTextAlignment(baseStyle)) 1004 result->removeProperty(CSSPropertyTextAlign); 1005 1006 return result; 1007 } 1008 1009 1010 int getIdentifierValue(CSSStyleDeclaration* style, int propertyID) 1011 { 1012 if (!style) 1013 return 0; 1014 1015 RefPtr<CSSValue> value = style->getPropertyCSSValue(propertyID); 1016 if (!value || !value->isPrimitiveValue()) 1017 return 0; 1018 1019 return static_cast<CSSPrimitiveValue*>(value.get())->getIdent(); 1020 } 1021 1022 static bool isCSSValueLength(CSSPrimitiveValue* value) 1023 { 1024 return value->primitiveType() >= CSSPrimitiveValue::CSS_PX && value->primitiveType() <= CSSPrimitiveValue::CSS_PC; 1025 } 1026 1027 int legacyFontSizeFromCSSValue(Document* document, CSSPrimitiveValue* value, bool shouldUseFixedFontDefaultSize, LegacyFontSizeMode mode) 1028 { 1029 if (isCSSValueLength(value)) { 1030 int pixelFontSize = value->getIntValue(CSSPrimitiveValue::CSS_PX); 1031 int legacyFontSize = CSSStyleSelector::legacyFontSize(document, pixelFontSize, shouldUseFixedFontDefaultSize); 1032 // Use legacy font size only if pixel value matches exactly to that of legacy font size. 1033 int cssPrimitiveEquivalent = legacyFontSize - 1 + CSSValueXSmall; 1034 if (mode == AlwaysUseLegacyFontSize || CSSStyleSelector::fontSizeForKeyword(document, cssPrimitiveEquivalent, shouldUseFixedFontDefaultSize) == pixelFontSize) 1035 return legacyFontSize; 1036 1037 return 0; 1038 } 1039 1040 if (CSSValueXSmall <= value->getIdent() && value->getIdent() <= CSSValueWebkitXxxLarge) 1041 return value->getIdent() - CSSValueXSmall + 1; 1042 1043 return 0; 1044 } 1045 1046 } -
trunk/Source/WebCore/editing/EditingStyle.h
r80580 r83618 33 33 34 34 #include "CSSPropertyNames.h" 35 #include "PlatformString.h" 35 36 #include "WritingDirection.h" 36 37 #include <wtf/Forward.h> … … 44 45 class CSSComputedStyleDeclaration; 45 46 class CSSMutableStyleDeclaration; 47 class CSSPrimitiveValue; 46 48 class Document; 47 49 class HTMLElement; … … 145 147 }; 146 148 149 class StyleChange { 150 public: 151 StyleChange(EditingStyle*, const Position&); 152 153 String cssStyle() const { return m_cssStyle; } 154 bool applyBold() const { return m_applyBold; } 155 bool applyItalic() const { return m_applyItalic; } 156 bool applyUnderline() const { return m_applyUnderline; } 157 bool applyLineThrough() const { return m_applyLineThrough; } 158 bool applySubscript() const { return m_applySubscript; } 159 bool applySuperscript() const { return m_applySuperscript; } 160 bool applyFontColor() const { return m_applyFontColor.length() > 0; } 161 bool applyFontFace() const { return m_applyFontFace.length() > 0; } 162 bool applyFontSize() const { return m_applyFontSize.length() > 0; } 163 164 String fontColor() { return m_applyFontColor; } 165 String fontFace() { return m_applyFontFace; } 166 String fontSize() { return m_applyFontSize; } 167 168 bool operator==(const StyleChange& other) 169 { 170 return m_cssStyle == other.m_cssStyle 171 && m_applyBold == other.m_applyBold 172 && m_applyItalic == other.m_applyItalic 173 && m_applyUnderline == other.m_applyUnderline 174 && m_applyLineThrough == other.m_applyLineThrough 175 && m_applySubscript == other.m_applySubscript 176 && m_applySuperscript == other.m_applySuperscript 177 && m_applyFontColor == other.m_applyFontColor 178 && m_applyFontFace == other.m_applyFontFace 179 && m_applyFontSize == other.m_applyFontSize; 180 } 181 bool operator!=(const StyleChange& other) 182 { 183 return !(*this == other); 184 } 185 private: 186 void extractTextStyles(Document*, CSSMutableStyleDeclaration*, bool shouldUseFixedFontDefaultSize); 187 188 String m_cssStyle; 189 bool m_applyBold; 190 bool m_applyItalic; 191 bool m_applyUnderline; 192 bool m_applyLineThrough; 193 bool m_applySubscript; 194 bool m_applySuperscript; 195 String m_applyFontColor; 196 String m_applyFontFace; 197 String m_applyFontSize; 198 }; 199 200 // FIXME: Remove these functions or make them non-global to discourage using CSSStyleDeclaration directly. 201 int getIdentifierValue(CSSStyleDeclaration*, int propertyID); 202 enum LegacyFontSizeMode { AlwaysUseLegacyFontSize, UseLegacyFontSizeOnlyIfPixelValuesMatch }; 203 int legacyFontSizeFromCSSValue(Document*, CSSPrimitiveValue*, bool shouldUseFixedFontDefaultSize, LegacyFontSizeMode); 204 147 205 } // namespace WebCore 148 206
Note: See TracChangeset
for help on using the changeset viewer.