Index: Source/core/editing/VisiblePosition.cpp |
diff --git a/Source/core/editing/VisiblePosition.cpp b/Source/core/editing/VisiblePosition.cpp |
index 0aafd6c0831558336d3c969d60d830da2db2c439..0ecd02cccb40f79e6a65e2005504a5671a295b79 100644 |
--- a/Source/core/editing/VisiblePosition.cpp |
+++ b/Source/core/editing/VisiblePosition.cpp |
@@ -63,21 +63,20 @@ void VisiblePosition::init(const Position& position, EAffinity affinity) |
VisiblePosition VisiblePosition::next(EditingBoundaryCrossingRule rule) const |
{ |
- // FIXME: Support CanSkipEditingBoundary |
- ASSERT(rule == CanCrossEditingBoundary || rule == CannotCrossEditingBoundary); |
VisiblePosition next(nextVisuallyDistinctCandidate(m_deepPosition), m_affinity); |
- if (rule == CanCrossEditingBoundary) |
+ switch (rule) { |
+ case CanCrossEditingBoundary: |
return next; |
- |
- return honorEditingBoundaryAtOrAfter(next); |
+ case CannotCrossEditingBoundary: |
+ return honorEditingBoundaryAtOrAfter(next); |
+ case CanSkipOverEditingBoundary: |
+ return skipToEndOfEditingBoundary(next); |
+ } |
} |
VisiblePosition VisiblePosition::previous(EditingBoundaryCrossingRule rule) const |
{ |
- // FIXME: Support CanSkipEditingBoundary |
- ASSERT(rule == CanCrossEditingBoundary || rule == CannotCrossEditingBoundary); |
- // find first previous DOM position that is visible |
Position pos = previousVisuallyDistinctCandidate(m_deepPosition); |
// return null visible position if there is no previous visible position |
@@ -97,10 +96,14 @@ VisiblePosition VisiblePosition::previous(EditingBoundaryCrossingRule rule) cons |
} |
#endif |
- if (rule == CanCrossEditingBoundary) |
+ switch (rule) { |
+ case CanCrossEditingBoundary: |
return prev; |
- |
- return honorEditingBoundaryAtOrBefore(prev); |
+ case CannotCrossEditingBoundary: |
+ return honorEditingBoundaryAtOrBefore(prev); |
+ case CanSkipOverEditingBoundary: |
+ return skipToStartOfEditingBoundary(prev); |
+ } |
} |
Position VisiblePosition::leftVisuallyDistinctCandidate() const |
@@ -488,6 +491,46 @@ VisiblePosition VisiblePosition::honorEditingBoundaryAtOrAfter(const VisiblePosi |
return firstEditablePositionAfterPositionInRoot(pos.deepEquivalent(), highestRoot); |
} |
+VisiblePosition VisiblePosition::skipToStartOfEditingBoundary(const VisiblePosition &pos) const |
+{ |
+ if (pos.isNull()) |
+ return pos; |
+ |
+ Node* highestRoot = highestEditableRoot(deepEquivalent()); |
+ Node* highestRootOfPos = highestEditableRoot(pos.deepEquivalent()); |
+ |
+ // Return pos itself if the two are from the very same editable region, or both are non-editable. |
+ if (highestRootOfPos == highestRoot) |
+ return pos; |
+ |
+ // If |pos| has an editable root, skip to the start |
+ if (highestRootOfPos) |
+ return previousVisuallyDistinctCandidate(Position(highestRootOfPos, Position::PositionIsBeforeAnchor).parentAnchoredEquivalent()); |
+ |
+ // That must mean that |pos| is not editable. Return the last position before pos that is in the same editable region as this position |
+ return lastEditablePositionBeforePositionInRoot(pos.deepEquivalent(), highestRoot); |
+} |
+ |
+VisiblePosition VisiblePosition::skipToEndOfEditingBoundary(const VisiblePosition &pos) const |
+{ |
+ if (pos.isNull()) |
+ return pos; |
+ |
+ Node* highestRoot = highestEditableRoot(deepEquivalent()); |
+ Node* highestRootOfPos = highestEditableRoot(pos.deepEquivalent()); |
+ |
+ // Return pos itself if the two are from the very same editable region, or both are non-editable. |
+ if (highestRootOfPos == highestRoot) |
+ return pos; |
+ |
+ // If |pos| has an editable root, skip to the end |
+ if (highestRootOfPos) |
+ return Position(highestRootOfPos, Position::PositionIsAfterAnchor).parentAnchoredEquivalent(); |
+ |
+ // That must mean that |pos| is not editable. Return the next position after pos that is in the same editable region as this position |
+ return firstEditablePositionAfterPositionInRoot(pos.deepEquivalent(), highestRoot); |
+} |
+ |
static Position canonicalizeCandidate(const Position& candidate) |
{ |
if (candidate.isNull()) |