15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2007, 2008, 2009 Apple Computer, Inc.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010, 2011 Google Inc. All rights reserved.
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    documentation and/or other materials provided with the distribution.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/EditingStyle.h"
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
30197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionStatePlaceholder.h"
315d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/HTMLNames.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSComputedStyleDeclaration.h"
337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/css/CSSPropertyMetadata.h"
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSRuleList.h"
3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSStyleRule.h"
3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSValueList.h"
37197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/css/CSSValuePool.h"
385267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "core/css/FontSize.h"
3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/StylePropertySet.h"
4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/StyleRule.h"
417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/css/parser/CSSParser.h"
4281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)#include "core/css/resolver/StyleResolver.h"
43197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/dom/Document.h"
44591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/dom/Element.h"
4553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Node.h"
4653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/NodeTraversal.h"
4753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Position.h"
4853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/QualifiedName.h"
4953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/ApplyStyleCommand.h"
5053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/Editor.h"
5153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/FrameSelection.h"
5253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/HTMLInterchange.h"
5353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/htmlediting.h"
54d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/LocalFrame.h"
5509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/html/HTMLFontElement.h"
56c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/html/HTMLSpanElement.h"
57197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/rendering/RenderBox.h"
58197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/rendering/RenderObject.h"
5953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/style/RenderStyle.h"
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
61c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
63e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)static const CSSPropertyID& textDecorationPropertyForEditing()
64e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){
65e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    static const CSSPropertyID property = RuntimeEnabledFeatures::css3TextDecorationsEnabled() ? CSSPropertyTextDecorationLine : CSSPropertyTextDecoration;
66e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    return property;
67e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)}
68e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Editing style properties must be preserved during editing operation.
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// e.g. when a user inserts a new paragraph, all properties listed here must be copied to the new paragraph.
713c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch// NOTE: Use either allEditingProperties() or inheritableEditingProperties() to
723c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch// respect runtime enabling of properties.
7353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static const CSSPropertyID staticEditingProperties[] = {
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyBackgroundColor,
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyColor,
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyFontFamily,
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyFontSize,
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyFontStyle,
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyFontVariant,
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyFontWeight,
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyLetterSpacing,
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyLineHeight,
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyOrphans,
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyTextAlign,
85e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // FIXME: CSSPropertyTextDecoration needs to be removed when CSS3 Text
86e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // Decoration feature is no longer experimental.
873c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    CSSPropertyTextDecoration,
88e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    CSSPropertyTextDecorationLine,
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyTextIndent,
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyTextTransform,
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyWhiteSpace,
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyWidows,
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyWordSpacing,
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyWebkitTextDecorationsInEffect,
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyWebkitTextFillColor,
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyWebkitTextStrokeColor,
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyWebkitTextStrokeWidth,
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)enum EditingPropertiesType { OnlyInheritableEditingProperties, AllEditingProperties };
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static const Vector<CSSPropertyID>& allEditingProperties()
10353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
10453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    DEFINE_STATIC_LOCAL(Vector<CSSPropertyID>, properties, ());
105e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    if (properties.isEmpty()) {
1067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        CSSPropertyMetadata::filterEnabledCSSPropertiesIntoVector(staticEditingProperties, WTF_ARRAY_LENGTH(staticEditingProperties), properties);
107e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        if (RuntimeEnabledFeatures::css3TextDecorationsEnabled())
108e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            properties.remove(properties.find(CSSPropertyTextDecoration));
109e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    }
11053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return properties;
11153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
11253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
11353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static const Vector<CSSPropertyID>& inheritableEditingProperties()
11453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
11553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    DEFINE_STATIC_LOCAL(Vector<CSSPropertyID>, properties, ());
1163c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    if (properties.isEmpty()) {
1177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        CSSPropertyMetadata::filterEnabledCSSPropertiesIntoVector(staticEditingProperties, WTF_ARRAY_LENGTH(staticEditingProperties), properties);
1183c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        for (size_t index = 0; index < properties.size();) {
119e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            if (!CSSPropertyMetadata::isInheritedProperty(properties[index])) {
1203c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch                properties.remove(index);
1213c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch                continue;
1223c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch            }
1233c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch            ++index;
1243c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        }
1253c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    }
12653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return properties;
12753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
12853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class StyleDeclarationType>
13043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)static PassRefPtrWillBeRawPtr<MutableStylePropertySet> copyEditingProperties(StyleDeclarationType* style, EditingPropertiesType type = OnlyInheritableEditingProperties)
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (type == AllEditingProperties)
13353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return style->copyPropertiesInSet(allEditingProperties());
13453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return style->copyPropertiesInSet(inheritableEditingProperties());
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline bool isEditingProperty(int id)
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return allEditingProperties().contains(static_cast<CSSPropertyID>(id));
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
142323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)static PassRefPtrWillBeRawPtr<MutableStylePropertySet> editingStyleFromComputedStyle(PassRefPtrWillBeRawPtr<CSSComputedStyleDeclaration> style, EditingPropertiesType type = OnlyInheritableEditingProperties)
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!style)
14593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return MutableStylePropertySet::create();
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return copyEditingProperties(style.get(), type);
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)static PassRefPtrWillBeRawPtr<MutableStylePropertySet> getPropertiesNotIn(StylePropertySet* styleWithRedundantProperties, CSSStyleDeclaration* baseStyle);
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)enum LegacyFontSizeMode { AlwaysUseLegacyFontSize, UseLegacyFontSizeOnlyIfPixelValuesMatch };
151197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic int legacyFontSizeFromCSSValue(Document*, CSSPrimitiveValue*, FixedPitchFontType, LegacyFontSizeMode);
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool isTransparentColorValue(CSSValue*);
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool hasTransparentBackgroundColor(CSSStyleDeclaration*);
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool hasTransparentBackgroundColor(StylePropertySet*);
155d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)static PassRefPtrWillBeRawPtr<CSSValue> backgroundColorInEffect(Node*);
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
157f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liuclass HTMLElementEquivalent : public NoBaseWillBeGarbageCollected<HTMLElementEquivalent> {
158f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
159f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(HTMLElementEquivalent);
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
161c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    static PassOwnPtrWillBeRawPtr<HTMLElementEquivalent> create(CSSPropertyID propertyID, CSSValueID primitiveValue, const HTMLQualifiedName& tagName)
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
163f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        return adoptPtrWillBeNoop(new HTMLElementEquivalent(propertyID, primitiveValue, tagName));
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual bool matches(const Element* element) const { return !m_tagName || element->hasTagName(*m_tagName); }
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual bool hasAttribute() const { return false; }
168926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    virtual bool propertyExistsInStyle(const StylePropertySet* style) const { return style->getPropertyCSSValue(m_propertyID); }
169c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual bool valueIsPresentInStyle(HTMLElement*, StylePropertySet*) const;
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual void addToStyle(Element*, EditingStyle*) const;
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
172f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    virtual void trace(Visitor* visitor) { visitor->trace(m_primitiveValue); }
173f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)protected:
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLElementEquivalent(CSSPropertyID);
176c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    HTMLElementEquivalent(CSSPropertyID, const HTMLQualifiedName& tagName);
177c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    HTMLElementEquivalent(CSSPropertyID, CSSValueID primitiveValue, const HTMLQualifiedName& tagName);
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const CSSPropertyID m_propertyID;
179f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    const RefPtrWillBeMember<CSSPrimitiveValue> m_primitiveValue;
180c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    const HTMLQualifiedName* m_tagName; // We can store a pointer because HTML tag names are const global.
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
183f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo LiuDEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(HTMLElementEquivalent);
184f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)HTMLElementEquivalent::HTMLElementEquivalent(CSSPropertyID id)
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : m_propertyID(id)
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_tagName(0)
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
191c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)HTMLElementEquivalent::HTMLElementEquivalent(CSSPropertyID id, const HTMLQualifiedName& tagName)
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : m_propertyID(id)
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_tagName(&tagName)
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
197c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)HTMLElementEquivalent::HTMLElementEquivalent(CSSPropertyID id, CSSValueID primitiveValue, const HTMLQualifiedName& tagName)
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : m_propertyID(id)
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_primitiveValue(CSSPrimitiveValue::createIdentifier(primitiveValue))
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_tagName(&tagName)
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(primitiveValue != CSSValueInvalid);
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
205c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)bool HTMLElementEquivalent::valueIsPresentInStyle(HTMLElement* element, StylePropertySet* style) const
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
207d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtrWillBeRawPtr<CSSValue> value = style->getPropertyCSSValue(m_propertyID);
2085267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    return matches(element) && value && value->isPrimitiveValue() && toCSSPrimitiveValue(value.get())->getValueID() == m_primitiveValue->getValueID();
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void HTMLElementEquivalent::addToStyle(Element*, EditingStyle* style) const
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    style->setProperty(m_propertyID, m_primitiveValue->cssText());
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
216f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liuclass HTMLTextDecorationEquivalent FINAL : public HTMLElementEquivalent {
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
218c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    static PassOwnPtrWillBeRawPtr<HTMLElementEquivalent> create(CSSValueID primitiveValue, const HTMLQualifiedName& tagName)
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
220f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        return adoptPtrWillBeNoop(new HTMLTextDecorationEquivalent(primitiveValue, tagName));
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
22209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual bool propertyExistsInStyle(const StylePropertySet*) const OVERRIDE;
223c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual bool valueIsPresentInStyle(HTMLElement*, StylePropertySet*) const OVERRIDE;
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
225f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    virtual void trace(Visitor* visitor) OVERRIDE { HTMLElementEquivalent::trace(visitor); }
226f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
228c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    HTMLTextDecorationEquivalent(CSSValueID primitiveValue, const HTMLQualifiedName& tagName);
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
231c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)HTMLTextDecorationEquivalent::HTMLTextDecorationEquivalent(CSSValueID primitiveValue, const HTMLQualifiedName& tagName)
232e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    : HTMLElementEquivalent(textDecorationPropertyForEditing(), primitiveValue, tagName)
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // m_propertyID is used in HTMLElementEquivalent::addToStyle
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool HTMLTextDecorationEquivalent::propertyExistsInStyle(const StylePropertySet* style) const
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
239e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    return style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect)
240e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        || style->getPropertyCSSValue(textDecorationPropertyForEditing());
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
243c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)bool HTMLTextDecorationEquivalent::valueIsPresentInStyle(HTMLElement* element, StylePropertySet* style) const
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
245d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtrWillBeRawPtr<CSSValue> styleValue = style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!styleValue)
247e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        styleValue = style->getPropertyCSSValue(textDecorationPropertyForEditing());
2483c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    return matches(element) && styleValue && styleValue->isValueList() && toCSSValueList(styleValue.get())->hasValue(m_primitiveValue.get());
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class HTMLAttributeEquivalent : public HTMLElementEquivalent {
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
253c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    static PassOwnPtrWillBeRawPtr<HTMLAttributeEquivalent> create(CSSPropertyID propertyID, const HTMLQualifiedName& tagName, const QualifiedName& attrName)
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
255f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        return adoptPtrWillBeNoop(new HTMLAttributeEquivalent(propertyID, tagName, attrName));
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
257f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    static PassOwnPtrWillBeRawPtr<HTMLAttributeEquivalent> create(CSSPropertyID propertyID, const QualifiedName& attrName)
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
259f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        return adoptPtrWillBeNoop(new HTMLAttributeEquivalent(propertyID, attrName));
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
262c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual bool matches(const Element* element) const OVERRIDE { return HTMLElementEquivalent::matches(element) && element->hasAttribute(m_attrName); }
26309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual bool hasAttribute() const OVERRIDE { return true; }
264c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual bool valueIsPresentInStyle(HTMLElement*, StylePropertySet*) const OVERRIDE;
26509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual void addToStyle(Element*, EditingStyle*) const OVERRIDE;
266d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    virtual PassRefPtrWillBeRawPtr<CSSValue> attributeValueAsCSSValue(Element*) const;
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    inline const QualifiedName& attributeName() const { return m_attrName; }
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
269f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    virtual void trace(Visitor* visitor) OVERRIDE { HTMLElementEquivalent::trace(visitor); }
270f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)protected:
272c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    HTMLAttributeEquivalent(CSSPropertyID, const HTMLQualifiedName& tagName, const QualifiedName& attrName);
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLAttributeEquivalent(CSSPropertyID, const QualifiedName& attrName);
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const QualifiedName& m_attrName; // We can store a reference because HTML attribute names are const global.
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
277c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)HTMLAttributeEquivalent::HTMLAttributeEquivalent(CSSPropertyID id, const HTMLQualifiedName& tagName, const QualifiedName& attrName)
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : HTMLElementEquivalent(id, tagName)
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_attrName(attrName)
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)HTMLAttributeEquivalent::HTMLAttributeEquivalent(CSSPropertyID id, const QualifiedName& attrName)
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : HTMLElementEquivalent(id)
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_attrName(attrName)
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
289c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)bool HTMLAttributeEquivalent::valueIsPresentInStyle(HTMLElement* element, StylePropertySet* style) const
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
291d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtrWillBeRawPtr<CSSValue> value = attributeValueAsCSSValue(element);
292d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtrWillBeRawPtr<CSSValue> styleValue = style->getPropertyCSSValue(m_propertyID);
29302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
294926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return compareCSSValuePtr(value, styleValue);
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void HTMLAttributeEquivalent::addToStyle(Element* element, EditingStyle* style) const
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
299d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (RefPtrWillBeRawPtr<CSSValue> value = attributeValueAsCSSValue(element))
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        style->setProperty(m_propertyID, value->cssText());
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
303d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)PassRefPtrWillBeRawPtr<CSSValue> HTMLAttributeEquivalent::attributeValueAsCSSValue(Element* element) const
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(element);
306d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const AtomicString& value = element->getAttribute(m_attrName);
307d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (value.isNull())
308d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
30902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
31007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    RefPtrWillBeRawPtr<MutableStylePropertySet> dummyStyle = nullptr;
31193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    dummyStyle = MutableStylePropertySet::create();
312d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    dummyStyle->setProperty(m_propertyID, value);
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return dummyStyle->getPropertyCSSValue(m_propertyID);
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
31609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class HTMLFontSizeEquivalent FINAL : public HTMLAttributeEquivalent {
3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
318f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    static PassOwnPtrWillBeRawPtr<HTMLFontSizeEquivalent> create()
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
320f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        return adoptPtrWillBeNoop(new HTMLFontSizeEquivalent());
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
322d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    virtual PassRefPtrWillBeRawPtr<CSSValue> attributeValueAsCSSValue(Element*) const OVERRIDE;
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
324f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    virtual void trace(Visitor* visitor) OVERRIDE { HTMLAttributeEquivalent::trace(visitor); }
325f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLFontSizeEquivalent();
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)HTMLFontSizeEquivalent::HTMLFontSizeEquivalent()
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : HTMLAttributeEquivalent(CSSPropertyFontSize, HTMLNames::fontTag, HTMLNames::sizeAttr)
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
335d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)PassRefPtrWillBeRawPtr<CSSValue> HTMLFontSizeEquivalent::attributeValueAsCSSValue(Element* element) const
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(element);
338d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const AtomicString& value = element->getAttribute(m_attrName);
339d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (value.isNull())
340d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
3415267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    CSSValueID size;
342d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!HTMLFontElement::cssValueFromFontSizeNumber(value, size))
343d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return CSSPrimitiveValue::createIdentifier(size);
3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float EditingStyle::NoFontDelta = 0.0f;
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)EditingStyle::EditingStyle()
350197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    : m_fixedPitchFontType(NonFixedPitchFont)
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_fontSizeDelta(NoFontDelta)
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
355c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)EditingStyle::EditingStyle(ContainerNode* node, PropertiesToInclude propertiesToInclude)
356197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    : m_fixedPitchFontType(NonFixedPitchFont)
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_fontSizeDelta(NoFontDelta)
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    init(node, propertiesToInclude);
3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)EditingStyle::EditingStyle(const Position& position, PropertiesToInclude propertiesToInclude)
363197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    : m_fixedPitchFontType(NonFixedPitchFont)
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_fontSizeDelta(NoFontDelta)
3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    init(position.deprecatedNode(), propertiesToInclude);
3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)EditingStyle::EditingStyle(const StylePropertySet* style)
370d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    : m_mutableStyle(style ? style->mutableCopy() : nullptr)
371197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    , m_fixedPitchFontType(NonFixedPitchFont)
3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_fontSizeDelta(NoFontDelta)
3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    extractFontSizeDelta();
3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)EditingStyle::EditingStyle(CSSPropertyID propertyID, const String& value)
378d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    : m_mutableStyle(nullptr)
379197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    , m_fixedPitchFontType(NonFixedPitchFont)
3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_fontSizeDelta(NoFontDelta)
3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setProperty(propertyID, value);
3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)EditingStyle::~EditingStyle()
3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static RGBA32 cssValueToRGBA(CSSValue* colorValue)
3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!colorValue || !colorValue->isPrimitiveValue())
3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return Color::transparent;
39302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
3943c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    CSSPrimitiveValue* primitiveColor = toCSSPrimitiveValue(colorValue);
3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (primitiveColor->isRGBColor())
3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return primitiveColor->getRGBA32Value();
39702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RGBA32 rgba = 0;
3997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // FIXME: Why ignore the return value?
4007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    CSSParser::parseColor(rgba, colorValue->cssText());
4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return rgba;
4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline RGBA32 getRGBAFontColor(CSSStyleDeclaration* style)
4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return cssValueToRGBA(style->getPropertyCSSValueInternal(CSSPropertyColor).get());
4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline RGBA32 getRGBAFontColor(StylePropertySet* style)
4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return cssValueToRGBA(style->getPropertyCSSValue(CSSPropertyColor).get());
4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline RGBA32 getRGBABackgroundColor(CSSStyleDeclaration* style)
4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return cssValueToRGBA(style->getPropertyCSSValueInternal(CSSPropertyBackgroundColor).get());
4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline RGBA32 getRGBABackgroundColor(StylePropertySet* style)
4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return cssValueToRGBA(style->getPropertyCSSValue(CSSPropertyBackgroundColor).get());
4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline RGBA32 rgbaBackgroundColorInEffect(Node* node)
4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return cssValueToRGBA(backgroundColorInEffect(node).get());
4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static int textAlignResolvingStartAndEnd(int textAlign, int direction)
4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (textAlign) {
4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSValueCenter:
4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSValueWebkitCenter:
4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return CSSValueCenter;
4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSValueJustify:
4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return CSSValueJustify;
4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSValueLeft:
4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSValueWebkitLeft:
4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return CSSValueLeft;
4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSValueRight:
4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSValueWebkitRight:
4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return CSSValueRight;
4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSValueStart:
4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return direction != CSSValueRtl ? CSSValueLeft : CSSValueRight;
4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSValueEnd:
4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return direction == CSSValueRtl ? CSSValueRight : CSSValueLeft;
4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return CSSValueInvalid;
4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template<typename T>
4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static int textAlignResolvingStartAndEnd(T* style)
4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return textAlignResolvingStartAndEnd(getIdentifierValue(style, CSSPropertyTextAlign), getIdentifierValue(style, CSSPropertyDirection));
4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void EditingStyle::init(Node* node, PropertiesToInclude propertiesToInclude)
4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
459c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (isTabHTMLSpanElementTextNode(node))
460c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        node = tabSpanElement(node)->parentNode();
461c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    else if (isTabHTMLSpanElement(node))
4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        node = node->parentNode();
4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
464323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> computedStyleAtPosition = CSSComputedStyleDeclaration::create(node);
46593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    m_mutableStyle = propertiesToInclude == AllProperties && computedStyleAtPosition ? computedStyleAtPosition->copyProperties() : editingStyleFromComputedStyle(computedStyleAtPosition);
4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (propertiesToInclude == EditingPropertiesInEffect) {
468d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (RefPtrWillBeRawPtr<CSSValue> value = backgroundColorInEffect(node))
4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_mutableStyle->setProperty(CSSPropertyBackgroundColor, value->cssText());
470d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (RefPtrWillBeRawPtr<CSSValue> value = computedStyleAtPosition->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect))
4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_mutableStyle->setProperty(CSSPropertyTextDecoration, value->cssText());
4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (node && node->computedStyle()) {
4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderStyle* renderStyle = node->computedStyle();
4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        removeTextFillAndStrokeColorsIfNeeded(renderStyle);
4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        replaceFontSizeByKeywordIfPossible(renderStyle, computedStyleAtPosition.get());
4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
480197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    m_fixedPitchFontType = computedStyleAtPosition->fixedPitchFontType();
4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    extractFontSizeDelta();
4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void EditingStyle::removeTextFillAndStrokeColorsIfNeeded(RenderStyle* renderStyle)
4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
48609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // If a node's text fill color is currentColor, then its children use
4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // their font-color as their text fill color (they don't
4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // inherit it).  Likewise for stroke color.
48909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (renderStyle->textFillColor().isCurrentColor())
4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_mutableStyle->removeProperty(CSSPropertyWebkitTextFillColor);
49109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (renderStyle->textStrokeColor().isCurrentColor())
4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_mutableStyle->removeProperty(CSSPropertyWebkitTextStrokeColor);
4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void EditingStyle::setProperty(CSSPropertyID propertyID, const String& value, bool important)
4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_mutableStyle)
49893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        m_mutableStyle = MutableStylePropertySet::create();
4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_mutableStyle->setProperty(propertyID, value, important);
5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void EditingStyle::replaceFontSizeByKeywordIfPossible(RenderStyle* renderStyle, CSSComputedStyleDeclaration* computedStyle)
5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(renderStyle);
5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (renderStyle->fontDescription().keywordSize())
5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_mutableStyle->setProperty(CSSPropertyFontSize, computedStyle->getFontSizeCSSValuePreferringKeyword()->cssText());
5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void EditingStyle::extractFontSizeDelta()
5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_mutableStyle)
5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_mutableStyle->getPropertyCSSValue(CSSPropertyFontSize)) {
5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Explicit font size overrides any delta.
5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_mutableStyle->removeProperty(CSSPropertyWebkitFontSizeDelta);
5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Get the adjustment amount out of the style.
522d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtrWillBeRawPtr<CSSValue> value = m_mutableStyle->getPropertyCSSValue(CSSPropertyWebkitFontSizeDelta);
5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!value || !value->isPrimitiveValue())
5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5263c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value.get());
5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Only PX handled now. If we handle more types in the future, perhaps
5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // a switch statement here would be more appropriate.
5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!primitiveValue->isPx())
5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_fontSizeDelta = primitiveValue->getFloatValue();
5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_mutableStyle->removeProperty(CSSPropertyWebkitFontSizeDelta);
5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool EditingStyle::isEmpty() const
5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return (!m_mutableStyle || m_mutableStyle->isEmpty()) && m_fontSizeDelta == NoFontDelta;
5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool EditingStyle::textDirection(WritingDirection& writingDirection) const
5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_mutableStyle)
5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
547d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtrWillBeRawPtr<CSSValue> unicodeBidi = m_mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!unicodeBidi || !unicodeBidi->isPrimitiveValue())
5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5515267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    CSSValueID unicodeBidiValue = toCSSPrimitiveValue(unicodeBidi.get())->getValueID();
5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (unicodeBidiValue == CSSValueEmbed) {
553d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        RefPtrWillBeRawPtr<CSSValue> direction = m_mutableStyle->getPropertyCSSValue(CSSPropertyDirection);
5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!direction || !direction->isPrimitiveValue())
5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5575267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        writingDirection = toCSSPrimitiveValue(direction.get())->getValueID() == CSSValueLtr ? LeftToRightWritingDirection : RightToLeftWritingDirection;
5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (unicodeBidiValue == CSSValueNormal) {
5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        writingDirection = NaturalWritingDirection;
5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void EditingStyle::overrideWithStyle(const StylePropertySet* style)
5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!style || style->isEmpty())
5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_mutableStyle)
57593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        m_mutableStyle = MutableStylePropertySet::create();
5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_mutableStyle->mergeAndOverrideOnConflict(style);
5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    extractFontSizeDelta();
5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void EditingStyle::clear()
5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_mutableStyle.clear();
583197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    m_fixedPitchFontType = NonFixedPitchFont;
5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_fontSizeDelta = NoFontDelta;
5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
587f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)PassRefPtrWillBeRawPtr<EditingStyle> EditingStyle::copy() const
5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
589f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    RefPtrWillBeRawPtr<EditingStyle> copy = EditingStyle::create();
5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_mutableStyle)
59193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        copy->m_mutableStyle = m_mutableStyle->mutableCopy();
592197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    copy->m_fixedPitchFontType = m_fixedPitchFontType;
5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    copy->m_fontSizeDelta = m_fontSizeDelta;
5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return copy;
5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
597f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)PassRefPtrWillBeRawPtr<EditingStyle> EditingStyle::extractAndRemoveBlockProperties()
5985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
599f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    RefPtrWillBeRawPtr<EditingStyle> blockProperties = EditingStyle::create();
6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_mutableStyle)
6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return blockProperties;
6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    blockProperties->m_mutableStyle = m_mutableStyle->copyBlockProperties();
6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_mutableStyle->removeBlockProperties();
6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return blockProperties;
6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
609f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)PassRefPtrWillBeRawPtr<EditingStyle> EditingStyle::extractAndRemoveTextDirection()
6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
611f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    RefPtrWillBeRawPtr<EditingStyle> textDirection = EditingStyle::create();
61293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    textDirection->m_mutableStyle = MutableStylePropertySet::create();
6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    textDirection->m_mutableStyle->setProperty(CSSPropertyUnicodeBidi, CSSValueEmbed, m_mutableStyle->propertyIsImportant(CSSPropertyUnicodeBidi));
6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    textDirection->m_mutableStyle->setProperty(CSSPropertyDirection, m_mutableStyle->getPropertyValue(CSSPropertyDirection),
6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_mutableStyle->propertyIsImportant(CSSPropertyDirection));
6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_mutableStyle->removeProperty(CSSPropertyUnicodeBidi);
6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_mutableStyle->removeProperty(CSSPropertyDirection);
6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return textDirection;
6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void EditingStyle::removeBlockProperties()
6245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_mutableStyle)
6265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
6275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_mutableStyle->removeBlockProperties();
6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
631c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void EditingStyle::removeStyleAddedByElement(Element* element)
6325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
633c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!element || !element->parentNode())
6345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
635c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    RefPtrWillBeRawPtr<MutableStylePropertySet> parentStyle = editingStyleFromComputedStyle(CSSComputedStyleDeclaration::create(element->parentNode()), AllEditingProperties);
636c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    RefPtrWillBeRawPtr<MutableStylePropertySet> nodeStyle = editingStyleFromComputedStyle(CSSComputedStyleDeclaration::create(element), AllEditingProperties);
63709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    nodeStyle->removeEquivalentProperties(parentStyle.get());
63809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_mutableStyle->removeEquivalentProperties(nodeStyle.get());
6395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
641c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void EditingStyle::removeStyleConflictingWithStyleOfElement(Element* element)
6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
643c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!element || !element->parentNode() || !m_mutableStyle)
6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
646c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    RefPtrWillBeRawPtr<MutableStylePropertySet> parentStyle = editingStyleFromComputedStyle(CSSComputedStyleDeclaration::create(element->parentNode()), AllEditingProperties);
647c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    RefPtrWillBeRawPtr<MutableStylePropertySet> nodeStyle = editingStyleFromComputedStyle(CSSComputedStyleDeclaration::create(element), AllEditingProperties);
64809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    nodeStyle->removeEquivalentProperties(parentStyle.get());
6495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned propertyCount = nodeStyle->propertyCount();
6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0; i < propertyCount; ++i)
6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_mutableStyle->removeProperty(nodeStyle->propertyAt(i).id());
6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void EditingStyle::collapseTextDecorationProperties()
6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_mutableStyle)
6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
6595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
660d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtrWillBeRawPtr<CSSValue> textDecorationsInEffect = m_mutableStyle->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
6615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!textDecorationsInEffect)
6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (textDecorationsInEffect->isValueList())
665e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        m_mutableStyle->setProperty(textDecorationPropertyForEditing(), textDecorationsInEffect->cssText(), m_mutableStyle->propertyIsImportant(textDecorationPropertyForEditing()));
6665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
667e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        m_mutableStyle->removeProperty(textDecorationPropertyForEditing());
6685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_mutableStyle->removeProperty(CSSPropertyWebkitTextDecorationsInEffect);
6695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// CSS properties that create a visual difference only when applied to text.
6725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const CSSPropertyID textOnlyProperties[] = {
673e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // FIXME: CSSPropertyTextDecoration needs to be removed when CSS3 Text
674e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // Decoration feature is no longer experimental.
6755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyTextDecoration,
676e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    CSSPropertyTextDecorationLine,
6775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyWebkitTextDecorationsInEffect,
6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyFontStyle,
6795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyFontWeight,
6805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyColor,
6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
6825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TriState EditingStyle::triStateOfStyle(EditingStyle* style) const
6845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!style || !style->m_mutableStyle)
6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return FalseTriState;
6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return triStateOfStyle(style->m_mutableStyle->ensureCSSStyleDeclaration(), DoNotIgnoreTextOnlyProperties);
6885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TriState EditingStyle::triStateOfStyle(CSSStyleDeclaration* styleToCompare, ShouldIgnoreTextOnlyProperties shouldIgnoreTextOnlyProperties) const
6915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
69243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    RefPtrWillBeRawPtr<MutableStylePropertySet> difference = getPropertiesNotIn(m_mutableStyle.get(), styleToCompare);
6935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (shouldIgnoreTextOnlyProperties == IgnoreTextOnlyProperties)
6955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        difference->removePropertiesInSet(textOnlyProperties, WTF_ARRAY_LENGTH(textOnlyProperties));
6965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (difference->isEmpty())
6985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return TrueTriState;
6995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (difference->propertyCount() == m_mutableStyle->propertyCount())
7005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return FalseTriState;
7015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return MixedTriState;
7035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TriState EditingStyle::triStateOfStyle(const VisibleSelection& selection) const
7065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!selection.isCaretOrRange())
7085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return FalseTriState;
7095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (selection.isCaret())
7115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return triStateOfStyle(EditingStyle::styleAtSelectionStart(selection).get());
7125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TriState state = FalseTriState;
714f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    bool nodeIsStart = true;
71551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    for (Node* node = selection.start().deprecatedNode(); node; node = NodeTraversal::next(*node)) {
716197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (node->renderer() && node->hasEditableStyle()) {
717323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> nodeStyle = CSSComputedStyleDeclaration::create(node);
718f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            if (nodeStyle) {
719f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                TriState nodeState = triStateOfStyle(nodeStyle.get(), node->isTextNode() ? EditingStyle::DoNotIgnoreTextOnlyProperties : EditingStyle::IgnoreTextOnlyProperties);
720f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                if (nodeIsStart) {
721f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                    state = nodeState;
722f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                    nodeIsStart = false;
723f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                } else if (state != nodeState && node->isTextNode()) {
724f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                    state = MixedTriState;
725f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                    break;
726f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)                }
7275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
7285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
7295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (node == selection.end().deprecatedNode())
7305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
7315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return state;
7345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
736c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)bool EditingStyle::conflictsWithInlineStyleOfElement(HTMLElement* element, EditingStyle* extractedStyle, Vector<CSSPropertyID>* conflictingProperties) const
7375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(element);
7395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!conflictingProperties || conflictingProperties->isEmpty());
7405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const StylePropertySet* inlineStyle = element->inlineStyle();
7425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_mutableStyle || !inlineStyle)
7435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
7445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned propertyCount = m_mutableStyle->propertyCount();
7465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0; i < propertyCount; ++i) {
7475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        CSSPropertyID propertyID = m_mutableStyle->propertyAt(i).id();
7485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // We don't override whitespace property of a tab span because that would collapse the tab into a space.
750c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (propertyID == CSSPropertyWhiteSpace && isTabHTMLSpanElement(element))
7515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
7525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
753e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        if (propertyID == CSSPropertyWebkitTextDecorationsInEffect && inlineStyle->getPropertyCSSValue(textDecorationPropertyForEditing())) {
7545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!conflictingProperties)
7555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return true;
7565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            conflictingProperties->append(CSSPropertyTextDecoration);
757e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            // Because text-decoration expands to text-decoration-line when CSS3
758e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            // Text Decoration is enabled, we also state it as conflicting.
759e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            if (RuntimeEnabledFeatures::css3TextDecorationsEnabled())
760e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                conflictingProperties->append(CSSPropertyTextDecorationLine);
7615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (extractedStyle)
762e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                extractedStyle->setProperty(textDecorationPropertyForEditing(), inlineStyle->getPropertyValue(textDecorationPropertyForEditing()), inlineStyle->propertyIsImportant(textDecorationPropertyForEditing()));
7635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
7645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
7655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!inlineStyle->getPropertyCSSValue(propertyID))
7675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
7685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (propertyID == CSSPropertyUnicodeBidi && inlineStyle->getPropertyCSSValue(CSSPropertyDirection)) {
7705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!conflictingProperties)
7715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return true;
7725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            conflictingProperties->append(CSSPropertyDirection);
7735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (extractedStyle)
7745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                extractedStyle->setProperty(propertyID, inlineStyle->getPropertyValue(propertyID), inlineStyle->propertyIsImportant(propertyID));
7755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
7765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!conflictingProperties)
7785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
7795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        conflictingProperties->append(propertyID);
7815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (extractedStyle)
7835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            extractedStyle->setProperty(propertyID, inlineStyle->getPropertyValue(propertyID), inlineStyle->propertyIsImportant(propertyID));
7845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return conflictingProperties && !conflictingProperties->isEmpty();
7875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
789f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liustatic const WillBeHeapVector<OwnPtrWillBeMember<HTMLElementEquivalent> >& htmlElementEquivalents()
7905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
791f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    DEFINE_STATIC_LOCAL(WillBePersistentHeapVector<OwnPtrWillBeMember<HTMLElementEquivalent> >, HTMLElementEquivalents, ());
7925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!HTMLElementEquivalents.size()) {
7935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        HTMLElementEquivalents.append(HTMLElementEquivalent::create(CSSPropertyFontWeight, CSSValueBold, HTMLNames::bTag));
7945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        HTMLElementEquivalents.append(HTMLElementEquivalent::create(CSSPropertyFontWeight, CSSValueBold, HTMLNames::strongTag));
7955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        HTMLElementEquivalents.append(HTMLElementEquivalent::create(CSSPropertyVerticalAlign, CSSValueSub, HTMLNames::subTag));
7965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        HTMLElementEquivalents.append(HTMLElementEquivalent::create(CSSPropertyVerticalAlign, CSSValueSuper, HTMLNames::supTag));
7975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        HTMLElementEquivalents.append(HTMLElementEquivalent::create(CSSPropertyFontStyle, CSSValueItalic, HTMLNames::iTag));
7985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        HTMLElementEquivalents.append(HTMLElementEquivalent::create(CSSPropertyFontStyle, CSSValueItalic, HTMLNames::emTag));
7995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        HTMLElementEquivalents.append(HTMLTextDecorationEquivalent::create(CSSValueUnderline, HTMLNames::uTag));
8015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        HTMLElementEquivalents.append(HTMLTextDecorationEquivalent::create(CSSValueLineThrough, HTMLNames::sTag));
8025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        HTMLElementEquivalents.append(HTMLTextDecorationEquivalent::create(CSSValueLineThrough, HTMLNames::strikeTag));
8035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return HTMLElementEquivalents;
8065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool EditingStyle::conflictsWithImplicitStyleOfElement(HTMLElement* element, EditingStyle* extractedStyle, ShouldExtractMatchingStyle shouldExtractMatchingStyle) const
8105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_mutableStyle)
8125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
8135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
814f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    const WillBeHeapVector<OwnPtrWillBeMember<HTMLElementEquivalent> >& HTMLElementEquivalents = htmlElementEquivalents();
8155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < HTMLElementEquivalents.size(); ++i) {
8165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const HTMLElementEquivalent* equivalent = HTMLElementEquivalents[i].get();
8175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (equivalent->matches(element) && equivalent->propertyExistsInStyle(m_mutableStyle.get())
8185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            && (shouldExtractMatchingStyle == ExtractMatchingStyle || !equivalent->valueIsPresentInStyle(element, m_mutableStyle.get()))) {
8195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (extractedStyle)
8205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                equivalent->addToStyle(element, extractedStyle);
8215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
8225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
8235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
8255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
827f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liustatic const WillBeHeapVector<OwnPtrWillBeMember<HTMLAttributeEquivalent> >& htmlAttributeEquivalents()
8285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
829f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    DEFINE_STATIC_LOCAL(WillBePersistentHeapVector<OwnPtrWillBeMember<HTMLAttributeEquivalent> >, HTMLAttributeEquivalents, ());
8305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!HTMLAttributeEquivalents.size()) {
8315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // elementIsStyledSpanOrHTMLEquivalent depends on the fact each HTMLAttriuteEquivalent matches exactly one attribute
8325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // of exactly one element except dirAttr.
8335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        HTMLAttributeEquivalents.append(HTMLAttributeEquivalent::create(CSSPropertyColor, HTMLNames::fontTag, HTMLNames::colorAttr));
8345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        HTMLAttributeEquivalents.append(HTMLAttributeEquivalent::create(CSSPropertyFontFamily, HTMLNames::fontTag, HTMLNames::faceAttr));
8355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        HTMLAttributeEquivalents.append(HTMLFontSizeEquivalent::create());
8365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        HTMLAttributeEquivalents.append(HTMLAttributeEquivalent::create(CSSPropertyDirection, HTMLNames::dirAttr));
8385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        HTMLAttributeEquivalents.append(HTMLAttributeEquivalent::create(CSSPropertyUnicodeBidi, HTMLNames::dirAttr));
8395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return HTMLAttributeEquivalents;
8425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool EditingStyle::conflictsWithImplicitStyleOfAttributes(HTMLElement* element) const
8455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(element);
8475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_mutableStyle)
8485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
8495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
850f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    const WillBeHeapVector<OwnPtrWillBeMember<HTMLAttributeEquivalent> >& HTMLAttributeEquivalents = htmlAttributeEquivalents();
8515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < HTMLAttributeEquivalents.size(); ++i) {
8525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (HTMLAttributeEquivalents[i]->matches(element) && HTMLAttributeEquivalents[i]->propertyExistsInStyle(m_mutableStyle.get())
8535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            && !HTMLAttributeEquivalents[i]->valueIsPresentInStyle(element, m_mutableStyle.get()))
8545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
8555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
8585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool EditingStyle::extractConflictingImplicitStyleOfAttributes(HTMLElement* element, ShouldPreserveWritingDirection shouldPreserveWritingDirection,
8615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    EditingStyle* extractedStyle, Vector<QualifiedName>& conflictingAttributes, ShouldExtractMatchingStyle shouldExtractMatchingStyle) const
8625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(element);
8645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // HTMLAttributeEquivalent::addToStyle doesn't support unicode-bidi and direction properties
8655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!extractedStyle || shouldPreserveWritingDirection == PreserveWritingDirection);
8665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_mutableStyle)
8675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
8685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
869f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    const WillBeHeapVector<OwnPtrWillBeMember<HTMLAttributeEquivalent> >& HTMLAttributeEquivalents = htmlAttributeEquivalents();
8705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool removed = false;
8715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < HTMLAttributeEquivalents.size(); ++i) {
8725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const HTMLAttributeEquivalent* equivalent = HTMLAttributeEquivalents[i].get();
8735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // unicode-bidi and direction are pushed down separately so don't push down with other styles.
8755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (shouldPreserveWritingDirection == PreserveWritingDirection && equivalent->attributeName() == HTMLNames::dirAttr)
8765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
8775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!equivalent->matches(element) || !equivalent->propertyExistsInStyle(m_mutableStyle.get())
8795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            || (shouldExtractMatchingStyle == DoNotExtractMatchingStyle && equivalent->valueIsPresentInStyle(element, m_mutableStyle.get())))
8805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
8815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (extractedStyle)
8835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            equivalent->addToStyle(element, extractedStyle);
8845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        conflictingAttributes.append(equivalent->attributeName());
8855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        removed = true;
8865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return removed;
8895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool EditingStyle::styleIsPresentInComputedStyleOfNode(Node* node) const
8925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return !m_mutableStyle || getPropertiesNotIn(m_mutableStyle.get(), CSSComputedStyleDeclaration::create(node).get())->isEmpty();
8945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool EditingStyle::elementIsStyledSpanOrHTMLEquivalent(const HTMLElement* element)
8975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
898d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(element);
8995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool elementIsSpanOrElementEquivalent = false;
900d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (isHTMLSpanElement(*element))
9015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        elementIsSpanOrElementEquivalent = true;
9025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else {
903f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        const WillBeHeapVector<OwnPtrWillBeMember<HTMLElementEquivalent> >& HTMLElementEquivalents = htmlElementEquivalents();
9045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        size_t i;
9055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (i = 0; i < HTMLElementEquivalents.size(); ++i) {
9065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (HTMLElementEquivalents[i]->matches(element)) {
9075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                elementIsSpanOrElementEquivalent = true;
9085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
9095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
9105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
9115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
913c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    AttributeCollection attributes = element->attributes();
914c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (attributes.isEmpty())
9155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return elementIsSpanOrElementEquivalent; // span, b, etc... without any attributes
9165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned matchedAttributes = 0;
918f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    const WillBeHeapVector<OwnPtrWillBeMember<HTMLAttributeEquivalent> >& HTMLAttributeEquivalents = htmlAttributeEquivalents();
9195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < HTMLAttributeEquivalents.size(); ++i) {
9205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (HTMLAttributeEquivalents[i]->matches(element) && HTMLAttributeEquivalents[i]->attributeName() != HTMLNames::dirAttr)
9215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            matchedAttributes++;
9225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!elementIsSpanOrElementEquivalent && !matchedAttributes)
9255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false; // element is not a span, a html element equivalent, or font element.
92602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
9275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (element->getAttribute(HTMLNames::classAttr) == AppleStyleSpanClass)
9285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        matchedAttributes++;
9295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (element->hasAttribute(HTMLNames::styleAttr)) {
9315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (const StylePropertySet* style = element->inlineStyle()) {
9325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            unsigned propertyCount = style->propertyCount();
9335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (unsigned i = 0; i < propertyCount; ++i) {
9345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (!isEditingProperty(style->propertyAt(i).id()))
9355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    return false;
9365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
9375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
9385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        matchedAttributes++;
9395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // font with color attribute, span with style attribute, etc...
942c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ASSERT(matchedAttributes <= attributes.size());
943c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return matchedAttributes >= attributes.size();
9445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void EditingStyle::prepareToApplyAt(const Position& position, ShouldPreserveWritingDirection shouldPreserveWritingDirection)
9475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_mutableStyle)
9495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
9505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // ReplaceSelectionCommand::handleStyleSpans() requires that this function only removes the editing style.
9525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If this function was modified in the future to delete all redundant properties, then add a boolean value to indicate
9535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // which one of editingStyleAtPosition or computedStyle is called.
954f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    RefPtrWillBeRawPtr<EditingStyle> editingStyleAtPosition = EditingStyle::create(position, EditingPropertiesInEffect);
9555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StylePropertySet* styleAtPosition = editingStyleAtPosition->m_mutableStyle.get();
9565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
95707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    RefPtrWillBeRawPtr<CSSValue> unicodeBidi = nullptr;
95807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    RefPtrWillBeRawPtr<CSSValue> direction = nullptr;
9595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (shouldPreserveWritingDirection == PreserveWritingDirection) {
9605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        unicodeBidi = m_mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
9615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        direction = m_mutableStyle->getPropertyCSSValue(CSSPropertyDirection);
9625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_mutableStyle->removeEquivalentProperties(styleAtPosition);
9655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (textAlignResolvingStartAndEnd(m_mutableStyle.get()) == textAlignResolvingStartAndEnd(styleAtPosition))
9675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_mutableStyle->removeProperty(CSSPropertyTextAlign);
9685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (getRGBAFontColor(m_mutableStyle.get()) == getRGBAFontColor(styleAtPosition))
9705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_mutableStyle->removeProperty(CSSPropertyColor);
9715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasTransparentBackgroundColor(m_mutableStyle.get())
9735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || cssValueToRGBA(m_mutableStyle->getPropertyCSSValue(CSSPropertyBackgroundColor).get()) == rgbaBackgroundColorInEffect(position.containerNode()))
9745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_mutableStyle->removeProperty(CSSPropertyBackgroundColor);
9755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (unicodeBidi && unicodeBidi->isPrimitiveValue()) {
9775267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        m_mutableStyle->setProperty(CSSPropertyUnicodeBidi, toCSSPrimitiveValue(unicodeBidi.get())->getValueID());
9785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (direction && direction->isPrimitiveValue())
9795267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            m_mutableStyle->setProperty(CSSPropertyDirection, toCSSPrimitiveValue(direction.get())->getValueID());
9805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void EditingStyle::mergeTypingStyle(Document* document)
9845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(document);
9865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
987f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    RefPtrWillBeRawPtr<EditingStyle> typingStyle = document->frame()->selection().typingStyle();
9885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!typingStyle || typingStyle == this)
9895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
9905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    mergeStyle(typingStyle->style(), OverrideValues);
9925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
994c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void EditingStyle::mergeInlineStyleOfElement(HTMLElement* element, CSSPropertyOverrideMode mode, PropertiesToInclude propertiesToInclude)
9955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(element);
9975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!element->inlineStyle())
9985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
9995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (propertiesToInclude) {
10015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case AllProperties:
10025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        mergeStyle(element->inlineStyle(), mode);
10035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
10045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case OnlyEditingInheritableProperties:
10055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        mergeStyle(copyEditingProperties(element->inlineStyle(), OnlyInheritableEditingProperties).get(), mode);
10065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
10075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case EditingPropertiesInEffect:
10085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        mergeStyle(copyEditingProperties(element->inlineStyle(), AllEditingProperties).get(), mode);
10095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
10105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1013591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic inline bool elementMatchesAndPropertyIsNotInInlineStyleDecl(const HTMLElementEquivalent* equivalent, const Element* element,
10145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    EditingStyle::CSSPropertyOverrideMode mode, StylePropertySet* style)
10155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1016926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return equivalent->matches(element) && (!element->inlineStyle() || !equivalent->propertyExistsInStyle(element->inlineStyle()))
10175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        && (mode == EditingStyle::OverrideValues || !equivalent->propertyExistsInStyle(style));
10185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
102043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)static PassRefPtrWillBeRawPtr<MutableStylePropertySet> extractEditingProperties(const StylePropertySet* style, EditingStyle::PropertiesToInclude propertiesToInclude)
10213c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{
10223c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    if (!style)
1023d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
10243c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
10253c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    switch (propertiesToInclude) {
10263c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    case EditingStyle::AllProperties:
10273c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    case EditingStyle::EditingPropertiesInEffect:
10283c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return copyEditingProperties(style, AllEditingProperties);
10293c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    case EditingStyle::OnlyEditingInheritableProperties:
10303c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return copyEditingProperties(style, OnlyInheritableEditingProperties);
10313c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    }
10323c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
10333c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    ASSERT_NOT_REACHED();
1034d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return nullptr;
10353c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch}
10363c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
1037591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid EditingStyle::mergeInlineAndImplicitStyleOfElement(Element* element, CSSPropertyOverrideMode mode, PropertiesToInclude propertiesToInclude)
10385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1039f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    RefPtrWillBeRawPtr<EditingStyle> styleFromRules = EditingStyle::create();
10405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    styleFromRules->mergeStyleFromRulesForSerialization(element);
1041c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
1042c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (element->inlineStyle())
1043c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        styleFromRules->m_mutableStyle->mergeAndOverrideOnConflict(element->inlineStyle());
1044c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
10453c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    styleFromRules->m_mutableStyle = extractEditingProperties(styleFromRules->m_mutableStyle.get(), propertiesToInclude);
10465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    mergeStyle(styleFromRules->m_mutableStyle.get(), mode);
10475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1048f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    const WillBeHeapVector<OwnPtrWillBeMember<HTMLElementEquivalent> >& elementEquivalents = htmlElementEquivalents();
10495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < elementEquivalents.size(); ++i) {
10505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (elementMatchesAndPropertyIsNotInInlineStyleDecl(elementEquivalents[i].get(), element, mode, m_mutableStyle.get()))
10515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            elementEquivalents[i]->addToStyle(element, this);
10525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1054f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    const WillBeHeapVector<OwnPtrWillBeMember<HTMLAttributeEquivalent> >& attributeEquivalents = htmlAttributeEquivalents();
10555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < attributeEquivalents.size(); ++i) {
10565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (attributeEquivalents[i]->attributeName() == HTMLNames::dirAttr)
10575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue; // We don't want to include directionality
10585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (elementMatchesAndPropertyIsNotInInlineStyleDecl(attributeEquivalents[i].get(), element, mode, m_mutableStyle.get()))
10595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            attributeEquivalents[i]->addToStyle(element, this);
10605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1063c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)PassRefPtrWillBeRawPtr<EditingStyle> EditingStyle::wrappingStyleForSerialization(ContainerNode* context, bool shouldAnnotate)
10645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1065f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    RefPtrWillBeRawPtr<EditingStyle> wrappingStyle = nullptr;
10665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (shouldAnnotate) {
10675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        wrappingStyle = EditingStyle::create(context, EditingStyle::EditingPropertiesInEffect);
10685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Styles that Mail blockquotes contribute should only be placed on the Mail blockquote,
10705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // to help us differentiate those styles from ones that the user has applied.
10715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // This helps us get the color of content pasted into blockquotes right.
1072c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        wrappingStyle->removeStyleAddedByElement(toHTMLElement(enclosingNodeOfType(firstPositionInOrBeforeNode(context), isMailHTMLBlockquoteElement, CanCrossEditingBoundary)));
10735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Call collapseTextDecorationProperties first or otherwise it'll copy the value over from in-effect to text-decorations.
10755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        wrappingStyle->collapseTextDecorationProperties();
107602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
10775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return wrappingStyle.release();
10785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    wrappingStyle = EditingStyle::create();
10815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // When not annotating for interchange, we only preserve inline style declarations.
1083c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    for (ContainerNode* node = context; node && !node->isDocumentNode(); node = node->parentNode()) {
1084c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (node->isStyledElement() && !isMailHTMLBlockquoteElement(node)) {
1085591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch            wrappingStyle->mergeInlineAndImplicitStyleOfElement(toElement(node), EditingStyle::DoNotOverrideValues,
10865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                EditingStyle::EditingPropertiesInEffect);
10875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
10885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return wrappingStyle.release();
10915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void mergeTextDecorationValues(CSSValueList* mergedValue, const CSSValueList* valueToMerge)
10955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1096197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    DEFINE_STATIC_REF_WILL_BE_PERSISTENT(CSSPrimitiveValue, underline, (CSSPrimitiveValue::createIdentifier(CSSValueUnderline)));
1097197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    DEFINE_STATIC_REF_WILL_BE_PERSISTENT(CSSPrimitiveValue, lineThrough, (CSSPrimitiveValue::createIdentifier(CSSValueLineThrough)));
109851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (valueToMerge->hasValue(underline) && !mergedValue->hasValue(underline))
109951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        mergedValue->append(underline);
11005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
110151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (valueToMerge->hasValue(lineThrough) && !mergedValue->hasValue(lineThrough))
110251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        mergedValue->append(lineThrough);
11035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void EditingStyle::mergeStyle(const StylePropertySet* style, CSSPropertyOverrideMode mode)
11065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!style)
11085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_mutableStyle) {
111193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        m_mutableStyle = style->mutableCopy();
11125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned propertyCount = style->propertyCount();
11165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0; i < propertyCount; ++i) {
11175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        StylePropertySet::PropertyReference property = style->propertyAt(i);
1118d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        RefPtrWillBeRawPtr<CSSValue> value = m_mutableStyle->getPropertyCSSValue(property.id());
11195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // text decorations never override values
1121e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        if ((property.id() == textDecorationPropertyForEditing() || property.id() == CSSPropertyWebkitTextDecorationsInEffect) && property.value()->isValueList() && value) {
11225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (value->isValueList()) {
11233c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch                mergeTextDecorationValues(toCSSValueList(value.get()), toCSSValueList(property.value()));
11245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
11255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
1126d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            value = nullptr; // text-decoration: none is equivalent to not having the property
11275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
11285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (mode == OverrideValues || (mode == DoNotOverrideValues && !value))
11305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_mutableStyle->setProperty(property.id(), property.value()->cssText(), property.isImportant());
11315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
113443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)static PassRefPtrWillBeRawPtr<MutableStylePropertySet> styleFromMatchedRulesForElement(Element* element, unsigned rulesToInclude)
11355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
113643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
113707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    RefPtrWillBeRawPtr<StyleRuleList> matchedRules = element->document().ensureStyleResolver().styleRulesForElement(element, rulesToInclude);
11385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (matchedRules) {
113919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        for (unsigned i = 0; i < matchedRules->m_list.size(); ++i)
1140d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            style->mergeAndOverrideOnConflict(&matchedRules->m_list[i]->properties());
11415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return style.release();
11435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1145591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid EditingStyle::mergeStyleFromRules(Element* element)
11465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
114743e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    RefPtrWillBeRawPtr<MutableStylePropertySet> styleFromMatchedRules = styleFromMatchedRulesForElement(element,
11485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        StyleResolver::AuthorCSSRules | StyleResolver::CrossOriginCSSRules);
114902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    // Styles from the inline style declaration, held in the variable "style", take precedence
11505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // over those from matched rules.
11515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_mutableStyle)
11525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        styleFromMatchedRules->mergeAndOverrideOnConflict(m_mutableStyle.get());
11535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    clear();
11555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_mutableStyle = styleFromMatchedRules;
11565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1158591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid EditingStyle::mergeStyleFromRulesForSerialization(Element* element)
11595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    mergeStyleFromRules(element);
11615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
116202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    // The property value, if it's a percentage, may not reflect the actual computed value.
11635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // For example: style="height: 1%; overflow: visible;" in quirksmode
11645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: There are others like this, see <rdar://problem/5195123> Slashdot copy/paste fidelity problem
1165323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> computedStyleForElement = CSSComputedStyleDeclaration::create(element);
116643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    RefPtrWillBeRawPtr<MutableStylePropertySet> fromComputedStyle = MutableStylePropertySet::create();
11675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
11685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        unsigned propertyCount = m_mutableStyle->propertyCount();
11695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (unsigned i = 0; i < propertyCount; ++i) {
11705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            StylePropertySet::PropertyReference property = m_mutableStyle->propertyAt(i);
11715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            CSSValue* value = property.value();
11725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!value->isPrimitiveValue())
11735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
11743c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch            if (toCSSPrimitiveValue(value)->isPercentage()) {
1175d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (RefPtrWillBeRawPtr<CSSValue> computedPropertyValue = computedStyleForElement->getPropertyCSSValue(property.id()))
11765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    fromComputedStyle->addParsedProperty(CSSProperty(property.id(), computedPropertyValue));
11775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
11785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
11795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_mutableStyle->mergeAndOverrideOnConflict(fromComputedStyle.get());
11815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
118393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)static void removePropertiesInStyle(MutableStylePropertySet* styleToRemovePropertiesFrom, StylePropertySet* style)
11845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned propertyCount = style->propertyCount();
11865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<CSSPropertyID> propertiesToRemove(propertyCount);
11875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0; i < propertyCount; ++i)
11885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        propertiesToRemove[i] = style->propertyAt(i).id();
11895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    styleToRemovePropertiesFrom->removePropertiesInSet(propertiesToRemove.data(), propertiesToRemove.size());
11915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1193c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void EditingStyle::removeStyleFromRulesAndContext(Element* element, ContainerNode* context)
11945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(element);
11965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_mutableStyle)
11975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // 1. Remove style from matched rules because style remain without repeating it in inline style declaration
120043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    RefPtrWillBeRawPtr<MutableStylePropertySet> styleFromMatchedRules = styleFromMatchedRulesForElement(element, StyleResolver::AllButEmptyCSSRules);
12015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (styleFromMatchedRules && !styleFromMatchedRules->isEmpty())
12025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_mutableStyle = getPropertiesNotIn(m_mutableStyle.get(), styleFromMatchedRules->ensureCSSStyleDeclaration());
12035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // 2. Remove style present in context and not overriden by matched rules.
1205f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    RefPtrWillBeRawPtr<EditingStyle> computedStyle = EditingStyle::create(context, EditingPropertiesInEffect);
12065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (computedStyle->m_mutableStyle) {
12075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!computedStyle->m_mutableStyle->getPropertyCSSValue(CSSPropertyBackgroundColor))
12085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            computedStyle->m_mutableStyle->setProperty(CSSPropertyBackgroundColor, CSSValueTransparent);
12095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        removePropertiesInStyle(computedStyle->m_mutableStyle.get(), styleFromMatchedRules.get());
12115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_mutableStyle = getPropertiesNotIn(m_mutableStyle.get(), computedStyle->m_mutableStyle->ensureCSSStyleDeclaration());
12125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
12135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // 3. If this element is a span and has display: inline or float: none, remove them unless they are overriden by rules.
12155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // These rules are added by serialization code to wrap text nodes.
12165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isStyleSpanOrSpanWithOnlyStyleAttribute(element)) {
12175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!styleFromMatchedRules->getPropertyCSSValue(CSSPropertyDisplay) && getIdentifierValue(m_mutableStyle.get(), CSSPropertyDisplay) == CSSValueInline)
12185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_mutableStyle->removeProperty(CSSPropertyDisplay);
12195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!styleFromMatchedRules->getPropertyCSSValue(CSSPropertyFloat) && getIdentifierValue(m_mutableStyle.get(), CSSPropertyFloat) == CSSValueNone)
12205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_mutableStyle->removeProperty(CSSPropertyFloat);
12215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
12225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void EditingStyle::removePropertiesInElementDefaultStyle(Element* element)
12255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
12265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_mutableStyle || m_mutableStyle->isEmpty())
12275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
12285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1229197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    RefPtrWillBeRawPtr<StylePropertySet> defaultStyle = styleFromMatchedRulesForElement(element, StyleResolver::UAAndUserCSSRules);
12305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    removePropertiesInStyle(m_mutableStyle.get(), defaultStyle.get());
12325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1234197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid EditingStyle::addAbsolutePositioningFromElement(const Element& element)
1235197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
1236197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    LayoutRect rect = element.boundingBox();
1237197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    RenderObject* renderer = element.renderer();
1238197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
1239197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    LayoutUnit x = rect.x();
1240197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    LayoutUnit y = rect.y();
1241197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    LayoutUnit width = rect.width();
1242197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    LayoutUnit height = rect.height();
1243197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (renderer && renderer->isBox()) {
1244197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        RenderBox* renderBox = toRenderBox(renderer);
1245197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
1246197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        x -= renderBox->marginLeft();
1247197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        y -= renderBox->marginTop();
1248197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
1249197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        m_mutableStyle->setProperty(CSSPropertyBoxSizing, CSSValueBorderBox);
1250197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
1251197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
1252197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    m_mutableStyle->setProperty(CSSPropertyPosition, CSSValueAbsolute);
1253197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    m_mutableStyle->setProperty(CSSPropertyLeft, cssValuePool().createValue(x, CSSPrimitiveValue::CSS_PX));
1254197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    m_mutableStyle->setProperty(CSSPropertyTop, cssValuePool().createValue(y, CSSPrimitiveValue::CSS_PX));
1255197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    m_mutableStyle->setProperty(CSSPropertyWidth, cssValuePool().createValue(width, CSSPrimitiveValue::CSS_PX));
1256197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    m_mutableStyle->setProperty(CSSPropertyHeight, cssValuePool().createValue(height, CSSPrimitiveValue::CSS_PX));
1257197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
1258197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
12595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void EditingStyle::forceInline()
12605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
12615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_mutableStyle)
126293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        m_mutableStyle = MutableStylePropertySet::create();
12635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const bool propertyIsImportant = true;
12645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_mutableStyle->setProperty(CSSPropertyDisplay, CSSValueInline, propertyIsImportant);
12655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int EditingStyle::legacyFontSize(Document* document) const
12685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1269d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtrWillBeRawPtr<CSSValue> cssValue = m_mutableStyle->getPropertyCSSValue(CSSPropertyFontSize);
12705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!cssValue || !cssValue->isPrimitiveValue())
12715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
12723c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    return legacyFontSizeFromCSSValue(document, toCSSPrimitiveValue(cssValue.get()),
1273197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        m_fixedPitchFontType, AlwaysUseLegacyFontSize);
12745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1276f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)PassRefPtrWillBeRawPtr<EditingStyle> EditingStyle::styleAtSelectionStart(const VisibleSelection& selection, bool shouldUseBackgroundColorInEffect)
12775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
12785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (selection.isNone())
1279d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
12805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Position position = adjustedSelectionStartForStyleComputation(selection);
12825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
128302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    // If the pos is at the end of a text node, then this node is not fully selected.
128402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    // Move it to the next deep equivalent position to avoid removing the style from this node.
128502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    // e.g. if pos was at Position("hello", 5) in <b>hello<div>world</div></b>, we want Position("world", 0) instead.
128602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    // We only do this for range because caret at Position("hello", 5) in <b>hello</b>world should give you font-weight: bold.
128702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    Node* positionNode = position.containerNode();
128802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    if (selection.isRange() && positionNode && positionNode->isTextNode() && position.computeOffsetInContainerNode() == positionNode->maxCharacterOffset())
128902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        position = nextVisuallyDistinctCandidate(position);
12905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Element* element = position.element();
12925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!element)
1293d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
12945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1295f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    RefPtrWillBeRawPtr<EditingStyle> style = EditingStyle::create(element, EditingStyle::AllProperties);
12968abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    style->mergeTypingStyle(&element->document());
12975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If background color is transparent, traverse parent nodes until we hit a different value or document root
12995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Also, if the selection is a range, ignore the background color at the start of selection,
13005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // and find the background color of the common ancestor.
13015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (shouldUseBackgroundColorInEffect && (selection.isRange() || hasTransparentBackgroundColor(style->m_mutableStyle.get()))) {
1302a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        RefPtrWillBeRawPtr<Range> range(selection.toNormalizedRange());
1303f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        if (PassRefPtrWillBeRawPtr<CSSValue> value = backgroundColorInEffect(range->commonAncestorContainer()))
13045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            style->setProperty(CSSPropertyBackgroundColor, value->cssText());
13055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
13065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return style;
13085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WritingDirection EditingStyle::textDirectionForSelection(const VisibleSelection& selection, EditingStyle* typingStyle, bool& hasNestedOrMultipleEmbeddings)
13115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    hasNestedOrMultipleEmbeddings = true;
13135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (selection.isNone())
13155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return NaturalWritingDirection;
13165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Position position = selection.start().downstream();
13185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* node = position.deprecatedNode();
13205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node)
13215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return NaturalWritingDirection;
13225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Position end;
13245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (selection.isRange()) {
13255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        end = selection.end().upstream();
13265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13278abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        ASSERT(end.document());
13288abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        Node* pastLast = Range::create(*end.document(), position.parentAnchoredEquivalent(), end.parentAnchoredEquivalent())->pastLastNode();
132951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        for (Node* n = node; n && n != pastLast; n = NodeTraversal::next(*n)) {
13305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!n->isStyledElement())
13315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
13325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1333323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> style = CSSComputedStyleDeclaration::create(n);
1334d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            RefPtrWillBeRawPtr<CSSValue> unicodeBidi = style->getPropertyCSSValue(CSSPropertyUnicodeBidi);
13355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!unicodeBidi || !unicodeBidi->isPrimitiveValue())
13365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
13375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13385267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            CSSValueID unicodeBidiValue = toCSSPrimitiveValue(unicodeBidi.get())->getValueID();
13395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (unicodeBidiValue == CSSValueEmbed || unicodeBidiValue == CSSValueBidiOverride)
13405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return NaturalWritingDirection;
13415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
13425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
13435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (selection.isCaret()) {
13455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        WritingDirection direction;
13465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (typingStyle && typingStyle->textDirection(direction)) {
13475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            hasNestedOrMultipleEmbeddings = false;
13485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return direction;
13495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
13505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        node = selection.visibleStart().deepEquivalent().deprecatedNode();
13515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
13525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The selection is either a caret with no typing attributes or a range in which no embedding is added, so just use the start position
13545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // to decide.
13555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* block = enclosingBlock(node);
13565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    WritingDirection foundDirection = NaturalWritingDirection;
13575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (; node != block; node = node->parentNode()) {
13595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!node->isStyledElement())
13605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
13615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1362c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        Element* element = toElement(node);
1363c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> style = CSSComputedStyleDeclaration::create(element);
1364d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        RefPtrWillBeRawPtr<CSSValue> unicodeBidi = style->getPropertyCSSValue(CSSPropertyUnicodeBidi);
13655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!unicodeBidi || !unicodeBidi->isPrimitiveValue())
13665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
13675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13685267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        CSSValueID unicodeBidiValue = toCSSPrimitiveValue(unicodeBidi.get())->getValueID();
13695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (unicodeBidiValue == CSSValueNormal)
13705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
13715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (unicodeBidiValue == CSSValueBidiOverride)
13735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return NaturalWritingDirection;
13745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(unicodeBidiValue == CSSValueEmbed);
1376d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        RefPtrWillBeRawPtr<CSSValue> direction = style->getPropertyCSSValue(CSSPropertyDirection);
13775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!direction || !direction->isPrimitiveValue())
13785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
13795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13805267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        int directionValue = toCSSPrimitiveValue(direction.get())->getValueID();
13815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (directionValue != CSSValueLtr && directionValue != CSSValueRtl)
13825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
13835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (foundDirection != NaturalWritingDirection)
13855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return NaturalWritingDirection;
13865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // In the range case, make sure that the embedding element persists until the end of the range.
1388c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (selection.isRange() && !end.deprecatedNode()->isDescendantOf(element))
13895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return NaturalWritingDirection;
139002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
13915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        foundDirection = directionValue == CSSValueLtr ? LeftToRightWritingDirection : RightToLeftWritingDirection;
13925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
13935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    hasNestedOrMultipleEmbeddings = false;
13945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return foundDirection;
13955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1397f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)void EditingStyle::trace(Visitor* visitor)
1398f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
1399f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    visitor->trace(m_mutableStyle);
1400f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
1401f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
140293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)static void reconcileTextDecorationProperties(MutableStylePropertySet* style)
140302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch{
1404d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtrWillBeRawPtr<CSSValue> textDecorationsInEffect = style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
1405d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtrWillBeRawPtr<CSSValue> textDecoration = style->getPropertyCSSValue(textDecorationPropertyForEditing());
14065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We shouldn't have both text-decoration and -webkit-text-decorations-in-effect because that wouldn't make sense.
14075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!textDecorationsInEffect || !textDecoration);
14085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (textDecorationsInEffect) {
1409e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        style->setProperty(textDecorationPropertyForEditing(), textDecorationsInEffect->cssText());
14105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        style->removeProperty(CSSPropertyWebkitTextDecorationsInEffect);
14115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        textDecoration = textDecorationsInEffect;
14125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
14135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If text-decoration is set to "none", remove the property because we don't want to add redundant "text-decoration: none".
14155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (textDecoration && !textDecoration->isValueList())
1416e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        style->removeProperty(textDecorationPropertyForEditing());
14175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)StyleChange::StyleChange(EditingStyle* style, const Position& position)
14205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : m_applyBold(false)
14215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_applyItalic(false)
14225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_applyUnderline(false)
14235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_applyLineThrough(false)
14245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_applySubscript(false)
14255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_applySuperscript(false)
14265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
14278abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    Document* document = position.document();
14285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!style || !style->style() || !document || !document->frame())
14295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
14305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1431323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> computedStyle = position.computedStyle();
14325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: take care of background-color in effect
143343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    RefPtrWillBeRawPtr<MutableStylePropertySet> mutableStyle = getPropertiesNotIn(style->style(), computedStyle.get());
14345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    reconcileTextDecorationProperties(mutableStyle.get());
1436c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    if (!document->frame()->editor().shouldStyleWithCSS())
1437197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        extractTextStyles(document, mutableStyle.get(), computedStyle->fixedPitchFontType());
14385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Changing the whitespace style in a tab span would collapse the tab into a space.
1440c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (isTabHTMLSpanElementTextNode(position.deprecatedNode()) || isTabHTMLSpanElement((position.deprecatedNode())))
14415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        mutableStyle->removeProperty(CSSPropertyWhiteSpace);
14425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If unicode-bidi is present in mutableStyle and direction is not, then add direction to mutableStyle.
14445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: Shouldn't this be done in getPropertiesNotIn?
14455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi) && !style->style()->getPropertyCSSValue(CSSPropertyDirection))
14465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        mutableStyle->setProperty(CSSPropertyDirection, style->style()->getPropertyValue(CSSPropertyDirection));
14475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Save the result for later
14495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_cssStyle = mutableStyle->asText().stripWhiteSpace();
14505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
145293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)static void setTextDecorationProperty(MutableStylePropertySet* style, const CSSValueList* newTextDecoration, CSSPropertyID propertyID)
14535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
14545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (newTextDecoration->length())
14555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        style->setProperty(propertyID, newTextDecoration->cssText(), style->propertyIsImportant(propertyID));
14565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else {
14575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // text-decoration: none is redundant since it does not remove any text decorations.
14585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        style->removeProperty(propertyID);
14595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
14605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1462197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid StyleChange::extractTextStyles(Document* document, MutableStylePropertySet* style, FixedPitchFontType fixedPitchFontType)
14635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
14645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(style);
14655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (getIdentifierValue(style, CSSPropertyFontWeight) == CSSValueBold) {
14675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        style->removeProperty(CSSPropertyFontWeight);
14685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_applyBold = true;
14695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
14705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int fontStyle = getIdentifierValue(style, CSSPropertyFontStyle);
14725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (fontStyle == CSSValueItalic || fontStyle == CSSValueOblique) {
14735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        style->removeProperty(CSSPropertyFontStyle);
14745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_applyItalic = true;
14755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
14765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Assuming reconcileTextDecorationProperties has been called, there should not be -webkit-text-decorations-in-effect
14785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Furthermore, text-decoration: none has been trimmed so that text-decoration property is always a CSSValueList.
1479d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtrWillBeRawPtr<CSSValue> textDecoration = style->getPropertyCSSValue(textDecorationPropertyForEditing());
14805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (textDecoration && textDecoration->isValueList()) {
1481197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        DEFINE_STATIC_REF_WILL_BE_PERSISTENT(CSSPrimitiveValue, underline, (CSSPrimitiveValue::createIdentifier(CSSValueUnderline)));
1482197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        DEFINE_STATIC_REF_WILL_BE_PERSISTENT(CSSPrimitiveValue, lineThrough, (CSSPrimitiveValue::createIdentifier(CSSValueLineThrough)));
148309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        RefPtrWillBeRawPtr<CSSValueList> newTextDecoration = toCSSValueList(textDecoration.get())->copy();
148451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (newTextDecoration->removeAll(underline))
14855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_applyUnderline = true;
148651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (newTextDecoration->removeAll(lineThrough))
14875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_applyLineThrough = true;
14885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If trimTextDecorations, delete underline and line-through
1490e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        setTextDecorationProperty(style, newTextDecoration.get(), textDecorationPropertyForEditing());
14915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
14925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int verticalAlign = getIdentifierValue(style, CSSPropertyVerticalAlign);
14945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (verticalAlign) {
14955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSValueSub:
14965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        style->removeProperty(CSSPropertyVerticalAlign);
14975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_applySubscript = true;
14985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
14995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSValueSuper:
15005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        style->removeProperty(CSSPropertyVerticalAlign);
15015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_applySuperscript = true;
15025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
15035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
15045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (style->getPropertyCSSValue(CSSPropertyColor)) {
15065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_applyFontColor = Color(getRGBAFontColor(style)).serialized();
15075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        style->removeProperty(CSSPropertyColor);
15085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
15095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_applyFontFace = style->getPropertyValue(CSSPropertyFontFamily);
15115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Remove single quotes for Outlook 2007 compatibility. See https://bugs.webkit.org/show_bug.cgi?id=79448
15125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_applyFontFace.replaceWithLiteral('\'', "");
15135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    style->removeProperty(CSSPropertyFontFamily);
15145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1515d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (RefPtrWillBeRawPtr<CSSValue> fontSize = style->getPropertyCSSValue(CSSPropertyFontSize)) {
1516197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (!fontSize->isPrimitiveValue()) {
15175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            style->removeProperty(CSSPropertyFontSize); // Can't make sense of the number. Put no font size.
1518197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        } else if (int legacyFontSize = legacyFontSizeFromCSSValue(document, toCSSPrimitiveValue(fontSize.get()), fixedPitchFontType, UseLegacyFontSizeOnlyIfPixelValuesMatch)) {
15195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_applyFontSize = String::number(legacyFontSize);
15205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            style->removeProperty(CSSPropertyFontSize);
15215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
15225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
15235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
152593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)static void diffTextDecorations(MutableStylePropertySet* style, CSSPropertyID propertID, CSSValue* refTextDecoration)
15265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1527d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtrWillBeRawPtr<CSSValue> textDecoration = style->getPropertyCSSValue(propertID);
15285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!textDecoration || !textDecoration->isValueList() || !refTextDecoration || !refTextDecoration->isValueList())
15295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
15305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
153109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    RefPtrWillBeRawPtr<CSSValueList> newTextDecoration = toCSSValueList(textDecoration.get())->copy();
15323c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    CSSValueList* valuesInRefTextDecoration = toCSSValueList(refTextDecoration);
15335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < valuesInRefTextDecoration->length(); i++)
15355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        newTextDecoration->removeAll(valuesInRefTextDecoration->item(i));
15365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setTextDecorationProperty(style, newTextDecoration.get(), propertID);
15385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool fontWeightIsBold(CSSValue* fontWeight)
15415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!fontWeight->isPrimitiveValue())
15435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
15445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Because b tag can only bold text, there are only two states in plain html: bold and not bold.
15465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Collapse all other values to either one of these two states for editing purposes.
15475267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    switch (toCSSPrimitiveValue(fontWeight)->getValueID()) {
15485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSValue100:
15495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSValue200:
15505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSValue300:
15515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSValue400:
15525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSValue500:
15535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSValueNormal:
15545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
15555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSValueBold:
15565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSValue600:
15575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSValue700:
15585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSValue800:
15595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSValue900:
15605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
15615267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        default:
15625267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            break;
15635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
15645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT_NOT_REACHED(); // For CSSValueBolder and CSSValueLighter
15665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
15675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1569e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)static bool fontWeightNeedsResolving(CSSValue* fontWeight)
15705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1571e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    if (!fontWeight->isPrimitiveValue())
1572e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        return true;
15735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1574e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    CSSValueID value = toCSSPrimitiveValue(fontWeight)->getValueID();
1575e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    return value == CSSValueLighter || value == CSSValueBolder;
15765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
157843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)PassRefPtrWillBeRawPtr<MutableStylePropertySet> getPropertiesNotIn(StylePropertySet* styleWithRedundantProperties, CSSStyleDeclaration* baseStyle)
15795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(styleWithRedundantProperties);
15815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(baseStyle);
158243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    RefPtrWillBeRawPtr<MutableStylePropertySet> result = styleWithRedundantProperties->mutableCopy();
15835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    result->removeEquivalentProperties(baseStyle);
15855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1586d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtrWillBeRawPtr<CSSValue> baseTextDecorationsInEffect = baseStyle->getPropertyCSSValueInternal(CSSPropertyWebkitTextDecorationsInEffect);
1587e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    diffTextDecorations(result.get(), textDecorationPropertyForEditing(), baseTextDecorationsInEffect.get());
15885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    diffTextDecorations(result.get(), CSSPropertyWebkitTextDecorationsInEffect, baseTextDecorationsInEffect.get());
15895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1590d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (RefPtrWillBeRawPtr<CSSValue> baseFontWeight = baseStyle->getPropertyCSSValueInternal(CSSPropertyFontWeight)) {
1591d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (RefPtrWillBeRawPtr<CSSValue> fontWeight = result->getPropertyCSSValue(CSSPropertyFontWeight)) {
1592e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            if (!fontWeightNeedsResolving(fontWeight.get()) && (fontWeightIsBold(fontWeight.get()) == fontWeightIsBold(baseFontWeight.get())))
1593e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                result->removeProperty(CSSPropertyFontWeight);
1594e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        }
1595e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    }
15965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (baseStyle->getPropertyCSSValueInternal(CSSPropertyColor) && getRGBAFontColor(result.get()) == getRGBAFontColor(baseStyle))
15985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result->removeProperty(CSSPropertyColor);
15995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (baseStyle->getPropertyCSSValueInternal(CSSPropertyTextAlign)
16015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        && textAlignResolvingStartAndEnd(result.get()) == textAlignResolvingStartAndEnd(baseStyle))
16025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result->removeProperty(CSSPropertyTextAlign);
16035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (baseStyle->getPropertyCSSValueInternal(CSSPropertyBackgroundColor) && getRGBABackgroundColor(result.get()) == getRGBABackgroundColor(baseStyle))
16055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result->removeProperty(CSSPropertyBackgroundColor);
16065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
160793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return result.release();
16085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16105267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)CSSValueID getIdentifierValue(StylePropertySet* style, CSSPropertyID propertyID)
16115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
16125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!style)
16135267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return CSSValueInvalid;
1614d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtrWillBeRawPtr<CSSValue> value = style->getPropertyCSSValue(propertyID);
16155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!value || !value->isPrimitiveValue())
16165267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return CSSValueInvalid;
16175267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    return toCSSPrimitiveValue(value.get())->getValueID();
16185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16205267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)CSSValueID getIdentifierValue(CSSStyleDeclaration* style, CSSPropertyID propertyID)
16215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
16225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!style)
16235267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return CSSValueInvalid;
1624d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtrWillBeRawPtr<CSSValue> value = style->getPropertyCSSValueInternal(propertyID);
16255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!value || !value->isPrimitiveValue())
16265267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return CSSValueInvalid;
16275267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    return toCSSPrimitiveValue(value.get())->getValueID();
16285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool isCSSValueLength(CSSPrimitiveValue* value)
16315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
16325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return value->isFontIndependentLength();
16335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1635197021e6b966cfb06891637935ef33fff06433d1Ben Murdochint legacyFontSizeFromCSSValue(Document* document, CSSPrimitiveValue* value, FixedPitchFontType fixedPitchFontType, LegacyFontSizeMode mode)
16365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
16375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isCSSValueLength(value)) {
16385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int pixelFontSize = value->getIntValue(CSSPrimitiveValue::CSS_PX);
1639197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        int legacyFontSize = FontSize::legacyFontSize(document, pixelFontSize, fixedPitchFontType);
16405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Use legacy font size only if pixel value matches exactly to that of legacy font size.
16417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (mode == AlwaysUseLegacyFontSize || FontSize::fontSizeForKeyword(document, legacyFontSize, fixedPitchFontType) == pixelFontSize)
16425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return legacyFontSize;
16435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
16455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
16465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16475267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    if (CSSValueXSmall <= value->getValueID() && value->getValueID() <= CSSValueWebkitXxxLarge)
16485267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return value->getValueID() - CSSValueXSmall + 1;
16495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
16515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool isTransparentColorValue(CSSValue* cssValue)
16545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
16555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!cssValue)
16565267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return true;
16575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!cssValue->isPrimitiveValue())
16585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
16595267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    CSSPrimitiveValue* value = toCSSPrimitiveValue(cssValue);
16605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (value->isRGBColor())
16615267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return !alphaChannel(value->getRGBA32Value());
16625267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    return value->getValueID() == CSSValueTransparent;
16635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool hasTransparentBackgroundColor(CSSStyleDeclaration* style)
16665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1667d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtrWillBeRawPtr<CSSValue> cssValue = style->getPropertyCSSValueInternal(CSSPropertyBackgroundColor);
16685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return isTransparentColorValue(cssValue.get());
16695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
167002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
16715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool hasTransparentBackgroundColor(StylePropertySet* style)
16725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1673d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtrWillBeRawPtr<CSSValue> cssValue = style->getPropertyCSSValue(CSSPropertyBackgroundColor);
16745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return isTransparentColorValue(cssValue.get());
16755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1677d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)PassRefPtrWillBeRawPtr<CSSValue> backgroundColorInEffect(Node* node)
16785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
16795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (Node* ancestor = node; ancestor; ancestor = ancestor->parentNode()) {
1680323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> ancestorStyle = CSSComputedStyleDeclaration::create(ancestor);
16815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!hasTransparentBackgroundColor(ancestorStyle.get()))
16825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return ancestorStyle->getPropertyCSSValue(CSSPropertyBackgroundColor);
16835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1684d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return nullptr;
16855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1688