Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Unified Diff: third_party/WebKit/Source/core/editing/EditingStyleUtilities.cpp

Issue 2685783004: Add EditingStyleUtitilies.{cpp,h} to BUILD.gn (Closed)
Patch Set: keep the original copyright comment Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/core/editing/EditingStyleUtilities.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/editing/EditingStyleUtilities.cpp
diff --git a/third_party/WebKit/Source/core/editing/EditingStyleUtilities.cpp b/third_party/WebKit/Source/core/editing/EditingStyleUtilities.cpp
index 1df94712e37316dc885fad69969c0f7b0aac1eb5..cdb69e511994a38376defbdbeef35cf0143c3d80 100644
--- a/third_party/WebKit/Source/core/editing/EditingStyleUtilities.cpp
+++ b/third_party/WebKit/Source/core/editing/EditingStyleUtilities.cpp
@@ -24,761 +24,20 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "core/editing/EditingStyle.h"
+#include "EditingStyleUtilities.h"
-#include "bindings/core/v8/ExceptionState.h"
-#include "core/HTMLNames.h"
#include "core/css/CSSColorValue.h"
#include "core/css/CSSComputedStyleDeclaration.h"
#include "core/css/CSSIdentifierValue.h"
-#include "core/css/CSSPrimitiveValue.h"
-#include "core/css/CSSPrimitiveValueMappings.h"
-#include "core/css/CSSPropertyMetadata.h"
-#include "core/css/CSSRuleList.h"
-#include "core/css/CSSStyleRule.h"
-#include "core/css/CSSValueList.h"
-#include "core/css/FontSize.h"
#include "core/css/StylePropertySet.h"
-#include "core/css/StyleRule.h"
#include "core/css/parser/CSSParser.h"
-#include "core/css/resolver/StyleResolver.h"
-#include "core/dom/Document.h"
-#include "core/dom/Element.h"
-#include "core/dom/Node.h"
-#include "core/dom/NodeComputedStyle.h"
-#include "core/dom/NodeTraversal.h"
-#include "core/dom/QualifiedName.h"
+#include "core/editing/EditingStyle.h"
#include "core/editing/EditingUtilities.h"
-#include "core/editing/Editor.h"
-#include "core/editing/FrameSelection.h"
-#include "core/editing/Position.h"
-#include "core/editing/commands/ApplyStyleCommand.h"
-#include "core/editing/serializers/HTMLInterchange.h"
-#include "core/frame/LocalFrame.h"
-#include "core/html/HTMLFontElement.h"
-#include "core/html/HTMLSpanElement.h"
-#include "core/layout/LayoutBox.h"
-#include "core/layout/LayoutObject.h"
-#include "core/style/ComputedStyle.h"
-#include "wtf/StdLibExtras.h"
namespace blink {
-static const CSSPropertyID& textDecorationPropertyForEditing() {
- static const CSSPropertyID property =
- RuntimeEnabledFeatures::css3TextDecorationsEnabled()
- ? CSSPropertyTextDecorationLine
- : CSSPropertyTextDecoration;
- return property;
-}
-
-// Editing style properties must be preserved during editing operation.
-// e.g. when a user inserts a new paragraph, all properties listed here must be
-// copied to the new paragraph.
-// NOTE: Use either allEditingProperties() or inheritableEditingProperties() to
-// respect runtime enabling of properties.
-static const CSSPropertyID staticEditingProperties[] = {
- CSSPropertyBackgroundColor, CSSPropertyColor, CSSPropertyFontFamily,
- CSSPropertyFontSize, CSSPropertyFontStyle, CSSPropertyFontVariantLigatures,
- CSSPropertyFontVariantCaps, CSSPropertyFontWeight, CSSPropertyLetterSpacing,
- CSSPropertyOrphans, CSSPropertyTextAlign,
- // FIXME: CSSPropertyTextDecoration needs to be removed when CSS3 Text
- // Decoration feature is no longer experimental.
- CSSPropertyTextDecoration, CSSPropertyTextDecorationLine,
- CSSPropertyTextIndent, CSSPropertyTextTransform, CSSPropertyWhiteSpace,
- CSSPropertyWidows, CSSPropertyWordSpacing,
- CSSPropertyWebkitTextDecorationsInEffect, CSSPropertyWebkitTextFillColor,
- CSSPropertyWebkitTextStrokeColor, CSSPropertyWebkitTextStrokeWidth,
- CSSPropertyCaretColor};
-
-enum EditingPropertiesType {
- OnlyInheritableEditingProperties,
- AllEditingProperties
-};
-
-static const Vector<CSSPropertyID>& allEditingProperties() {
- DEFINE_STATIC_LOCAL(Vector<CSSPropertyID>, properties, ());
- if (properties.isEmpty()) {
- CSSPropertyMetadata::filterEnabledCSSPropertiesIntoVector(
- staticEditingProperties, WTF_ARRAY_LENGTH(staticEditingProperties),
- properties);
- if (RuntimeEnabledFeatures::css3TextDecorationsEnabled())
- properties.remove(properties.find(CSSPropertyTextDecoration));
- }
- return properties;
-}
-
-static const Vector<CSSPropertyID>& inheritableEditingProperties() {
- DEFINE_STATIC_LOCAL(Vector<CSSPropertyID>, properties, ());
- if (properties.isEmpty()) {
- CSSPropertyMetadata::filterEnabledCSSPropertiesIntoVector(
- staticEditingProperties, WTF_ARRAY_LENGTH(staticEditingProperties),
- properties);
- for (size_t index = 0; index < properties.size();) {
- if (!CSSPropertyMetadata::isInheritedProperty(properties[index])) {
- properties.remove(index);
- continue;
- }
- ++index;
- }
- }
- return properties;
-}
-
-template <class StyleDeclarationType>
-static MutableStylePropertySet* copyEditingProperties(
- StyleDeclarationType* style,
- EditingPropertiesType type = OnlyInheritableEditingProperties) {
- if (type == AllEditingProperties)
- return style->copyPropertiesInSet(allEditingProperties());
- return style->copyPropertiesInSet(inheritableEditingProperties());
-}
-
-static inline bool isEditingProperty(int id) {
- return allEditingProperties().contains(static_cast<CSSPropertyID>(id));
-}
-
-static MutableStylePropertySet* editingStyleFromComputedStyle(
- CSSComputedStyleDeclaration* style,
- EditingPropertiesType type = OnlyInheritableEditingProperties) {
- if (!style)
- return MutableStylePropertySet::create(HTMLQuirksMode);
- return copyEditingProperties(style, type);
-}
-
-static CSSComputedStyleDeclaration* ensureComputedStyle(
- const Position& position) {
- Element* elem = associatedElementOf(position);
- if (!elem)
- return nullptr;
- return CSSComputedStyleDeclaration::create(elem);
-}
-
-static MutableStylePropertySet* getPropertiesNotIn(
- StylePropertySet* styleWithRedundantProperties,
- CSSStyleDeclaration* baseStyle);
-enum LegacyFontSizeMode {
- AlwaysUseLegacyFontSize,
- UseLegacyFontSizeOnlyIfPixelValuesMatch
-};
-static int legacyFontSizeFromCSSValue(Document*,
- const CSSValue*,
- bool,
- LegacyFontSizeMode);
-static bool isTransparentColorValue(const CSSValue*);
-static bool hasTransparentBackgroundColor(CSSStyleDeclaration*);
-static bool hasTransparentBackgroundColor(StylePropertySet*);
-static const CSSValue* backgroundColorValueInEffect(Node*);
-static bool hasAncestorVerticalAlignStyle(Node&, CSSValueID);
-
-class HTMLElementEquivalent : public GarbageCollected<HTMLElementEquivalent> {
- public:
- static HTMLElementEquivalent* create(CSSPropertyID propertyID,
- CSSValueID primitiveValue,
- const HTMLQualifiedName& tagName) {
- return new HTMLElementEquivalent(propertyID, primitiveValue, tagName);
- }
-
- virtual bool matches(const Element* element) const {
- return !m_tagName || element->hasTagName(*m_tagName);
- }
- virtual bool hasAttribute() const { return false; }
- virtual bool propertyExistsInStyle(const StylePropertySet* style) const {
- return style->getPropertyCSSValue(m_propertyID);
- }
- virtual bool valueIsPresentInStyle(HTMLElement*, StylePropertySet*) const;
- virtual void addToStyle(Element*, EditingStyle*) const;
-
- DEFINE_INLINE_VIRTUAL_TRACE() { visitor->trace(m_identifierValue); }
-
- protected:
- HTMLElementEquivalent(CSSPropertyID);
- HTMLElementEquivalent(CSSPropertyID, const HTMLQualifiedName& tagName);
- HTMLElementEquivalent(CSSPropertyID,
- CSSValueID primitiveValue,
- const HTMLQualifiedName& tagName);
- const CSSPropertyID m_propertyID;
- const Member<CSSIdentifierValue> m_identifierValue;
- // We can store a pointer because HTML tag names are const global.
- const HTMLQualifiedName* m_tagName;
-};
-
-HTMLElementEquivalent::HTMLElementEquivalent(CSSPropertyID id)
- : m_propertyID(id), m_tagName(0) {}
-
-HTMLElementEquivalent::HTMLElementEquivalent(CSSPropertyID id,
- const HTMLQualifiedName& tagName)
- : m_propertyID(id), m_tagName(&tagName) {}
-
-HTMLElementEquivalent::HTMLElementEquivalent(CSSPropertyID id,
- CSSValueID valueID,
- const HTMLQualifiedName& tagName)
- : m_propertyID(id),
- m_identifierValue(CSSIdentifierValue::create(valueID)),
- m_tagName(&tagName) {
- DCHECK_NE(valueID, CSSValueInvalid);
-}
-
-bool HTMLElementEquivalent::valueIsPresentInStyle(
- HTMLElement* element,
- StylePropertySet* style) const {
- const CSSValue* value = style->getPropertyCSSValue(m_propertyID);
- return matches(element) && value && value->isIdentifierValue() &&
- toCSSIdentifierValue(value)->getValueID() ==
- m_identifierValue->getValueID();
-}
-
-void HTMLElementEquivalent::addToStyle(Element*, EditingStyle* style) const {
- style->setProperty(m_propertyID, m_identifierValue->cssText());
-}
-
-class HTMLTextDecorationEquivalent final : public HTMLElementEquivalent {
- public:
- static HTMLElementEquivalent* create(CSSValueID primitiveValue,
- const HTMLQualifiedName& tagName) {
- return new HTMLTextDecorationEquivalent(primitiveValue, tagName);
- }
- bool propertyExistsInStyle(const StylePropertySet*) const override;
- bool valueIsPresentInStyle(HTMLElement*, StylePropertySet*) const override;
-
- DEFINE_INLINE_VIRTUAL_TRACE() { HTMLElementEquivalent::trace(visitor); }
-
- private:
- HTMLTextDecorationEquivalent(CSSValueID primitiveValue,
- const HTMLQualifiedName& tagName);
-};
-
-HTMLTextDecorationEquivalent::HTMLTextDecorationEquivalent(
- CSSValueID primitiveValue,
- const HTMLQualifiedName& tagName)
- : HTMLElementEquivalent(textDecorationPropertyForEditing(),
- primitiveValue,
- tagName)
-// m_propertyID is used in HTMLElementEquivalent::addToStyle
-{}
-
-bool HTMLTextDecorationEquivalent::propertyExistsInStyle(
- const StylePropertySet* style) const {
- return style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect) ||
- style->getPropertyCSSValue(textDecorationPropertyForEditing());
-}
-
-bool HTMLTextDecorationEquivalent::valueIsPresentInStyle(
- HTMLElement* element,
- StylePropertySet* style) const {
- const CSSValue* styleValue =
- style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
- if (!styleValue)
- styleValue = style->getPropertyCSSValue(textDecorationPropertyForEditing());
- return matches(element) && styleValue && styleValue->isValueList() &&
- toCSSValueList(styleValue)->hasValue(*m_identifierValue);
-}
-
-class HTMLAttributeEquivalent : public HTMLElementEquivalent {
- public:
- static HTMLAttributeEquivalent* create(CSSPropertyID propertyID,
- const HTMLQualifiedName& tagName,
- const QualifiedName& attrName) {
- return new HTMLAttributeEquivalent(propertyID, tagName, attrName);
- }
- static HTMLAttributeEquivalent* create(CSSPropertyID propertyID,
- const QualifiedName& attrName) {
- return new HTMLAttributeEquivalent(propertyID, attrName);
- }
-
- bool matches(const Element* element) const override {
- return HTMLElementEquivalent::matches(element) &&
- element->hasAttribute(m_attrName);
- }
- bool hasAttribute() const override { return true; }
- bool valueIsPresentInStyle(HTMLElement*, StylePropertySet*) const override;
- void addToStyle(Element*, EditingStyle*) const override;
- virtual const CSSValue* attributeValueAsCSSValue(Element*) const;
- inline const QualifiedName& attributeName() const { return m_attrName; }
-
- DEFINE_INLINE_VIRTUAL_TRACE() { HTMLElementEquivalent::trace(visitor); }
-
- protected:
- HTMLAttributeEquivalent(CSSPropertyID,
- const HTMLQualifiedName& tagName,
- const QualifiedName& attrName);
- HTMLAttributeEquivalent(CSSPropertyID, const QualifiedName& attrName);
- // We can store a reference because HTML attribute names are const global.
- const QualifiedName& m_attrName;
-};
-
-HTMLAttributeEquivalent::HTMLAttributeEquivalent(
- CSSPropertyID id,
- const HTMLQualifiedName& tagName,
- const QualifiedName& attrName)
- : HTMLElementEquivalent(id, tagName), m_attrName(attrName) {}
-
-HTMLAttributeEquivalent::HTMLAttributeEquivalent(CSSPropertyID id,
- const QualifiedName& attrName)
- : HTMLElementEquivalent(id), m_attrName(attrName) {}
-
-bool HTMLAttributeEquivalent::valueIsPresentInStyle(
- HTMLElement* element,
- StylePropertySet* style) const {
- const CSSValue* value = attributeValueAsCSSValue(element);
- const CSSValue* styleValue = style->getPropertyCSSValue(m_propertyID);
-
- return compareCSSValuePtr(value, styleValue);
-}
-
-void HTMLAttributeEquivalent::addToStyle(Element* element,
- EditingStyle* style) const {
- if (const CSSValue* value = attributeValueAsCSSValue(element))
- style->setProperty(m_propertyID, value->cssText());
-}
-
-const CSSValue* HTMLAttributeEquivalent::attributeValueAsCSSValue(
- Element* element) const {
- DCHECK(element);
- const AtomicString& value = element->getAttribute(m_attrName);
- if (value.isNull())
- return nullptr;
-
- MutableStylePropertySet* dummyStyle = nullptr;
- dummyStyle = MutableStylePropertySet::create(HTMLQuirksMode);
- dummyStyle->setProperty(m_propertyID, value);
- return dummyStyle->getPropertyCSSValue(m_propertyID);
-}
-
-class HTMLFontSizeEquivalent final : public HTMLAttributeEquivalent {
- public:
- static HTMLFontSizeEquivalent* create() {
- return new HTMLFontSizeEquivalent();
- }
- const CSSValue* attributeValueAsCSSValue(Element*) const override;
-
- DEFINE_INLINE_VIRTUAL_TRACE() { HTMLAttributeEquivalent::trace(visitor); }
-
- private:
- HTMLFontSizeEquivalent();
-};
-
-HTMLFontSizeEquivalent::HTMLFontSizeEquivalent()
- : HTMLAttributeEquivalent(CSSPropertyFontSize,
- HTMLNames::fontTag,
- HTMLNames::sizeAttr) {}
-
-const CSSValue* HTMLFontSizeEquivalent::attributeValueAsCSSValue(
- Element* element) const {
- DCHECK(element);
- const AtomicString& value = element->getAttribute(m_attrName);
- if (value.isNull())
- return nullptr;
- CSSValueID size;
- if (!HTMLFontElement::cssValueFromFontSizeNumber(value, size))
- return nullptr;
- return CSSIdentifierValue::create(size);
-}
-
-float EditingStyle::NoFontDelta = 0.0f;
-
-EditingStyle::EditingStyle(ContainerNode* node,
- PropertiesToInclude propertiesToInclude) {
- init(node, propertiesToInclude);
-}
-
-EditingStyle::EditingStyle(const Position& position,
- PropertiesToInclude propertiesToInclude) {
- init(position.anchorNode(), propertiesToInclude);
-}
-
-EditingStyle::EditingStyle(const StylePropertySet* style)
- : m_mutableStyle(style ? style->mutableCopy() : nullptr) {
- extractFontSizeDelta();
-}
-
-EditingStyle::EditingStyle(CSSPropertyID propertyID, const String& value)
- : m_mutableStyle(nullptr) {
- setProperty(propertyID, value);
- m_isVerticalAlign = propertyID == CSSPropertyVerticalAlign &&
- (value == "sub" || value == "super");
-}
-
-static Color cssValueToColor(const CSSValue* colorValue) {
- if (!colorValue ||
- (!colorValue->isColorValue() && !colorValue->isPrimitiveValue() &&
- !colorValue->isIdentifierValue()))
- return Color::transparent;
-
- if (colorValue->isColorValue())
- return toCSSColorValue(colorValue)->value();
-
- Color color = 0;
- // FIXME: Why ignore the return value?
- CSSParser::parseColor(color, colorValue->cssText());
- return color;
-}
-
-static inline Color getFontColor(CSSStyleDeclaration* style) {
- return cssValueToColor(style->getPropertyCSSValueInternal(CSSPropertyColor));
-}
-
-static inline Color getFontColor(StylePropertySet* style) {
- return cssValueToColor(style->getPropertyCSSValue(CSSPropertyColor));
-}
-
-static inline Color getBackgroundColor(CSSStyleDeclaration* style) {
- return cssValueToColor(
- style->getPropertyCSSValueInternal(CSSPropertyBackgroundColor));
-}
-
-static inline Color getBackgroundColor(StylePropertySet* style) {
- return cssValueToColor(
- style->getPropertyCSSValue(CSSPropertyBackgroundColor));
-}
-
-static inline Color backgroundColorInEffect(Node* node) {
- return cssValueToColor(backgroundColorValueInEffect(node));
-}
-
-static int textAlignResolvingStartAndEnd(int textAlign, int direction) {
- switch (textAlign) {
- case CSSValueCenter:
- case CSSValueWebkitCenter:
- return CSSValueCenter;
- case CSSValueJustify:
- return CSSValueJustify;
- case CSSValueLeft:
- case CSSValueWebkitLeft:
- return CSSValueLeft;
- case CSSValueRight:
- case CSSValueWebkitRight:
- return CSSValueRight;
- case CSSValueStart:
- return direction != CSSValueRtl ? CSSValueLeft : CSSValueRight;
- case CSSValueEnd:
- return direction == CSSValueRtl ? CSSValueRight : CSSValueLeft;
- }
- return CSSValueInvalid;
-}
-
-template <typename T>
-static int textAlignResolvingStartAndEnd(T* style) {
- return textAlignResolvingStartAndEnd(
- getIdentifierValue(style, CSSPropertyTextAlign),
- getIdentifierValue(style, CSSPropertyDirection));
-}
-
-void EditingStyle::init(Node* node, PropertiesToInclude propertiesToInclude) {
- if (isTabHTMLSpanElementTextNode(node))
- node = tabSpanElement(node)->parentNode();
- else if (isTabHTMLSpanElement(node))
- node = node->parentNode();
-
- CSSComputedStyleDeclaration* computedStyleAtPosition =
- CSSComputedStyleDeclaration::create(node);
- m_mutableStyle =
- propertiesToInclude == AllProperties && computedStyleAtPosition
- ? computedStyleAtPosition->copyProperties()
- : editingStyleFromComputedStyle(computedStyleAtPosition);
-
- if (propertiesToInclude == EditingPropertiesInEffect) {
- if (const CSSValue* value = backgroundColorValueInEffect(node))
- m_mutableStyle->setProperty(CSSPropertyBackgroundColor, value->cssText());
- if (const CSSValue* value = computedStyleAtPosition->getPropertyCSSValue(
- CSSPropertyWebkitTextDecorationsInEffect))
- m_mutableStyle->setProperty(CSSPropertyTextDecoration, value->cssText());
- }
-
- if (node && node->ensureComputedStyle()) {
- const ComputedStyle* computedStyle = node->ensureComputedStyle();
- removeInheritedColorsIfNeeded(computedStyle);
- replaceFontSizeByKeywordIfPossible(computedStyle, computedStyleAtPosition);
- }
-
- m_isMonospaceFont = computedStyleAtPosition->isMonospaceFont();
- extractFontSizeDelta();
-}
-
-void EditingStyle::removeInheritedColorsIfNeeded(
- const ComputedStyle* computedStyle) {
- // If a node's text fill color is currentColor, then its children use
- // their font-color as their text fill color (they don't
- // inherit it). Likewise for stroke color.
- // Similar thing happens for caret-color if it's auto or currentColor.
- if (computedStyle->textFillColor().isCurrentColor())
- m_mutableStyle->removeProperty(CSSPropertyWebkitTextFillColor);
- if (computedStyle->textStrokeColor().isCurrentColor())
- m_mutableStyle->removeProperty(CSSPropertyWebkitTextStrokeColor);
- if (computedStyle->caretColor().isAutoColor() ||
- computedStyle->caretColor().isCurrentColor())
- m_mutableStyle->removeProperty(CSSPropertyCaretColor);
-}
-
-void EditingStyle::setProperty(CSSPropertyID propertyID,
- const String& value,
- bool important) {
- if (!m_mutableStyle)
- m_mutableStyle = MutableStylePropertySet::create(HTMLQuirksMode);
-
- m_mutableStyle->setProperty(propertyID, value, important);
-}
-
-void EditingStyle::replaceFontSizeByKeywordIfPossible(
- const ComputedStyle* computedStyle,
- CSSComputedStyleDeclaration* cssComputedStyle) {
- DCHECK(computedStyle);
- if (computedStyle->getFontDescription().keywordSize()) {
- m_mutableStyle->setProperty(
- CSSPropertyFontSize,
- cssComputedStyle->getFontSizeCSSValuePreferringKeyword()->cssText());
- }
-}
-
-void EditingStyle::extractFontSizeDelta() {
- if (!m_mutableStyle)
- return;
-
- if (m_mutableStyle->getPropertyCSSValue(CSSPropertyFontSize)) {
- // Explicit font size overrides any delta.
- m_mutableStyle->removeProperty(CSSPropertyWebkitFontSizeDelta);
- return;
- }
-
- // Get the adjustment amount out of the style.
- const CSSValue* value =
- m_mutableStyle->getPropertyCSSValue(CSSPropertyWebkitFontSizeDelta);
- if (!value || !value->isPrimitiveValue())
- return;
-
- const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
-
- // Only PX handled now. If we handle more types in the future, perhaps
- // a switch statement here would be more appropriate.
- if (!primitiveValue->isPx())
- return;
-
- m_fontSizeDelta = primitiveValue->getFloatValue();
- m_mutableStyle->removeProperty(CSSPropertyWebkitFontSizeDelta);
-}
-
-bool EditingStyle::isEmpty() const {
- return (!m_mutableStyle || m_mutableStyle->isEmpty()) &&
- m_fontSizeDelta == NoFontDelta;
-}
-
-bool EditingStyle::textDirection(WritingDirection& writingDirection) const {
- if (!m_mutableStyle)
- return false;
-
- const CSSValue* unicodeBidi =
- m_mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
- if (!unicodeBidi || !unicodeBidi->isIdentifierValue())
- return false;
-
- CSSValueID unicodeBidiValue = toCSSIdentifierValue(unicodeBidi)->getValueID();
- if (isEmbedOrIsolate(unicodeBidiValue)) {
- const CSSValue* direction =
- m_mutableStyle->getPropertyCSSValue(CSSPropertyDirection);
- if (!direction || !direction->isIdentifierValue())
- return false;
-
- writingDirection =
- toCSSIdentifierValue(direction)->getValueID() == CSSValueLtr
- ? LeftToRightWritingDirection
- : RightToLeftWritingDirection;
-
- return true;
- }
-
- if (unicodeBidiValue == CSSValueNormal) {
- writingDirection = NaturalWritingDirection;
- return true;
- }
-
- return false;
-}
-
-void EditingStyle::overrideWithStyle(const StylePropertySet* style) {
- if (!style || style->isEmpty())
- return;
- if (!m_mutableStyle)
- m_mutableStyle = MutableStylePropertySet::create(HTMLQuirksMode);
- m_mutableStyle->mergeAndOverrideOnConflict(style);
- extractFontSizeDelta();
-}
-
-void EditingStyle::clear() {
- m_mutableStyle.clear();
- m_isMonospaceFont = false;
- m_fontSizeDelta = NoFontDelta;
-}
-
-EditingStyle* EditingStyle::copy() const {
- EditingStyle* copy = EditingStyle::create();
- if (m_mutableStyle)
- copy->m_mutableStyle = m_mutableStyle->mutableCopy();
- copy->m_isMonospaceFont = m_isMonospaceFont;
- copy->m_fontSizeDelta = m_fontSizeDelta;
- return copy;
-}
-
-// This is the list of CSS properties that apply specially to block-level
-// elements.
-static const CSSPropertyID staticBlockProperties[] = {
- CSSPropertyBreakAfter,
- CSSPropertyBreakBefore,
- CSSPropertyBreakInside,
- CSSPropertyOrphans,
- CSSPropertyOverflow, // This can be also be applied to replaced elements
- CSSPropertyColumnCount,
- CSSPropertyColumnGap,
- CSSPropertyColumnRuleColor,
- CSSPropertyColumnRuleStyle,
- CSSPropertyColumnRuleWidth,
- CSSPropertyWebkitColumnBreakBefore,
- CSSPropertyWebkitColumnBreakAfter,
- CSSPropertyWebkitColumnBreakInside,
- CSSPropertyColumnWidth,
- CSSPropertyPageBreakAfter,
- CSSPropertyPageBreakBefore,
- CSSPropertyPageBreakInside,
- CSSPropertyTextAlign,
- CSSPropertyTextAlignLast,
- CSSPropertyTextIndent,
- CSSPropertyTextJustify,
- CSSPropertyWidows};
-
-static const Vector<CSSPropertyID>& blockPropertiesVector() {
- DEFINE_STATIC_LOCAL(Vector<CSSPropertyID>, properties, ());
- if (properties.isEmpty()) {
- CSSPropertyMetadata::filterEnabledCSSPropertiesIntoVector(
- staticBlockProperties, WTF_ARRAY_LENGTH(staticBlockProperties),
- properties);
- }
- return properties;
-}
-
-EditingStyle* EditingStyle::extractAndRemoveBlockProperties() {
- EditingStyle* blockProperties = EditingStyle::create();
- if (!m_mutableStyle)
- return blockProperties;
-
- blockProperties->m_mutableStyle =
- m_mutableStyle->copyPropertiesInSet(blockPropertiesVector());
- removeBlockProperties();
-
- return blockProperties;
-}
-
-EditingStyle* EditingStyle::extractAndRemoveTextDirection() {
- EditingStyle* textDirection = EditingStyle::create();
- textDirection->m_mutableStyle =
- MutableStylePropertySet::create(HTMLQuirksMode);
- textDirection->m_mutableStyle->setProperty(
- CSSPropertyUnicodeBidi, CSSValueIsolate,
- m_mutableStyle->propertyIsImportant(CSSPropertyUnicodeBidi));
- textDirection->m_mutableStyle->setProperty(
- CSSPropertyDirection,
- m_mutableStyle->getPropertyValue(CSSPropertyDirection),
- m_mutableStyle->propertyIsImportant(CSSPropertyDirection));
-
- m_mutableStyle->removeProperty(CSSPropertyUnicodeBidi);
- m_mutableStyle->removeProperty(CSSPropertyDirection);
-
- return textDirection;
-}
-
-void EditingStyle::removeBlockProperties() {
- if (!m_mutableStyle)
- return;
-
- m_mutableStyle->removePropertiesInSet(blockPropertiesVector().data(),
- blockPropertiesVector().size());
-}
-
-void EditingStyle::removeStyleAddedByElement(Element* element) {
- if (!element || !element->parentNode())
- return;
- MutableStylePropertySet* parentStyle = editingStyleFromComputedStyle(
- CSSComputedStyleDeclaration::create(element->parentNode()),
- AllEditingProperties);
- MutableStylePropertySet* nodeStyle = editingStyleFromComputedStyle(
- CSSComputedStyleDeclaration::create(element), AllEditingProperties);
- nodeStyle->removeEquivalentProperties(parentStyle);
- m_mutableStyle->removeEquivalentProperties(nodeStyle);
-}
-
-void EditingStyle::removeStyleConflictingWithStyleOfElement(Element* element) {
- if (!element || !element->parentNode() || !m_mutableStyle)
- return;
-
- MutableStylePropertySet* parentStyle = editingStyleFromComputedStyle(
- CSSComputedStyleDeclaration::create(element->parentNode()),
- AllEditingProperties);
- MutableStylePropertySet* nodeStyle = editingStyleFromComputedStyle(
- CSSComputedStyleDeclaration::create(element), AllEditingProperties);
- nodeStyle->removeEquivalentProperties(parentStyle);
-
- unsigned propertyCount = nodeStyle->propertyCount();
- for (unsigned i = 0; i < propertyCount; ++i)
- m_mutableStyle->removeProperty(nodeStyle->propertyAt(i).id());
-}
-
-void EditingStyle::collapseTextDecorationProperties() {
- if (!m_mutableStyle)
- return;
-
- const CSSValue* textDecorationsInEffect = m_mutableStyle->getPropertyCSSValue(
- CSSPropertyWebkitTextDecorationsInEffect);
- if (!textDecorationsInEffect)
- return;
-
- if (textDecorationsInEffect->isValueList()) {
- m_mutableStyle->setProperty(textDecorationPropertyForEditing(),
- textDecorationsInEffect->cssText(),
- m_mutableStyle->propertyIsImportant(
- textDecorationPropertyForEditing()));
- } else {
- m_mutableStyle->removeProperty(textDecorationPropertyForEditing());
- }
- m_mutableStyle->removeProperty(CSSPropertyWebkitTextDecorationsInEffect);
-}
-
-// CSS properties that create a visual difference only when applied to text.
-static const CSSPropertyID textOnlyProperties[] = {
- // FIXME: CSSPropertyTextDecoration needs to be removed when CSS3 Text
- // Decoration feature is no longer experimental.
- CSSPropertyTextDecoration,
- CSSPropertyTextDecorationLine,
- CSSPropertyWebkitTextDecorationsInEffect,
- CSSPropertyFontStyle,
- CSSPropertyFontWeight,
- CSSPropertyColor,
-};
-
-TriState EditingStyle::triStateOfStyle(EditingStyle* style) const {
- if (!style || !style->m_mutableStyle)
- return FalseTriState;
- return triStateOfStyle(style->m_mutableStyle->ensureCSSStyleDeclaration(),
- DoNotIgnoreTextOnlyProperties);
-}
-
-TriState EditingStyle::triStateOfStyle(
- CSSStyleDeclaration* styleToCompare,
- ShouldIgnoreTextOnlyProperties shouldIgnoreTextOnlyProperties) const {
- MutableStylePropertySet* difference =
- getPropertiesNotIn(m_mutableStyle.get(), styleToCompare);
-
- if (shouldIgnoreTextOnlyProperties == IgnoreTextOnlyProperties) {
- difference->removePropertiesInSet(textOnlyProperties,
- WTF_ARRAY_LENGTH(textOnlyProperties));
- }
-
- if (difference->isEmpty())
- return TrueTriState;
- if (difference->propertyCount() == m_mutableStyle->propertyCount())
- return FalseTriState;
-
- return MixedTriState;
-}
-
-static bool hasAncestorVerticalAlignStyle(Node& node, CSSValueID value) {
+bool EditingStyleUtilities::hasAncestorVerticalAlignStyle(Node& node,
+ CSSValueID value) {
for (Node& runner : NodeTraversal::inclusiveAncestorsOf(node)) {
CSSComputedStyleDeclaration* ancestorStyle =
CSSComputedStyleDeclaration::create(&runner);
@@ -788,476 +47,7 @@ static bool hasAncestorVerticalAlignStyle(Node& node, CSSValueID value) {
return false;
}
-TriState EditingStyle::triStateOfStyle(
- const VisibleSelection& selection) const {
- if (selection.isNone())
- return FalseTriState;
-
- if (selection.isCaret())
- return triStateOfStyle(EditingStyle::styleAtSelectionStart(selection));
-
- TriState state = FalseTriState;
- bool nodeIsStart = true;
- for (Node& node : NodeTraversal::startsAt(*selection.start().anchorNode())) {
- if (node.layoutObject() && hasEditableStyle(node)) {
- CSSComputedStyleDeclaration* nodeStyle =
- CSSComputedStyleDeclaration::create(&node);
- if (nodeStyle) {
- // If the selected element has <sub> or <sup> ancestor element, apply
- // the corresponding style(vertical-align) to it so that
- // document.queryCommandState() works with the style. See bug
- // http://crbug.com/582225.
- if (m_isVerticalAlign &&
- getIdentifierValue(nodeStyle, CSSPropertyVerticalAlign) ==
- CSSValueBaseline) {
- const CSSIdentifierValue* verticalAlign = toCSSIdentifierValue(
- m_mutableStyle->getPropertyCSSValue(CSSPropertyVerticalAlign));
- if (hasAncestorVerticalAlignStyle(node,
- verticalAlign->getValueID())) {
- node.mutableComputedStyle()->setVerticalAlign(
- verticalAlign->convertTo<EVerticalAlign>());
- }
- }
-
- // Pass EditingStyle::DoNotIgnoreTextOnlyProperties without checking if
- // node.isTextNode() because the node can be an element node. See bug
- // http://crbug.com/584939.
- TriState nodeState = triStateOfStyle(
- nodeStyle, EditingStyle::DoNotIgnoreTextOnlyProperties);
- if (nodeIsStart) {
- state = nodeState;
- nodeIsStart = false;
- } else if (state != nodeState && node.isTextNode()) {
- state = MixedTriState;
- break;
- }
- }
- }
- if (&node == selection.end().anchorNode())
- break;
- }
-
- return state;
-}
-
-bool EditingStyle::conflictsWithInlineStyleOfElement(
- HTMLElement* element,
- EditingStyle* extractedStyle,
- Vector<CSSPropertyID>* conflictingProperties) const {
- DCHECK(element);
- DCHECK(!conflictingProperties || conflictingProperties->isEmpty());
-
- const StylePropertySet* inlineStyle = element->inlineStyle();
- if (!m_mutableStyle || !inlineStyle)
- return false;
-
- unsigned propertyCount = m_mutableStyle->propertyCount();
- for (unsigned i = 0; i < propertyCount; ++i) {
- CSSPropertyID propertyID = m_mutableStyle->propertyAt(i).id();
-
- // We don't override whitespace property of a tab span because that would
- // collapse the tab into a space.
- if (propertyID == CSSPropertyWhiteSpace && isTabHTMLSpanElement(element))
- continue;
-
- if (propertyID == CSSPropertyWebkitTextDecorationsInEffect &&
- inlineStyle->getPropertyCSSValue(textDecorationPropertyForEditing())) {
- if (!conflictingProperties)
- return true;
- conflictingProperties->push_back(CSSPropertyTextDecoration);
- // Because text-decoration expands to text-decoration-line when CSS3
- // Text Decoration is enabled, we also state it as conflicting.
- if (RuntimeEnabledFeatures::css3TextDecorationsEnabled())
- conflictingProperties->push_back(CSSPropertyTextDecorationLine);
- if (extractedStyle) {
- extractedStyle->setProperty(
- textDecorationPropertyForEditing(),
- inlineStyle->getPropertyValue(textDecorationPropertyForEditing()),
- inlineStyle->propertyIsImportant(
- textDecorationPropertyForEditing()));
- }
- continue;
- }
-
- if (!inlineStyle->getPropertyCSSValue(propertyID))
- continue;
-
- if (propertyID == CSSPropertyUnicodeBidi &&
- inlineStyle->getPropertyCSSValue(CSSPropertyDirection)) {
- if (!conflictingProperties)
- return true;
- conflictingProperties->push_back(CSSPropertyDirection);
- if (extractedStyle) {
- extractedStyle->setProperty(
- propertyID, inlineStyle->getPropertyValue(propertyID),
- inlineStyle->propertyIsImportant(propertyID));
- }
- }
-
- if (!conflictingProperties)
- return true;
-
- conflictingProperties->push_back(propertyID);
-
- if (extractedStyle) {
- extractedStyle->setProperty(propertyID,
- inlineStyle->getPropertyValue(propertyID),
- inlineStyle->propertyIsImportant(propertyID));
- }
- }
-
- return conflictingProperties && !conflictingProperties->isEmpty();
-}
-
-static const HeapVector<Member<HTMLElementEquivalent>>&
-htmlElementEquivalents() {
- DEFINE_STATIC_LOCAL(HeapVector<Member<HTMLElementEquivalent>>,
- HTMLElementEquivalents,
- (new HeapVector<Member<HTMLElementEquivalent>>));
- if (!HTMLElementEquivalents.size()) {
- HTMLElementEquivalents.push_back(HTMLElementEquivalent::create(
- CSSPropertyFontWeight, CSSValueBold, HTMLNames::bTag));
- HTMLElementEquivalents.push_back(HTMLElementEquivalent::create(
- CSSPropertyFontWeight, CSSValueBold, HTMLNames::strongTag));
- HTMLElementEquivalents.push_back(HTMLElementEquivalent::create(
- CSSPropertyVerticalAlign, CSSValueSub, HTMLNames::subTag));
- HTMLElementEquivalents.push_back(HTMLElementEquivalent::create(
- CSSPropertyVerticalAlign, CSSValueSuper, HTMLNames::supTag));
- HTMLElementEquivalents.push_back(HTMLElementEquivalent::create(
- CSSPropertyFontStyle, CSSValueItalic, HTMLNames::iTag));
- HTMLElementEquivalents.push_back(HTMLElementEquivalent::create(
- CSSPropertyFontStyle, CSSValueItalic, HTMLNames::emTag));
-
- HTMLElementEquivalents.push_back(HTMLTextDecorationEquivalent::create(
- CSSValueUnderline, HTMLNames::uTag));
- HTMLElementEquivalents.push_back(HTMLTextDecorationEquivalent::create(
- CSSValueLineThrough, HTMLNames::sTag));
- HTMLElementEquivalents.push_back(HTMLTextDecorationEquivalent::create(
- CSSValueLineThrough, HTMLNames::strikeTag));
- }
-
- return HTMLElementEquivalents;
-}
-
-bool EditingStyle::conflictsWithImplicitStyleOfElement(
- HTMLElement* element,
- EditingStyle* extractedStyle,
- ShouldExtractMatchingStyle shouldExtractMatchingStyle) const {
- if (!m_mutableStyle)
- return false;
-
- const HeapVector<Member<HTMLElementEquivalent>>& HTMLElementEquivalents =
- htmlElementEquivalents();
- for (size_t i = 0; i < HTMLElementEquivalents.size(); ++i) {
- const HTMLElementEquivalent* equivalent = HTMLElementEquivalents[i].get();
- if (equivalent->matches(element) &&
- equivalent->propertyExistsInStyle(m_mutableStyle.get()) &&
- (shouldExtractMatchingStyle == ExtractMatchingStyle ||
- !equivalent->valueIsPresentInStyle(element, m_mutableStyle.get()))) {
- if (extractedStyle)
- equivalent->addToStyle(element, extractedStyle);
- return true;
- }
- }
- return false;
-}
-
-static const HeapVector<Member<HTMLAttributeEquivalent>>&
-htmlAttributeEquivalents() {
- DEFINE_STATIC_LOCAL(HeapVector<Member<HTMLAttributeEquivalent>>,
- HTMLAttributeEquivalents,
- (new HeapVector<Member<HTMLAttributeEquivalent>>));
- if (!HTMLAttributeEquivalents.size()) {
- // elementIsStyledSpanOrHTMLEquivalent depends on the fact each
- // HTMLAttriuteEquivalent matches exactly one attribute of exactly one
- // element except dirAttr.
- HTMLAttributeEquivalents.push_back(HTMLAttributeEquivalent::create(
- CSSPropertyColor, HTMLNames::fontTag, HTMLNames::colorAttr));
- HTMLAttributeEquivalents.push_back(HTMLAttributeEquivalent::create(
- CSSPropertyFontFamily, HTMLNames::fontTag, HTMLNames::faceAttr));
- HTMLAttributeEquivalents.push_back(HTMLFontSizeEquivalent::create());
-
- HTMLAttributeEquivalents.push_back(HTMLAttributeEquivalent::create(
- CSSPropertyDirection, HTMLNames::dirAttr));
- HTMLAttributeEquivalents.push_back(HTMLAttributeEquivalent::create(
- CSSPropertyUnicodeBidi, HTMLNames::dirAttr));
- }
-
- return HTMLAttributeEquivalents;
-}
-
-bool EditingStyle::conflictsWithImplicitStyleOfAttributes(
- HTMLElement* element) const {
- DCHECK(element);
- if (!m_mutableStyle)
- return false;
-
- const HeapVector<Member<HTMLAttributeEquivalent>>& HTMLAttributeEquivalents =
- htmlAttributeEquivalents();
- for (const auto& equivalent : HTMLAttributeEquivalents) {
- if (equivalent->matches(element) &&
- equivalent->propertyExistsInStyle(m_mutableStyle.get()) &&
- !equivalent->valueIsPresentInStyle(element, m_mutableStyle.get()))
- return true;
- }
-
- return false;
-}
-
-bool EditingStyle::extractConflictingImplicitStyleOfAttributes(
- HTMLElement* element,
- ShouldPreserveWritingDirection shouldPreserveWritingDirection,
- EditingStyle* extractedStyle,
- Vector<QualifiedName>& conflictingAttributes,
- ShouldExtractMatchingStyle shouldExtractMatchingStyle) const {
- DCHECK(element);
- // HTMLAttributeEquivalent::addToStyle doesn't support unicode-bidi and
- // direction properties
- if (extractedStyle)
- DCHECK_EQ(shouldPreserveWritingDirection, PreserveWritingDirection);
- if (!m_mutableStyle)
- return false;
-
- const HeapVector<Member<HTMLAttributeEquivalent>>& HTMLAttributeEquivalents =
- htmlAttributeEquivalents();
- bool removed = false;
- for (const auto& attribute : HTMLAttributeEquivalents) {
- const HTMLAttributeEquivalent* equivalent = attribute.get();
-
- // unicode-bidi and direction are pushed down separately so don't push down
- // with other styles.
- if (shouldPreserveWritingDirection == PreserveWritingDirection &&
- equivalent->attributeName() == HTMLNames::dirAttr)
- continue;
-
- if (!equivalent->matches(element) ||
- !equivalent->propertyExistsInStyle(m_mutableStyle.get()) ||
- (shouldExtractMatchingStyle == DoNotExtractMatchingStyle &&
- equivalent->valueIsPresentInStyle(element, m_mutableStyle.get())))
- continue;
-
- if (extractedStyle)
- equivalent->addToStyle(element, extractedStyle);
- conflictingAttributes.push_back(equivalent->attributeName());
- removed = true;
- }
-
- return removed;
-}
-
-bool EditingStyle::styleIsPresentInComputedStyleOfNode(Node* node) const {
- return !m_mutableStyle ||
- getPropertiesNotIn(m_mutableStyle.get(),
- CSSComputedStyleDeclaration::create(node))
- ->isEmpty();
-}
-
-bool EditingStyle::elementIsStyledSpanOrHTMLEquivalent(
- const HTMLElement* element) {
- DCHECK(element);
- bool elementIsSpanOrElementEquivalent = false;
- if (isHTMLSpanElement(*element)) {
- elementIsSpanOrElementEquivalent = true;
- } else {
- const HeapVector<Member<HTMLElementEquivalent>>& HTMLElementEquivalents =
- htmlElementEquivalents();
- size_t i;
- for (i = 0; i < HTMLElementEquivalents.size(); ++i) {
- if (HTMLElementEquivalents[i]->matches(element)) {
- elementIsSpanOrElementEquivalent = true;
- break;
- }
- }
- }
-
- AttributeCollection attributes = element->attributes();
- if (attributes.isEmpty()) {
- // span, b, etc... without any attributes
- return elementIsSpanOrElementEquivalent;
- }
-
- unsigned matchedAttributes = 0;
- const HeapVector<Member<HTMLAttributeEquivalent>>& HTMLAttributeEquivalents =
- htmlAttributeEquivalents();
- for (const auto& equivalent : HTMLAttributeEquivalents) {
- if (equivalent->matches(element) &&
- equivalent->attributeName() != HTMLNames::dirAttr)
- matchedAttributes++;
- }
-
- if (!elementIsSpanOrElementEquivalent && !matchedAttributes) {
- // element is not a span, a html element equivalent, or font element.
- return false;
- }
-
- if (element->getAttribute(HTMLNames::classAttr) == AppleStyleSpanClass)
- matchedAttributes++;
-
- if (element->hasAttribute(HTMLNames::styleAttr)) {
- if (const StylePropertySet* style = element->inlineStyle()) {
- unsigned propertyCount = style->propertyCount();
- for (unsigned i = 0; i < propertyCount; ++i) {
- if (!isEditingProperty(style->propertyAt(i).id()))
- return false;
- }
- }
- matchedAttributes++;
- }
-
- // font with color attribute, span with style attribute, etc...
- DCHECK_LE(matchedAttributes, attributes.size());
- return matchedAttributes >= attributes.size();
-}
-
-void EditingStyle::prepareToApplyAt(
- const Position& position,
- ShouldPreserveWritingDirection shouldPreserveWritingDirection) {
- if (!m_mutableStyle)
- return;
-
- // ReplaceSelectionCommand::handleStyleSpans() requires that this function
- // only removes the editing style. If this function was modified in the future
- // to delete all redundant properties, then add a boolean value to indicate
- // which one of editingStyleAtPosition or computedStyle is called.
- EditingStyle* editingStyleAtPosition =
- EditingStyle::create(position, EditingPropertiesInEffect);
- StylePropertySet* styleAtPosition =
- editingStyleAtPosition->m_mutableStyle.get();
-
- const CSSValue* unicodeBidi = nullptr;
- const CSSValue* direction = nullptr;
- if (shouldPreserveWritingDirection == PreserveWritingDirection) {
- unicodeBidi = m_mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
- direction = m_mutableStyle->getPropertyCSSValue(CSSPropertyDirection);
- }
-
- m_mutableStyle->removeEquivalentProperties(styleAtPosition);
-
- if (textAlignResolvingStartAndEnd(m_mutableStyle.get()) ==
- textAlignResolvingStartAndEnd(styleAtPosition))
- m_mutableStyle->removeProperty(CSSPropertyTextAlign);
-
- if (getFontColor(m_mutableStyle.get()) == getFontColor(styleAtPosition))
- m_mutableStyle->removeProperty(CSSPropertyColor);
-
- if (hasTransparentBackgroundColor(m_mutableStyle.get()) ||
- cssValueToColor(
- m_mutableStyle->getPropertyCSSValue(CSSPropertyBackgroundColor)) ==
- backgroundColorInEffect(position.computeContainerNode()))
- m_mutableStyle->removeProperty(CSSPropertyBackgroundColor);
-
- if (unicodeBidi && unicodeBidi->isIdentifierValue()) {
- m_mutableStyle->setProperty(
- CSSPropertyUnicodeBidi,
- toCSSIdentifierValue(unicodeBidi)->getValueID());
- if (direction && direction->isIdentifierValue()) {
- m_mutableStyle->setProperty(
- CSSPropertyDirection, toCSSIdentifierValue(direction)->getValueID());
- }
- }
-}
-
-void EditingStyle::mergeTypingStyle(Document* document) {
- DCHECK(document);
-
- EditingStyle* typingStyle = document->frame()->selection().typingStyle();
- if (!typingStyle || typingStyle == this)
- return;
-
- mergeStyle(typingStyle->style(), OverrideValues);
-}
-
-void EditingStyle::mergeInlineStyleOfElement(
- HTMLElement* element,
- CSSPropertyOverrideMode mode,
- PropertiesToInclude propertiesToInclude) {
- DCHECK(element);
- if (!element->inlineStyle())
- return;
-
- switch (propertiesToInclude) {
- case AllProperties:
- mergeStyle(element->inlineStyle(), mode);
- return;
- case OnlyEditingInheritableProperties:
- mergeStyle(copyEditingProperties(element->inlineStyle(),
- OnlyInheritableEditingProperties),
- mode);
- return;
- case EditingPropertiesInEffect:
- mergeStyle(
- copyEditingProperties(element->inlineStyle(), AllEditingProperties),
- mode);
- return;
- }
-}
-
-static inline bool elementMatchesAndPropertyIsNotInInlineStyleDecl(
- const HTMLElementEquivalent* equivalent,
- const Element* element,
- EditingStyle::CSSPropertyOverrideMode mode,
- StylePropertySet* style) {
- return equivalent->matches(element) &&
- (!element->inlineStyle() ||
- !equivalent->propertyExistsInStyle(element->inlineStyle())) &&
- (mode == EditingStyle::OverrideValues ||
- !equivalent->propertyExistsInStyle(style));
-}
-
-static MutableStylePropertySet* extractEditingProperties(
- const StylePropertySet* style,
- EditingStyle::PropertiesToInclude propertiesToInclude) {
- if (!style)
- return nullptr;
-
- switch (propertiesToInclude) {
- case EditingStyle::AllProperties:
- case EditingStyle::EditingPropertiesInEffect:
- return copyEditingProperties(style, AllEditingProperties);
- case EditingStyle::OnlyEditingInheritableProperties:
- return copyEditingProperties(style, OnlyInheritableEditingProperties);
- }
-
- NOTREACHED();
- return nullptr;
-}
-
-void EditingStyle::mergeInlineAndImplicitStyleOfElement(
- Element* element,
- CSSPropertyOverrideMode mode,
- PropertiesToInclude propertiesToInclude) {
- EditingStyle* styleFromRules = EditingStyle::create();
- styleFromRules->mergeStyleFromRulesForSerialization(element);
-
- if (element->inlineStyle()) {
- styleFromRules->m_mutableStyle->mergeAndOverrideOnConflict(
- element->inlineStyle());
- }
-
- styleFromRules->m_mutableStyle = extractEditingProperties(
- styleFromRules->m_mutableStyle.get(), propertiesToInclude);
- mergeStyle(styleFromRules->m_mutableStyle.get(), mode);
-
- const HeapVector<Member<HTMLElementEquivalent>>& elementEquivalents =
- htmlElementEquivalents();
- for (const auto& equivalent : elementEquivalents) {
- if (elementMatchesAndPropertyIsNotInInlineStyleDecl(
- equivalent.get(), element, mode, m_mutableStyle.get()))
- equivalent->addToStyle(element, this);
- }
-
- const HeapVector<Member<HTMLAttributeEquivalent>>& attributeEquivalents =
- htmlAttributeEquivalents();
- for (const auto& attribute : attributeEquivalents) {
- if (attribute->attributeName() == HTMLNames::dirAttr)
- continue; // We don't want to include directionality
- if (elementMatchesAndPropertyIsNotInInlineStyleDecl(
- attribute.get(), element, mode, m_mutableStyle.get()))
- attribute->addToStyle(element, this);
- }
-}
-
-EditingStyle* EditingStyle::wrappingStyleForAnnotatedSerialization(
+EditingStyle* EditingStyleUtilities::wrappingStyleForAnnotatedSerialization(
ContainerNode* context) {
EditingStyle* wrappingStyle =
EditingStyle::create(context, EditingStyle::EditingPropertiesInEffect);
@@ -1277,7 +67,7 @@ EditingStyle* EditingStyle::wrappingStyleForAnnotatedSerialization(
return wrappingStyle;
}
-EditingStyle* EditingStyle::wrappingStyleForSerialization(
+EditingStyle* EditingStyleUtilities::wrappingStyleForSerialization(
ContainerNode* context) {
DCHECK(context);
EditingStyle* wrappingStyle = EditingStyle::create();
@@ -1297,246 +87,7 @@ EditingStyle* EditingStyle::wrappingStyleForSerialization(
return wrappingStyle;
}
-static const CSSValueList& mergeTextDecorationValues(
- const CSSValueList& mergedValue,
- const CSSValueList& valueToMerge) {
- DEFINE_STATIC_LOCAL(CSSIdentifierValue, underline,
- (CSSIdentifierValue::create(CSSValueUnderline)));
- DEFINE_STATIC_LOCAL(CSSIdentifierValue, lineThrough,
- (CSSIdentifierValue::create(CSSValueLineThrough)));
- CSSValueList& result = *mergedValue.copy();
- if (valueToMerge.hasValue(underline) && !mergedValue.hasValue(underline))
- result.append(underline);
-
- if (valueToMerge.hasValue(lineThrough) && !mergedValue.hasValue(lineThrough))
- result.append(lineThrough);
-
- return result;
-}
-
-void EditingStyle::mergeStyle(const StylePropertySet* style,
- CSSPropertyOverrideMode mode) {
- if (!style)
- return;
-
- if (!m_mutableStyle) {
- m_mutableStyle = style->mutableCopy();
- return;
- }
-
- unsigned propertyCount = style->propertyCount();
- for (unsigned i = 0; i < propertyCount; ++i) {
- StylePropertySet::PropertyReference property = style->propertyAt(i);
- const CSSValue* value = m_mutableStyle->getPropertyCSSValue(property.id());
-
- // text decorations never override values
- if ((property.id() == textDecorationPropertyForEditing() ||
- property.id() == CSSPropertyWebkitTextDecorationsInEffect) &&
- property.value().isValueList() && value) {
- if (value->isValueList()) {
- const CSSValueList& result = mergeTextDecorationValues(
- *toCSSValueList(value), toCSSValueList(property.value()));
- m_mutableStyle->setProperty(property.id(), result,
- property.isImportant());
- continue;
- }
- // text-decoration: none is equivalent to not having the property
- value = nullptr;
- }
-
- if (mode == OverrideValues || (mode == DoNotOverrideValues && !value))
- m_mutableStyle->setProperty(property.toCSSProperty());
- }
-}
-
-static MutableStylePropertySet* styleFromMatchedRulesForElement(
- Element* element,
- unsigned rulesToInclude) {
- MutableStylePropertySet* style =
- MutableStylePropertySet::create(HTMLQuirksMode);
- StyleRuleList* matchedRules =
- element->document().ensureStyleResolver().styleRulesForElement(
- element, rulesToInclude);
- if (matchedRules) {
- for (unsigned i = 0; i < matchedRules->size(); ++i)
- style->mergeAndOverrideOnConflict(&matchedRules->at(i)->properties());
- }
- return style;
-}
-
-void EditingStyle::mergeStyleFromRules(Element* element) {
- MutableStylePropertySet* styleFromMatchedRules =
- styleFromMatchedRulesForElement(
- element,
- StyleResolver::AuthorCSSRules | StyleResolver::CrossOriginCSSRules);
- // Styles from the inline style declaration, held in the variable "style",
- // take precedence over those from matched rules.
- if (m_mutableStyle)
- styleFromMatchedRules->mergeAndOverrideOnConflict(m_mutableStyle.get());
-
- clear();
- m_mutableStyle = styleFromMatchedRules;
-}
-
-void EditingStyle::mergeStyleFromRulesForSerialization(Element* element) {
- mergeStyleFromRules(element);
-
- // The property value, if it's a percentage, may not reflect the actual
- // computed value.
- // For example: style="height: 1%; overflow: visible;" in quirksmode
- // FIXME: There are others like this, see <rdar://problem/5195123> Slashdot
- // copy/paste fidelity problem
- CSSComputedStyleDeclaration* computedStyleForElement =
- CSSComputedStyleDeclaration::create(element);
- MutableStylePropertySet* fromComputedStyle =
- MutableStylePropertySet::create(HTMLQuirksMode);
- {
- unsigned propertyCount = m_mutableStyle->propertyCount();
- for (unsigned i = 0; i < propertyCount; ++i) {
- StylePropertySet::PropertyReference property =
- m_mutableStyle->propertyAt(i);
- const CSSValue& value = property.value();
- if (!value.isPrimitiveValue())
- continue;
- if (toCSSPrimitiveValue(value).isPercentage()) {
- if (const CSSValue* computedPropertyValue =
- computedStyleForElement->getPropertyCSSValue(property.id())) {
- fromComputedStyle->addRespectingCascade(
- CSSProperty(property.id(), *computedPropertyValue));
- }
- }
- }
- }
- m_mutableStyle->mergeAndOverrideOnConflict(fromComputedStyle);
-}
-
-static void removePropertiesInStyle(
- MutableStylePropertySet* styleToRemovePropertiesFrom,
- StylePropertySet* style) {
- unsigned propertyCount = style->propertyCount();
- Vector<CSSPropertyID> propertiesToRemove(propertyCount);
- for (unsigned i = 0; i < propertyCount; ++i)
- propertiesToRemove[i] = style->propertyAt(i).id();
-
- styleToRemovePropertiesFrom->removePropertiesInSet(propertiesToRemove.data(),
- propertiesToRemove.size());
-}
-
-void EditingStyle::removeStyleFromRulesAndContext(Element* element,
- ContainerNode* context) {
- DCHECK(element);
- if (!m_mutableStyle)
- return;
-
- // StyleResolver requires clean style.
- DCHECK_GE(element->document().lifecycle().state(),
- DocumentLifecycle::StyleClean);
- DCHECK(element->document().isActive());
-
- // 1. Remove style from matched rules because style remain without repeating
- // it in inline style declaration
- MutableStylePropertySet* styleFromMatchedRules =
- styleFromMatchedRulesForElement(element,
- StyleResolver::AllButEmptyCSSRules);
- if (styleFromMatchedRules && !styleFromMatchedRules->isEmpty()) {
- m_mutableStyle =
- getPropertiesNotIn(m_mutableStyle.get(),
- styleFromMatchedRules->ensureCSSStyleDeclaration());
- }
-
- // 2. Remove style present in context and not overriden by matched rules.
- EditingStyle* computedStyle =
- EditingStyle::create(context, EditingPropertiesInEffect);
- if (computedStyle->m_mutableStyle) {
- if (!computedStyle->m_mutableStyle->getPropertyCSSValue(
- CSSPropertyBackgroundColor)) {
- computedStyle->m_mutableStyle->setProperty(CSSPropertyBackgroundColor,
- CSSValueTransparent);
- }
-
- removePropertiesInStyle(computedStyle->m_mutableStyle.get(),
- styleFromMatchedRules);
- m_mutableStyle = getPropertiesNotIn(
- m_mutableStyle.get(),
- computedStyle->m_mutableStyle->ensureCSSStyleDeclaration());
- }
-
- // 3. If this element is a span and has display: inline or float: none, remove
- // them unless they are overriden by rules. These rules are added by
- // serialization code to wrap text nodes.
- if (isStyleSpanOrSpanWithOnlyStyleAttribute(element)) {
- if (!styleFromMatchedRules->getPropertyCSSValue(CSSPropertyDisplay) &&
- getIdentifierValue(m_mutableStyle.get(), CSSPropertyDisplay) ==
- CSSValueInline)
- m_mutableStyle->removeProperty(CSSPropertyDisplay);
- if (!styleFromMatchedRules->getPropertyCSSValue(CSSPropertyFloat) &&
- getIdentifierValue(m_mutableStyle.get(), CSSPropertyFloat) ==
- CSSValueNone)
- m_mutableStyle->removeProperty(CSSPropertyFloat);
- }
-}
-
-void EditingStyle::removePropertiesInElementDefaultStyle(Element* element) {
- if (!m_mutableStyle || m_mutableStyle->isEmpty())
- return;
-
- StylePropertySet* defaultStyle = styleFromMatchedRulesForElement(
- element, StyleResolver::UAAndUserCSSRules);
-
- removePropertiesInStyle(m_mutableStyle.get(), defaultStyle);
-}
-
-void EditingStyle::addAbsolutePositioningFromElement(const Element& element) {
- LayoutRect rect = element.boundingBox();
- LayoutObject* layoutObject = element.layoutObject();
-
- LayoutUnit x = rect.x();
- LayoutUnit y = rect.y();
- LayoutUnit width = rect.width();
- LayoutUnit height = rect.height();
- if (layoutObject && layoutObject->isBox()) {
- LayoutBox* layoutBox = toLayoutBox(layoutObject);
-
- x -= layoutBox->marginLeft();
- y -= layoutBox->marginTop();
-
- m_mutableStyle->setProperty(CSSPropertyBoxSizing, CSSValueBorderBox);
- }
-
- m_mutableStyle->setProperty(CSSPropertyPosition, CSSValueAbsolute);
- m_mutableStyle->setProperty(
- CSSPropertyLeft,
- *CSSPrimitiveValue::create(x, CSSPrimitiveValue::UnitType::Pixels));
- m_mutableStyle->setProperty(
- CSSPropertyTop,
- *CSSPrimitiveValue::create(y, CSSPrimitiveValue::UnitType::Pixels));
- m_mutableStyle->setProperty(
- CSSPropertyWidth,
- *CSSPrimitiveValue::create(width, CSSPrimitiveValue::UnitType::Pixels));
- m_mutableStyle->setProperty(
- CSSPropertyHeight,
- *CSSPrimitiveValue::create(height, CSSPrimitiveValue::UnitType::Pixels));
-}
-
-void EditingStyle::forceInline() {
- if (!m_mutableStyle)
- m_mutableStyle = MutableStylePropertySet::create(HTMLQuirksMode);
- const bool propertyIsImportant = true;
- m_mutableStyle->setProperty(CSSPropertyDisplay, CSSValueInline,
- propertyIsImportant);
-}
-
-int EditingStyle::legacyFontSize(Document* document) const {
- const CSSValue* cssValue =
- m_mutableStyle->getPropertyCSSValue(CSSPropertyFontSize);
- if (!cssValue ||
- !(cssValue->isPrimitiveValue() || cssValue->isIdentifierValue()))
- return 0;
- return legacyFontSizeFromCSSValue(document, cssValue, m_isMonospaceFont,
- AlwaysUseLegacyFontSize);
-}
-
-EditingStyle* EditingStyle::styleAtSelectionStart(
+EditingStyle* EditingStyleUtilities::styleAtSelectionStart(
const VisibleSelection& selection,
bool shouldUseBackgroundColorInEffect,
MutableStylePropertySet* styleToCheck) {
@@ -1585,7 +136,7 @@ EditingStyle* EditingStyle::styleAtSelectionStart(
if (getIdentifierValue(elementStyle, CSSPropertyVerticalAlign) ==
CSSValueBaseline &&
hasAncestorVerticalAlignStyle(*element, valueID))
- style->m_mutableStyle->setProperty(CSSPropertyVerticalAlign, valueID);
+ style->style()->setProperty(CSSPropertyVerticalAlign, valueID);
}
// If background color is transparent, traverse parent nodes until we hit a
@@ -1593,8 +144,7 @@ EditingStyle* EditingStyle::styleAtSelectionStart(
// the background color at the start of selection, and find the background
// color of the common ancestor.
if (shouldUseBackgroundColorInEffect &&
- (selection.isRange() ||
- hasTransparentBackgroundColor(style->m_mutableStyle.get()))) {
+ (selection.isRange() || hasTransparentBackgroundColor(style->style()))) {
const EphemeralRange range(selection.toNormalizedEphemeralRange());
if (const CSSValue* value =
backgroundColorValueInEffect(Range::commonAncestorContainer(
@@ -1614,7 +164,7 @@ static bool isUnicodeBidiNestedOrMultipleEmbeddings(CSSValueID valueID) {
valueID == CSSValueIsolateOverride || valueID == CSSValuePlaintext;
}
-WritingDirection EditingStyle::textDirectionForSelection(
+WritingDirection EditingStyleUtilities::textDirectionForSelection(
const VisibleSelection& selection,
EditingStyle* typingStyle,
bool& hasNestedOrMultipleEmbeddings) {
@@ -1717,318 +267,7 @@ WritingDirection EditingStyle::textDirectionForSelection(
return foundDirection;
}
-DEFINE_TRACE(EditingStyle) {
- visitor->trace(m_mutableStyle);
-}
-
-static void reconcileTextDecorationProperties(MutableStylePropertySet* style) {
- const CSSValue* textDecorationsInEffect =
- style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
- const CSSValue* textDecoration =
- style->getPropertyCSSValue(textDecorationPropertyForEditing());
- // "LayoutTests/editing/execCommand/insert-list-and-strikethrough.html" makes
- // both |textDecorationsInEffect| and |textDecoration| non-null.
- if (textDecorationsInEffect) {
- style->setProperty(textDecorationPropertyForEditing(),
- textDecorationsInEffect->cssText());
- style->removeProperty(CSSPropertyWebkitTextDecorationsInEffect);
- textDecoration = textDecorationsInEffect;
- }
-
- // If text-decoration is set to "none", remove the property because we don't
- // want to add redundant "text-decoration: none".
- if (textDecoration && !textDecoration->isValueList())
- style->removeProperty(textDecorationPropertyForEditing());
-}
-
-StyleChange::StyleChange(EditingStyle* style, const Position& position)
- : m_applyBold(false),
- m_applyItalic(false),
- m_applyUnderline(false),
- m_applyLineThrough(false),
- m_applySubscript(false),
- m_applySuperscript(false) {
- Document* document = position.document();
- if (!style || !style->style() || !document || !document->frame() ||
- !associatedElementOf(position))
- return;
-
- CSSComputedStyleDeclaration* computedStyle = ensureComputedStyle(position);
- // FIXME: take care of background-color in effect
- MutableStylePropertySet* mutableStyle =
- getPropertiesNotIn(style->style(), computedStyle);
- DCHECK(mutableStyle);
-
- reconcileTextDecorationProperties(mutableStyle);
- if (!document->frame()->editor().shouldStyleWithCSS())
- extractTextStyles(document, mutableStyle, computedStyle->isMonospaceFont());
-
- // Changing the whitespace style in a tab span would collapse the tab into a
- // space.
- if (isTabHTMLSpanElementTextNode(position.anchorNode()) ||
- isTabHTMLSpanElement((position.anchorNode())))
- mutableStyle->removeProperty(CSSPropertyWhiteSpace);
-
- // If unicode-bidi is present in mutableStyle and direction is not, then add
- // direction to mutableStyle.
- // FIXME: Shouldn't this be done in getPropertiesNotIn?
- if (mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi) &&
- !style->style()->getPropertyCSSValue(CSSPropertyDirection)) {
- mutableStyle->setProperty(
- CSSPropertyDirection,
- style->style()->getPropertyValue(CSSPropertyDirection));
- }
-
- // Save the result for later
- m_cssStyle = mutableStyle->asText().stripWhiteSpace();
-}
-
-static void setTextDecorationProperty(MutableStylePropertySet* style,
- const CSSValueList* newTextDecoration,
- CSSPropertyID propertyID) {
- if (newTextDecoration->length()) {
- style->setProperty(propertyID, newTextDecoration->cssText(),
- style->propertyIsImportant(propertyID));
- } else {
- // text-decoration: none is redundant since it does not remove any text
- // decorations.
- style->removeProperty(propertyID);
- }
-}
-
-void StyleChange::extractTextStyles(Document* document,
- MutableStylePropertySet* style,
- bool isMonospaceFont) {
- DCHECK(style);
-
- if (getIdentifierValue(style, CSSPropertyFontWeight) == CSSValueBold) {
- style->removeProperty(CSSPropertyFontWeight);
- m_applyBold = true;
- }
-
- int fontStyle = getIdentifierValue(style, CSSPropertyFontStyle);
- if (fontStyle == CSSValueItalic || fontStyle == CSSValueOblique) {
- style->removeProperty(CSSPropertyFontStyle);
- m_applyItalic = true;
- }
-
- // Assuming reconcileTextDecorationProperties has been called, there should
- // not be -webkit-text-decorations-in-effect
- // Furthermore, text-decoration: none has been trimmed so that text-decoration
- // property is always a CSSValueList.
- const CSSValue* textDecoration =
- style->getPropertyCSSValue(textDecorationPropertyForEditing());
- if (textDecoration && textDecoration->isValueList()) {
- DEFINE_STATIC_LOCAL(CSSIdentifierValue, underline,
- (CSSIdentifierValue::create(CSSValueUnderline)));
- DEFINE_STATIC_LOCAL(CSSIdentifierValue, lineThrough,
- (CSSIdentifierValue::create(CSSValueLineThrough)));
- CSSValueList* newTextDecoration = toCSSValueList(textDecoration)->copy();
- if (newTextDecoration->removeAll(underline))
- m_applyUnderline = true;
- if (newTextDecoration->removeAll(lineThrough))
- m_applyLineThrough = true;
-
- // If trimTextDecorations, delete underline and line-through
- setTextDecorationProperty(style, newTextDecoration,
- textDecorationPropertyForEditing());
- }
-
- int verticalAlign = getIdentifierValue(style, CSSPropertyVerticalAlign);
- switch (verticalAlign) {
- case CSSValueSub:
- style->removeProperty(CSSPropertyVerticalAlign);
- m_applySubscript = true;
- break;
- case CSSValueSuper:
- style->removeProperty(CSSPropertyVerticalAlign);
- m_applySuperscript = true;
- break;
- }
-
- if (style->getPropertyCSSValue(CSSPropertyColor)) {
- m_applyFontColor = getFontColor(style).serialized();
- style->removeProperty(CSSPropertyColor);
- }
-
- m_applyFontFace = style->getPropertyValue(CSSPropertyFontFamily);
- // Remove double quotes for Outlook 2007 compatibility. See
- // https://bugs.webkit.org/show_bug.cgi?id=79448
- m_applyFontFace.replace('"', "");
- style->removeProperty(CSSPropertyFontFamily);
-
- if (const CSSValue* fontSize =
- style->getPropertyCSSValue(CSSPropertyFontSize)) {
- if (!fontSize->isPrimitiveValue() && !fontSize->isIdentifierValue()) {
- // Can't make sense of the number. Put no font size.
- style->removeProperty(CSSPropertyFontSize);
- } else if (int legacyFontSize = legacyFontSizeFromCSSValue(
- document, fontSize, isMonospaceFont,
- UseLegacyFontSizeOnlyIfPixelValuesMatch)) {
- m_applyFontSize = String::number(legacyFontSize);
- style->removeProperty(CSSPropertyFontSize);
- }
- }
-}
-
-static void diffTextDecorations(MutableStylePropertySet* style,
- CSSPropertyID propertyID,
- const CSSValue* refTextDecoration) {
- const CSSValue* textDecoration = style->getPropertyCSSValue(propertyID);
- if (!textDecoration || !textDecoration->isValueList() || !refTextDecoration ||
- !refTextDecoration->isValueList())
- return;
-
- CSSValueList* newTextDecoration = toCSSValueList(textDecoration)->copy();
- const CSSValueList* valuesInRefTextDecoration =
- toCSSValueList(refTextDecoration);
-
- for (size_t i = 0; i < valuesInRefTextDecoration->length(); i++)
- newTextDecoration->removeAll(valuesInRefTextDecoration->item(i));
-
- setTextDecorationProperty(style, newTextDecoration, propertyID);
-}
-
-static bool fontWeightIsBold(const CSSValue* fontWeight) {
- if (!fontWeight->isIdentifierValue())
- return false;
-
- // Because b tag can only bold text, there are only two states in plain html:
- // bold and not bold. Collapse all other values to either one of these two
- // states for editing purposes.
- switch (toCSSIdentifierValue(fontWeight)->getValueID()) {
- case CSSValue100:
- case CSSValue200:
- case CSSValue300:
- case CSSValue400:
- case CSSValue500:
- case CSSValueNormal:
- return false;
- case CSSValueBold:
- case CSSValue600:
- case CSSValue700:
- case CSSValue800:
- case CSSValue900:
- return true;
- default:
- break;
- }
-
- NOTREACHED(); // For CSSValueBolder and CSSValueLighter
- return false;
-}
-
-static bool fontWeightNeedsResolving(const CSSValue* fontWeight) {
- if (!fontWeight->isIdentifierValue())
- return true;
-
- const CSSValueID value = toCSSIdentifierValue(fontWeight)->getValueID();
- return value == CSSValueLighter || value == CSSValueBolder;
-}
-
-MutableStylePropertySet* getPropertiesNotIn(
- StylePropertySet* styleWithRedundantProperties,
- CSSStyleDeclaration* baseStyle) {
- DCHECK(styleWithRedundantProperties);
- DCHECK(baseStyle);
- MutableStylePropertySet* result = styleWithRedundantProperties->mutableCopy();
-
- result->removeEquivalentProperties(baseStyle);
-
- const CSSValue* baseTextDecorationsInEffect =
- baseStyle->getPropertyCSSValueInternal(
- CSSPropertyWebkitTextDecorationsInEffect);
- diffTextDecorations(result, textDecorationPropertyForEditing(),
- baseTextDecorationsInEffect);
- diffTextDecorations(result, CSSPropertyWebkitTextDecorationsInEffect,
- baseTextDecorationsInEffect);
-
- if (const CSSValue* baseFontWeight =
- baseStyle->getPropertyCSSValueInternal(CSSPropertyFontWeight)) {
- if (const CSSValue* fontWeight =
- result->getPropertyCSSValue(CSSPropertyFontWeight)) {
- if (!fontWeightNeedsResolving(fontWeight) &&
- !fontWeightNeedsResolving(baseFontWeight) &&
- (fontWeightIsBold(fontWeight) == fontWeightIsBold(baseFontWeight)))
- result->removeProperty(CSSPropertyFontWeight);
- }
- }
-
- if (baseStyle->getPropertyCSSValueInternal(CSSPropertyColor) &&
- getFontColor(result) == getFontColor(baseStyle))
- result->removeProperty(CSSPropertyColor);
-
- if (baseStyle->getPropertyCSSValueInternal(CSSPropertyTextAlign) &&
- textAlignResolvingStartAndEnd(result) ==
- textAlignResolvingStartAndEnd(baseStyle))
- result->removeProperty(CSSPropertyTextAlign);
-
- if (baseStyle->getPropertyCSSValueInternal(CSSPropertyBackgroundColor) &&
- getBackgroundColor(result) == getBackgroundColor(baseStyle))
- result->removeProperty(CSSPropertyBackgroundColor);
-
- return result;
-}
-
-CSSValueID getIdentifierValue(StylePropertySet* style,
- CSSPropertyID propertyID) {
- if (!style)
- return CSSValueInvalid;
- const CSSValue* value = style->getPropertyCSSValue(propertyID);
- if (!value || !value->isIdentifierValue())
- return CSSValueInvalid;
- return toCSSIdentifierValue(value)->getValueID();
-}
-
-CSSValueID getIdentifierValue(CSSStyleDeclaration* style,
- CSSPropertyID propertyID) {
- if (!style)
- return CSSValueInvalid;
- const CSSValue* value = style->getPropertyCSSValueInternal(propertyID);
- if (!value || !value->isIdentifierValue())
- return CSSValueInvalid;
- return toCSSIdentifierValue(value)->getValueID();
-}
-
-int legacyFontSizeFromCSSValue(Document* document,
- const CSSValue* value,
- bool isMonospaceFont,
- LegacyFontSizeMode mode) {
- if (value->isPrimitiveValue()) {
- const CSSPrimitiveValue& primitiveValue = toCSSPrimitiveValue(*value);
- CSSPrimitiveValue::LengthUnitType lengthType;
- if (CSSPrimitiveValue::unitTypeToLengthUnitType(
- primitiveValue.typeWithCalcResolved(), lengthType) &&
- lengthType == CSSPrimitiveValue::UnitTypePixels) {
- double conversion =
- CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(
- primitiveValue.typeWithCalcResolved());
- int pixelFontSize =
- clampTo<int>(primitiveValue.getDoubleValue() * conversion);
- int legacyFontSize =
- FontSize::legacyFontSize(document, pixelFontSize, isMonospaceFont);
- // Use legacy font size only if pixel value matches exactly to that of
- // legacy font size.
- if (mode == AlwaysUseLegacyFontSize ||
- FontSize::fontSizeForKeyword(document, legacyFontSize,
- isMonospaceFont) == pixelFontSize)
- return legacyFontSize;
-
- return 0;
- }
- }
-
- if (value->isIdentifierValue()) {
- const CSSIdentifierValue& identifierValue = toCSSIdentifierValue(*value);
- if (CSSValueXSmall <= identifierValue.getValueID() &&
- identifierValue.getValueID() <= CSSValueWebkitXxxLarge)
- return identifierValue.getValueID() - CSSValueXSmall + 1;
- }
-
- return 0;
-}
-
-bool isTransparentColorValue(const CSSValue* cssValue) {
+bool EditingStyleUtilities::isTransparentColorValue(const CSSValue* cssValue) {
if (!cssValue)
return true;
if (cssValue->isColorValue())
@@ -2038,19 +277,22 @@ bool isTransparentColorValue(const CSSValue* cssValue) {
return toCSSIdentifierValue(cssValue)->getValueID() == CSSValueTransparent;
}
-bool hasTransparentBackgroundColor(CSSStyleDeclaration* style) {
+bool EditingStyleUtilities::hasTransparentBackgroundColor(
+ CSSStyleDeclaration* style) {
const CSSValue* cssValue =
style->getPropertyCSSValueInternal(CSSPropertyBackgroundColor);
return isTransparentColorValue(cssValue);
}
-bool hasTransparentBackgroundColor(StylePropertySet* style) {
+bool EditingStyleUtilities::hasTransparentBackgroundColor(
+ StylePropertySet* style) {
const CSSValue* cssValue =
style->getPropertyCSSValue(CSSPropertyBackgroundColor);
return isTransparentColorValue(cssValue);
}
-const CSSValue* backgroundColorValueInEffect(Node* node) {
+const CSSValue* EditingStyleUtilities::backgroundColorValueInEffect(
+ Node* node) {
for (Node* ancestor = node; ancestor; ancestor = ancestor->parentNode()) {
CSSComputedStyleDeclaration* ancestorStyle =
CSSComputedStyleDeclaration::create(ancestor);
« no previous file with comments | « third_party/WebKit/Source/core/editing/EditingStyleUtilities.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698