summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/dom/Position.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/dom/Position.cpp')
-rw-r--r--Source/WebCore/dom/Position.cpp63
1 files changed, 33 insertions, 30 deletions
diff --git a/Source/WebCore/dom/Position.cpp b/Source/WebCore/dom/Position.cpp
index 473610a..1b58a42 100644
--- a/Source/WebCore/dom/Position.cpp
+++ b/Source/WebCore/dom/Position.cpp
@@ -46,7 +46,7 @@ using namespace HTMLNames;
static Node* nextRenderedEditable(Node* node)
{
while ((node = node->nextLeafNode())) {
- if (!node->isContentEditable())
+ if (!node->rendererIsEditable())
continue;
RenderObject* renderer = node->renderer();
if (!renderer)
@@ -60,7 +60,7 @@ static Node* nextRenderedEditable(Node* node)
static Node* previousRenderedEditable(Node* node)
{
while ((node = node->previousLeafNode())) {
- if (!node->isContentEditable())
+ if (!node->rendererIsEditable())
continue;
RenderObject* renderer = node->renderer();
if (!renderer)
@@ -94,11 +94,13 @@ Position::Position(PassRefPtr<Node> anchorNode, int offset, AnchorType anchorTyp
, m_anchorType(anchorType)
, m_isLegacyEditingPosition(false)
{
+ ASSERT(!m_anchorNode || !editingIgnoresContent(m_anchorNode.get()));
ASSERT(anchorType == PositionIsOffsetInAnchor);
}
void Position::moveToPosition(PassRefPtr<Node> node, int offset)
{
+ ASSERT(!editingIgnoresContent(node.get()));
ASSERT(anchorType() == PositionIsOffsetInAnchor || m_isLegacyEditingPosition);
m_anchorNode = node;
m_offset = offset;
@@ -161,12 +163,12 @@ Position Position::parentAnchoredEquivalent() const
return Position();
// FIXME: This should only be necessary for legacy positions, but is also needed for positions before and after Tables
- if (m_offset <= 0) {
+ if (m_offset <= 0 && m_anchorType != PositionIsAfterAnchor) {
if (m_anchorNode->parentNode() && (editingIgnoresContent(m_anchorNode.get()) || isTableElement(m_anchorNode.get())))
return positionInParentBeforeNode(m_anchorNode.get());
- return Position(m_anchorNode, 0, PositionIsOffsetInAnchor);
+ return firstPositionInOrBeforeNode(m_anchorNode.get());
}
- if (!m_anchorNode->offsetInCharacters() && static_cast<unsigned>(m_offset) == m_anchorNode->childNodeCount()
+ if (!m_anchorNode->offsetInCharacters() && (m_anchorType == PositionIsAfterAnchor || static_cast<unsigned>(m_offset) == m_anchorNode->childNodeCount())
&& (editingIgnoresContent(m_anchorNode.get()) || isTableElement(m_anchorNode.get()))) {
return positionInParentAfterNode(m_anchorNode.get());
}
@@ -240,15 +242,15 @@ Position Position::previous(PositionMoveType moveType) const
Node* n = deprecatedNode();
if (!n)
return *this;
-
- int o = m_offset;
+
+ int o = deprecatedEditingOffset();
// FIXME: Negative offsets shouldn't be allowed. We should catch this earlier.
ASSERT(o >= 0);
if (o > 0) {
Node* child = n->childNode(o - 1);
if (child)
- return lastDeepEditingPositionForNode(child);
+ return lastPositionInOrAfterNode(child);
// There are two reasons child might be 0:
// 1) The node is node like a text node that is not an element, and therefore has no children.
@@ -279,15 +281,15 @@ Position Position::next(PositionMoveType moveType) const
Node* n = deprecatedNode();
if (!n)
return *this;
-
- int o = m_offset;
+
+ int o = deprecatedEditingOffset();
// FIXME: Negative offsets shouldn't be allowed. We should catch this earlier.
ASSERT(o >= 0);
Node* child = n->childNode(o);
if (child || (!n->hasChildNodes() && o < lastOffsetForEditing(n))) {
if (child)
- return firstDeepEditingPositionForNode(child);
+ return firstPositionInOrBeforeNode(child);
// There are two reasons child might be 0:
// 1) The node is node like a text node that is not an element, and therefore has no children.
@@ -323,14 +325,14 @@ bool Position::atFirstEditingPositionForNode() const
{
if (isNull())
return true;
- return m_offset <= 0;
+ return m_anchorType == PositionIsBeforeAnchor || m_offset <= 0;
}
bool Position::atLastEditingPositionForNode() const
{
if (isNull())
return true;
- return m_offset >= lastOffsetForEditing(deprecatedNode());
+ return m_anchorType == PositionIsAfterAnchor || m_offset >= lastOffsetForEditing(deprecatedNode());
}
// A position is considered at editing boundary if one of the following is true:
@@ -343,15 +345,15 @@ bool Position::atLastEditingPositionForNode() const
bool Position::atEditingBoundary() const
{
Position nextPosition = downstream(CanCrossEditingBoundary);
- if (atFirstEditingPositionForNode() && nextPosition.isNotNull() && !nextPosition.deprecatedNode()->isContentEditable())
+ if (atFirstEditingPositionForNode() && nextPosition.isNotNull() && !nextPosition.deprecatedNode()->rendererIsEditable())
return true;
Position prevPosition = upstream(CanCrossEditingBoundary);
- if (atLastEditingPositionForNode() && prevPosition.isNotNull() && !prevPosition.deprecatedNode()->isContentEditable())
+ if (atLastEditingPositionForNode() && prevPosition.isNotNull() && !prevPosition.deprecatedNode()->rendererIsEditable())
return true;
- return nextPosition.isNotNull() && !nextPosition.deprecatedNode()->isContentEditable()
- && prevPosition.isNotNull() && !prevPosition.deprecatedNode()->isContentEditable();
+ return nextPosition.isNotNull() && !nextPosition.deprecatedNode()->rendererIsEditable()
+ && prevPosition.isNotNull() && !prevPosition.deprecatedNode()->rendererIsEditable();
}
Node* Position::parentEditingBoundary() const
@@ -364,7 +366,7 @@ Node* Position::parentEditingBoundary() const
return 0;
Node* boundary = m_anchorNode.get();
- while (boundary != documentElement && boundary->parentNode() && m_anchorNode->isContentEditable() == boundary->parentNode()->isContentEditable())
+ while (boundary != documentElement && boundary->parentNode() && m_anchorNode->rendererIsEditable() == boundary->parentNode()->rendererIsEditable())
boundary = boundary->parentNode();
return boundary;
@@ -523,17 +525,17 @@ Position Position::upstream(EditingBoundaryCrossingRule rule) const
// FIXME: PositionIterator should respect Before and After positions.
PositionIterator lastVisible = m_anchorType == PositionIsAfterAnchor ? Position(m_anchorNode, caretMaxOffset(m_anchorNode.get())) : *this;
PositionIterator currentPos = lastVisible;
- bool startEditable = startNode->isContentEditable();
+ bool startEditable = startNode->rendererIsEditable();
Node* lastNode = startNode;
bool boundaryCrossed = false;
for (; !currentPos.atStart(); currentPos.decrement()) {
Node* currentNode = currentPos.node();
// Don't check for an editability change if we haven't moved to a different node,
- // to avoid the expense of computing isContentEditable().
+ // to avoid the expense of computing rendererIsEditable().
if (currentNode != lastNode) {
// Don't change editability.
- bool currentEditable = currentNode->isContentEditable();
+ bool currentEditable = currentNode->rendererIsEditable();
if (startEditable != currentEditable) {
if (rule == CannotCrossEditingBoundary)
break;
@@ -569,7 +571,7 @@ Position Position::upstream(EditingBoundaryCrossingRule rule) const
// Return position after tables and nodes which have content that can be ignored.
if (editingIgnoresContent(currentNode) || isTableElement(currentNode)) {
if (currentPos.atEndOfNode())
- return lastDeepEditingPositionForNode(currentNode);
+ return positionAfterNode(currentNode);
continue;
}
@@ -645,17 +647,17 @@ Position Position::downstream(EditingBoundaryCrossingRule rule) const
// FIXME: PositionIterator should respect Before and After positions.
PositionIterator lastVisible = m_anchorType == PositionIsAfterAnchor ? Position(m_anchorNode, caretMaxOffset(m_anchorNode.get())) : *this;
PositionIterator currentPos = lastVisible;
- bool startEditable = startNode->isContentEditable();
+ bool startEditable = startNode->rendererIsEditable();
Node* lastNode = startNode;
bool boundaryCrossed = false;
for (; !currentPos.atEnd(); currentPos.increment()) {
Node* currentNode = currentPos.node();
// Don't check for an editability change if we haven't moved to a different node,
- // to avoid the expense of computing isContentEditable().
+ // to avoid the expense of computing rendererIsEditable().
if (currentNode != lastNode) {
// Don't change editability.
- bool currentEditable = currentNode->isContentEditable();
+ bool currentEditable = currentNode->rendererIsEditable();
if (startEditable != currentEditable) {
if (rule == CannotCrossEditingBoundary)
break;
@@ -781,7 +783,8 @@ bool Position::isCandidate() const
return false;
if (renderer->isBR())
- return !m_offset && !nodeIsUserSelectNone(deprecatedNode()->parentNode());
+ // FIXME: The condition should be m_anchorType == PositionIsBeforeAnchor, but for now we still need to support legacy positions.
+ return !m_offset && m_anchorType != PositionIsAfterAnchor && !nodeIsUserSelectNone(deprecatedNode()->parentNode());
if (renderer->isText())
return !nodeIsUserSelectNone(deprecatedNode()) && inRenderedText();
@@ -796,10 +799,10 @@ bool Position::isCandidate() const
if (toRenderBlock(renderer)->height() || m_anchorNode->hasTagName(bodyTag)) {
if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer))
return atFirstEditingPositionForNode() && !Position::nodeIsUserSelectNone(deprecatedNode());
- return m_anchorNode->isContentEditable() && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();
+ return m_anchorNode->rendererIsEditable() && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();
}
} else
- return m_anchorNode->isContentEditable() && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();
+ return m_anchorNode->rendererIsEditable() && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();
return false;
}
@@ -982,7 +985,7 @@ Position Position::trailingWhitespacePosition(EAffinity, bool considerNonCollaps
VisiblePosition v(*this);
UChar c = v.characterAfter();
// The space must not be in another paragraph and it must be editable.
- if (!isEndOfParagraph(v) && v.next(true).isNotNull())
+ if (!isEndOfParagraph(v) && v.next(CannotCrossEditingBoundary).isNotNull())
if (considerNonCollapsibleWhitespace ? (isSpaceOrNewline(c) || c == noBreakSpace) : isCollapsibleWhitespace(c))
return *this;
@@ -1053,7 +1056,7 @@ static Position upstreamIgnoringEditingBoundaries(Position position)
void Position::getInlineBoxAndOffset(EAffinity affinity, TextDirection primaryDirection, InlineBox*& inlineBox, int& caretOffset) const
{
- caretOffset = m_offset;
+ caretOffset = deprecatedEditingOffset();
RenderObject* renderer = deprecatedNode()->renderer();
if (!renderer->isText()) {