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 42namespace WebCore { 43 44class CSSStyleDeclaration; 45class CSSComputedStyleDeclaration; 46class CSSMutableStyleDeclaration; 47class CSSPrimitiveValue; 48class Document; 49class HTMLElement; 50class Node; 51class Position; 52class QualifiedName; 53class RenderStyle; 54class StyledElement; 55 56enum TriState { FalseTriState, TrueTriState, MixedTriState }; 57 58class EditingStyle : public RefCounted<EditingStyle> { 59public: 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 127private: 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 149class StyleChange { 150public: 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 } 185private: 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. 201int getIdentifierValue(CSSStyleDeclaration*, int propertyID); 202enum LegacyFontSizeMode { AlwaysUseLegacyFontSize, UseLegacyFontSizeOnlyIfPixelValuesMatch }; 203int legacyFontSizeFromCSSValue(Document*, CSSPrimitiveValue*, bool shouldUseFixedFontDefaultSize, LegacyFontSizeMode); 204 205} // namespace WebCore 206 207#endif // EditingStyle_h 208