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 "CSSPropertyNames.h" 36#include "WritingDirection.h" 37#include <wtf/Forward.h> 38#include <wtf/RefCounted.h> 39#include <wtf/RefPtr.h> 40#include <wtf/TriState.h> 41#include <wtf/Vector.h> 42#include <wtf/text/WTFString.h> 43 44namespace WebCore { 45 46class CSSStyleDeclaration; 47class CSSComputedStyleDeclaration; 48class CSSPrimitiveValue; 49class CSSValue; 50class Document; 51class Element; 52class HTMLElement; 53class MutableStylePropertySet; 54class Node; 55class Position; 56class QualifiedName; 57class RenderStyle; 58class StylePropertySet; 59class StyledElement; 60class VisibleSelection; 61 62class EditingStyle : public RefCounted<EditingStyle> { 63public: 64 65 enum PropertiesToInclude { AllProperties, OnlyEditingInheritableProperties, EditingPropertiesInEffect }; 66 enum ShouldPreserveWritingDirection { PreserveWritingDirection, DoNotPreserveWritingDirection }; 67 enum ShouldExtractMatchingStyle { ExtractMatchingStyle, DoNotExtractMatchingStyle }; 68 static float NoFontDelta; 69 70 static PassRefPtr<EditingStyle> create() 71 { 72 return adoptRef(new EditingStyle()); 73 } 74 75 static PassRefPtr<EditingStyle> create(Node* node, PropertiesToInclude propertiesToInclude = OnlyEditingInheritableProperties) 76 { 77 return adoptRef(new EditingStyle(node, propertiesToInclude)); 78 } 79 80 static PassRefPtr<EditingStyle> create(const Position& position, PropertiesToInclude propertiesToInclude = OnlyEditingInheritableProperties) 81 { 82 return adoptRef(new EditingStyle(position, propertiesToInclude)); 83 } 84 85 static PassRefPtr<EditingStyle> create(const StylePropertySet* style) 86 { 87 return adoptRef(new EditingStyle(style)); 88 } 89 90 static PassRefPtr<EditingStyle> create(CSSPropertyID propertyID, const String& value) 91 { 92 return adoptRef(new EditingStyle(propertyID, value)); 93 } 94 95 ~EditingStyle(); 96 97 MutableStylePropertySet* style() { return m_mutableStyle.get(); } 98 bool textDirection(WritingDirection&) const; 99 bool isEmpty() const; 100 void setStyle(PassRefPtr<MutableStylePropertySet>); 101 void overrideWithStyle(const StylePropertySet*); 102 void clear(); 103 PassRefPtr<EditingStyle> copy() const; 104 PassRefPtr<EditingStyle> extractAndRemoveBlockProperties(); 105 PassRefPtr<EditingStyle> extractAndRemoveTextDirection(); 106 void removeBlockProperties(); 107 void removeStyleAddedByNode(Node*); 108 void removeStyleConflictingWithStyleOfNode(Node*); 109 void removeNonEditingProperties(); 110 void collapseTextDecorationProperties(); 111 enum ShouldIgnoreTextOnlyProperties { IgnoreTextOnlyProperties, DoNotIgnoreTextOnlyProperties }; 112 TriState triStateOfStyle(EditingStyle*) const; 113 TriState triStateOfStyle(const VisibleSelection&) const; 114 bool conflictsWithInlineStyleOfElement(StyledElement* element) const { return conflictsWithInlineStyleOfElement(element, 0, 0); } 115 bool conflictsWithInlineStyleOfElement(StyledElement* element, EditingStyle* extractedStyle, Vector<CSSPropertyID>& conflictingProperties) const 116 { 117 return conflictsWithInlineStyleOfElement(element, extractedStyle, &conflictingProperties); 118 } 119 bool conflictsWithImplicitStyleOfElement(HTMLElement*, EditingStyle* extractedStyle = 0, ShouldExtractMatchingStyle = DoNotExtractMatchingStyle) const; 120 bool conflictsWithImplicitStyleOfAttributes(HTMLElement*) const; 121 bool extractConflictingImplicitStyleOfAttributes(HTMLElement*, ShouldPreserveWritingDirection, EditingStyle* extractedStyle, 122 Vector<QualifiedName>& conflictingAttributes, ShouldExtractMatchingStyle) const; 123 bool styleIsPresentInComputedStyleOfNode(Node*) const; 124 125 static bool elementIsStyledSpanOrHTMLEquivalent(const HTMLElement*); 126 127 void prepareToApplyAt(const Position&, ShouldPreserveWritingDirection = DoNotPreserveWritingDirection); 128 void mergeTypingStyle(Document*); 129 enum CSSPropertyOverrideMode { OverrideValues, DoNotOverrideValues }; 130 void mergeInlineStyleOfElement(StyledElement*, CSSPropertyOverrideMode, PropertiesToInclude = AllProperties); 131 static PassRefPtr<EditingStyle> wrappingStyleForSerialization(Node* context, bool shouldAnnotate); 132 void mergeStyleFromRules(StyledElement*); 133 void mergeStyleFromRulesForSerialization(StyledElement*); 134 void removeStyleFromRulesAndContext(StyledElement*, Node* context); 135 void removePropertiesInElementDefaultStyle(Element*); 136 void forceInline(); 137 int legacyFontSize(Document*) const; 138 139 float fontSizeDelta() const { return m_fontSizeDelta; } 140 bool hasFontSizeDelta() const { return m_fontSizeDelta != NoFontDelta; } 141 bool shouldUseFixedDefaultFontSize() const { return m_shouldUseFixedDefaultFontSize; } 142 143 static PassRefPtr<EditingStyle> styleAtSelectionStart(const VisibleSelection&, bool shouldUseBackgroundColorInEffect = false); 144 static WritingDirection textDirectionForSelection(const VisibleSelection&, EditingStyle* typingStyle, bool& hasNestedOrMultipleEmbeddings); 145private: 146 EditingStyle(); 147 EditingStyle(Node*, PropertiesToInclude); 148 EditingStyle(const Position&, PropertiesToInclude); 149 explicit EditingStyle(const StylePropertySet*); 150 EditingStyle(CSSPropertyID, const String& value); 151 void init(Node*, PropertiesToInclude); 152 void removeTextFillAndStrokeColorsIfNeeded(RenderStyle*); 153 void setProperty(CSSPropertyID, const String& value, bool important = false); 154 void extractFontSizeDelta(); 155 template<typename T> 156 TriState triStateOfStyle(T* styleToCompare, ShouldIgnoreTextOnlyProperties) const; 157 bool conflictsWithInlineStyleOfElement(StyledElement*, EditingStyle* extractedStyle, Vector<CSSPropertyID>* conflictingProperties) const; 158 void mergeInlineAndImplicitStyleOfElement(StyledElement*, CSSPropertyOverrideMode, PropertiesToInclude); 159 void mergeStyle(const StylePropertySet*, CSSPropertyOverrideMode); 160 161 RefPtr<MutableStylePropertySet> m_mutableStyle; 162 bool m_shouldUseFixedDefaultFontSize; 163 float m_fontSizeDelta; 164 165 friend class HTMLElementEquivalent; 166 friend class HTMLAttributeEquivalent; 167}; 168 169class StyleChange { 170public: 171 StyleChange() 172 : m_applyBold(false) 173 , m_applyItalic(false) 174 , m_applyUnderline(false) 175 , m_applyLineThrough(false) 176 , m_applySubscript(false) 177 , m_applySuperscript(false) 178 { } 179 180 StyleChange(EditingStyle*, const Position&); 181 182 String cssStyle() const { return m_cssStyle; } 183 bool applyBold() const { return m_applyBold; } 184 bool applyItalic() const { return m_applyItalic; } 185 bool applyUnderline() const { return m_applyUnderline; } 186 bool applyLineThrough() const { return m_applyLineThrough; } 187 bool applySubscript() const { return m_applySubscript; } 188 bool applySuperscript() const { return m_applySuperscript; } 189 bool applyFontColor() const { return m_applyFontColor.length() > 0; } 190 bool applyFontFace() const { return m_applyFontFace.length() > 0; } 191 bool applyFontSize() const { return m_applyFontSize.length() > 0; } 192 193 String fontColor() { return m_applyFontColor; } 194 String fontFace() { return m_applyFontFace; } 195 String fontSize() { return m_applyFontSize; } 196 197 bool operator==(const StyleChange& other) 198 { 199 return m_cssStyle == other.m_cssStyle 200 && m_applyBold == other.m_applyBold 201 && m_applyItalic == other.m_applyItalic 202 && m_applyUnderline == other.m_applyUnderline 203 && m_applyLineThrough == other.m_applyLineThrough 204 && m_applySubscript == other.m_applySubscript 205 && m_applySuperscript == other.m_applySuperscript 206 && m_applyFontColor == other.m_applyFontColor 207 && m_applyFontFace == other.m_applyFontFace 208 && m_applyFontSize == other.m_applyFontSize; 209 } 210 bool operator!=(const StyleChange& other) 211 { 212 return !(*this == other); 213 } 214private: 215 void extractTextStyles(Document*, MutableStylePropertySet*, bool shouldUseFixedFontDefaultSize); 216 217 String m_cssStyle; 218 bool m_applyBold; 219 bool m_applyItalic; 220 bool m_applyUnderline; 221 bool m_applyLineThrough; 222 bool m_applySubscript; 223 bool m_applySuperscript; 224 String m_applyFontColor; 225 String m_applyFontFace; 226 String m_applyFontSize; 227}; 228 229} // namespace WebCore 230 231#endif // EditingStyle_h 232