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

Side by Side Diff: third_party/WebKit/Source/core/editing/EditingStyle.cpp

Issue 2399663003: Reflow comments in //third_party/WebKit/Source/core/editing (Closed)
Patch Set: Created 4 years, 2 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007, 2008, 2009 Apple Computer, Inc. 2 * Copyright (C) 2007, 2008, 2009 Apple Computer, Inc.
3 * Copyright (C) 2010, 2011 Google Inc. All rights reserved. 3 * Copyright (C) 2010, 2011 Google Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 66
67 static const CSSPropertyID& textDecorationPropertyForEditing() { 67 static const CSSPropertyID& textDecorationPropertyForEditing() {
68 static const CSSPropertyID property = 68 static const CSSPropertyID property =
69 RuntimeEnabledFeatures::css3TextDecorationsEnabled() 69 RuntimeEnabledFeatures::css3TextDecorationsEnabled()
70 ? CSSPropertyTextDecorationLine 70 ? CSSPropertyTextDecorationLine
71 : CSSPropertyTextDecoration; 71 : CSSPropertyTextDecoration;
72 return property; 72 return property;
73 } 73 }
74 74
75 // Editing style properties must be preserved during editing operation. 75 // Editing style properties must be preserved during editing operation.
76 // e.g. when a user inserts a new paragraph, all properties listed here must be copied to the new paragraph. 76 // e.g. when a user inserts a new paragraph, all properties listed here must be
77 // copied to the new paragraph.
77 // NOTE: Use either allEditingProperties() or inheritableEditingProperties() to 78 // NOTE: Use either allEditingProperties() or inheritableEditingProperties() to
78 // respect runtime enabling of properties. 79 // respect runtime enabling of properties.
79 static const CSSPropertyID staticEditingProperties[] = { 80 static const CSSPropertyID staticEditingProperties[] = {
80 CSSPropertyBackgroundColor, CSSPropertyColor, CSSPropertyFontFamily, 81 CSSPropertyBackgroundColor, CSSPropertyColor, CSSPropertyFontFamily,
81 CSSPropertyFontSize, CSSPropertyFontStyle, CSSPropertyFontVariantLigatures, 82 CSSPropertyFontSize, CSSPropertyFontStyle, CSSPropertyFontVariantLigatures,
82 CSSPropertyFontVariantCaps, CSSPropertyFontWeight, CSSPropertyLetterSpacing, 83 CSSPropertyFontVariantCaps, CSSPropertyFontWeight, CSSPropertyLetterSpacing,
83 CSSPropertyOrphans, CSSPropertyTextAlign, 84 CSSPropertyOrphans, CSSPropertyTextAlign,
84 // FIXME: CSSPropertyTextDecoration needs to be removed when CSS3 Text 85 // FIXME: CSSPropertyTextDecoration needs to be removed when CSS3 Text
85 // Decoration feature is no longer experimental. 86 // Decoration feature is no longer experimental.
86 CSSPropertyTextDecoration, CSSPropertyTextDecorationLine, 87 CSSPropertyTextDecoration, CSSPropertyTextDecorationLine,
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 DEFINE_INLINE_VIRTUAL_TRACE() { visitor->trace(m_identifierValue); } 192 DEFINE_INLINE_VIRTUAL_TRACE() { visitor->trace(m_identifierValue); }
192 193
193 protected: 194 protected:
194 HTMLElementEquivalent(CSSPropertyID); 195 HTMLElementEquivalent(CSSPropertyID);
195 HTMLElementEquivalent(CSSPropertyID, const HTMLQualifiedName& tagName); 196 HTMLElementEquivalent(CSSPropertyID, const HTMLQualifiedName& tagName);
196 HTMLElementEquivalent(CSSPropertyID, 197 HTMLElementEquivalent(CSSPropertyID,
197 CSSValueID primitiveValue, 198 CSSValueID primitiveValue,
198 const HTMLQualifiedName& tagName); 199 const HTMLQualifiedName& tagName);
199 const CSSPropertyID m_propertyID; 200 const CSSPropertyID m_propertyID;
200 const Member<CSSIdentifierValue> m_identifierValue; 201 const Member<CSSIdentifierValue> m_identifierValue;
201 const HTMLQualifiedName* 202 // We can store a pointer because HTML tag names are const global.
202 m_tagName; // We can store a pointer because HTML tag names are const glo bal. 203 const HTMLQualifiedName* m_tagName;
203 }; 204 };
204 205
205 HTMLElementEquivalent::HTMLElementEquivalent(CSSPropertyID id) 206 HTMLElementEquivalent::HTMLElementEquivalent(CSSPropertyID id)
206 : m_propertyID(id), m_tagName(0) {} 207 : m_propertyID(id), m_tagName(0) {}
207 208
208 HTMLElementEquivalent::HTMLElementEquivalent(CSSPropertyID id, 209 HTMLElementEquivalent::HTMLElementEquivalent(CSSPropertyID id,
209 const HTMLQualifiedName& tagName) 210 const HTMLQualifiedName& tagName)
210 : m_propertyID(id), m_tagName(&tagName) {} 211 : m_propertyID(id), m_tagName(&tagName) {}
211 212
212 HTMLElementEquivalent::HTMLElementEquivalent(CSSPropertyID id, 213 HTMLElementEquivalent::HTMLElementEquivalent(CSSPropertyID id,
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 virtual const CSSValue* attributeValueAsCSSValue(Element*) const; 296 virtual const CSSValue* attributeValueAsCSSValue(Element*) const;
296 inline const QualifiedName& attributeName() const { return m_attrName; } 297 inline const QualifiedName& attributeName() const { return m_attrName; }
297 298
298 DEFINE_INLINE_VIRTUAL_TRACE() { HTMLElementEquivalent::trace(visitor); } 299 DEFINE_INLINE_VIRTUAL_TRACE() { HTMLElementEquivalent::trace(visitor); }
299 300
300 protected: 301 protected:
301 HTMLAttributeEquivalent(CSSPropertyID, 302 HTMLAttributeEquivalent(CSSPropertyID,
302 const HTMLQualifiedName& tagName, 303 const HTMLQualifiedName& tagName,
303 const QualifiedName& attrName); 304 const QualifiedName& attrName);
304 HTMLAttributeEquivalent(CSSPropertyID, const QualifiedName& attrName); 305 HTMLAttributeEquivalent(CSSPropertyID, const QualifiedName& attrName);
305 const QualifiedName& 306 // We can store a reference because HTML attribute names are const global.
306 m_attrName; // We can store a reference because HTML attribute names are const global. 307 const QualifiedName& m_attrName;
307 }; 308 };
308 309
309 HTMLAttributeEquivalent::HTMLAttributeEquivalent( 310 HTMLAttributeEquivalent::HTMLAttributeEquivalent(
310 CSSPropertyID id, 311 CSSPropertyID id,
311 const HTMLQualifiedName& tagName, 312 const HTMLQualifiedName& tagName,
312 const QualifiedName& attrName) 313 const QualifiedName& attrName)
313 : HTMLElementEquivalent(id, tagName), m_attrName(attrName) {} 314 : HTMLElementEquivalent(id, tagName), m_attrName(attrName) {}
314 315
315 HTMLAttributeEquivalent::HTMLAttributeEquivalent(CSSPropertyID id, 316 HTMLAttributeEquivalent::HTMLAttributeEquivalent(CSSPropertyID id,
316 const QualifiedName& attrName) 317 const QualifiedName& attrName)
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 606
606 EditingStyle* EditingStyle::copy() const { 607 EditingStyle* EditingStyle::copy() const {
607 EditingStyle* copy = EditingStyle::create(); 608 EditingStyle* copy = EditingStyle::create();
608 if (m_mutableStyle) 609 if (m_mutableStyle)
609 copy->m_mutableStyle = m_mutableStyle->mutableCopy(); 610 copy->m_mutableStyle = m_mutableStyle->mutableCopy();
610 copy->m_isMonospaceFont = m_isMonospaceFont; 611 copy->m_isMonospaceFont = m_isMonospaceFont;
611 copy->m_fontSizeDelta = m_fontSizeDelta; 612 copy->m_fontSizeDelta = m_fontSizeDelta;
612 return copy; 613 return copy;
613 } 614 }
614 615
615 // This is the list of CSS properties that apply specially to block-level elemen ts. 616 // This is the list of CSS properties that apply specially to block-level
617 // elements.
616 static const CSSPropertyID staticBlockProperties[] = { 618 static const CSSPropertyID staticBlockProperties[] = {
617 CSSPropertyBreakAfter, 619 CSSPropertyBreakAfter,
618 CSSPropertyBreakBefore, 620 CSSPropertyBreakBefore,
619 CSSPropertyBreakInside, 621 CSSPropertyBreakInside,
620 CSSPropertyOrphans, 622 CSSPropertyOrphans,
621 CSSPropertyOverflow, // This can be also be applied to replaced elements 623 CSSPropertyOverflow, // This can be also be applied to replaced elements
622 CSSPropertyColumnCount, 624 CSSPropertyColumnCount,
623 CSSPropertyColumnGap, 625 CSSPropertyColumnGap,
624 CSSPropertyColumnRuleColor, 626 CSSPropertyColumnRuleColor,
625 CSSPropertyColumnRuleStyle, 627 CSSPropertyColumnRuleStyle,
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
786 if (selection.isCaret()) 788 if (selection.isCaret())
787 return triStateOfStyle(EditingStyle::styleAtSelectionStart(selection)); 789 return triStateOfStyle(EditingStyle::styleAtSelectionStart(selection));
788 790
789 TriState state = FalseTriState; 791 TriState state = FalseTriState;
790 bool nodeIsStart = true; 792 bool nodeIsStart = true;
791 for (Node& node : NodeTraversal::startsAt(*selection.start().anchorNode())) { 793 for (Node& node : NodeTraversal::startsAt(*selection.start().anchorNode())) {
792 if (node.layoutObject() && hasEditableStyle(node)) { 794 if (node.layoutObject() && hasEditableStyle(node)) {
793 CSSComputedStyleDeclaration* nodeStyle = 795 CSSComputedStyleDeclaration* nodeStyle =
794 CSSComputedStyleDeclaration::create(&node); 796 CSSComputedStyleDeclaration::create(&node);
795 if (nodeStyle) { 797 if (nodeStyle) {
796 // If the selected element has <sub> or <sup> ancestor element, apply th e corresponding 798 // If the selected element has <sub> or <sup> ancestor element, apply
797 // style(vertical-align) to it so that document.queryCommandState() work s with the style. 799 // the corresponding style(vertical-align) to it so that
798 // See bug http://crbug.com/582225. 800 // document.queryCommandState() works with the style. See bug
801 // http://crbug.com/582225.
799 if (m_isVerticalAlign && 802 if (m_isVerticalAlign &&
800 getIdentifierValue(nodeStyle, CSSPropertyVerticalAlign) == 803 getIdentifierValue(nodeStyle, CSSPropertyVerticalAlign) ==
801 CSSValueBaseline) { 804 CSSValueBaseline) {
802 const CSSIdentifierValue* verticalAlign = toCSSIdentifierValue( 805 const CSSIdentifierValue* verticalAlign = toCSSIdentifierValue(
803 m_mutableStyle->getPropertyCSSValue(CSSPropertyVerticalAlign)); 806 m_mutableStyle->getPropertyCSSValue(CSSPropertyVerticalAlign));
804 if (hasAncestorVerticalAlignStyle(node, verticalAlign->getValueID())) 807 if (hasAncestorVerticalAlignStyle(node, verticalAlign->getValueID()))
805 node.mutableComputedStyle()->setVerticalAlign( 808 node.mutableComputedStyle()->setVerticalAlign(
806 verticalAlign->convertTo<EVerticalAlign>()); 809 verticalAlign->convertTo<EVerticalAlign>());
807 } 810 }
808 811
809 // Pass EditingStyle::DoNotIgnoreTextOnlyProperties without checking if node.isTextNode() 812 // Pass EditingStyle::DoNotIgnoreTextOnlyProperties without checking if
810 // because the node can be an element node. See bug http://crbug.com/584 939. 813 // node.isTextNode() because the node can be an element node. See bug
814 // http://crbug.com/584939.
811 TriState nodeState = triStateOfStyle( 815 TriState nodeState = triStateOfStyle(
812 nodeStyle, EditingStyle::DoNotIgnoreTextOnlyProperties); 816 nodeStyle, EditingStyle::DoNotIgnoreTextOnlyProperties);
813 if (nodeIsStart) { 817 if (nodeIsStart) {
814 state = nodeState; 818 state = nodeState;
815 nodeIsStart = false; 819 nodeIsStart = false;
816 } else if (state != nodeState && node.isTextNode()) { 820 } else if (state != nodeState && node.isTextNode()) {
817 state = MixedTriState; 821 state = MixedTriState;
818 break; 822 break;
819 } 823 }
820 } 824 }
(...skipping 13 matching lines...) Expand all
834 DCHECK(!conflictingProperties || conflictingProperties->isEmpty()); 838 DCHECK(!conflictingProperties || conflictingProperties->isEmpty());
835 839
836 const StylePropertySet* inlineStyle = element->inlineStyle(); 840 const StylePropertySet* inlineStyle = element->inlineStyle();
837 if (!m_mutableStyle || !inlineStyle) 841 if (!m_mutableStyle || !inlineStyle)
838 return false; 842 return false;
839 843
840 unsigned propertyCount = m_mutableStyle->propertyCount(); 844 unsigned propertyCount = m_mutableStyle->propertyCount();
841 for (unsigned i = 0; i < propertyCount; ++i) { 845 for (unsigned i = 0; i < propertyCount; ++i) {
842 CSSPropertyID propertyID = m_mutableStyle->propertyAt(i).id(); 846 CSSPropertyID propertyID = m_mutableStyle->propertyAt(i).id();
843 847
844 // We don't override whitespace property of a tab span because that would co llapse the tab into a space. 848 // We don't override whitespace property of a tab span because that would
849 // collapse the tab into a space.
845 if (propertyID == CSSPropertyWhiteSpace && isTabHTMLSpanElement(element)) 850 if (propertyID == CSSPropertyWhiteSpace && isTabHTMLSpanElement(element))
846 continue; 851 continue;
847 852
848 if (propertyID == CSSPropertyWebkitTextDecorationsInEffect && 853 if (propertyID == CSSPropertyWebkitTextDecorationsInEffect &&
849 inlineStyle->getPropertyCSSValue(textDecorationPropertyForEditing())) { 854 inlineStyle->getPropertyCSSValue(textDecorationPropertyForEditing())) {
850 if (!conflictingProperties) 855 if (!conflictingProperties)
851 return true; 856 return true;
852 conflictingProperties->append(CSSPropertyTextDecoration); 857 conflictingProperties->append(CSSPropertyTextDecoration);
853 // Because text-decoration expands to text-decoration-line when CSS3 858 // Because text-decoration expands to text-decoration-line when CSS3
854 // Text Decoration is enabled, we also state it as conflicting. 859 // Text Decoration is enabled, we also state it as conflicting.
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 } 948 }
944 return false; 949 return false;
945 } 950 }
946 951
947 static const HeapVector<Member<HTMLAttributeEquivalent>>& 952 static const HeapVector<Member<HTMLAttributeEquivalent>>&
948 htmlAttributeEquivalents() { 953 htmlAttributeEquivalents() {
949 DEFINE_STATIC_LOCAL(HeapVector<Member<HTMLAttributeEquivalent>>, 954 DEFINE_STATIC_LOCAL(HeapVector<Member<HTMLAttributeEquivalent>>,
950 HTMLAttributeEquivalents, 955 HTMLAttributeEquivalents,
951 (new HeapVector<Member<HTMLAttributeEquivalent>>)); 956 (new HeapVector<Member<HTMLAttributeEquivalent>>));
952 if (!HTMLAttributeEquivalents.size()) { 957 if (!HTMLAttributeEquivalents.size()) {
953 // elementIsStyledSpanOrHTMLEquivalent depends on the fact each HTMLAttriute Equivalent matches exactly one attribute 958 // elementIsStyledSpanOrHTMLEquivalent depends on the fact each
954 // of exactly one element except dirAttr. 959 // HTMLAttriuteEquivalent matches exactly one attribute of exactly one
960 // element except dirAttr.
955 HTMLAttributeEquivalents.append(HTMLAttributeEquivalent::create( 961 HTMLAttributeEquivalents.append(HTMLAttributeEquivalent::create(
956 CSSPropertyColor, HTMLNames::fontTag, HTMLNames::colorAttr)); 962 CSSPropertyColor, HTMLNames::fontTag, HTMLNames::colorAttr));
957 HTMLAttributeEquivalents.append(HTMLAttributeEquivalent::create( 963 HTMLAttributeEquivalents.append(HTMLAttributeEquivalent::create(
958 CSSPropertyFontFamily, HTMLNames::fontTag, HTMLNames::faceAttr)); 964 CSSPropertyFontFamily, HTMLNames::fontTag, HTMLNames::faceAttr));
959 HTMLAttributeEquivalents.append(HTMLFontSizeEquivalent::create()); 965 HTMLAttributeEquivalents.append(HTMLFontSizeEquivalent::create());
960 966
961 HTMLAttributeEquivalents.append(HTMLAttributeEquivalent::create( 967 HTMLAttributeEquivalents.append(HTMLAttributeEquivalent::create(
962 CSSPropertyDirection, HTMLNames::dirAttr)); 968 CSSPropertyDirection, HTMLNames::dirAttr));
963 HTMLAttributeEquivalents.append(HTMLAttributeEquivalent::create( 969 HTMLAttributeEquivalents.append(HTMLAttributeEquivalent::create(
964 CSSPropertyUnicodeBidi, HTMLNames::dirAttr)); 970 CSSPropertyUnicodeBidi, HTMLNames::dirAttr));
(...skipping 20 matching lines...) Expand all
985 return false; 991 return false;
986 } 992 }
987 993
988 bool EditingStyle::extractConflictingImplicitStyleOfAttributes( 994 bool EditingStyle::extractConflictingImplicitStyleOfAttributes(
989 HTMLElement* element, 995 HTMLElement* element,
990 ShouldPreserveWritingDirection shouldPreserveWritingDirection, 996 ShouldPreserveWritingDirection shouldPreserveWritingDirection,
991 EditingStyle* extractedStyle, 997 EditingStyle* extractedStyle,
992 Vector<QualifiedName>& conflictingAttributes, 998 Vector<QualifiedName>& conflictingAttributes,
993 ShouldExtractMatchingStyle shouldExtractMatchingStyle) const { 999 ShouldExtractMatchingStyle shouldExtractMatchingStyle) const {
994 DCHECK(element); 1000 DCHECK(element);
995 // HTMLAttributeEquivalent::addToStyle doesn't support unicode-bidi and direct ion properties 1001 // HTMLAttributeEquivalent::addToStyle doesn't support unicode-bidi and
1002 // direction properties
996 if (extractedStyle) 1003 if (extractedStyle)
997 DCHECK_EQ(shouldPreserveWritingDirection, PreserveWritingDirection); 1004 DCHECK_EQ(shouldPreserveWritingDirection, PreserveWritingDirection);
998 if (!m_mutableStyle) 1005 if (!m_mutableStyle)
999 return false; 1006 return false;
1000 1007
1001 const HeapVector<Member<HTMLAttributeEquivalent>>& HTMLAttributeEquivalents = 1008 const HeapVector<Member<HTMLAttributeEquivalent>>& HTMLAttributeEquivalents =
1002 htmlAttributeEquivalents(); 1009 htmlAttributeEquivalents();
1003 bool removed = false; 1010 bool removed = false;
1004 for (const auto& attribute : HTMLAttributeEquivalents) { 1011 for (const auto& attribute : HTMLAttributeEquivalents) {
1005 const HTMLAttributeEquivalent* equivalent = attribute.get(); 1012 const HTMLAttributeEquivalent* equivalent = attribute.get();
1006 1013
1007 // unicode-bidi and direction are pushed down separately so don't push down with other styles. 1014 // unicode-bidi and direction are pushed down separately so don't push down
1015 // with other styles.
1008 if (shouldPreserveWritingDirection == PreserveWritingDirection && 1016 if (shouldPreserveWritingDirection == PreserveWritingDirection &&
1009 equivalent->attributeName() == HTMLNames::dirAttr) 1017 equivalent->attributeName() == HTMLNames::dirAttr)
1010 continue; 1018 continue;
1011 1019
1012 if (!equivalent->matches(element) || 1020 if (!equivalent->matches(element) ||
1013 !equivalent->propertyExistsInStyle(m_mutableStyle.get()) || 1021 !equivalent->propertyExistsInStyle(m_mutableStyle.get()) ||
1014 (shouldExtractMatchingStyle == DoNotExtractMatchingStyle && 1022 (shouldExtractMatchingStyle == DoNotExtractMatchingStyle &&
1015 equivalent->valueIsPresentInStyle(element, m_mutableStyle.get()))) 1023 equivalent->valueIsPresentInStyle(element, m_mutableStyle.get())))
1016 continue; 1024 continue;
1017 1025
(...skipping 25 matching lines...) Expand all
1043 size_t i; 1051 size_t i;
1044 for (i = 0; i < HTMLElementEquivalents.size(); ++i) { 1052 for (i = 0; i < HTMLElementEquivalents.size(); ++i) {
1045 if (HTMLElementEquivalents[i]->matches(element)) { 1053 if (HTMLElementEquivalents[i]->matches(element)) {
1046 elementIsSpanOrElementEquivalent = true; 1054 elementIsSpanOrElementEquivalent = true;
1047 break; 1055 break;
1048 } 1056 }
1049 } 1057 }
1050 } 1058 }
1051 1059
1052 AttributeCollection attributes = element->attributes(); 1060 AttributeCollection attributes = element->attributes();
1053 if (attributes.isEmpty()) 1061 if (attributes.isEmpty()) {
1054 return elementIsSpanOrElementEquivalent; // span, b, etc... without any att ributes 1062 // span, b, etc... without any attributes
1063 return elementIsSpanOrElementEquivalent;
1064 }
1055 1065
1056 unsigned matchedAttributes = 0; 1066 unsigned matchedAttributes = 0;
1057 const HeapVector<Member<HTMLAttributeEquivalent>>& HTMLAttributeEquivalents = 1067 const HeapVector<Member<HTMLAttributeEquivalent>>& HTMLAttributeEquivalents =
1058 htmlAttributeEquivalents(); 1068 htmlAttributeEquivalents();
1059 for (const auto& equivalent : HTMLAttributeEquivalents) { 1069 for (const auto& equivalent : HTMLAttributeEquivalents) {
1060 if (equivalent->matches(element) && 1070 if (equivalent->matches(element) &&
1061 equivalent->attributeName() != HTMLNames::dirAttr) 1071 equivalent->attributeName() != HTMLNames::dirAttr)
1062 matchedAttributes++; 1072 matchedAttributes++;
1063 } 1073 }
1064 1074
1065 if (!elementIsSpanOrElementEquivalent && !matchedAttributes) 1075 if (!elementIsSpanOrElementEquivalent && !matchedAttributes) {
1066 return false; // element is not a span, a html element equivalent, or font element. 1076 // element is not a span, a html element equivalent, or font element.
1077 return false;
1078 }
1067 1079
1068 if (element->getAttribute(HTMLNames::classAttr) == AppleStyleSpanClass) 1080 if (element->getAttribute(HTMLNames::classAttr) == AppleStyleSpanClass)
1069 matchedAttributes++; 1081 matchedAttributes++;
1070 1082
1071 if (element->hasAttribute(HTMLNames::styleAttr)) { 1083 if (element->hasAttribute(HTMLNames::styleAttr)) {
1072 if (const StylePropertySet* style = element->inlineStyle()) { 1084 if (const StylePropertySet* style = element->inlineStyle()) {
1073 unsigned propertyCount = style->propertyCount(); 1085 unsigned propertyCount = style->propertyCount();
1074 for (unsigned i = 0; i < propertyCount; ++i) { 1086 for (unsigned i = 0; i < propertyCount; ++i) {
1075 if (!isEditingProperty(style->propertyAt(i).id())) 1087 if (!isEditingProperty(style->propertyAt(i).id()))
1076 return false; 1088 return false;
1077 } 1089 }
1078 } 1090 }
1079 matchedAttributes++; 1091 matchedAttributes++;
1080 } 1092 }
1081 1093
1082 // font with color attribute, span with style attribute, etc... 1094 // font with color attribute, span with style attribute, etc...
1083 DCHECK_LE(matchedAttributes, attributes.size()); 1095 DCHECK_LE(matchedAttributes, attributes.size());
1084 return matchedAttributes >= attributes.size(); 1096 return matchedAttributes >= attributes.size();
1085 } 1097 }
1086 1098
1087 void EditingStyle::prepareToApplyAt( 1099 void EditingStyle::prepareToApplyAt(
1088 const Position& position, 1100 const Position& position,
1089 ShouldPreserveWritingDirection shouldPreserveWritingDirection) { 1101 ShouldPreserveWritingDirection shouldPreserveWritingDirection) {
1090 if (!m_mutableStyle) 1102 if (!m_mutableStyle)
1091 return; 1103 return;
1092 1104
1093 // ReplaceSelectionCommand::handleStyleSpans() requires that this function onl y removes the editing style. 1105 // ReplaceSelectionCommand::handleStyleSpans() requires that this function
1094 // If this function was modified in the future to delete all redundant propert ies, then add a boolean value to indicate 1106 // only removes the editing style. If this function was modified in the future
1107 // to delete all redundant properties, then add a boolean value to indicate
1095 // which one of editingStyleAtPosition or computedStyle is called. 1108 // which one of editingStyleAtPosition or computedStyle is called.
1096 EditingStyle* editingStyleAtPosition = 1109 EditingStyle* editingStyleAtPosition =
1097 EditingStyle::create(position, EditingPropertiesInEffect); 1110 EditingStyle::create(position, EditingPropertiesInEffect);
1098 StylePropertySet* styleAtPosition = 1111 StylePropertySet* styleAtPosition =
1099 editingStyleAtPosition->m_mutableStyle.get(); 1112 editingStyleAtPosition->m_mutableStyle.get();
1100 1113
1101 const CSSValue* unicodeBidi = nullptr; 1114 const CSSValue* unicodeBidi = nullptr;
1102 const CSSValue* direction = nullptr; 1115 const CSSValue* direction = nullptr;
1103 if (shouldPreserveWritingDirection == PreserveWritingDirection) { 1116 if (shouldPreserveWritingDirection == PreserveWritingDirection) {
1104 unicodeBidi = m_mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi); 1117 unicodeBidi = m_mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1236 EditingStyle::create(context, EditingStyle::EditingPropertiesInEffect); 1249 EditingStyle::create(context, EditingStyle::EditingPropertiesInEffect);
1237 1250
1238 // Styles that Mail blockquotes contribute should only be placed on the Mail 1251 // Styles that Mail blockquotes contribute should only be placed on the Mail
1239 // blockquote, to help us differentiate those styles from ones that the user 1252 // blockquote, to help us differentiate those styles from ones that the user
1240 // has applied. This helps us get the color of content pasted into 1253 // has applied. This helps us get the color of content pasted into
1241 // blockquotes right. 1254 // blockquotes right.
1242 wrappingStyle->removeStyleAddedByElement(toHTMLElement(enclosingNodeOfType( 1255 wrappingStyle->removeStyleAddedByElement(toHTMLElement(enclosingNodeOfType(
1243 firstPositionInOrBeforeNode(context), isMailHTMLBlockquoteElement, 1256 firstPositionInOrBeforeNode(context), isMailHTMLBlockquoteElement,
1244 CanCrossEditingBoundary))); 1257 CanCrossEditingBoundary)));
1245 1258
1246 // Call collapseTextDecorationProperties first or otherwise it'll copy the val ue over from in-effect to text-decorations. 1259 // Call collapseTextDecorationProperties first or otherwise it'll copy the
1260 // value over from in-effect to text-decorations.
1247 wrappingStyle->collapseTextDecorationProperties(); 1261 wrappingStyle->collapseTextDecorationProperties();
1248 1262
1249 return wrappingStyle; 1263 return wrappingStyle;
1250 } 1264 }
1251 1265
1252 EditingStyle* EditingStyle::wrappingStyleForSerialization( 1266 EditingStyle* EditingStyle::wrappingStyleForSerialization(
1253 ContainerNode* context) { 1267 ContainerNode* context) {
1254 DCHECK(context); 1268 DCHECK(context);
1255 EditingStyle* wrappingStyle = EditingStyle::create(); 1269 EditingStyle* wrappingStyle = EditingStyle::create();
1256 1270
1257 // When not annotating for interchange, we only preserve inline style declarat ions. 1271 // When not annotating for interchange, we only preserve inline style
1272 // declarations.
1258 for (Node& node : NodeTraversal::inclusiveAncestorsOf(*context)) { 1273 for (Node& node : NodeTraversal::inclusiveAncestorsOf(*context)) {
1259 if (node.isDocumentNode()) 1274 if (node.isDocumentNode())
1260 break; 1275 break;
1261 if (node.isStyledElement() && !isMailHTMLBlockquoteElement(&node)) { 1276 if (node.isStyledElement() && !isMailHTMLBlockquoteElement(&node)) {
1262 wrappingStyle->mergeInlineAndImplicitStyleOfElement( 1277 wrappingStyle->mergeInlineAndImplicitStyleOfElement(
1263 toElement(&node), EditingStyle::DoNotOverrideValues, 1278 toElement(&node), EditingStyle::DoNotOverrideValues,
1264 EditingStyle::EditingPropertiesInEffect); 1279 EditingStyle::EditingPropertiesInEffect);
1265 } 1280 }
1266 } 1281 }
1267 1282
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1304 if ((property.id() == textDecorationPropertyForEditing() || 1319 if ((property.id() == textDecorationPropertyForEditing() ||
1305 property.id() == CSSPropertyWebkitTextDecorationsInEffect) && 1320 property.id() == CSSPropertyWebkitTextDecorationsInEffect) &&
1306 property.value().isValueList() && value) { 1321 property.value().isValueList() && value) {
1307 if (value->isValueList()) { 1322 if (value->isValueList()) {
1308 const CSSValueList& result = mergeTextDecorationValues( 1323 const CSSValueList& result = mergeTextDecorationValues(
1309 *toCSSValueList(value), toCSSValueList(property.value())); 1324 *toCSSValueList(value), toCSSValueList(property.value()));
1310 m_mutableStyle->setProperty(property.id(), result, 1325 m_mutableStyle->setProperty(property.id(), result,
1311 property.isImportant()); 1326 property.isImportant());
1312 continue; 1327 continue;
1313 } 1328 }
1314 value = 1329 // text-decoration: none is equivalent to not having the property
1315 nullptr; // text-decoration: none is equivalent to not having the pro perty 1330 value = nullptr;
1316 } 1331 }
1317 1332
1318 if (mode == OverrideValues || (mode == DoNotOverrideValues && !value)) 1333 if (mode == OverrideValues || (mode == DoNotOverrideValues && !value))
1319 m_mutableStyle->setProperty(property.toCSSProperty()); 1334 m_mutableStyle->setProperty(property.toCSSProperty());
1320 } 1335 }
1321 } 1336 }
1322 1337
1323 static MutableStylePropertySet* styleFromMatchedRulesForElement( 1338 static MutableStylePropertySet* styleFromMatchedRulesForElement(
1324 Element* element, 1339 Element* element,
1325 unsigned rulesToInclude) { 1340 unsigned rulesToInclude) {
1326 MutableStylePropertySet* style = 1341 MutableStylePropertySet* style =
1327 MutableStylePropertySet::create(HTMLQuirksMode); 1342 MutableStylePropertySet::create(HTMLQuirksMode);
1328 StyleRuleList* matchedRules = 1343 StyleRuleList* matchedRules =
1329 element->document().ensureStyleResolver().styleRulesForElement( 1344 element->document().ensureStyleResolver().styleRulesForElement(
1330 element, rulesToInclude); 1345 element, rulesToInclude);
1331 if (matchedRules) { 1346 if (matchedRules) {
1332 for (unsigned i = 0; i < matchedRules->size(); ++i) 1347 for (unsigned i = 0; i < matchedRules->size(); ++i)
1333 style->mergeAndOverrideOnConflict(&matchedRules->at(i)->properties()); 1348 style->mergeAndOverrideOnConflict(&matchedRules->at(i)->properties());
1334 } 1349 }
1335 return style; 1350 return style;
1336 } 1351 }
1337 1352
1338 void EditingStyle::mergeStyleFromRules(Element* element) { 1353 void EditingStyle::mergeStyleFromRules(Element* element) {
1339 MutableStylePropertySet* styleFromMatchedRules = 1354 MutableStylePropertySet* styleFromMatchedRules =
1340 styleFromMatchedRulesForElement( 1355 styleFromMatchedRulesForElement(
1341 element, 1356 element,
1342 StyleResolver::AuthorCSSRules | StyleResolver::CrossOriginCSSRules); 1357 StyleResolver::AuthorCSSRules | StyleResolver::CrossOriginCSSRules);
1343 // Styles from the inline style declaration, held in the variable "style", tak e precedence 1358 // Styles from the inline style declaration, held in the variable "style",
1344 // over those from matched rules. 1359 // take precedence over those from matched rules.
1345 if (m_mutableStyle) 1360 if (m_mutableStyle)
1346 styleFromMatchedRules->mergeAndOverrideOnConflict(m_mutableStyle.get()); 1361 styleFromMatchedRules->mergeAndOverrideOnConflict(m_mutableStyle.get());
1347 1362
1348 clear(); 1363 clear();
1349 m_mutableStyle = styleFromMatchedRules; 1364 m_mutableStyle = styleFromMatchedRules;
1350 } 1365 }
1351 1366
1352 void EditingStyle::mergeStyleFromRulesForSerialization(Element* element) { 1367 void EditingStyle::mergeStyleFromRulesForSerialization(Element* element) {
1353 mergeStyleFromRules(element); 1368 mergeStyleFromRules(element);
1354 1369
1355 // The property value, if it's a percentage, may not reflect the actual comput ed value. 1370 // The property value, if it's a percentage, may not reflect the actual
1371 // computed value.
1356 // For example: style="height: 1%; overflow: visible;" in quirksmode 1372 // For example: style="height: 1%; overflow: visible;" in quirksmode
1357 // FIXME: There are others like this, see <rdar://problem/5195123> Slashdot co py/paste fidelity problem 1373 // FIXME: There are others like this, see <rdar://problem/5195123> Slashdot
1374 // copy/paste fidelity problem
1358 CSSComputedStyleDeclaration* computedStyleForElement = 1375 CSSComputedStyleDeclaration* computedStyleForElement =
1359 CSSComputedStyleDeclaration::create(element); 1376 CSSComputedStyleDeclaration::create(element);
1360 MutableStylePropertySet* fromComputedStyle = 1377 MutableStylePropertySet* fromComputedStyle =
1361 MutableStylePropertySet::create(HTMLQuirksMode); 1378 MutableStylePropertySet::create(HTMLQuirksMode);
1362 { 1379 {
1363 unsigned propertyCount = m_mutableStyle->propertyCount(); 1380 unsigned propertyCount = m_mutableStyle->propertyCount();
1364 for (unsigned i = 0; i < propertyCount; ++i) { 1381 for (unsigned i = 0; i < propertyCount; ++i) {
1365 StylePropertySet::PropertyReference property = 1382 StylePropertySet::PropertyReference property =
1366 m_mutableStyle->propertyAt(i); 1383 m_mutableStyle->propertyAt(i);
1367 const CSSValue& value = property.value(); 1384 const CSSValue& value = property.value();
(...skipping 26 matching lines...) Expand all
1394 ContainerNode* context) { 1411 ContainerNode* context) {
1395 DCHECK(element); 1412 DCHECK(element);
1396 if (!m_mutableStyle) 1413 if (!m_mutableStyle)
1397 return; 1414 return;
1398 1415
1399 // TODO(yosin): The use of updateStyleAndLayoutIgnorePendingStylesheets 1416 // TODO(yosin): The use of updateStyleAndLayoutIgnorePendingStylesheets
1400 // needs to be audited. see http://crbug.com/590369 for more details. 1417 // needs to be audited. see http://crbug.com/590369 for more details.
1401 element->document().updateStyleAndLayoutIgnorePendingStylesheetsForNode( 1418 element->document().updateStyleAndLayoutIgnorePendingStylesheetsForNode(
1402 element); 1419 element);
1403 1420
1404 // 1. Remove style from matched rules because style remain without repeating i t in inline style declaration 1421 // 1. Remove style from matched rules because style remain without repeating
1422 // it in inline style declaration
1405 MutableStylePropertySet* styleFromMatchedRules = 1423 MutableStylePropertySet* styleFromMatchedRules =
1406 styleFromMatchedRulesForElement(element, 1424 styleFromMatchedRulesForElement(element,
1407 StyleResolver::AllButEmptyCSSRules); 1425 StyleResolver::AllButEmptyCSSRules);
1408 if (styleFromMatchedRules && !styleFromMatchedRules->isEmpty()) 1426 if (styleFromMatchedRules && !styleFromMatchedRules->isEmpty())
1409 m_mutableStyle = 1427 m_mutableStyle =
1410 getPropertiesNotIn(m_mutableStyle.get(), 1428 getPropertiesNotIn(m_mutableStyle.get(),
1411 styleFromMatchedRules->ensureCSSStyleDeclaration()); 1429 styleFromMatchedRules->ensureCSSStyleDeclaration());
1412 1430
1413 // 2. Remove style present in context and not overriden by matched rules. 1431 // 2. Remove style present in context and not overriden by matched rules.
1414 EditingStyle* computedStyle = 1432 EditingStyle* computedStyle =
1415 EditingStyle::create(context, EditingPropertiesInEffect); 1433 EditingStyle::create(context, EditingPropertiesInEffect);
1416 if (computedStyle->m_mutableStyle) { 1434 if (computedStyle->m_mutableStyle) {
1417 if (!computedStyle->m_mutableStyle->getPropertyCSSValue( 1435 if (!computedStyle->m_mutableStyle->getPropertyCSSValue(
1418 CSSPropertyBackgroundColor)) 1436 CSSPropertyBackgroundColor))
1419 computedStyle->m_mutableStyle->setProperty(CSSPropertyBackgroundColor, 1437 computedStyle->m_mutableStyle->setProperty(CSSPropertyBackgroundColor,
1420 CSSValueTransparent); 1438 CSSValueTransparent);
1421 1439
1422 removePropertiesInStyle(computedStyle->m_mutableStyle.get(), 1440 removePropertiesInStyle(computedStyle->m_mutableStyle.get(),
1423 styleFromMatchedRules); 1441 styleFromMatchedRules);
1424 m_mutableStyle = getPropertiesNotIn( 1442 m_mutableStyle = getPropertiesNotIn(
1425 m_mutableStyle.get(), 1443 m_mutableStyle.get(),
1426 computedStyle->m_mutableStyle->ensureCSSStyleDeclaration()); 1444 computedStyle->m_mutableStyle->ensureCSSStyleDeclaration());
1427 } 1445 }
1428 1446
1429 // 3. If this element is a span and has display: inline or float: none, remove them unless they are overriden by rules. 1447 // 3. If this element is a span and has display: inline or float: none, remove
1430 // These rules are added by serialization code to wrap text nodes. 1448 // them unless they are overriden by rules. These rules are added by
1449 // serialization code to wrap text nodes.
1431 if (isStyleSpanOrSpanWithOnlyStyleAttribute(element)) { 1450 if (isStyleSpanOrSpanWithOnlyStyleAttribute(element)) {
1432 if (!styleFromMatchedRules->getPropertyCSSValue(CSSPropertyDisplay) && 1451 if (!styleFromMatchedRules->getPropertyCSSValue(CSSPropertyDisplay) &&
1433 getIdentifierValue(m_mutableStyle.get(), CSSPropertyDisplay) == 1452 getIdentifierValue(m_mutableStyle.get(), CSSPropertyDisplay) ==
1434 CSSValueInline) 1453 CSSValueInline)
1435 m_mutableStyle->removeProperty(CSSPropertyDisplay); 1454 m_mutableStyle->removeProperty(CSSPropertyDisplay);
1436 if (!styleFromMatchedRules->getPropertyCSSValue(CSSPropertyFloat) && 1455 if (!styleFromMatchedRules->getPropertyCSSValue(CSSPropertyFloat) &&
1437 getIdentifierValue(m_mutableStyle.get(), CSSPropertyFloat) == 1456 getIdentifierValue(m_mutableStyle.get(), CSSPropertyFloat) ==
1438 CSSValueNone) 1457 CSSValueNone)
1439 m_mutableStyle->removeProperty(CSSPropertyFloat); 1458 m_mutableStyle->removeProperty(CSSPropertyFloat);
1440 } 1459 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1511 1530
1512 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets 1531 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
1513 // needs to be audited. see http://crbug.com/590369 for more details. 1532 // needs to be audited. see http://crbug.com/590369 for more details.
1514 document.updateStyleAndLayoutIgnorePendingStylesheets(); 1533 document.updateStyleAndLayoutIgnorePendingStylesheets();
1515 1534
1516 DocumentLifecycle::DisallowTransitionScope disallowTransition( 1535 DocumentLifecycle::DisallowTransitionScope disallowTransition(
1517 document.lifecycle()); 1536 document.lifecycle());
1518 1537
1519 Position position = adjustedSelectionStartForStyleComputation(selection); 1538 Position position = adjustedSelectionStartForStyleComputation(selection);
1520 1539
1521 // If the pos is at the end of a text node, then this node is not fully select ed. 1540 // If the pos is at the end of a text node, then this node is not fully
1522 // Move it to the next deep equivalent position to avoid removing the style fr om this node. 1541 // selected. Move it to the next deep equivalent position to avoid removing
1523 // e.g. if pos was at Position("hello", 5) in <b>hello<div>world</div></b>, we want Position("world", 0) instead. 1542 // the style from this node.
1524 // We only do this for range because caret at Position("hello", 5) in <b>hello </b>world should give you font-weight: bold. 1543 // e.g. if pos was at Position("hello", 5) in <b>hello<div>world</div></b>, we
1544 // want Position("world", 0) instead.
1545 // We only do this for range because caret at Position("hello", 5) in
1546 // <b>hello</b>world should give you font-weight: bold.
1525 Node* positionNode = position.computeContainerNode(); 1547 Node* positionNode = position.computeContainerNode();
1526 if (selection.isRange() && positionNode && positionNode->isTextNode() && 1548 if (selection.isRange() && positionNode && positionNode->isTextNode() &&
1527 position.computeOffsetInContainerNode() == 1549 position.computeOffsetInContainerNode() ==
1528 positionNode->maxCharacterOffset()) 1550 positionNode->maxCharacterOffset())
1529 position = nextVisuallyDistinctCandidate(position); 1551 position = nextVisuallyDistinctCandidate(position);
1530 1552
1531 Element* element = associatedElementOf(position); 1553 Element* element = associatedElementOf(position);
1532 if (!element) 1554 if (!element)
1533 return nullptr; 1555 return nullptr;
1534 1556
1535 EditingStyle* style = 1557 EditingStyle* style =
1536 EditingStyle::create(element, EditingStyle::AllProperties); 1558 EditingStyle::create(element, EditingStyle::AllProperties);
1537 style->mergeTypingStyle(&element->document()); 1559 style->mergeTypingStyle(&element->document());
1538 1560
1539 // If |element| has <sub> or <sup> ancestor element, apply the corresponding 1561 // If |element| has <sub> or <sup> ancestor element, apply the corresponding
1540 // style(vertical-align) to it so that document.queryCommandState() works with the style. 1562 // style(vertical-align) to it so that document.queryCommandState() works with
1541 // See bug http://crbug.com/582225. 1563 // the style. See bug http://crbug.com/582225.
1542 CSSValueID valueID = 1564 CSSValueID valueID =
1543 getIdentifierValue(styleToCheck, CSSPropertyVerticalAlign); 1565 getIdentifierValue(styleToCheck, CSSPropertyVerticalAlign);
1544 if (valueID == CSSValueSub || valueID == CSSValueSuper) { 1566 if (valueID == CSSValueSub || valueID == CSSValueSuper) {
1545 CSSComputedStyleDeclaration* elementStyle = 1567 CSSComputedStyleDeclaration* elementStyle =
1546 CSSComputedStyleDeclaration::create(element); 1568 CSSComputedStyleDeclaration::create(element);
1547 // Find the ancestor that has CSSValueSub or CSSValueSuper as the value of C SS vertical-align property. 1569 // Find the ancestor that has CSSValueSub or CSSValueSuper as the value of
1570 // CSS vertical-align property.
1548 if (getIdentifierValue(elementStyle, CSSPropertyVerticalAlign) == 1571 if (getIdentifierValue(elementStyle, CSSPropertyVerticalAlign) ==
1549 CSSValueBaseline && 1572 CSSValueBaseline &&
1550 hasAncestorVerticalAlignStyle(*element, valueID)) 1573 hasAncestorVerticalAlignStyle(*element, valueID))
1551 style->m_mutableStyle->setProperty(CSSPropertyVerticalAlign, valueID); 1574 style->m_mutableStyle->setProperty(CSSPropertyVerticalAlign, valueID);
1552 } 1575 }
1553 1576
1554 // If background color is transparent, traverse parent nodes until we hit a di fferent value or document root 1577 // If background color is transparent, traverse parent nodes until we hit a
1555 // Also, if the selection is a range, ignore the background color at the start of selection, 1578 // different value or document root Also, if the selection is a range, ignore
1556 // and find the background color of the common ancestor. 1579 // the background color at the start of selection, and find the background
1580 // color of the common ancestor.
1557 if (shouldUseBackgroundColorInEffect && 1581 if (shouldUseBackgroundColorInEffect &&
1558 (selection.isRange() || 1582 (selection.isRange() ||
1559 hasTransparentBackgroundColor(style->m_mutableStyle.get()))) { 1583 hasTransparentBackgroundColor(style->m_mutableStyle.get()))) {
1560 const EphemeralRange range(selection.toNormalizedEphemeralRange()); 1584 const EphemeralRange range(selection.toNormalizedEphemeralRange());
1561 if (const CSSValue* value = 1585 if (const CSSValue* value =
1562 backgroundColorValueInEffect(Range::commonAncestorContainer( 1586 backgroundColorValueInEffect(Range::commonAncestorContainer(
1563 range.startPosition().computeContainerNode(), 1587 range.startPosition().computeContainerNode(),
1564 range.endPosition().computeContainerNode()))) 1588 range.endPosition().computeContainerNode())))
1565 style->setProperty(CSSPropertyBackgroundColor, value->cssText()); 1589 style->setProperty(CSSPropertyBackgroundColor, value->cssText());
1566 } 1590 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1619 if (selection.isCaret()) { 1643 if (selection.isCaret()) {
1620 WritingDirection direction; 1644 WritingDirection direction;
1621 if (typingStyle && typingStyle->textDirection(direction)) { 1645 if (typingStyle && typingStyle->textDirection(direction)) {
1622 hasNestedOrMultipleEmbeddings = false; 1646 hasNestedOrMultipleEmbeddings = false;
1623 return direction; 1647 return direction;
1624 } 1648 }
1625 node = selection.visibleStart().deepEquivalent().anchorNode(); 1649 node = selection.visibleStart().deepEquivalent().anchorNode();
1626 } 1650 }
1627 DCHECK(node); 1651 DCHECK(node);
1628 1652
1629 // The selection is either a caret with no typing attributes or a range in whi ch no embedding is added, so just use the start position 1653 // The selection is either a caret with no typing attributes or a range in
1630 // to decide. 1654 // which no embedding is added, so just use the start position to decide.
1631 Node* block = enclosingBlock(node); 1655 Node* block = enclosingBlock(node);
1632 WritingDirection foundDirection = NaturalWritingDirection; 1656 WritingDirection foundDirection = NaturalWritingDirection;
1633 1657
1634 for (Node& runner : NodeTraversal::inclusiveAncestorsOf(*node)) { 1658 for (Node& runner : NodeTraversal::inclusiveAncestorsOf(*node)) {
1635 if (runner == block) 1659 if (runner == block)
1636 break; 1660 break;
1637 if (!runner.isStyledElement()) 1661 if (!runner.isStyledElement())
1638 continue; 1662 continue;
1639 1663
1640 Element* element = &toElement(runner); 1664 Element* element = &toElement(runner);
(...skipping 18 matching lines...) Expand all
1659 if (!direction || !direction->isIdentifierValue()) 1683 if (!direction || !direction->isIdentifierValue())
1660 continue; 1684 continue;
1661 1685
1662 int directionValue = toCSSIdentifierValue(direction)->getValueID(); 1686 int directionValue = toCSSIdentifierValue(direction)->getValueID();
1663 if (directionValue != CSSValueLtr && directionValue != CSSValueRtl) 1687 if (directionValue != CSSValueLtr && directionValue != CSSValueRtl)
1664 continue; 1688 continue;
1665 1689
1666 if (foundDirection != NaturalWritingDirection) 1690 if (foundDirection != NaturalWritingDirection)
1667 return NaturalWritingDirection; 1691 return NaturalWritingDirection;
1668 1692
1669 // In the range case, make sure that the embedding element persists until th e end of the range. 1693 // In the range case, make sure that the embedding element persists until
1694 // the end of the range.
1670 if (selection.isRange() && !end.anchorNode()->isDescendantOf(element)) 1695 if (selection.isRange() && !end.anchorNode()->isDescendantOf(element))
1671 return NaturalWritingDirection; 1696 return NaturalWritingDirection;
1672 1697
1673 foundDirection = directionValue == CSSValueLtr 1698 foundDirection = directionValue == CSSValueLtr
1674 ? LeftToRightWritingDirection 1699 ? LeftToRightWritingDirection
1675 : RightToLeftWritingDirection; 1700 : RightToLeftWritingDirection;
1676 } 1701 }
1677 hasNestedOrMultipleEmbeddings = false; 1702 hasNestedOrMultipleEmbeddings = false;
1678 return foundDirection; 1703 return foundDirection;
1679 } 1704 }
1680 1705
1681 DEFINE_TRACE(EditingStyle) { 1706 DEFINE_TRACE(EditingStyle) {
1682 visitor->trace(m_mutableStyle); 1707 visitor->trace(m_mutableStyle);
1683 } 1708 }
1684 1709
1685 static void reconcileTextDecorationProperties(MutableStylePropertySet* style) { 1710 static void reconcileTextDecorationProperties(MutableStylePropertySet* style) {
1686 const CSSValue* textDecorationsInEffect = 1711 const CSSValue* textDecorationsInEffect =
1687 style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect); 1712 style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
1688 const CSSValue* textDecoration = 1713 const CSSValue* textDecoration =
1689 style->getPropertyCSSValue(textDecorationPropertyForEditing()); 1714 style->getPropertyCSSValue(textDecorationPropertyForEditing());
1690 // We shouldn't have both text-decoration and -webkit-text-decorations-in-effe ct because that wouldn't make sense. 1715 // We shouldn't have both text-decoration and
1716 // -webkit-text-decorations-in-effect because that wouldn't make sense.
1691 DCHECK(!textDecorationsInEffect || !textDecoration); 1717 DCHECK(!textDecorationsInEffect || !textDecoration);
1692 if (textDecorationsInEffect) { 1718 if (textDecorationsInEffect) {
1693 style->setProperty(textDecorationPropertyForEditing(), 1719 style->setProperty(textDecorationPropertyForEditing(),
1694 textDecorationsInEffect->cssText()); 1720 textDecorationsInEffect->cssText());
1695 style->removeProperty(CSSPropertyWebkitTextDecorationsInEffect); 1721 style->removeProperty(CSSPropertyWebkitTextDecorationsInEffect);
1696 textDecoration = textDecorationsInEffect; 1722 textDecoration = textDecorationsInEffect;
1697 } 1723 }
1698 1724
1699 // If text-decoration is set to "none", remove the property because we don't w ant to add redundant "text-decoration: none". 1725 // If text-decoration is set to "none", remove the property because we don't
1726 // want to add redundant "text-decoration: none".
1700 if (textDecoration && !textDecoration->isValueList()) 1727 if (textDecoration && !textDecoration->isValueList())
1701 style->removeProperty(textDecorationPropertyForEditing()); 1728 style->removeProperty(textDecorationPropertyForEditing());
1702 } 1729 }
1703 1730
1704 StyleChange::StyleChange(EditingStyle* style, const Position& position) 1731 StyleChange::StyleChange(EditingStyle* style, const Position& position)
1705 : m_applyBold(false), 1732 : m_applyBold(false),
1706 m_applyItalic(false), 1733 m_applyItalic(false),
1707 m_applyUnderline(false), 1734 m_applyUnderline(false),
1708 m_applyLineThrough(false), 1735 m_applyLineThrough(false),
1709 m_applySubscript(false), 1736 m_applySubscript(false),
1710 m_applySuperscript(false) { 1737 m_applySuperscript(false) {
1711 Document* document = position.document(); 1738 Document* document = position.document();
1712 if (!style || !style->style() || !document || !document->frame() || 1739 if (!style || !style->style() || !document || !document->frame() ||
1713 !associatedElementOf(position)) 1740 !associatedElementOf(position))
1714 return; 1741 return;
1715 1742
1716 CSSComputedStyleDeclaration* computedStyle = ensureComputedStyle(position); 1743 CSSComputedStyleDeclaration* computedStyle = ensureComputedStyle(position);
1717 // FIXME: take care of background-color in effect 1744 // FIXME: take care of background-color in effect
1718 MutableStylePropertySet* mutableStyle = 1745 MutableStylePropertySet* mutableStyle =
1719 getPropertiesNotIn(style->style(), computedStyle); 1746 getPropertiesNotIn(style->style(), computedStyle);
1720 DCHECK(mutableStyle); 1747 DCHECK(mutableStyle);
1721 1748
1722 reconcileTextDecorationProperties(mutableStyle); 1749 reconcileTextDecorationProperties(mutableStyle);
1723 if (!document->frame()->editor().shouldStyleWithCSS()) 1750 if (!document->frame()->editor().shouldStyleWithCSS())
1724 extractTextStyles(document, mutableStyle, computedStyle->isMonospaceFont()); 1751 extractTextStyles(document, mutableStyle, computedStyle->isMonospaceFont());
1725 1752
1726 // Changing the whitespace style in a tab span would collapse the tab into a s pace. 1753 // Changing the whitespace style in a tab span would collapse the tab into a
1754 // space.
1727 if (isTabHTMLSpanElementTextNode(position.anchorNode()) || 1755 if (isTabHTMLSpanElementTextNode(position.anchorNode()) ||
1728 isTabHTMLSpanElement((position.anchorNode()))) 1756 isTabHTMLSpanElement((position.anchorNode())))
1729 mutableStyle->removeProperty(CSSPropertyWhiteSpace); 1757 mutableStyle->removeProperty(CSSPropertyWhiteSpace);
1730 1758
1731 // If unicode-bidi is present in mutableStyle and direction is not, then add d irection to mutableStyle. 1759 // If unicode-bidi is present in mutableStyle and direction is not, then add
1760 // direction to mutableStyle.
1732 // FIXME: Shouldn't this be done in getPropertiesNotIn? 1761 // FIXME: Shouldn't this be done in getPropertiesNotIn?
1733 if (mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi) && 1762 if (mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi) &&
1734 !style->style()->getPropertyCSSValue(CSSPropertyDirection)) 1763 !style->style()->getPropertyCSSValue(CSSPropertyDirection))
1735 mutableStyle->setProperty( 1764 mutableStyle->setProperty(
1736 CSSPropertyDirection, 1765 CSSPropertyDirection,
1737 style->style()->getPropertyValue(CSSPropertyDirection)); 1766 style->style()->getPropertyValue(CSSPropertyDirection));
1738 1767
1739 // Save the result for later 1768 // Save the result for later
1740 m_cssStyle = mutableStyle->asText().stripWhiteSpace(); 1769 m_cssStyle = mutableStyle->asText().stripWhiteSpace();
1741 } 1770 }
(...skipping 20 matching lines...) Expand all
1762 style->removeProperty(CSSPropertyFontWeight); 1791 style->removeProperty(CSSPropertyFontWeight);
1763 m_applyBold = true; 1792 m_applyBold = true;
1764 } 1793 }
1765 1794
1766 int fontStyle = getIdentifierValue(style, CSSPropertyFontStyle); 1795 int fontStyle = getIdentifierValue(style, CSSPropertyFontStyle);
1767 if (fontStyle == CSSValueItalic || fontStyle == CSSValueOblique) { 1796 if (fontStyle == CSSValueItalic || fontStyle == CSSValueOblique) {
1768 style->removeProperty(CSSPropertyFontStyle); 1797 style->removeProperty(CSSPropertyFontStyle);
1769 m_applyItalic = true; 1798 m_applyItalic = true;
1770 } 1799 }
1771 1800
1772 // Assuming reconcileTextDecorationProperties has been called, there should no t be -webkit-text-decorations-in-effect 1801 // Assuming reconcileTextDecorationProperties has been called, there should
1773 // Furthermore, text-decoration: none has been trimmed so that text-decoration property is always a CSSValueList. 1802 // not be -webkit-text-decorations-in-effect
1803 // Furthermore, text-decoration: none has been trimmed so that text-decoration
1804 // property is always a CSSValueList.
1774 const CSSValue* textDecoration = 1805 const CSSValue* textDecoration =
1775 style->getPropertyCSSValue(textDecorationPropertyForEditing()); 1806 style->getPropertyCSSValue(textDecorationPropertyForEditing());
1776 if (textDecoration && textDecoration->isValueList()) { 1807 if (textDecoration && textDecoration->isValueList()) {
1777 DEFINE_STATIC_LOCAL(CSSIdentifierValue, underline, 1808 DEFINE_STATIC_LOCAL(CSSIdentifierValue, underline,
1778 (CSSIdentifierValue::create(CSSValueUnderline))); 1809 (CSSIdentifierValue::create(CSSValueUnderline)));
1779 DEFINE_STATIC_LOCAL(CSSIdentifierValue, lineThrough, 1810 DEFINE_STATIC_LOCAL(CSSIdentifierValue, lineThrough,
1780 (CSSIdentifierValue::create(CSSValueLineThrough))); 1811 (CSSIdentifierValue::create(CSSValueLineThrough)));
1781 CSSValueList* newTextDecoration = toCSSValueList(textDecoration)->copy(); 1812 CSSValueList* newTextDecoration = toCSSValueList(textDecoration)->copy();
1782 if (newTextDecoration->removeAll(underline)) 1813 if (newTextDecoration->removeAll(underline))
1783 m_applyUnderline = true; 1814 m_applyUnderline = true;
(...skipping 16 matching lines...) Expand all
1800 m_applySuperscript = true; 1831 m_applySuperscript = true;
1801 break; 1832 break;
1802 } 1833 }
1803 1834
1804 if (style->getPropertyCSSValue(CSSPropertyColor)) { 1835 if (style->getPropertyCSSValue(CSSPropertyColor)) {
1805 m_applyFontColor = getFontColor(style).serialized(); 1836 m_applyFontColor = getFontColor(style).serialized();
1806 style->removeProperty(CSSPropertyColor); 1837 style->removeProperty(CSSPropertyColor);
1807 } 1838 }
1808 1839
1809 m_applyFontFace = style->getPropertyValue(CSSPropertyFontFamily); 1840 m_applyFontFace = style->getPropertyValue(CSSPropertyFontFamily);
1810 // Remove double quotes for Outlook 2007 compatibility. See https://bugs.webki t.org/show_bug.cgi?id=79448 1841 // Remove double quotes for Outlook 2007 compatibility. See
1842 // https://bugs.webkit.org/show_bug.cgi?id=79448
1811 m_applyFontFace.replace('"', ""); 1843 m_applyFontFace.replace('"', "");
1812 style->removeProperty(CSSPropertyFontFamily); 1844 style->removeProperty(CSSPropertyFontFamily);
1813 1845
1814 if (const CSSValue* fontSize = 1846 if (const CSSValue* fontSize =
1815 style->getPropertyCSSValue(CSSPropertyFontSize)) { 1847 style->getPropertyCSSValue(CSSPropertyFontSize)) {
1816 if (!fontSize->isPrimitiveValue() && !fontSize->isIdentifierValue()) { 1848 if (!fontSize->isPrimitiveValue() && !fontSize->isIdentifierValue()) {
1817 style->removeProperty( 1849 // Can't make sense of the number. Put no font size.
1818 CSSPropertyFontSize); // Can't make sense of the number. Put no font size. 1850 style->removeProperty(CSSPropertyFontSize);
1819 } else if (int legacyFontSize = legacyFontSizeFromCSSValue( 1851 } else if (int legacyFontSize = legacyFontSizeFromCSSValue(
1820 document, fontSize, isMonospaceFont, 1852 document, fontSize, isMonospaceFont,
1821 UseLegacyFontSizeOnlyIfPixelValuesMatch)) { 1853 UseLegacyFontSizeOnlyIfPixelValuesMatch)) {
1822 m_applyFontSize = String::number(legacyFontSize); 1854 m_applyFontSize = String::number(legacyFontSize);
1823 style->removeProperty(CSSPropertyFontSize); 1855 style->removeProperty(CSSPropertyFontSize);
1824 } 1856 }
1825 } 1857 }
1826 } 1858 }
1827 1859
1828 static void diffTextDecorations(MutableStylePropertySet* style, 1860 static void diffTextDecorations(MutableStylePropertySet* style,
(...skipping 11 matching lines...) Expand all
1840 for (size_t i = 0; i < valuesInRefTextDecoration->length(); i++) 1872 for (size_t i = 0; i < valuesInRefTextDecoration->length(); i++)
1841 newTextDecoration->removeAll(valuesInRefTextDecoration->item(i)); 1873 newTextDecoration->removeAll(valuesInRefTextDecoration->item(i));
1842 1874
1843 setTextDecorationProperty(style, newTextDecoration, propertyID); 1875 setTextDecorationProperty(style, newTextDecoration, propertyID);
1844 } 1876 }
1845 1877
1846 static bool fontWeightIsBold(const CSSValue* fontWeight) { 1878 static bool fontWeightIsBold(const CSSValue* fontWeight) {
1847 if (!fontWeight->isIdentifierValue()) 1879 if (!fontWeight->isIdentifierValue())
1848 return false; 1880 return false;
1849 1881
1850 // Because b tag can only bold text, there are only two states in plain html: bold and not bold. 1882 // Because b tag can only bold text, there are only two states in plain html:
1851 // Collapse all other values to either one of these two states for editing pur poses. 1883 // bold and not bold. Collapse all other values to either one of these two
1884 // states for editing purposes.
1852 switch (toCSSIdentifierValue(fontWeight)->getValueID()) { 1885 switch (toCSSIdentifierValue(fontWeight)->getValueID()) {
1853 case CSSValue100: 1886 case CSSValue100:
1854 case CSSValue200: 1887 case CSSValue200:
1855 case CSSValue300: 1888 case CSSValue300:
1856 case CSSValue400: 1889 case CSSValue400:
1857 case CSSValue500: 1890 case CSSValue500:
1858 case CSSValueNormal: 1891 case CSSValueNormal:
1859 return false; 1892 return false;
1860 case CSSValueBold: 1893 case CSSValueBold:
1861 case CSSValue600: 1894 case CSSValue600:
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1953 if (CSSPrimitiveValue::unitTypeToLengthUnitType( 1986 if (CSSPrimitiveValue::unitTypeToLengthUnitType(
1954 primitiveValue.typeWithCalcResolved(), lengthType) && 1987 primitiveValue.typeWithCalcResolved(), lengthType) &&
1955 lengthType == CSSPrimitiveValue::UnitTypePixels) { 1988 lengthType == CSSPrimitiveValue::UnitTypePixels) {
1956 double conversion = 1989 double conversion =
1957 CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor( 1990 CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(
1958 primitiveValue.typeWithCalcResolved()); 1991 primitiveValue.typeWithCalcResolved());
1959 int pixelFontSize = 1992 int pixelFontSize =
1960 clampTo<int>(primitiveValue.getDoubleValue() * conversion); 1993 clampTo<int>(primitiveValue.getDoubleValue() * conversion);
1961 int legacyFontSize = 1994 int legacyFontSize =
1962 FontSize::legacyFontSize(document, pixelFontSize, isMonospaceFont); 1995 FontSize::legacyFontSize(document, pixelFontSize, isMonospaceFont);
1963 // Use legacy font size only if pixel value matches exactly to that of leg acy font size. 1996 // Use legacy font size only if pixel value matches exactly to that of
1997 // legacy font size.
1964 if (mode == AlwaysUseLegacyFontSize || 1998 if (mode == AlwaysUseLegacyFontSize ||
1965 FontSize::fontSizeForKeyword(document, legacyFontSize, 1999 FontSize::fontSizeForKeyword(document, legacyFontSize,
1966 isMonospaceFont) == pixelFontSize) 2000 isMonospaceFont) == pixelFontSize)
1967 return legacyFontSize; 2001 return legacyFontSize;
1968 2002
1969 return 0; 2003 return 0;
1970 } 2004 }
1971 } 2005 }
1972 2006
1973 if (value->isIdentifierValue()) { 2007 if (value->isIdentifierValue()) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2006 for (Node* ancestor = node; ancestor; ancestor = ancestor->parentNode()) { 2040 for (Node* ancestor = node; ancestor; ancestor = ancestor->parentNode()) {
2007 CSSComputedStyleDeclaration* ancestorStyle = 2041 CSSComputedStyleDeclaration* ancestorStyle =
2008 CSSComputedStyleDeclaration::create(ancestor); 2042 CSSComputedStyleDeclaration::create(ancestor);
2009 if (!hasTransparentBackgroundColor(ancestorStyle)) 2043 if (!hasTransparentBackgroundColor(ancestorStyle))
2010 return ancestorStyle->getPropertyCSSValue(CSSPropertyBackgroundColor); 2044 return ancestorStyle->getPropertyCSSValue(CSSPropertyBackgroundColor);
2011 } 2045 }
2012 return nullptr; 2046 return nullptr;
2013 } 2047 }
2014 2048
2015 } // namespace blink 2049 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/editing/EditingStyle.h ('k') | third_party/WebKit/Source/core/editing/EditingUtilities.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698