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 Document; 49 class HTMLElement; 50 class Node; 51 class Position; 52 class QualifiedName; 53 class RenderStyle; 54 class StyledElement; 55 56 enum TriState { FalseTriState, TrueTriState, MixedTriState }; 57 58 class EditingStyle : public RefCounted<EditingStyle> { 59 public: 60 61 enum PropertiesToInclude { AllProperties, OnlyInheritableProperties }; 62 enum ShouldPreserveWritingDirection { PreserveWritingDirection, DoNotPreserveWritingDirection }; 63 enum ShouldExtractMatchingStyle { ExtractMatchingStyle, DoNotExtractMatchingStyle }; 64 static float NoFontDelta; 65 66 static PassRefPtr<EditingStyle> create() 67 { 68 return adoptRef(new EditingStyle()); 69 } 70 71 static PassRefPtr<EditingStyle> create(Node* node, PropertiesToInclude propertiesToInclude = OnlyInheritableProperties) 72 { 73 return adoptRef(new EditingStyle(node, propertiesToInclude)); 74 } 75 76 static PassRefPtr<EditingStyle> create(const Position& position) 77 { 78 return adoptRef(new EditingStyle(position)); 79 } 80 81 static PassRefPtr<EditingStyle> create(const CSSStyleDeclaration* style) 82 { 83 return adoptRef(new EditingStyle(style)); 84 } 85 86 static PassRefPtr<EditingStyle> create(int propertyID, const String& value) 87 { 88 return adoptRef(new EditingStyle(propertyID, value)); 89 } 90 91 ~EditingStyle(); 92 93 CSSMutableStyleDeclaration* style() { return m_mutableStyle.get(); } 94 bool textDirection(WritingDirection&) const; 95 bool isEmpty() const; 96 void setStyle(PassRefPtr<CSSMutableStyleDeclaration>); 97 void overrideWithStyle(const CSSMutableStyleDeclaration*); 98 void clear(); 99 PassRefPtr<EditingStyle> copy() const; 100 PassRefPtr<EditingStyle> extractAndRemoveBlockProperties(); 101 PassRefPtr<EditingStyle> extractAndRemoveTextDirection(); 102 void removeBlockProperties(); 103 void removeStyleAddedByNode(Node*); 104 void removeStyleConflictingWithStyleOfNode(Node*); 105 void removeNonEditingProperties(); 106 void collapseTextDecorationProperties(); 107 enum ShouldIgnoreTextOnlyProperties { IgnoreTextOnlyProperties, DoNotIgnoreTextOnlyProperties }; 108 TriState triStateOfStyle(CSSStyleDeclaration*, ShouldIgnoreTextOnlyProperties = DoNotIgnoreTextOnlyProperties) const; 109 bool conflictsWithInlineStyleOfElement(StyledElement* element) const { return conflictsWithInlineStyleOfElement(element, 0, 0); } 110 bool conflictsWithInlineStyleOfElement(StyledElement* element, EditingStyle* extractedStyle, Vector<CSSPropertyID>& conflictingProperties) const 111 { 112 return conflictsWithInlineStyleOfElement(element, extractedStyle, &conflictingProperties); 113 } 114 bool conflictsWithImplicitStyleOfElement(HTMLElement*, EditingStyle* extractedStyle = 0, ShouldExtractMatchingStyle = DoNotExtractMatchingStyle) const; 115 bool conflictsWithImplicitStyleOfAttributes(HTMLElement*) const; 116 bool extractConflictingImplicitStyleOfAttributes(HTMLElement*, ShouldPreserveWritingDirection, EditingStyle* extractedStyle, 117 Vector<QualifiedName>& conflictingAttributes, ShouldExtractMatchingStyle) const; 118 bool styleIsPresentInComputedStyleOfNode(Node*) const; 119 void prepareToApplyAt(const Position&, ShouldPreserveWritingDirection = DoNotPreserveWritingDirection); 120 void mergeTypingStyle(Document*); 121 void mergeInlineStyleOfElement(StyledElement*); 122 123 float fontSizeDelta() const { return m_fontSizeDelta; } 124 bool hasFontSizeDelta() const { return m_fontSizeDelta != NoFontDelta; } 125 bool shouldUseFixedDefaultFontSize() const { return m_shouldUseFixedDefaultFontSize; } 126 127 private: 128 EditingStyle(); 129 EditingStyle(Node*, PropertiesToInclude); 130 EditingStyle(const Position&); 131 EditingStyle(const CSSStyleDeclaration*); 132 EditingStyle(int propertyID, const String& value); 133 void init(Node*, PropertiesToInclude); 134 void removeTextFillAndStrokeColorsIfNeeded(RenderStyle*); 135 void setProperty(int propertyID, const String& value, bool important = false); 136 void replaceFontSizeByKeywordIfPossible(RenderStyle*, CSSComputedStyleDeclaration*); 137 void extractFontSizeDelta(); 138 bool conflictsWithInlineStyleOfElement(StyledElement*, EditingStyle* extractedStyle, Vector<CSSPropertyID>* conflictingProperties) const; 139 void mergeStyle(CSSMutableStyleDeclaration*); 140 141 RefPtr<CSSMutableStyleDeclaration> m_mutableStyle; 142 bool m_shouldUseFixedDefaultFontSize; 143 float m_fontSizeDelta; 144 145 friend class HTMLElementEquivalent; 146 friend class HTMLAttributeEquivalent; 147 }; 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 205 } // namespace WebCore 206 207 #endif // EditingStyle_h 208