summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/WebCore/editing/ApplyStyleCommand.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/WebCore/editing/ApplyStyleCommand.cpp')
-rw-r--r--src/3rdparty/webkit/WebCore/editing/ApplyStyleCommand.cpp93
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;
}
}
}