diff options
Diffstat (limited to 'src/3rdparty/webkit/WebCore/editing/ApplyStyleCommand.cpp')
-rw-r--r-- | src/3rdparty/webkit/WebCore/editing/ApplyStyleCommand.cpp | 93 |
1 files changed, 60 insertions, 33 deletions
diff --git a/src/3rdparty/webkit/WebCore/editing/ApplyStyleCommand.cpp b/src/3rdparty/webkit/WebCore/editing/ApplyStyleCommand.cpp index 998a1e2df..36cd82315 100644 --- a/src/3rdparty/webkit/WebCore/editing/ApplyStyleCommand.cpp +++ b/src/3rdparty/webkit/WebCore/editing/ApplyStyleCommand.cpp @@ -98,13 +98,12 @@ void StyleChange::init(PassRefPtr<CSSStyleDeclaration> style, const Position& po Document* document = position.node() ? position.node()->document() : 0; if (!document || !document->frame()) return; - + bool useHTMLFormattingTags = !document->frame()->editor()->shouldStyleWithCSS(); - RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable(); - + // We shouldn't have both text-decoration and -webkit-text-decorations-in-effect because that wouldn't make sense. + ASSERT(!mutableStyle->getPropertyCSSValue(CSSPropertyTextDecoration) || !mutableStyle->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect)); String styleText(""); - bool addedDirection = false; CSSMutableStyleDeclaration::const_iterator end = mutableStyle->end(); for (CSSMutableStyleDeclaration::const_iterator it = mutableStyle->begin(); it != end; ++it) { @@ -130,12 +129,12 @@ void StyleChange::init(PassRefPtr<CSSStyleDeclaration> style, const Position& po } // Add this property - - if (property->id() == CSSPropertyWebkitTextDecorationsInEffect) { - // we have to special-case text decorations - // FIXME: Why? + if (property->id() == CSSPropertyTextDecoration || property->id() == CSSPropertyWebkitTextDecorationsInEffect) { + // Always use text-decoration because -webkit-text-decoration-in-effect is internal. CSSProperty alteredProperty(CSSPropertyTextDecoration, property->value(), property->isImportant()); - styleText += alteredProperty.cssText(); + // We don't add "text-decoration: none" because it doesn't override the existing text decorations; i.e. redundant + if (!equalIgnoringCase(alteredProperty.value()->cssText(), "none")) + styleText += alteredProperty.cssText(); } else styleText += property->cssText(); @@ -962,6 +961,25 @@ bool ApplyStyleCommand::implicitlyStyledElementShouldBeRemovedWhenApplyingStyle( if (elem->hasLocalName(iTag) || elem->hasLocalName(emTag)) return true; break; + case CSSPropertyTextDecoration: + case CSSPropertyWebkitTextDecorationsInEffect: + ASSERT(property.value()); + if (property.value()->isValueList()) { + CSSValueList* valueList = static_cast<CSSValueList*>(property.value()); + DEFINE_STATIC_LOCAL(RefPtr<CSSPrimitiveValue>, underline, (CSSPrimitiveValue::createIdentifier(CSSValueUnderline))); + DEFINE_STATIC_LOCAL(RefPtr<CSSPrimitiveValue>, lineThrough, (CSSPrimitiveValue::createIdentifier(CSSValueLineThrough))); + // Because style is new style to be applied, we delete element only if the element is not used in style. + if (!valueList->hasValue(underline.get()) && elem->hasLocalName(uTag)) + return true; + if (!valueList->hasValue(lineThrough.get()) && (elem->hasLocalName(strikeTag) || elem->hasLocalName(sTag))) + return true; + } else { + // If the value is NOT a list, then it must be "none", in which case we should remove all text decorations. + ASSERT(property.value()->cssText() == "none"); + if (elem->hasLocalName(uTag) || elem->hasLocalName(strikeTag) || elem->hasLocalName(sTag)) + return true; + } + break; } } return false; @@ -1075,11 +1093,17 @@ static bool hasTextDecorationProperty(Node *node) static Node* highestAncestorWithTextDecoration(Node *node) { - Node *result = NULL; + ASSERT(node); + Node* result = 0; + Node* unsplittableElement = unsplittableElementForPosition(Position(node, 0)); for (Node *n = node; n; n = n->parentNode()) { if (hasTextDecorationProperty(n)) result = n; + // Should stop at the editable root (cannot cross editing boundary) and + // also stop at the unsplittable element to be consistent with other UAs + if (n == unsplittableElement) + break; } return result; @@ -1162,32 +1186,35 @@ void ApplyStyleCommand::applyTextDecorationStyle(Node *node, CSSMutableStyleDecl } } -void ApplyStyleCommand::pushDownTextDecorationStyleAroundNode(Node* node, bool force) +void ApplyStyleCommand::pushDownTextDecorationStyleAroundNode(Node* targetNode, bool forceNegate) { - Node *highestAncestor = highestAncestorWithTextDecoration(node); - - if (highestAncestor) { - Node *nextCurrent; - Node *nextChild; - for (Node *current = highestAncestor; current != node; current = nextCurrent) { - ASSERT(current); - - nextCurrent = NULL; - - RefPtr<CSSMutableStyleDeclaration> decoration = force ? extractAndNegateTextDecorationStyle(current) : extractTextDecorationStyle(current); + ASSERT(targetNode); + Node* highestAncestor = highestAncestorWithTextDecoration(targetNode); + if (!highestAncestor) + return; - for (Node *child = current->firstChild(); child; child = nextChild) { - nextChild = child->nextSibling(); + // The outer loop is traversing the tree vertically from highestAncestor to targetNode + Node* current = highestAncestor; + while (current != targetNode) { + ASSERT(current); + ASSERT(current->contains(targetNode)); + RefPtr<CSSMutableStyleDeclaration> decoration = forceNegate ? extractAndNegateTextDecorationStyle(current) : extractTextDecorationStyle(current); + + // The inner loop will go through children on each level + Node* child = current->firstChild(); + while (child) { + Node* nextChild = child->nextSibling(); + + // Apply text decoration to all nodes containing targetNode and their siblings but NOT to targetNode + if (child != targetNode) + applyTextDecorationStyle(child, decoration.get()); + + // We found the next node for the outer loop (contains targetNode) + // When reached targetNode, stop the outer loop upon the completion of the current inner loop + if (child == targetNode || child->contains(targetNode)) + current = child; - if (node == child) { - nextCurrent = child; - } else if (node->isDescendantOf(child)) { - applyTextDecorationStyle(child, decoration.get()); - nextCurrent = child; - } else { - applyTextDecorationStyle(child, decoration.get()); - } - } + child = nextChild; } } } |