/* * If we're dragging start caret, we do not want to drag over previous * character of end caret. Same as end caret. So we check if content offset * exceed previous/next character of end/start caret base on aDragMode. */ static bool CompareRangeWithContentOffset(nsRange* aRange, nsFrameSelection* aSelection, nsIFrame::ContentOffsets& aOffsets, SelectionCarets::DragMode aDragMode) { MOZ_ASSERT(aDragMode != SelectionCarets::NONE); nsINode* node = nullptr; int32_t nodeOffset = 0; nsFrameSelection::HINT hint = nsFrameSelection::HINTLEFT; nsDirection dir; if (aDragMode == SelectionCarets::START_FRAME) { // Check previous character of end node offset node = aRange->GetEndParent(); nodeOffset = aRange->EndOffset(); hint = nsFrameSelection::HINTLEFT; dir = eDirPrevious; } else { // Check next character of start node offset node = aRange->GetStartParent(); nodeOffset = aRange->StartOffset(); hint = nsFrameSelection::HINTRIGHT; dir = eDirNext; } nsCOMPtr<nsIContent> content = do_QueryInterface(node); int32_t offset = 0; nsIFrame* theFrame = aSelection->GetFrameForNodeOffset(content, nodeOffset, hint, &offset); NS_ENSURE_TRUE(theFrame, false); // Move one character forward/backward from point and get offset nsPeekOffsetStruct pos(eSelectCluster, dir, offset, 0, true, true, //limit on scrolled views false, false); nsresult rv = theFrame->PeekOffset(&pos); if (NS_FAILED(rv)) { pos.mResultContent = content; pos.mContentOffset = nodeOffset; } // Compare with current point int32_t result = nsContentUtils::ComparePoints(aOffsets.content, aOffsets.StartOffset(), pos.mResultContent, pos.mContentOffset); if ((aDragMode == SelectionCarets::START_FRAME && result == 1) || (aDragMode == SelectionCarets::END_FRAME && result == -1)) { aOffsets.content = pos.mResultContent; aOffsets.offset = pos.mContentOffset; aOffsets.secondaryOffset = pos.mContentOffset; } return true; }
bool AccessibleCaretManager::CompareRangeWithContentOffset(nsIFrame::ContentOffsets& aOffsets) { Selection* selection = GetSelection(); if (!selection) { return false; } uint32_t rangeCount = selection->RangeCount(); MOZ_ASSERT(rangeCount > 0); int32_t rangeIndex = (mActiveCaret == mFirstCaret.get() ? rangeCount - 1 : 0); RefPtr<nsRange> range = selection->GetRangeAt(rangeIndex); nsINode* node = nullptr; int32_t nodeOffset = 0; CaretAssociationHint hint; nsDirection dir; if (mActiveCaret == mFirstCaret.get()) { // Check previous character of end node offset node = range->GetEndParent(); nodeOffset = range->EndOffset(); hint = CARET_ASSOCIATE_BEFORE; dir = eDirPrevious; } else { // Check next character of start node offset node = range->GetStartParent(); nodeOffset = range->StartOffset(); hint = CARET_ASSOCIATE_AFTER; dir = eDirNext; } nsCOMPtr<nsIContent> content = do_QueryInterface(node); RefPtr<nsFrameSelection> fs = GetFrameSelection(); if (!fs) { return false; } int32_t offset = 0; nsIFrame* theFrame = fs->GetFrameForNodeOffset(content, nodeOffset, hint, &offset); if (!theFrame) { return false; } // Move one character forward/backward from point and get offset nsPeekOffsetStruct pos(eSelectCluster, dir, offset, nsPoint(0, 0), true, true, //limit on scrolled views false, false, false); nsresult rv = theFrame->PeekOffset(&pos); if (NS_FAILED(rv)) { pos.mResultContent = content; pos.mContentOffset = nodeOffset; } // Compare with current point int32_t result = nsContentUtils::ComparePoints(aOffsets.content, aOffsets.StartOffset(), pos.mResultContent, pos.mContentOffset); if ((mActiveCaret == mFirstCaret.get() && result == 1) || (mActiveCaret == mSecondCaret.get() && result == -1)) { aOffsets.content = pos.mResultContent; aOffsets.offset = pos.mContentOffset; aOffsets.secondaryOffset = pos.mContentOffset; } return true; }