| OLD | NEW |
| 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 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 void HTMLAttributeEquivalent::addToStyle(Element* element, EditingStyle* style)
const | 284 void HTMLAttributeEquivalent::addToStyle(Element* element, EditingStyle* style)
const |
| 285 { | 285 { |
| 286 if (RefPtrWillBeRawPtr<CSSValue> value = attributeValueAsCSSValue(element)) | 286 if (RefPtrWillBeRawPtr<CSSValue> value = attributeValueAsCSSValue(element)) |
| 287 style->setProperty(m_propertyID, value->cssText()); | 287 style->setProperty(m_propertyID, value->cssText()); |
| 288 } | 288 } |
| 289 | 289 |
| 290 PassRefPtrWillBeRawPtr<CSSValue> HTMLAttributeEquivalent::attributeValueAsCSSVal
ue(Element* element) const | 290 PassRefPtrWillBeRawPtr<CSSValue> HTMLAttributeEquivalent::attributeValueAsCSSVal
ue(Element* element) const |
| 291 { | 291 { |
| 292 ASSERT(element); | 292 ASSERT(element); |
| 293 if (!element->hasAttribute(m_attrName)) | 293 if (!element->hasAttribute(m_attrName)) |
| 294 return 0; | 294 return nullptr; |
| 295 | 295 |
| 296 RefPtr<MutableStylePropertySet> dummyStyle; | 296 RefPtr<MutableStylePropertySet> dummyStyle; |
| 297 dummyStyle = MutableStylePropertySet::create(); | 297 dummyStyle = MutableStylePropertySet::create(); |
| 298 dummyStyle->setProperty(m_propertyID, element->getAttribute(m_attrName)); | 298 dummyStyle->setProperty(m_propertyID, element->getAttribute(m_attrName)); |
| 299 return dummyStyle->getPropertyCSSValue(m_propertyID); | 299 return dummyStyle->getPropertyCSSValue(m_propertyID); |
| 300 } | 300 } |
| 301 | 301 |
| 302 class HTMLFontSizeEquivalent FINAL : public HTMLAttributeEquivalent { | 302 class HTMLFontSizeEquivalent FINAL : public HTMLAttributeEquivalent { |
| 303 public: | 303 public: |
| 304 static PassOwnPtr<HTMLFontSizeEquivalent> create() | 304 static PassOwnPtr<HTMLFontSizeEquivalent> create() |
| 305 { | 305 { |
| 306 return adoptPtr(new HTMLFontSizeEquivalent()); | 306 return adoptPtr(new HTMLFontSizeEquivalent()); |
| 307 } | 307 } |
| 308 virtual PassRefPtrWillBeRawPtr<CSSValue> attributeValueAsCSSValue(Element*)
const OVERRIDE; | 308 virtual PassRefPtrWillBeRawPtr<CSSValue> attributeValueAsCSSValue(Element*)
const OVERRIDE; |
| 309 | 309 |
| 310 private: | 310 private: |
| 311 HTMLFontSizeEquivalent(); | 311 HTMLFontSizeEquivalent(); |
| 312 }; | 312 }; |
| 313 | 313 |
| 314 HTMLFontSizeEquivalent::HTMLFontSizeEquivalent() | 314 HTMLFontSizeEquivalent::HTMLFontSizeEquivalent() |
| 315 : HTMLAttributeEquivalent(CSSPropertyFontSize, HTMLNames::fontTag, HTMLNames
::sizeAttr) | 315 : HTMLAttributeEquivalent(CSSPropertyFontSize, HTMLNames::fontTag, HTMLNames
::sizeAttr) |
| 316 { | 316 { |
| 317 } | 317 } |
| 318 | 318 |
| 319 PassRefPtrWillBeRawPtr<CSSValue> HTMLFontSizeEquivalent::attributeValueAsCSSValu
e(Element* element) const | 319 PassRefPtrWillBeRawPtr<CSSValue> HTMLFontSizeEquivalent::attributeValueAsCSSValu
e(Element* element) const |
| 320 { | 320 { |
| 321 ASSERT(element); | 321 ASSERT(element); |
| 322 if (!element->hasAttribute(m_attrName)) | 322 if (!element->hasAttribute(m_attrName)) |
| 323 return 0; | 323 return nullptr; |
| 324 CSSValueID size; | 324 CSSValueID size; |
| 325 if (!HTMLFontElement::cssValueFromFontSizeNumber(element->getAttribute(m_att
rName), size)) | 325 if (!HTMLFontElement::cssValueFromFontSizeNumber(element->getAttribute(m_att
rName), size)) |
| 326 return 0; | 326 return nullptr; |
| 327 return CSSPrimitiveValue::createIdentifier(size); | 327 return CSSPrimitiveValue::createIdentifier(size); |
| 328 } | 328 } |
| 329 | 329 |
| 330 float EditingStyle::NoFontDelta = 0.0f; | 330 float EditingStyle::NoFontDelta = 0.0f; |
| 331 | 331 |
| 332 EditingStyle::EditingStyle() | 332 EditingStyle::EditingStyle() |
| 333 : m_shouldUseFixedDefaultFontSize(false) | 333 : m_shouldUseFixedDefaultFontSize(false) |
| 334 , m_fontSizeDelta(NoFontDelta) | 334 , m_fontSizeDelta(NoFontDelta) |
| 335 { | 335 { |
| 336 } | 336 } |
| 337 | 337 |
| 338 EditingStyle::EditingStyle(Node* node, PropertiesToInclude propertiesToInclude) | 338 EditingStyle::EditingStyle(Node* node, PropertiesToInclude propertiesToInclude) |
| 339 : m_shouldUseFixedDefaultFontSize(false) | 339 : m_shouldUseFixedDefaultFontSize(false) |
| 340 , m_fontSizeDelta(NoFontDelta) | 340 , m_fontSizeDelta(NoFontDelta) |
| 341 { | 341 { |
| 342 init(node, propertiesToInclude); | 342 init(node, propertiesToInclude); |
| 343 } | 343 } |
| 344 | 344 |
| 345 EditingStyle::EditingStyle(const Position& position, PropertiesToInclude propert
iesToInclude) | 345 EditingStyle::EditingStyle(const Position& position, PropertiesToInclude propert
iesToInclude) |
| 346 : m_shouldUseFixedDefaultFontSize(false) | 346 : m_shouldUseFixedDefaultFontSize(false) |
| 347 , m_fontSizeDelta(NoFontDelta) | 347 , m_fontSizeDelta(NoFontDelta) |
| 348 { | 348 { |
| 349 init(position.deprecatedNode(), propertiesToInclude); | 349 init(position.deprecatedNode(), propertiesToInclude); |
| 350 } | 350 } |
| 351 | 351 |
| 352 EditingStyle::EditingStyle(const StylePropertySet* style) | 352 EditingStyle::EditingStyle(const StylePropertySet* style) |
| 353 : m_mutableStyle(style ? style->mutableCopy() : 0) | 353 : m_mutableStyle(style ? style->mutableCopy() : nullptr) |
| 354 , m_shouldUseFixedDefaultFontSize(false) | 354 , m_shouldUseFixedDefaultFontSize(false) |
| 355 , m_fontSizeDelta(NoFontDelta) | 355 , m_fontSizeDelta(NoFontDelta) |
| 356 { | 356 { |
| 357 extractFontSizeDelta(); | 357 extractFontSizeDelta(); |
| 358 } | 358 } |
| 359 | 359 |
| 360 EditingStyle::EditingStyle(CSSPropertyID propertyID, const String& value) | 360 EditingStyle::EditingStyle(CSSPropertyID propertyID, const String& value) |
| 361 : m_mutableStyle(0) | 361 : m_mutableStyle(nullptr) |
| 362 , m_shouldUseFixedDefaultFontSize(false) | 362 , m_shouldUseFixedDefaultFontSize(false) |
| 363 , m_fontSizeDelta(NoFontDelta) | 363 , m_fontSizeDelta(NoFontDelta) |
| 364 { | 364 { |
| 365 setProperty(propertyID, value); | 365 setProperty(propertyID, value); |
| 366 } | 366 } |
| 367 | 367 |
| 368 EditingStyle::~EditingStyle() | 368 EditingStyle::~EditingStyle() |
| 369 { | 369 { |
| 370 } | 370 } |
| 371 | 371 |
| (...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 995 static inline bool elementMatchesAndPropertyIsNotInInlineStyleDecl(const HTMLEle
mentEquivalent* equivalent, const Element* element, | 995 static inline bool elementMatchesAndPropertyIsNotInInlineStyleDecl(const HTMLEle
mentEquivalent* equivalent, const Element* element, |
| 996 EditingStyle::CSSPropertyOverrideMode mode, StylePropertySet* style) | 996 EditingStyle::CSSPropertyOverrideMode mode, StylePropertySet* style) |
| 997 { | 997 { |
| 998 return equivalent->matches(element) && (!element->inlineStyle() || !equivale
nt->propertyExistsInStyle(element->inlineStyle())) | 998 return equivalent->matches(element) && (!element->inlineStyle() || !equivale
nt->propertyExistsInStyle(element->inlineStyle())) |
| 999 && (mode == EditingStyle::OverrideValues || !equivalent->propertyExistsI
nStyle(style)); | 999 && (mode == EditingStyle::OverrideValues || !equivalent->propertyExistsI
nStyle(style)); |
| 1000 } | 1000 } |
| 1001 | 1001 |
| 1002 static PassRefPtr<MutableStylePropertySet> extractEditingProperties(const StyleP
ropertySet* style, EditingStyle::PropertiesToInclude propertiesToInclude) | 1002 static PassRefPtr<MutableStylePropertySet> extractEditingProperties(const StyleP
ropertySet* style, EditingStyle::PropertiesToInclude propertiesToInclude) |
| 1003 { | 1003 { |
| 1004 if (!style) | 1004 if (!style) |
| 1005 return 0; | 1005 return nullptr; |
| 1006 | 1006 |
| 1007 switch (propertiesToInclude) { | 1007 switch (propertiesToInclude) { |
| 1008 case EditingStyle::AllProperties: | 1008 case EditingStyle::AllProperties: |
| 1009 case EditingStyle::EditingPropertiesInEffect: | 1009 case EditingStyle::EditingPropertiesInEffect: |
| 1010 return copyEditingProperties(style, AllEditingProperties); | 1010 return copyEditingProperties(style, AllEditingProperties); |
| 1011 case EditingStyle::OnlyEditingInheritableProperties: | 1011 case EditingStyle::OnlyEditingInheritableProperties: |
| 1012 return copyEditingProperties(style, OnlyInheritableEditingProperties); | 1012 return copyEditingProperties(style, OnlyInheritableEditingProperties); |
| 1013 } | 1013 } |
| 1014 | 1014 |
| 1015 ASSERT_NOT_REACHED(); | 1015 ASSERT_NOT_REACHED(); |
| 1016 return 0; | 1016 return nullptr; |
| 1017 } | 1017 } |
| 1018 | 1018 |
| 1019 void EditingStyle::mergeInlineAndImplicitStyleOfElement(Element* element, CSSPro
pertyOverrideMode mode, PropertiesToInclude propertiesToInclude) | 1019 void EditingStyle::mergeInlineAndImplicitStyleOfElement(Element* element, CSSPro
pertyOverrideMode mode, PropertiesToInclude propertiesToInclude) |
| 1020 { | 1020 { |
| 1021 RefPtr<EditingStyle> styleFromRules = EditingStyle::create(); | 1021 RefPtr<EditingStyle> styleFromRules = EditingStyle::create(); |
| 1022 styleFromRules->mergeStyleFromRulesForSerialization(element); | 1022 styleFromRules->mergeStyleFromRulesForSerialization(element); |
| 1023 styleFromRules->m_mutableStyle = extractEditingProperties(styleFromRules->m_
mutableStyle.get(), propertiesToInclude); | 1023 styleFromRules->m_mutableStyle = extractEditingProperties(styleFromRules->m_
mutableStyle.get(), propertiesToInclude); |
| 1024 mergeStyle(styleFromRules->m_mutableStyle.get(), mode); | 1024 mergeStyle(styleFromRules->m_mutableStyle.get(), mode); |
| 1025 | 1025 |
| 1026 mergeInlineStyleOfElement(element, mode, propertiesToInclude); | 1026 mergeInlineStyleOfElement(element, mode, propertiesToInclude); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1097 for (unsigned i = 0; i < propertyCount; ++i) { | 1097 for (unsigned i = 0; i < propertyCount; ++i) { |
| 1098 StylePropertySet::PropertyReference property = style->propertyAt(i); | 1098 StylePropertySet::PropertyReference property = style->propertyAt(i); |
| 1099 RefPtrWillBeRawPtr<CSSValue> value = m_mutableStyle->getPropertyCSSValue
(property.id()); | 1099 RefPtrWillBeRawPtr<CSSValue> value = m_mutableStyle->getPropertyCSSValue
(property.id()); |
| 1100 | 1100 |
| 1101 // text decorations never override values | 1101 // text decorations never override values |
| 1102 if ((property.id() == textDecorationPropertyForEditing() || property.id(
) == CSSPropertyWebkitTextDecorationsInEffect) && property.value()->isValueList(
) && value) { | 1102 if ((property.id() == textDecorationPropertyForEditing() || property.id(
) == CSSPropertyWebkitTextDecorationsInEffect) && property.value()->isValueList(
) && value) { |
| 1103 if (value->isValueList()) { | 1103 if (value->isValueList()) { |
| 1104 mergeTextDecorationValues(toCSSValueList(value.get()), toCSSValu
eList(property.value())); | 1104 mergeTextDecorationValues(toCSSValueList(value.get()), toCSSValu
eList(property.value())); |
| 1105 continue; | 1105 continue; |
| 1106 } | 1106 } |
| 1107 value = 0; // text-decoration: none is equivalent to not having the
property | 1107 value = nullptr; // text-decoration: none is equivalent to not havin
g the property |
| 1108 } | 1108 } |
| 1109 | 1109 |
| 1110 if (mode == OverrideValues || (mode == DoNotOverrideValues && !value)) | 1110 if (mode == OverrideValues || (mode == DoNotOverrideValues && !value)) |
| 1111 m_mutableStyle->setProperty(property.id(), property.value()->cssText
(), property.isImportant()); | 1111 m_mutableStyle->setProperty(property.id(), property.value()->cssText
(), property.isImportant()); |
| 1112 } | 1112 } |
| 1113 } | 1113 } |
| 1114 | 1114 |
| 1115 static PassRefPtr<MutableStylePropertySet> styleFromMatchedRulesForElement(Eleme
nt* element, unsigned rulesToInclude) | 1115 static PassRefPtr<MutableStylePropertySet> styleFromMatchedRulesForElement(Eleme
nt* element, unsigned rulesToInclude) |
| 1116 { | 1116 { |
| 1117 RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create(); | 1117 RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create(); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1225 RefPtrWillBeRawPtr<CSSValue> cssValue = m_mutableStyle->getPropertyCSSValue(
CSSPropertyFontSize); | 1225 RefPtrWillBeRawPtr<CSSValue> cssValue = m_mutableStyle->getPropertyCSSValue(
CSSPropertyFontSize); |
| 1226 if (!cssValue || !cssValue->isPrimitiveValue()) | 1226 if (!cssValue || !cssValue->isPrimitiveValue()) |
| 1227 return 0; | 1227 return 0; |
| 1228 return legacyFontSizeFromCSSValue(document, toCSSPrimitiveValue(cssValue.get
()), | 1228 return legacyFontSizeFromCSSValue(document, toCSSPrimitiveValue(cssValue.get
()), |
| 1229 m_shouldUseFixedDefaultFontSize, AlwaysUseLegacyFontSize); | 1229 m_shouldUseFixedDefaultFontSize, AlwaysUseLegacyFontSize); |
| 1230 } | 1230 } |
| 1231 | 1231 |
| 1232 PassRefPtr<EditingStyle> EditingStyle::styleAtSelectionStart(const VisibleSelect
ion& selection, bool shouldUseBackgroundColorInEffect) | 1232 PassRefPtr<EditingStyle> EditingStyle::styleAtSelectionStart(const VisibleSelect
ion& selection, bool shouldUseBackgroundColorInEffect) |
| 1233 { | 1233 { |
| 1234 if (selection.isNone()) | 1234 if (selection.isNone()) |
| 1235 return 0; | 1235 return nullptr; |
| 1236 | 1236 |
| 1237 Position position = adjustedSelectionStartForStyleComputation(selection); | 1237 Position position = adjustedSelectionStartForStyleComputation(selection); |
| 1238 | 1238 |
| 1239 // If the pos is at the end of a text node, then this node is not fully sele
cted. | 1239 // If the pos is at the end of a text node, then this node is not fully sele
cted. |
| 1240 // Move it to the next deep equivalent position to avoid removing the style
from this node. | 1240 // Move it to the next deep equivalent position to avoid removing the style
from this node. |
| 1241 // e.g. if pos was at Position("hello", 5) in <b>hello<div>world</div></b>,
we want Position("world", 0) instead. | 1241 // e.g. if pos was at Position("hello", 5) in <b>hello<div>world</div></b>,
we want Position("world", 0) instead. |
| 1242 // We only do this for range because caret at Position("hello", 5) in <b>hel
lo</b>world should give you font-weight: bold. | 1242 // We only do this for range because caret at Position("hello", 5) in <b>hel
lo</b>world should give you font-weight: bold. |
| 1243 Node* positionNode = position.containerNode(); | 1243 Node* positionNode = position.containerNode(); |
| 1244 if (selection.isRange() && positionNode && positionNode->isTextNode() && pos
ition.computeOffsetInContainerNode() == positionNode->maxCharacterOffset()) | 1244 if (selection.isRange() && positionNode && positionNode->isTextNode() && pos
ition.computeOffsetInContainerNode() == positionNode->maxCharacterOffset()) |
| 1245 position = nextVisuallyDistinctCandidate(position); | 1245 position = nextVisuallyDistinctCandidate(position); |
| 1246 | 1246 |
| 1247 Element* element = position.element(); | 1247 Element* element = position.element(); |
| 1248 if (!element) | 1248 if (!element) |
| 1249 return 0; | 1249 return nullptr; |
| 1250 | 1250 |
| 1251 RefPtr<EditingStyle> style = EditingStyle::create(element, EditingStyle::All
Properties); | 1251 RefPtr<EditingStyle> style = EditingStyle::create(element, EditingStyle::All
Properties); |
| 1252 style->mergeTypingStyle(&element->document()); | 1252 style->mergeTypingStyle(&element->document()); |
| 1253 | 1253 |
| 1254 // If background color is transparent, traverse parent nodes until we hit a
different value or document root | 1254 // If background color is transparent, traverse parent nodes until we hit a
different value or document root |
| 1255 // Also, if the selection is a range, ignore the background color at the sta
rt of selection, | 1255 // Also, if the selection is a range, ignore the background color at the sta
rt of selection, |
| 1256 // and find the background color of the common ancestor. | 1256 // and find the background color of the common ancestor. |
| 1257 if (shouldUseBackgroundColorInEffect && (selection.isRange() || hasTranspare
ntBackgroundColor(style->m_mutableStyle.get()))) { | 1257 if (shouldUseBackgroundColorInEffect && (selection.isRange() || hasTranspare
ntBackgroundColor(style->m_mutableStyle.get()))) { |
| 1258 RefPtr<Range> range(selection.toNormalizedRange()); | 1258 RefPtr<Range> range(selection.toNormalizedRange()); |
| 1259 if (PassRefPtrWillBeRawPtr<CSSValue> value = backgroundColorInEffect(ran
ge->commonAncestorContainer(IGNORE_EXCEPTION))) | 1259 if (PassRefPtrWillBeRawPtr<CSSValue> value = backgroundColorInEffect(ran
ge->commonAncestorContainer(IGNORE_EXCEPTION))) |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1628 return isTransparentColorValue(cssValue.get()); | 1628 return isTransparentColorValue(cssValue.get()); |
| 1629 } | 1629 } |
| 1630 | 1630 |
| 1631 PassRefPtrWillBeRawPtr<CSSValue> backgroundColorInEffect(Node* node) | 1631 PassRefPtrWillBeRawPtr<CSSValue> backgroundColorInEffect(Node* node) |
| 1632 { | 1632 { |
| 1633 for (Node* ancestor = node; ancestor; ancestor = ancestor->parentNode()) { | 1633 for (Node* ancestor = node; ancestor; ancestor = ancestor->parentNode()) { |
| 1634 RefPtr<CSSComputedStyleDeclaration> ancestorStyle = CSSComputedStyleDecl
aration::create(ancestor); | 1634 RefPtr<CSSComputedStyleDeclaration> ancestorStyle = CSSComputedStyleDecl
aration::create(ancestor); |
| 1635 if (!hasTransparentBackgroundColor(ancestorStyle.get())) | 1635 if (!hasTransparentBackgroundColor(ancestorStyle.get())) |
| 1636 return ancestorStyle->getPropertyCSSValue(CSSPropertyBackgroundColor
); | 1636 return ancestorStyle->getPropertyCSSValue(CSSPropertyBackgroundColor
); |
| 1637 } | 1637 } |
| 1638 return 0; | 1638 return nullptr; |
| 1639 } | 1639 } |
| 1640 | 1640 |
| 1641 } | 1641 } |
| OLD | NEW |