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