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/fonts/FixedPitchFontType.h" 39 #include "platform/heap/Handle.h" 40 #include "wtf/Forward.h" 41 #include "wtf/RefCounted.h" 42 #include "wtf/RefPtr.h" 43 #include "wtf/TriState.h" 44 #include "wtf/Vector.h" 45 #include "wtf/text/WTFString.h" 46 47 namespace blink { 48 49 class CSSStyleDeclaration; 50 class CSSComputedStyleDeclaration; 51 class ContainerNode; 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 create()71 static PassRefPtrWillBeRawPtr<EditingStyle> create() 72 { 73 return adoptRefWillBeNoop(new EditingStyle()); 74 } 75 76 static PassRefPtrWillBeRawPtr<EditingStyle> create(ContainerNode* 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 create(const StylePropertySet * style)86 static PassRefPtrWillBeRawPtr<EditingStyle> create(const StylePropertySet* style) 87 { 88 return adoptRefWillBeNoop(new EditingStyle(style)); 89 } 90 create(CSSPropertyID propertyID,const String & value)91 static PassRefPtrWillBeRawPtr<EditingStyle> create(CSSPropertyID propertyID, const String& value) 92 { 93 return adoptRefWillBeNoop(new EditingStyle(propertyID, value)); 94 } 95 96 ~EditingStyle(); 97 style()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 removeStyleAddedByElement(Element*); 108 void removeStyleConflictingWithStyleOfElement(Element*); 109 void collapseTextDecorationProperties(); 110 enum ShouldIgnoreTextOnlyProperties { IgnoreTextOnlyProperties, DoNotIgnoreTextOnlyProperties }; 111 TriState triStateOfStyle(EditingStyle*) const; 112 TriState triStateOfStyle(const VisibleSelection&) const; conflictsWithInlineStyleOfElement(HTMLElement * element)113 bool conflictsWithInlineStyleOfElement(HTMLElement* element) const { return conflictsWithInlineStyleOfElement(element, 0, 0); } conflictsWithInlineStyleOfElement(HTMLElement * element,EditingStyle * extractedStyle,Vector<CSSPropertyID> & conflictingProperties)114 bool conflictsWithInlineStyleOfElement(HTMLElement* 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(HTMLElement*, CSSPropertyOverrideMode, PropertiesToInclude = AllProperties); 130 static PassRefPtrWillBeRawPtr<EditingStyle> wrappingStyleForSerialization(ContainerNode* context, bool shouldAnnotate); 131 void mergeStyleFromRules(Element*); 132 void mergeStyleFromRulesForSerialization(Element*); 133 void removeStyleFromRulesAndContext(Element*, ContainerNode* context); 134 void removePropertiesInElementDefaultStyle(Element*); 135 void addAbsolutePositioningFromElement(const Element&); 136 void forceInline(); 137 int legacyFontSize(Document*) const; 138 fontSizeDelta()139 float fontSizeDelta() const { return m_fontSizeDelta; } hasFontSizeDelta()140 bool hasFontSizeDelta() const { return m_fontSizeDelta != NoFontDelta; } 141 142 static PassRefPtrWillBeRawPtr<EditingStyle> styleAtSelectionStart(const VisibleSelection&, bool shouldUseBackgroundColorInEffect = false); 143 static WritingDirection textDirectionForSelection(const VisibleSelection&, EditingStyle* typingStyle, bool& hasNestedOrMultipleEmbeddings); 144 145 void trace(Visitor*); 146 147 private: 148 EditingStyle(); 149 EditingStyle(ContainerNode*, PropertiesToInclude); 150 EditingStyle(const Position&, PropertiesToInclude); 151 explicit EditingStyle(const StylePropertySet*); 152 EditingStyle(CSSPropertyID, const String& value); 153 void init(Node*, PropertiesToInclude); 154 void removeTextFillAndStrokeColorsIfNeeded(RenderStyle*); 155 void setProperty(CSSPropertyID, const String& value, bool important = false); 156 void replaceFontSizeByKeywordIfPossible(RenderStyle*, CSSComputedStyleDeclaration*); 157 void extractFontSizeDelta(); 158 TriState triStateOfStyle(CSSStyleDeclaration* styleToCompare, ShouldIgnoreTextOnlyProperties) const; 159 bool conflictsWithInlineStyleOfElement(HTMLElement*, EditingStyle* extractedStyle, Vector<CSSPropertyID>* conflictingProperties) const; 160 void mergeInlineAndImplicitStyleOfElement(Element*, CSSPropertyOverrideMode, PropertiesToInclude); 161 void mergeStyle(const StylePropertySet*, CSSPropertyOverrideMode); 162 163 RefPtrWillBeMember<MutableStylePropertySet> m_mutableStyle; 164 FixedPitchFontType m_fixedPitchFontType; 165 float m_fontSizeDelta; 166 167 friend class HTMLElementEquivalent; 168 friend class HTMLAttributeEquivalent; 169 }; 170 171 class StyleChange { 172 public: StyleChange()173 StyleChange() 174 : m_applyBold(false) 175 , m_applyItalic(false) 176 , m_applyUnderline(false) 177 , m_applyLineThrough(false) 178 , m_applySubscript(false) 179 , m_applySuperscript(false) 180 { } 181 182 StyleChange(EditingStyle*, const Position&); 183 cssStyle()184 String cssStyle() const { return m_cssStyle; } applyBold()185 bool applyBold() const { return m_applyBold; } applyItalic()186 bool applyItalic() const { return m_applyItalic; } applyUnderline()187 bool applyUnderline() const { return m_applyUnderline; } applyLineThrough()188 bool applyLineThrough() const { return m_applyLineThrough; } applySubscript()189 bool applySubscript() const { return m_applySubscript; } applySuperscript()190 bool applySuperscript() const { return m_applySuperscript; } applyFontColor()191 bool applyFontColor() const { return m_applyFontColor.length() > 0; } applyFontFace()192 bool applyFontFace() const { return m_applyFontFace.length() > 0; } applyFontSize()193 bool applyFontSize() const { return m_applyFontSize.length() > 0; } 194 fontColor()195 String fontColor() { return m_applyFontColor; } fontFace()196 String fontFace() { return m_applyFontFace; } fontSize()197 String fontSize() { return m_applyFontSize; } 198 199 bool operator==(const StyleChange& other) 200 { 201 return m_cssStyle == other.m_cssStyle 202 && m_applyBold == other.m_applyBold 203 && m_applyItalic == other.m_applyItalic 204 && m_applyUnderline == other.m_applyUnderline 205 && m_applyLineThrough == other.m_applyLineThrough 206 && m_applySubscript == other.m_applySubscript 207 && m_applySuperscript == other.m_applySuperscript 208 && m_applyFontColor == other.m_applyFontColor 209 && m_applyFontFace == other.m_applyFontFace 210 && m_applyFontSize == other.m_applyFontSize; 211 } 212 bool operator!=(const StyleChange& other) 213 { 214 return !(*this == other); 215 } 216 private: 217 void extractTextStyles(Document*, MutableStylePropertySet*, FixedPitchFontType); 218 219 String m_cssStyle; 220 bool m_applyBold; 221 bool m_applyItalic; 222 bool m_applyUnderline; 223 bool m_applyLineThrough; 224 bool m_applySubscript; 225 bool m_applySuperscript; 226 String m_applyFontColor; 227 String m_applyFontFace; 228 String m_applyFontSize; 229 }; 230 231 // FIXME: Remove these functions or make them non-global to discourage using CSSStyleDeclaration directly. 232 CSSValueID getIdentifierValue(CSSStyleDeclaration*, CSSPropertyID); 233 CSSValueID getIdentifierValue(StylePropertySet*, CSSPropertyID); 234 235 } // namespace blink 236 237 #endif // EditingStyle_h 238