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