From 2d12d4ababc8541695768e4c767a2aeef5367420 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Mon, 2 Mar 2020 07:35:49 +0000 Subject: [PATCH] Bug 1618089 - part 5: Make `WSRunObject::GetASCIIShitespacesBounds()` return 2 `EditorDOMPoint`s r=m_kato Before changing `WSPoint` to `EditorDOMPointBase`, we need to change some methods which are helped by the methods returning `WSPoint`. Differential Revision: https://phabricator.services.mozilla.com/D64335 --HG-- extra : moz-landing-system : lando --- editor/libeditor/WSRunObject.cpp | 151 +++++++++++++------------------ editor/libeditor/WSRunObject.h | 23 ++--- 2 files changed, 71 insertions(+), 103 deletions(-) diff --git a/editor/libeditor/WSRunObject.cpp b/editor/libeditor/WSRunObject.cpp index 9c6d2d5bcc97..6863b754dcd1 100644 --- a/editor/libeditor/WSRunObject.cpp +++ b/editor/libeditor/WSRunObject.cpp @@ -52,14 +52,6 @@ template WSScanResult WSRunScanner::ScanNextVisibleNodeOrBlockBoundaryFrom( const EditorDOMPoint& aPoint) const; template WSScanResult WSRunScanner::ScanNextVisibleNodeOrBlockBoundaryFrom( const EditorRawDOMPoint& aPoint) const; -template void WSRunObject::GetASCIIWhitespacesBounds( - int16_t aDir, const EditorDOMPoint& aPoint, dom::Text** outStartNode, - int32_t* outStartOffset, dom::Text** outEndNode, - int32_t* outEndOffset) const; -template void WSRunObject::GetASCIIWhitespacesBounds( - int16_t aDir, const EditorRawDOMPoint& aPoint, dom::Text** outStartNode, - int32_t* outStartOffset, dom::Text** outEndNode, - int32_t* outEndOffset) const; template WSRunScanner::WSRunScanner(const HTMLEditor* aHTMLEditor, @@ -427,16 +419,17 @@ nsresult WSRunObject::DeleteWSBackward() { // Caller's job to ensure that previous char is really ws. If it is normal // ws, we need to delete the whole run. if (nsCRT::IsAsciiSpace(point.mChar)) { - RefPtr startNodeText, endNodeText; - int32_t startOffset, endOffset; - GetASCIIWhitespacesBounds( - eBoth, EditorRawDOMPoint(point.mTextNode, point.mOffset + 1), - getter_AddRefs(startNodeText), &startOffset, - getter_AddRefs(endNodeText), &endOffset); + EditorRawDOMPoint atNextChar(point.mTextNode, point.mOffset); + DebugOnly advanced = atNextChar.AdvanceOffset(); + NS_WARNING_ASSERTION(advanced, "Failed to advance offset"); + EditorDOMPoint start, end; + Tie(start, end) = GetASCIIWhitespacesBounds(eBoth, atNextChar); // adjust surrounding ws - nsCOMPtr startNode = startNodeText.get(); - nsCOMPtr endNode = endNodeText.get(); + nsCOMPtr startNode = start.GetContainer(); + nsCOMPtr endNode = end.GetContainer(); + int32_t startOffset = start.Offset(); + int32_t endOffset = end.Offset(); nsresult rv = WSRunObject::PrepareToDeleteRange( MOZ_KnownLive(mHTMLEditor), address_of(startNode), &startOffset, address_of(endNode), &endOffset); @@ -491,15 +484,15 @@ nsresult WSRunObject::DeleteWSForward() { // Caller's job to ensure that next char is really ws. If it is normal ws, // we need to delete the whole run. if (nsCRT::IsAsciiSpace(point.mChar)) { - RefPtr startNodeText, endNodeText; - int32_t startOffset, endOffset; - GetASCIIWhitespacesBounds( - eBoth, EditorRawDOMPoint(point.mTextNode, point.mOffset + 1), - getter_AddRefs(startNodeText), &startOffset, - getter_AddRefs(endNodeText), &endOffset); - + EditorRawDOMPoint atNextChar(point.mTextNode, point.mOffset); + DebugOnly advanced = atNextChar.AdvanceOffset(); + NS_WARNING_ASSERTION(advanced, "Failed to advance offset"); + EditorDOMPoint start, end; + Tie(start, end) = GetASCIIWhitespacesBounds(eBoth, atNextChar); // Adjust surrounding ws - nsCOMPtr startNode(startNodeText), endNode(endNodeText); + nsCOMPtr startNode(start.GetContainer()), + endNode(end.GetContainer()); + int32_t startOffset = start.Offset(), endOffset = end.Offset(); nsresult rv = WSRunObject::PrepareToDeleteRange( MOZ_KnownLive(mHTMLEditor), address_of(startNode), &startOffset, address_of(endNode), &endOffset); @@ -1277,13 +1270,10 @@ nsresult WSRunObject::PrepareToDeleteRangePriv(WSRunObject* aEndObject) { // up WSPoint point = GetPreviousCharPoint(mScanStartPoint); if (point.mTextNode && nsCRT::IsAsciiSpace(point.mChar)) { - RefPtr wsStartNode, wsEndNode; - int32_t wsStartOffset, wsEndOffset; - GetASCIIWhitespacesBounds(eBoth, mScanStartPoint, - getter_AddRefs(wsStartNode), &wsStartOffset, - getter_AddRefs(wsEndNode), &wsEndOffset); - point.mTextNode = wsStartNode; - point.mOffset = wsStartOffset; + EditorDOMPoint start, end; + Tie(start, end) = GetASCIIWhitespacesBounds(eBoth, mScanStartPoint); + point.mTextNode = start.GetContainerAsText(); + point.mOffset = start.Offset(); nsresult rv = InsertNBSPAndRemoveFollowingASCIIWhitespaces(point); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; @@ -1322,13 +1312,10 @@ nsresult WSRunObject::PrepareToSplitAcrossBlocksPriv() { // up WSPoint point = GetPreviousCharPoint(mScanStartPoint); if (point.mTextNode && nsCRT::IsAsciiSpace(point.mChar)) { - RefPtr wsStartNode, wsEndNode; - int32_t wsStartOffset, wsEndOffset; - GetASCIIWhitespacesBounds(eBoth, mScanStartPoint, - getter_AddRefs(wsStartNode), &wsStartOffset, - getter_AddRefs(wsEndNode), &wsEndOffset); - point.mTextNode = wsStartNode; - point.mOffset = wsStartOffset; + EditorDOMPoint start, end; + Tie(start, end) = GetASCIIWhitespacesBounds(eBoth, mScanStartPoint); + point.mTextNode = start.GetContainerAsText(); + point.mOffset = start.Offset(); nsresult rv = InsertNBSPAndRemoveFollowingASCIIWhitespaces(point); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; @@ -1557,18 +1544,15 @@ nsresult WSRunObject::InsertNBSPAndRemoveFollowingASCIIWhitespaces( } // Next, find range of whitespaces it will be replaced. - RefPtr startNode, endNode; - int32_t startOffset = 0, endOffset = 0; - - GetASCIIWhitespacesBounds( - eAfter, EditorRawDOMPoint(aPoint.mTextNode, aPoint.mOffset + 1), - getter_AddRefs(startNode), &startOffset, getter_AddRefs(endNode), - &endOffset); + EditorRawDOMPoint atNextChar(aPoint.mTextNode, aPoint.mOffset); + DebugOnly advanced = atNextChar.AdvanceOffset(); + NS_WARNING_ASSERTION(advanced, "Failed to advance offset from the point"); + EditorDOMPoint start, end; + Tie(start, end) = GetASCIIWhitespacesBounds(eAfter, atNextChar); // Finally, delete that replaced ws, if any - if (startNode) { - rv = DeleteRange(EditorRawDOMPoint(startNode, startOffset), - EditorRawDOMPoint(endNode, endOffset)); + if (start.IsSet()) { + nsresult rv = DeleteRange(start, end); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -1578,32 +1562,26 @@ nsresult WSRunObject::InsertNBSPAndRemoveFollowingASCIIWhitespaces( } template -void WSRunObject::GetASCIIWhitespacesBounds( - int16_t aDir, const EditorDOMPointBase& aPoint, Text** outStartNode, - int32_t* outStartOffset, Text** outEndNode, int32_t* outEndOffset) const { +Tuple WSRunObject::GetASCIIWhitespacesBounds( + int16_t aDir, const EditorDOMPointBase& aPoint) const { MOZ_ASSERT(aPoint.IsSet()); - MOZ_ASSERT(outStartNode); - MOZ_ASSERT(outStartOffset); - MOZ_ASSERT(outEndNode); - MOZ_ASSERT(outEndOffset); - RefPtr startNode, endNode; - int32_t startOffset = 0, endOffset = 0; + EditorDOMPoint start, end; if (aDir & eAfter) { WSPoint point = GetNextCharPoint(aPoint); if (point.mTextNode) { - // We found a text node, at least - startNode = endNode = point.mTextNode; - startOffset = endOffset = point.mOffset; - - // Scan ahead to end of ASCII ws + // We found a text node, at least. + start.Set(point.mTextNode, point.mOffset); + end = start; + // Scan ahead to end of ASCII whitespaces. for (; nsCRT::IsAsciiSpace(point.mChar) && point.mTextNode; point = GetNextCharPointFromPointInText(point)) { - endNode = point.mTextNode; - // endOffset is _after_ ws + // End of the range should be after the whitespace. + end.Set(point.mTextNode, point.mOffset); + DebugOnly advanced = end.AdvanceOffset(); + NS_WARNING_ASSERTION(advanced, "Failed to advance offset"); point.mOffset++; - endOffset = point.mOffset; } } } @@ -1611,27 +1589,24 @@ void WSRunObject::GetASCIIWhitespacesBounds( if (aDir & eBefore) { WSPoint point = GetPreviousCharPoint(aPoint); if (point.mTextNode) { - // We found a text node, at least - startNode = point.mTextNode; - startOffset = point.mOffset + 1; - if (!endNode) { - endNode = startNode; - endOffset = startOffset; + // We found a text node, at least. + start.Set(point.mTextNode, point.mOffset); + DebugOnly advanced = start.AdvanceOffset(); + NS_WARNING_ASSERTION(advanced, "Failed to advance offset"); + if (!end.IsSet()) { + end = start; } - - // Scan back to start of ASCII ws + // Scan back to start of ASCII whitespaces. for (; nsCRT::IsAsciiSpace(point.mChar) && point.mTextNode; point = GetPreviousCharPointFromPointInText(point)) { - startNode = point.mTextNode; - startOffset = point.mOffset; + start.Set(point.mTextNode, point.mOffset); } } } - startNode.forget(outStartNode); - *outStartOffset = startOffset; - endNode.forget(outEndNode); - *outEndOffset = endOffset; + MOZ_ASSERT(!start.IsSet() || start.IsInTextNode()); + MOZ_ASSERT(!end.IsSet() || end.IsInTextNode()); + return MakeTuple(start, end); } template @@ -1893,13 +1868,14 @@ nsresult WSRunObject::CheckTrailingNBSPOfRun(WSFragment* aRun) { // will ensure that if someone types two spaces after a sentence, and the // editor softwraps at this point, the spaces won't be split across lines, // which looks ugly and is bad for the moose. - - RefPtr startNode, endNode; - int32_t startOffset, endOffset; - GetASCIIWhitespacesBounds( - eBoth, EditorRawDOMPoint(prevPoint.mTextNode, prevPoint.mOffset + 1), - getter_AddRefs(startNode), &startOffset, getter_AddRefs(endNode), - &endOffset); + EditorRawDOMPoint atNextCharOfPreviousPoint(prevPoint.mTextNode, + prevPoint.mOffset); + DebugOnly advanced = atNextCharOfPreviousPoint.AdvanceOffset(); + NS_WARNING_ASSERTION(advanced, + "Failed to advance offset from previous char"); + EditorDOMPoint start, end; + Tie(start, end) = + GetASCIIWhitespacesBounds(eBoth, atNextCharOfPreviousPoint); // Delete that nbsp nsresult rv = DeleteRange( @@ -1913,7 +1889,8 @@ nsresult WSRunObject::CheckTrailingNBSPOfRun(WSFragment* aRun) { AutoTransactionsConserveSelection dontChangeMySelection(mHTMLEditor); rv = MOZ_KnownLive(mHTMLEditor) .InsertTextIntoTextNodeWithTransaction( - nsDependentSubstring(&kNBSP, 1), *startNode, startOffset, + nsDependentSubstring(&kNBSP, 1), + MOZ_KnownLive(*start.GetContainerAsText()), start.Offset(), true); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; diff --git a/editor/libeditor/WSRunObject.h b/editor/libeditor/WSRunObject.h index eda2311c962c..1c6cea41da02 100644 --- a/editor/libeditor/WSRunObject.h +++ b/editor/libeditor/WSRunObject.h @@ -12,6 +12,7 @@ #include "mozilla/EditorDOMPoint.h" // for EditorDOMPoint #include "mozilla/HTMLEditor.h" #include "mozilla/Maybe.h" +#include "mozilla/Tuple.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/HTMLBRElement.h" #include "mozilla/dom/Text.h" @@ -810,30 +811,20 @@ class MOZ_STACK_CLASS WSRunObject final : public WSRunScanner { nsresult InsertNBSPAndRemoveFollowingASCIIWhitespaces(WSPoint aPoint); /** - * GetASCIIWhitespacesBounds() retrieves whitespaces before and/or after the - * point specified by aNode and aOffset. + * GetASCIIWhitespacesBounds() returns a range from start of whitespaces + * and end of whitespaces if the character at aPoint is an ASCII whitespace. + * Note that the end is next character of the last whitespace. * * @param aDir Specify eBefore if you want to scan text backward. * Specify eAfter if you want to scan text forward. * Specify eBoth if you want to scan text to both * direction. * @param aPoint The point to start to scan whitespaces from. - * @param outStartNode [out] The container of first ASCII whitespace. - * If there is no whitespaces, returns nullptr. - * @param outStartOffset [out] The offset of first ASCII whitespace in - * outStartNode. - * @param outEndNode [out] The container of last ASCII whitespace. - * If there is no whitespaces, returns nullptr. - * @param outEndOffset [out] The offset of last ASCII whitespace in - * outEndNode. + * @return Start and end of the expanded range. */ template - void GetASCIIWhitespacesBounds(int16_t aDir, - const EditorDOMPointBase& aPoint, - dom::Text** outStartNode, - int32_t* outStartOffset, - dom::Text** outEndNode, - int32_t* outEndOffset) const; + Tuple GetASCIIWhitespacesBounds( + int16_t aDir, const EditorDOMPointBase& aPoint) const; MOZ_CAN_RUN_SCRIPT nsresult CheckTrailingNBSPOfRun(WSFragment* aRun);