Index: Source/core/editing/ApplyStyleCommand.cpp |
diff --git a/Source/core/editing/ApplyStyleCommand.cpp b/Source/core/editing/ApplyStyleCommand.cpp |
index 62762cf6f0bcf4023d2d4ccfe306d22724534141..472165b28fce5dfaa95e8bb46bb6e3dace57dd80 100644 |
--- a/Source/core/editing/ApplyStyleCommand.cpp |
+++ b/Source/core/editing/ApplyStyleCommand.cpp |
@@ -44,6 +44,8 @@ |
#include "core/editing/VisibleUnits.h" |
#include "core/editing/htmlediting.h" |
#include "core/frame/UseCounter.h" |
+#include "core/html/HTMLFontElement.h" |
+#include "core/html/HTMLSpanElement.h" |
#include "core/rendering/RenderObject.h" |
#include "core/rendering/RenderText.h" |
#include "platform/heap/Handle.h" |
@@ -60,19 +62,19 @@ static String& styleSpanClassString() |
return styleSpanClassString; |
} |
-bool isLegacyAppleStyleSpan(const Node *node) |
+bool isLegacyAppleStyleSpan(const Node* node) |
{ |
- if (!node || !node->isHTMLElement()) |
+ if (!isHTMLSpanElement(node)) |
return false; |
- const HTMLElement& element = toHTMLElement(*node); |
- if (!isHTMLSpanElement(element) || element.getAttribute(classAttr) != styleSpanClassString()) |
+ const HTMLSpanElement& span = toHTMLSpanElement(*node); |
+ if (span.getAttribute(classAttr) != styleSpanClassString()) |
return false; |
- UseCounter::count(element.document(), UseCounter::EditingAppleStyleSpanClass); |
+ UseCounter::count(span.document(), UseCounter::EditingAppleStyleSpanClass); |
return true; |
} |
-static bool hasNoAttributeOrOnlyStyleAttribute(const Element* element, ShouldStyleAttributeBeEmpty shouldStyleAttributeBeEmpty) |
+static bool hasNoAttributeOrOnlyStyleAttribute(const HTMLElement* element, ShouldStyleAttributeBeEmpty shouldStyleAttributeBeEmpty) |
{ |
if (!element->hasAttributes()) |
return true; |
@@ -92,14 +94,14 @@ bool isStyleSpanOrSpanWithOnlyStyleAttribute(const Element* element) |
{ |
if (!isHTMLSpanElement(element)) |
return false; |
- return hasNoAttributeOrOnlyStyleAttribute(toHTMLElement(element), AllowNonEmptyStyleAttribute); |
+ return hasNoAttributeOrOnlyStyleAttribute(toHTMLSpanElement(element), AllowNonEmptyStyleAttribute); |
} |
static inline bool isSpanWithoutAttributesOrUnstyledStyleSpan(const Node* node) |
{ |
if (!isHTMLSpanElement(node)) |
return false; |
- return hasNoAttributeOrOnlyStyleAttribute(toHTMLElement(node), StyleAttributeShouldBeEmpty); |
+ return hasNoAttributeOrOnlyStyleAttribute(toHTMLSpanElement(node), StyleAttributeShouldBeEmpty); |
} |
bool isEmptyFontTag(const Element* element, ShouldStyleAttributeBeEmpty shouldStyleAttributeBeEmpty) |
@@ -107,17 +109,17 @@ bool isEmptyFontTag(const Element* element, ShouldStyleAttributeBeEmpty shouldSt |
if (!isHTMLFontElement(element)) |
return false; |
- return hasNoAttributeOrOnlyStyleAttribute(toHTMLElement(element), shouldStyleAttributeBeEmpty); |
+ return hasNoAttributeOrOnlyStyleAttribute(toHTMLFontElement(element), shouldStyleAttributeBeEmpty); |
} |
-static PassRefPtrWillBeRawPtr<Element> createFontElement(Document& document) |
+static PassRefPtrWillBeRawPtr<HTMLFontElement> createFontElement(Document& document) |
{ |
- return createHTMLElement(document, fontTag); |
+ return toHTMLFontElement(createHTMLElement(document, fontTag).get()); |
} |
-PassRefPtrWillBeRawPtr<HTMLElement> createStyleSpanElement(Document& document) |
+PassRefPtrWillBeRawPtr<HTMLSpanElement> createStyleSpanElement(Document& document) |
{ |
- return createHTMLElement(document, spanTag); |
+ return toHTMLSpanElement(createHTMLElement(document, spanTag).get()); |
} |
ApplyStyleCommand::ApplyStyleCommand(Document& document, const EditingStyle* style, EditAction editingAction, EPropertyLevel propertyLevel) |
@@ -268,14 +270,13 @@ void ApplyStyleCommand::applyBlockStyle(EditingStyle *style) |
while (paragraphStart.isNotNull() && paragraphStart != beyondEnd) { |
StyleChange styleChange(style, paragraphStart.deepEquivalent()); |
if (styleChange.cssStyle().length() || m_removeOnly) { |
- RefPtrWillBeRawPtr<Node> block = enclosingBlock(paragraphStart.deepEquivalent().deprecatedNode()); |
+ RefPtrWillBeRawPtr<Element> block = enclosingBlock(paragraphStart.deepEquivalent().deprecatedNode()); |
const Position& paragraphStartToMove = paragraphStart.deepEquivalent(); |
if (!m_removeOnly && isEditablePosition(paragraphStartToMove)) { |
RefPtrWillBeRawPtr<Element> newBlock = moveParagraphContentsToNewBlockIfNecessary(paragraphStartToMove); |
if (newBlock) |
block = newBlock; |
} |
- ASSERT(!block || block->isElementNode()); |
if (block && block->isHTMLElement()) { |
removeCSSStyle(style, toHTMLElement(block)); |
if (!m_removeOnly) |
@@ -390,13 +391,13 @@ void ApplyStyleCommand::applyRelativeFontStyleChange(EditingStyle* style) |
RefPtrWillBeRawPtr<HTMLElement> element = nullptr; |
if (node->isHTMLElement()) { |
// Only work on fully selected nodes. |
- if (!nodeFullySelected(node, start, end)) |
+ if (!elementFullySelected(toHTMLElement(*node), start, end)) |
continue; |
element = toHTMLElement(node); |
} else if (node->isTextNode() && node->renderer() && node->parentNode() != lastStyledNode) { |
// Last styled node was not parent node of this text node, but we wish to style this |
// text node. To make this possible, add a style span to surround this text node. |
- RefPtrWillBeRawPtr<HTMLElement> span = createStyleSpanElement(document()); |
+ RefPtrWillBeRawPtr<HTMLSpanElement> span = createStyleSpanElement(document()); |
surroundNodeRangeWithElement(node, node, span.get()); |
element = span.release(); |
} else { |
@@ -458,14 +459,14 @@ HTMLElement* ApplyStyleCommand::splitAncestorsWithUnicodeBidi(Node* node, bool b |
{ |
// We are allowed to leave the highest ancestor with unicode-bidi unsplit if it is unicode-bidi: embed and direction: allowedDirection. |
// In that case, we return the unsplit ancestor. Otherwise, we return 0. |
- Node* block = enclosingBlock(node); |
+ Element* block = enclosingBlock(node); |
if (!block) |
return 0; |
- Node* highestAncestorWithUnicodeBidi = 0; |
- Node* nextHighestAncestorWithUnicodeBidi = 0; |
+ ContainerNode* highestAncestorWithUnicodeBidi = 0; |
+ ContainerNode* nextHighestAncestorWithUnicodeBidi = 0; |
int highestAncestorUnicodeBidi = 0; |
- for (Node* n = node->parentNode(); n != block; n = n->parentNode()) { |
+ for (ContainerNode* n = node->parentNode(); n != block; n = n->parentNode()) { |
int unicodeBidi = getIdentifierValue(CSSComputedStyleDeclaration::create(n).get(), CSSPropertyUnicodeBidi); |
if (unicodeBidi && unicodeBidi != CSSValueNormal) { |
highestAncestorUnicodeBidi = unicodeBidi; |
@@ -505,13 +506,13 @@ HTMLElement* ApplyStyleCommand::splitAncestorsWithUnicodeBidi(Node* node, bool b |
return unsplitAncestor; |
} |
-void ApplyStyleCommand::removeEmbeddingUpToEnclosingBlock(Node* node, Node* unsplitAncestor) |
+void ApplyStyleCommand::removeEmbeddingUpToEnclosingBlock(Node* node, HTMLElement* unsplitAncestor) |
{ |
- Node* block = enclosingBlock(node); |
+ Element* block = enclosingBlock(node); |
if (!block) |
return; |
- for (Node* n = node->parentNode(); n != block && n != unsplitAncestor; n = n->parentNode()) { |
+ for (ContainerNode* n = node->parentNode(); n != block && n != unsplitAncestor; n = n->parentNode()) { |
if (!n->isStyledElement()) |
continue; |
@@ -539,11 +540,11 @@ void ApplyStyleCommand::removeEmbeddingUpToEnclosingBlock(Node* node, Node* unsp |
} |
} |
-static Node* highestEmbeddingAncestor(Node* startNode, Node* enclosingNode) |
+static HTMLElement* highestEmbeddingAncestor(Node* startNode, Node* enclosingNode) |
{ |
for (Node* n = startNode; n && n != enclosingNode; n = n->parentNode()) { |
if (n->isHTMLElement() && getIdentifierValue(CSSComputedStyleDeclaration::create(n).get(), CSSPropertyUnicodeBidi) == CSSValueEmbed) |
- return n; |
+ return toHTMLElement(n); |
} |
return 0; |
@@ -615,11 +616,11 @@ void ApplyStyleCommand::applyInlineStyle(EditingStyle* style) |
// Avoid removing the dir attribute and the unicode-bidi and direction properties from the unsplit ancestors. |
Position embeddingRemoveStart = removeStart; |
- if (startUnsplitAncestor && nodeFullySelected(startUnsplitAncestor, removeStart, end)) |
+ if (startUnsplitAncestor && elementFullySelected(*startUnsplitAncestor, removeStart, end)) |
embeddingRemoveStart = positionInParentAfterNode(*startUnsplitAncestor); |
Position embeddingRemoveEnd = end; |
- if (endUnsplitAncestor && nodeFullySelected(endUnsplitAncestor, removeStart, end)) |
+ if (endUnsplitAncestor && elementFullySelected(*endUnsplitAncestor, removeStart, end)) |
embeddingRemoveEnd = positionInParentBeforeNode(*endUnsplitAncestor).downstream(); |
if (embeddingRemoveEnd != removeStart || embeddingRemoveEnd != end) { |
@@ -656,12 +657,12 @@ void ApplyStyleCommand::applyInlineStyle(EditingStyle* style) |
RefPtrWillBeRawPtr<EditingStyle> styleToApply = style; |
if (hasTextDirection) { |
// Avoid applying the unicode-bidi and direction properties beneath ancestors that already have them. |
- Node* embeddingStartNode = highestEmbeddingAncestor(start.deprecatedNode(), enclosingBlock(start.deprecatedNode())); |
- Node* embeddingEndNode = highestEmbeddingAncestor(end.deprecatedNode(), enclosingBlock(end.deprecatedNode())); |
+ HTMLElement* embeddingStartElement = highestEmbeddingAncestor(start.deprecatedNode(), enclosingBlock(start.deprecatedNode())); |
+ HTMLElement* embeddingEndElement = highestEmbeddingAncestor(end.deprecatedNode(), enclosingBlock(end.deprecatedNode())); |
- if (embeddingStartNode || embeddingEndNode) { |
- Position embeddingApplyStart = embeddingStartNode ? positionInParentAfterNode(*embeddingStartNode) : start; |
- Position embeddingApplyEnd = embeddingEndNode ? positionInParentBeforeNode(*embeddingEndNode) : end; |
+ if (embeddingStartElement || embeddingEndElement) { |
+ Position embeddingApplyStart = embeddingStartElement ? positionInParentAfterNode(*embeddingStartElement) : start; |
+ Position embeddingApplyEnd = embeddingEndElement ? positionInParentBeforeNode(*embeddingEndElement) : end; |
ASSERT(embeddingApplyStart.isNotNull() && embeddingApplyEnd.isNotNull()); |
if (!embeddingStyle) { |
@@ -758,7 +759,7 @@ public: |
RefPtrWillBeMember<Node> end; |
RefPtrWillBeMember<Node> pastEndNode; |
Position positionForStyleComputation; |
- RefPtrWillBeMember<Node> dummyElement; |
+ RefPtrWillBeMember<HTMLSpanElement> dummyElement; |
StyleChange change; |
}; |
@@ -784,13 +785,13 @@ void ApplyStyleCommand::applyInlineStyleToNodeRange(EditingStyle* style, PassRef |
continue; |
if (!node->rendererIsRichlyEditable() && node->isHTMLElement()) { |
+ HTMLElement* element = toHTMLElement(node); |
// This is a plaintext-only region. Only proceed if it's fully selected. |
// pastEndNode is the node after the last fully selected node, so if it's inside node then |
// node isn't fully selected. |
- if (pastEndNode && pastEndNode->isDescendantOf(node.get())) |
+ if (pastEndNode && pastEndNode->isDescendantOf(element)) |
break; |
// Add to this element's inline style and skip over its contents. |
- HTMLElement* element = toHTMLElement(node); |
next = NodeTraversal::nextSkippingChildren(*node); |
if (!style->style()) |
continue; |
@@ -889,15 +890,16 @@ void ApplyStyleCommand::removeConflictingInlineStyleFromRun(EditingStyle* style, |
if (!node->isHTMLElement()) |
continue; |
- RefPtrWillBeRawPtr<Node> previousSibling = node->previousSibling(); |
- RefPtrWillBeRawPtr<Node> nextSibling = node->nextSibling(); |
- RefPtrWillBeRawPtr<ContainerNode> parent = node->parentNode(); |
- removeInlineStyleFromElement(style, toHTMLElement(node), RemoveAlways); |
- if (!node->inDocument()) { |
+ HTMLElement& element = toHTMLElement(*node); |
+ RefPtrWillBeRawPtr<Node> previousSibling = element.previousSibling(); |
+ RefPtrWillBeRawPtr<Node> nextSibling = element.nextSibling(); |
+ RefPtrWillBeRawPtr<ContainerNode> parent = element.parentNode(); |
+ removeInlineStyleFromElement(style, &element, RemoveAlways); |
+ if (!element.inDocument()) { |
// FIXME: We might need to update the start and the end of current selection here but need a test. |
- if (runStart == node) |
+ if (runStart == element) |
runStart = previousSibling ? previousSibling->nextSibling() : parent->firstChild(); |
- if (runEnd == node) |
+ if (runEnd == element) |
runEnd = nextSibling ? nextSibling->previousSibling() : parent->lastChild(); |
} |
} |
@@ -1139,7 +1141,7 @@ void ApplyStyleCommand::removeInlineStyle(EditingStyle* style, const Position &s |
} else { |
next = NodeTraversal::next(*node); |
} |
- if (node->isHTMLElement() && nodeFullySelected(node.get(), start, end)) { |
+ if (node->isHTMLElement() && elementFullySelected(toHTMLElement(*node), start, end)) { |
RefPtrWillBeRawPtr<HTMLElement> elem = toHTMLElement(node); |
RefPtrWillBeRawPtr<Node> prev = NodeTraversal::previousPostOrder(*elem); |
RefPtrWillBeRawPtr<Node> next = NodeTraversal::next(*elem); |
@@ -1180,16 +1182,13 @@ void ApplyStyleCommand::removeInlineStyle(EditingStyle* style, const Position &s |
updateStartEnd(s, e); |
} |
-bool ApplyStyleCommand::nodeFullySelected(Node *node, const Position &start, const Position &end) const |
+bool ApplyStyleCommand::elementFullySelected(HTMLElement& element, const Position& start, const Position& end) const |
{ |
- ASSERT(node); |
- ASSERT(node->isElementNode()); |
- |
// The tree may have changed and Position::upstream() relies on an up-to-date layout. |
- node->document().updateLayoutIgnorePendingStylesheets(); |
+ element.document().updateLayoutIgnorePendingStylesheets(); |
- return comparePositions(firstPositionInOrBeforeNode(node), start) >= 0 |
- && comparePositions(lastPositionInOrAfterNode(node).upstream(), end) <= 0; |
+ return comparePositions(firstPositionInOrBeforeNode(&element), start) >= 0 |
+ && comparePositions(lastPositionInOrAfterNode(&element).upstream(), end) <= 0; |
} |
void ApplyStyleCommand::splitTextAtStart(const Position& start, const Position& end) |
@@ -1409,7 +1408,7 @@ void ApplyStyleCommand::addInlineStyleIfNeeded(EditingStyle* style, PassRefPtrWi |
return; |
RefPtrWillBeRawPtr<Node> start = passedStart; |
- RefPtrWillBeMember<Node> dummyElement = nullptr; |
+ RefPtrWillBeMember<HTMLSpanElement> dummyElement = nullptr; |
StyleChange styleChange(style, positionToComputeInlineStyleChange(start, dummyElement)); |
if (dummyElement) |
@@ -1418,7 +1417,7 @@ void ApplyStyleCommand::addInlineStyleIfNeeded(EditingStyle* style, PassRefPtrWi |
applyInlineStyleChange(start, passedEnd, styleChange, addStyledElement); |
} |
-Position ApplyStyleCommand::positionToComputeInlineStyleChange(PassRefPtrWillBeRawPtr<Node> startNode, RefPtrWillBeMember<Node>& dummyElement) |
+Position ApplyStyleCommand::positionToComputeInlineStyleChange(PassRefPtrWillBeRawPtr<Node> startNode, RefPtrWillBeMember<HTMLSpanElement>& dummyElement) |
{ |
// It's okay to obtain the style at the startNode because we've removed all relevant styles from the current run. |
if (!startNode->isElementNode()) { |
@@ -1438,11 +1437,11 @@ void ApplyStyleCommand::applyInlineStyleChange(PassRefPtrWillBeRawPtr<Node> pass |
ASSERT(endNode->inDocument()); |
// Find appropriate font and span elements top-down. |
- HTMLElement* fontContainer = 0; |
+ HTMLFontElement* fontContainer = 0; |
HTMLElement* styleContainer = 0; |
for (Node* container = startNode.get(); container && startNode == endNode; container = container->firstChild()) { |
if (isHTMLFontElement(*container)) |
- fontContainer = toHTMLElement(container); |
+ fontContainer = toHTMLFontElement(container); |
bool styleContainerIsNotSpan = !isHTMLSpanElement(styleContainer); |
if (container->isHTMLElement()) { |
HTMLElement* containerElement = toHTMLElement(container); |
@@ -1465,7 +1464,7 @@ void ApplyStyleCommand::applyInlineStyleChange(PassRefPtrWillBeRawPtr<Node> pass |
if (styleChange.applyFontSize()) |
setNodeAttribute(fontContainer, sizeAttr, AtomicString(styleChange.fontSize())); |
} else { |
- RefPtrWillBeRawPtr<Element> fontElement = createFontElement(document()); |
+ RefPtrWillBeRawPtr<HTMLFontElement> fontElement = createFontElement(document()); |
if (styleChange.applyFontColor()) |
fontElement->setAttribute(colorAttr, AtomicString(styleChange.fontColor())); |
if (styleChange.applyFontFace()) |
@@ -1490,7 +1489,7 @@ void ApplyStyleCommand::applyInlineStyleChange(PassRefPtrWillBeRawPtr<Node> pass |
setNodeAttribute(styleContainer, styleAttr, AtomicString(styleChange.cssStyle())); |
} |
} else { |
- RefPtrWillBeRawPtr<Element> styleElement = createStyleSpanElement(document()); |
+ RefPtrWillBeRawPtr<HTMLSpanElement> styleElement = createStyleSpanElement(document()); |
styleElement->setAttribute(styleAttr, AtomicString(styleChange.cssStyle())); |
surroundNodeRangeWithElement(startNode, endNode, styleElement.release()); |
} |