1 /* 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef EditingStyle_h 32 #define EditingStyle_h 33 34 #include "CSSPropertyNames.h" 35 #include "PlatformString.h" 36 #include "WritingDirection.h" 37 #include <wtf/Forward.h> 38 #include <wtf/RefCounted.h> 39 #include <wtf/RefPtr.h> 40 #include <wtf/Vector.h> 41 42 namespace WebCore { 43 44 class CSSStyleDeclaration; 45 class CSSComputedStyleDeclaration; 46 class CSSMutableStyleDeclaration; 47 class CSSPrimitiveValue; 48 class CSSValue; 49 class Document; 50 class HTMLElement; 51 class Node; 52 class Position; 53 class QualifiedName; 54 class RenderStyle; 55 class StyledElement; 56 57 enum TriState { FalseTriState, TrueTriState, MixedTriState }; 58 59 class EditingStyle : public RefCounted<EditingStyle> { 60 public: 61 62 enum PropertiesToInclude { AllProperties, OnlyInheritableProperties, InheritablePropertiesAndBackgroundColorInEffect }; 63 enum ShouldPreserveWritingDirection { PreserveWritingDirection, DoNotPreserveWritingDirection }; 64 enum ShouldExtractMatchingStyle { ExtractMatchingStyle, DoNotExtractMatchingStyle }; 65 static float NoFontDelta; 66 create()67 static PassRefPtr<EditingStyle> create() 68 { 69 return adoptRef(new EditingStyle()); 70 } 71 72 static PassRefPtr<EditingStyle> create(Node* node, PropertiesToInclude propertiesToInclude = OnlyInheritableProperties) 73 { 74 return adoptRef(new EditingStyle(node, propertiesToInclude)); 75 } 76 77 static PassRefPtr<EditingStyle> create(const Position& position, PropertiesToInclude propertiesToInclude = OnlyInheritableProperties) 78 { 79 return adoptRef(new EditingStyle(position, propertiesToInclude)); 80 } 81 create(const CSSStyleDeclaration * style)82 static PassRefPtr<EditingStyle> create(const CSSStyleDeclaration* style) 83 { 84 return adoptRef(new EditingStyle(style)); 85 } 86 create(int propertyID,const String & value)87 static PassRefPtr<EditingStyle> create(int propertyID, const String& value) 88 { 89 return adoptRef(new EditingStyle(propertyID, value)); 90 } 91 92 ~EditingStyle(); 93 style()94 CSSMutableStyleDeclaration* style() { return m_mutableStyle.get(); } 95 bool textDirection(WritingDirection&) const; 96 bool isEmpty() const; 97 void setStyle(PassRefPtr<CSSMutableStyleDeclaration>); 98 void overrideWithStyle(const CSSMutableStyleDeclaration*); 99 void clear(); 100 PassRefPtr<EditingStyle> copy() const; 101 PassRefPtr<EditingStyle> extractAndRemoveBlockProperties(); 102 PassRefPtr<EditingStyle> extractAndRemoveTextDirection(); 103 void removeBlockProperties(); 104 void removeStyleAddedByNode(Node*); 105 void removeStyleConflictingWithStyleOfNode(Node*); 106 void removeNonEditingProperties(); 107 void collapseTextDecorationProperties(); 108 enum ShouldIgnoreTextOnlyProperties { IgnoreTextOnlyProperties, DoNotIgnoreTextOnlyProperties }; 109 TriState triStateOfStyle(CSSStyleDeclaration*, ShouldIgnoreTextOnlyProperties = DoNotIgnoreTextOnlyProperties) const; conflictsWithInlineStyleOfElement(StyledElement * element)110 bool conflictsWithInlineStyleOfElement(StyledElement* element) const { return conflictsWithInlineStyleOfElement(element, 0, 0); } conflictsWithInlineStyleOfElement(StyledElement * element,EditingStyle * extractedStyle,Vector<CSSPropertyID> & conflictingProperties)111 bool conflictsWithInlineStyleOfElement(StyledElement* element, EditingStyle* extractedStyle, Vector<CSSPropertyID>& conflictingProperties) const 112 { 113 return conflictsWithInlineStyleOfElement(element, extractedStyle, &conflictingProperties); 114 } 115 bool conflictsWithImplicitStyleOfElement(HTMLElement*, EditingStyle* extractedStyle = 0, ShouldExtractMatchingStyle = DoNotExtractMatchingStyle) const; 116 bool conflictsWithImplicitStyleOfAttributes(HTMLElement*) const; 117 bool extractConflictingImplicitStyleOfAttributes(HTMLElement*, ShouldPreserveWritingDirection, EditingStyle* extractedStyle, 118 Vector<QualifiedName>& conflictingAttributes, ShouldExtractMatchingStyle) const; 119 bool styleIsPresentInComputedStyleOfNode(Node*) const; 120 void prepareToApplyAt(const Position&, ShouldPreserveWritingDirection = DoNotPreserveWritingDirection); 121 void mergeTypingStyle(Document*); 122 void mergeInlineStyleOfElement(StyledElement*); 123 fontSizeDelta()124 float fontSizeDelta() const { return m_fontSizeDelta; } hasFontSizeDelta()125 bool hasFontSizeDelta() const { return m_fontSizeDelta != NoFontDelta; } shouldUseFixedDefaultFontSize()126 bool shouldUseFixedDefaultFontSize() const { return m_shouldUseFixedDefaultFontSize; } 127 128 private: 129 EditingStyle(); 130 EditingStyle(Node*, PropertiesToInclude); 131 EditingStyle(const Position&, PropertiesToInclude); 132 EditingStyle(const CSSStyleDeclaration*); 133 EditingStyle(int propertyID, const String& value); 134 void init(Node*, PropertiesToInclude); 135 void removeTextFillAndStrokeColorsIfNeeded(RenderStyle*); 136 void setProperty(int propertyID, const String& value, bool important = false); 137 void replaceFontSizeByKeywordIfPossible(RenderStyle*, CSSComputedStyleDeclaration*); 138 void extractFontSizeDelta(); 139 bool conflictsWithInlineStyleOfElement(StyledElement*, EditingStyle* extractedStyle, Vector<CSSPropertyID>* conflictingProperties) const; 140 void mergeStyle(CSSMutableStyleDeclaration*); 141 142 RefPtr<CSSMutableStyleDeclaration> m_mutableStyle; 143 bool m_shouldUseFixedDefaultFontSize; 144 float m_fontSizeDelta; 145 146 friend class HTMLElementEquivalent; 147 friend class HTMLAttributeEquivalent; 148 }; 149 150 class StyleChange { 151 public: 152 StyleChange(EditingStyle*, const Position&); 153 cssStyle()154 String cssStyle() const { return m_cssStyle; } applyBold()155 bool applyBold() const { return m_applyBold; } applyItalic()156 bool applyItalic() const { return m_applyItalic; } applyUnderline()157 bool applyUnderline() const { return m_applyUnderline; } applyLineThrough()158 bool applyLineThrough() const { return m_applyLineThrough; } applySubscript()159 bool applySubscript() const { return m_applySubscript; } applySuperscript()160 bool applySuperscript() const { return m_applySuperscript; } applyFontColor()161 bool applyFontColor() const { return m_applyFontColor.length() > 0; } applyFontFace()162 bool applyFontFace() const { return m_applyFontFace.length() > 0; } applyFontSize()163 bool applyFontSize() const { return m_applyFontSize.length() > 0; } 164 fontColor()165 String fontColor() { return m_applyFontColor; } fontFace()166 String fontFace() { return m_applyFontFace; } fontSize()167 String fontSize() { return m_applyFontSize; } 168 169 bool operator==(const StyleChange& other) 170 { 171 return m_cssStyle == other.m_cssStyle 172 && m_applyBold == other.m_applyBold 173 && m_applyItalic == other.m_applyItalic 174 && m_applyUnderline == other.m_applyUnderline 175 && m_applyLineThrough == other.m_applyLineThrough 176 && m_applySubscript == other.m_applySubscript 177 && m_applySuperscript == other.m_applySuperscript 178 && m_applyFontColor == other.m_applyFontColor 179 && m_applyFontFace == other.m_applyFontFace 180 && m_applyFontSize == other.m_applyFontSize; 181 } 182 bool operator!=(const StyleChange& other) 183 { 184 return !(*this == other); 185 } 186 private: 187 void extractTextStyles(Document*, CSSMutableStyleDeclaration*, bool shouldUseFixedFontDefaultSize); 188 189 String m_cssStyle; 190 bool m_applyBold; 191 bool m_applyItalic; 192 bool m_applyUnderline; 193 bool m_applyLineThrough; 194 bool m_applySubscript; 195 bool m_applySuperscript; 196 String m_applyFontColor; 197 String m_applyFontFace; 198 String m_applyFontSize; 199 }; 200 201 // FIXME: Remove these functions or make them non-global to discourage using CSSStyleDeclaration directly. 202 int getIdentifierValue(CSSStyleDeclaration*, int propertyID); 203 enum LegacyFontSizeMode { AlwaysUseLegacyFontSize, UseLegacyFontSizeOnlyIfPixelValuesMatch }; 204 int legacyFontSizeFromCSSValue(Document*, CSSPrimitiveValue*, bool shouldUseFixedFontDefaultSize, LegacyFontSizeMode); 205 bool hasTransparentBackgroundColor(CSSStyleDeclaration*); 206 PassRefPtr<CSSValue> backgroundColorInEffect(Node*); 207 208 } // namespace WebCore 209 210 #endif // EditingStyle_h 211