Index: Source/core/editing/htmlediting.cpp |
diff --git a/Source/core/editing/htmlediting.cpp b/Source/core/editing/htmlediting.cpp |
index 4a0fce96c2b78d37bcf1166ef55ef1adfd391f11..d8341a3f6fd2aa74970860a3b02003720dd3a323 100644 |
--- a/Source/core/editing/htmlediting.cpp |
+++ b/Source/core/editing/htmlediting.cpp |
@@ -50,6 +50,7 @@ |
#include "core/html/HTMLLIElement.h" |
#include "core/html/HTMLOListElement.h" |
#include "core/html/HTMLParagraphElement.h" |
+#include "core/html/HTMLSpanElement.h" |
#include "core/html/HTMLTableCellElement.h" |
#include "core/html/HTMLUListElement.h" |
#include "core/rendering/RenderObject.h" |
@@ -113,20 +114,19 @@ int comparePositions(const VisiblePosition& a, const VisiblePosition& b) |
return comparePositions(a.deepEquivalent(), b.deepEquivalent()); |
} |
-Node* highestEditableRoot(const Position& position, EditableType editableType) |
+ContainerNode* highestEditableRoot(const Position& position, EditableType editableType) |
{ |
- Node* node = position.deprecatedNode(); |
- if (!node) |
+ if (position.isNull()) |
return 0; |
- Node* highestRoot = editableRootForPosition(position, editableType); |
+ ContainerNode* highestRoot = editableRootForPosition(position, editableType); |
if (!highestRoot) |
return 0; |
if (isHTMLBodyElement(*highestRoot)) |
return highestRoot; |
- node = highestRoot->parentNode(); |
+ ContainerNode* node = highestRoot->parentNode(); |
while (node) { |
if (node->hasEditableStyle(editableType)) |
highestRoot = node; |
@@ -138,7 +138,7 @@ Node* highestEditableRoot(const Position& position, EditableType editableType) |
return highestRoot; |
} |
-Node* lowestEditableAncestor(Node* node) |
+Element* lowestEditableAncestor(Node* node) |
{ |
while (node) { |
if (node->hasEditableStyle()) |
@@ -258,7 +258,7 @@ Position previousVisuallyDistinctCandidate(const Position& position) |
return Position(); |
} |
-VisiblePosition firstEditableVisiblePositionAfterPositionInRoot(const Position& position, Node* highestRoot) |
+VisiblePosition firstEditableVisiblePositionAfterPositionInRoot(const Position& position, ContainerNode* highestRoot) |
{ |
// position falls before highestRoot. |
if (comparePositions(position, firstPositionInNode(highestRoot)) == -1 && highestRoot->hasEditableStyle()) |
@@ -283,7 +283,7 @@ VisiblePosition firstEditableVisiblePositionAfterPositionInRoot(const Position& |
return VisiblePosition(editablePosition); |
} |
-VisiblePosition lastEditableVisiblePositionBeforePositionInRoot(const Position& position, Node* highestRoot) |
+VisiblePosition lastEditableVisiblePositionBeforePositionInRoot(const Position& position, ContainerNode* highestRoot) |
{ |
return VisiblePosition(lastEditablePositionBeforePositionInRoot(position, highestRoot)); |
} |
@@ -336,10 +336,10 @@ Element* enclosingBlock(Node* node, EditingBoundaryCrossingRule rule) |
TextDirection directionOfEnclosingBlock(const Position& position) |
{ |
- Node* enclosingBlockNode = enclosingBlock(position.containerNode()); |
- if (!enclosingBlockNode) |
+ Element* enclosingBlockElement = enclosingBlock(position.containerNode()); |
+ if (!enclosingBlockElement) |
return LTR; |
- RenderObject* renderer = enclosingBlockNode->renderer(); |
+ RenderObject* renderer = enclosingBlockElement->renderer(); |
return renderer ? renderer->style()->direction() : LTR; |
} |
@@ -408,7 +408,7 @@ const String& nonBreakingSpaceString() |
} |
// FIXME: need to dump this |
-bool isSpecialElement(const Node *n) |
+bool isSpecialHTMLElement(const Node* n) |
{ |
if (!n) |
return false; |
@@ -432,39 +432,43 @@ bool isSpecialElement(const Node *n) |
return false; |
} |
-static Node* firstInSpecialElement(const Position& pos) |
+static HTMLElement* firstInSpecialElement(const Position& pos) |
{ |
- Node* rootEditableElement = pos.containerNode()->rootEditableElement(); |
- for (Node* n = pos.deprecatedNode(); n && n->rootEditableElement() == rootEditableElement; n = n->parentNode()) |
- if (isSpecialElement(n)) { |
+ Element* rootEditableElement = pos.containerNode()->rootEditableElement(); |
+ for (Node* n = pos.deprecatedNode(); n && n->rootEditableElement() == rootEditableElement; n = n->parentNode()) { |
+ if (isSpecialHTMLElement(n)) { |
+ HTMLElement* specialElement = toHTMLElement(n); |
VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM); |
- VisiblePosition firstInElement = VisiblePosition(firstPositionInOrBeforeNode(n), DOWNSTREAM); |
- if (isRenderedTable(n) && vPos == firstInElement.next()) |
- return n; |
+ VisiblePosition firstInElement = VisiblePosition(firstPositionInOrBeforeNode(specialElement), DOWNSTREAM); |
+ if (isRenderedTable(specialElement) && vPos == firstInElement.next()) |
+ return specialElement; |
if (vPos == firstInElement) |
- return n; |
+ return specialElement; |
} |
+ } |
return 0; |
} |
-static Node* lastInSpecialElement(const Position& pos) |
+static HTMLElement* lastInSpecialElement(const Position& pos) |
{ |
- Node* rootEditableElement = pos.containerNode()->rootEditableElement(); |
- for (Node* n = pos.deprecatedNode(); n && n->rootEditableElement() == rootEditableElement; n = n->parentNode()) |
- if (isSpecialElement(n)) { |
+ Element* rootEditableElement = pos.containerNode()->rootEditableElement(); |
+ for (Node* n = pos.deprecatedNode(); n && n->rootEditableElement() == rootEditableElement; n = n->parentNode()) { |
+ if (isSpecialHTMLElement(n)) { |
+ HTMLElement* specialElement = toHTMLElement(n); |
VisiblePosition vPos = VisiblePosition(pos, DOWNSTREAM); |
- VisiblePosition lastInElement = VisiblePosition(lastPositionInOrAfterNode(n), DOWNSTREAM); |
- if (isRenderedTable(n) && vPos == lastInElement.previous()) |
- return n; |
+ VisiblePosition lastInElement = VisiblePosition(lastPositionInOrAfterNode(specialElement), DOWNSTREAM); |
+ if (isRenderedTable(specialElement) && vPos == lastInElement.previous()) |
+ return specialElement; |
if (vPos == lastInElement) |
- return n; |
+ return specialElement; |
} |
+ } |
return 0; |
} |
-Position positionBeforeContainingSpecialElement(const Position& pos, Node** containingSpecialElement) |
+Position positionBeforeContainingSpecialElement(const Position& pos, HTMLElement** containingSpecialElement) |
{ |
- Node* n = firstInSpecialElement(pos); |
+ HTMLElement* n = firstInSpecialElement(pos); |
if (!n) |
return pos; |
Position result = positionInParentBeforeNode(*n); |
@@ -475,9 +479,9 @@ Position positionBeforeContainingSpecialElement(const Position& pos, Node** cont |
return result; |
} |
-Position positionAfterContainingSpecialElement(const Position& pos, Node **containingSpecialElement) |
+Position positionAfterContainingSpecialElement(const Position& pos, HTMLElement** containingSpecialElement) |
{ |
- Node* n = lastInSpecialElement(pos); |
+ HTMLElement* n = lastInSpecialElement(pos); |
if (!n) |
return pos; |
Position result = positionInParentAfterNode(*n); |
@@ -548,18 +552,18 @@ bool isListItem(const Node* n) |
return n && n->renderer() && n->renderer()->isListItem(); |
} |
-Node* enclosingNodeWithTag(const Position& p, const QualifiedName& tagName) |
+Element* enclosingElementWithTag(const Position& p, const QualifiedName& tagName) |
{ |
if (p.isNull()) |
return 0; |
- Node* root = highestEditableRoot(p); |
- for (Node* n = p.deprecatedNode(); n; n = n->parentNode()) { |
- if (root && !n->hasEditableStyle()) |
+ ContainerNode* root = highestEditableRoot(p); |
+ for (Element* ancestor = ElementTraversal::firstAncestorOrSelf(*p.deprecatedNode()); ancestor; ancestor = ElementTraversal::firstAncestor(*ancestor)) { |
+ if (root && !ancestor->hasEditableStyle()) |
continue; |
- if (n->hasTagName(tagName)) |
- return n; |
- if (n == root) |
+ if (ancestor->hasTagName(tagName)) |
+ return ancestor; |
+ if (ancestor == root) |
return 0; |
} |
@@ -573,7 +577,7 @@ Node* enclosingNodeOfType(const Position& p, bool (*nodeIsOfType)(const Node*), |
if (p.isNull()) |
return 0; |
- Node* root = rule == CannotCrossEditingBoundary ? highestEditableRoot(p) : 0; |
+ ContainerNode* root = rule == CannotCrossEditingBoundary ? highestEditableRoot(p) : 0; |
for (Node* n = p.deprecatedNode(); n; n = n->parentNode()) { |
// Don't return a non-editable node if the input position was editable, since |
// the callers from editing will no doubt want to perform editing inside the returned node. |
@@ -591,7 +595,7 @@ Node* enclosingNodeOfType(const Position& p, bool (*nodeIsOfType)(const Node*), |
Node* highestEnclosingNodeOfType(const Position& p, bool (*nodeIsOfType)(const Node*), EditingBoundaryCrossingRule rule, Node* stayWithin) |
{ |
Node* highest = 0; |
- Node* root = rule == CannotCrossEditingBoundary ? highestEditableRoot(p) : 0; |
+ ContainerNode* root = rule == CannotCrossEditingBoundary ? highestEditableRoot(p) : 0; |
for (Node* n = p.containerNode(); n && n != stayWithin; n = n->parentNode()) { |
if (root && !n->hasEditableStyle()) |
continue; |
@@ -621,7 +625,7 @@ static bool hasARenderedDescendant(Node* node, Node* excludedNode) |
Node* highestNodeToRemoveInPruning(Node* node, Node* excludeNode) |
{ |
Node* previousNode = 0; |
- Node* rootEditableElement = node ? node->rootEditableElement() : 0; |
+ Element* rootEditableElement = node ? node->rootEditableElement() : 0; |
for (; node; node = node->parentNode()) { |
if (RenderObject* renderer = node->renderer()) { |
if (!renderer->canHaveChildren() || hasARenderedDescendant(node, previousNode) || rootEditableElement == node || excludeNode == node) |
@@ -632,7 +636,7 @@ Node* highestNodeToRemoveInPruning(Node* node, Node* excludeNode) |
return 0; |
} |
-Node* enclosingTableCell(const Position& p) |
+Element* enclosingTableCell(const Position& p) |
{ |
return toElement(enclosingNodeOfType(p, isTableCell)); |
} |
@@ -642,10 +646,11 @@ Element* enclosingAnchorElement(const Position& p) |
if (p.isNull()) |
return 0; |
- Node* node = p.deprecatedNode(); |
- while (node && !(node->isElementNode() && node->isLink())) |
- node = node->parentNode(); |
- return toElement(node); |
+ for (Element* ancestor = ElementTraversal::firstAncestorOrSelf(*p.deprecatedNode()); ancestor; ancestor = ElementTraversal::firstAncestor(*ancestor)) { |
+ if (ancestor->isLink()) |
+ return ancestor; |
+ } |
+ return 0; |
} |
HTMLElement* enclosingList(Node* node) |
@@ -653,7 +658,7 @@ HTMLElement* enclosingList(Node* node) |
if (!node) |
return 0; |
- Node* root = highestEditableRoot(firstPositionInOrBeforeNode(node)); |
+ ContainerNode* root = highestEditableRoot(firstPositionInOrBeforeNode(node)); |
for (ContainerNode* n = node->parentNode(); n; n = n->parentNode()) { |
if (isHTMLUListElement(*n) || isHTMLOListElement(*n)) |
@@ -671,7 +676,7 @@ Node* enclosingListChild(Node *node) |
return 0; |
// Check for a list item element, or for a node whose parent is a list element. Such a node |
// will appear visually as a list item (but without a list marker) |
- Node* root = highestEditableRoot(firstPositionInOrBeforeNode(node)); |
+ ContainerNode* root = highestEditableRoot(firstPositionInOrBeforeNode(node)); |
// FIXME: This function is inappropriately named if it starts with node instead of node->parentNode() |
for (Node* n = node; n && n->parentNode(); n = n->parentNode()) { |
@@ -701,7 +706,7 @@ Node* enclosingEmptyListItem(const VisiblePosition& visiblePos) |
return listChildNode; |
} |
-HTMLElement* outermostEnclosingList(Node* node, Node* rootList) |
+HTMLElement* outermostEnclosingList(Node* node, HTMLElement* rootList) |
{ |
HTMLElement* list = enclosingList(node); |
if (!list) |
@@ -825,9 +830,9 @@ PassRefPtrWillBeRawPtr<HTMLElement> createHTMLElement(Document& document, const |
return HTMLElementFactory::createHTMLElement(tagName, document, 0, false); |
} |
-bool isTabSpanNode(const Node* node) |
+bool isTabSpanElement(const Node* node) |
{ |
- if (!isHTMLSpanElement(node) || toElement(node)->getAttribute(classAttr) != AppleTabSpanClass) |
+ if (!isHTMLSpanElement(node) || toHTMLSpanElement(node)->getAttribute(classAttr) != AppleTabSpanClass) |
return false; |
UseCounter::count(node->document(), UseCounter::EditingAppleTabSpanClass); |
return true; |
@@ -835,20 +840,20 @@ bool isTabSpanNode(const Node* node) |
bool isTabSpanTextNode(const Node* node) |
{ |
- return node && node->isTextNode() && node->parentNode() && isTabSpanNode(node->parentNode()); |
+ return node && node->isTextNode() && node->parentNode() && isTabSpanElement(node->parentNode()); |
} |
-Node* tabSpanNode(const Node* node) |
+HTMLSpanElement* tabSpanElement(const Node* node) |
{ |
- return isTabSpanTextNode(node) ? node->parentNode() : 0; |
+ return isTabSpanTextNode(node) ? toHTMLSpanElement(node->parentNode()) : 0; |
} |
-PassRefPtrWillBeRawPtr<Element> createTabSpanElement(Document& document, PassRefPtrWillBeRawPtr<Node> prpTabTextNode) |
+PassRefPtrWillBeRawPtr<HTMLSpanElement> createTabSpanElement(Document& document, PassRefPtrWillBeRawPtr<Text> prpTabTextNode) |
{ |
- RefPtrWillBeRawPtr<Node> tabTextNode = prpTabTextNode; |
+ RefPtrWillBeRawPtr<Text> tabTextNode = prpTabTextNode; |
// Make the span to hold the tab. |
- RefPtrWillBeRawPtr<Element> spanElement = document.createElement(spanTag, false); |
+ RefPtrWillBeRawPtr<HTMLSpanElement> spanElement = toHTMLSpanElement(document.createElement(spanTag, false).get()); |
spanElement->setAttribute(classAttr, AppleTabSpanClass); |
spanElement->setAttribute(styleAttr, "white-space:pre"); |
@@ -861,14 +866,14 @@ PassRefPtrWillBeRawPtr<Element> createTabSpanElement(Document& document, PassRef |
return spanElement.release(); |
} |
-PassRefPtrWillBeRawPtr<Element> createTabSpanElement(Document& document, const String& tabText) |
+PassRefPtrWillBeRawPtr<HTMLSpanElement> createTabSpanElement(Document& document, const String& tabText) |
{ |
return createTabSpanElement(document, document.createTextNode(tabText)); |
} |
-PassRefPtrWillBeRawPtr<Element> createTabSpanElement(Document& document) |
+PassRefPtrWillBeRawPtr<HTMLSpanElement> createTabSpanElement(Document& document) |
{ |
- return createTabSpanElement(document, PassRefPtrWillBeRawPtr<Node>(nullptr)); |
+ return createTabSpanElement(document, PassRefPtrWillBeRawPtr<Text>(nullptr)); |
} |
bool isNodeRendered(const Node *node) |
@@ -889,7 +894,7 @@ static Position previousCharacterPosition(const Position& position, EAffinity af |
if (position.isNull()) |
return Position(); |
- Node* fromRootEditableElement = position.anchorNode()->rootEditableElement(); |
+ Element* fromRootEditableElement = position.anchorNode()->rootEditableElement(); |
bool atStartOfLine = isStartOfLine(VisiblePosition(position, affinity)); |
bool rendered = position.isCandidate(); |