--- a/editor/libeditor/WSRunObject.cpp
+++ b/editor/libeditor/WSRunObject.cpp
@@ -191,20 +191,20 @@ WSRunObject::InsertBreak(Selection& aSel
// Handle any changes needed to ws run after inserted br
if (!afterRun || (afterRun->mType & WSType::trailingWS)) {
// Don't need to do anything. Just insert break. ws won't change.
} else if (afterRun->mType & WSType::leadingWS) {
// Delete the leading ws that is after insertion point. We don't
// have to (it would still not be significant after br), but it's
// just more aesthetically pleasing to.
- nsresult rv =
- DeleteChars(pointToInsert.Container(), pointToInsert.Offset(),
- afterRun->mEndNode, afterRun->mEndOffset);
- NS_ENSURE_SUCCESS(rv, nullptr);
+ nsresult rv = DeleteRange(pointToInsert.AsRaw(), afterRun->EndPoint());
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return nullptr;
+ }
} else if (afterRun->mType == WSType::normalWS) {
// Need to determine if break at front of non-nbsp run. If so, convert
// run to nbsp.
WSPoint thePoint =
GetCharAfter(pointToInsert.Container(), pointToInsert.Offset());
if (thePoint.mTextNode && nsCRT::IsAsciiSpace(thePoint.mChar)) {
WSPoint prevPoint = GetCharBefore(thePoint);
if (!prevPoint.mTextNode ||
@@ -217,20 +217,20 @@ WSRunObject::InsertBreak(Selection& aSel
}
// Handle any changes needed to ws run before inserted br
if (!beforeRun || (beforeRun->mType & WSType::leadingWS)) {
// Don't need to do anything. Just insert break. ws won't change.
} else if (beforeRun->mType & WSType::trailingWS) {
// Need to delete the trailing ws that is before insertion point, because it
// would become significant after break inserted.
- nsresult rv =
- DeleteChars(beforeRun->mStartNode, beforeRun->mStartOffset,
- pointToInsert.Container(), pointToInsert.Offset());
- NS_ENSURE_SUCCESS(rv, nullptr);
+ nsresult rv = DeleteRange(beforeRun->StartPoint(), pointToInsert.AsRaw());
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return nullptr;
+ }
} else if (beforeRun->mType == WSType::normalWS) {
// Try to change an nbsp to a space, just to prevent nbsp proliferation
nsresult rv =
CheckTrailingNBSP(beforeRun, pointToInsert.Container(),
pointToInsert.Offset());
NS_ENSURE_SUCCESS(rv, nullptr);
}
}
@@ -281,38 +281,38 @@ WSRunObject::InsertText(nsIDocument& aDo
AutoTrackDOMPoint tracker(mHTMLEditor->mRangeUpdater, &pointToInsert);
// Handle any changes needed to ws run after inserted text
if (!afterRun || afterRun->mType & WSType::trailingWS) {
// Don't need to do anything. Just insert text. ws won't change.
} else if (afterRun->mType & WSType::leadingWS) {
// Delete the leading ws that is after insertion point, because it
// would become significant after text inserted.
- nsresult rv =
- DeleteChars(pointToInsert.Container(), pointToInsert.Offset(),
- afterRun->mEndNode, afterRun->mEndOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ nsresult rv = DeleteRange(pointToInsert.AsRaw(), afterRun->EndPoint());
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
} else if (afterRun->mType == WSType::normalWS) {
// Try to change an nbsp to a space, if possible, just to prevent nbsp
// proliferation
nsresult rv = CheckLeadingNBSP(afterRun, pointToInsert.Container(),
pointToInsert.Offset());
NS_ENSURE_SUCCESS(rv, rv);
}
// Handle any changes needed to ws run before inserted text
if (!beforeRun || beforeRun->mType & WSType::leadingWS) {
// Don't need to do anything. Just insert text. ws won't change.
} else if (beforeRun->mType & WSType::trailingWS) {
// Need to delete the trailing ws that is before insertion point, because
// it would become significant after text inserted.
- nsresult rv =
- DeleteChars(beforeRun->mStartNode, beforeRun->mStartOffset,
- pointToInsert.Container(), pointToInsert.Offset());
- NS_ENSURE_SUCCESS(rv, rv);
+ nsresult rv = DeleteRange(beforeRun->StartPoint(), pointToInsert.AsRaw());
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
} else if (beforeRun->mType == WSType::normalWS) {
// Try to change an nbsp to a space, if possible, just to prevent nbsp
// proliferation
nsresult rv = CheckTrailingNBSP(beforeRun, pointToInsert.Container(),
pointToInsert.Offset());
NS_ENSURE_SUCCESS(rv, rv);
}
@@ -391,18 +391,23 @@ WSRunObject::InsertText(nsIDocument& aDo
nsresult
WSRunObject::DeleteWSBackward()
{
WSPoint point = GetCharBefore(mNode, mOffset);
NS_ENSURE_TRUE(point.mTextNode, NS_OK); // nothing to delete
// Easy case, preformatted ws.
if (mPRE && (nsCRT::IsAsciiSpace(point.mChar) || point.mChar == nbsp)) {
- return DeleteChars(point.mTextNode, point.mOffset,
- point.mTextNode, point.mOffset + 1);
+ nsresult rv =
+ DeleteRange(EditorRawDOMPoint(point.mTextNode, point.mOffset),
+ EditorRawDOMPoint(point.mTextNode, point.mOffset + 1));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
}
// 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<Text> startNodeText, endNodeText;
int32_t startOffset, endOffset;
GetAsciiWSBounds(eBoth, point.mTextNode, point.mOffset + 1,
@@ -414,47 +419,62 @@ WSRunObject::DeleteWSBackward()
nsCOMPtr<nsINode> endNode = endNodeText.get();
nsresult rv =
WSRunObject::PrepareToDeleteRange(mHTMLEditor,
address_of(startNode), &startOffset,
address_of(endNode), &endOffset);
NS_ENSURE_SUCCESS(rv, rv);
// finally, delete that ws
- return DeleteChars(startNode, startOffset, endNode, endOffset);
+ rv = DeleteRange(EditorRawDOMPoint(startNode, startOffset),
+ EditorRawDOMPoint(endNode, endOffset));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
}
if (point.mChar == nbsp) {
nsCOMPtr<nsINode> node(point.mTextNode);
// adjust surrounding ws
int32_t startOffset = point.mOffset;
int32_t endOffset = point.mOffset + 1;
nsresult rv =
WSRunObject::PrepareToDeleteRange(mHTMLEditor,
address_of(node), &startOffset,
address_of(node), &endOffset);
NS_ENSURE_SUCCESS(rv, rv);
// finally, delete that ws
- return DeleteChars(node, startOffset, node, endOffset);
+ rv = DeleteRange(EditorRawDOMPoint(node, startOffset),
+ EditorRawDOMPoint(node, endOffset));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
}
return NS_OK;
}
nsresult
WSRunObject::DeleteWSForward()
{
WSPoint point = GetCharAfter(mNode, mOffset);
NS_ENSURE_TRUE(point.mTextNode, NS_OK); // nothing to delete
// Easy case, preformatted ws.
if (mPRE && (nsCRT::IsAsciiSpace(point.mChar) || point.mChar == nbsp)) {
- return DeleteChars(point.mTextNode, point.mOffset,
- point.mTextNode, point.mOffset + 1);
+ nsresult rv =
+ DeleteRange(EditorRawDOMPoint(point.mTextNode, point.mOffset),
+ EditorRawDOMPoint(point.mTextNode, point.mOffset + 1));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
}
// 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<Text> startNodeText, endNodeText;
int32_t startOffset, endOffset;
GetAsciiWSBounds(eBoth, point.mTextNode, point.mOffset + 1,
@@ -465,32 +485,42 @@ WSRunObject::DeleteWSForward()
nsCOMPtr<nsINode> startNode(startNodeText), endNode(endNodeText);
nsresult rv =
WSRunObject::PrepareToDeleteRange(mHTMLEditor,
address_of(startNode), &startOffset,
address_of(endNode), &endOffset);
NS_ENSURE_SUCCESS(rv, rv);
// Finally, delete that ws
- return DeleteChars(startNode, startOffset, endNode, endOffset);
+ rv = DeleteRange(EditorRawDOMPoint(startNode, startOffset),
+ EditorRawDOMPoint(endNode, endOffset));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
}
if (point.mChar == nbsp) {
nsCOMPtr<nsINode> node(point.mTextNode);
// Adjust surrounding ws
int32_t startOffset = point.mOffset;
int32_t endOffset = point.mOffset+1;
nsresult rv =
WSRunObject::PrepareToDeleteRange(mHTMLEditor,
address_of(node), &startOffset,
address_of(node), &endOffset);
NS_ENSURE_SUCCESS(rv, rv);
// Finally, delete that ws
- return DeleteChars(node, startOffset, node, endOffset);
+ rv = DeleteRange(EditorRawDOMPoint(node, startOffset),
+ EditorRawDOMPoint(node, endOffset));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
}
return NS_OK;
}
void
WSRunObject::PriorVisibleNode(nsINode* aNode,
int32_t aOffset,
@@ -1185,19 +1215,20 @@ WSRunObject::PrepareToDeleteRangePriv(WS
// get the runs before and after selection
WSFragment* beforeRun = FindNearestRun(Point(), false);
WSFragment* afterRun = aEndObject->FindNearestRun(aEndObject->Point(), true);
// trim after run of any leading ws
if (afterRun && (afterRun->mType & WSType::leadingWS)) {
nsresult rv =
- aEndObject->DeleteChars(aEndObject->mNode, aEndObject->mOffset,
- afterRun->mEndNode, afterRun->mEndOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ aEndObject->DeleteRange(aEndObject->Point(), afterRun->EndPoint());
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
}
// adjust normal ws in afterRun if needed
if (afterRun && afterRun->mType == WSType::normalWS && !aEndObject->mPRE) {
if ((beforeRun && (beforeRun->mType & WSType::leadingWS)) ||
(!beforeRun && ((mStartReason & WSType::block) ||
mStartReason == WSType::br))) {
// make sure leading char of following ws is an nbsp, so that it will show up
WSPoint point = aEndObject->GetCharAfter(aEndObject->mNode,
@@ -1205,19 +1236,20 @@ WSRunObject::PrepareToDeleteRangePriv(WS
if (point.mTextNode && nsCRT::IsAsciiSpace(point.mChar)) {
nsresult rv = aEndObject->ConvertToNBSP(point);
NS_ENSURE_SUCCESS(rv, rv);
}
}
}
// trim before run of any trailing ws
if (beforeRun && (beforeRun->mType & WSType::trailingWS)) {
- nsresult rv = DeleteChars(beforeRun->mStartNode, beforeRun->mStartOffset,
- mNode, mOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ nsresult rv = DeleteRange(beforeRun->StartPoint(), Point());
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
} else if (beforeRun && beforeRun->mType == WSType::normalWS && !mPRE) {
if ((afterRun && (afterRun->mType & WSType::trailingWS)) ||
(afterRun && afterRun->mType == WSType::normalWS) ||
(!afterRun && (aEndObject->mEndReason & WSType::block))) {
// make sure trailing char of starting ws is an nbsp, so that it will show up
WSPoint point = GetCharBefore(mNode, mOffset);
if (point.mTextNode && nsCRT::IsAsciiSpace(point.mChar)) {
RefPtr<Text> wsStartNode, wsEndNode;
@@ -1271,83 +1303,95 @@ WSRunObject::PrepareToSplitAcrossBlocksP
nsresult rv = ConvertToNBSP(point);
NS_ENSURE_SUCCESS(rv, rv);
}
}
return NS_OK;
}
nsresult
-WSRunObject::DeleteChars(nsINode* aStartNode,
- int32_t aStartOffset,
- nsINode* aEndNode,
- int32_t aEndOffset)
+WSRunObject::DeleteRange(const EditorRawDOMPoint& aStartPoint,
+ const EditorRawDOMPoint& aEndPoint)
{
+ if (NS_WARN_IF(!aStartPoint.IsSet()) ||
+ NS_WARN_IF(!aEndPoint.IsSet())) {
+ return NS_ERROR_INVALID_ARG;
+ }
+ MOZ_ASSERT(aStartPoint.IsSetAndValid());
+ MOZ_ASSERT(aEndPoint.IsSetAndValid());
+
// MOOSE: this routine needs to be modified to preserve the integrity of the
// wsFragment info.
- NS_ENSURE_TRUE(aStartNode && aEndNode, NS_ERROR_NULL_POINTER);
- if (aStartNode == aEndNode && aStartOffset == aEndOffset) {
+ if (aStartPoint == aEndPoint) {
// Nothing to delete
return NS_OK;
}
- int32_t idx = mNodeArray.IndexOf(aStartNode);
- if (idx == -1) {
- // If our strarting point wasn't one of our ws text nodes, then just go
- // through them from the beginning.
- idx = 0;
- }
-
- if (aStartNode == aEndNode && aStartNode->GetAsText()) {
- return mHTMLEditor->DeleteText(*aStartNode->GetAsText(),
- static_cast<uint32_t>(aStartOffset),
- static_cast<uint32_t>(aEndOffset - aStartOffset));
+ if (aStartPoint.Container() == aEndPoint.Container() &&
+ aStartPoint.Container()->GetAsText()) {
+ return mHTMLEditor->DeleteText(*aStartPoint.Container()->GetAsText(),
+ aStartPoint.Offset(),
+ aEndPoint.Offset() - aStartPoint.Offset());
}
RefPtr<nsRange> range;
int32_t count = mNodeArray.Length();
+ int32_t idx = mNodeArray.IndexOf(aStartPoint.Container());
+ if (idx == -1) {
+ // If our starting point wasn't one of our ws text nodes, then just go
+ // through them from the beginning.
+ idx = 0;
+ }
for (; idx < count; idx++) {
RefPtr<Text> node = mNodeArray[idx];
if (!node) {
// We ran out of ws nodes; must have been deleting to end
return NS_OK;
}
- if (node == aStartNode) {
- uint32_t len = node->Length();
- if (uint32_t(aStartOffset) < len) {
+ if (node == aStartPoint.Container()) {
+ if (!aStartPoint.IsEndOfContainer()) {
nsresult rv =
- mHTMLEditor->DeleteText(*node, AssertedCast<uint32_t>(aStartOffset),
- len - aStartOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ mHTMLEditor->DeleteText(*node, aStartPoint.Offset(),
+ aStartPoint.Container()->Length() -
+ aStartPoint.Offset());
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
}
- } else if (node == aEndNode) {
- if (aEndOffset) {
- nsresult rv =
- mHTMLEditor->DeleteText(*node, 0, AssertedCast<uint32_t>(aEndOffset));
- NS_ENSURE_SUCCESS(rv, rv);
+ } else if (node == aEndPoint.Container()) {
+ if (!aEndPoint.IsStartOfContainer()) {
+ nsresult rv = mHTMLEditor->DeleteText(*node, 0, aEndPoint.Offset());
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
}
break;
} else {
if (!range) {
- range = new nsRange(aStartNode);
- nsresult rv =
- range->SetStartAndEnd(aStartNode, aStartOffset, aEndNode, aEndOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ range = new nsRange(aStartPoint.Container());
+ nsresult rv = range->SetStartAndEnd(aStartPoint, aEndPoint);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
}
bool nodeBefore, nodeAfter;
nsresult rv =
nsRange::CompareNodeToRange(node, range, &nodeBefore, &nodeAfter);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
if (nodeAfter) {
break;
}
if (!nodeBefore) {
rv = mHTMLEditor->DeleteNode(node);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
mNodeArray.RemoveElement(node);
--count;
--idx;
}
}
}
return NS_OK;
}
@@ -1470,18 +1514,21 @@ WSRunObject::ConvertToNBSP(WSPoint aPoin
int32_t startOffset = 0, endOffset = 0;
GetAsciiWSBounds(eAfter, aPoint.mTextNode, aPoint.mOffset + 1,
getter_AddRefs(startNode), &startOffset,
getter_AddRefs(endNode), &endOffset);
// Finally, delete that replaced ws, if any
if (startNode) {
- rv = DeleteChars(startNode, startOffset, endNode, endOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = DeleteRange(EditorRawDOMPoint(startNode, startOffset),
+ EditorRawDOMPoint(endNode, endOffset));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
}
return NS_OK;
}
void
WSRunObject::GetAsciiWSBounds(int16_t aDir,
nsINode* aNode,
@@ -1773,37 +1820,45 @@ WSRunObject::CheckTrailingNBSPOfRun(WSFr
AutoTransactionsConserveSelection dontChangeMySelection(mHTMLEditor);
nsAutoString spaceStr(char16_t(32));
nsresult rv =
mHTMLEditor->InsertTextIntoTextNodeImpl(spaceStr, *thePoint.mTextNode,
thePoint.mOffset, true);
NS_ENSURE_SUCCESS(rv, rv);
// Finally, delete that nbsp
- rv = DeleteChars(thePoint.mTextNode, thePoint.mOffset + 1,
- thePoint.mTextNode, thePoint.mOffset + 2);
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = DeleteRange(EditorRawDOMPoint(thePoint.mTextNode,
+ thePoint.mOffset + 1),
+ EditorRawDOMPoint(thePoint.mTextNode,
+ thePoint.mOffset + 2));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
} else if (!mPRE && spaceNBSP && rightCheck) {
// Don't mess with this preformatted for now. We have a run of ASCII
// whitespace (which will render as one space) followed by an nbsp (which
// is at the end of the whitespace run). Let's switch their order. This
// 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<Text> startNode, endNode;
int32_t startOffset, endOffset;
GetAsciiWSBounds(eBoth, prevPoint.mTextNode, prevPoint.mOffset + 1,
getter_AddRefs(startNode), &startOffset,
getter_AddRefs(endNode), &endOffset);
// Delete that nbsp
- nsresult rv = DeleteChars(thePoint.mTextNode, thePoint.mOffset,
- thePoint.mTextNode, thePoint.mOffset + 1);
- NS_ENSURE_SUCCESS(rv, rv);
+ nsresult rv = DeleteRange(EditorRawDOMPoint(thePoint.mTextNode,
+ thePoint.mOffset),
+ EditorRawDOMPoint(thePoint.mTextNode,
+ thePoint.mOffset + 1));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
// Finally, insert that nbsp before the ASCII ws run
AutoTransactionsConserveSelection dontChangeMySelection(mHTMLEditor);
nsAutoString nbspStr(nbsp);
rv = mHTMLEditor->InsertTextIntoTextNodeImpl(nbspStr, *startNode,
startOffset, true);
NS_ENSURE_SUCCESS(rv, rv);
}
@@ -1840,19 +1895,23 @@ WSRunObject::CheckTrailingNBSP(WSFragmen
AutoTransactionsConserveSelection dontChangeMySelection(mHTMLEditor);
nsAutoString spaceStr(char16_t(32));
nsresult rv =
mHTMLEditor->InsertTextIntoTextNodeImpl(spaceStr, *thePoint.mTextNode,
thePoint.mOffset, true);
NS_ENSURE_SUCCESS(rv, rv);
// Finally, delete that nbsp
- rv = DeleteChars(thePoint.mTextNode, thePoint.mOffset + 1,
- thePoint.mTextNode, thePoint.mOffset + 2);
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = DeleteRange(EditorRawDOMPoint(thePoint.mTextNode,
+ thePoint.mOffset + 1),
+ EditorRawDOMPoint(thePoint.mTextNode,
+ thePoint.mOffset + 2));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
}
return NS_OK;
}
nsresult
WSRunObject::CheckLeadingNBSP(WSFragment* aRun,
nsINode* aNode,
int32_t aOffset)
@@ -1883,33 +1942,38 @@ WSRunObject::CheckLeadingNBSP(WSFragment
AutoTransactionsConserveSelection dontChangeMySelection(mHTMLEditor);
nsAutoString spaceStr(char16_t(32));
nsresult rv =
mHTMLEditor->InsertTextIntoTextNodeImpl(spaceStr, *thePoint.mTextNode,
thePoint.mOffset, true);
NS_ENSURE_SUCCESS(rv, rv);
// Finally, delete that nbsp
- rv = DeleteChars(thePoint.mTextNode, thePoint.mOffset + 1,
- thePoint.mTextNode, thePoint.mOffset + 2);
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = DeleteRange(EditorRawDOMPoint(thePoint.mTextNode,
+ thePoint.mOffset + 1),
+ EditorRawDOMPoint(thePoint.mTextNode,
+ thePoint.mOffset + 2));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
}
return NS_OK;
}
nsresult
WSRunObject::Scrub()
{
WSFragment *run = mStartRun;
while (run) {
if (run->mType & (WSType::leadingWS | WSType::trailingWS)) {
- nsresult rv = DeleteChars(run->mStartNode, run->mStartOffset,
- run->mEndNode, run->mEndOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ nsresult rv = DeleteRange(run->StartPoint(), run->EndPoint());
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
}
run = run->mRight;
}
return NS_OK;
}
bool
WSRunObject::IsBlockNode(nsINode* aNode)