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 if (pos.atStartOfTree()) return VisiblePosition(); VisiblePosition prev = VisiblePosition(pos, DOWNSTREAM); ASSERT(prev != *this); #ifndef NDEBUG // we should always be able to make the affinity DOWNSTREAM, because going previous from an // UPSTREAM position can never yield another UPSTREAM position (unless line wrap length is 0!). if (prev.isNotNull() && m_affinity == UPSTREAM) { VisiblePosition temp = prev; temp.setAffinity(UPSTREAM); ASSERT(inSameLine(temp, prev)); } #endif if (rule == CanCrossEditingBoundary) return prev; return honorEditingBoundaryAtOrBefore(prev); }
VisiblePosition VisiblePosition::previous(bool stayInEditableContent) const { // find first previous DOM position that is visible Position pos = previousVisiblePosition(m_deepPosition); // return null visible position if there is no previous visible position if (pos.atStart()) return VisiblePosition(); VisiblePosition prev = VisiblePosition(pos, DOWNSTREAM); ASSERT(prev != *this); #ifndef NDEBUG // we should always be able to make the affinity DOWNSTREAM, because going previous from an // UPSTREAM position can never yield another UPSTREAM position (unless line wrap length is 0!). if (prev.isNotNull() && m_affinity == UPSTREAM) { VisiblePosition temp = prev; temp.setAffinity(UPSTREAM); ASSERT(inSameLine(temp, prev)); } #endif if (!stayInEditableContent || prev.isNull()) return prev; Node* highestRoot = highestEditableRoot(deepEquivalent()); if (!prev.deepEquivalent().node()->isAncestor(highestRoot)) return VisiblePosition(); if (highestEditableRoot(prev.deepEquivalent()) == highestRoot) return prev; return lastEditablePositionBeforePositionInRoot(prev.deepEquivalent(), highestRoot); }
VisiblePosition VisiblePosition::previous(EditingBoundaryCrossingRule rule) const { Position pos = previousVisuallyDistinctCandidate(m_deepPosition); // return null visible position if there is no previous visible position if (pos.atStartOfTree()) return VisiblePosition(); VisiblePosition prev = VisiblePosition(pos, DOWNSTREAM); ASSERT(prev != *this); #if ENABLE(ASSERT) // we should always be able to make the affinity DOWNSTREAM, because going previous from an // UPSTREAM position can never yield another UPSTREAM position (unless line wrap length is 0!). if (prev.isNotNull() && m_affinity == UPSTREAM) { VisiblePosition temp = prev; temp.setAffinity(UPSTREAM); ASSERT(inSameLine(temp, prev)); } #endif switch (rule) { case CanCrossEditingBoundary: return prev; case CannotCrossEditingBoundary: return honorEditingBoundaryAtOrBefore(prev); case CanSkipOverEditingBoundary: return skipToStartOfEditingBoundary(prev); } ASSERT_NOT_REACHED(); return honorEditingBoundaryAtOrBefore(prev); }
void setAffinityUsingLinePosition(VisiblePosition &pos) { // When not moving across line wrap, make sure to end up with DOWNSTREAM affinity. if (pos.isNotNull() && pos.affinity() == UPSTREAM) { VisiblePosition temp(pos); temp.setAffinity(DOWNSTREAM); if (!visiblePositionsOnDifferentLines(temp, pos)) pos.setAffinity(DOWNSTREAM); } }
// NOTE: Consider providing this utility method as AX API VisiblePositionRange AccessibilityObject::visiblePositionRangeForRange(const PlainTextRange& range) const { if (range.start + range.length > text().length()) return VisiblePositionRange(); VisiblePosition startPosition = visiblePositionForIndex(range.start); startPosition.setAffinity(DOWNSTREAM); VisiblePosition endPosition = visiblePositionForIndex(range.start + range.length); return VisiblePositionRange(startPosition, endPosition); }
VisiblePosition VisiblePosition::previous() const { VisiblePosition result = VisiblePosition(previousVisiblePosition(m_deepPosition), DOWNSTREAM); #ifndef NDEBUG // we should always be able to make the affinity DOWNSTREAM, because going previous from an // UPSTREAM position can never yield another UPSTREAM position (unless line wrap length is 0!). if (result.isNotNull() && m_affinity == UPSTREAM) { VisiblePosition temp = result; temp.setAffinity(UPSTREAM); ASSERT(!visiblePositionsOnDifferentLines(temp, result)); } #endif return result; }
static gboolean webkit_accessible_text_set_caret_offset(AtkText* text, gint offset) { AccessibilityObject* coreObject = core(text); // FIXME: We need to reimplement visiblePositionRangeForRange here // because the actual function checks the offset is within the // boundaries of text().length(), but text() only works for text // controls... VisiblePosition startPosition = coreObject->visiblePositionForIndex(offset); startPosition.setAffinity(DOWNSTREAM); VisiblePosition endPosition = coreObject->visiblePositionForIndex(offset); VisiblePositionRange range = VisiblePositionRange(startPosition, endPosition); coreObject->setSelectedVisiblePositionRange(range); return TRUE; }